vendor: 5,492 bytes, lines 1-9
1var iq=Object.defineProperty;var rq=(t,e,a)=>e in t?iq(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a;var di=(t,e,a)=>rq(t,typeof e!="symbol"?e+"":e,a);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const r of i)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function a(i){const r={};return i.integrity&&(r.integrity=i.integrity),i.referrerPolicy&&(r.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?r.credentials="include":i.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function n(i){if(i.ep)return;i.ep=!0;const r=a(i);fetch(i.href,r)}})();function wu(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var QT={exports:{}},qf={},XT={exports:{}},be={};/** 2 * @license React 3 * react.production.min.js 4 * 5 * Copyright (c) Facebook, Inc. and its affiliates. 6 * 7 * This source code is licensed under the MIT license found in the 8 * LICENSE file in the root directory of this source tree. 9 */var ku=Symbol.for("react.element"),oq=Symbol.for("react.portal"),sq=Symbol.for("react.fragment"),lq=Symbol.for("react.strict_mode"),cq=Symbol.for("react.profiler"),dq=Symbol.for("react.provider"),uq=Symbol.for("react.context"),pq=Symbol.for("react.forward_ref"),mq=Symbol.for("react.suspense"),hq=Symbol.for("react.memo"),fq=Symbol.for("react.lazy"),R2=Symbol.iterator;function gq(t){return t===null||typeof t!="object"?null:(t=R2&&t[R2]||t["@@iterator"],typeof t=="function"?t:null)}var YT={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},ZT=Object.assign,eN={};function ql(t,e,a){this.props=t,this.context=e,this.refs=eN,this.updater=a||YT}ql.prototype.isReactComponent={};ql.prototype.setState=function(t,e){if(typeof t!="object"&&typeof t!="function"&&t!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,t,e,"setState")};ql.prototype.forceUpdate=function(t){this.updater.enqueueForceUpdate(this,t,"forceUpdate")};function tN(){}tN.prototype=ql.prototype;function e1(t,e,a){this.props=t,this.context=e,this.refs=eN,this.updater=a||YT}var t1=e1.prototype=new tN;t1.constructor=e1;ZT(t1,ql.prototype);t1.isPureReactComponent=!0;var L2=Array.isArray,aN=Object.prototype.hasOwnProperty,a1={current:null},nN={key:!0,ref:!0,__self:!0,__source:!0};function iN(t,e,a){var n,i={},r=null,o=null;if(e!=null)for(n in e.ref!==void 0&&(o=e.ref),e.key!==void 0&&(r=""+e.key),e)aN.call(e,n)&&!nN.hasOwnProperty(n)&&(i[n]=e[n]);var l=arguments.length-2;if(l===1)i.children=a;else if(1<l){for(var c=Array(l),d=0;d<l;d++)c[d]=arguments[d+2];i.children=c}if(t&&t.defaultProps)for(n in l=t.defaultProps,l)i[n]===void 0&&(i[n]=l[n]);return{$$typeof:ku,type:t,key:r,ref:o,props:i,_owner:a1.current}}function yq(t,e){return{$$typeof:ku,type:t.type,key:e,ref:t.ref,props:t.props,_owner:t._owner}}function n1(t){return typeof t=="object"&&t!==null&&t.$$typeof===ku}function xq(t){var e={"=":"=0",":":"=2"};return"$"+t.replace(/[=:]/g,function(a){return e[a]})}var O2=/\/+/g;function ky(t,e){return typeof t=="object"&&t!==null&&t.key!=null?xq(""+t.key):e.toString(36)}function dm(t,e,a,n,i){var r=typeof t;(r==="undefined"||r==="boolean")&&(t=null);var o=!1;if(t===null)o=!0;else switch(r){case"string":case"number":o=!0;break;case"object":switch(t.$$typeof){case ku:case oq:o=!0}}if(o)return o=t,i=i(o),t=n===""?"."+ky(o,0):n,L2(i)?(a="",t!=null&&(a=t.replace(O2,"$&/")+"/"),dm(i,e,a,"",function(d){return d})):i!=null&&(n1(i)&&(i=yq(i,a+(!i.key||o&&o.key===i.key?"":(""+i.key).replace(O2,"$&/")+"/")+t)),e.push(i)),1;if(o=0,n=n===""?".":n+":",L2(t))for(var l=0;l<t.length;l++){r=t[l];var c=n+ky(r,l);o+=dm(r,e,a,c,i)}else if(c=gq(t),typeof c=="function")for(t=c.call(t),l=0;!(r=t.next()).done;)r=r.value,c=n+ky(r,l++),o+=dm(r,e,a,c,i);else if(r==="object")throw e=String(t),Error("Objects are not valid as a React child (found: "+(e==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":e)+"). If you meant to render a collection of children, use an array instead.");return o}function fp(t,e,a){if(t==null)return t;var n=[],i=0;return dm(t,n,"","",function(r){return e.call(a,r,i++)}),n}function vq(t){if(t._status===-1){var e=t._result;e=e(),e.then(function(a){(t._status===0||t._status===-1)&&(t._status=1,t._result=a)},function(a){(t._status===0||t._status===-1)&&(t._status=2,t._result=a)}),t._status===-1&&(t._status=0,t._result=e)}if(t._status===1)return t._result.default;throw t._result}var va={current:null},um={transition:null},bq={ReactCurrentDispatcher:va,ReactCurrentBatchConfig:um,ReactCurrentOwner:a1};function rN(){throw Error("act(...) is not supported in production builds of React.")}be.Children={map:fp,forEach:function(t,e,a){fp(t,function(){e.apply(this,arguments)},a)},count:function(t){var e=0;return fp(t,function(){e++}),e},toArray:function(t){return fp(t,function(e){return e})||[]},only:function(t){if(!n1(t))throw Error("React.Children.only expected to receive a single React element child.");return t}};be.Component=ql;be.Fragment=sq;be.Profiler=cq;be.PureComponent=e1;be.StrictMode=lq;be.Suspense=mq;
vendor: 7,474 bytes, lines 9-25
9be.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=bq;be.act=rN;be.cloneElement=function(t,e,a){if(t==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+t+".");var n=ZT({},t.props),i=t.key,r=t.ref,o=t._owner;if(e!=null){if(e.ref!==void 0&&(r=e.ref,o=a1.current),e.key!==void 0&&(i=""+e.key),t.type&&t.type.defaultProps)var l=t.type.defaultProps;for(c in e)aN.call(e,c)&&!nN.hasOwnProperty(c)&&(n[c]=e[c]===void 0&&l!==void 0?l[c]:e[c])}var c=arguments.length-2;if(c===1)n.children=a;else if(1<c){l=Array(c);for(var d=0;d<c;d++)l[d]=arguments[d+2];n.children=l}return{$$typeof:ku,type:t.type,key:i,ref:r,props:n,_owner:o}};be.createContext=function(t){return t={$$typeof:uq,_currentValue:t,_currentValue2:t,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},t.Provider={$$typeof:dq,_context:t},t.Consumer=t};be.createElement=iN;be.createFactory=function(t){var e=iN.bind(null,t);return e.type=t,e};be.createRef=function(){return{current:null}};be.forwardRef=function(t){return{$$typeof:pq,render:t}};be.isValidElement=n1;be.lazy=function(t){return{$$typeof:fq,_payload:{_status:-1,_result:t},_init:vq}};be.memo=function(t,e){return{$$typeof:hq,type:t,compare:e===void 0?null:e}};be.startTransition=function(t){var e=um.transition;um.transition={};try{t()}finally{um.transition=e}};be.unstable_act=rN;be.useCallback=function(t,e){return va.current.useCallback(t,e)};be.useContext=function(t){return va.current.useContext(t)};be.useDebugValue=function(){};be.useDeferredValue=function(t){return va.current.useDeferredValue(t)};be.useEffect=function(t,e){return va.current.useEffect(t,e)};be.useId=function(){return va.current.useId()};be.useImperativeHandle=function(t,e,a){return va.current.useImperativeHandle(t,e,a)};be.useInsertionEffect=function(t,e){return va.current.useInsertionEffect(t,e)};be.useLayoutEffect=function(t,e){return va.current.useLayoutEffect(t,e)};be.useMemo=function(t,e){return va.current.useMemo(t,e)};be.useReducer=function(t,e,a){return va.current.useReducer(t,e,a)};be.useRef=function(t){return va.current.useRef(t)};be.useState=function(t){return va.current.useState(t)};be.useSyncExternalStore=function(t,e,a){return va.current.useSyncExternalStore(t,e,a)};be.useTransition=function(){return va.current.useTransition()};be.version="18.3.1";XT.exports=be;var k=XT.exports;const Re=wu(k);/** 10 * @license React 11 * react-jsx-runtime.production.min.js 12 * 13 * Copyright (c) Facebook, Inc. and its affiliates. 14 * 15 * This source code is licensed under the MIT license found in the 16 * LICENSE file in the root directory of this source tree. 17 */var wq=k,kq=Symbol.for("react.element"),Sq=Symbol.for("react.fragment"),_q=Object.prototype.hasOwnProperty,Aq=wq.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Eq={key:!0,ref:!0,__self:!0,__source:!0};function oN(t,e,a){var n,i={},r=null,o=null;a!==void 0&&(r=""+a),e.key!==void 0&&(r=""+e.key),e.ref!==void 0&&(o=e.ref);for(n in e)_q.call(e,n)&&!Eq.hasOwnProperty(n)&&(i[n]=e[n]);if(t&&t.defaultProps)for(n in e=t.defaultProps,e)i[n]===void 0&&(i[n]=e[n]);return{$$typeof:kq,type:t,key:r,ref:o,props:i,_owner:Aq.current}}qf.Fragment=Sq;qf.jsx=oN;qf.jsxs=oN;QT.exports=qf;var s=QT.exports,xx={},sN={exports:{}},Ga={},lN={exports:{}},cN={};/** 18 * @license React 19 * scheduler.production.min.js 20 * 21 * Copyright (c) Facebook, Inc. and its affiliates. 22 * 23 * This source code is licensed under the MIT license found in the 24 * LICENSE file in the root directory of this source tree. 25 */(function(t){function e(F,Z){var re=F.length;F.push(Z);e:for(;0<re;){var fe=re-1>>>1,ve=F[fe];if(0<i(ve,Z))F[fe]=Z,F[re]=ve,re=fe;else break e}}function a(F){return F.length===0?null:F[0]}function n(F){if(F.length===0)return null;var Z=F[0],re=F.pop();if(re!==Z){F[0]=re;e:for(var fe=0,ve=F.length,Ie=ve>>>1;fe<Ie;){var ne=2*(fe+1)-1,ge=F[ne],Me=ne+1,We=F[Me];if(0>i(ge,re))Me<ve&&0>i(We,ge)?(F[fe]=We,F[Me]=re,fe=Me):(F[fe]=ge,F[ne]=re,fe=ne);else if(Me<ve&&0>i(We,re))F[fe]=We,F[Me]=re,fe=Me;else break e}}return Z}function i(F,Z){var re=F.sortIndex-Z.sortIndex;return re!==0?re:F.id-Z.id}if(typeof performance=="object"&&typeof performance.now=="function"){var r=performance;t.unstable_now=function(){return r.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],d=[],u=1,p=null,m=3,h=!1,g=!1,y=!1,x=typeof setTimeout=="function"?setTimeout:null,v=typeof clearTimeout=="function"?clearTimeout:null,w=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(F){for(var Z=a(d);Z!==null;){if(Z.callback===null)n(d);else if(Z.startTime<=F)n(d),Z.sortIndex=Z.expirationTime,e(c,Z);else break;Z=a(d)}}function T(F){if(y=!1,S(F),!g)if(a(c)!==null)g=!0,ke(P);else{var Z=a(d);Z!==null&&ae(T,Z.startTime-F)}}function P(F,Z){g=!1,y&&(y=!1,v(E),E=-1),h=!0;var re=m;try{for(S(Z),p=a(c);p!==null&&(!(p.expirationTime>Z)||F&&!L());){var fe=p.callback;if(typeof fe=="function"){p.callback=null,m=p.priorityLevel;var ve=fe(p.expirationTime<=Z);Z=t.unstable_now(),typeof ve=="function"?p.callback=ve:p===a(c)&&n(c),S(Z)}else n(c);p=a(c)}if(p!==null)var Ie=!0;else{var ne=a(d);ne!==null&&ae(T,ne.startTime-Z),Ie=!1}return Ie}finally{p=null,m=re,h=!1}}var M=!1,C=null,E=-1,j=5,N=-1;function L(){return!(t.unstable_now()-N<j)}function O(){if(C!==null){var F=t.unstable_now();N=F;var Z=!0;try{Z=C(!0,F)}finally{Z?R():(M=!1,C=null)}}else M=!1}var R;if(typeof w=="function")R=function(){w(O)};else if(typeof MessageChannel<"u"){var G=new MessageChannel,ee=G.port2;G.port1.onmessage=O,R=function(){ee.postMessage(null)}}else R=function(){x(O,0)};function ke(F){C=F,M||(M=!0,R())}function ae(F,Z){E=x(function(){F(t.unstable_now())},Z)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(F){F.callback=null},t.unstable_continueExecution=function(){g||h||(g=!0,ke(P))},t.unstable_forceFrameRate=function(F){0>F||125<F?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):j=0<F?Math.floor(1e3/F):5},t.unstable_getCurrentPriorityLevel=function(){return m},t.unstable_getFirstCallbackNode=function(){return a(c)},t.unstable_next=function(F){switch(m){case 1:case 2:case 3:var Z=3;break;default:Z=m}var re=m;m=Z;try{return F()}finally{m=re}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(F,Z){switch(F){case 1:case 2:case 3:case 4:case 5:break;default:F=3}var re=m;m=F;try{return Z()}finally{m=re}},t.unstable_scheduleCallback=function(F,Z,re){var fe=t.unstable_now();switch(typeof re=="object"&&re!==null?(re=re.delay,re=typeof re=="number"&&0<re?fe+re:fe):re=fe,F){case 1:var ve=-1;break;case 2:ve=250;break;case 5:ve=1073741823;break;case 4:ve=1e4;break;default:ve=5e3}return ve=re+ve,F={id:u++,callback:Z,priorityLevel:F,startTime:re,expirationTime:ve,sortIndex:-1},re>fe?(F.sortIndex=re,e(d,F),a(c)===null&&F===a(d)&&(y?(v(E),E=-1):y=!0,ae(T,re-fe))):(F.sortIndex=ve,e(c,F),g||h||(g=!0,ke(P))),F},t.unstable_shouldYield=L,t.unstable_wrapCallback=function(F){var Z=m;return function(){var re=m;m=Z;try{return F.apply(this,arguments)}finally{m=re}}}})(cN);lN.exports=cN;
vendor: 4,228 bytes, lines 25-33
25var Cq=lN.exports;/** 26 * @license React 27 * react-dom.production.min.js 28 * 29 * Copyright (c) Facebook, Inc. and its affiliates. 30 * 31 * This source code is licensed under the MIT license found in the 32 * LICENSE file in the root directory of this source tree. 33 */var jq=k,$a=Cq;function U(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,a=1;a<arguments.length;a++)e+="&args[]="+encodeURIComponent(arguments[a]);return"Minified React error #"+t+"; visit "+e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var dN=new Set,Nd={};function ls(t,e){pl(t,e),pl(t+"Capture",e)}function pl(t,e){for(Nd[t]=e,t=0;t<e.length;t++)dN.add(e[t])}var Ri=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),vx=Object.prototype.hasOwnProperty,Tq=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,M2={},D2={};function Nq(t){return vx.call(D2,t)?!0:vx.call(M2,t)?!1:Tq.test(t)?D2[t]=!0:(M2[t]=!0,!1)}function Iq(t,e,a,n){if(a!==null&&a.type===0)return!1;switch(typeof e){case"function":case"symbol":return!0;case"boolean":return n?!1:a!==null?!a.acceptsBooleans:(t=t.toLowerCase().slice(0,5),t!=="data-"&&t!=="aria-");default:return!1}}function Pq(t,e,a,n){if(e===null||typeof e>"u"||Iq(t,e,a,n))return!0;if(n)return!1;if(a!==null)switch(a.type){case 3:return!e;case 4:return e===!1;case 5:return isNaN(e);case 6:return isNaN(e)||1>e}return!1}function ba(t,e,a,n,i,r,o){this.acceptsBooleans=e===2||e===3||e===4,this.attributeName=n,this.attributeNamespace=i,this.mustUseProperty=a,this.propertyName=t,this.type=e,this.sanitizeURL=r,this.removeEmptyString=o}var Ut={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(t){Ut[t]=new ba(t,0,!1,t,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(t){var e=t[0];Ut[e]=new ba(e,1,!1,t[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(t){Ut[t]=new ba(t,2,!1,t.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(t){Ut[t]=new ba(t,2,!1,t,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(t){Ut[t]=new ba(t,3,!1,t.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(t){Ut[t]=new ba(t,3,!0,t,null,!1,!1)});["capture","download"].forEach(function(t){Ut[t]=new ba(t,4,!1,t,null,!1,!1)});["cols","rows","size","span"].forEach(function(t){Ut[t]=new ba(t,6,!1,t,null,!1,!1)});["rowSpan","start"].forEach(function(t){Ut[t]=new ba(t,5,!1,t.toLowerCase(),null,!1,!1)});var i1=/[\-:]([a-z])/g;function r1(t){return t[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode
33-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(t){var e=t.replace(i1,r1);Ut[e]=new ba(e,1,!1,t,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(t){var e=t.replace(i1,r1);Ut[e]=new ba(e,1,!1,t,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(t){var e=t.replace(i1,r1);Ut[e]=new ba(e,1,!1,t,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(t){Ut[t]=new ba(t,1,!1,t.toLowerCase(),null,!1,!1)});Ut.xlinkHref=new ba("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(t){Ut[t]=new ba(t,1,!1,t.toLowerCase(),null,!0,!0)});function o1(t,e,a,n){var i=Ut.hasOwnProperty(e)?Ut[e]:null;(i!==null?i.type!==0:n||!(2<e.length)||e[0]!=="o"&&e[0]!=="O"||e[1]!=="n"&&e[1]!=="N")&&(Pq(e,a,i,n)&&(a=null),n||i===null?Nq(e)&&(a===null?t.removeAttribute(e):t.setAttribute(e,""+a)):i.mustUseProperty?t[i.propertyName]=a===null?i.type===3?!1:"":a:(e=i.attributeName,n=i.attributeNamespace,a===null?t.removeAttribute(e):(i=i.type,a=i===3||i===4&&a===!0?"":""+a,n?t.setAttributeNS(n,e,a):t.setAttribute(e,a))))}var Ui=jq.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,gp=Symbol.for("react.element"),Rs=Symbol.for("react.portal"),Ls=Symbol.for("react.fragment"),s1=Symbol.for("react.strict_mode"),bx=Symbol.for("react.profiler"),uN=Symbol.for("react.provider"),pN=Symbol.for("react.context"),l1=Symbol.for("react.forward_ref"),wx=Symbol.for("react.suspense"),kx=Symbol.for("react.suspense_list"),c1=Symbol.for("react.memo"),tr=Symbol.for("react.lazy"),mN=Symbol.for("react.offscreen"),q2=Symbol.iterator;function hc(t){return t===null||typeof t!="object"?null:(t=q2&&t[q2]||t["@@iterator"],typeof t=="function"?t:null)}var Ze=Object.assign,Sy;function Lc(t){if(Sy===void 0)try{throw Error()}catch(a){var e=a.stack.trim().match(/\n( *(at )?)/);Sy=e&&e[1]||""}return` 34`+Sy+t}var _y=!1;function Ay(t,e){if(!t||_y)return"";_y=!0;var a=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(e)if(e=function(){throw Error()},Object.defineProperty(e.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(e,[])}catch(d){var n=d}Reflect.construct(t,[],e)}else{try{e.call()}catch(d){n=d}t.call(e.prototype)}else{try{throw Error()}catch(d){n=d}t()}}catch(d){if(d&&n&&typeof d.stack=="string"){for(var i=d.stack.split(` 35`),r=n.stack.split(` 36`),o=i.length-1,l=r.length-1;1<=o&&0<=l&&i[o]!==r[l];)l--;for(;1<=o&&0<=l;o--,l--)if(i[o]!==r[l]){if(o!==1||l!==1)do if(o--,l--,0>l||i[o]!==r[l]){var c=` 37`+i[o].replace(" at new "," at ");return t.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",t.displayName)),c}while(1<=o&&0<=l);break}}}finally{_y=!1,Error.prepareStackTrace=a}return(t=t?t.displayName||t.name:"")?Lc(t):""}function Rq(t){switch(t.tag){case 5:return Lc(t.type);case 16:return Lc("Lazy");case 13:return Lc("Suspense");case 19:return Lc("SuspenseList");case 0:case 2:case 15:return t=Ay(t.type,!1),t;case 11:return t=Ay(t.type.render,!1),t;case 1:return t=Ay(t.type,!0),t;default:return""}}function Sx(t){if(t==null)return null;if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case Ls:return"Fragment";case Rs:return"Portal";case bx:return"Profiler";case s1:return"StrictMode";case wx:return"Suspense";case kx:return"SuspenseList"}if(typeof t=="object")switch(t.$$typeof){case pN:return(t.displayName||"Context")+".Consumer";case uN:return(t._context.displayName||"Context")+".Provider";case l1:var e=t.render;return t=t.displayName,t||(t=e.displayName||e.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case c1:return e=t.displayName||null,e!==null?e:Sx(t.type)||"Memo";case tr:e=t._payload,t=t._init;try{return Sx(t(e))}catch{}}return null}function Lq(t){var e=t.type;switch(t.tag){case 24:return"Cache";case 9:return(e.displayName||"Context")+".Consumer";case 10:return(e._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return t=e.render,t=t.displayName||t.name||"",e.displayName||(t!==""?"ForwardRef("+t+")":"ForwardRef");case 7:return"Fragment";case 5:return e;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Sx(e);case 8:return e===s1?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e}return null}function Dr(t){switch(typeof t){case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function hN(t){var e=t.type;
vendor: 11,635 bytes, line 37
37return(t=t.nodeName)&&t.toLowerCase()==="input"&&(e==="checkbox"||e==="radio")}function Oq(t){var e=hN(t)?"checked":"value",a=Object.getOwnPropertyDescriptor(t.constructor.prototype,e),n=""+t[e];if(!t.hasOwnProperty(e)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var i=a.get,r=a.set;return Object.defineProperty(t,e,{configurable:!0,get:function(){return i.call(this)},set:function(o){n=""+o,r.call(this,o)}}),Object.defineProperty(t,e,{enumerable:a.enumerable}),{getValue:function(){return n},setValue:function(o){n=""+o},stopTracking:function(){t._valueTracker=null,delete t[e]}}}}function yp(t){t._valueTracker||(t._valueTracker=Oq(t))}function fN(t){if(!t)return!1;var e=t._valueTracker;if(!e)return!0;var a=e.getValue(),n="";return t&&(n=hN(t)?t.checked?"true":"false":t.value),t=n,t!==a?(e.setValue(t),!0):!1}function Km(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function _x(t,e){var a=e.checked;return Ze({},e,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a??t._wrapperState.initialChecked})}function z2(t,e){var a=e.defaultValue==null?"":e.defaultValue,n=e.checked!=null?e.checked:e.defaultChecked;a=Dr(e.value!=null?e.value:a),t._wrapperState={initialChecked:n,initialValue:a,controlled:e.type==="checkbox"||e.type==="radio"?e.checked!=null:e.value!=null}}function gN(t,e){e=e.checked,e!=null&&o1(t,"checked",e,!1)}function Ax(t,e){gN(t,e);var a=Dr(e.value),n=e.type;if(a!=null)n==="number"?(a===0&&t.value===""||t.value!=a)&&(t.value=""+a):t.value!==""+a&&(t.value=""+a);else if(n==="submit"||n==="reset"){t.removeAttribute("value");return}e.hasOwnProperty("value")?Ex(t,e.type,a):e.hasOwnProperty("defaultValue")&&Ex(t,e.type,Dr(e.defaultValue)),e.checked==null&&e.defaultChecked!=null&&(t.defaultChecked=!!e.defaultChecked)}function V2(t,e,a){if(e.hasOwnProperty("value")||e.hasOwnProperty("defaultValue")){var n=e.type;if(!(n!=="submit"&&n!=="reset"||e.value!==void 0&&e.value!==null))return;e=""+t._wrapperState.initialValue,a||e===t.value||(t.value=e),t.defaultValue=e}a=t.name,a!==""&&(t.name=""),t.defaultChecked=!!t._wrapperState.initialChecked,a!==""&&(t.name=a)}function Ex(t,e,a){(e!=="number"||Km(t.ownerDocument)!==t)&&(a==null?t.defaultValue=""+t._wrapperState.initialValue:t.defaultValue!==""+a&&(t.defaultValue=""+a))}var Oc=Array.isArray;function Xs(t,e,a,n){if(t=t.options,e){e={};for(var i=0;i<a.length;i++)e["$"+a[i]]=!0;for(a=0;a<t.length;a++)i=e.hasOwnProperty("$"+t[a].value),t[a].selected!==i&&(t[a].selected=i),i&&n&&(t[a].defaultSelected=!0)}else{for(a=""+Dr(a),e=null,i=0;i<t.length;i++){if(t[i].value===a){t[i].selected=!0,n&&(t[i].defaultSelected=!0);return}e!==null||t[i].disabled||(e=t[i])}e!==null&&(e.selected=!0)}}function Cx(t,e){if(e.dangerouslySetInnerHTML!=null)throw Error(U(91));return Ze({},e,{value:void 0,defaultValue:void 0,children:""+t._wrapperState.initialValue})}function H2(t,e){var a=e.value;if(a==null){if(a=e.children,e=e.defaultValue,a!=null){if(e!=null)throw Error(U(92));if(Oc(a)){if(1<a.length)throw Error(U(93));a=a[0]}e=a}e==null&&(e=""),a=e}t._wrapperState={initialValue:Dr(a)}}function yN(t,e){var a=Dr(e.value),n=Dr(e.defaultValue);a!=null&&(a=""+a,a!==t.value&&(t.value=a),e.defaultValue==null&&t.defaultValue!==a&&(t.defaultValue=a)),n!=null&&(t.defaultValue=""+n)}function F2(t){var e=t.textContent;e===t._wrapperState.initialValue&&e!==""&&e!==null&&(t.value=e)}function xN(t){switch(t){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function jx(t,e){return t==null||t==="http://www.w3.org/1999/xhtml"?xN(e):t==="http://www.w3.org/2000/svg"&&e==="foreignObject"?"http://www.w3.org/1999/xhtml":t}var xp,vN=function(t){return typeof MSApp<"u"&&MSApp.execUnsafeLocalFunction?function(e,a,n,i){MSApp.execUnsafeLocalFunction(function(){return t(e,a,n,i)})}:t}(function(t,e){if(t.namespaceURI!=="http://www.w3.org/2000/svg"||"innerHTML"in t)t.innerHTML=e;else{for(xp=xp||document.createElement("div"),xp.innerHTML="<svg>"+e.valueOf().toString()+"</svg>",e=xp.firstChild;t.firstChild;)t.removeChild(t.firstChild);for(;e.firstChild;)t.appendChild(e.firstChild)}});function Id(t,e){if(e){var a=t.firstChild;if(a&&a===t.lastChild&&a.nodeType===3){a.nodeValue=e;return}}t.textContent=e}var Jc={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Mq=["Webkit","ms","Moz","O"];Object.keys(Jc).forEach(function(t){Mq.forEach(function(e){e=e+t.charAt(0).toUpperCase()+t.substring(1),Jc[e]=Jc[t]})});function bN(t,e,a){return e==null||typeof e=="boolean"||e===""?"":a||typeof e!="number"||e===0||Jc.hasOwnProperty(t)&&Jc[t]?(""+e).trim():e+"px"}function wN(t,e){t=t.style;for(var a in e)if(e.hasOwnProperty(a)){var n=a.indexOf("--")===0,i=bN(a,e[a],n);a==="float"&&(a="cssFloat"),n?t.setProperty(a,i):t[a]=i}}var Dq=Ze({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Tx(t,e){if(e){if(Dq[t]&&(e.children!=null||e.dangerouslySetInnerHTML!=null))throw Error(U(137,t));if(e.dangerouslySetInnerHTML!=null){if(e.children!=null)throw Error(U(60));if(typeof e.dangerouslySetInnerHTML!="object"||!("__html"in e.dangerouslySetInnerHTML))throw Error(U(61))}if(e.style!=null&&typeof e.style!="object")throw Error(U(62))}}function Nx(t,e){if(t.indexOf("-")===-1)return typeof e.is=="string";switch(t){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Ix=null;function d1(t){return t=t.target||t.srcElement||window,t.correspondingUseElement&&(t=t.correspondingUseElement),t.nodeType===3?t.parentNode:t}var Px=null,Ys=null,Zs=null;function B2(t){if(t=Au(t)){if(typeof Px!="function")throw Error(U(280));var e=t.stateNode;e&&(e=Bf(e),Px(t.stateNode,t.type,e))}}function kN(t){Ys?Zs?Zs.push(t):Zs=[t]:Ys=t}function SN(){if(Ys){var t=Ys,e=Zs;if(Zs=Ys=null,B2(t),e)for(t=0;t<e.length;t++)B2(e[t])}}function _N(t,e){return t(e)}function AN(){}var Ey=!1;function EN(t,e,a){if(Ey)return t(e,a);Ey=!0;try{return _N(t,e,a)}finally{Ey=!1,(Ys!==null||Zs!==null)&&(AN(),SN())}}function Pd(t,e){var a=t.stateNode;if(a===null)return null;var n=Bf(a);if(n===null)return null;a=n[e];e:switch(e){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(n=!n.disabled)||(t=t.type,n=!(t==="button"||t==="input"||t==="select"||t==="textarea")),t=!n;break e;default:t=!1}if(t)return null;if(a&&typeof a!="function")throw Error(U(231,e,typeof a));return a}var Rx=!1;if(Ri)try{var fc={};Object.defineProperty(fc,"passive",{get:function(){Rx=!0}}),window.addEventListener("test",fc,fc),window.removeEventListener("test",fc,fc)}catch{Rx=!1}function qq(t,e,a,n,i,r,o,l,c){var d=Array.prototype.slice.call(arguments,3);try{e.apply(a,d)}catch(u){this.onError(u)}}var Qc=!1,Jm=null,Qm=!1,Lx=null,zq={onError:function(t){Qc=!0,Jm=t}};function Vq(t,e,a,n,i,r,o,l,c){Qc=!1,Jm=null,qq.apply(zq,arguments)}function Hq(t,e,a,n,i,r,o,l,c){if(Vq.apply(this,arguments),Qc){if(Qc){var d=Jm;Qc=!1,Jm=null}else throw Error(U(198));Qm||(Qm=!0,Lx=d)}}function cs(t){var e=t,a=t;if(t.alternate)for(;e.return;)e=e.return;else{t=e;do e=t,e.flags&4098&&(a=e.return),t=e.return;while(t)}return e.tag===3?a:null}function CN(t){if(t.tag===13){var e=t.memoizedState;if(e===null&&(t=t.alternate,t!==null&&(e=t.memoizedState)),e!==null)return e.dehydrated}return null}function U2(t){if(cs(t)!==t)throw Error(U(188))}function Fq(t){var e=t.alternate;if(!e){if(e=cs(t),e===null)throw Error(U(188));return e!==t?null:t}for(var a=t,n=e;;){var i=a.return;if(i===null)break;var r=i.alternate;if(r===null){if(n=i.return,n!==null){a=n;continue}break}if(i.child===r.child){for(r=i.child;r;){if(r===a)return U2(i),t;if(r===n)return U2(i),e;r=r.sibling}throw Error(U(188))}if(a.return!==n.return)a=i,n=r;else{for(var o=!1,l=i.child;l;){if(l===a){o=!0,a=i,n=r;break}if(l===n){o=!0,n=i,a=r;break}l=l.sibling}if(!o){for(l=r.child;l;){if(l===a){o=!0,a=r,n=i;break}if(l===n){o=!0,n=r,a=i;break}l=l.sibling}if(!o)throw Error(U(189))}}if(a.alternate!==n)throw Error(U(190))}if(a.tag!==3)throw Error(U(188));return a.stateNode.current===a?t:e}function jN(t){return t=Fq(t),t!==null?TN(t):null}function TN(t){if(t.tag===5||t.tag===6)return t;for(t=t.child;t!==null;){var e=TN(t);if(e!==null)return e;t=t.sibling}return null}var NN=$a.unstable_scheduleCallback,$2=$a.unstable_cancelCallback,Bq=$a.unstable_shouldYield,Uq=$a.unstable_requestPaint,pt=$a.unstable_now,$q=$a.unstable_getCurrentPriorityLevel,u1=$a.unstable_ImmediatePriority,IN=$a.unstable_UserBlockingPriority,Xm=$a.unstable_NormalPriority,Wq=$a.unstable_LowPriority,PN=$a.unstable_IdlePriority,zf=null,Xn=null;function Gq(t){if(Xn&&typeof Xn.onCommitFiberRoot=="function")try{Xn.onCommitFiberRoot(zf,t,void 0,(t.current.flags&128)===128)}catch{}}var Tn=Math.clz32?Math.clz32:Qq,Kq=Math.log,Jq=Math.LN2;function Qq(t){return t>>>=0,t===0?32:31-(Kq(t)/Jq|0)|0}var vp=64,bp=4194304;function Mc(t){switch(t&-t){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: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 t&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return t&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return t}}function Ym(t,e){var a=t.pendingLanes;if(a===0)return 0;var n=0,i=t.suspendedLanes,r=t.pingedLanes,o=a&268435455;if(o!==0){var l=o&~i;l!==0?n=Mc(l):(r&=o,r!==0&&(n=Mc(r)))}else o=a&~i,o!==0?n=Mc(o):r!==0&&(n=Mc(r));if(n===0)return 0;if(e!==0&&e!==n&&!(e&i)&&(i=n&-n,r=e&-e,i>=r||i===16&&(r&4194240)!==0))return e;if(n&4&&(n|=a&16),e=t.entangledLanes,e!==0)for(t=t.entanglements,e&=n;0<e;)a=31-Tn(e),i=1<<a,n|=t[a],e&=~i;return n}function Xq(t,e){switch(t){case 1:case 2:case 4:return e+250;case 8:case 16:case 32:case 64: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 e+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Yq(t,e){for(var a=t.suspendedLanes,n=t.pingedLanes,i=t.expirationTimes,r=t.pendingLanes;0<r;){var o=31-Tn(r),l=1<<o,c=i[o];c===-1?(!(l&a)||l&n)&&(i[o]=Xq(l,e)):c<=e&&(t.expiredLanes|=l),r&=~l}}function Ox(t){return t=t.pendingLanes&-1073741825,t!==0?t:t&1073741824?1073741824:0}function RN(){var t=vp;return vp<<=1,!(vp&4194240)&&(vp=64),t}function Cy(t){for(var e=[],a=0;31>a;
vendor: 4,110 bytes, line 37
37a++)e.push(t);return e}function Su(t,e,a){t.pendingLanes|=e,e!==536870912&&(t.suspendedLanes=0,t.pingedLanes=0),t=t.eventTimes,e=31-Tn(e),t[e]=a}function Zq(t,e){var a=t.pendingLanes&~e;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.expiredLanes&=e,t.mutableReadLanes&=e,t.entangledLanes&=e,e=t.entanglements;var n=t.eventTimes;for(t=t.expirationTimes;0<a;){var i=31-Tn(a),r=1<<i;e[i]=0,n[i]=-1,t[i]=-1,a&=~r}}function p1(t,e){var a=t.entangledLanes|=e;for(t=t.entanglements;a;){var n=31-Tn(a),i=1<<n;i&e|t[n]&e&&(t[n]|=e),a&=~i}}var Le=0;function LN(t){return t&=-t,1<t?4<t?t&268435455?16:536870912:4:1}var ON,m1,MN,DN,qN,Mx=!1,wp=[],wr=null,kr=null,Sr=null,Rd=new Map,Ld=new Map,or=[],e6="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function W2(t,e){switch(t){case"focusin":case"focusout":wr=null;break;case"dragenter":case"dragleave":kr=null;break;case"mouseover":case"mouseout":Sr=null;break;case"pointerover":case"pointerout":Rd.delete(e.pointerId);break;case"gotpointercapture":case"lostpointercapture":Ld.delete(e.pointerId)}}function gc(t,e,a,n,i,r){return t===null||t.nativeEvent!==r?(t={blockedOn:e,domEventName:a,eventSystemFlags:n,nativeEvent:r,targetContainers:[i]},e!==null&&(e=Au(e),e!==null&&m1(e)),t):(t.eventSystemFlags|=n,e=t.targetContainers,i!==null&&e.indexOf(i)===-1&&e.push(i),t)}function t6(t,e,a,n,i){switch(e){case"focusin":return wr=gc(wr,t,e,a,n,i),!0;case"dragenter":return kr=gc(kr,t,e,a,n,i),!0;case"mouseover":return Sr=gc(Sr,t,e,a,n,i),!0;case"pointerover":var r=i.pointerId;return Rd.set(r,gc(Rd.get(r)||null,t,e,a,n,i)),!0;case"gotpointercapture":return r=i.pointerId,Ld.set(r,gc(Ld.get(r)||null,t,e,a,n,i)),!0}return!1}function zN(t){var e=xo(t.target);if(e!==null){var a=cs(e);if(a!==null){if(e=a.tag,e===13){if(e=CN(a),e!==null){t.blockedOn=e,qN(t.priority,function(){MN(a)});return}}else if(e===3&&a.stateNode.current.memoizedState.isDehydrated){t.blockedOn=a.tag===3?a.stateNode.containerInfo:null;return}}}t.blockedOn=null}function pm(t){if(t.blockedOn!==null)return!1;for(var e=t.targetContainers;0<e.length;){var a=Dx(t.domEventName,t.eventSystemFlags,e[0],t.nativeEvent);if(a===null){a=t.nativeEvent;var n=new a.constructor(a.type,a);Ix=n,a.target.dispatchEvent(n),Ix=null}else return e=Au(a),e!==null&&m1(e),t.blockedOn=a,!1;e.shift()}return!0}function G2(t,e,a){pm(t)&&a.delete(e)}function a6(){Mx=!1,wr!==null&&pm(wr)&&(wr=null),kr!==null&&pm(kr)&&(kr=null),Sr!==null&&pm(Sr)&&(Sr=null),Rd.forEach(G2),Ld.forEach(G2)}function yc(t,e){t.blockedOn===e&&(t.blockedOn=null,Mx||(Mx=!0,$a.unstable_scheduleCallback($a.unstable_NormalPriority,a6)))}function Od(t){function e(i){return yc(i,t)}if(0<wp.length){yc(wp[0],t);for(var a=1;a<wp.length;a++){var n=wp[a];n.blockedOn===t&&(n.blockedOn=null)}}for(wr!==null&&yc(wr,t),kr!==null&&yc(kr,t),Sr!==null&&yc(Sr,t),Rd.forEach(e),Ld.forEach(e),a=0;a<or.length;a++)n=or[a],n.blockedOn===t&&(n.blockedOn=null);for(;0<or.length&&(a=or[0],a.blockedOn===null);)zN(a),a.blockedOn===null&&or.shift()}var el=Ui.ReactCurrentBatchConfig,Zm=!0;function n6(t,e,a,n){var i=Le,r=el.transition;el.transition=null;try{Le=1,h1(t,e,a,n)}finally{Le=i,el.transition=r}}function i6(t,e,a,n){var i=Le,r=el.transition;el.transition=null;try{Le=4,h1(t,e,a,n)}finally{Le=i,el.transition=r}}function h1(t,e,a,n){if(Zm){var i=Dx(t,e,a,n);if(i===null)Dy(t,e,n,eh,a),W2(t,n);else if(t6(i,t,e,a,n))n.stopPropagation();else if(W2(t,n),e&4&&-1<e6.indexOf(t)){for(;i!==null;){var r=Au(i);if(r!==null&&ON(r),r=Dx(t,e,a,n),r===null&&Dy(t,e,n,eh,a),r===i)break;i=r}i!==null&&n.stopPropagation()}else Dy(t,e,n,null,a)}}var eh=null;function Dx(t,e,a,n){if(eh=null,t=d1(n),t=xo(t),t!==null)if(e=cs(t),e===null)t=null;else if(a=e.tag,a===13){if(t=CN(e),t!==null)return t;t=null}else if(a===3){if(e.stateNode.current.memoizedState.isDehydrated)return e.tag===3?e.stateNode.containerInfo:null;t=null}else e!==t&&(t=null);return eh=t,null}
vendor: 10,401 bytes, line 37
37function VN(t){switch(t){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch($q()){case u1:return 1;case IN:return 4;case Xm:case Wq:return 16;case PN:return 536870912;default:return 16}default:return 16}}var hr=null,f1=null,mm=null;function HN(){if(mm)return mm;var t,e=f1,a=e.length,n,i="value"in hr?hr.value:hr.textContent,r=i.length;for(t=0;t<a&&e[t]===i[t];t++);var o=a-t;for(n=1;n<=o&&e[a-n]===i[r-n];n++);return mm=i.slice(t,1<n?1-n:void 0)}function hm(t){var e=t.keyCode;return"charCode"in t?(t=t.charCode,t===0&&e===13&&(t=13)):t=e,t===10&&(t=13),32<=t||t===13?t:0}function kp(){return!0}function K2(){return!1}function Ka(t){function e(a,n,i,r,o){this._reactName=a,this._targetInst=i,this.type=n,this.nativeEvent=r,this.target=o,this.currentTarget=null;for(var l in t)t.hasOwnProperty(l)&&(a=t[l],this[l]=a?a(r):r[l]);return this.isDefaultPrevented=(r.defaultPrevented!=null?r.defaultPrevented:r.returnValue===!1)?kp:K2,this.isPropagationStopped=K2,this}return Ze(e.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():typeof a.returnValue!="unknown"&&(a.returnValue=!1),this.isDefaultPrevented=kp)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():typeof a.cancelBubble!="unknown"&&(a.cancelBubble=!0),this.isPropagationStopped=kp)},persist:function(){},isPersistent:kp}),e}var zl={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(t){return t.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},g1=Ka(zl),_u=Ze({},zl,{view:0,detail:0}),r6=Ka(_u),jy,Ty,xc,Vf=Ze({},_u,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:y1,button:0,buttons:0,relatedTarget:function(t){return t.relatedTarget===void 0?t.fromElement===t.srcElement?t.toElement:t.fromElement:t.relatedTarget},movementX:function(t){return"movementX"in t?t.movementX:(t!==xc&&(xc&&t.type==="mousemove"?(jy=t.screenX-xc.screenX,Ty=t.screenY-xc.screenY):Ty=jy=0,xc=t),jy)},movementY:function(t){return"movementY"in t?t.movementY:Ty}}),J2=Ka(Vf),o6=Ze({},Vf,{dataTransfer:0}),s6=Ka(o6),l6=Ze({},_u,{relatedTarget:0}),Ny=Ka(l6),c6=Ze({},zl,{animationName:0,elapsedTime:0,pseudoElement:0}),d6=Ka(c6),u6=Ze({},zl,{clipboardData:function(t){return"clipboardData"in t?t.clipboardData:window.clipboardData}}),p6=Ka(u6),m6=Ze({},zl,{data:0}),Q2=Ka(m6),h6={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},f6={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},g6={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function y6(t){var e=this.nativeEvent;return e.getModifierState?e.getModifierState(t):(t=g6[t])?!!e[t]:!1}function y1(){return y6}var x6=Ze({},_u,{key:function(t){if(t.key){var e=h6[t.key]||t.key;if(e!=="Unidentified")return e}return t.type==="keypress"?(t=hm(t),t===13?"Enter":String.fromCharCode(t)):t.type==="keydown"||t.type==="keyup"?f6[t.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:y1,charCode:function(t){return t.type==="keypress"?hm(t):0},keyCode:function(t){return t.type==="keydown"||t.type==="keyup"?t.keyCode:0},which:function(t){return t.type==="keypress"?hm(t):t.type==="keydown"||t.type==="keyup"?t.keyCode:0}}),v6=Ka(x6),b6=Ze({},Vf,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),X2=Ka(b6),w6=Ze({},_u,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:y1}),k6=Ka(w6),S6=Ze({},zl,{propertyName:0,elapsedTime:0,pseudoElement:0}),_6=Ka(S6),A6=Ze({},Vf,{deltaX:function(t){return"deltaX"in t?t.deltaX:"wheelDeltaX"in t?-t.wheelDeltaX:0},deltaY:function(t){return"deltaY"in t?t.deltaY:"wheelDeltaY"in t?-t.wheelDeltaY:"wheelDelta"in t?-t.wheelDelta:0},deltaZ:0,deltaMode:0}),E6=Ka(A6),C6=[9,13,27,32],x1=Ri&&"CompositionEvent"in window,Xc=null;Ri&&"documentMode"in document&&(Xc=document.documentMode);var j6=Ri&&"TextEvent"in window&&!Xc,FN=Ri&&(!x1||Xc&&8<Xc&&11>=Xc),Y2=" ",Z2=!1;function BN(t,e){switch(t){case"keyup":return C6.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function UN(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Os=!1;function T6(t,e){switch(t){case"compositionend":return UN(e);case"keypress":return e.which!==32?null:(Z2=!0,Y2);case"textInput":return t=e.data,t===Y2&&Z2?null:t;default:return null}}function N6(t,e){if(Os)return t==="compositionend"||!x1&&BN(t,e)?(t=HN(),mm=f1=hr=null,Os=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1<e.char.length)return e.char;if(e.which)return String.fromCharCode(e.which)}return null;case"compositionend":return FN&&e.locale!=="ko"?null:e.data;default:return null}}var I6={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function e_(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e==="input"?!!I6[t.type]:e==="textarea"}function $N(t,e,a,n){kN(n),e=th(e,"onChange"),0<e.length&&(a=new g1("onChange","change",null,a,n),t.push({event:a,listeners:e}))}var Yc=null,Md=null;function P6(t){aI(t,0)}function Hf(t){var e=qs(t);if(fN(e))return t}function R6(t,e){if(t==="change")return e}var WN=!1;if(Ri){var Iy;if(Ri){var Py="oninput"in document;if(!Py){var t_=document.createElement("div");t_.setAttribute("oninput","return;"),Py=typeof t_.oninput=="function"}Iy=Py}else Iy=!1;WN=Iy&&(!document.documentMode||9<document.documentMode)}function a_(){Yc&&(Yc.detachEvent("onpropertychange",GN),Md=Yc=null)}function GN(t){if(t.propertyName==="value"&&Hf(Md)){var e=[];$N(e,Md,t,d1(t)),EN(P6,e)}}function L6(t,e,a){t==="focusin"?(a_(),Yc=e,Md=a,Yc.attachEvent("onpropertychange",GN)):t==="focusout"&&a_()}function O6(t){if(t==="selectionchange"||t==="keyup"||t==="keydown")return Hf(Md)}function M6(t,e){if(t==="click")return Hf(e)}function D6(t,e){if(t==="input"||t==="change")return Hf(e)}function q6(t,e){return t===e&&(t!==0||1/t===1/e)||t!==t&&e!==e}var Ln=typeof Object.is=="function"?Object.is:q6;function Dd(t,e){if(Ln(t,e))return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;var a=Object.keys(t),n=Object.keys(e);if(a.length!==n.length)return!1;for(n=0;n<a.length;n++){var i=a[n];if(!vx.call(e,i)||!Ln(t[i],e[i]))return!1}return!0}function n_(t){for(;t&&t.firstChild;)t=t.firstChild;return t}function i_(t,e){var a=n_(t);t=0;for(var n;a;){if(a.nodeType===3){if(n=t+a.textContent.length,t<=e&&n>=e)return{node:a,offset:e-t};t=n}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=n_(a)}}function KN(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?KN(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function JN(){for(var t=window,e=Km();e instanceof t.HTMLIFrameElement;){try{var a=typeof e.contentWindow.location.href=="string"}catch{a=!1}if(a)t=e.contentWindow;else break;e=Km(t.document)}return e}function v1(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}function z6(t){var e=JN(),a=t.focusedElem,n=t.selectionRange;if(e!==a&&a&&a.ownerDocument&&KN(a.ownerDocument.documentElement,a)){if(n!==null&&v1(a)){if(e=n.start,t=n.end,t===void 0&&(t=e),"selectionStart"in a)a.selectionStart=e,a.selectionEnd=Math.min(t,a.value.length);else if(t=(e=a.ownerDocument||document)&&e.defaultView||window,t.getSelection){t=t.getSelection();var i=a.textContent.length,r=Math.min(n.start,i);n=n.end===void 0?r:Math.min(n.end,i),!t.extend&&r>n&&(i=n,n=r,r=i),i=i_(a,r);var o=i_(a,n);i&&o&&(t.rangeCount!==1||t.anchorNode!==i.node||t.anchorOffset!==i.offset||t.focusNode!==o.node||t.focusOffset!==o.offset)&&(e=e.createRange(),e.setStart(i.node,i.offset),t.removeAllRanges(),r>n?(t.addRange(e),t.extend(o.node,o.offset)):(e.setEnd(o.node,o.offset),t.addRange(e)))}}for(e=[],t=a;t=t.parentNode;)t.nodeType===1&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof a.focus=="function"&&a.focus(),a=0;a<e.length;a++)t=e[a],t.element.scrollLeft=t.left,t.element.scrollTop=t.top}}var V6=Ri&&"documentMode"in document&&11>=document.documentMode,Ms=null,qx=null,Zc=null,zx=!1;function r_(t,e,a){var n=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;zx||Ms==null||Ms!==Km(n)||(n=Ms,"selectionStart"in n&&v1(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focu
vendor: 4,501 bytes, line 37
37sNode:n.focusNode,focusOffset:n.focusOffset}),Zc&&Dd(Zc,n)||(Zc=n,n=th(qx,"onSelect"),0<n.length&&(e=new g1("onSelect","select",null,e,a),t.push({event:e,listeners:n}),e.target=Ms)))}function Sp(t,e){var a={};return a[t.toLowerCase()]=e.toLowerCase(),a["Webkit"+t]="webkit"+e,a["Moz"+t]="moz"+e,a}var Ds={animationend:Sp("Animation","AnimationEnd"),animationiteration:Sp("Animation","AnimationIteration"),animationstart:Sp("Animation","AnimationStart"),transitionend:Sp("Transition","TransitionEnd")},Ry={},QN={};Ri&&(QN=document.createElement("div").style,"AnimationEvent"in window||(delete Ds.animationend.animation,delete Ds.animationiteration.animation,delete Ds.animationstart.animation),"TransitionEvent"in window||delete Ds.transitionend.transition);function Ff(t){if(Ry[t])return Ry[t];if(!Ds[t])return t;var e=Ds[t],a;for(a in e)if(e.hasOwnProperty(a)&&a in QN)return Ry[t]=e[a];return t}var XN=Ff("animationend"),YN=Ff("animationiteration"),ZN=Ff("animationstart"),eI=Ff("transitionend"),tI=new Map,o_="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Wr(t,e){tI.set(t,e),ls(e,[t])}for(var Ly=0;Ly<o_.length;Ly++){var Oy=o_[Ly],H6=Oy.toLowerCase(),F6=Oy[0].toUpperCase()+Oy.slice(1);Wr(H6,"on"+F6)}Wr(XN,"onAnimationEnd");Wr(YN,"onAnimationIteration");Wr(ZN,"onAnimationStart");Wr("dblclick","onDoubleClick");Wr("focusin","onFocus");Wr("focusout","onBlur");Wr(eI,"onTransitionEnd");pl("onMouseEnter",["mouseout","mouseover"]);pl("onMouseLeave",["mouseout","mouseover"]);pl("onPointerEnter",["pointerout","pointerover"]);pl("onPointerLeave",["pointerout","pointerover"]);ls("onChange","change click focusin focusout input keydown keyup selectionchange".split(" "));ls("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" "));ls("onBeforeInput",["compositionend","keypress","textInput","paste"]);ls("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" "));ls("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" "));ls("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Dc="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),B6=new Set("cancel close invalid load scroll toggle".split(" ").concat(Dc));function s_(t,e,a){var n=t.type||"unknown-event";t.currentTarget=a,Hq(n,e,void 0,t),t.currentTarget=null}function aI(t,e){e=(e&4)!==0;for(var a=0;a<t.length;a++){var n=t[a],i=n.event;n=n.listeners;e:{var r=void 0;if(e)for(var o=n.length-1;0<=o;o--){var l=n[o],c=l.instance,d=l.currentTarget;if(l=l.listener,c!==r&&i.isPropagationStopped())break e;s_(i,l,d),r=c}else for(o=0;o<n.length;o++){if(l=n[o],c=l.instance,d=l.currentTarget,l=l.listener,c!==r&&i.isPropagationStopped())break e;s_(i,l,d),r=c}}}if(Qm)throw t=Lx,Qm=!1,Lx=null,t}function Fe(t,e){var a=e[Ux];a===void 0&&(a=e[Ux]=new Set);var n=t+"__bubble";a.has(n)||(nI(e,t,2,!1),a.add(n))}function My(t,e,a){var n=0;e&&(n|=4),nI(a,t,n,e)}var _p="_reactListening"+Math.random().toString(36).slice(2);function qd(t){if(!t[_p]){t[_p]=!0,dN.forEach(function(a){a!=="selectionchange"&&(B6.has(a)||My(a,!1,t),My(a,!0,t))});var e=t.nodeType===9?t:t.ownerDocument;e===null||e[_p]||(e[_p]=!0,My("selectionchange",!1,e))}}function nI(t,e,a,n){switch(VN(e)){case 1:var i=n6;break;case 4:i=i6;break;default:i=h1}a=i.bind(null,e,a,t),i=void 0,!Rx||e!=="touchstart"&&e!=="touchmove"&&e!=="wheel"||(i=!0),n?i!==void 0?t.addEventListener(e,a,{capture:!0,passive:i}):t.addEventListener(e,a,!0):i!==void 0?t.addEventListener(e,a,{passive:i}):t.addEventListener(e,a,!1)}function Dy(t,e,a,n,i){var r=n;if(!(e&1)&&!(e&2)&&n!==null)e:for(;;){if(n===null)return;var o=n.tag;if(o===3||o===4){var l=n.stateNode.containerInfo;
vendor: 5,316 bytes, lines 37-38
37if(l===i||l.nodeType===8&&l.parentNode===i)break;if(o===4)for(o=n.return;o!==null;){var c=o.tag;if((c===3||c===4)&&(c=o.stateNode.containerInfo,c===i||c.nodeType===8&&c.parentNode===i))return;o=o.return}for(;l!==null;){if(o=xo(l),o===null)return;if(c=o.tag,c===5||c===6){n=r=o;continue e}l=l.parentNode}}n=n.return}EN(function(){var d=r,u=d1(a),p=[];e:{var m=tI.get(t);if(m!==void 0){var h=g1,g=t;switch(t){case"keypress":if(hm(a)===0)break e;case"keydown":case"keyup":h=v6;break;case"focusin":g="focus",h=Ny;break;case"focusout":g="blur",h=Ny;break;case"beforeblur":case"afterblur":h=Ny;break;case"click":if(a.button===2)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":h=J2;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":h=s6;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":h=k6;break;case XN:case YN:case ZN:h=d6;break;case eI:h=_6;break;case"scroll":h=r6;break;case"wheel":h=E6;break;case"copy":case"cut":case"paste":h=p6;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":h=X2}var y=(e&4)!==0,x=!y&&t==="scroll",v=y?m!==null?m+"Capture":null:m;y=[];for(var w=d,S;w!==null;){S=w;var T=S.stateNode;if(S.tag===5&&T!==null&&(S=T,v!==null&&(T=Pd(w,v),T!=null&&y.push(zd(w,T,S)))),x)break;w=w.return}0<y.length&&(m=new h(m,g,null,a,u),p.push({event:m,listeners:y}))}}if(!(e&7)){e:{if(m=t==="mouseover"||t==="pointerover",h=t==="mouseout"||t==="pointerout",m&&a!==Ix&&(g=a.relatedTarget||a.fromElement)&&(xo(g)||g[Li]))break e;if((h||m)&&(m=u.window===u?u:(m=u.ownerDocument)?m.defaultView||m.parentWindow:window,h?(g=a.relatedTarget||a.toElement,h=d,g=g?xo(g):null,g!==null&&(x=cs(g),g!==x||g.tag!==5&&g.tag!==6)&&(g=null)):(h=null,g=d),h!==g)){if(y=J2,T="onMouseLeave",v="onMouseEnter",w="mouse",(t==="pointerout"||t==="pointerover")&&(y=X2,T="onPointerLeave",v="onPointerEnter",w="pointer"),x=h==null?m:qs(h),S=g==null?m:qs(g),m=new y(T,w+"leave",h,a,u),m.target=x,m.relatedTarget=S,T=null,xo(u)===d&&(y=new y(v,w+"enter",g,a,u),y.target=S,y.relatedTarget=x,T=y),x=T,h&&g)t:{for(y=h,v=g,w=0,S=y;S;S=ws(S))w++;for(S=0,T=v;T;T=ws(T))S++;for(;0<w-S;)y=ws(y),w--;for(;0<S-w;)v=ws(v),S--;for(;w--;){if(y===v||v!==null&&y===v.alternate)break t;y=ws(y),v=ws(v)}y=null}else y=null;h!==null&&l_(p,m,h,y,!1),g!==null&&x!==null&&l_(p,x,g,y,!0)}}e:{if(m=d?qs(d):window,h=m.nodeName&&m.nodeName.toLowerCase(),h==="select"||h==="input"&&m.type==="file")var P=R6;else if(e_(m))if(WN)P=D6;else{P=O6;var M=L6}else(h=m.nodeName)&&h.toLowerCase()==="input"&&(m.type==="checkbox"||m.type==="radio")&&(P=M6);if(P&&(P=P(t,d))){$N(p,P,a,u);break e}M&&M(t,m,d),t==="focusout"&&(M=m._wrapperState)&&M.controlled&&m.type==="number"&&Ex(m,"number",m.value)}switch(M=d?qs(d):window,t){case"focusin":(e_(M)||M.contentEditable==="true")&&(Ms=M,qx=d,Zc=null);break;case"focusout":Zc=qx=Ms=null;break;case"mousedown":zx=!0;break;case"contextmenu":case"mouseup":case"dragend":zx=!1,r_(p,a,u);break;case"selectionchange":if(V6)break;case"keydown":case"keyup":r_(p,a,u)}var C;if(x1)e:{switch(t){case"compositionstart":var E="onCompositionStart";break e;case"compositionend":E="onCompositionEnd";break e;case"compositionupdate":E="onCompositionUpdate";break e}E=void 0}else Os?BN(t,a)&&(E="onCompositionEnd"):t==="keydown"&&a.keyCode===229&&(E="onCompositionStart");E&&(FN&&a.locale!=="ko"&&(Os||E!=="onCompositionStart"?E==="onCompositionEnd"&&Os&&(C=HN()):(hr=u,f1="value"in hr?hr.value:hr.textContent,Os=!0)),M=th(d,E),0<M.length&&(E=new Q2(E,t,null,a,u),p.push({event:E,listeners:M}),C?E.data=C:(C=UN(a),C!==null&&(E.data=C)))),(C=j6?T6(t,a):N6(t,a))&&(d=th(d,"onBeforeInput"),0<d.length&&(u=new Q2("onBeforeInput","beforeinput",null,a,u),p.push({event:u,listeners:d}),u.data=C))}aI(p,e)})}function zd(t,e,a){return{instance:t,listener:e,currentTarget:a}}function th(t,e){for(var a=e+"Capture",n=[];t!==null;){var i=t,r=i.stateNode;i.tag===5&&r!==null&&(i=r,r=Pd(t,a),r!=null&&n.unshift(zd(t,r,i)),r=Pd(t,e),r!=null&&n.push(zd(t,r,i))),t=t.return}return n}function ws(t){if(t===null)return null;do t=t.return;while(t&&t.tag!==5);return t||null}function l_(t,e,a,n,i){for(var r=e._reactName,o=[];a!==null&&a!==n;){var l=a,c=l.alternate,d=l.stateNode;if(c!==null&&c===n)break;l.tag===5&&d!==null&&(l=d,i?(c=Pd(a,r),c!=null&&o.unshift(zd(a,c,l))):i||(c=Pd(a,r),c!=null&&o.push(zd(a,c,l)))),a=a.return}o.length!==0&&t.push({event:e,listeners:o})}var U6=/\r\n?/g,$6=/\u0000|\uFFFD/g;function c_(t){return(typeof t=="string"?t:""+t).replace(U6,` 38`).replace($6,"")}function Ap(t,e,a){if(e=c_(e),c_(t)!==e&&a)throw Error(U(425))}function ah(){}var Vx=null,Hx=null;function Fx(t,e){return t==="textarea"||t==="noscript"||typeof e.children=="string"||typeof e.children=="number"||typeof e.dangerouslySetInnerHTML=="object"&&e.dangerouslySetInnerHTML!==null&&e.dangerouslySetInnerHTML.__html!=null}var Bx=typeof setTimeout=="function"?setTimeout:void 0,W6=typeof clearTimeout=="function"?clearTimeout:void 0,d_=typeof Promise=="function"?Promise:void 0,G6=typeof queueMicrotask=="function"?queueMicrotask:typeof d_<"u"?function(t){return d_.resolve(null).then(t).cat
vendor: 4,633 bytes, line 38
38ch(K6)}:Bx;function K6(t){setTimeout(function(){throw t})}function qy(t,e){var a=e,n=0;do{var i=a.nextSibling;if(t.removeChild(a),i&&i.nodeType===8)if(a=i.data,a==="/$"){if(n===0){t.removeChild(i),Od(e);return}n--}else a!=="$"&&a!=="$?"&&a!=="$!"||n++;a=i}while(a);Od(e)}function _r(t){for(;t!=null;t=t.nextSibling){var e=t.nodeType;if(e===1||e===3)break;if(e===8){if(e=t.data,e==="$"||e==="$!"||e==="$?")break;if(e==="/$")return null}}return t}function u_(t){t=t.previousSibling;for(var e=0;t;){if(t.nodeType===8){var a=t.data;if(a==="$"||a==="$!"||a==="$?"){if(e===0)return t;e--}else a==="/$"&&e++}t=t.previousSibling}return null}var Vl=Math.random().toString(36).slice(2),Wn="__reactFiber$"+Vl,Vd="__reactProps$"+Vl,Li="__reactContainer$"+Vl,Ux="__reactEvents$"+Vl,J6="__reactListeners$"+Vl,Q6="__reactHandles$"+Vl;function xo(t){var e=t[Wn];if(e)return e;for(var a=t.parentNode;a;){if(e=a[Li]||a[Wn]){if(a=e.alternate,e.child!==null||a!==null&&a.child!==null)for(t=u_(t);t!==null;){if(a=t[Wn])return a;t=u_(t)}return e}t=a,a=t.parentNode}return null}function Au(t){return t=t[Wn]||t[Li],!t||t.tag!==5&&t.tag!==6&&t.tag!==13&&t.tag!==3?null:t}function qs(t){if(t.tag===5||t.tag===6)return t.stateNode;throw Error(U(33))}function Bf(t){return t[Vd]||null}var $x=[],zs=-1;function Gr(t){return{current:t}}function $e(t){0>zs||(t.current=$x[zs],$x[zs]=null,zs--)}function Ve(t,e){zs++,$x[zs]=t.current,t.current=e}var qr={},ia=Gr(qr),Ea=Gr(!1),Bo=qr;function ml(t,e){var a=t.type.contextTypes;if(!a)return qr;var n=t.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===e)return n.__reactInternalMemoizedMaskedChildContext;var i={},r;for(r in a)i[r]=e[r];return n&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=e,t.__reactInternalMemoizedMaskedChildContext=i),i}function Ca(t){return t=t.childContextTypes,t!=null}function nh(){$e(Ea),$e(ia)}function p_(t,e,a){if(ia.current!==qr)throw Error(U(168));Ve(ia,e),Ve(Ea,a)}function iI(t,e,a){var n=t.stateNode;if(e=e.childContextTypes,typeof n.getChildContext!="function")return a;n=n.getChildContext();for(var i in n)if(!(i in e))throw Error(U(108,Lq(t)||"Unknown",i));return Ze({},a,n)}function ih(t){return t=(t=t.stateNode)&&t.__reactInternalMemoizedMergedChildContext||qr,Bo=ia.current,Ve(ia,t),Ve(Ea,Ea.current),!0}function m_(t,e,a){var n=t.stateNode;if(!n)throw Error(U(169));a?(t=iI(t,e,Bo),n.__reactInternalMemoizedMergedChildContext=t,$e(Ea),$e(ia),Ve(ia,t)):$e(Ea),Ve(Ea,a)}var yi=null,Uf=!1,zy=!1;function rI(t){yi===null?yi=[t]:yi.push(t)}function X6(t){Uf=!0,rI(t)}function Kr(){if(!zy&&yi!==null){zy=!0;var t=0,e=Le;try{var a=yi;for(Le=1;t<a.length;t++){var n=a[t];do n=n(!0);while(n!==null)}yi=null,Uf=!1}catch(i){throw yi!==null&&(yi=yi.slice(t+1)),NN(u1,Kr),i}finally{Le=e,zy=!1}}return null}var Vs=[],Hs=0,rh=null,oh=0,nn=[],rn=0,Uo=null,vi=1,bi="";function po(t,e){Vs[Hs++]=oh,Vs[Hs++]=rh,rh=t,oh=e}function oI(t,e,a){nn[rn++]=vi,nn[rn++]=bi,nn[rn++]=Uo,Uo=t;var n=vi;t=bi;var i=32-Tn(n)-1;n&=~(1<<i),a+=1;var r=32-Tn(e)+i;if(30<r){var o=i-i%5;r=(n&(1<<o)-1).toString(32),n>>=o,i-=o,vi=1<<32-Tn(e)+i|a<<i|n,bi=r+t}else vi=1<<r|a<<i|n,bi=t}function b1(t){t.return!==null&&(po(t,1),oI(t,1,0))}function w1(t){for(;t===rh;)rh=Vs[--Hs],Vs[Hs]=null,oh=Vs[--Hs],Vs[Hs]=null;for(;t===Uo;)Uo=nn[--rn],nn[rn]=null,bi=nn[--rn],nn[rn]=null,vi=nn[--rn],nn[rn]=null}var Fa=null,za=null,Ge=!1,_n=null;function sI(t,e){var a=sn(5,null,null,0);a.elementType="DELETED",a.stateNode=e,a.return=t,e=t.deletions,e===null?(t.deletions=[a],t.flags|=16):e.push(a)}function h_(t,e){switch(t.tag){case 5:var a=t.type;return e=e.nodeType!==1||a.toLowerCase()!==e.nodeName.toLowerCase()?null:e,e!==null?(t.stateNode=e,Fa=t,za=_r(e.firstChild),!0):!1;case 6:return e=t.pendingProps===""||e.nodeType!==3?null:e,e!==null?(t.stateNode=e,Fa=t,za=null,!0):!1;case 13:return e=e.nodeType!==8?null:e,e!==null?(a=Uo!==null?{id:vi,overflow:bi}:null,t.memoizedState={dehydrated:e,treeContext:a,retryLane:1073741824},a=sn(18,null,null,0),a.stateNode=e,a.return=t,t.child=a,Fa=t,za=null,!0):!1;default:return!1}}function Wx(t){return(t.mode&1)!==0&&(t.flags&128)===0}function Gx(t){if(Ge){var e=za;if(e){var a=e;if(!h_(t,e)){if(Wx(t))throw Error(U(418));e=_r(a.nextSibling);var n=Fa;e&&h_(t,e)?sI(n,a):(t.flags=t.flags&-4097|2,Ge=!1,Fa=t)}}else{if(Wx(t))throw Error(U(418));t.flags=t.flags&-4097|2,Ge=!1,Fa=t}}}function f_(t){for(t=t.return;t!==null&&t.tag!==5&&t.tag!==3&&t.tag!==13;)t=t.return;Fa=t}function Ep(t){if(t!==Fa)return!1;if(!Ge)return f_(t),Ge=!0,!1;var e;if((e=t.tag!==3)&&!(e=t.tag!==5)&&(e=t.type,e=e!=="head"&&e!=="body"&&!Fx(t.type,t.memoizedProps)),e&&(e=za)){if
vendor: 10,470 bytes, line 38
38(Wx(t))throw lI(),Error(U(418));for(;e;)sI(t,e),e=_r(e.nextSibling)}if(f_(t),t.tag===13){if(t=t.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(U(317));e:{for(t=t.nextSibling,e=0;t;){if(t.nodeType===8){var a=t.data;if(a==="/$"){if(e===0){za=_r(t.nextSibling);break e}e--}else a!=="$"&&a!=="$!"&&a!=="$?"||e++}t=t.nextSibling}za=null}}else za=Fa?_r(t.stateNode.nextSibling):null;return!0}function lI(){for(var t=za;t;)t=_r(t.nextSibling)}function hl(){za=Fa=null,Ge=!1}function k1(t){_n===null?_n=[t]:_n.push(t)}var Y6=Ui.ReactCurrentBatchConfig;function vc(t,e,a){if(t=a.ref,t!==null&&typeof t!="function"&&typeof t!="object"){if(a._owner){if(a=a._owner,a){if(a.tag!==1)throw Error(U(309));var n=a.stateNode}if(!n)throw Error(U(147,t));var i=n,r=""+t;return e!==null&&e.ref!==null&&typeof e.ref=="function"&&e.ref._stringRef===r?e.ref:(e=function(o){var l=i.refs;o===null?delete l[r]:l[r]=o},e._stringRef=r,e)}if(typeof t!="string")throw Error(U(284));if(!a._owner)throw Error(U(290,t))}return t}function Cp(t,e){throw t=Object.prototype.toString.call(e),Error(U(31,t==="[object Object]"?"object with keys {"+Object.keys(e).join(", ")+"}":t))}function g_(t){var e=t._init;return e(t._payload)}function cI(t){function e(v,w){if(t){var S=v.deletions;S===null?(v.deletions=[w],v.flags|=16):S.push(w)}}function a(v,w){if(!t)return null;for(;w!==null;)e(v,w),w=w.sibling;return null}function n(v,w){for(v=new Map;w!==null;)w.key!==null?v.set(w.key,w):v.set(w.index,w),w=w.sibling;return v}function i(v,w){return v=jr(v,w),v.index=0,v.sibling=null,v}function r(v,w,S){return v.index=S,t?(S=v.alternate,S!==null?(S=S.index,S<w?(v.flags|=2,w):S):(v.flags|=2,w)):(v.flags|=1048576,w)}function o(v){return t&&v.alternate===null&&(v.flags|=2),v}function l(v,w,S,T){return w===null||w.tag!==6?(w=Wy(S,v.mode,T),w.return=v,w):(w=i(w,S),w.return=v,w)}function c(v,w,S,T){var P=S.type;return P===Ls?u(v,w,S.props.children,T,S.key):w!==null&&(w.elementType===P||typeof P=="object"&&P!==null&&P.$$typeof===tr&&g_(P)===w.type)?(T=i(w,S.props),T.ref=vc(v,w,S),T.return=v,T):(T=wm(S.type,S.key,S.props,null,v.mode,T),T.ref=vc(v,w,S),T.return=v,T)}function d(v,w,S,T){return w===null||w.tag!==4||w.stateNode.containerInfo!==S.containerInfo||w.stateNode.implementation!==S.implementation?(w=Gy(S,v.mode,T),w.return=v,w):(w=i(w,S.children||[]),w.return=v,w)}function u(v,w,S,T,P){return w===null||w.tag!==7?(w=Po(S,v.mode,T,P),w.return=v,w):(w=i(w,S),w.return=v,w)}function p(v,w,S){if(typeof w=="string"&&w!==""||typeof w=="number")return w=Wy(""+w,v.mode,S),w.return=v,w;if(typeof w=="object"&&w!==null){switch(w.$$typeof){case gp:return S=wm(w.type,w.key,w.props,null,v.mode,S),S.ref=vc(v,null,w),S.return=v,S;case Rs:return w=Gy(w,v.mode,S),w.return=v,w;case tr:var T=w._init;return p(v,T(w._payload),S)}if(Oc(w)||hc(w))return w=Po(w,v.mode,S,null),w.return=v,w;Cp(v,w)}return null}function m(v,w,S,T){var P=w!==null?w.key:null;if(typeof S=="string"&&S!==""||typeof S=="number")return P!==null?null:l(v,w,""+S,T);if(typeof S=="object"&&S!==null){switch(S.$$typeof){case gp:return S.key===P?c(v,w,S,T):null;case Rs:return S.key===P?d(v,w,S,T):null;case tr:return P=S._init,m(v,w,P(S._payload),T)}if(Oc(S)||hc(S))return P!==null?null:u(v,w,S,T,null);Cp(v,S)}return null}function h(v,w,S,T,P){if(typeof T=="string"&&T!==""||typeof T=="number")return v=v.get(S)||null,l(w,v,""+T,P);if(typeof T=="object"&&T!==null){switch(T.$$typeof){case gp:return v=v.get(T.key===null?S:T.key)||null,c(w,v,T,P);case Rs:return v=v.get(T.key===null?S:T.key)||null,d(w,v,T,P);case tr:var M=T._init;return h(v,w,S,M(T._payload),P)}if(Oc(T)||hc(T))return v=v.get(S)||null,u(w,v,T,P,null);Cp(w,T)}return null}function g(v,w,S,T){for(var P=null,M=null,C=w,E=w=0,j=null;C!==null&&E<S.length;E++){C.index>E?(j=C,C=null):j=C.sibling;var N=m(v,C,S[E],T);if(N===null){C===null&&(C=j);break}t&&C&&N.alternate===null&&e(v,C),w=r(N,w,E),M===null?P=N:M.sibling=N,M=N,C=j}if(E===S.length)return a(v,C),Ge&&po(v,E),P;if(C===null){for(;E<S.length;E++)C=p(v,S[E],T),C!==null&&(w=r(C,w,E),M===null?P=C:M.sibling=C,M=C);return Ge&&po(v,E),P}for(C=n(v,C);E<S.length;E++)j=h(C,v,E,S[E],T),j!==null&&(t&&j.alternate!==null&&C.delete(j.key===null?E:j.key),w=r(j,w,E),M===null?P=j:M.sibling=j,M=j);return t&&C.forEach(function(L){return e(v,L)}),Ge&&po(v,E),P}function y(v,w,S,T){var P=hc(S);if(typeof P!="function")throw Error(U(150));if(S=P.call(S),S==null)throw Error(U(151));for(var M=P=null,C=w,E=w=0,j=null,N=S.next();C!==null&&!N.done;E++,N=S.next()){C.index>E?(j=C,C=null):j=C.sibling;var L=m(v,C,N.value,T);if(L===null){C===null&&(C=j);break}t&&C&&L.alternate===null&&e(v,C),w=r(L,w,E),M===null?P=L:M.sibling=L,M=L,C=j}if(N.done)return a(v,C),Ge&&po(v,E),P;if(C===null){for(;!N.done;E++,N=S.next())N=p(v,N.value,T),N!==null&&(w=r(N,w,E),M===null?P=N:M.sibling=N,M=N);return Ge&&po(v,E),P}for(C=n(v,C);!N.done;E++,N=S.next())N=h(C,v,E,N.value,T),N!==null&&(t&&N.alternate!==null&&C.delete(N.key===null?E:N.key),w=r(N,w,E),M===null?P=N:M.sibling=N,M=N);return t&&C.forEach(function(O){return e(v,O)}),Ge&&po(v,E),P}function x(v,w,S,T){if(typeof S=="object"&&S!==null&&S.type===Ls&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case gp:e:{for(var P=S.key,M=w;M!==null;){if(M.key===P){if(P=S.type,P===Ls){if(M.tag===7){a(v,M.sibling),w=i(M,S.props.children),w.return=v,v=w;break e}}else if(M.elementType===P||typeof P=="object"&&P!==null&&P.$$typeof===tr&&g_(P)===M.type){a(v,M.sibling),w=i(M,S.props),w.ref=vc(v,M,S),w.return=v,v=w;break e}a(v,M);break}else e(v,M);M=M.sibling}S.type===Ls?(w=Po(S.props.children,v.mode,T,S.key),w.return=v,v=w):(T=wm(S.type,S.key,S.props,null,v.mode,T),T.ref=vc(v,w,S),T.return=v,v=T)}return o(v);case Rs:e:{for(M=S.key;w!==null;){if(w.key===M)if(w.tag===4&&w.stateNode.containerInfo===S.containerInfo&&w.stateNode.implementation===S.implementation){a(v,w.sibling),w=i(w,S.children||[]),w.return=v,v=w;break e}else{a(v,w);break}else e(v,w);w=w.sibling}w=Gy(S,v.mode,T),w.return=v,v=w}return o(v);case tr:return M=S._init,x(v,w,M(S._payload),T)}if(Oc(S))return g(v,w,S,T);if(hc(S))return y(v,w,S,T);Cp(v,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,w!==null&&w.tag===6?(a(v,w.sibling),w=i(w,S),w.return=v,v=w):(a(v,w),w=Wy(S,v.mode,T),w.return=v,v=w),o(v)):a(v,w)}return x}var fl=cI(!0),dI=cI(!1),sh=Gr(null),lh=null,Fs=null,S1=null;function _1(){S1=Fs=lh=null}function A1(t){var e=sh.current;$e(sh),t._currentValue=e}function Kx(t,e,a){for(;t!==null;){var n=t.alternate;if((t.childLanes&e)!==e?(t.childLanes|=e,n!==null&&(n.childLanes|=e)):n!==null&&(n.childLanes&e)!==e&&(n.childLanes|=e),t===a)break;t=t.return}}function tl(t,e){lh=t,S1=Fs=null,t=t.dependencies,t!==null&&t.firstContext!==null&&(t.lanes&e&&(Aa=!0),t.firstContext=null)}function pn(t){var e=t._currentValue;if(S1!==t)if(t={context:t,memoizedValue:e,next:null},Fs===null){if(lh===null)throw Error(U(308));Fs=t,lh.dependencies={lanes:0,firstContext:t}}else Fs=Fs.next=t;return e}var vo=null;function E1(t){vo===null?vo=[t]:vo.push(t)}function uI(t,e,a,n){var i=e.interleaved;return i===null?(a.next=a,E1(e)):(a.next=i.next,i.next=a),e.interleaved=a,Oi(t,n)}function Oi(t,e){t.lanes|=e;var a=t.alternate;for(a!==null&&(a.lanes|=e),a=t,t=t.return;t!==null;)t.childLanes|=e,a=t.alternate,a!==null&&(a.childLanes|=e),a=t,t=t.return;return a.tag===3?a.stateNode:null}var ar=!1;function C1(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function pI(t,e){t=t.updateQueue,e.updateQueue===t&&(e.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,effects:t.effects})}function Ei(t,e){return{eventTime:t,lane:e,tag:0,payload:null,callback:null,next:null}}function Ar(t,e,a){var n=t.updateQueue;if(n===null)return null;if(n=n.shared,Ee&2){var i=n.pending;return i===null?e.next=e:(e.next=i.next,i.next=e),n.pending=e,Oi(t,a)}return i=n.interleaved,i===null?(e.next=e,E1(n)):(e.next=i.next,i.next=e),n.interleaved=e,Oi(t,a)}function fm(t,e,a){if(e=e.updateQueue,e!==null&&(e=e.shared,(a&4194240)!==0)){var n=e.lanes;n&=t.pendingLanes,a|=n,e.lanes=a,p1(t,a)}}function y_(t,e){var a=t.updateQueue,n=t.alternate;if(n!==null&&(n=n.updateQueue,a===n)){var i=null,r=null;if(a=a.firstBaseUpdate,a!==null){do{var o={eventTime:a.eventTime,lane:a.lane,tag:a.tag,payload:a.payload,callback:a.callback,next:null};r===null?i=r=o:r=r.next=o,a=a.next}while(a!==null);r===null?i=r=e:r=r.next=e}else i=r=e;a={baseState:n.baseState,firstBaseUpdate:i,lastBaseUpdate:r,shared:n.shared,effects:n.effects},t.updateQueue=a;return}t=a.lastBaseUpdate,t===null?a.firstBaseUpdate=e:t.next=e,a.lastBaseUpdate=e}function ch(t,e,a,n){var i=t.updateQueue;ar=!1;var r=i.firstBaseUpdate,o=i.lastBaseUpdate,l=i.shared.pending;if(l!==null){i.shared.pending=null;var c=l,d=c.next;c.next=null,o===null?r=d:o.next=d,o=c;var u=t.alternate;u!==null&&(u=u.updateQueue,l=u.lastBaseUpdate,l!==o&&(l===null?u.firstBaseUpdate=d:l.next=d,u.lastBaseUpdate=c))}if(r!==null){var p=i.baseState;o=0,u=d=c=null,l=r;do{var m=l.lane,h=l.eventTime;if((n&m)===m){u!==null&&(u=u.next={eventTime:h,lane:0,tag:l.tag,payload:l.payload,callback:l.callback,next:null});e:{var g=t,y=l;switch(m=e,h=a,y.tag){case 1:if(g=y.payload,typeof g=="function"){p=g.call(h,p,m);break e}p=g;break e;case 3:g.flags=g.flags&-65537|128;case 0:if(g=y.payload,m=typeof g=="function"?g.call(h,p,m):g,m==null)break e;p=Ze({},p,m);break e;case 2:ar=!0}}l.callback!==null&&l.lane!==0&&(t.flags|=64,m=i.effects,m===null?i.effects=[l]:m.push(l))}else h={eventTime:h,lane:m,tag:l.tag,payload:l.payload,callback:l.callback,next:null},u===null?(d=u=h,c=p):u=u.next=h,o|=m;if(l=l.next,l===null){if(l=i.shared.pending,l===null)break;m=l,l=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(!0);if(u===null&&(c=p),i.baseState=c,i.firstBaseUpdate=d,i.lastBaseUpdate=u,e=i.shared.interleaved,e!==null){i=e;do o|=i.lane,i=i.next;while(i!==e)}else r===null&&(i.shared.lanes=0);Wo|=o,t.lanes=o,t.memoizedState=p}}function x_(t,e,a){if(t=e.effects,e.effects=null,t!==null)for(e=0;e<t.length;e++){var n=t[e],i=n.callback;if(i!==null){if(n.callback=null,n=a,typeof i!="function")throw Error(U(191,i));i.call(n)}}}var Eu={},Yn=Gr(Eu),Hd=Gr(Eu),Fd=Gr(Eu);function bo(t){if(t===Eu)throw Error(U(174));return t}function j1(t,e){switch(Ve(Fd,e),Ve(Hd,t),Ve(Yn,Eu),t=e.nodeType,t){case 9:case 11:e=(e
vendor: 6,847 bytes, line 38
38=e.documentElement)?e.namespaceURI:jx(null,"");break;default:t=t===8?e.parentNode:e,e=t.namespaceURI||null,t=t.tagName,e=jx(e,t)}$e(Yn),Ve(Yn,e)}function gl(){$e(Yn),$e(Hd),$e(Fd)}function mI(t){bo(Fd.current);var e=bo(Yn.current),a=jx(e,t.type);e!==a&&(Ve(Hd,t),Ve(Yn,a))}function T1(t){Hd.current===t&&($e(Yn),$e(Hd))}var Je=Gr(0);function dh(t){for(var e=t;e!==null;){if(e.tag===13){var a=e.memoizedState;if(a!==null&&(a=a.dehydrated,a===null||a.data==="$?"||a.data==="$!"))return e}else if(e.tag===19&&e.memoizedProps.revealOrder!==void 0){if(e.flags&128)return e}else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break;for(;e.sibling===null;){if(e.return===null||e.return===t)return null;e=e.return}e.sibling.return=e.return,e=e.sibling}return null}var Vy=[];function N1(){for(var t=0;t<Vy.length;t++)Vy[t]._workInProgressVersionPrimary=null;Vy.length=0}var gm=Ui.ReactCurrentDispatcher,Hy=Ui.ReactCurrentBatchConfig,$o=0,Ye=null,wt=null,jt=null,uh=!1,ed=!1,Bd=0,Z6=0;function Qt(){throw Error(U(321))}function I1(t,e){if(e===null)return!1;for(var a=0;a<e.length&&a<t.length;a++)if(!Ln(t[a],e[a]))return!1;return!0}function P1(t,e,a,n,i,r){if($o=r,Ye=e,e.memoizedState=null,e.updateQueue=null,e.lanes=0,gm.current=t===null||t.memoizedState===null?nz:iz,t=a(n,i),ed){r=0;do{if(ed=!1,Bd=0,25<=r)throw Error(U(301));r+=1,jt=wt=null,e.updateQueue=null,gm.current=rz,t=a(n,i)}while(ed)}if(gm.current=ph,e=wt!==null&&wt.next!==null,$o=0,jt=wt=Ye=null,uh=!1,e)throw Error(U(300));return t}function R1(){var t=Bd!==0;return Bd=0,t}function Fn(){var t={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return jt===null?Ye.memoizedState=jt=t:jt=jt.next=t,jt}function mn(){if(wt===null){var t=Ye.alternate;t=t!==null?t.memoizedState:null}else t=wt.next;var e=jt===null?Ye.memoizedState:jt.next;if(e!==null)jt=e,wt=t;else{if(t===null)throw Error(U(310));wt=t,t={memoizedState:wt.memoizedState,baseState:wt.baseState,baseQueue:wt.baseQueue,queue:wt.queue,next:null},jt===null?Ye.memoizedState=jt=t:jt=jt.next=t}return jt}function Ud(t,e){return typeof e=="function"?e(t):e}function Fy(t){var e=mn(),a=e.queue;if(a===null)throw Error(U(311));a.lastRenderedReducer=t;var n=wt,i=n.baseQueue,r=a.pending;if(r!==null){if(i!==null){var o=i.next;i.next=r.next,r.next=o}n.baseQueue=i=r,a.pending=null}if(i!==null){r=i.next,n=n.baseState;var l=o=null,c=null,d=r;do{var u=d.lane;if(($o&u)===u)c!==null&&(c=c.next={lane:0,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null}),n=d.hasEagerState?d.eagerState:t(n,d.action);else{var p={lane:u,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null};c===null?(l=c=p,o=n):c=c.next=p,Ye.lanes|=u,Wo|=u}d=d.next}while(d!==null&&d!==r);c===null?o=n:c.next=l,Ln(n,e.memoizedState)||(Aa=!0),e.memoizedState=n,e.baseState=o,e.baseQueue=c,a.lastRenderedState=n}if(t=a.interleaved,t!==null){i=t;do r=i.lane,Ye.lanes|=r,Wo|=r,i=i.next;while(i!==t)}else i===null&&(a.lanes=0);return[e.memoizedState,a.dispatch]}function By(t){var e=mn(),a=e.queue;if(a===null)throw Error(U(311));a.lastRenderedReducer=t;var n=a.dispatch,i=a.pending,r=e.memoizedState;if(i!==null){a.pending=null;var o=i=i.next;do r=t(r,o.action),o=o.next;while(o!==i);Ln(r,e.memoizedState)||(Aa=!0),e.memoizedState=r,e.baseQueue===null&&(e.baseState=r),a.lastRenderedState=r}return[r,n]}function hI(){}function fI(t,e){var a=Ye,n=mn(),i=e(),r=!Ln(n.memoizedState,i);if(r&&(n.memoizedState=i,Aa=!0),n=n.queue,L1(xI.bind(null,a,n,t),[t]),n.getSnapshot!==e||r||jt!==null&&jt.memoizedState.tag&1){if(a.flags|=2048,$d(9,yI.bind(null,a,n,i,e),void 0,null),It===null)throw Error(U(349));$o&30||gI(a,e,i)}return i}function gI(t,e,a){t.flags|=16384,t={getSnapshot:e,value:a},e=Ye.updateQueue,e===null?(e={lastEffect:null,stores:null},Ye.updateQueue=e,e.stores=[t]):(a=e.stores,a===null?e.stores=[t]:a.push(t))}function yI(t,e,a,n){e.value=a,e.getSnapshot=n,vI(e)&&bI(t)}function xI(t,e,a){return a(function(){vI(e)&&bI(t)})}function vI(t){var e=t.getSnapshot;t=t.value;try{var a=e();return!Ln(t,a)}catch{return!0}}function bI(t){var e=Oi(t,1);e!==null&&Nn(e,t,1,-1)}function v_(t){var e=Fn();return typeof t=="function"&&(t=t()),e.memoizedState=e.baseState=t,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Ud,lastRenderedState:t},e.queue=t,t=t.dispatch=az.bind(null,Ye,t),[e.memoizedState,t]}function $d(t,e,a,n){return t={tag:t,create:e,destroy:a,deps:n,next:null},e=Ye.updateQueue,e===null?(e={lastEffect:null,stores:null},Ye.updateQueue=e,e.lastEffect=t.next=t):(a=e.lastEffect,a===null?e.lastEffect=t.next=t:(n=a.next,a.next=t,t.next=n,e.lastEffect=t)),t}function wI(){return mn().memoizedState}function ym(t,e,a,n){var i=Fn();Ye.flags|=t,i.memoizedState=$d(1|e,a,void 0,n===void 0?null:n)}function $f(t,e,a,n){var i=mn();n=n===void 0?null:n;var r=void 0;if(wt!==null){var o=wt.memoizedState;if(r=o.destroy,n!==null&&I1(n,o.deps)){i.memoizedState=$d(e,a,r,n);return}}Ye.flags|=t,i.memoizedState=$d(1|e,a,r,n)}function b_(t,e){return ym(8390656,8,t,e)}function L1(t,e){return $f(2048,8,t,e)}function kI(t,e){return $f(4,2,t,e)}function SI(t,e){return $f(4,4,t,e)}function _I(t,e){if(typeof e=="function")return t=t(),e(t),function(){e(null)};if(e!=null)return t=t(),e.current=t,function(){e.current=null}}function AI(t,e,a){return a=a!=null?a.concat([t]):null,$f(4,4,_I.bind(null,e,t),a)}function O1(){}function EI(t,e){var a=mn();e=e===void 0?null:e;var n=a.memoizedState;return n!==null&&e!==null&&I1(e,n[1])?n[0]:(a.memoizedState=[t,e],t)}function CI(t,e){var a=mn();e=e===void 0?null:e;var n=a.memoizedState;return n!==null&&e!==null&&I1(e,n[1])?n[0]:(t=t(),a.memoizedState=[t,e],t)}function jI(t,e,a){return $o&21?(Ln(a,e)||(a=RN(),Ye.lanes|=a,Wo|=a,t.baseState=!0),e):(t.baseState&&(t.baseState=!1,Aa=!0),t.memoizedState=a)}function ez(t,e){var a=Le;Le=a!==0&&4>a?a:4,t(!0);var n=Hy.transition;Hy.transition={};try{t(!1),e()}finally{Le=a,Hy.transition=n}}function TI(){return mn().memoizedState}function tz(t,e,a){var n=Cr(t);if(a={lane:n,action:a,hasEagerState:!1,eagerState:null,next:null},NI(t))II(e,a);else if(a=uI(t,e,a,n),a!==null){var i=fa();Nn(a,t,n,i),PI(a,e,n)}}function az(t,e,a){var n=Cr(t),i={lane:n,action:a,hasEagerState:!1,eagerState:null,next:null};if(NI(t))II(e,i);else{var r=t.alternate;if(t.lanes===0&&(r===null||r.lanes===0)&&(r=e.lastRenderedReducer,r!==null))try{var o=e.lastRenderedState,l=r(o,a);if(i.hasEagerState=!0,i.eagerState=l,Ln(l,o)){var c=e.interleaved;c===null?(i.next=i,E1(e)):(i.next=c.next,c.next=i),e.interleaved=i;return}}catch{}finally{}a=uI(t,e,i,n),a!==null&&(i=fa(),Nn(a,t,n,i),PI(a,e,n))}}function NI(t){var e=t.alternate;return t===Ye||e!==null&&e===Ye}function II(t,e){ed=uh=!0;var a=t.pending;a===null?e.next=e:(e.next=a.next,a.next=e),t.pending=e}function PI(t,e,a){if(a&4194240){var n=e.lanes;
vendor: 8,339 bytes, lines 38-40
38n&=t.pendingLanes,a|=n,e.lanes=a,p1(t,a)}}var ph={readContext:pn,useCallback:Qt,useContext:Qt,useEffect:Qt,useImperativeHandle:Qt,useInsertionEffect:Qt,useLayoutEffect:Qt,useMemo:Qt,useReducer:Qt,useRef:Qt,useState:Qt,useDebugValue:Qt,useDeferredValue:Qt,useTransition:Qt,useMutableSource:Qt,useSyncExternalStore:Qt,useId:Qt,unstable_isNewReconciler:!1},nz={readContext:pn,useCallback:function(t,e){return Fn().memoizedState=[t,e===void 0?null:e],t},useContext:pn,useEffect:b_,useImperativeHandle:function(t,e,a){return a=a!=null?a.concat([t]):null,ym(4194308,4,_I.bind(null,e,t),a)},useLayoutEffect:function(t,e){return ym(4194308,4,t,e)},useInsertionEffect:function(t,e){return ym(4,2,t,e)},useMemo:function(t,e){var a=Fn();return e=e===void 0?null:e,t=t(),a.memoizedState=[t,e],t},useReducer:function(t,e,a){var n=Fn();return e=a!==void 0?a(e):e,n.memoizedState=n.baseState=e,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:e},n.queue=t,t=t.dispatch=tz.bind(null,Ye,t),[n.memoizedState,t]},useRef:function(t){var e=Fn();return t={current:t},e.memoizedState=t},useState:v_,useDebugValue:O1,useDeferredValue:function(t){return Fn().memoizedState=t},useTransition:function(){var t=v_(!1),e=t[0];return t=ez.bind(null,t[1]),Fn().memoizedState=t,[e,t]},useMutableSource:function(){},useSyncExternalStore:function(t,e,a){var n=Ye,i=Fn();if(Ge){if(a===void 0)throw Error(U(407));a=a()}else{if(a=e(),It===null)throw Error(U(349));$o&30||gI(n,e,a)}i.memoizedState=a;var r={value:a,getSnapshot:e};return i.queue=r,b_(xI.bind(null,n,r,t),[t]),n.flags|=2048,$d(9,yI.bind(null,n,r,a,e),void 0,null),a},useId:function(){var t=Fn(),e=It.identifierPrefix;if(Ge){var a=bi,n=vi;a=(n&~(1<<32-Tn(n)-1)).toString(32)+a,e=":"+e+"R"+a,a=Bd++,0<a&&(e+="H"+a.toString(32)),e+=":"}else a=Z6++,e=":"+e+"r"+a.toString(32)+":";return t.memoizedState=e},unstable_isNewReconciler:!1},iz={readContext:pn,useCallback:EI,useContext:pn,useEffect:L1,useImperativeHandle:AI,useInsertionEffect:kI,useLayoutEffect:SI,useMemo:CI,useReducer:Fy,useRef:wI,useState:function(){return Fy(Ud)},useDebugValue:O1,useDeferredValue:function(t){var e=mn();return jI(e,wt.memoizedState,t)},useTransition:function(){var t=Fy(Ud)[0],e=mn().memoizedState;return[t,e]},useMutableSource:hI,useSyncExternalStore:fI,useId:TI,unstable_isNewReconciler:!1},rz={readContext:pn,useCallback:EI,useContext:pn,useEffect:L1,useImperativeHandle:AI,useInsertionEffect:kI,useLayoutEffect:SI,useMemo:CI,useReducer:By,useRef:wI,useState:function(){return By(Ud)},useDebugValue:O1,useDeferredValue:function(t){var e=mn();return wt===null?e.memoizedState=t:jI(e,wt.memoizedState,t)},useTransition:function(){var t=By(Ud)[0],e=mn().memoizedState;return[t,e]},useMutableSource:hI,useSyncExternalStore:fI,useId:TI,unstable_isNewReconciler:!1};function kn(t,e){if(t&&t.defaultProps){e=Ze({},e),t=t.defaultProps;for(var a in t)e[a]===void 0&&(e[a]=t[a]);return e}return e}function Jx(t,e,a,n){e=t.memoizedState,a=a(n,e),a=a==null?e:Ze({},e,a),t.memoizedState=a,t.lanes===0&&(t.updateQueue.baseState=a)}var Wf={isMounted:function(t){return(t=t._reactInternals)?cs(t)===t:!1},enqueueSetState:function(t,e,a){t=t._reactInternals;var n=fa(),i=Cr(t),r=Ei(n,i);r.payload=e,a!=null&&(r.callback=a),e=Ar(t,r,i),e!==null&&(Nn(e,t,i,n),fm(e,t,i))},enqueueReplaceState:function(t,e,a){t=t._reactInternals;var n=fa(),i=Cr(t),r=Ei(n,i);r.tag=1,r.payload=e,a!=null&&(r.callback=a),e=Ar(t,r,i),e!==null&&(Nn(e,t,i,n),fm(e,t,i))},enqueueForceUpdate:function(t,e){t=t._reactInternals;var a=fa(),n=Cr(t),i=Ei(a,n);i.tag=2,e!=null&&(i.callback=e),e=Ar(t,i,n),e!==null&&(Nn(e,t,n,a),fm(e,t,n))}};function w_(t,e,a,n,i,r,o){return t=t.stateNode,typeof t.shouldComponentUpdate=="function"?t.shouldComponentUpdate(n,r,o):e.prototype&&e.prototype.isPureReactComponent?!Dd(a,n)||!Dd(i,r):!0}function RI(t,e,a){var n=!1,i=qr,r=e.contextType;return typeof r=="object"&&r!==null?r=pn(r):(i=Ca(e)?Bo:ia.current,n=e.contextTypes,r=(n=n!=null)?ml(t,i):qr),e=new e(a,r),t.memoizedState=e.state!==null&&e.state!==void 0?e.state:null,e.updater=Wf,t.stateNode=e,e._reactInternals=t,n&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=i,t.__reactInternalMemoizedMaskedChildContext=r),e}function k_(t,e,a,n){t=e.state,typeof e.componentWillReceiveProps=="function"&&e.componentWillReceiveProps(a,n),typeof e.UNSAFE_componentWillReceiveProps=="function"&&e.UNSAFE_componentWillReceiveProps(a,n),e.state!==t&&Wf.enqueueReplaceState(e,e.state,null)}function Qx(t,e,a,n){var i=t.stateNode;i.props=a,i.state=t.memoizedState,i.refs={},C1(t);var r=e.contextType;typeof r=="object"&&r!==null?i.context=pn(r):(r=Ca(e)?Bo:ia.current,i.context=ml(t,r)),i.state=t.memoizedState,r=e.getDerivedStateFromProps,typeof r=="function"&&(Jx(t,e,r,a),i.state=t.memoizedState),typeof e.getDerivedStateFromProps=="function"||typeof i.getSnapshotBeforeUpdate=="function"||typeof i.UNSAFE_componentWillMount!="function"&&typeof i.componentWillMount!="function"||(e=i.state,typeof i.componentWillMount=="function"&&i.componentWillMount(),typeof i.UNSAFE_componentWillMount=="function"&&i.UNSAFE_componentWillMount(),e!==i.state&&Wf.enqueueReplaceState(i,i.state,null),ch(t,a,i,n),i.state=t.memoizedState),typeof i.componentDidMount=="function"&&(t.flags|=4194308)}function yl(t,e){try{var a="",n=e;do a+=Rq(n),n=n.return;while(n);var i=a}catch(r){i=` 39Error generating stack: `+r.message+` 40`+r.stack}return{value:t,source:e,stack:i,digest:null}}function Uy(t,e,a){return{value:t,source:null,stack:a??null,digest:e??null}}function Xx(t,e){try{console.error(e.value)}catch(a){setTimeout(function(){throw a})}}var oz=typeof WeakMap=="function"?WeakMap:Map;function LI(t,e,a){a=Ei(-1,a),a.tag=3,a.payload={element:null};var n=e.value;return a.callback=function(){hh||(hh=!0,sv=n),Xx(t,e)},a}function OI(t,e,a){a=Ei(-1,a),a.tag=3;var n=t.type.getDerivedStateFromError;if(typeof n=="function"){var i=e.value;a.payload=function(){return n(i)},a.callback=function(){Xx(t,e)}}var r=t.stateNode;return r!==null&&typeof r.componentDidCatch=="function"&&(a.callback=function(){Xx(t,e),typeof n!="function"&&(Er===null?Er=new Set([this]):Er.add(this));var o=e.stack;this.componentDidCatch(e.value,{componentStack:o!==null?o:""})}),a}function S_(t,e,a){var n=t.pingCache;if(n===null){n=t.pingCache=new oz;var i=new Set;n.set(e,i)}else i=n.get(e),i===void 0&&(i=new Set,n.set(e,i));i.has(a)||(i.add(a),t=bz.bind(null,t,e,a),e.then(t,t))}function __(t){do{var e;if((e=t.tag===13)&&(e=t.memoizedState,e=e!==null?e.dehydrated!==null:!0),e)return t;t=t.return}while(t!==null);return null}function A_(t,e,a,n,i){return t.mode&1?(t.flags|=65536,t.lanes=i,t):(t===e?t.flags|=65536:(t.flags|=128,a.flags|=131072,a.flags&=-52805,a.tag===1&&(a.alternate===null?a.tag=17:(e=Ei(-1,1),e.tag=2,Ar(a,e,1))),a.lanes|=1),t)}var sz=Ui.ReactCurrentOwner,Aa=!1;function ua(t,e,a,n){e.child=t===null?dI(e,null,a,n):fl(e,t.child,a,n)}function E_(t,e,a,n,i){a=a.render;var r=e.ref;return tl(e,i),n=P1(t,e,a,n,r,i),a=R1(),t!==null&&!Aa?(e.updateQueue=t.updateQueue,e.flags&=-2053,t.lanes&=~i,Mi(t,e,i)):(Ge&&a&&b1(e),e.flags|=1,ua(t,e,n,i),e.child)}function C_(t,e,a,n,i){if(t===null){var r=a.type;return typeof r=="function"&&!B1(r)&&r.defaultProps===void 0&&a.compare===null&&a.defaultProps===void 0?(e.tag=15,e.type=r,MI(t,e,r,n,i)):(t=wm(a.type,null,n,e,e.mode,i),t.ref=e.ref,t.return=e,e.child=t)}if(r=t.child,!(t.lanes&i)){var o=r.memoizedProps;if(a=a.compare,a=a!==null?a:Dd,a(o,n)&&t.ref===e.ref)return Mi(t,e,i)}return e.flags|=1,t=jr(r,n),t.ref=e.ref,t.return=e,e.child=t}function MI(t,e,a,n,i){if(t!==null){var r=t.memoizedProps;if(Dd(r,n)&&t.ref===e.ref)if(Aa=!1,e.pendingProps=n=r,(t.lanes&i)!==0)t.flags&131072&&(Aa=!0);else return e.lanes=t.lanes,Mi(t,e,i)}return Yx(t,e,a,n,i)}function DI(t,e,a){var n=e.pendingProps,i=n.children,r=t!==null?t.memoizedState:null;if(n.mode==="hidden")if(!(e.mode&1))e.memoizedState={baseLanes:0,cachePool:null,transitions:null},Ve(Us,Da),Da|=a;else{if(!(a&1073741824))return t=r!==null?r.baseLanes|a:a,e.lanes=e.childLanes=1073741824,e.memoizedState={baseLanes:t,cachePool:null,transitions:null},e.updateQueue=null,Ve(Us,Da),Da|=t,null;e.memoizedState={baseLanes:0,cachePool:null,transitions:null},n=r!==null?r.baseLanes:a,Ve(Us,Da),Da|=n}else r!==null?(n=r.baseLanes|a,e.memoizedState=null):n=a,Ve(Us,Da),Da|=n;
vendor: 4,972 bytes, line 40
40return ua(t,e,i,a),e.child}function qI(t,e){var a=e.ref;(t===null&&a!==null||t!==null&&t.ref!==a)&&(e.flags|=512,e.flags|=2097152)}function Yx(t,e,a,n,i){var r=Ca(a)?Bo:ia.current;return r=ml(e,r),tl(e,i),a=P1(t,e,a,n,r,i),n=R1(),t!==null&&!Aa?(e.updateQueue=t.updateQueue,e.flags&=-2053,t.lanes&=~i,Mi(t,e,i)):(Ge&&n&&b1(e),e.flags|=1,ua(t,e,a,i),e.child)}function j_(t,e,a,n,i){if(Ca(a)){var r=!0;ih(e)}else r=!1;if(tl(e,i),e.stateNode===null)xm(t,e),RI(e,a,n),Qx(e,a,n,i),n=!0;else if(t===null){var o=e.stateNode,l=e.memoizedProps;o.props=l;var c=o.context,d=a.contextType;typeof d=="object"&&d!==null?d=pn(d):(d=Ca(a)?Bo:ia.current,d=ml(e,d));var u=a.getDerivedStateFromProps,p=typeof u=="function"||typeof o.getSnapshotBeforeUpdate=="function";p||typeof o.UNSAFE_componentWillReceiveProps!="function"&&typeof o.componentWillReceiveProps!="function"||(l!==n||c!==d)&&k_(e,o,n,d),ar=!1;var m=e.memoizedState;o.state=m,ch(e,n,o,i),c=e.memoizedState,l!==n||m!==c||Ea.current||ar?(typeof u=="function"&&(Jx(e,a,u,n),c=e.memoizedState),(l=ar||w_(e,a,l,n,m,c,d))?(p||typeof o.UNSAFE_componentWillMount!="function"&&typeof o.componentWillMount!="function"||(typeof o.componentWillMount=="function"&&o.componentWillMount(),typeof o.UNSAFE_componentWillMount=="function"&&o.UNSAFE_componentWillMount()),typeof o.componentDidMount=="function"&&(e.flags|=4194308)):(typeof o.componentDidMount=="function"&&(e.flags|=4194308),e.memoizedProps=n,e.memoizedState=c),o.props=n,o.state=c,o.context=d,n=l):(typeof o.componentDidMount=="function"&&(e.flags|=4194308),n=!1)}else{o=e.stateNode,pI(t,e),l=e.memoizedProps,d=e.type===e.elementType?l:kn(e.type,l),o.props=d,p=e.pendingProps,m=o.context,c=a.contextType,typeof c=="object"&&c!==null?c=pn(c):(c=Ca(a)?Bo:ia.current,c=ml(e,c));var h=a.getDerivedStateFromProps;(u=typeof h=="function"||typeof o.getSnapshotBeforeUpdate=="function")||typeof o.UNSAFE_componentWillReceiveProps!="function"&&typeof o.componentWillReceiveProps!="function"||(l!==p||m!==c)&&k_(e,o,n,c),ar=!1,m=e.memoizedState,o.state=m,ch(e,n,o,i);var g=e.memoizedState;l!==p||m!==g||Ea.current||ar?(typeof h=="function"&&(Jx(e,a,h,n),g=e.memoizedState),(d=ar||w_(e,a,d,n,m,g,c)||!1)?(u||typeof o.UNSAFE_componentWillUpdate!="function"&&typeof o.componentWillUpdate!="function"||(typeof o.componentWillUpdate=="function"&&o.componentWillUpdate(n,g,c),typeof o.UNSAFE_componentWillUpdate=="function"&&o.UNSAFE_componentWillUpdate(n,g,c)),typeof o.componentDidUpdate=="function"&&(e.flags|=4),typeof o.getSnapshotBeforeUpdate=="function"&&(e.flags|=1024)):(typeof o.componentDidUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=4),typeof o.getSnapshotBeforeUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=1024),e.memoizedProps=n,e.memoizedState=g),o.props=n,o.state=g,o.context=c,n=d):(typeof o.componentDidUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=4),typeof o.getSnapshotBeforeUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=1024),n=!1)}return Zx(t,e,a,n,r,i)}function Zx(t,e,a,n,i,r){qI(t,e);var o=(e.flags&128)!==0;if(!n&&!o)return i&&m_(e,a,!1),Mi(t,e,r);n=e.stateNode,sz.current=e;var l=o&&typeof a.getDerivedStateFromError!="function"?null:n.render();return e.flags|=1,t!==null&&o?(e.child=fl(e,t.child,null,r),e.child=fl(e,null,l,r)):ua(t,e,l,r),e.memoizedState=n.state,i&&m_(e,a,!0),e.child}function zI(t){var e=t.stateNode;e.pendingContext?p_(t,e.pendingContext,e.pendingContext!==e.context):e.context&&p_(t,e.context,!1),j1(t,e.containerInfo)}function T_(t,e,a,n,i){return hl(),k1(i),e.flags|=256,ua(t,e,a,n),e.child}var ev={dehydrated:null,treeContext:null,retryLane:0};function tv(t){return{baseLanes:t,cachePool:null,transitions:null}}function VI(t,e,a){var n=e.pendingProps,i=Je.current,r=!1,o=(e.flags&128)!==0,l;if((l=o)||(l=t!==null&&t.memoizedState===null?!1:(i&2)!==0),l?(r=!0,e.flags&=-129):(t===null||t.memoizedState!==null)&&(i|=1),Ve(Je,i&1),t===null)return Gx(e),t=e.memoizedState,t!==null&&(t=t.dehydrated,t!==null)?(e.mode&1?t.data==="$!"?e.lanes=8:e.lanes=1073741824:e.lanes=1,null):(o=n.children,t=n.fallback,r?(n=e.mode,r=e.child,o={mode:"hidden",children:o},!(n&1)&&r!==null?(r.childLanes=0,r.pendingProps=o):r=Jf(o,n,0,null),t=Po(t,n,a,null),r.return=e,t.return=e,r.sibling=t,e.child=r,e.child.memoizedState=tv(a),e.memoizedState=ev,t):M1(e,o));if(i=t.memoizedState,i!==null&&(l=i.dehydrated,l!==null))return lz(t,e,o,n,l,i,a);if(r){r=n.fallback,o=e.mode,i=t.child,l=i.sibling;var c={mode:"hidden",children:n.children};return!(o&1)&&e.child!==i?(n=e.child,n.childLanes=0,n.pendingProps=c,e.deletions=null):(n=jr(i,c),n.subtreeFlags=i.subtreeFlags&14680064),l!==null?r=jr(l,r):(r=Po(r,o,a,null),r.flags|=2),r.return=e,n.return=e,n.sibling=r,e.child=n,n=r,r=e.child,o=t.child.memoizedState,o=o===null?tv(a):{baseLanes:o.baseLanes|a,cachePool:null,transitions:o.transitions},r.memoizedState=o,r.childLanes=t.childLanes&~a,e.memoizedState=ev,n}
vendor: 8,788 bytes, line 40
40return r=t.child,t=r.sibling,n=jr(r,{mode:"visible",children:n.children}),!(e.mode&1)&&(n.lanes=a),n.return=e,n.sibling=null,t!==null&&(a=e.deletions,a===null?(e.deletions=[t],e.flags|=16):a.push(t)),e.child=n,e.memoizedState=null,n}function M1(t,e){return e=Jf({mode:"visible",children:e},t.mode,0,null),e.return=t,t.child=e}function jp(t,e,a,n){return n!==null&&k1(n),fl(e,t.child,null,a),t=M1(e,e.pendingProps.children),t.flags|=2,e.memoizedState=null,t}function lz(t,e,a,n,i,r,o){if(a)return e.flags&256?(e.flags&=-257,n=Uy(Error(U(422))),jp(t,e,o,n)):e.memoizedState!==null?(e.child=t.child,e.flags|=128,null):(r=n.fallback,i=e.mode,n=Jf({mode:"visible",children:n.children},i,0,null),r=Po(r,i,o,null),r.flags|=2,n.return=e,r.return=e,n.sibling=r,e.child=n,e.mode&1&&fl(e,t.child,null,o),e.child.memoizedState=tv(o),e.memoizedState=ev,r);if(!(e.mode&1))return jp(t,e,o,null);if(i.data==="$!"){if(n=i.nextSibling&&i.nextSibling.dataset,n)var l=n.dgst;return n=l,r=Error(U(419)),n=Uy(r,n,void 0),jp(t,e,o,n)}if(l=(o&t.childLanes)!==0,Aa||l){if(n=It,n!==null){switch(o&-o){case 4:i=2;break;case 16:i=8;break;case 64: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:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:i=32;break;case 536870912:i=268435456;break;default:i=0}i=i&(n.suspendedLanes|o)?0:i,i!==0&&i!==r.retryLane&&(r.retryLane=i,Oi(t,i),Nn(n,t,i,-1))}return F1(),n=Uy(Error(U(421))),jp(t,e,o,n)}return i.data==="$?"?(e.flags|=128,e.child=t.child,e=wz.bind(null,t),i._reactRetry=e,null):(t=r.treeContext,za=_r(i.nextSibling),Fa=e,Ge=!0,_n=null,t!==null&&(nn[rn++]=vi,nn[rn++]=bi,nn[rn++]=Uo,vi=t.id,bi=t.overflow,Uo=e),e=M1(e,n.children),e.flags|=4096,e)}function N_(t,e,a){t.lanes|=e;var n=t.alternate;n!==null&&(n.lanes|=e),Kx(t.return,e,a)}function $y(t,e,a,n,i){var r=t.memoizedState;r===null?t.memoizedState={isBackwards:e,rendering:null,renderingStartTime:0,last:n,tail:a,tailMode:i}:(r.isBackwards=e,r.rendering=null,r.renderingStartTime=0,r.last=n,r.tail=a,r.tailMode=i)}function HI(t,e,a){var n=e.pendingProps,i=n.revealOrder,r=n.tail;if(ua(t,e,n.children,a),n=Je.current,n&2)n=n&1|2,e.flags|=128;else{if(t!==null&&t.flags&128)e:for(t=e.child;t!==null;){if(t.tag===13)t.memoizedState!==null&&N_(t,a,e);else if(t.tag===19)N_(t,a,e);else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break e;for(;t.sibling===null;){if(t.return===null||t.return===e)break e;t=t.return}t.sibling.return=t.return,t=t.sibling}n&=1}if(Ve(Je,n),!(e.mode&1))e.memoizedState=null;else switch(i){case"forwards":for(a=e.child,i=null;a!==null;)t=a.alternate,t!==null&&dh(t)===null&&(i=a),a=a.sibling;a=i,a===null?(i=e.child,e.child=null):(i=a.sibling,a.sibling=null),$y(e,!1,i,a,r);break;case"backwards":for(a=null,i=e.child,e.child=null;i!==null;){if(t=i.alternate,t!==null&&dh(t)===null){e.child=i;break}t=i.sibling,i.sibling=a,a=i,i=t}$y(e,!0,a,null,r);break;case"together":$y(e,!1,null,null,void 0);break;default:e.memoizedState=null}return e.child}function xm(t,e){!(e.mode&1)&&t!==null&&(t.alternate=null,e.alternate=null,e.flags|=2)}function Mi(t,e,a){if(t!==null&&(e.dependencies=t.dependencies),Wo|=e.lanes,!(a&e.childLanes))return null;if(t!==null&&e.child!==t.child)throw Error(U(153));if(e.child!==null){for(t=e.child,a=jr(t,t.pendingProps),e.child=a,a.return=e;t.sibling!==null;)t=t.sibling,a=a.sibling=jr(t,t.pendingProps),a.return=e;a.sibling=null}return e.child}function cz(t,e,a){switch(e.tag){case 3:zI(e),hl();break;case 5:mI(e);break;case 1:Ca(e.type)&&ih(e);break;case 4:j1(e,e.stateNode.containerInfo);break;case 10:var n=e.type._context,i=e.memoizedProps.value;Ve(sh,n._currentValue),n._currentValue=i;break;case 13:if(n=e.memoizedState,n!==null)return n.dehydrated!==null?(Ve(Je,Je.current&1),e.flags|=128,null):a&e.child.childLanes?VI(t,e,a):(Ve(Je,Je.current&1),t=Mi(t,e,a),t!==null?t.sibling:null);Ve(Je,Je.current&1);break;case 19:if(n=(a&e.childLanes)!==0,t.flags&128){if(n)return HI(t,e,a);e.flags|=128}if(i=e.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),Ve(Je,Je.current),n)break;return null;case 22:case 23:return e.lanes=0,DI(t,e,a)}return Mi(t,e,a)}var FI,av,BI,UI;FI=function(t,e){for(var a=e.child;a!==null;){if(a.tag===5||a.tag===6)t.appendChild(a.stateNode);else if(a.tag!==4&&a.child!==null){a.child.return=a,a=a.child;continue}if(a===e)break;for(;a.sibling===null;){if(a.return===null||a.return===e)return;a=a.return}a.sibling.return=a.return,a=a.sibling}};av=function(){};BI=function(t,e,a,n){var i=t.memoizedProps;if(i!==n){t=e.stateNode,bo(Yn.current);var r=null;switch(a){case"input":i=_x(t,i),n=_x(t,n),r=[];break;case"select":i=Ze({},i,{value:void 0}),n=Ze({},n,{value:void 0}),r=[];break;case"textarea":i=Cx(t,i),n=Cx(t,n),r=[];break;default:typeof i.onClick!="function"&&typeof n.onClick=="function"&&(t.onclick=ah)}Tx(a,n);var o;a=null;for(d in i)if(!n.hasOwnProperty(d)&&i.hasOwnProperty(d)&&i[d]!=null)if(d==="style"){var l=i[d];for(o in l)l.hasOwnProperty(o)&&(a||(a={}),a[o]="")}else d!=="dangerouslySetInnerHTML"&&d!=="children"&&d!=="suppressContentEditableWarning"&&d!=="suppressHydrationWarning"&&d!=="autoFocus"&&(Nd.hasOwnProperty(d)?r||(r=[]):(r=r||[]).push(d,null));for(d in n){var c=n[d];if(l=i!=null?i[d]:void 0,n.hasOwnProperty(d)&&c!==l&&(c!=null||l!=null))if(d==="style")if(l){for(o in l)!l.hasOwnProperty(o)||c&&c.hasOwnProperty(o)||(a||(a={}),a[o]="");for(o in c)c.hasOwnProperty(o)&&l[o]!==c[o]&&(a||(a={}),a[o]=c[o])}else a||(r||(r=[]),r.push(d,a)),a=c;else d==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,l=l?l.__html:void 0,c!=null&&l!==c&&(r=r||[]).push(d,c)):d==="children"?typeof c!="string"&&typeof c!="number"||(r=r||[]).push(d,""+c):d!=="suppressContentEditableWarning"&&d!=="suppressHydrationWarning"&&(Nd.hasOwnProperty(d)?(c!=null&&d==="onScroll"&&Fe("scroll",t),r||l===c||(r=[])):(r=r||[]).push(d,c))}a&&(r=r||[]).push("style",a);var d=r;(e.updateQueue=d)&&(e.flags|=4)}};UI=function(t,e,a,n){a!==n&&(e.flags|=4)};function bc(t,e){if(!Ge)switch(t.tailMode){case"hidden":e=t.tail;for(var a=null;e!==null;)e.alternate!==null&&(a=e),e=e.sibling;a===null?t.tail=null:a.sibling=null;break;case"collapsed":a=t.tail;for(var n=null;a!==null;)a.alternate!==null&&(n=a),a=a.sibling;n===null?e||t.tail===null?t.tail=null:t.tail.sibling=null:n.sibling=null}}function Xt(t){var e=t.alternate!==null&&t.alternate.child===t.child,a=0,n=0;if(e)for(var i=t.child;i!==null;)a|=i.lanes|i.childLanes,n|=i.subtreeFlags&14680064,n|=i.flags&14680064,i.return=t,i=i.sibling;else for(i=t.child;i!==null;)a|=i.lanes|i.childLanes,n|=i.subtreeFlags,n|=i.flags,i.return=t,i=i.sibling;return t.subtreeFlags|=n,t.childLanes=a,e}function dz(t,e,a){var n=e.pendingProps;switch(w1(e),e.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Xt(e),null;case 1:return Ca(e.type)&&nh(),Xt(e),null;case 3:return n=e.stateNode,gl(),$e(Ea),$e(ia),N1(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(t===null||t.child===null)&&(Ep(e)?e.flags|=4:t===null||t.memoizedState.isDehydrated&&!(e.flags&256)||(e.flags|=1024,_n!==null&&(dv(_n),_n=null))),av(t,e),Xt(e),null;case 5:T1(e);var i=bo(Fd.current);if(a=e.type,t!==null&&e.stateNode!=null)BI(t,e,a,n,i),t.ref!==e.ref&&(e.flags|=512,e.flags|=2097152);else{if(!n){if(e.stateNode===null)throw Error(U(166));return Xt(e),null}if(t=bo(Yn.current),Ep(e)){n=e.stateNode,a=e.type;var r=e.memoizedProps;switch(n[Wn]=e,n[Vd]=r,t=(e.mode&1)!==0,a){case"dialog":Fe("cancel",n),Fe("close",n);break;case"iframe":case"object":case"embed":Fe("load",n);break;case"video":case"audio":for(i=0;i<Dc.length;i++)Fe(Dc[i],n);break;case"source":Fe("error",n);break;case"img":case"image":case"link":Fe("error",n),Fe("load",n);break;case"details":Fe("toggle",n);break;case"input":z2(n,r),Fe("invalid",n);break;case"select":n._wrapperState={wasMultiple:!!r.multiple},Fe("invalid",n);break;case"textarea":H2(n,r),Fe("invalid",n)}Tx(a,r),i=null;for(var o in r)if(r.hasOwnProperty(o)){var l=r[o];o==="children"?typeof l=="string"?n.textContent!==l&&(r.suppressHydrationWarning!==!0&&Ap(n.textContent,l,t),i=["children",l]):typeof l=="number"&&n.textContent!==""+l&&(r.suppressHydrationWarning!==!0&&Ap(n.textContent,l,t),i=["children",""+l]):Nd.hasOwnProperty(o)&&l!=null&&o==="onScroll"&&Fe("scroll",n)}switch(a){case"input":yp(n),V2(n,r,!0);break;case"textarea":yp(n),F2(n);break;case"select":case"option":break;default:typeof r.onClick=="function"&&(n.onclick=ah)}n=i,e.updateQueue=n,n!==null&&(e.flags|=4)}else{o=i.nodeType===9?i:i.ownerDocument,t==="http://www.w3.org/1999/xhtml"&&(t=xN(a)),t==="http://www.w3.org/1999/xhtml"?a==="script"?(t=o.createElement("div"),t.innerHTML="<script><\/script>
40",t=t.removeChild(t.firstChild)):typeof n.is=="string"?t=o.createElement(a,{is:n.is}):(t=o.createElement(a),a==="select"&&(o=t,n.multiple?o.multiple=!0:n.size&&(o.size=n.size))):t=o.createElementNS(t,a),t[Wn]=e,t[Vd]=n,FI(t,e,!1,!1),e.stateNode=t;e:{switch(o=Nx(a,n),a){case"dialog":Fe("cancel",t),Fe("close",t),i=n;break;case"iframe":case"object":case"embed":Fe("load",t),i=n;break;case"video":case"audio":for(i=0;i<Dc.length;i++)Fe(Dc[i],t);i=n;break;case"source":Fe("error",t),i=n;break;case"img":case"image":case"link":Fe("error",t),Fe("load",t),i=n;break;case"details":Fe("toggle",t),i=n;break;case"input":z2(t,n),i=_x(t,n),Fe("invalid",t);break;case"option":i=n;break;case"select":t._wrapperState={wasMultiple:!!n.multiple},i=Ze({},n,{value:void 0}),Fe("invalid",t);break;case"textarea":H2(t,n),i=Cx(t,n),Fe("invalid",t);break;default:i=n}Tx(a,i),l=i;for(r in l)if(l.hasOwnProperty(r)){var c=l[r];r==="style"?wN(t,c):r==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,c!=null&&vN(t,c)):r==="children"?typeof c=="string"?(a!=="textarea"||c!=="")&&Id(t,c):typeof c=="number"&&Id(t,""+c):r!=="suppressContentEditableWarning"&&r!=="suppressHydrationWarning"&&r!=="autoFocus"&&(Nd.hasOwnProperty(r)?c!=null&&r==="onScroll"&&Fe("scroll",t):c!=null&&o1(t,r,c,o))}switch(a){case"input":yp(t),V2(t,n,!1);break;case"textarea":yp(t),F2(t);break;case"option":n.value!=null&&t.setAttribute("value",""+Dr(n.value));break;case"select":t.multiple=!!n.multiple,r=n.value,r!=null?Xs(t,!!n.multiple,r,!1):n.defaultValue!=null&&Xs(t,!!n.multiple,n.defaultValue,!0);break;default:typeof i.onClick=="function"&&(t.onclick=ah)}switch(a){case"button":case"input":case"select":case"textarea":n=!!n.autoFocus;break e;case"img":n=!0;break e;default:n=!1}}n&&(e.flags|=4)}e.ref!==null&&(e.flags|=512,e.flags|=2097152)}return Xt(e),null;case 6:if(t&&e.stateNode!=null)UI(t,e,t.memoizedProps,n);else{if(typeof n!="string"&&e.stateNode===null)throw Error(U(166));if(a=bo(Fd.current),bo(Yn.current),Ep(e)){if(n=e.stateNode,a=e.memoizedProps,n[Wn]=e,(r=n.nodeValue!==a)&&(t=Fa,t!==null))switch(t.tag){case 3:Ap(n.nodeValue,a,(t.mode&1)!==0);break;case 5:t.memoizedProps.suppressHydrationWarning!==!0&&Ap(n.nodeValue,a,(t.mode&1)!==0)}r&&(e.flags|=4)}else n=(a.nodeType===9?a:a.ownerDocument).createTextNode(n),n[Wn]=e,e.stateNode=n}return Xt(e),null;case 13:if($e(Je),n=e.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(Ge&&za!==null&&e.mode&1&&!(e.flags&128))lI(),hl(),e.flags|=98560,r=!1;else if(r=Ep(e),n!==null&&n.dehydrated!==null){if(t===null){if(!r)throw Error(U(318));if(r=e.memoizedState,r=r!==null?r.dehydrated:null,!r)throw Error(U(317));r[Wn]=e}else hl(),!(e.flags&128)&&(e.memoizedState=null),e.flags|=4;Xt(e),r=!1}else _n!==null&&(dv(_n),_n=null),r=!0;if(!r)return e.flags&65536?e:null}return e.flags&128?(e.lanes=a,e):(n=n!==null,n!==(t!==null&&t.memoizedState!==null)&&n&&(e.child.flags|=8192,e.mode&1&&(t===null||Je.current&1?kt===0&&(kt=3):F1())),e.updateQueue!==null&&(e.flags|=4),Xt(e),null);case 4:return gl(),av(t,e),t===null&&qd(e.stateNode.containerInfo),Xt(e),null;case 10:return A1(e.type._context),Xt(e),null;case 17:return Ca(e.type)&&nh(),Xt(e),null;case 19:if($e(Je),r=e.memoizedState,r===null)return Xt(e),null;if(n=(e.flags&128)!==0,o=r.rendering,o===null)if(n)bc(r,!1);else{if(kt!==0||t!==null&&t.flags&128)for(t=e.child;t!==null;){if(o=dh(t),o!==null){for(e.flags|=128,bc(r,!1),n=o.updateQueue,n!==null&&(e.updateQueue=n,e.flags|=4),e.subtreeFlags=0,n=a,a=e.child;a!==null;)r=a,t=n,r.flags&=14680066,o=r.alternate,o===null?(r.childLanes=0,r.lanes=t,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=o.childLanes,r.lanes=o.lanes,r.child=o.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=o.memoizedProps,r.memoizedState=o.memoizedState,r.updateQueue=o.updateQueue,r.type=o.type,t=o.dependencies,r.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext}),a=a.sibling;return Ve(Je,Je.current&1|2),e.child}t=t.sibling}r.tail!==null&&pt()>xl&&(e.flags|=128,n=!0,bc(r,!1),e.lanes=4194304)}else{if(!n)if(t=dh(o),t!==null){if(e.flags|=128,n=!0,a=t.updateQueue,a!==null&&(e.updateQueue=a,e.flags|=4),bc(r,!0),r.tail===null&&r.tailMode==="hidden"&&!o.alternate&&!Ge)return Xt(e),null}else 2*pt()-r.renderingStartTime>xl&&a!==1073741824&&(e.flags|=128,n=!0,bc(r,!1),e.lanes=4194304);r.isBackwards?(o.sibling=e.child,e.child=o):(a=r.last,a!==null?a.sibling=o:e.child=o,r.last=o
vendor: 24,891 bytes, line 40
40)}return r.tail!==null?(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=pt(),e.sibling=null,a=Je.current,Ve(Je,n?a&1|2:a&1),e):(Xt(e),null);case 22:case 23:return H1(),n=e.memoizedState!==null,t!==null&&t.memoizedState!==null!==n&&(e.flags|=8192),n&&e.mode&1?Da&1073741824&&(Xt(e),e.subtreeFlags&6&&(e.flags|=8192)):Xt(e),null;case 24:return null;case 25:return null}throw Error(U(156,e.tag))}function uz(t,e){switch(w1(e),e.tag){case 1:return Ca(e.type)&&nh(),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return gl(),$e(Ea),$e(ia),N1(),t=e.flags,t&65536&&!(t&128)?(e.flags=t&-65537|128,e):null;case 5:return T1(e),null;case 13:if($e(Je),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(U(340));hl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return $e(Je),null;case 4:return gl(),null;case 10:return A1(e.type._context),null;case 22:case 23:return H1(),null;case 24:return null;default:return null}}var Tp=!1,ta=!1,pz=typeof WeakSet=="function"?WeakSet:Set,Q=null;function Bs(t,e){var a=t.ref;if(a!==null)if(typeof a=="function")try{a(null)}catch(n){ot(t,e,n)}else a.current=null}function nv(t,e,a){try{a()}catch(n){ot(t,e,n)}}var I_=!1;function mz(t,e){if(Vx=Zm,t=JN(),v1(t)){if("selectionStart"in t)var a={start:t.selectionStart,end:t.selectionEnd};else e:{a=(a=t.ownerDocument)&&a.defaultView||window;var n=a.getSelection&&a.getSelection();if(n&&n.rangeCount!==0){a=n.anchorNode;var i=n.anchorOffset,r=n.focusNode;n=n.focusOffset;try{a.nodeType,r.nodeType}catch{a=null;break e}var o=0,l=-1,c=-1,d=0,u=0,p=t,m=null;t:for(;;){for(var h;p!==a||i!==0&&p.nodeType!==3||(l=o+i),p!==r||n!==0&&p.nodeType!==3||(c=o+n),p.nodeType===3&&(o+=p.nodeValue.length),(h=p.firstChild)!==null;)m=p,p=h;for(;;){if(p===t)break t;if(m===a&&++d===i&&(l=o),m===r&&++u===n&&(c=o),(h=p.nextSibling)!==null)break;p=m,m=p.parentNode}p=h}a=l===-1||c===-1?null:{start:l,end:c}}else a=null}a=a||{start:0,end:0}}else a=null;for(Hx={focusedElem:t,selectionRange:a},Zm=!1,Q=e;Q!==null;)if(e=Q,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,Q=t;else for(;Q!==null;){e=Q;try{var g=e.alternate;if(e.flags&1024)switch(e.tag){case 0:case 11:case 15:break;case 1:if(g!==null){var y=g.memoizedProps,x=g.memoizedState,v=e.stateNode,w=v.getSnapshotBeforeUpdate(e.elementType===e.type?y:kn(e.type,y),x);v.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var S=e.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(U(163))}}catch(T){ot(e,e.return,T)}if(t=e.sibling,t!==null){t.return=e.return,Q=t;break}Q=e.return}return g=I_,I_=!1,g}function td(t,e,a){var n=e.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&t)===t){var r=i.destroy;i.destroy=void 0,r!==void 0&&nv(e,a,r)}i=i.next}while(i!==n)}}function Gf(t,e){if(e=e.updateQueue,e=e!==null?e.lastEffect:null,e!==null){var a=e=e.next;do{if((a.tag&t)===t){var n=a.create;a.destroy=n()}a=a.next}while(a!==e)}}function iv(t){var e=t.ref;if(e!==null){var a=t.stateNode;switch(t.tag){case 5:t=a;break;default:t=a}typeof e=="function"?e(t):e.current=t}}function $I(t){var e=t.alternate;e!==null&&(t.alternate=null,$I(e)),t.child=null,t.deletions=null,t.sibling=null,t.tag===5&&(e=t.stateNode,e!==null&&(delete e[Wn],delete e[Vd],delete e[Ux],delete e[J6],delete e[Q6])),t.stateNode=null,t.return=null,t.dependencies=null,t.memoizedProps=null,t.memoizedState=null,t.pendingProps=null,t.stateNode=null,t.updateQueue=null}function WI(t){return t.tag===5||t.tag===3||t.tag===4}function P_(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||WI(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function rv(t,e,a){var n=t.tag;if(n===5||n===6)t=t.stateNode,e?a.nodeType===8?a.parentNode.insertBefore(t,e):a.insertBefore(t,e):(a.nodeType===8?(e=a.parentNode,e.insertBefore(t,a)):(e=a,e.appendChild(t)),a=a._reactRootContainer,a!=null||e.onclick!==null||(e.onclick=ah));else if(n!==4&&(t=t.child,t!==null))for(rv(t,e,a),t=t.sibling;t!==null;)rv(t,e,a),t=t.sibling}function ov(t,e,a){var n=t.tag;if(n===5||n===6)t=t.stateNode,e?a.insertBefore(t,e):a.appendChild(t);else if(n!==4&&(t=t.child,t!==null))for(ov(t,e,a),t=t.sibling;t!==null;)ov(t,e,a),t=t.sibling}var Mt=null,Sn=!1;function Ji(t,e,a){for(a=a.child;a!==null;)GI(t,e,a),a=a.sibling}function GI(t,e,a){if(Xn&&typeof Xn.onCommitFiberUnmount=="function")try{Xn.onCommitFiberUnmount(zf,a)}catch{}switch(a.tag){case 5:ta||Bs(a,e);case 6:var n=Mt,i=Sn;Mt=null,Ji(t,e,a),Mt=n,Sn=i,Mt!==null&&(Sn?(t=Mt,a=a.stateNode,t.nodeType===8?t.parentNode.removeChild(a):t.removeChild(a)):Mt.removeChild(a.stateNode));break;case 18:Mt!==null&&(Sn?(t=Mt,a=a.stateNode,t.nodeType===8?qy(t.parentNode,a):t.nodeType===1&&qy(t,a),Od(t)):qy(Mt,a.stateNode));break;case 4:n=Mt,i=Sn,Mt=a.stateNode.containerInfo,Sn=!0,Ji(t,e,a),Mt=n,Sn=i;break;case 0:case 11:case 14:case 15:if(!ta&&(n=a.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){i=n=n.next;do{var r=i,o=r.destroy;r=r.tag,o!==void 0&&(r&2||r&4)&&nv(a,e,o),i=i.next}while(i!==n)}Ji(t,e,a);break;case 1:if(!ta&&(Bs(a,e),n=a.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=a.memoizedProps,n.state=a.memoizedState,n.componentWillUnmount()}catch(l){ot(a,e,l)}Ji(t,e,a);break;case 21:Ji(t,e,a);break;case 22:a.mode&1?(ta=(n=ta)||a.memoizedState!==null,Ji(t,e,a),ta=n):Ji(t,e,a);break;default:Ji(t,e,a)}}function R_(t){var e=t.updateQueue;if(e!==null){t.updateQueue=null;var a=t.stateNode;a===null&&(a=t.stateNode=new pz),e.forEach(function(n){var i=kz.bind(null,t,n);a.has(n)||(a.add(n),n.then(i,i))})}}function xn(t,e){var a=e.deletions;if(a!==null)for(var n=0;n<a.length;n++){var i=a[n];try{var r=t,o=e,l=o;e:for(;l!==null;){switch(l.tag){case 5:Mt=l.stateNode,Sn=!1;break e;case 3:Mt=l.stateNode.containerInfo,Sn=!0;break e;case 4:Mt=l.stateNode.containerInfo,Sn=!0;break e}l=l.return}if(Mt===null)throw Error(U(160));GI(r,o,i),Mt=null,Sn=!1;var c=i.alternate;c!==null&&(c.return=null),i.return=null}catch(d){ot(i,e,d)}}if(e.subtreeFlags&12854)for(e=e.child;e!==null;)KI(e,t),e=e.sibling}function KI(t,e){var a=t.alternate,n=t.flags;switch(t.tag){case 0:case 11:case 14:case 15:if(xn(e,t),Hn(t),n&4){try{td(3,t,t.return),Gf(3,t)}catch(y){ot(t,t.return,y)}try{td(5,t,t.return)}catch(y){ot(t,t.return,y)}}break;case 1:xn(e,t),Hn(t),n&512&&a!==null&&Bs(a,a.return);break;case 5:if(xn(e,t),Hn(t),n&512&&a!==null&&Bs(a,a.return),t.flags&32){var i=t.stateNode;try{Id(i,"")}catch(y){ot(t,t.return,y)}}if(n&4&&(i=t.stateNode,i!=null)){var r=t.memoizedProps,o=a!==null?a.memoizedProps:r,l=t.type,c=t.updateQueue;if(t.updateQueue=null,c!==null)try{l==="input"&&r.type==="radio"&&r.name!=null&&gN(i,r),Nx(l,o);var d=Nx(l,r);for(o=0;o<c.length;o+=2){var u=c[o],p=c[o+1];u==="style"?wN(i,p):u==="dangerouslySetInnerHTML"?vN(i,p):u==="children"?Id(i,p):o1(i,u,p,d)}switch(l){case"input":Ax(i,r);break;case"textarea":yN(i,r);break;case"select":var m=i._wrapperState.wasMultiple;i._wrapperState.wasMultiple=!!r.multiple;var h=r.value;h!=null?Xs(i,!!r.multiple,h,!1):m!==!!r.multiple&&(r.defaultValue!=null?Xs(i,!!r.multiple,r.defaultValue,!0):Xs(i,!!r.multiple,r.multiple?[]:"",!1))}i[Vd]=r}catch(y){ot(t,t.return,y)}}break;case 6:if(xn(e,t),Hn(t),n&4){if(t.stateNode===null)throw Error(U(162));i=t.stateNode,r=t.memoizedProps;try{i.nodeValue=r}catch(y){ot(t,t.return,y)}}break;case 3:if(xn(e,t),Hn(t),n&4&&a!==null&&a.memoizedState.isDehydrated)try{Od(e.containerInfo)}catch(y){ot(t,t.return,y)}break;case 4:xn(e,t),Hn(t);break;case 13:xn(e,t),Hn(t),i=t.child,i.flags&8192&&(r=i.memoizedState!==null,i.stateNode.isHidden=r,!r||i.alternate!==null&&i.alternate.memoizedState!==null||(z1=pt())),n&4&&R_(t);break;case 22:if(u=a!==null&&a.memoizedState!==null,t.mode&1?(ta=(d=ta)||u,xn(e,t),ta=d):xn(e,t),Hn(t),n&8192){if(d=t.memoizedState!==null,(t.stateNode.isHidden=d)&&!u&&t.mode&1)for(Q=t,u=t.child;u!==null;){for(p=Q=u;Q!==null;){switch(m=Q,h=m.child,m.tag){case 0:case 11:case 14:case 15:td(4,m,m.return);break;case 1:Bs(m,m.return);var g=m.stateNode;if(typeof g.componentWillUnmount=="function"){n=m,a=m.return;try{e=n,g.props=e.memoizedProps,g.state=e.memoizedState,g.componentWillUnmount()}catch(y){ot(n,a,y)}}break;case 5:Bs(m,m.return);break;case 22:if(m.memoizedState!==null){O_(p);continue}}h!==null?(h.return=m,Q=h):O_(p)}u=u.sibling}e:for(u=null,p=t;;){if(p.tag===5){if(u===null){u=p;try{i=p.stateNode,d?(r=i.style,typeof r.setProperty=="function"?r.setProperty("display","none","important"):r.display="none"):(l=p.stateNode,c=p.memoizedProps.style,o=c!=null&&c.hasOwnProperty("display")?c.display:null,l.style.display=bN("display",o))}catch(y){ot(t,t.return,y)}}}else if(p.tag===6){if(u===null)try{p.stateNode.nodeValue=d?"":p.memoizedProps}catch(y){ot(t,t.return,y)}}else if((p.tag!==22&&p.tag!==23||p.memoizedState===null||p===t)&&p.child!==null){p.child.return=p,p=p.child;continue}if(p===t)break e;for(;p.sibling===null;){if(p.return===null||p.return===t)break e;u===p&&(u=null),p=p.return}u===p&&(u=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:xn(e,t),Hn(t),n&4&&R_(t);break;case 21:break;default:xn(e,t),Hn(t)}}function Hn(t){var e=t.flags;if(e&2){try{e:{for(var a=t.return;a!==null;){if(WI(a)){var n=a;break e}a=a.return}throw Error(U(160))}switch(n.tag){case 5:var i=n.stateNode;n.flags&32&&(Id(i,""),n.flags&=-33);var r=P_(t);ov(t,r,i);break;case 3:case 4:var o=n.stateNode.containerInfo,l=P_(t);rv(t,l,o);break;default:throw Error(U(161))}}catch(c){ot(t,t.return,c)}t.flags&=-3}e&4096&&(t.flags&=-4097)}function hz(t,e,a){Q=t,JI(t)}function JI(t,e,a){for(var n=(t.mode&1)!==0;Q!==null;){var i=Q,r=i.child;if(i.tag===22&&n){var o=i.memoizedState!==null||Tp;if(!o){var l=i.alternate,c=l!==null&&l.memoizedState!==null||ta;l=Tp;var d=ta;if(Tp=o,(ta=c)&&!d)for(Q=i;Q!==null;)o=Q,c=o.child,o.tag===22&&o.memoizedState!==null?M_(i):c!==null?(c.return=o,Q=c):M_(i);for(;r!==null;)Q=r,JI(r),r=r.sibling;Q=i,Tp=l,ta=d}L_(t)}else i.subtreeFlags&8772&&r!==null?(r.return=i,Q=r):L_(t)}}function L_(t){for(;Q!==null;){var e=Q;if(e.flags&8772){var a=e.alternate;try{if(e.flags&8772)switch(e.tag){case 0:case 11:case 15:ta||Gf(5,e);break;case 1:var n=e.stateNode;if(e.flags&4&&!ta)if(a===null)n.componentDidMount();else{var i=e.elementType===e.type?a.memoizedProps:kn(e.type,a.memoizedProps);n.componentDidUpdate(i,a.memoizedState,n.__reactInternalSnapshotBeforeUpdate)}var r=e.updateQueue;r!==null&&x_(e,r,n);break;case 3:var o=e.updateQueue;if(o!==null){if(a=null,e.child!==null)switch(e.child.tag){case 5:a=e.child.stateNode;break;case 1:a=e.child.stateNode}x_(e,o,a)}break;case 5:var l=e.stateNode;if(a===null&&e.flags&4){a=l;var c=e.memoizedProps;switch(e.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&a.focus();break;case"img":c.src&&(a.src=c.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(e.memoizedState===null){var d=e.alternate;if(d!==null){var u=d.memoizedState;if(u!==null){var p=u.dehydrated;p!==null&&Od(p)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(U(163))}ta||e.flags&512&&iv(e)}catch(m){ot(e,e.return,m)}}if(e===t){Q=null;break}if(a=e.sibling,a!==null){a.return=e.return,Q=a;break}Q=e.return}}function O_(t){for(;Q!==null;){var e=Q;if(e===t){Q=null;break}var a=e.sibling;if(a!==null){a.return=e.return,Q=a;break}Q=e.return}}function M_(t){for(;Q!==null;){var e=Q;try{switch(e.tag){case 0:case 11:case 15:var a=e.return;try{Gf(4,e)}catch(c){ot(e,a,c)}break;case 1:var n=e.stateNode;if(typeof n.componentDidMount=="function"){var i=e.return;try{n.componentDidMount()}catch(c){ot(e,i,c)}}var r=e.return;try{iv(e)}catch(c){ot(e,r,c)}break;case 5:var o=e.return;try{iv(e)}catch(c){ot(e,o,c)}}}catch(c){ot(e,e.return,c)}if(e===t){Q=null;break}var l=e.sibling;if(l!==null){l.return=e.return,Q=l;break}Q=e.return}}var fz=Math.ceil,mh=Ui.ReactCurrentDispatcher,D1=Ui.ReactCurrentOwner,cn=Ui.ReactCurrentBatchConfig,Ee=0,It=null,ft=null,Ft=0,Da=0,Us=Gr(0),kt=0,Wd=null,Wo=0,Kf=0,q1=0,ad=null,ka=null,z1=0,xl=1/0,fi=null,hh=!1,sv=null,Er=null,Np=!1,fr=null,fh=0,nd=0,lv=null,vm=-1,bm=0;function fa(){return Ee&6?pt():vm!==-1?vm:vm=pt()}function Cr(t){return t.mode&1?Ee&2&&Ft!==0?Ft&-Ft:Y6.transition!==null?(bm===0&&(bm=RN()),bm):(t=Le,t!==0||(t=window.event,t=t===void 0?16:VN(t.type)),t):1}function Nn(t,e,a,n){if(50<nd)throw nd=0,lv=null,Error(U(185));Su(t,a,n),(!(Ee&2)||t!==It)&&(t===It&&(!(Ee&2)&&(Kf|=a),kt===4&&sr(t,Ft)),ja(t,n),a===1&&Ee===0&&!(e.mode&1)&&(xl=pt()+500,Uf&&Kr()))}function ja(t,e){var a=t.callbackNode;Yq(t,e);var n=Ym(t,t===It?Ft:0);if(n===0)a!==null&&$2(a),t.callbackNode=null,t.callbackPriority=0;else if(e=n&-n,t.callbackPriority!==e){if(a!=null&&$2(a),e===1)t.tag===0?X6(D_.bind(null,t)):rI(D_.bind(null,t)),G6(function(){!(Ee&6)&&Kr()}),a=null;else{switch(LN(n)){case 1:a=u1;break;case 4:a=IN;break;case 16:a=Xm;break;case 536870912:a=PN;break;default:a=Xm}a=nP(a,QI.bind(null,t))}t.callbackPriority=e,t.callbackNode=a}}function QI(t,e){if(vm=-1,bm=0,Ee&6)throw Error(U(327));var a=t.callbackNode;if(al()&&t.callbackNode!==a)return null;var n=Ym(t,t===It?Ft:0);if(n===0)return null;if(n&30||n&t.expiredLanes||e)e=gh(t,n);else{e=n;var i=Ee;Ee|=2;var r=YI();(It!==t||Ft!==e)&&(fi=null,xl=pt()+500,Io(t,e));do try{xz();break}catch(l){XI(t,l)}while(!0);_1(),mh.current=r,Ee=i,ft!==null?e=0:(It=null,Ft=0,e=kt)}if(e!==0){if(e===2&&(i=Ox(t),i!==0&&(n=i,e=cv(t,i))),e===1)throw a=Wd,Io(t,0),sr(t,n),ja(t,pt()),a;if(e===6)sr(t,n);else{if(i=t.current.alternate,!(n&30)&&!gz(i)&&(e=gh(t,n),e===2&&(r=Ox(t),r!==0&&(n=r,e=cv(t,r))),e===1))throw a=Wd,Io(t,0),sr(t,n),ja(t,pt()),a;switch(t.finishedWork=i,t.finishedLanes=n,e){case 0:case 1:throw Error(U(345));case 2:mo(t,ka,fi);break;case 3:if(sr(t,n),(n&130023424)===n&&(e=z1+500-pt(),10<e)){if(Ym(t,0)!==0)break;if(i=t.suspendedLanes,(i&n)!==n){fa(),t.pingedLanes|=t.suspendedLanes&i;break}t.timeoutHandle=Bx(mo.bind(null,t,ka,fi),e);break}mo(t,ka,fi);break;case 4:if(sr(t,n),(n&4194240)===n)break;for(e=t.eventTimes,i=-1;0<n;){var o=31-Tn(n);r=1<<o,o=e[o],o>i&&(i=o),n&=~r}if(n=i,n=pt()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*fz(n/1960))-n,10<n){t.timeoutHandle=Bx(mo.bind(null,t,ka,fi),n);break}mo(t,ka,fi);break;case 5:mo(t,ka,fi);break;default:throw Error(U(329))}}}return ja(t,pt()),t.callbackNode===a?QI.bind(null,t):null}function cv(t,e){var a=ad;return t.current.memoizedState.isDehydrated&&(Io(t,e).flags|=256),t=gh(t,e),t!==2&&(e=ka,ka=a,e!==null&&dv(e)),t}function dv(t){ka===null?ka=t:ka.push.apply(ka,t)}function gz(t){for(var e=t;;){if(e.flags&16384){var a=e.updateQueue;if(a!==null&&(a=a.stores,a!==null))for(var n=0;n<a.length;n++){var i=a[n],r=i.getSnapshot;i=i.value;try{if(!Ln(r(),i))return!1}catch{return!1}}}if(a=e.child,e.subtreeFlags&16384&&a!==null)a.return=e,e=a;else{if(e===t)break;for(;e.sibling===null;){if(e.return===null||e.return===t)return!0;e=e.return}e.sibling.return=e.return,e=e.sibling}}return!0}function sr(t,e){for(e&=~q1,e&=~Kf,t.suspendedLanes|=e,t.pingedLanes&=~e,t=t.expirationTimes;0<e;){var a=31-Tn(e),n=1<<a;t[a]=-1,e&=~n}}function D_(t){if(Ee&6)throw Error(U(327));al();var e=Ym(t,0);if(!(e&1))return ja(t,pt()),null;var a=gh(t,e);if(t.tag!==0&&a===2){var n=Ox(t);n!==0&&(e=n,a=cv(t,n))}if(a===1)throw a=Wd,Io(t,0),sr(t,e),ja(t,pt()),a;if(a===6)throw Error(U(345));return t.finishedWork=t.current.alternate,t.finishedLanes=e,mo(t,ka,fi),ja(t,pt()),null}function V1(t,e){var a=Ee;Ee|=1;try{return t(e)}finally{Ee=a,Ee===0&&(xl=pt()+500,Uf&&Kr())}}function Go(t){fr!==null&&fr.tag===0&&!(Ee&6)&&al();var e=Ee;Ee|=1;var a=cn.transition,n=Le;try{if(cn.transition=null,Le=1,t)return t()}finally{Le=n,cn.transition=a,Ee=e,!(Ee&6)&&Kr()}}function H1(){Da=Us.current,$e(Us)}function Io(t,e){t.finishedWork=null,t.finishedLanes=0;var a=t.timeoutHandle;if(a!==-1&&(t.timeoutHandle=-1,W6(a)),ft!==null)for(a=ft.return;a!==null;){var n=a;switch(w1(n),n.tag){case 1:n=n.type.childContextTypes,n!=null&&nh();break;case 3:gl(),$e(Ea),$e(ia),N1();break;case 5:T1(n);break;case 4:gl();break;case 13:$e(Je);break;case 19:$e(Je);break;case 10:A1(n.type._context);break;case 22:case 23:H1()}a=a.return}if(It=t,ft=t=jr(t.current,null),Ft=Da=e,kt=0,Wd=null,q1=Kf=Wo=0,ka=ad=null,vo!==null){for(e=0;e<vo.length;e++)if(a=vo[e],n=a.interleaved,n!==null){a.interleaved=null;var i=n.next,r=a.pending;if(r!==null){var o=r.next;r.next=i,n.next=o}a.pending=n}vo=null}return t}function XI(t,e){do{var a=ft;try{if(_1(),gm.current=ph,uh){for(var n=Ye.memoizedState;n!==null;){var i=n.queue;i!==null&&(i.pending=null),n=n.next}uh=!1}if($o=0,jt=wt=Ye=null,ed=!1,Bd=0,D1.current=null,a===null||a.return===null){kt=1,Wd=e,ft=null;break}e:{var r=t,o=a.return,l=a,c=e;if(e=Ft,l.flags|=32768,c!==null&&typeof c=="object"&&typeof c.then=="function"){var d=c,u=l,p=u.tag;if(!(u.mode&1)&&(p===0||p===11||p===15)){var m=u.alternate;m?(u.updateQueue=m.updateQueue,u.memoizedState=m.memoizedState,u.lanes=m.lanes):(u.updateQueue=null,u.memoizedState=null)}var h=__(o);if(h!==null){h.flags&=-257,A_(h,o,l,r,e),h.mode&1&&S_(r,d,e),e=h,c=d;var g=e.updateQueue;if(g===null){var y=new Set;y.add(c),e.updateQueue=y}else g.add(c);break e}else{if(!(e&1)){S_(r,d,e),F1();break e}c=Error(U(426))}}else if(Ge&&l.mode&1){var x=__(o);if(x!==null){!(x.flags&65536)&&(x.flags|=256),A_(x,o,l,r,e),k1(yl(c,l));break e}}r=c=yl(c,l),kt!==4&&(kt=2),ad===null?ad=[r]:ad.push(r),r=o;do{switch(r.tag){case 3:r.flags|=65536,e&=-e,r.lanes|=e;var v=LI(r,c,e);y_(r,v);break e;case 1:l=c;var w=r.type,S=r.stateNode;if(!(r.flags&128)&&(typeof w.getDerivedStateFromError=="function"||S!==null&&typeof S.componentDidCatch=="function"&&(Er===null||!Er.has(S)))){r.flags|=65536,e&=-e,r.lanes|=e;var T=OI(r,l,e);y_(r,T);break e}}r=r.return}while(r!==null)}eP(a)}catch(P){e=P,ft===a&&a!==null&&(ft=a=a.return);continue}break}while(!0)}function YI(){var t=mh.current;return mh.current=ph,t===null?ph:t}function F1(){(kt===0||kt===3||kt===2)&&(kt=4),It===null||!(Wo&268435455)&&!(Kf&268435455)||sr(It,Ft)}function gh(t,e){var a=Ee;Ee|=2;var n=YI();(It!==t||Ft!==e)&&(fi=null,Io(t,e));do try{yz();break}catch(i){XI(t,i)}while(!0);if(_1(),Ee=a,mh.current=n,ft!==null)throw Error(U(261));return It=null,Ft=0,kt}function yz(){for(;ft!==null;)ZI(ft)}function xz(){for(;ft!==null&&!Bq();)ZI(ft)}function ZI(t){var e=aP(t.alternate,t,Da);t.memoizedProps=t.pendingProps,e===null?eP(t):ft=e,D1.current=null}function eP(t){var e=t;do{var a=e.alternate;if(t=e.return,e.flags&32768){if(a=uz(a,e),a!==null){a.flags&=32767,ft=a;return}if(t!==null)t.flags|=32768,t.subtreeFlags=0,t.deletions=null;else{kt=6,ft=null;return}}else if(a=dz(a,e,Da),a!==null){ft=a;return}if(e=e.sibling,e!==null){ft=e;return}ft=e=t}while(e!==null);kt===0&&(kt=5)}function mo(t,e,a){var n=Le,i=cn.transition;try{cn.transition=null,Le=1,vz(t,e,a,n)}finally{cn.transition=i,Le=n}return null}function vz(t,e,a,n){do al();while(fr!==null);if(Ee&6)throw Error(U(327));a=t.finishedWork;var i=t.finishedLanes;if(a===null)return null;if(t.finishedWork=null,t.finishedLanes=0,a===t.current)throw Error(U(177));t.callbackNode=null,t.callbackPriority=0;var r=a.lanes|a.childLanes;if(Zq(t,r),t===It&&(ft=It=null,Ft=0),!(a.subtreeFlags&2064)&&!(a.flags&2064)||Np||(Np=!0,nP(Xm,function(){return al(),null})),r=(a.flags&15990)!==0,a.subtreeFlags&15990||r){r=cn.transition,cn.transition=null;var o=Le;Le=1;var l=Ee;Ee|=4,D1.current=null,mz(t,a),KI(a,t),z6(Hx),Zm=!!Vx,Hx=Vx=null,t.current=a,hz(a),Uq(),Ee=l,Le=o,cn.transition=r}else t.current=a;if(Np&&(Np=!1,fr=t,fh=i),r=t.pendingLanes,r===0&&(Er=null),Gq(a.stateNode),ja(t,pt()),e!==null)for(n=t.onRecoverableError,a=0;a<e.length;a++)i=e[a],n(i.value,{componentStack:i.stack,digest:i.digest});if(hh)throw hh=!1,t=sv,sv=null,t;return fh&1&&t.tag!==0&&al(),r=t.pendingLanes,r&1?t===lv?nd++:(nd=0,lv=t):nd=0,Kr(),null}function al(){if(fr!==null){var t=LN(fh),e=cn.transition,a=Le;try{if(cn.transition=null,Le=16>t?16:t,fr===null)var n=!1;else{if(t=fr,fr=null,fh=0,Ee&6)throw Error(U(331));var i=Ee;for(Ee|=4,Q=t.current;Q!==null;){var r=Q,o=r.child;if(Q.flags&16){var l=r.deletions;if(l!==null){for(var c=0;c<l.length;c++){var d=l[c];for(Q=d;Q!==null;){var u=Q;switch(u.tag){case 0:case 11:case 15:td(8,u,r)}var p=u.child;if(p!==null)p.return=u,Q=p;else for(;Q!==null;){u=Q;var m=u.sibling,h=u.return;if($I(u),u===d){Q=null;break}if(m!==null){m.return=h,Q=m;break}Q=h}}}var g=r.alternate;if(g!==null){var y=g.child;if(y!==null){g.child=null;do{var x=y.sibling;y.sibling=null,y=x}while(y!==null)}}Q=r}}if(r.subtreeFlags&2064&&o!==null)o.return=r,Q=o;else e:for(;Q!==null;){if(r=Q,r.flags&2048)switch(r.tag){case 0:case 11:case 15:td(9,r,r.return)}var v=r.sibling;if(v!==null){v.return=r.return,Q=v;break e}Q=r.return}}var w=t.current;for(Q=w;Q!==null;){o=Q;var S=o.child;if(o.subtreeFlags&2064&&S!==null)S.return=o,Q=S;else e:for(o=w;Q!==null;){if(l=Q,l.flags&2048)try{switch(l.tag){case 0:case 11:case 15:Gf(9,l)}}catch(P){ot(l,l.return,P)}if(l===o){Q=null;break e}var T=l.sibling;if(T!==null){T.return=l.return,Q=T;break e}Q=l.return}}if(Ee=i,Kr(),Xn&&typeof Xn.onPostCommitFiberRoot=="function")try{Xn.onPostCommitFiberRoot(zf,t)}catch{}n=!0}return n}finally{Le=a,cn.transition=e}}return!1}function q_(t,e,a){e=yl(a,e),e=LI(t,e,1),t=Ar(t,e,1),e=fa(),t!==null&&(Su(t,1,e),ja(t,e))}function ot(t,e,a){if(t.tag===3)q_(t,t,a);else for(;e!==null;){if(e.tag===3){q_(e,t,a);break}else if(e.tag===1){var n=e.stateNode;if(typeof e.type.getDerivedStateFromError=="function"||typeof n.componentDidCatch=="function"&&(Er===null||!Er.has(n))){t=yl(a,t),t=OI(e,t,1),e=Ar(e,t,1),t=fa(),e!==null&&(Su(e,1,t),ja(e,t));break}}e=e.return}}function bz(t,e,a){var n=t.pingCache;n!==null&&n.delete(e),e=fa(),t.pingedLanes|=t.suspendedLanes&a,It===t&&(Ft&a)===a&&(kt===4||kt===3&&(Ft&130023424)===Ft&&500>pt()-z1?Io(t,0):q1|=a),ja(t,e)}function tP(t,e){e===0&&(t.mode&1?(e=bp,bp<<=1,!(bp&130023424)&&(bp=4194304)):e=1);var a=fa();t=Oi(t,e),t!==null&&(Su(t,e,a),ja(t,a))}function wz(t){var e=t.memoizedState,a=0;e!==null&&(a=e.retryLane),tP(t,a)}function kz(t,e){var a=0;switch(t.tag){case 13:var n=t.stateNode,i=t.memoizedState;i!==null&&(a=i.retryLane);break;case 19:n=t.stateNode;break;default:throw Error(U(314))}n!==null&&n.delete(e),tP(t,a)}var aP;aP=function(t,e,a){if(t!==null)if(t.memoizedProps!==e.pendingProps||Ea.current)Aa=!0;else{if(!(t.lanes&a)&&!(e.flags&128))return Aa=!1,cz(t,e,a);Aa=!!(t.flags&131072)}else Aa=!1,Ge&&e.flags&1048576&&oI(e,oh,e.index);switch(e.lanes=0,e.tag){case 2:var n=e.type;xm(t,e),t=e.pendingProps;var i=ml(e,ia.current);tl(e,a),i=P1(null,e,n,t,i,a);var r=R1();return e.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(e.tag=1,e.memoizedState=null,e.updateQueue=null,Ca(n)?(r=!0,ih(e)):r=!1,e.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,C1(e),i.updater=Wf,e.stateNode=i,i._reactInternals=e,Qx(e,n,t,a),e=Zx(null,e,n,!0,r,a)):(e.tag=0,Ge&&r&&b1(e),ua(null,e,i,a),e=e.child),e;case 16:n=e.elementType;e:{switch(xm(t,e),t=e.pendingProps,i=n._init,n=i(n._payload),e.type=n,i=e.tag=_z(n),t=kn(n,t),i){case 0:e=Yx(null,e,n,t,a);break e;case 1:e=j_(null,e,n,t,a);break e;case 11:e=E_(null,e,n,t,a);break e;case 14:e=C_(null,e,n,kn(n.type,t),a);break e}throw Error(U(306,n,""))}return e;case 0:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),Yx(t,e,n,i,a);case 1:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),j_(t,e,n,i,a);case 3:e:{if(zI(e),t===null)throw Error(U(387));n=e.pendingProps,r=e.memoizedState,i=r.element,pI(t,e),ch(e,n,null,a);var o=e.memoizedState;if(n=o.element,r.isDehydrated)if(r={element:n,isDehydrated:!1,cache:o.cache,pendingSuspenseBoundaries:o.pendingSuspenseBoundaries,transitions:o.transitions},e.updateQueue.baseState=r,e.memoizedState=r,e.flags&256){i=yl(Error(U(423)),e),e=T_(t,e,n,a,i);break e}else if(n!==i){i=yl(Error(U(424)),e),e=T_(t,e,n,a,i);break e}else for(za=_r(e.stateNode.containerInfo.firstChild),Fa=e,Ge=!0,_n=null,a=dI(e,null,n,a),e.child=a;a;)a.flags=a.flags&-3|4096,a=a.sibling;else{if(hl(),n===i){e=Mi(t,e,a);break e}ua(t,e,n,a)}e=e.child}return e;case 5:return mI(e),t===null&&Gx(e),n=e.type,i=e.pendingProps,r=t!==null?t.memoizedProps:null,o=i.children,Fx(n,i)?o=null:r!==null&&Fx(n,r)&&(e.flags|=32),qI(t,e),ua(t,e,o,a),e.child;case 6:return t===null&&Gx(e),null;case 13:return VI(t,e,a);case 4:return j1(e,e.stateNode.containerInfo),n=e.pendingProps,t===null?e.child=fl(e,null,n,a):ua(t,e,n,a),e.child;case 11:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),E_(t,e,n,i,a);case 7:return ua(t,e,e.pendingProps,a),e.child;case 8:return ua(t,e,e.pendingProps.children,a),e.child;case 12:return ua(t,e,e.pendingProps.children,a),e.child;
vendor: 4,549 bytes, line 40
40case 10:e:{if(n=e.type._context,i=e.pendingProps,r=e.memoizedProps,o=i.value,Ve(sh,n._currentValue),n._currentValue=o,r!==null)if(Ln(r.value,o)){if(r.children===i.children&&!Ea.current){e=Mi(t,e,a);break e}}else for(r=e.child,r!==null&&(r.return=e);r!==null;){var l=r.dependencies;if(l!==null){o=r.child;for(var c=l.firstContext;c!==null;){if(c.context===n){if(r.tag===1){c=Ei(-1,a&-a),c.tag=2;var d=r.updateQueue;if(d!==null){d=d.shared;var u=d.pending;u===null?c.next=c:(c.next=u.next,u.next=c),d.pending=c}}r.lanes|=a,c=r.alternate,c!==null&&(c.lanes|=a),Kx(r.return,a,e),l.lanes|=a;break}c=c.next}}else if(r.tag===10)o=r.type===e.type?null:r.child;else if(r.tag===18){if(o=r.return,o===null)throw Error(U(341));o.lanes|=a,l=o.alternate,l!==null&&(l.lanes|=a),Kx(o,a,e),o=r.sibling}else o=r.child;if(o!==null)o.return=r;else for(o=r;o!==null;){if(o===e){o=null;break}if(r=o.sibling,r!==null){r.return=o.return,o=r;break}o=o.return}r=o}ua(t,e,i.children,a),e=e.child}return e;case 9:return i=e.type,n=e.pendingProps.children,tl(e,a),i=pn(i),n=n(i),e.flags|=1,ua(t,e,n,a),e.child;case 14:return n=e.type,i=kn(n,e.pendingProps),i=kn(n.type,i),C_(t,e,n,i,a);case 15:return MI(t,e,e.type,e.pendingProps,a);case 17:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),xm(t,e),e.tag=1,Ca(n)?(t=!0,ih(e)):t=!1,tl(e,a),RI(e,n,i),Qx(e,n,i,a),Zx(null,e,n,!0,t,a);case 19:return HI(t,e,a);case 22:return DI(t,e,a)}throw Error(U(156,e.tag))};function nP(t,e){return NN(t,e)}function Sz(t,e,a,n){this.tag=t,this.key=a,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=e,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function sn(t,e,a,n){return new Sz(t,e,a,n)}function B1(t){return t=t.prototype,!(!t||!t.isReactComponent)}function _z(t){if(typeof t=="function")return B1(t)?1:0;if(t!=null){if(t=t.$$typeof,t===l1)return 11;if(t===c1)return 14}return 2}function jr(t,e){var a=t.alternate;return a===null?(a=sn(t.tag,e,t.key,t.mode),a.elementType=t.elementType,a.type=t.type,a.stateNode=t.stateNode,a.alternate=t,t.alternate=a):(a.pendingProps=e,a.type=t.type,a.flags=0,a.subtreeFlags=0,a.deletions=null),a.flags=t.flags&14680064,a.childLanes=t.childLanes,a.lanes=t.lanes,a.child=t.child,a.memoizedProps=t.memoizedProps,a.memoizedState=t.memoizedState,a.updateQueue=t.updateQueue,e=t.dependencies,a.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext},a.sibling=t.sibling,a.index=t.index,a.ref=t.ref,a}function wm(t,e,a,n,i,r){var o=2;if(n=t,typeof t=="function")B1(t)&&(o=1);else if(typeof t=="string")o=5;else e:switch(t){case Ls:return Po(a.children,i,r,e);case s1:o=8,i|=8;break;case bx:return t=sn(12,a,e,i|2),t.elementType=bx,t.lanes=r,t;case wx:return t=sn(13,a,e,i),t.elementType=wx,t.lanes=r,t;case kx:return t=sn(19,a,e,i),t.elementType=kx,t.lanes=r,t;case mN:return Jf(a,i,r,e);default:if(typeof t=="object"&&t!==null)switch(t.$$typeof){case uN:o=10;break e;case pN:o=9;break e;case l1:o=11;break e;case c1:o=14;break e;case tr:o=16,n=null;break e}throw Error(U(130,t==null?t:typeof t,""))}return e=sn(o,a,e,i),e.elementType=t,e.type=n,e.lanes=r,e}function Po(t,e,a,n){return t=sn(7,t,n,e),t.lanes=a,t}function Jf(t,e,a,n){return t=sn(22,t,n,e),t.elementType=mN,t.lanes=a,t.stateNode={isHidden:!1},t}function Wy(t,e,a){return t=sn(6,t,null,e),t.lanes=a,t}function Gy(t,e,a){return e=sn(4,t.children!==null?t.children:[],t.key,e),e.lanes=a,e.stateNode={containerInfo:t.containerInfo,pendingChildren:null,implementation:t.implementation},e}function Az(t,e,a,n,i){this.tag=e,this.containerInfo=t,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Cy(0),this.expirationTimes=Cy(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Cy(0),this.identifierPrefix=n,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function U1(t,e,a,n,i,r,o,l,c){return t=new Az(t,e,a,l,c),e===1?(e=1,r===!0&&(e|=8)):e=0,r=sn(3,null,null,e),t.current=r,r.stateNode=t,r.memoizedState={element:n,isDehydrated:a,cache:null,transitions:null,pendingSuspenseBoundaries:null},C1(r),t}function Ez(t,e,a){var n=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;
vendor: 4,591 bytes, line 40
40return{$$typeof:Rs,key:n==null?null:""+n,children:t,containerInfo:e,implementation:a}}function iP(t){if(!t)return qr;t=t._reactInternals;e:{if(cs(t)!==t||t.tag!==1)throw Error(U(170));var e=t;do{switch(e.tag){case 3:e=e.stateNode.context;break e;case 1:if(Ca(e.type)){e=e.stateNode.__reactInternalMemoizedMergedChildContext;break e}}e=e.return}while(e!==null);throw Error(U(171))}if(t.tag===1){var a=t.type;if(Ca(a))return iI(t,a,e)}return e}function rP(t,e,a,n,i,r,o,l,c){return t=U1(a,n,!0,t,i,r,o,l,c),t.context=iP(null),a=t.current,n=fa(),i=Cr(a),r=Ei(n,i),r.callback=e??null,Ar(a,r,i),t.current.lanes=i,Su(t,i,n),ja(t,n),t}function Qf(t,e,a,n){var i=e.current,r=fa(),o=Cr(i);return a=iP(a),e.context===null?e.context=a:e.pendingContext=a,e=Ei(r,o),e.payload={element:t},n=n===void 0?null:n,n!==null&&(e.callback=n),t=Ar(i,e,o),t!==null&&(Nn(t,i,o,r),fm(t,i,o)),o}function yh(t){if(t=t.current,!t.child)return null;switch(t.child.tag){case 5:return t.child.stateNode;default:return t.child.stateNode}}function z_(t,e){if(t=t.memoizedState,t!==null&&t.dehydrated!==null){var a=t.retryLane;t.retryLane=a!==0&&a<e?a:e}}function $1(t,e){z_(t,e),(t=t.alternate)&&z_(t,e)}function Cz(){return null}var oP=typeof reportError=="function"?reportError:function(t){console.error(t)};function W1(t){this._internalRoot=t}Xf.prototype.render=W1.prototype.render=function(t){var e=this._internalRoot;if(e===null)throw Error(U(409));Qf(t,e,null,null)};Xf.prototype.unmount=W1.prototype.unmount=function(){var t=this._internalRoot;if(t!==null){this._internalRoot=null;var e=t.containerInfo;Go(function(){Qf(null,t,null,null)}),e[Li]=null}};function Xf(t){this._internalRoot=t}Xf.prototype.unstable_scheduleHydration=function(t){if(t){var e=DN();t={blockedOn:null,target:t,priority:e};for(var a=0;a<or.length&&e!==0&&e<or[a].priority;a++);or.splice(a,0,t),a===0&&zN(t)}};function G1(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)}function Yf(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11&&(t.nodeType!==8||t.nodeValue!==" react-mount-point-unstable "))}function V_(){}function jz(t,e,a,n,i){if(i){if(typeof n=="function"){var r=n;n=function(){var d=yh(o);r.call(d)}}var o=rP(e,n,t,0,null,!1,!1,"",V_);return t._reactRootContainer=o,t[Li]=o.current,qd(t.nodeType===8?t.parentNode:t),Go(),o}for(;i=t.lastChild;)t.removeChild(i);if(typeof n=="function"){var l=n;n=function(){var d=yh(c);l.call(d)}}var c=U1(t,0,!1,null,null,!1,!1,"",V_);return t._reactRootContainer=c,t[Li]=c.current,qd(t.nodeType===8?t.parentNode:t),Go(function(){Qf(e,c,a,n)}),c}function Zf(t,e,a,n,i){var r=a._reactRootContainer;if(r){var o=r;if(typeof i=="function"){var l=i;i=function(){var c=yh(o);l.call(c)}}Qf(e,o,t,i)}else o=jz(a,e,t,i,n);return yh(o)}ON=function(t){switch(t.tag){case 3:var e=t.stateNode;if(e.current.memoizedState.isDehydrated){var a=Mc(e.pendingLanes);a!==0&&(p1(e,a|1),ja(e,pt()),!(Ee&6)&&(xl=pt()+500,Kr()))}break;case 13:Go(function(){var n=Oi(t,1);if(n!==null){var i=fa();Nn(n,t,1,i)}}),$1(t,1)}};m1=function(t){if(t.tag===13){var e=Oi(t,134217728);if(e!==null){var a=fa();Nn(e,t,134217728,a)}$1(t,134217728)}};MN=function(t){if(t.tag===13){var e=Cr(t),a=Oi(t,e);if(a!==null){var n=fa();Nn(a,t,e,n)}$1(t,e)}};DN=function(){return Le};qN=function(t,e){var a=Le;try{return Le=t,e()}finally{Le=a}};Px=function(t,e,a){switch(e){case"input":if(Ax(t,a),e=a.name,a.type==="radio"&&e!=null){for(a=t;a.parentNode;)a=a.parentNode;for(a=a.querySelectorAll("input[name="+JSON.stringify(""+e)+'][type="radio"]'),e=0;e<a.length;e++){var n=a[e];if(n!==t&&n.form===t.form){var i=Bf(n);if(!i)throw Error(U(90));fN(n),Ax(n,i)}}}break;case"textarea":yN(t,a);break;case"select":e=a.value,e!=null&&Xs(t,!!a.multiple,e,!1)}};_N=V1;AN=Go;var Tz={usingClientEntryPoint:!1,Events:[Au,qs,Bf,kN,SN,V1]},wc={findFiberByHostInstance:xo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},Nz={bundleType:wc.bundleType,version:wc.version,rendererPackageName:wc.rendererPackageName,rendererConfig:wc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Ui.ReactCurrentDispatcher,findHostInstanceByFiber:function(t){return t=jN(t),t===null?null:t.stateNode},findFiberByHostInstance:wc.findFiberByHostInstance||Cz,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};
40if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var Ip=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Ip.isDisabled&&Ip.supportsFiber)try{zf=Ip.inject(Nz),Xn=Ip}catch{}}Ga.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Tz;Ga.createPortal=function(t,e){var a=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!G1(e))throw Error(U(200));return Ez(t,e,null,a)};Ga.createRoot=function(t,e){if(!G1(t))throw Error(U(299));var a=!1,n="",i=oP;return e!=null&&(e.unstable_strictMode===!0&&(a=!0),e.identifierPrefix!==void 0&&(n=e.identifierPrefix),e.onRecoverableError!==void 0&&(i=e.onRecoverableError)),e=U1(t,1,!1,null,null,a,!1,n,i),t[Li]=e.current,qd(t.nodeType===8?t.parentNode:t),new W1(e)};Ga.findDOMNode=function(t){if(t==null)return null;if(t.nodeType===1)return t;var e=t._reactInternals;if(e===void 0)throw typeof t.render=="function"?Error(U(188)):(t=Object.keys(t).join(","),Error(U(268,t)));return t=jN(e),t=t===null?null:t.stateNode,t};Ga.flushSync=function(t){return Go(t)};Ga.hydrate=function(t,e,a){if(!Yf(e))throw Error(U(200));return Zf(null,t,e,!0,a)};Ga.hydrateRoot=function(t,e,a){if(!G1(t))throw Error(U(405));var n=a!=null&&a.hydratedSources||null,i=!1,r="",o=oP;if(a!=null&&(a.unstable_strictMode===!0&&(i=!0),a.identifierPrefix!==void 0&&(r=a.identifierPrefix),a.onRecoverableError!==void 0&&(o=a.onRecoverableError)),e=rP(e,null,t,1,a??null,i,!1,r,o),t[Li]=e.current,qd(t),n)for(t=0;t<n.length;t++)a=n[t],i=a._getVersion,i=i(a._source),e.mutableSourceEagerHydrationData==null?e.mutableSourceEagerHydrationData=[a,i]:e.mutableSourceEagerHydrationData.push(a,i);return new Xf(e)};Ga.render=function(t,e,a){if(!Yf(e))throw Error(U(200));return Zf(null,t,e,!1,a)};Ga.unmountComponentAtNode=function(t){if(!Yf(t))throw Error(U(40));return t._reactRootContainer?(Go(function(){Zf(null,null,t,!1,function(){t._reactRootContainer=null,t[Li]=null})}),!0):!1};Ga.unstable_batchedUpdates=V1;Ga.unstable_renderSubtreeIntoContainer=function(t,e,a,n){if(!Yf(a))throw Error(U(200));if(t==null||t._reactInternals===void 0)throw Error(U(38));return Zf(t,e,a,!1,n)};Ga.version="18.3.1-next-f1338f8080-20240426";function sP(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(sP)}catch(t){console.error(t)}}sP(),sN.exports=Ga;var lP=sN.exports;const Iz=wu(lP);var H_=lP;xx.createRoot=H_.createRoot,xx.hydrateRoot=H_.hydrateRoot;var Pz=typeof Element<"u",Rz=typeof Map=="function",Lz=typeof Set=="function",Oz=typeof ArrayBuffer=="function"&&!!ArrayBuffer.isView;function km(t,e){if(t===e)return!0;if(t&&e&&typeof t=="object"&&typeof e=="object"){if(t.constructor!==e.constructor)return!1;var a,n,i;if(Array.isArray(t)){if(a=t.length,a!=e.length)return!1;for(n=a;n--!==0;)if(!km(t[n],e[n]))return!1;return!0}var r;if(Rz&&t instanceof Map&&e instanceof Map){if(t.size!==e.size)return!1;for(r=t.entries();!(n=r.next()).done;)if(!e.has(n.value[0]))return!1;for(r=t.entries();!(n=r.next()).done;)if(!km(n.value[1],e.get(n.value[0])))return!1;return!0}if(Lz&&t instanceof Set&&e instanceof Set){if(t.size!==e.size)return!1;for(r=t.entries();!(n=r.next()).done;)if(!e.has(n.value[0]))return!1;return!0}if(Oz&&ArrayBuffer.isView(t)&&ArrayBuffer.isView(e)){if(a=t.length,a!=e.length)return!1;for(n=a;n--!==0;)if(t[n]!==e[n])return!1;return!0}if(t.constructor===RegExp)return t.source===e.source&&t.flags===e.flags;if(t.valueOf!==Object.prototype.valueOf&&typeof t.valueOf=="function"&&typeof e.valueOf=="function")return t.valueOf()===e.valueOf();if(t.toString!==Object.prototype.toString&&typeof t.toString=="function"&&typeof e.toString=="function")return t.toString()===e.toString();if(i=Object.keys(t),a=i.length,a!==Object.keys(e).length)return!1;for(n=a;n--!==0;)if(!Object.prototype.hasOwnProperty.call(e,i[n]))return!1;if(Pz&&t instanceof Element)return!1;for(n=a;n--!==0;)if(!((i[n]==="_owner"||i[n]==="__v"||i[n]==="__o")&&t.$$typeof)&&!km(t[i[n]],e[i[n]]))return!1;return!0}return t!==t&&e!==e}var Mz=function(e,a){try{return km(e,a)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}};const Dz=wu(Mz);var qz=function(t,e,a,n,i,r,o,l){if(!t){var c;if(e===void 0)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var d=[a,n,i,r,o,l],u=0;c=new Error(e.replace(/%s/g,function(){return d[u++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}},zz=qz;const F_=wu(zz);var Vz=function(e,a,n,i){var r=n?n.call(i,e,a):void 0;if(r!==void 0)return!!r;if(e===a)return!0;
40if(typeof e!="object"||!e||typeof a!="object"||!a)return!1;var o=Object.keys(e),l=Object.keys(a);if(o.length!==l.length)return!1;for(var c=Object.prototype.hasOwnProperty.bind(a),d=0;d<o.length;d++){var u=o[d];if(!c(u))return!1;var p=e[u],m=a[u];if(r=n?n.call(i,p,m,u):void 0,r===!1||r===void 0&&p!==m)return!1}return!0};const Hz=wu(Vz);var cP=(t=>(t.BASE="base",t.BODY="body",t.HEAD="head",t.HTML="html",t.LINK="link",t.META="meta",t.NOSCRIPT="noscript",t.SCRIPT="script",t.STYLE="style",t.TITLE="title",t.FRAGMENT="Symbol(react.fragment)",t))(cP||{}),Ky={link:{rel:["amphtml","canonical","alternate"]},script:{type:["application/ld+json"]},meta:{charset:"",name:["generator","robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]}},B_=Object.values(cP),eg={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},dP=Object.entries(eg).reduce((t,[e,a])=>(t[a]=e,t),{}),En="data-rh",nl={DEFAULT_TITLE:"defaultTitle",DEFER:"defer",ENCODE_SPECIAL_CHARACTERS:"encodeSpecialCharacters",ON_CHANGE_CLIENT_STATE:"onChangeClientState",TITLE_TEMPLATE:"titleTemplate",PRIORITIZE_SEO_TAGS:"prioritizeSeoTags"},il=(t,e)=>{for(let a=t.length-1;a>=0;a-=1){const n=t[a];if(Object.prototype.hasOwnProperty.call(n,e))return n[e]}return null},Fz=t=>{let e=il(t,"title");const a=il(t,nl.TITLE_TEMPLATE);if(Array.isArray(e)&&(e=e.join("")),a&&e)return a.replace(/%s/g,()=>e);const n=il(t,nl.DEFAULT_TITLE);return e||n||void 0},Bz=t=>il(t,nl.ON_CHANGE_CLIENT_STATE)||(()=>{}),Jy=(t,e)=>e.filter(a=>typeof a[t]<"u").map(a=>a[t]).reduce((a,n)=>({...a,...n}),{}),Uz=(t,e)=>e.filter(a=>typeof a.base<"u").map(a=>a.base).reverse().reduce((a,n)=>{if(!a.length){const i=Object.keys(n);for(let r=0;r<i.length;r+=1){const l=i[r].toLowerCase();if(t.indexOf(l)!==-1&&n[l])return a.concat(n)}}return a},[]),$z=t=>console&&typeof console.warn=="function"&&console.warn(t),kc=(t,e,a)=>{const n={};return a.filter(i=>Array.isArray(i[t])?!0:(typeof i[t]<"u"&&$z(`Helmet: ${t} should be of type "Array". Instead found type "${typeof i[t]}"`),!1)).map(i=>i[t]).reverse().reduce((i,r)=>{const o={};r.filter(c=>{let d;const u=Object.keys(c);for(let m=0;m<u.length;m+=1){const h=u[m],g=h.toLowerCase();e.indexOf(g)!==-1&&!(d==="rel"&&c[d].toLowerCase()==="canonical")&&!(g==="rel"&&c[g].toLowerCase()==="stylesheet")&&(d=g),e.indexOf(h)!==-1&&(h==="innerHTML"||h==="cssText"||h==="itemprop")&&(d=h)}if(!d||!c[d])return!1;const p=c[d].toLowerCase();return n[d]||(n[d]={}),o[d]||(o[d]={}),n[d][p]?!1:(o[d][p]=!0,!0)}).reverse().forEach(c=>i.push(c));const l=Object.keys(o);for(let c=0;c<l.length;c+=1){const d=l[c],u={...n[d],...o[d]};n[d]=u}return i},[]).reverse()},Wz=(t,e)=>{if(Array.isArray(t)&&t.length){for(let a=0;a<t.length;a+=1)if(t[a][e])return!0}return!1},Gz=t=>({baseTag:Uz(["href"],t),bodyAttributes:Jy("bodyAttributes",t),defer:il(t,nl.DEFER),encode:il(t,nl.ENCODE_SPECIAL_CHARACTERS),htmlAttributes:Jy("htmlAttributes",t),linkTags:kc("link",["rel","href"],t),metaTags:kc("meta",["name","charset","http-equiv","property","itemprop"],t),noscriptTags:kc("noscript",["innerHTML"],t),onChangeClientState:Bz(t),scriptTags:kc("script",["src","innerHTML"],t),styleTags:kc("style",["cssText"],t),title:Fz(t),titleAttributes:Jy("titleAttributes",t),prioritizeSeoTags:Wz(t,nl.PRIORITIZE_SEO_TAGS)}),uP=t=>Array.isArray(t)?t.join(""):t,Kz=(t,e)=>{const a=Object.keys(t);for(let n=0;n<a.length;n+=1)if(e[a[n]]&&e[a[n]].includes(t[a[n]]))return!0;return!1},Qy=(t,e)=>Array.isArray(t)?t.reduce((a,n)=>(Kz(n,e)?a.priority.push(n):a.default.push(n),a),{priority:[],default:[]}):{default:t,priority:[]},U_=(t,e)=>({...t,[e]:void 0}),Jz=["noscript","script","style"],uv=(t,e=!0)=>e===!1?String(t):String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),pP=t=>Object.keys(t).reduce((e,a)=>{const n=typeof t[a]<"u"?`${a}="${t[a]}"`:`${a}`;return e?`${e} ${n}`:n},""),Qz=(t,e,a,n)=>{const i=pP(a),r=uP(e);return i?`<${t} ${En}="true" ${i}>${uv(r,n)}</${t}>`:`<${t} ${En}="true">${uv(r,n)}</${t}>`},Xz=(t,e,a=!0)=>e.reduce((n,i)=>{const r=i,o=Object.keys(r).filter(d=>!(d==="innerHTML"||d==="cssText")).reduce((d,u)=>{const p=typeof r[u]>"u"?u:`${u}="${uv(r[u],a)}"`;return d?`${d} ${p}`:p},""),l=r.innerHTML||r.cssText||"",c=Jz.indexOf(t)===-1;return`${n}<${t} ${En}="true" ${o}${c?"/>":`>${l}</${t}>`}`},""),mP=(t,e={})=>Object.keys(t).reduce((a,n)=>{const i=eg[n];return a[i||n]=t[n],a},e),Yz=(t,e,a)=>{const n={key:e,[En]:!0},i=mP(a,n);return[Re.createElement("title",i,e)]},Sm=(t,e)=>e.map((a,n)=>{const i={key:n,[En]:!0};
40return Object.keys(a).forEach(r=>{const l=eg[r]||r;if(l==="innerHTML"||l==="cssText"){const c=a.innerHTML||a.cssText;i.dangerouslySetInnerHTML={__html:c}}else i[l]=a[r]}),Re.createElement(t,i)}),tn=(t,e,a=!0)=>{switch(t){case"title":return{toComponent:()=>Yz(t,e.title,e.titleAttributes),toString:()=>Qz(t,e.title,e.titleAttributes,a)};case"bodyAttributes":case"htmlAttributes":return{toComponent:()=>mP(e),toString:()=>pP(e)};default:return{toComponent:()=>Sm(t,e),toString:()=>Xz(t,e,a)}}},Zz=({metaTags:t,linkTags:e,scriptTags:a,encode:n})=>{const i=Qy(t,Ky.meta),r=Qy(e,Ky.link),o=Qy(a,Ky.script);return{priorityMethods:{toComponent:()=>[...Sm("meta",i.priority),...Sm("link",r.priority),...Sm("script",o.priority)],toString:()=>`${tn("meta",i.priority,n)} ${tn("link",r.priority,n)} ${tn("script",o.priority,n)}`},metaTags:i.default,linkTags:r.default,scriptTags:o.default}},eV=t=>{const{baseTag:e,bodyAttributes:a,encode:n=!0,htmlAttributes:i,noscriptTags:r,styleTags:o,title:l="",titleAttributes:c,prioritizeSeoTags:d}=t;let{linkTags:u,metaTags:p,scriptTags:m}=t,h={toComponent:()=>[],toString:()=>""};return d&&({priorityMethods:h,linkTags:u,metaTags:p,scriptTags:m}=Zz(t)),{priority:h,base:tn("base",e,n),bodyAttributes:tn("bodyAttributes",a,n),htmlAttributes:tn("htmlAttributes",i,n),link:tn("link",u,n),meta:tn("meta",p,n),noscript:tn("noscript",r,n),script:tn("script",m,n),style:tn("style",o,n),title:tn("title",{title:l,titleAttributes:c},n)}},pv=eV,Pp=[],K1=!!(typeof window<"u"&&window.document&&window.document.createElement),mv=class{constructor(t,e){di(this,"instances",[]);di(this,"canUseDOM",K1);di(this,"context");di(this,"value",{setHelmet:t=>{this.context.helmet=t},helmetInstances:{get:()=>this.canUseDOM?Pp:this.instances,add:t=>{(this.canUseDOM?Pp:this.instances).push(t)},remove:t=>{const e=(this.canUseDOM?Pp:this.instances).indexOf(t);(this.canUseDOM?Pp:this.instances).splice(e,1)}}});this.context=t,this.canUseDOM=e||!1,e||(t.helmet=pv({baseTag:[],bodyAttributes:{},htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))}},tV=parseInt(Re.version.split(".")[0],10),hv=tV>=19,aV={},hP=Re.createContext(aV),No,fP=(No=class extends k.Component{constructor(a){super(a);di(this,"helmetData");hv?this.helmetData=null:this.helmetData=new mv(this.props.context||{},No.canUseDOM)}render(){return hv?Re.createElement(Re.Fragment,null,this.props.children):Re.createElement(hP.Provider,{value:this.helmetData.value},this.props.children)}},di(No,"canUseDOM",K1),No),ks=(t,e)=>{const a=document.head||document.querySelector("head"),n=a.querySelectorAll(`${t}[${En}]`),i=[].slice.call(n),r=[];let o;return e&&e.length&&e.forEach(l=>{const c=document.createElement(t);for(const d in l)if(Object.prototype.hasOwnProperty.call(l,d))if(d==="innerHTML")c.innerHTML=l.innerHTML;else if(d==="cssText"){const u=l.cssText;c.appendChild(document.createTextNode(u))}else{const u=d,p=typeof l[u]>"u"?"":l[u];c.setAttribute(d,p)}c.setAttribute(En,"true"),i.some((d,u)=>(o=u,c.isEqualNode(d)))?i.splice(o,1):r.push(c)}
40),i.forEach(l=>{var c;return(c=l.parentNode)==null?void 0:c.removeChild(l)}),r.forEach(l=>a.appendChild(l)),{oldTags:i,newTags:r}},fv=(t,e)=>{const a=document.getElementsByTagName(t)[0];if(!a)return;const n=a.getAttribute(En),i=n?n.split(","):[],r=[...i],o=Object.keys(e);for(const l of o){const c=e[l]||"";a.getAttribute(l)!==c&&a.setAttribute(l,c),i.indexOf(l)===-1&&i.push(l);const d=r.indexOf(l);d!==-1&&r.splice(d,1)}for(let l=r.length-1;l>=0;l-=1)a.removeAttribute(r[l]);i.length===r.length?a.removeAttribute(En):a.getAttribute(En)!==o.join(",")&&a.setAttribute(En,o.join(","))},nV=(t,e)=>{typeof t<"u"&&document.title!==t&&(document.title=uP(t)),fv("title",e)},$_=(t,e)=>{const{baseTag:a,bodyAttributes:n,htmlAttributes:i,linkTags:r,metaTags:o,noscriptTags:l,onChangeClientState:c,scriptTags:d,styleTags:u,title:p,titleAttributes:m}=t;fv("body",n),fv("html",i),nV(p,m);const h={baseTag:ks("base",a),linkTags:ks("link",r),metaTags:ks("meta",o),noscriptTags:ks("noscript",l),scriptTags:ks("script",d),styleTags:ks("style",u)},g={},y={};Object.keys(h).forEach(x=>{const{newTags:v,oldTags:w}=h[x];v.length&&(g[x]=v),w.length&&(y[x]=h[x].oldTags)}),e&&e(),c(t,g,y)},Sc=null,iV=t=>{Sc&&cancelAnimationFrame(Sc),t.defer?Sc=requestAnimationFrame(()=>{$_(t,()=>{Sc=null})}):($_(t),Sc=null)},rV=iV,W_=class extends k.Component{constructor(){super(...arguments);di(this,"rendered",!1)}shouldComponentUpdate(e){return!Hz(e,this.props)}componentDidUpdate(){this.emitChange()}componentWillUnmount(){const{helmetInstances:e}=this.props.context;e.remove(this),this.emitChange()}emitChange(){const{helmetInstances:e,setHelmet:a}=this.props.context;let n=null;const i=Gz(e.get().map(r=>{const{context:o,...l}=r.props;return l}));fP.canUseDOM?rV(i):pv&&(n=pv(i)),a(n)}init(){if(this.rendered)return;this.rendered=!0;const{helmetInstances:e}=this.props.context;e.add(this),this.emitChange()}render(){return this.init(),null}},_m=[],G_=t=>{const e={};for(const a of Object.keys(t))e[dP[a]||a]=t[a];return e},lo=t=>{const e={};for(const a of Object.keys(t)){const n=eg[a];e[n||a]=t[a]}return e},K_=(t,e)=>{if(!K1)return;const a=document.getElementsByTagName(t)[0];if(!a)return;const n="data-rh-managed",i=a.getAttribute(n),r=i?i.split(","):[],o=Object.keys(e);for(const l of r)o.includes(l)||a.removeAttribute(l);for(const l of o){const c=e[l];c==null||c===!1?a.removeAttribute(l):c===!0?a.setAttribute(l,""):a.setAttribute(l,String(c))}o.length>0?a.setAttribute(n,o.join(",")):a.removeAttribute(n)},Xy=()=>{const t={},e={};for(const a of _m){const{htmlAttributes:n,bodyAttributes:i}=a.props;n&&Object.assign(t,G_(n)),i&&Object.assign(e,G_(i))}K_("html",t),K_("body",e)},oV=class extends k.Component{componentDidMount(){_m.push(this),Xy()}componentDidUpdate(){Xy()}componentWillUnmount(){const t=_m.indexOf(this);t!==-1&&_m.splice(t,1),Xy()}resolveTitle(){const{title:t,titleTemplate:e,defaultTitle:a}=this.props;return t&&e?e.replace(/%s/g,()=>Array.isArray(t)?t.join(""):t):t||a||void 0}renderTitle(){const t=this.resolveTitle();if(t===void 0)return null;const e=this.props.titleAttributes||{};return Re.createElement("title",lo(e),t)}renderBase(){const{base:t}=this.props;return t?Re.createElement("base",lo(t)):null}renderMeta(){const{meta:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>Re.createElement("meta",{key:a,...lo(e)}))}renderLink(){const{link:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>Re.createElement("link",{key:a,...lo(e)}))}renderScript(){const{script:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>{const{innerHTML:n,...i}=e,r=lo(i);return n&&(r.dangerouslySetInnerHTML={__html:n}),Re.createElement("script",{key:a,...r})})}renderStyle(){const{style:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>{const{cssText:n,...i}=e,r=lo(i);return n&&(r.dangerouslySetInnerHTML={__html:n}),Re.createElement("style",{key:a,...r})})}renderNoscript(){const{noscript:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>{const{innerHTML:n,...i}=e,r=lo(i);return n&&(r.dangerouslySetInnerHTML={__html:n}),Re.createElement("noscript",{key:a,...r})})}render(){return Re.createElement(Re.Fragment,null,this.renderTitle(),this.renderBase(),this.renderMeta(),this.renderLink(),this.renderScript(),this.renderStyle(),this.renderNoscript())}},yx,gP=(yx=class extends k.Component{shouldComponentUpdate(t){return!Dz(U_(this.props,"helmetData"),U_(t,"helmetData"))}mapNestedChildrenToProps(t,e){if(!e)return null;switch(t.type){case"script":case"noscript":return{innerHTML:e};case"style":return{cssText:e};default:throw new Error(`<${t.type} /> elements are self-closing and can not contain children. Refer to our API for more information.`)}}flattenArrayTypeChildren(t,e,a,n){return{...e,[t.type]:[...e[t.type]||[],{...a,...this.mapNestedChildrenToProps(t,n)}]}}mapObjectTypeChildren(t,e,a,n){switch(t.type){case"title":return{...e,[t.type]:n,titleAttributes:{...a}};case"body":return{...e,bodyAttributes:{...a}};case"html":return{...e,htmlAttributes:{...a}};default:return{...e,[t.type]:{...a}}}}mapArrayTypeChildrenToProps(t,e){let a={...e};return Object.keys(t).forEach(n=>{a={...a,[n]:t[n]}}),a}
40warnOnInvalidChildren(t,e){return F_(B_.some(a=>t.type===a),typeof t.type=="function"?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":`Only elements types ${B_.join(", ")} are allowed. Helmet does not support rendering <${t.type}> elements. Refer to our API for more information.`),F_(!e||typeof e=="string"||Array.isArray(e)&&!e.some(a=>typeof a!="string"),`Helmet expects a string as a child of <${t.type}>. Did you forget to wrap your children in braces? ( <${t.type}>{\`\`}</${t.type}> ) Refer to our API for more information.`),!0}mapChildrenToProps(t,e){let a={};return Re.Children.forEach(t,n=>{if(!n||!n.props)return;const{children:i,...r}=n.props,o=Object.keys(r).reduce((c,d)=>(c[dP[d]||d]=r[d],c),{});let{type:l}=n;switch(typeof l=="symbol"?l=l.toString():this.warnOnInvalidChildren(n,i),l){case"Symbol(react.fragment)":e=this.mapChildrenToProps(i,e);break;case"link":case"meta":case"noscript":case"script":case"style":a=this.flattenArrayTypeChildren(n,a,o,i);break;default:e=this.mapObjectTypeChildren(n,e,o,i);break}}),this.mapArrayTypeChildrenToProps(a,e)}render(){const{children:t,...e}=this.props;let a={...e},{helmetData:n}=e;if(t&&(a=this.mapChildrenToProps(t,a)),n&&!(n instanceof mv)){const i=n;n=new mv(i.context,!0),delete a.helmetData}return hv?Re.createElement(oV,{...a}):n?Re.createElement(W_,{...a,context:n.value}):Re.createElement(hP.Consumer,null,i=>Re.createElement(W_,{...a,context:i}))}},di(yx,"defaultProps",{defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1}),yx);/** 41 * react-router v7.12.0 42 * 43 * Copyright (c) Remix Software Inc. 44 * 45 * This source code is licensed under the MIT license found in the 46 * LICENSE.md file in the root directory of this source tree. 47 * 48 * @license MIT 49 */var J_="popstate";function sV(t={}){function e(n,i){let{pathname:r,search:o,hash:l}=n.location;return gv("",{pathname:r,search:o,hash:l},i.state&&i.state.usr||null,i.state&&i.state.key||"default")}function a(n,i){return typeof i=="string"?i:Gd(i)}return cV(e,a,null,t)}function Ke(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)}function Wa(t,e){if(!t){typeof console<"u"&&console.warn(e);try{throw new Error(e)}catch{}}}function lV(){return Math.random().toString(36).substring(2,10)}function Q_(t,e){return{usr:t.state,key:t.key,idx:e}}function gv(t,e,a=null,n){return{pathname:typeof t=="string"?t:t.pathname,search:"",hash:"",...typeof e=="string"?Hl(e):e,state:a,key:e&&e.key||n||lV()}}function Gd({pathname:t="/",search:e="",hash:a=""}){return e&&e!=="?"&&(t+=e.charAt(0)==="?"?e:"?"+e),a&&a!=="#"&&(t+=a.charAt(0)==="#"?a:"#"+a),t}function Hl(t){let e={};if(t){let a=t.indexOf("#");a>=0&&(e.hash=t.substring(a),t=t.substring(0,a));let n=t.indexOf("?");n>=0&&(e.search=t.substring(n),t=t.substring(0,n)),t&&(e.pathname=t)}return e}function cV(t,e,a,n={}){let{window:i=document.defaultView,v5Compat:r=!1}=n,o=i.history,l="POP",c=null,d=u();d==null&&(d=0,o.replaceState({...o.state,idx:d},""));function u(){return(o.state||{idx:null}).idx}function p(){l="POP";let x=u(),v=x==null?null:x-d;d=x,c&&c({action:l,location:y.location,delta:v})}function m(x,v){l="PUSH";let w=gv(y.location,x,v);d=u()+1;let S=Q_(w,d),T=y.createHref(w);try{o.pushState(S,"",T)}catch(P){if(P instanceof DOMException&&P.name==="DataCloneError")throw P;i.location.assign(T)}r&&c&&c({action:l,location:y.location,delta:1})}function h(x,v){l="REPLACE";let w=gv(y.location,x,v);d=u();let S=Q_(w,d),T=y.createHref(w);o.replaceState(S,"",T),r&&c&&c({action:l,location:y.location,delta:0})}function g(x){return dV(x)}let y={get action(){return l},get location(){return t(i,o)}
49,listen(x){if(c)throw new Error("A history only accepts one active listener");return i.addEventListener(J_,p),c=x,()=>{i.removeEventListener(J_,p),c=null}},createHref(x){return e(i,x)},createURL:g,encodeLocation(x){let v=g(x);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:m,replace:h,go(x){return o.go(x)}};return y}function dV(t,e=!1){let a="http://localhost";typeof window<"u"&&(a=window.location.origin!=="null"?window.location.origin:window.location.href),Ke(a,"No window.location.(origin|href) available to create URL");let n=typeof t=="string"?t:Gd(t);return n=n.replace(/ $/,"%20"),!e&&n.startsWith("//")&&(n=a+n),new URL(n,a)}function yP(t,e,a="/"){return uV(t,e,a,!1)}function uV(t,e,a,n){let i=typeof e=="string"?Hl(e):e,r=Di(i.pathname||"/",a);if(r==null)return null;let o=xP(t);pV(o);let l=null;for(let c=0;l==null&&c<o.length;++c){let d=SV(r);l=wV(o[c],d,n)}return l}function xP(t,e=[],a=[],n="",i=!1){let r=(o,l,c=i,d)=>{let u={relativePath:d===void 0?o.path||"":d,caseSensitive:o.caseSensitive===!0,childrenIndex:l,route:o};if(u.relativePath.startsWith("/")){if(!u.relativePath.startsWith(n)&&c)return;Ke(u.relativePath.startsWith(n),`Absolute route path "${u.relativePath}" nested under path "${n}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),u.relativePath=u.relativePath.slice(n.length)}let p=Ci([n,u.relativePath]),m=a.concat(u);o.children&&o.children.length>0&&(Ke(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${p}".`),xP(o.children,e,m,p,c)),!(o.path==null&&!o.index)&&e.push({path:p,score:vV(p,o.index),routesMeta:m})};return t.forEach((o,l)=>{var c;if(o.path===""||!((c=o.path)!=null&&c.includes("?")))r(o,l);else for(let d of vP(o.path))r(o,l,!0,d)}),e}function vP(t){let e=t.split("/");if(e.length===0)return[];let[a,...n]=e,i=a.endsWith("?"),r=a.replace(/\?$/,"");if(n.length===0)return i?[r,""]:[r];let o=vP(n.join("/")),l=[];return l.push(...o.map(c=>c===""?r:[r,c].join("/"))),i&&l.push(...o),l.map(c=>t.startsWith("/")&&c===""?"/":c)}function pV(t){t.sort((e,a)=>e.score!==a.score?a.score-e.score:bV(e.routesMeta.map(n=>n.childrenIndex),a.routesMeta.map(n=>n.childrenIndex)))}var mV=/^:[\w-]+$/,hV=3,fV=2,gV=1,yV=10,xV=-2,X_=t=>t==="*";function vV(t,e){let a=t.split("/"),n=a.length;return a.some(X_)&&(n+=xV),e&&(n+=fV),a.filter(i=>!X_(i)).reduce((i,r)=>i+(mV.test(r)?hV:r===""?gV:yV),n)}function bV(t,e){return t.length===e.length&&t.slice(0,-1).every((n,i)=>n===e[i])?t[t.length-1]-e[e.length-1]:0}function wV(t,e,a=!1){let{routesMeta:n}=t,i={},r="/",o=[];for(let l=0;l<n.length;++l){let c=n[l],d=l===n.length-1,u=r==="/"?e:e.slice(r.length)||"/",p=xh({path:c.relativePath,caseSensitive:c.caseSensitive,end:d},u),m=c.route;if(!p&&d&&a&&!n[n.length-1].route.index&&(p=xh({path:c.relativePath,caseSensitive:c.caseSensitive,end:!1},u)),!p)return null;
49Object.assign(i,p.params),o.push({params:i,pathname:Ci([r,p.pathname]),pathnameBase:CV(Ci([r,p.pathnameBase])),route:m}),p.pathnameBase!=="/"&&(r=Ci([r,p.pathnameBase]))}return o}function xh(t,e){typeof t=="string"&&(t={path:t,caseSensitive:!1,end:!0});let[a,n]=kV(t.path,t.caseSensitive,t.end),i=e.match(a);if(!i)return null;let r=i[0],o=r.replace(/(.)\/+$/,"$1"),l=i.slice(1);return{params:n.reduce((d,{paramName:u,isOptional:p},m)=>{if(u==="*"){let g=l[m]||"";o=r.slice(0,r.length-g.length).replace(/(.)\/+$/,"$1")}const h=l[m];return p&&!h?d[u]=void 0:d[u]=(h||"").replace(/%2F/g,"/"),d},{}),pathname:r,pathnameBase:o,pattern:t}}function kV(t,e=!1,a=!0){Wa(t==="*"||!t.endsWith("*")||t.endsWith("/*"),`Route path "${t}" will be treated as if it were "${t.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${t.replace(/\*$/,"/*")}".`);let n=[],i="^"+t.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,l,c)=>(n.push({paramName:l,isOptional:c!=null}),c?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return t.endsWith("*")?(n.push({paramName:"*"}),i+=t==="*"||t==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):a?i+="\\/*$":t!==""&&t!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,e?void 0:"i"),n]}function SV(t){try{return t.split("/").map(e=>decodeURIComponent(e).replace(/\//g,"%2F")).join("/")}catch(e){return Wa(!1,`The URL path "${t}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${e}).`),t}}function Di(t,e){if(e==="/")return t;if(!t.toLowerCase().startsWith(e.toLowerCase()))return null;let a=e.endsWith("/")?e.length-1:e.length,n=t.charAt(a);return n&&n!=="/"?null:t.slice(a)||"/"}var bP=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,_V=t=>bP.test(t);function AV(t,e="/"){let{pathname:a,search:n="",hash:i=""}=typeof t=="string"?Hl(t):t,r;if(a)if(_V(a))r=a;else{if(a.includes("//")){let o=a;a=a.replace(/\/\/+/g,"/"),Wa(!1,`Pathnames cannot have embedded double slashes - normalizing ${o} -> ${a}`)}a.startsWith("/")?r=Y_(a.substring(1),"/"):r=Y_(a,e)}else r=e;return{pathname:r,search:jV(n),hash:TV(i)}}function Y_(t,e){let a=e.replace(/\/+$/,"").split("/");return t.split("/").forEach(i=>{i===".."?a.length>1&&a.pop():i!=="."&&a.push(i)}),a.length>1?a.join("/"):"/"}function Yy(t,e,a,n){return`Cannot include a '${t}' character in a manually specified \`to.${e}\` field [${JSON.stringify(n)}]. Please separate it out to the \`to.${a}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function EV(t){return t.filter((e,a)=>a===0||e.route.path&&e.route.path.length>0)}function J1(t){let e=EV(t);return e.map((a,n)=>n===e.length-1?a.pathname:a.pathnameBase)}function Q1(t,e,a,n=!1){let i;typeof t=="string"?i=Hl(t):(i={...t},Ke(!i.pathname||!i.pathname.includes("?"),Yy("?","pathname","search",i)),Ke(!i.pathname||!i.pathname.includes("#"),Yy("#","pathname","hash",i)),Ke(!i.search||!i.search.includes("#"),Yy("#","search","hash",i)));let r=t===""||i.pathname==="",o=r?"/":i.pathname,l;if(o==null)l=a;else{let p=e.length-1;if(!n&&o.startsWith("..")){let m=o.split("/");for(;m[0]==="..";)m.shift(),p-=1;i.pathname=m.join("/")}l=p>=0?e[p]:"/"}let c=AV(i,l),d=o&&o!=="/"&&o.endsWith("/"),u=(r||o===".")&&a.endsWith("/");return!c.pathname.endsWith("/")&&(d||u)&&(c.pathname+="/"),c}var Ci=t=>t.join("/").replace(/\/\/+/g,"/"),CV=t=>t.replace(/\/+$/,"").replace(/^\/*/,"/"),jV=t=>!t||t==="?"?"":t.startsWith("?")?t:"?"+t,TV=t=>!t||t==="#"?"":t.startsWith("#")?t:"#"+t,NV=class{constructor(t,e,a,n=!1){this.status=t,this.statusText=e||"",this.internal=n,a instanceof Error?(this.data=a.toString(),this.error=a):this.data=a}};function IV(t){return t!=null&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.internal=="boolean"&&"data"in t}function PV(t){return t.map(e=>e.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var wP=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function kP(t,e){let a=t;if(typeof a!="string"||!bP.test(a))return{absoluteURL:void 0,isExternal:!1,to:a};let n=a,i=!1;if(wP)try{let r=new URL(window.location.href),o=a.startsWith("//")?new URL(r.protocol+a):new URL(a),l=Di(o.pathname,e);o.origin===r.origin&&l!=null?a=l+o.search+o.hash:i=!0}catch{Wa(!1,`<Link to="${a}">
49 contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:n,isExternal:i,to:a}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var SP=["POST","PUT","PATCH","DELETE"];new Set(SP);var RV=["GET",...SP];new Set(RV);var Fl=k.createContext(null);Fl.displayName="DataRouter";var tg=k.createContext(null);tg.displayName="DataRouterState";var LV=k.createContext(!1),_P=k.createContext({isTransitioning:!1});_P.displayName="ViewTransition";var OV=k.createContext(new Map);OV.displayName="Fetchers";var MV=k.createContext(null);MV.displayName="Await";var Ja=k.createContext(null);Ja.displayName="Navigation";var Cu=k.createContext(null);Cu.displayName="Location";var zn=k.createContext({outlet:null,matches:[],isDataRoute:!1});zn.displayName="Route";var X1=k.createContext(null);X1.displayName="RouteError";var AP="REACT_ROUTER_ERROR",DV="REDIRECT",qV="ROUTE_ERROR_RESPONSE";function zV(t){if(t.startsWith(`${AP}:${DV}:{`))try{let e=JSON.parse(t.slice(28));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.location=="string"&&typeof e.reloadDocument=="boolean"&&typeof e.replace=="boolean")return e}catch{}}function VV(t){if(t.startsWith(`${AP}:${qV}:{`))try{let e=JSON.parse(t.slice(40));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string")return new NV(e.status,e.statusText,e.data)}catch{}}function HV(t,{relative:e}={}){Ke(Bl(),"useHref() may be used only in the context of a <Router> component.");let{basename:a,navigator:n}=k.useContext(Ja),{hash:i,pathname:r,search:o}=ju(t,{relative:e}),l=r;return a!=="/"&&(l=r==="/"?a:Ci([a,r])),n.createHref({pathname:l,search:o,hash:i})}function Bl(){return k.useContext(Cu)!=null}function fn(){return Ke(Bl(),"useLocation() may be used only in the context of a <Router> component."),k.useContext(Cu).location}var EP="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function CP(t){k.useContext(Ja).static||k.useLayoutEffect(t)}function Qa(){let{isDataRoute:t}=k.useContext(zn);return t?e8():FV()}function FV(){Ke(Bl(),"useNavigate() may be used only in the context of a <Router> component.");let t=k.useContext(Fl),{basename:e,navigator:a}=k.useContext(Ja),{matches:n}=k.useContext(zn),{pathname:i}=fn(),r=JSON.stringify(J1(n)),o=k.useRef(!1);return CP(()=>{o.current=!0}),k.useCallback((c,d={})=>{if(Wa(o.current,EP),!o.current)return;if(typeof c=="number"){a.go(c);return}let u=Q1(c,JSON.parse(r),i,d.relative==="path");t==null&&e!=="/"&&(u.pathname=u.pathname==="/"?e:Ci([e,u.pathname])),(d.replace?a.replace:a.push)(u,d.state,d)},[e,a,r,i,t])}k.createContext(null);function jP(){let{matches:t}=k.useContext(zn),e=t[t.length-1];return e?e.params:{}}function ju(t,{relative:e}={}){let{matches:a}=k.useContext(zn),{pathname:n}=fn(),i=JSON.stringify(J1(a));return k.useMemo(()=>Q1(t,JSON.parse(i),n,e==="path"),[t,i,n,e])}function BV(t,e){return TP(t,e)}function TP(t,e,a,n,i){var w;Ke(Bl(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:r}=k.useContext(Ja),{matches:o}=k.useContext(zn),l=o[o.length-1],c=l?l.params:{},d=l?l.pathname:"/",u=l?l.pathnameBase:"/",p=l&&l.route;{let S=p&&p.path||"";IP(d,!p||S.endsWith("*")||S.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${d}" (under <Route path="${S}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. 50 51Please change the parent <Route path="${S}"> to <Route path="${S==="/"?"*":`${S}/*`}">.`)}let m=fn(),h;if(e){let S=typeof e=="string"?Hl(e):e;Ke(u==="/"||((w=S.pathname)==null?void 0:w.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${S.pathname}" was given in the \`location\` prop.`),h=S}else h=m;let g=h.pathname||"/",y=g;if(u!=="/"){let S=u.replace(/^\//,"").split("/");y="/"+g.replace(/^\//,"").split("/").slice(S.length).join("/")}let x=yP(t,{pathname:y});Wa(p||x!=null,`No routes matched location "${h.pathname}${h.search}${h.hash}" `),Wa(x==null||x[x.length-1].route.element!==void 0||x[x.length-1].route.Component!==void 0||x[x.length-1].route.lazy!==void 0,`Matched leaf route at location "${h.pathname}${h.search}${h.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let v=KV(x&&x.map(S=>Object.assign({},S,{params:Object.assign({},c,S.params),pathname:Ci([u,r.encodeLocation?r.encodeLocation(S.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:S.pathname]),pathnameBase:S.pathnameBase==="/"?u:Ci([u,r.encodeLocation?r.encodeLocation(S.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:S.pathnameBase])})),o,a,n,i);return e&&v?k.createElement(Cu.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...h},navigationType:"POP"}},v):v}function UV(){let t=ZV(),e=IV(t)?`${t.status} ${t.statusText}`:t instanceof Error?t.message:JSON.stringify(t),a=t instanceof Error?t.stack:null,n="rgba(200,200,200, 0.5)",i={padding:"0.5rem",backgroundColor:n},r={padding:"2px 4px",backgroundColor:n},o=null;return console.error("Error handled by React Router default ErrorBoundary:",t),o=k.createElement(k.Fragment,null,k.createElement("p",null,"ð¿ Hey developer ð"),k.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",k.createElement("code",{style:r},"ErrorBoundary")," or"," ",k.createElement("code",{style:r},"errorElement")," prop on your route.")),k.createElement(k.Fragment,null,k.createElement("h2",null,"Unexpected Application
51Error!"),k.createElement("h3",{style:{fontStyle:"italic"}},e),a?k.createElement("pre",{style:i},a):null,o)}var $V=k.createElement(UV,null),NP=class extends k.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,e){return e.location!==t.location||e.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:e.error,location:e.location,revalidation:t.revalidation||e.revalidation}}componentDidCatch(t,e){this.props.onError?this.props.onError(t,e):console.error("React Router caught the following error during render",t)}render(){let t=this.state.error;if(this.context&&typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){const a=VV(t.digest);a&&(t=a)}let e=t!==void 0?k.createElement(zn.Provider,{value:this.props.routeContext},k.createElement(X1.Provider,{value:t,children:this.props.component})):this.props.children;return this.context?k.createElement(WV,{error:t},e):e}};NP.contextType=LV;var Zy=new WeakMap;function WV({children:t,error:e}){let{basename:a}=k.useContext(Ja);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let n=zV(e.digest);if(n){let i=Zy.get(e);if(i)throw i;let r=kP(n.location,a);if(wP&&!Zy.get(e))if(r.isExternal||n.reloadDocument)window.location.href=r.absoluteURL||r.to;else{const o=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(r.to,{replace:n.replace}));throw Zy.set(e,o),o}return k.createElement("meta",{httpEquiv:"refresh",content:`0;url=${r.absoluteURL||r.to}`})}}return t}function GV({routeContext:t,match:e,children:a}){let n=k.useContext(Fl);return n&&n.static&&n.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(n.staticContext._deepestRenderedBoundaryId=e.route.id),k.createElement(zn.Provider,{value:t},a)}function KV(t,e=[],a=null,n=null,i=null){if(t==null){if(!a)return null;if(a.errors)t=a.matches;else if(e.length===0&&!a.initialized&&a.matches.length>0)t=a.matches;else return null}let r=t,o=a==null?void 0:a.errors;if(o!=null){let u=r.findIndex(p=>p.route.id&&(o==null?void 0:o[p.route.id])!==void 0);Ke(u>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),r=r.slice(0,Math.min(r.length,u+1))}let l=!1,c=-1;if(a)for(let u=0;u<r.length;u++){let p=r[u];if((p.route.HydrateFallback||p.route.hydrateFallbackElement)&&(c=u),p.route.id){let{loaderData:m,errors:h}=a,g=p.route.loader&&!m.hasOwnProperty(p.route.id)&&(!h||h[p.route.id]===void 0);if(p.route.lazy||g){l=!0,c>=0?r=r.slice(0,c+1):r=[r[0]];break}}}let d=a&&n?(u,p)=>{var m,h;n(u,{location:a.location,params:((h=(m=a.matches)==null?void 0:m[0])==null?void 0:h.params)??{},unstable_pattern:PV(a.matches),errorInfo:p})}:void 0;return r.reduceRight((u,p,m)=>{let h,g=!1,y=null,x=null;a&&(h=o&&p.route.id?o[p.route.id]:void 0,y=p.route.errorElement||$V,l&&(c<0&&m===0?(IP("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),g=!0,x=null):c===m&&(g=!0,x=p.route.hydrateFallbackElement||null)));let v=e.concat(r.slice(0,m+1)),w=()=>{let S;return h?S=y:g?S=x:p.route.Component?S=k.createElement(p.route.Component,null):p.route.element?S=p.route.element:S=u,k.createElement(GV,{match:p,routeContext:{outlet:u,matches:v,isDataRoute:a!=null},children:S})};return a&&(p.route.ErrorBoundary||p.route.errorElement||m===0)?k.createElement(NP,{location:a.location,revalidation:a.revalidation,component:y,error:h,children:w(),routeContext:{outlet:null,matches:v,isDataRoute:!0},onError:d}):w()},null)}function Y1(t){return`${t} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function JV(t){let e=k.useContext(Fl);return Ke(e,Y1(t)),e}function QV(t){let e=k.useContext(tg);return Ke(e,Y1(t)),e}function XV(t){let e=k.useContext(zn);return Ke(e,Y1(t)),e}function Z1(t){let e=XV(t),a=e.matches[e.matches.length-1];return Ke(a.route.id,`${t} can only be used on routes that contain a unique "id"`),a.route.id}function YV(){return Z1("useRouteId")}function ZV(){var n;let t=k.useContext(X1),e=QV("useRouteError"),a=Z1("useRouteError");return t!==void 0?t:(n=e.errors)==null?void 0:n[a]}function e8(){let{router:t}=JV("useNavigate"),e=Z1("useNavigate"),a=k.useRef(!1);return CP(()=>{a.current=!0}),k.useCallback(async(i,r={})=>{Wa(a.current,EP),a.current&&(typeof i=="number"?await t.navigate(i):await t.navigate(i,{fromRouteId:e,...r}))},[t,e])}var Z_={};function IP(t,e,a){!e&&!Z_[t]&&(Z_[t]=!0,Wa(!1,a))}k.memo(t8);function t8({routes:t,future:e,state:a,onError:n}){return TP(t,void 0,a,n,e)}function ew({to:t,replace:e,state:a,relative:n}){Ke(Bl(),"<Navigate> may be used only in the context of a <Router> component.");let{static:i}=k.useContext(Ja);Wa(!i,"<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.");let{matches:r}=k.useContext(zn),{pathname:o}=fn(),l=Qa(),c=Q1(t,J1(r),o,n==="path"),d=JSON.stringify(c);return k.useEffect(()=>{l(JSON.parse(d),{replace:e,state:a,relative:n})},[l,d,n,e,a]),null}function le(t){Ke(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function a8({basename:t="/",children:e=null,location:a,navigationType:n="POP",navigator:i,static:r=!1,unstable_useTransitions:o}){Ke(!Bl(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let l=t.replace(/^\/*/,"/"),c=k.useMemo(()=>({basename:l,navigator:i,static:r,unstable_useTransitions:o,future:{}}),[l,i,r,o]);
51typeof a=="string"&&(a=Hl(a));let{pathname:d="/",search:u="",hash:p="",state:m=null,key:h="default"}=a,g=k.useMemo(()=>{let y=Di(d,l);return y==null?null:{location:{pathname:y,search:u,hash:p,state:m,key:h},navigationType:n}},[l,d,u,p,m,h,n]);return Wa(g!=null,`<Router basename="${l}"> is not able to match the URL "${d}${u}${p}" because it does not start with the basename, so the <Router> won't render anything.`),g==null?null:k.createElement(Ja.Provider,{value:c},k.createElement(Cu.Provider,{children:e,value:g}))}function n8({children:t,location:e}){return BV(yv(t),e)}function yv(t,e=[]){let a=[];return k.Children.forEach(t,(n,i)=>{if(!k.isValidElement(n))return;let r=[...e,i];if(n.type===k.Fragment){a.push.apply(a,yv(n.props.children,r));return}Ke(n.type===le,`[${typeof n.type=="string"?n.type:n.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),Ke(!n.props.index||!n.props.children,"An index route cannot have child routes.");let o={id:n.props.id||r.join("-"),caseSensitive:n.props.caseSensitive,element:n.props.element,Component:n.props.Component,index:n.props.index,path:n.props.path,middleware:n.props.middleware,loader:n.props.loader,action:n.props.action,hydrateFallbackElement:n.props.hydrateFallbackElement,HydrateFallback:n.props.HydrateFallback,errorElement:n.props.errorElement,ErrorBoundary:n.props.ErrorBoundary,hasErrorBoundary:n.props.hasErrorBoundary===!0||n.props.ErrorBoundary!=null||n.props.errorElement!=null,shouldRevalidate:n.props.shouldRevalidate,handle:n.props.handle,lazy:n.props.lazy};n.props.children&&(o.children=yv(n.props.children,r)),a.push(o)}),a}var Am="get",Em="application/x-www-form-urlencoded";function ag(t){return typeof HTMLElement<"u"&&t instanceof HTMLElement}function i8(t){return ag(t)&&t.tagName.toLowerCase()==="button"}function r8(t){return ag(t)&&t.tagName.toLowerCase()==="form"}function o8(t){return ag(t)&&t.tagName.toLowerCase()==="input"}function s8(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}function l8(t,e){return t.button===0&&(!e||e==="_self")&&!s8(t)}function xv(t=""){return new URLSearchParams(typeof t=="string"||Array.isArray(t)||t instanceof URLSearchParams?t:Object.keys(t).reduce((e,a)=>{let n=t[a];return e.concat(Array.isArray(n)?n.map(i=>[a,i]):[[a,n]])},[]))}function c8(t,e){let a=xv(t);return e&&e.forEach((n,i)=>{a.has(i)||e.getAll(i).forEach(r=>{a.append(i,r)})}),a}var Rp=null;function d8(){if(Rp===null)try{new FormData(document.createElement("form"),0),Rp=!1}catch{Rp=!0}return Rp}var u8=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function e0(t){return t!=null&&!u8.has(t)?(Wa(!1,`"${t}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${Em}"`),null):t}function p8(t,e){let a,n,i,r,o;if(r8(t)){let l=t.getAttribute("action");n=l?Di(l,e):null,a=t.getAttribute("method")||Am,i=e0(t.getAttribute("enctype"))||Em,r=new FormData(t)}else if(i8(t)||o8(t)&&(t.type==="submit"||t.type==="image")){let l=t.form;if(l==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let c=t.getAttribute("formaction")||l.getAttribute("action");if(n=c?Di(c,e):null,a=t.getAttribute("formmethod")||l.getAttribute("method")||Am,i=e0(t.getAttribute("formenctype"))||e0(l.getAttribute("enctype"))||Em,r=new FormData(l,t),!d8()){let{name:d,type:u,value:p}=t;if(u==="image"){let m=d?`${d}.`:"";r.append(`${m}x`,"0"),r.append(`${m}y`,"0")}else d&&r.append(d,p)}}else{if(ag(t))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');a=Am,n=null,i=Em,o=t}return r&&i==="text/plain"&&(o=r,r=void 0),{action:n,method:a.toLowerCase(),encType:i,formData:r,body:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function tw(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)}function m8(t,e,a,n){let i=typeof t=="string"?new URL(t,typeof window>"u"?"server://singlefetch/":window.location.origin):t;return a?i.pathname.endsWith("/")?i.pathname=`${i.pathname}_.${n}`:i.pathname=`${i.pathname}.${n}`:i.pathname==="/"?i.pathname=`_root.${n}`:e&&Di(i.pathname,e)==="/"?i.pathname=`${e.replace(/\/$/,"")}/_root.${n}`:i.pathname=`${i.pathname.replace(/\/$/,"")}.${n}`,i}async function h8(t,e){if(t.id in e)return e[t.id];try{let a=await import(t.module);return e[t.id]=a,a}catch(a){return console.error(`Error loading route module \`${t.module}\`, reloading page...`),console.error(a),window.__reactRouterContext&&window.__reactRouterContext.
51isSpaMode,window.location.reload(),new Promise(()=>{})}}function f8(t){return t==null?!1:t.href==null?t.rel==="preload"&&typeof t.imageSrcSet=="string"&&typeof t.imageSizes=="string":typeof t.rel=="string"&&typeof t.href=="string"}async function g8(t,e,a){let n=await Promise.all(t.map(async i=>{let r=e.routes[i.route.id];if(r){let o=await h8(r,a);return o.links?o.links():[]}return[]}));return b8(n.flat(1).filter(f8).filter(i=>i.rel==="stylesheet"||i.rel==="preload").map(i=>i.rel==="stylesheet"?{...i,rel:"prefetch",as:"style"}:{...i,rel:"prefetch"}))}function eA(t,e,a,n,i,r){let o=(c,d)=>a[d]?c.route.id!==a[d].route.id:!0,l=(c,d)=>{var u;return a[d].pathname!==c.pathname||((u=a[d].route.path)==null?void 0:u.endsWith("*"))&&a[d].params["*"]!==c.params["*"]};return r==="assets"?e.filter((c,d)=>o(c,d)||l(c,d)):r==="data"?e.filter((c,d)=>{var p;let u=n.routes[c.route.id];if(!u||!u.hasLoader)return!1;if(o(c,d)||l(c,d))return!0;if(c.route.shouldRevalidate){let m=c.route.shouldRevalidate({currentUrl:new URL(i.pathname+i.search+i.hash,window.origin),currentParams:((p=a[0])==null?void 0:p.params)||{},nextUrl:new URL(t,window.origin),nextParams:c.params,defaultShouldRevalidate:!0});if(typeof m=="boolean")return m}return!0}):[]}function y8(t,e,{includeHydrateFallback:a}={}){return x8(t.map(n=>{let i=e.routes[n.route.id];if(!i)return[];let r=[i.module];return i.clientActionModule&&(r=r.concat(i.clientActionModule)),i.clientLoaderModule&&(r=r.concat(i.clientLoaderModule)),a&&i.hydrateFallbackModule&&(r=r.concat(i.hydrateFallbackModule)),i.imports&&(r=r.concat(i.imports)),r}).flat(1))}function x8(t){return[...new Set(t)]}function v8(t){let e={},a=Object.keys(t).sort();for(let n of a)e[n]=t[n];return e}function b8(t,e){let a=new Set;return new Set(e),t.reduce((n,i)=>{let r=JSON.stringify(v8(i));return a.has(r)||(a.add(r),n.push({key:r,link:i})),n},[])}function PP(){let t=k.useContext(Fl);return tw(t,"You must render this element inside a <DataRouterContext.Provider> element"),t}function w8(){let t=k.useContext(tg);return tw(t,"You must render this element inside a <DataRouterStateContext.Provider> element"),t}var aw=k.createContext(void 0);aw.displayName="FrameworkContext";function RP(){let t=k.useContext(aw);return tw(t,"You must render this element inside a <HydratedRouter> element"),t}function k8(t,e){let a=k.useContext(aw),[n,i]=k.useState(!1),[r,o]=k.useState(!1),{onFocus:l,onBlur:c,onMouseEnter:d,onMouseLeave:u,onTouchStart:p}=e,m=k.useRef(null);k.useEffect(()=>{if(t==="render"&&o(!0),t==="viewport"){let y=v=>{v.forEach(w=>{o(w.isIntersecting)})},x=new IntersectionObserver(y,{threshold:.5});return m.current&&x.observe(m.current),()=>{x.disconnect()}}},[t]),k.useEffect(()=>{if(n){let y=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(y)}}},[n]);let h=()=>{i(!0)},g=()=>{i(!1),o(!1)};return a?t!=="intent"?[r,m,{}]:[r,m,{onFocus:_c(l,h),onBlur:_c(c,g),onMouseEnter:_c(d,h),onMouseLeave:_c(u,g),onTouchStart:_c(p,h)}]:[!1,m,{}]}function _c(t,e){return a=>{t&&t(a),a.defaultPrevented||e(a)}}function S8({page:t,...e}){let{router:a}=PP(),n=k.useMemo(()=>yP(a.routes,t,a.basename),[a.routes,t,a.basename]);return n?k.createElement(A8,{page:t,matches:n,...e}):null}function _8(t){let{manifest:e,routeModules:a}=RP(),[n,i]=k.useState([]);return k.useEffect(()=>{let r=!1;return g8(t,e,a).then(o=>{r||i(o)}),()=>{r=!0}},[t,e,a]),n}function A8({page:t,matches:e,...a}){let n=fn(),{future:i,manifest:r,routeModules:o}=RP(),{basename:l}=PP(),{loaderData:c,matches:d}=w8(),u=k.useMemo(()=>eA(t,e,d,r,n,"data"),[t,e,d,r,n]),p=k.useMemo(()=>eA(t,e,d,r,n,"assets"),[t,e,d,r,n]),m=k.useMemo(()=>{if(t===n.pathname+n.search+n.hash)return[];let y=new Set,x=!1;if(e.forEach(w=>{var T;let S=r.routes[w.route.id];!S||!S.hasLoader||(!u.some(P=>P.route.id===w.route.id)&&w.route.id in c&&((T=o[w.route.id])!=null&&T.shouldRevalidate)||S.hasClientLoader?x=!0:y.add(w.route.id))}),y.size===0)return[];let v=m8(t,l,i.unstable_trailingSlashAwareDataRequests,"data");return x&&y.size>0&&v.searchParams.set("_routes",e.filter(w=>y.has(w.route.id)).map(w=>w.route.id).join(",")),[v.pathname+v.search]},[l,i.unstable_trailingSlashAwareDataRequests,c,n,r,u,e,t,o]),h=k.useMemo(()=>y8(p,r),[p,r]),g=_8(p);return k.createElement(k.Fragment,null,m.map(y=>k.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...a})),h.map(y=>k.createElement("link",{key:y,rel:"modulepreload",href:y,...a})),g.map(({key:y,link:x})=>k.createElement("link",{key:y,nonce:a.nonce,...x})))}function E8(...t){return e=>{t.forEach(a=>{typeof a=="function"?a(e):a!=null&&(a.current=e)})}}var C8=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{C8&&(window.__reactRouterVersion="7.12.0")}catch{}function j8({basename:t,children:e,unstable_useTransitions:a,window:n}){let i=k.useRef();i.current==null&&(i.current=sV({window:n,v5Compat:!0}));let r=i.current,[o,l]=k.useState({action:r.action,location:r.location}),c=k.useCallback(d=>{a===!1?l(d):k.startTransition(()=>l(d))},[a]);return k.useLayoutEffect(()=>r.listen(c),[r,c]),k.createElement(a8,{basename:t,children:e,location:o.location,navigationType:o.action,navigator:r,unstable_useTransitions:a})}var LP=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Te=k.forwardRef(function({onClick:e,discover:a="render",prefetch:n="none",relative:i,reloadDocument:r,replace:o,state:l,target:c,to:d,preventScrollReset:u,viewTransition:p,unstable_defaultShouldRevalidate:m,...h},g){let{basename:y,unstable_useTransitions:x}
51=k.useContext(Ja),v=typeof d=="string"&&LP.test(d),w=kP(d,y);d=w.to;let S=HV(d,{relative:i}),[T,P,M]=k8(n,h),C=P8(d,{replace:o,state:l,target:c,preventScrollReset:u,relative:i,viewTransition:p,unstable_defaultShouldRevalidate:m,unstable_useTransitions:x});function E(N){e&&e(N),N.defaultPrevented||C(N)}let j=k.createElement("a",{...h,...M,href:w.absoluteURL||S,onClick:w.isExternal||r?e:E,ref:E8(g,P),target:c,"data-discover":!v&&a==="render"?"true":void 0});return T&&!v?k.createElement(k.Fragment,null,j,k.createElement(S8,{page:S})):j});Te.displayName="Link";var T8=k.forwardRef(function({"aria-current":e="page",caseSensitive:a=!1,className:n="",end:i=!1,style:r,to:o,viewTransition:l,children:c,...d},u){let p=ju(o,{relative:d.relative}),m=fn(),h=k.useContext(tg),{navigator:g,basename:y}=k.useContext(Ja),x=h!=null&&q8(p)&&l===!0,v=g.encodeLocation?g.encodeLocation(p).pathname:p.pathname,w=m.pathname,S=h&&h.navigation&&h.navigation.location?h.navigation.location.pathname:null;a||(w=w.toLowerCase(),S=S?S.toLowerCase():null,v=v.toLowerCase()),S&&y&&(S=Di(S,y)||S);const T=v!=="/"&&v.endsWith("/")?v.length-1:v.length;let P=w===v||!i&&w.startsWith(v)&&w.charAt(T)==="/",M=S!=null&&(S===v||!i&&S.startsWith(v)&&S.charAt(v.length)==="/"),C={isActive:P,isPending:M,isTransitioning:x},E=P?e:void 0,j;typeof n=="function"?j=n(C):j=[n,P?"active":null,M?"pending":null,x?"transitioning":null].filter(Boolean).join(" ");let N=typeof r=="function"?r(C):r;return k.createElement(Te,{...d,"aria-current":E,className:j,ref:u,style:N,to:o,viewTransition:l},typeof c=="function"?c(C):c)});T8.displayName="NavLink";var N8=k.forwardRef(({discover:t="render",fetcherKey:e,navigate:a,reloadDocument:n,replace:i,state:r,method:o=Am,action:l,onSubmit:c,relative:d,preventScrollReset:u,viewTransition:p,unstable_defaultShouldRevalidate:m,...h},g)=>{let{unstable_useTransitions:y}=k.useContext(Ja),x=M8(),v=D8(l,{relative:d}),w=o.toLowerCase()==="get"?"get":"post",S=typeof l=="string"&&LP.test(l),T=P=>{if(c&&c(P),P.defaultPrevented)return;P.preventDefault();let M=P.nativeEvent.submitter,C=(M==null?void 0:M.getAttribute("formmethod"))||o,E=()=>x(M||P.currentTarget,{fetcherKey:e,method:C,navigate:a,replace:i,state:r,relative:d,preventScrollReset:u,viewTransition:p,unstable_defaultShouldRevalidate:m});y&&a!==!1?k.startTransition(()=>E()):E()};return k.createElement("form",{ref:g,method:w,action:v,onSubmit:n?c:T,...h,"data-discover":!S&&t==="render"?"true":void 0})});N8.displayName="Form";function I8(t){return`${t} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function OP(t){let e=k.useContext(Fl);return Ke(e,I8(t)),e}function P8(t,{target:e,replace:a,state:n,preventScrollReset:i,relative:r,viewTransition:o,unstable_defaultShouldRevalidate:l,unstable_useTransitions:c}={}){let d=Qa(),u=fn(),p=ju(t,{relative:r});return k.useCallback(m=>{if(l8(m,e)){m.preventDefault();let h=a!==void 0?a:Gd(u)===Gd(p),g=()=>d(t,{replace:h,state:n,preventScrollReset:i,relative:r,viewTransition:o,unstable_defaultShouldRevalidate:l});c?k.startTransition(()=>g()):g()}},[u,d,p,a,n,e,t,i,r,o,l,c])}function R8(t){Wa(typeof URLSearchParams<"u","You cannot use the `useSearchParams` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.");let e=k.useRef(xv(t)),a=k.useRef(!1),n=fn(),i=k.useMemo(()=>c8(n.search,a.current?null:e.current),[n.search]),r=Qa(),o=k.useCallback((l,c)=>{const d=xv(typeof l=="function"?l(new URLSearchParams(i)):l);a.current=!0,r("?"+d,c)},[r,i]);return[i,o]}var L8=0,O8=()=>`__${String(++L8)}__`;function M8(){let{router:t}=OP("useSubmit"),{basename:e}=k.useContext(Ja),a=YV(),n=t.fetch,i=t.navigate;return k.useCallback(async(r,o={})=>{let{action:l,method:c,encType:d,formData:u,body:p}=p8(r,e);if(o.navigate===!1){let m=o.fetcherKey||O8();await n(m,a,o.action||l,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:u,body:p,formMethod:o.method||c,formEncType:o.encType||d,flushSync:o.flushSync})}else await i(o.action||l,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:u,body:p,formMethod:o.method||c,formEncType:o.encType||d,replace:o.replace,state:o.state,fromRouteId:a,flushSync:o.flushSync,viewTransition:o.viewTransition})},[n,i,e,a])}function D8(t,{relative:e}={}){let{basename:a}=k.useContext(Ja),n=k.useContext(zn);Ke(n,"useFormAction must be used inside a RouteContext");let[i]=n.matches.slice(-1),r={...ju(t||".",{relative:e})},o=fn();if(t==null){r.search=o.search;
51let l=new URLSearchParams(r.search),c=l.getAll("index");if(c.some(u=>u==="")){l.delete("index"),c.filter(p=>p).forEach(p=>l.append("index",p));let u=l.toString();r.search=u?`?${u}`:""}}return(!t||t===".")&&i.route.index&&(r.search=r.search?r.search.replace(/^\?/,"?index&"):"?index"),a!=="/"&&(r.pathname=r.pathname==="/"?a:Ci([a,r.pathname])),Gd(r)}function q8(t,{relative:e}={}){let a=k.useContext(_P);Ke(a!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:n}=OP("useViewTransitionState"),i=ju(t,{relative:e});if(!a.isTransitioning)return!1;let r=Di(a.currentLocation.pathname,n)||a.currentLocation.pathname,o=Di(a.nextLocation.pathname,n)||a.nextLocation.pathname;return xh(i.pathname,o)!=null||xh(i.pathname,r)!=null}const MP=k.createContext();function z8({children:t}){const[e,a]=k.useState(!1),[n,i]=k.useState("Contáctanos"),r=(l="Contáctanos")=>{i(l),a(!0)},o=()=>{a(!1)};return s.jsx(MP.Provider,{value:{isOpen:e,modalTitle:n,openModal:r,closeModal:o},children:t})}function oa(){const t=k.useContext(MP);if(!t)throw new Error("useContactModal debe ser usado dentro de ContactModalProvider");return t}const de=t=>typeof t=="string",Ac=()=>{let t,e;const a=new Promise((n,i)=>{t=n,e=i});return a.resolve=t,a.reject=e,a},tA=t=>t==null?"":""+t,V8=(t,e,a)=>{t.forEach(n=>{e[n]&&(a[n]=e[n])})},H8=/###/g,aA=t=>t&&t.indexOf("###")>-1?t.replace(H8,"."):t,nA=t=>!t||de(t),id=(t,e,a)=>{const n=de(e)?e.split("."):e;let i=0;for(;i<n.length-1;){if(nA(t))return{};const r=aA(n[i]);!t[r]&&a&&(t[r]=new a),Object.prototype.hasOwnProperty.call(t,r)?t=t[r]:t={},++i}return nA(t)?{}:{obj:t,k:aA(n[i])}},iA=(t,e,a)=>{const{obj:n,k:i}=id(t,e,Object);if(n!==void 0||e.length===1){n[i]=a;return}let r=e[e.length-1],o=e.slice(0,e.length-1),l=id(t,o,Object);for(;l.obj===void 0&&o.length;)r=`${o[o.length-1]}.${r}`,o=o.slice(0,o.length-1),l=id(t,o,Object),l!=null&&l.obj&&typeof l.obj[`${l.k}.${r}`]<"u"&&(l.obj=void 0);l.obj[`${l.k}.${r}`]=a},F8=(t,e,a,n)=>{const{obj:i,k:r}=id(t,e,Object);i[r]=i[r]||[],i[r].push(a)},vh=(t,e)=>{const{obj:a,k:n}=id(t,e);if(a&&Object.prototype.hasOwnProperty.call(a,n))return a[n]},B8=(t,e,a)=>{const n=vh(t,a);return n!==void 0?n:vh(e,a)},DP=(t,e,a)=>{for(const n in e)n!=="__proto__"&&n!=="constructor"&&(n in t?de(t[n])||t[n]instanceof String||de(e[n])||e[n]instanceof String?a&&(t[n]=e[n]):DP(t[n],e[n],a):t[n]=e[n]);return t},Ss=t=>t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");var U8={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};const $8=t=>de(t)?t.replace(/[&<>"'\/]/g,e=>U8[e]):t;class W8{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){const a=this.regExpMap.get(e);if(a!==void 0)return a;const n=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,n),this.regExpQueue.push(e),n}}const G8=[" ",",","?","!",";"],K8=new W8(20),J8=(t,e,a)=>{e=e||"",a=a||"";const n=G8.filter(o=>e.indexOf(o)<0&&a.indexOf(o)<0);if(n.length===0)return!0;const i=K8.getRegExp(`(${n.map(o=>o==="?"?"\\?":o).join("|")})`);let r=!i.test(t);if(!r){const o=t.indexOf(a);o>0&&!i.test(t.substring(0,o))&&(r=!0)}return r},vv=(t,e,a=".")=>{if(!t)return;if(t[e])return Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0;const n=e.split(a);let i=t;for(let r=0;r<n.length;){if(!i||typeof i!="object")return;let o,l="";for(let c=r;c<n.length;++c)if(c!==r&&(l+=a),l+=n[c],o=i[l],o!==void 0){if(["string","number","boolean"].indexOf(typeof o)>-1&&c<n.length-1)continue;r+=c-r+1;break}i=o}return i},Kd=t=>t==null?void 0:t.replace("_","-"),Q8={type:"logger",log(t){this.output("log",t)},warn(t){this.output("warn",t)},error(t){this.output("error",t)},output(t,e){var a,n;(n=(a=console==null?void 0:console[t])==null?void 0:a.apply)==null||n.call(a,console,e)}};let X8=class bv{constructor(e,a={}){this.init(e,a)}init(e,a={}){this.prefix=a.prefix||"i18next:",this.logger=e||Q8,this.options=a,this.debug=a.debug}log(...e){return this.forward(e,"log","",!0)}warn(...e){return this.forward(e,"warn","",!0)}error(...e){return this.forward(e,"error","")}deprecate(...e){return this.forward(e,"warn","WARNING DEPRECATED: ",!0)}forward(e,a,n,i){return i&&!this.debug?null:(de(e[0])&&(e[0]=`${n}${this.prefix} ${e[0]}`),this.logger[a](e))}create(e){return new bv(this.logger,{prefix:`${this.prefix}:${e}:`,...this.options})}clone(e){return e=e||this.options,e.prefix=e.prefix||this.prefix,new bv(this.logger,e)}};var Jn=new X8;let ng=class{constructor(){this.observers={}}on(e,a){return e.split(" ").forEach(n=>{this.observers[n]||(this.observers[n]=new Map);const i=this.observers[n].get(a)||0;this.observers[n].set(a,i+1)}),this}
vendor: 1,390 bytes, line 51
51off(e,a){if(this.observers[e]){if(!a){delete this.observers[e];return}this.observers[e].delete(a)}}emit(e,...a){this.observers[e]&&Array.from(this.observers[e].entries()).forEach(([i,r])=>{for(let o=0;o<r;o++)i(...a)}),this.observers["*"]&&Array.from(this.observers["*"].entries()).forEach(([i,r])=>{for(let o=0;o<r;o++)i.apply(i,[e,...a])})}};class rA extends ng{constructor(e,a={ns:["translation"],defaultNS:"translation"}){super(),this.data=e||{},this.options=a,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.options.ignoreJSONStructure===void 0&&(this.options.ignoreJSONStructure=!0)}addNamespaces(e){this.options.ns.indexOf(e)<0&&this.options.ns.push(e)}removeNamespaces(e){const a=this.options.ns.indexOf(e);a>-1&&this.options.ns.splice(a,1)}getResource(e,a,n,i={}){var d,u;const r=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,o=i.ignoreJSONStructure!==void 0?i.ignoreJSONStructure:this.options.ignoreJSONStructure;let l;e.indexOf(".")>-1?l=e.split("."):(l=[e,a],n&&(Array.isArray(n)?l.push(...n):de(n)&&r?l.push(...n.split(r)):l.push(n)));const c=vh(this.data,l);return!c&&!a&&!n&&e.indexOf(".")>-1&&(e=l[0],a=l[1],n=l.slice(2).join(".")),c||!o||!de(n)?c:vv((u=(d=this.data)==null?void 0:d[e])==null?void 0:u[a],n,r)}addResource(e,a,n,i,r={silent:!1}){const o=r.keySeparator!==void 0?r.keySeparator:this.options.keySeparator;let l=[e,a];
vendor: 1,825 bytes, line 51
51n&&(l=l.concat(o?n.split(o):n)),e.indexOf(".")>-1&&(l=e.split("."),i=a,a=l[1]),this.addNamespaces(a),iA(this.data,l,i),r.silent||this.emit("added",e,a,n,i)}addResources(e,a,n,i={silent:!1}){for(const r in n)(de(n[r])||Array.isArray(n[r]))&&this.addResource(e,a,r,n[r],{silent:!0});i.silent||this.emit("added",e,a,n)}addResourceBundle(e,a,n,i,r,o={silent:!1,skipCopy:!1}){let l=[e,a];e.indexOf(".")>-1&&(l=e.split("."),i=n,n=a,a=l[1]),this.addNamespaces(a);let c=vh(this.data,l)||{};o.skipCopy||(n=JSON.parse(JSON.stringify(n))),i?DP(c,n,r):c={...c,...n},iA(this.data,l,c),o.silent||this.emit("added",e,a,n)}removeResourceBundle(e,a){this.hasResourceBundle(e,a)&&delete this.data[e][a],this.removeNamespaces(a),this.emit("removed",e,a)}hasResourceBundle(e,a){return this.getResource(e,a)!==void 0}getResourceBundle(e,a){return a||(a=this.options.defaultNS),this.getResource(e,a)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){const a=this.getDataByLanguage(e);return!!(a&&Object.keys(a)||[]).find(i=>a[i]&&Object.keys(a[i]).length>0)}toJSON(){return this.data}}var qP={processors:{},addPostProcessor(t){this.processors[t.name]=t},handle(t,e,a,n,i){return t.forEach(r=>{var o;e=((o=this.processors[r])==null?void 0:o.process(e,a,n,i))??e}),e}};const zP=Symbol("i18next/PATH_KEY");function Y8(){const t=[],e=Object.create(null);let a;return e.get=(n,i)=>{var r;return(r=a==null?void 0:a.revoke)==null||r.call(a),i===zP?t:(t.push(i),a=Proxy.revocable(n,e),a.proxy)},Proxy.revocable(Object.create(null),e).proxy}function wv(t,e){const{[zP]:a}=t(Y8());return a.join((e==null?void 0:e.keySeparator)??".")}const oA={},t0=t=>!de(t)&&typeof t!="boolean"&&typeof t!="number";class bh extends ng{constructor(e,a={}){super(),V8(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","
51i18nFormat","utils"],e,this),this.options=a,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.logger=Jn.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e,a={interpolation:{}}){const n={...a};if(e==null)return!1;const i=this.resolve(e,n);if((i==null?void 0:i.res)===void 0)return!1;const r=t0(i.res);return!(n.returnObjects===!1&&r)}extractFromKey(e,a){let n=a.nsSeparator!==void 0?a.nsSeparator:this.options.nsSeparator;n===void 0&&(n=":");const i=a.keySeparator!==void 0?a.keySeparator:this.options.keySeparator;let r=a.ns||this.options.defaultNS||[];const o=n&&e.indexOf(n)>-1,l=!this.options.userDefinedKeySeparator&&!a.keySeparator&&!this.options.userDefinedNsSeparator&&!a.nsSeparator&&!J8(e,n,i);if(o&&!l){const c=e.match(this.interpolator.nestingRegexp);if(c&&c.length>0)return{key:e,namespaces:de(r)?[r]:r};const d=e.split(n);(n!==i||n===i&&this.options.ns.indexOf(d[0])>-1)&&(r=d.shift()),e=d.join(i)}return{key:e,namespaces:de(r)?[r]:r}}translate(e,a,n){let i=typeof a=="object"?{...a}:a;if(typeof i!="object"&&this.options.overloadTranslationOptionHandler&&(i=this.options.overloadTranslationOptionHandler(arguments)),typeof i=="object"&&(i={...i}),i||(i={}),e==null)return"";typeof e=="function"&&(e=wv(e,{...this.options,...i})),Array.isArray(e)||(e=[String(e)]);const r=i.returnDetails!==void 0?i.returnDetails:this.options.returnDetails,o=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,{key:l,namespaces:c}=this.extractFromKey(e[e.length-1],i),d=c[c.length-1];let u=i.nsSeparator!==void 0?i.nsSeparator:this.options.nsSeparator;u===void 0&&(u=":");const p=i.lng||this.language,m=i.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if((p==null?void 0:p.toLowerCase())==="cimode")return m?r?{res:`${d}${u}${l}`,usedKey:l,exactUsedKey:l,usedLng:p,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:`${d}${u}${l}`:r?{res:l,usedKey:l,exactUsedKey:l,usedLng:p,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:l;const h=this.resolve(e,i);let g=h==null?void 0:h.res;const y=(h==null?void 0:h.usedKey)||l,x=(h==null?void 0:h.exactUsedKey)||l,v=["[object Number]","[object Function]","[object RegExp]"],w=i.joinArrays!==void 0?i.joinArrays:this.options.joinArrays,S=!this.i18nFormat||this.i18nFormat.handleAsObject,T=i.count!==void 0&&!de(i.count),P=bh.hasDefaultValue(i),M=T?this.pluralResolver.getSuffix(p,i.count,i):"",C=i.ordinal&&T?this.pluralResolver.getSuffix(p,i.count,{ordinal:!1}):"",E=T&&!i.ordinal&&i.count===0,j=E&&i[`defaultValue${this.options.pluralSeparator}zero`]||i[`defaultValue${M}`]||i[`defaultValue${C}`]||i.defaultValue;let N=g;S&&!g&&P&&(N=j);const L=t0(N),O=Object.prototype.toString.apply(N);if(S&&N&&L&&v.indexOf(O)<0&&!(de(w)&&Array.isArray(N))){if(!i.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");const R=this.options.returnedObjectHandler?this.options.returnedObjectHandler(y,N,{...i,ns:c}):`key '${l} (${this.language})' returned an object instead of string.`;return r?(h.res=R,h.usedParams=this.getUsedParamsDetails(i),h):R}if(o){const R=Array.isArray(N),G=R?[]:{},ee=R?x:y;for(const ke in N)if(Object.prototype.hasOwnProperty.call(N,ke)){const ae=`${ee}${o}${ke}`;P&&!g?G[ke]=this.translate(ae,{...i,defaultValue:t0(j)?j[ke]:void 0,joinArrays:!1,ns:c}):G[ke]=this.translate(ae,{...i,joinArrays:!1,ns:c}),G[ke]===ae&&(G[ke]=N[ke])}g=G}}else if(S&&de(w)&&Array.isArray(g))g=g.join(w),g&&(g=this.extendTranslation(g,e,i,n));else{let R=!1,G=!1;!this.isValidLookup(g)&&P&&(R=!0,g=j),this.isValidLookup(g)||(G=!0,g=l);const ke=(i.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&G?void 0:g,ae=P&&j!==g&&this.options.updateMissing;if(G||R||ae){if(this.logger.log(ae?"updateKey":"missingKey",p,d,l,ae?j:g),o){const fe=this.resolve(l,{...i,keySeparator:!1});fe&&fe.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let F=[];const Z=this.languageUtils.getFallbackCodes(this.options.fallbackLng,i.lng||this.language);if(this.options.saveMissingTo==="fallback"&&Z&&Z[0])for(let fe=0;fe<Z.length;fe++)F.push(Z[fe]);else this.options.saveMissingTo==="all"?F=this.languageUtils.toResolveHierarchy(i.lng||this.language):F.push(i.lng||this.language);const re=(fe,ve,Ie)=>{var ge;const ne=P&&Ie!==g?Ie:ke;this.options.missingKeyHandler?this.options.missingKeyHandler(fe,d,ve,ne,ae,i):(ge=this.backendConnector)!=null&&ge.saveMissing&&this.backendConnector.saveMissing(fe,d,ve,ne,ae,i),this.emit
vendor: 28,450 bytes, line 51
51("missingKey",fe,d,ve,g)};this.options.saveMissing&&(this.options.saveMissingPlurals&&T?F.forEach(fe=>{const ve=this.pluralResolver.getSuffixes(fe,i);E&&i[`defaultValue${this.options.pluralSeparator}zero`]&&ve.indexOf(`${this.options.pluralSeparator}zero`)<0&&ve.push(`${this.options.pluralSeparator}zero`),ve.forEach(Ie=>{re([fe],l+Ie,i[`defaultValue${Ie}`]||j)})}):re(F,l,j))}g=this.extendTranslation(g,e,i,h,n),G&&g===l&&this.options.appendNamespaceToMissingKey&&(g=`${d}${u}${l}`),(G||R)&&this.options.parseMissingKeyHandler&&(g=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${d}${u}${l}`:l,R?g:void 0,i))}return r?(h.res=g,h.usedParams=this.getUsedParamsDetails(i),h):g}extendTranslation(e,a,n,i,r){var c,d;if((c=this.i18nFormat)!=null&&c.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...n},n.lng||this.language||i.usedLng,i.usedNS,i.usedKey,{resolved:i});else if(!n.skipInterpolation){n.interpolation&&this.interpolator.init({...n,interpolation:{...this.options.interpolation,...n.interpolation}});const u=de(e)&&(((d=n==null?void 0:n.interpolation)==null?void 0:d.skipOnVariables)!==void 0?n.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let p;if(u){const h=e.match(this.interpolator.nestingRegexp);p=h&&h.length}let m=n.replace&&!de(n.replace)?n.replace:n;if(this.options.interpolation.defaultVariables&&(m={...this.options.interpolation.defaultVariables,...m}),e=this.interpolator.interpolate(e,m,n.lng||this.language||i.usedLng,n),u){const h=e.match(this.interpolator.nestingRegexp),g=h&&h.length;p<g&&(n.nest=!1)}!n.lng&&i&&i.res&&(n.lng=this.language||i.usedLng),n.nest!==!1&&(e=this.interpolator.nest(e,(...h)=>(r==null?void 0:r[0])===h[0]&&!n.context?(this.logger.warn(`It seems you are nesting recursively key: ${h[0]} in key: ${a[0]}`),null):this.translate(...h,a),n)),n.interpolation&&this.interpolator.reset()}const o=n.postProcess||this.options.postProcess,l=de(o)?[o]:o;return e!=null&&(l!=null&&l.length)&&n.applyPostProcessor!==!1&&(e=qP.handle(l,e,a,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...i,usedParams:this.getUsedParamsDetails(n)},...n}:n,this)),e}resolve(e,a={}){let n,i,r,o,l;return de(e)&&(e=[e]),e.forEach(c=>{if(this.isValidLookup(n))return;const d=this.extractFromKey(c,a),u=d.key;i=u;let p=d.namespaces;this.options.fallbackNS&&(p=p.concat(this.options.fallbackNS));const m=a.count!==void 0&&!de(a.count),h=m&&!a.ordinal&&a.count===0,g=a.context!==void 0&&(de(a.context)||typeof a.context=="number")&&a.context!=="",y=a.lngs?a.lngs:this.languageUtils.toResolveHierarchy(a.lng||this.language,a.fallbackLng);p.forEach(x=>{var v,w;this.isValidLookup(n)||(l=x,!oA[`${y[0]}-${x}`]&&((v=this.utils)!=null&&v.hasLoadedNamespace)&&!((w=this.utils)!=null&&w.hasLoadedNamespace(l))&&(oA[`${y[0]}-${x}`]=!0,this.logger.warn(`key "${i}" for languages "${y.join(", ")}" won't get resolved as namespace "${l}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),y.forEach(S=>{var M;if(this.isValidLookup(n))return;o=S;const T=[u];if((M=this.i18nFormat)!=null&&M.addLookupKeys)this.i18nFormat.addLookupKeys(T,u,S,x,a);else{let C;m&&(C=this.pluralResolver.getSuffix(S,a.count,a));const E=`${this.options.pluralSeparator}zero`,j=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(m&&(a.ordinal&&C.indexOf(j)===0&&T.push(u+C.replace(j,this.options.pluralSeparator)),T.push(u+C),h&&T.push(u+E)),g){const N=`${u}${this.options.contextSeparator||"_"}${a.context}`;T.push(N),m&&(a.ordinal&&C.indexOf(j)===0&&T.push(N+C.replace(j,this.options.pluralSeparator)),T.push(N+C),h&&T.push(N+E))}}let P;for(;P=T.pop();)this.isValidLookup(n)||(r=P,n=this.getResource(S,x,P,a))}))})}),{res:n,usedKey:i,exactUsedKey:r,usedLng:o,usedNS:l}}isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===null)&&!(!this.options.returnEmptyString&&e==="")}getResource(e,a,n,i={}){var r;return(r=this.i18nFormat)!=null&&r.getResource?this.i18nFormat.getResource(e,a,n,i):this.resourceStore.getResource(e,a,n,i)}getUsedParamsDetails(e={}){const a=["defaultValue","ordinal","context","replace","lng","lngs","fallbackLng","ns","keySeparator","nsSeparator","returnObjects","returnDetails","joinArrays","postProcess","interpolation"],n=e.replace&&!de(e.replace);let i=n?e.replace:e;if(n&&typeof e.count<"u"&&(i.count=e.count),this.options.interpolation.defaultVariables&&(i={...this.options.interpolation.defaultVariables,...i}),!n){i={...i};for(const r of a)delete i[r]}return i}static hasDefaultValue(e){const a="defaultValue";for(const n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&a===n.substring(0,a.length)&&e[n]!==void 0)return!0;return!1}}class sA{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=Jn.create("languageUtils")}getScriptPartFromCode(e){if(e=Kd(e),!e||e.indexOf("-")<0)return null;const a=e.split("-");return a.length===2||(a.pop(),a[a.length-1].toLowerCase()==="x")?null:this.formatLanguageCode(a.join("-"))}getLanguagePartFromCode(e){if(e=Kd(e),!e||e.indexOf("-")<0)return e;const a=e.split("-");return this.formatLanguageCode(a[0])}formatLanguageCode(e){if(de(e)&&e.indexOf("-")>-1){let a;try{a=Intl.getCanonicalLocales(e)[0]}catch{}return a&&this.options.lowerCaseLng&&(a=a.toLowerCase()),a||(this.options.lowerCaseLng?e.toLowerCase():e)}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return(this.options.load==="languageOnly"||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){if(!e)return null;let a;return e.forEach(n=>{if(a)return;const i=this.formatLanguageCode(n);(!this.options.supportedLngs||this.isSupportedCode(i))&&(a=i)}),!a&&this.options.supportedLngs&&e.forEach(n=>{if(a)return;const i=this.getScriptPartFromCode(n);if(this.isSupportedCode(i))return a=i;const r=this.getLanguagePartFromCode(n);if(this.isSupportedCode(r))return a=r;a=this.options.supportedLngs.find(o=>{if(o===r)return o;if(!(o.indexOf("-")<0&&r.indexOf("-")<0)&&(o.indexOf("-")>0&&r.indexOf("-")<0&&o.substring(0,o.indexOf("-"))===r||o.indexOf(r)===0&&r.length>1))return o})}),a||(a=this.getFallbackCodes(this.options.fallbackLng)[0]),a}getFallbackCodes(e,a){if(!e)return[];if(typeof e=="function"&&(e=e(a)),de(e)&&(e=[e]),Array.isArray(e))return e;if(!a)return e.default||[];let n=e[a];return n||(n=e[this.getScriptPartFromCode(a)]),n||(n=e[this.formatLanguageCode(a)]),n||(n=e[this.getLanguagePartFromCode(a)]),n||(n=e.default),n||[]}toResolveHierarchy(e,a){const n=this.getFallbackCodes((a===!1?[]:a)||this.options.fallbackLng||[],e),i=[],r=o=>{o&&(this.isSupportedCode(o)?i.push(o):this.logger.warn(`rejecting language code not found in supportedLngs: ${o}`))};return de(e)&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?(this.options.load!=="languageOnly"&&r(this.formatLanguageCode(e)),this.options.load!=="languageOnly"&&this.options.load!=="currentOnly"&&r(this.getScriptPartFromCode(e)),this.options.load!=="currentOnly"&&r(this.getLanguagePartFromCode(e))):de(e)&&r(this.formatLanguageCode(e)),n.forEach(o=>{i.indexOf(o)<0&&r(this.formatLanguageCode(o))}),i}}const lA={zero:0,one:1,two:2,few:3,many:4,other:5},cA={select:t=>t===1?"one":"other",resolvedOptions:()=>({pluralCategories:["one","other"]})};class Z8{constructor(e,a={}){this.languageUtils=e,this.options=a,this.logger=Jn.create("pluralResolver"),this.pluralRulesCache={}}clearCache(){this.pluralRulesCache={}}getRule(e,a={}){const n=Kd(e==="dev"?"en":e),i=a.ordinal?"ordinal":"cardinal",r=JSON.stringify({cleanedCode:n,type:i});if(r in this.pluralRulesCache)return this.pluralRulesCache[r];let o;try{o=new Intl.PluralRules(n,{type:i})}catch{if(!Intl)return this.logger.error("No Intl support, please use an Intl polyfill!"),cA;if(!e.match(/-|_/))return cA;const c=this.languageUtils.getLanguagePartFromCode(e);o=this.getRule(c,a)}return this.pluralRulesCache[r]=o,o}needsPlural(e,a={}){let n=this.getRule(e,a);return n||(n=this.getRule("dev",a)),(n==null?void 0:n.resolvedOptions().pluralCategories.length)>1}getPluralFormsOfKey(e,a,n={}){return this.getSuffixes(e,n).map(i=>`${a}${i}`)}getSuffixes(e,a={}){let n=this.getRule(e,a);return n||(n=this.getRule("dev",a)),n?n.resolvedOptions().pluralCategories.sort((i,r)=>lA[i]-lA[r]).map(i=>`${this.options.prepend}${a.ordinal?`ordinal${this.options.prepend}`:""}${i}`):[]}getSuffix(e,a,n={}){const i=this.getRule(e,n);return i?`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${i.select(a)}`:(this.logger.warn(`no plural rule found for: ${e}`),this.getSuffix("dev",a,n))}}const dA=(t,e,a,n=".",i=!0)=>{let r=B8(t,e,a);return!r&&i&&de(a)&&(r=vv(t,a,n),r===void 0&&(r=vv(e,a,n))),r},a0=t=>t.replace(/\$/g,"$$$$");class uA{constructor(e={}){var a;this.logger=Jn.create("interpolator"),this.options=e,this.format=((a=e==null?void 0:e.interpolation)==null?void 0:a.format)||(n=>n),this.init(e)}init(e={}){e.interpolation||(e.interpolation={escapeValue:!0});const{escape:a,escapeValue:n,useRawValueToEscape:i,prefix:r,prefixEscaped:o,suffix:l,suffixEscaped:c,formatSeparator:d,unescapeSuffix:u,unescapePrefix:p,nestingPrefix:m,nestingPrefixEscaped:h,nestingSuffix:g,nestingSuffixEscaped:y,nestingOptionsSeparator:x,maxReplaces:v,alwaysFormat:w}=e.interpolation;this.escape=a!==void 0?a:$8,this.escapeValue=n!==void 0?n:!0,this.useRawValueToEscape=i!==void 0?i:!1,this.prefix=r?Ss(r):o||"{{",this.suffix=l?Ss(l):c||"}}",this.formatSeparator=d||",",this.unescapePrefix=u?"":p||"-",this.unescapeSuffix=this.unescapePrefix?"":u||"",this.nestingPrefix=m?Ss(m):h||Ss("$t("),this.nestingSuffix=g?Ss(g):y||Ss(")"),this.nestingOptionsSeparator=x||",",this.maxReplaces=v||1e3,this.alwaysFormat=w!==void 0?w:!1,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const e=(a,n)=>(a==null?void 0:a.source)===n?(a.lastIndex=0,a):new RegExp(n,"g");this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`)}interpolate(e,a,n,i){var h;let r,o,l;const c=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},d=g=>{if(g.indexOf(this.formatSeparator)<0){const w=dA(a,c,g,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(w,void 0,n,{...i,...a,interpolationkey:g}):w}const y=g.split(this.formatSeparator),x=y.shift().trim(),v=y.join(this.formatSeparator).trim();return this.format(dA(a,c,x,this.options.keySeparator,this.options.ignoreJSONStructure),v,n,{...i,...a,interpolationkey:x})};this.resetRegExp();const u=(i==null?void 0:i.missingInterpolationHandler)||this.options.missingInterpolationHandler,p=((h=i==null?void 0:i.interpolation)==null?void 0:h.skipOnVariables)!==void 0?i.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:g=>a0(g)},{regex:this.regexp,safeValue:g=>this.escapeValue?a0(this.escape(g)):a0(g)}].forEach(g=>{for(l=0;r=g.regex.exec(e);){const y=r[1].trim();if(o=d(y),o===void 0)if(typeof u=="function"){const v=u(e,r,i);o=de(v)?v:""}else if(i&&Object.prototype.hasOwnProperty.call(i,y))o="";else if(p){o=r[0];continue}else this.logger.warn(`missed to pass in variable ${y} for interpolating ${e}`),o="";else!de(o)&&!this.useRawValueToEscape&&(o=tA(o));const x=g.safeValue(o);if(e=e.replace(r[0],x),p?(g.regex.lastIndex+=o.length,g.regex.lastIndex-=r[0].length):g.regex.lastIndex=0,l++,l>=this.maxReplaces)break}}),e}nest(e,a,n={}){let i,r,o;const l=(c,d)=>{const u=this.nestingOptionsSeparator;if(c.indexOf(u)<0)return c;const p=c.split(new RegExp(`${u}[ ]*{`));let m=`{${p[1]}`;c=p[0],m=this.interpolate(m,o);const h=m.match(/'/g),g=m.match(/"/g);(((h==null?void 0:h.length)??0)%2===0&&!g||g.length%2!==0)&&(m=m.replace(/'/g,'"'));try{o=JSON.parse(m),d&&(o={...d,...o})}catch(y){return this.logger.warn(`failed parsing options string in nesting for key ${c}`,y),`${c}${u}${m}`}return o.defaultValue&&o.defaultValue.indexOf(this.prefix)>-1&&delete o.defaultValue,c};for(;i=this.nestingRegexp.exec(e);){let c=[];o={...n},o=o.replace&&!de(o.replace)?o.replace:o,o.applyPostProcessor=!1,delete o.defaultValue;const d=/{.*}/.test(i[1])?i[1].lastIndexOf("}")+1:i[1].indexOf(this.formatSeparator);if(d!==-1&&(c=i[1].slice(d).split(this.formatSeparator).map(u=>u.trim()).filter(Boolean),i[1]=i[1].slice(0,d)),r=a(l.call(this,i[1].trim(),o),o),r&&i[0]===e&&!de(r))return r;de(r)||(r=tA(r)),r||(this.logger.warn(`missed to resolve ${i[1]} for nesting ${e}`),r=""),c.length&&(r=c.reduce((u,p)=>this.format(u,p,n.lng,{...n,interpolationkey:i[1].trim()}),r.trim())),e=e.replace(i[0],r),this.regexp.lastIndex=0}return e}}const eH=t=>{let e=t.toLowerCase().trim();const a={};if(t.indexOf("(")>-1){const n=t.split("(");e=n[0].toLowerCase().trim();const i=n[1].substring(0,n[1].length-1);e==="currency"&&i.indexOf(":")<0?a.currency||(a.currency=i.trim()):e==="relativetime"&&i.indexOf(":")<0?a.range||(a.range=i.trim()):i.split(";").forEach(o=>{if(o){const[l,...c]=o.split(":"),d=c.join(":").trim().replace(/^'+|'+$/g,""),u=l.trim();a[u]||(a[u]=d),d==="false"&&(a[u]=!1),d==="true"&&(a[u]=!0),isNaN(d)||(a[u]=parseInt(d,10))}})}return{formatName:e,formatOptions:a}},pA=t=>{const e={};return(a,n,i)=>{let r=i;i&&i.interpolationkey&&i.formatParams&&i.formatParams[i.interpolationkey]&&i[i.interpolationkey]&&(r={...r,[i.interpolationkey]:void 0});const o=n+JSON.stringify(r);let l=e[o];return l||(l=t(Kd(n),i),e[o]=l),l(a)}},tH=t=>(e,a,n)=>t(Kd(a),n)(e);class aH{constructor(e={}){this.logger=Jn.create("formatter"),this.options=e,this.init(e)}init(e,a={interpolation:{}}){this.formatSeparator=a.interpolation.formatSeparator||",";const n=a.cacheInBuiltFormats?pA:tH;this.formats={number:n((i,r)=>{const o=new Intl.NumberFormat(i,{...r});return l=>o.format(l)}),currency:n((i,r)=>{const o=new Intl.NumberFormat(i,{...r,style:"currency"});return l=>o.format(l)}),datetime:n((i,r)=>{const o=new Intl.DateTimeFormat(i,{...r});return l=>o.format(l)}),relativetime:n((i,r)=>{const o=new Intl.RelativeTimeFormat(i,{...r});return l=>o.format(l,r.range||"day")}),list:n((i,r)=>{const o=new Intl.ListFormat(i,{...r});return l=>o.format(l)})}}add(e,a){this.formats[e.toLowerCase().trim()]=a}addCached(e,a){this.formats[e.toLowerCase().trim()]=pA(a)}format(e,a,n,i={}){const r=a.split(this.formatSeparator);if(r.length>1&&r[0].indexOf("(")>1&&r[0].indexOf(")")<0&&r.find(l=>l.indexOf(")")>-1)){const l=r.findIndex(c=>c.indexOf(")")>-1);r[0]=[r[0],...r.splice(1,l)].join(this.formatSeparator)}return r.reduce((l,c)=>{var p;const{formatName:d,formatOptions:u}=eH(c);if(this.formats[d]){let m=l;try{const h=((p=i==null?void 0:i.formatParams)==null?void 0:p[i.interpolationkey])||{},g=h.locale||h.lng||i.locale||i.lng||n;m=this.formats[d](l,g,{...u,...i,...h})}catch(h){this.logger.warn(h)}return m}else this.logger.warn(`there was no format function for ${d}`);return l},e)}}const nH=(t,e)=>{t.pending[e]!==void 0&&(delete t.pending[e],t.pendingCount--)};class iH extends ng{constructor(e,a,n,i={}){var r,o;super(),this.backend=e,this.store=a,this.services=n,this.languageUtils=n.languageUtils,this.options=i,this.logger=Jn.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=i.maxParallelReads||10,this.readingCalls=0,this.maxRetries=i.maxRetries>=0?i.maxRetries:5,this.retryTimeout=i.retryTimeout>=1?i.retryTimeout:350,this.state={},this.queue=[],(o=(r=this.backend)==null?void 0:r.init)==null||o.call(r,n,i.backend,i)}queueLoad(e,a,n,i){const r={},o={},l={},c={};return e.forEach(d=>{let u=!0;a.forEach(p=>{const m=`${d}|${p}`;!n.reload&&this.store.hasResourceBundle(d,p)?this.state[m]=2:this.state[m]<0||(this.state[m]===1?o[m]===void 0&&(o[m]=!0):(this.state[m]=1,u=!1,o[m]===void 0&&(o[m]=!0),r[m]===void 0&&(r[m]=!0),c[p]===void 0&&(c[p]=!0)))}),u||(l[d]=!0)}),(Object.keys(r).length||Object.keys(o).length)&&this.queue.push({pending:o,pendingCount:Object.keys(o).length,loaded:{},errors:[],callback:i}),{toLoad:Object.keys(r),pending:Object.keys(o),toLoadLanguages:Object.keys(l),toLoadNamespaces:Object.keys(c)}}loaded(e,a,n){const i=e.split("|"),r=i[0],o=i[1];a&&this.emit("failedLoading",r,o,a),!a&&n&&this.store.addResourceBundle(r,o,n,void 0,void 0,{skipCopy:!0}),this.state[e]=a?-1:2,a&&n&&(this.state[e]=0);const l={};this.queue.forEach(c=>{F8(c.loaded,[r],o),nH(c,e),a&&c.errors.push(a),c.pendingCount===0&&!c.done&&(Object.keys(c.loaded).forEach(d=>{l[d]||(l[d]={});const u=c.loaded[d];u.length&&u.forEach(p=>{l[d][p]===void 0&&(l[d][p]=!0)})}),c.done=!0,c.errors.length?c.callback(c.errors):c.callback())}),this.emit("loaded",l),this.queue=this.queue.filter(c=>!c.done)}read(e,a,n,i=0,r=this.retryTimeout,o){if(!e.length)return o(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:a,fcName:n,tried:i,wait:r,callback:o});return}this.readingCalls++;const l=(d,u)=>{if(this.readingCalls--,this.waitingReads.length>0){const p=this.waitingReads.shift();this.read(p.lng,p.ns,p.fcName,p.tried,p.wait,p.callback)}if(d&&u&&i<this.maxRetries){setTimeout(()=>{this.read.call(this,e,a,n,i+1,r*2,o)},r);return}o(d,u)},c=this.backend[n].bind(this.backend);if(c.length===2){try{const d=c(e,a);d&&typeof d.then=="function"?d.then(u=>l(null,u)).catch(l):l(null,d)}catch(d){l(d)}return}return c(e,a,l)}prepareLoading(e,a,n={},i){if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),i&&i();de(e)&&(e=this.languageUtils.toResolveHierarchy(e)),de(a)&&(a=[a]);const r=this.queueLoad(e,a,n,i);if(!r.toLoad.length)return r.pending.length||i(),null;r.toLoad.forEach(o=>{this.loadOne(o)})}load(e,a,n){this.prepareLoading(e,a,{},n)}reload(e,a,n){this.prepareLoading(e,a,{reload:!0},n)}loadOne(e,a=""){const n=e.split("|"),i=n[0],r=n[1];this.read(i,r,"read",void 0,void 0,(o,l)=>{o&&this.logger.warn(`${a}loading namespace ${r} for language ${i} failed`,o),!o&&l&&this.logger.log(`${a}loaded namespace ${r} for language ${i}`,l),this.loaded(e,o,l)})}saveMissing(e,a,n,i,r,o={},l=()=>{}){var c,d,u,p,m;if((d=(c=this.services)==null?void 0:c.utils)!=null&&d.hasLoadedNamespace&&!((p=(u=this.services)==null?void 0:u.utils)!=null&&p.hasLoadedNamespace(a))){this.logger.warn(`did not save key "${n}" as the namespace "${a}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(!(n==null||n==="")){if((m=this.backend)!=null&&m.create){const h={...o,isUpdate:r},g=this.backend.create.bind(this.backend);if(g.length<6)try{let y;g.length===5?y=g(e,a,n,i,h):y=g(e,a,n,i),y&&typeof y.then=="function"?y.then(x=>l(null,x)).catch(l):l(null,y)}catch(y){l(y)}else g(e,a,n,i,l,h)}!e||!e[0]||this.store.addResource(e[0],a,n,i)}}}const n0=()=>({debug:!1,initAsync:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:t=>{let e={};if(typeof t[1]=="object"&&(e=t[1]),de(t[1])&&(e.defaultValue=t[1]),de(t[2])&&(e.tDescription=t[2]),typeof t[2]=="object"||typeof t[3]=="object"){const a=t[3]||t[2];Object.keys(a).forEach(n=>{e[n]=a[n]})}return e},interpolation:{escapeValue:!0,format:t=>t,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0},cacheInBuiltFormats:!0}),mA=t=>{var e,a;return de(t.ns)&&(t.ns=[t.ns]),de(t.fallbackLng)&&(t.fallbackLng=[t.fallbackLng]),de(t.fallbackNS)&&(t.fallbackNS=[t.fallbackNS]),((a=(e=t.supportedLngs)==null?void 0:e.indexOf)==null?void 0:a.call(e,"cimode"))<0&&(t.supportedLngs=t.supportedLngs.concat(["cimode"])),typeof t.initImmediate=="boolean"&&(t.initAsync=t.initImmediate),t},Lp=()=>{},rH=t=>{Object.getOwnPropertyNames(Object.getPrototypeOf(t)).forEach(a=>{typeof t[a]=="function"&&(t[a]=t[a].bind(t))})};class rd extends ng{constructor(e={},a){if(super(),this.options=mA(e),this.services={},this.logger=Jn,this.modules={external:[]},rH(this),a&&!this.isInitialized&&!e.isClone){if(!this.options.initAsync)return this.init(e,a),this;setTimeout(()=>{this.init(e,a)},0)}}init(e={},a){this.isInitializing=!0,typeof e=="function"&&(a=e,e={}),e.defaultNS==null&&e.ns&&(de(e.ns)?e.defaultNS=e.ns:e.ns.indexOf("translation")<0&&(e.defaultNS=e.ns[0]));const n=n0();this.options={...n,...this.options,...mA(e)},this.options.interpolation={...n.interpolation,...this.options.interpolation},e.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=e.keySeparator),e.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=e.nsSeparator),typeof this.options.overloadTranslationOptionHandler!="function"&&(this.options.overloadTranslationOptionHandler=n.overloadTranslationOptionHandler);const i=d=>d?typeof d=="function"?new d:d:null;if(!this.options.isClone){this.modules.logger?Jn.init(i(this.modules.logger),this.options):Jn.init(null,this.options);let d;this.modules.formatter?d=this.modules.formatter:d=aH;const u=new sA(this.options);this.store=new rA(this.options.resources,this.options);const p=this.services;p.logger=Jn,p.resourceStore=this.store,p.languageUtils=u,p.pluralResolver=new Z8(u,{prepend:this.options.pluralSeparator,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),this.options.interpolation.format&&this.options.interpolation.format!==n.interpolation.format&&this.logger.deprecate("init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting"),d&&(!this.options.interpolation.format||this.options.interpolation.format===n.interpolation.format)&&(p.formatter=i(d),p.formatter.init&&p.formatter.init(p,this.options),this.options.interpolation.format=p.formatter.format.bind(p.formatter)),p.interpolator=new uA(this.options),p.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},p.backendConnector=new iH(i(this.modules.backend),p.resourceStore,p,this.options),p.backendConnector.on("*",(h,...g)=>{this.emit(h,...g)}),this.modules.languageDetector&&(p.languageDetector=i(this.modules.languageDetector),p.languageDetector.init&&p.languageDetector.init(p,this.options.detection,this.options)),this.modules.i18nFormat&&(p.i18nFormat=i(this.modules.i18nFormat),p.i18nFormat.init&&p.i18nFormat.init(this)),this.translator=new bh(this.services,this.options),this.translator.on("*",(h,...g)=>{this.emit(h,...g)}),this.modules.external.forEach(h=>{h.init&&h.init(this)})}if(this.format=this.options.interpolation.format,a||(a=Lp),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const d=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);d.length>0&&d[0]!=="dev"&&(this.options.lng=d[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(d=>{this[d]=(...u)=>this.store[d](...u)}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(d=>{this[d]=(...u)=>(this.store[d](...u),this)});const l=Ac(),c=()=>{const d=(u,p)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),l.resolve(p),a(u,p)};if(this.languages&&!this.isInitialized)return d(null,this.t.bind(this));this.changeLanguage(this.options.lng,d)};return this.options.resources||!this.options.initAsync?c():setTimeout(c,0),l}loadResources(e,a=Lp){var r,o;let n=a;const i=de(e)?e:this.language;if(typeof e=="function"&&(n=e),!this.options.resources||this.options.partialBundledLanguages){if((i==null?void 0:i.toLowerCase())==="cimode"&&(!this.options.preload||this.options.preload.length===0))return n();const l=[],c=d=>{if(!d||d==="cimode")return;this.services.languageUtils.toResolveHierarchy(d).forEach(p=>{p!=="cimode"&&l.indexOf(p)<0&&l.push(p)})};i?c(i):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(u=>c(u)),(o=(r=this.options.preload)==null?void 0:r.forEach)==null||o.call(r,d=>c(d)),this.services.backendConnector.load(l,this.options.ns,d=>{!d&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),n(d)})}else n(null)}reloadResources(e,a,n){const i=Ac();return typeof e=="function"&&(n=e,e=void 0),typeof a=="function"&&(n=a,a=void 0),e||(e=this.languages),a||(a=this.options.ns),n||(n=Lp),this.services.backendConnector.reload(e,a,r=>{i.resolve(),n(r)}),i}use(e){if(!e)throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return e.type==="backend"&&(this.modules.backend=e),(e.type==="logger"||e.log&&e.warn&&e.error)&&(this.modules.logger=e),e.type==="languageDetector"&&(this.modules.languageDetector=e),e.type==="i18nFormat"&&(this.modules.i18nFormat=e),e.type==="postProcessor"&&qP.addPostProcessor(e),e.type==="formatter"&&(this.modules.formatter=e),e.type==="3rdParty"&&this.modules.external.push(e),this}setResolvedLanguage(e){if(!(!e||!this.languages)&&!(["cimode","dev"].indexOf(e)>-1)){for(let a=0;a<this.languages.length;a++){const n=this.languages[a];if(!(["cimode","dev"].indexOf(n)>-1)&&this.store.hasLanguageSomeTranslations(n)){this.resolvedLanguage=n;break}}!this.resolvedLanguage&&this.languages.indexOf(e)<0&&this.store.hasLanguageSomeTranslations(e)&&(this.resolvedLanguage=e,this.languages.unshift(e))}}changeLanguage(e,a){this.isLanguageChangingTo=e;const n=Ac();this.emit("languageChanging",e);const i=l=>{this.language=l,this.languages=this.services.languageUtils.toResolveHierarchy(l),this.resolvedLanguage=void 0,this.setResolvedLanguage(l)},r=(l,c)=>{c?this.isLanguageChangingTo===e&&(i(c),this.translator.changeLanguage(c),this.isLanguageChangingTo=void 0,this.emit("languageChanged",c),this.logger.log("languageChanged",c)):this.isLanguageChangingTo=void 0,n.resolve((...d)=>this.t(...d)),a&&a(l,(...d)=>this.t(...d))},o=l=>{var u,p;!e&&!l&&this.services.languageDetector&&(l=[]);const c=de(l)?l:l&&l[0],d=this.store.hasLanguageSomeTranslations(c)?c:this.services.languageUtils.getBestMatchFromCodes(de(l)?[l]:l);d&&(this.language||i(d),this.translator.language||this.translator.changeLanguage(d),(p=(u=this.services.languageDetector)==null?void 0:u.cacheUserLanguage)==null||p.call(u,d)),this.loadResources(d,m=>{r(m,d)})};return!e&&this.services.languageDetector&&!this.services.languageDetector.async?o(this.services.languageDetector.detect()):!e&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(o):this.services.languageDetector.detect(o):o(e),n}getFixedT(e,a,n){const i=(r,o,...l)=>{let c;typeof o!="object"?c=this.options.overloadTranslationOptionHandler([r,o].concat(l)):c={...o},c.lng=c.lng||i.lng,c.lngs=c.lngs||i.lngs,c.ns=c.ns||i.ns,c.keyPrefix!==""&&(c.keyPrefix=c.keyPrefix||n||i.keyPrefix);const d=this.options.keySeparator||".";let u;return c.keyPrefix&&Array.isArray(r)?u=r.map(p=>(typeof p=="function"&&(p=wv(p,{...this.options,...o})),`${c.keyPrefix}${d}
51${p}`)):(typeof r=="function"&&(r=wv(r,{...this.options,...o})),u=c.keyPrefix?`${c.keyPrefix}${d}${r}`:r),this.t(u,c)};return de(e)?i.lng=e:i.lngs=e,i.ns=a,i.keyPrefix=n,i}t(...e){var a;return(a=this.translator)==null?void 0:a.translate(...e)}exists(...e){var a;return(a=this.translator)==null?void 0:a.exists(...e)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e,a={}){if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;const n=a.lng||this.resolvedLanguage||this.languages[0],i=this.options?this.options.fallbackLng:!1,r=this.languages[this.languages.length-1];if(n.toLowerCase()==="cimode")return!0;const o=(l,c)=>{const d=this.services.backendConnector.state[`${l}|${c}`];return d===-1||d===0||d===2};if(a.precheck){const l=a.precheck(this,o);if(l!==void 0)return l}return!!(this.hasResourceBundle(n,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||o(n,e)&&(!i||o(r,e)))}loadNamespaces(e,a){const n=Ac();return this.options.ns?(de(e)&&(e=[e]),e.forEach(i=>{this.options.ns.indexOf(i)<0&&this.options.ns.push(i)}),this.loadResources(i=>{n.resolve(),a&&a(i)}),n):(a&&a(),Promise.resolve())}loadLanguages(e,a){const n=Ac();de(e)&&(e=[e]);const i=this.options.preload||[],r=e.filter(o=>i.indexOf(o)<0&&this.services.languageUtils.isSupportedCode(o));return r.length?(this.options.preload=i.concat(r),this.loadResources(o=>{n.resolve(),a&&a(o)}),n):(a&&a(),Promise.resolve())}dir(e){var i,r;if(e||(e=this.resolvedLanguage||(((i=this.languages)==null?void 0:i.length)>0?this.languages[0]:this.language)),!e)return"rtl";try{const o=new Intl.Locale(e);if(o&&o.getTextInfo){const l=o.getTextInfo();if(l&&l.direction)return l.direction}}catch{}const a=["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"],n=((r=this.services)==null?void 0:r.languageUtils)||new sA(n0());return e.toLowerCase().indexOf("-latn")>1?"ltr":a.indexOf(n.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(e={},a){const n=new rd(e,a);return n.createInstance=rd.createInstance,n}cloneInstance(e={},a=Lp){const n=e.forkResourceStore;n&&delete e.forkResourceStore;const i={...this.options,...e,isClone:!0},r=new rd(i);if((e.debug!==void 0||e.prefix!==void 0)&&(r.logger=r.logger.clone(e)),["store","services","language"].forEach(l=>{r[l]=this[l]}),r.services={...this.services},r.services.utils={hasLoadedNamespace:r.hasLoadedNamespace.bind(r)},n){const l=Object.keys(this.store.data).reduce((c,d)=>(c[d]={...this.store.data[d]},c[d]=Object.keys(c[d]).reduce((u,p)=>(u[p]={...c[d][p]},u),c[d]),c),{});r.store=new rA(l,i),r.services.resourceStore=r.store}if(e.interpolation){const c={...n0().interpolation,...this.options.interpolation,...e.interpolation},d={...i,interpolation:c};r.services.interpolator=new uA(d)}return r.translator=new bh(r.services,i),r.translator.on("*",(l,...c)=>{r.emit(l,...c)}),r.init(i,a),r.translator.options=i,r.translator.backendConnector.services.utils={hasLoadedNamespace:r.hasLoadedNamespace.bind(r)},r}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}const wa=rd.createInstance();wa.createInstance;wa.dir;wa.init;wa.loadResources;wa.reloadResources;wa.use;wa.changeLanguage;wa.getFixedT;wa.t;wa.exists;wa.setDefaultNamespace;wa.hasLoadedNamespace;wa.loadNamespaces;wa.loadLanguages;const oH=(t,e,a,n)=>{var r,o,l,c;const i=[a,{code:e,...n||{}}];if((o=(r=t==null?void 0:t.services)==null?void 0:r.logger)!=null&&o.forward)return t.services.logger.forward(i,"warn","react-i18next::",!0);Ko(i[0])&&(i[0]=`react-i18next:: ${i[0]}`),(c=(l=t==null?void 0:t.services)==null?void 0:l.logger)!=null&&c.warn?t.services.logger.warn(...i):console!=null&&console.warn&&console.warn(...i)},hA={},VP=(t,e,a,n)=>{Ko(a)&&hA[a]||(Ko(a)&&(hA[a]=new Date),oH(t,e,a,n))},HP=(t,e)=>()=>{if(t.isInitialized)e();else{const a=()=>{setTimeout(()=>{t.off("initialized",a)},0),e()};t.on("initialized",a)}},kv=(t,e,a)=>{t.loadNamespaces(e,HP(t,a))},fA=(t,e,a,n)=>
51{if(Ko(a)&&(a=[a]),t.options.preload&&t.options.preload.indexOf(e)>-1)return kv(t,a,n);a.forEach(i=>{t.options.ns.indexOf(i)<0&&t.options.ns.push(i)}),t.loadLanguages(e,HP(t,n))},sH=(t,e,a={})=>!e.languages||!e.languages.length?(VP(e,"NO_LANGUAGES","i18n.languages were undefined or empty",{languages:e.languages}),!0):e.hasLoadedNamespace(t,{lng:a.lng,precheck:(n,i)=>{if(a.bindI18n&&a.bindI18n.indexOf("languageChanging")>-1&&n.services.backendConnector.backend&&n.isLanguageChangingTo&&!i(n.isLanguageChangingTo,t))return!1}}),Ko=t=>typeof t=="string",lH=t=>typeof t=="object"&&t!==null,cH=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,dH={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"â¦","…":"â¦","/":"/","/":"/"},uH=t=>dH[t],pH=t=>t.replace(cH,uH);let Sv={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:pH,transDefaultProps:void 0};const mH=(t={})=>{Sv={...Sv,...t}},hH=()=>Sv;let FP;const fH=t=>{FP=t},gH=()=>FP,yH={type:"3rdParty",init(t){mH(t.options.react),fH(t)}},xH=k.createContext();class vH{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach(a=>{this.usedNamespaces[a]||(this.usedNamespaces[a]=!0)})}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}var BP={exports:{}},UP={};/** 52 * @license React 53 * use-sync-external-store-shim.production.js 54 * 55 * Copyright (c) Meta Platforms, Inc. and affiliates. 56 * 57 * This source code is licensed under the MIT license found in the 58 * LICENSE file in the root directory of this source tree. 59 */var vl=k;function bH(t,e){return t===e&&(t!==0||1/t===1/e)||t!==t&&e!==e}var wH=typeof Object.is=="function"?Object.is:bH,kH=vl.useState,SH=vl.useEffect,_H=vl.useLayoutEffect,AH=vl.useDebugValue;function EH(t,e){var a=e(),n=kH({inst:{value:a,getSnapshot:e}}),i=n[0].inst,r=n[1];return _H(function(){i.value=a,i.getSnapshot=e,i0(i)&&r({inst:i})},[t,a,e]),SH(function(){return i0(i)&&r({inst:i}),t(function(){i0(i)&&r({inst:i})})},[t]),AH(a),a}function i0(t){var e=t.getSnapshot;t=t.value;try{var a=e();return!wH(t,a)}catch{return!0}}function CH(t,e){return e()}var jH=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?CH:EH;UP.useSyncExternalStore=vl.useSyncExternalStore!==void 0?vl.useSyncExternalStore:jH;BP.exports=UP;var ig=BP.exports;const TH=(t,e)=>Ko(e)?e:lH(e)&&Ko(e.defaultValue)?e.defaultValue:Array.isArray(t)?t[t.length-1]:t,NH={t:TH,ready:!1},IH=()=>()=>{},$=(t,e={})=>{var j,N,L;const{i18n:a}=e,{i18n:n,defaultNS:i}=k.useContext(xH)||{},r=a||n||gH();r&&!r.reportNamespaces&&(r.reportNamespaces=new vH),r||VP(r,"NO_I18NEXT_INSTANCE","useTranslation: You will need to pass in an i18next instance by using initReactI18next");const o=k.useMemo(()=>{var O;return{...hH(),...(O=r==null?void 0:r.options)==null?void 0:O.react,...e}},[r,e]),{useSuspense:l,keyPrefix:c}=o,d=i||((j=r==null?void 0:r.options)==null?void 0:j.defaultNS),u=Ko(d)?[d]:d||["translation"],p=k.useMemo(()=>u,u);(L=(N=r==null?void 0:r.reportNamespaces)==null?void 0:N.addUsedNamespaces)==null||L.call(N,p);const m=k.useRef(0),h=k.useCallback(O=>{if(!r)return IH;const{bindI18n:R,bindI18nStore:G}=o,ee=()=>{m.current+=1,O()};return R&&r.on(R,ee),G&&r.store.on(G,ee),()=>{R&&R.split(" ").forEach(ke=>r.off(ke,ee)),G&&G.split(" ").forEach(ke=>r.store.off(ke,ee))}},[r,o]),g=k.useRef(),y=k.useCallback(()=>{if(!r)return NH;const O=!!(r.isInitialized||r.initializedStoreOnce)&&p.every(F=>sH(F,r,o)),R=e.lng||r.language,G=m.current,ee=g.current;if(ee&&ee.ready===O&&ee.lng===R&&ee.keyPrefix===c&&ee.revision===G)return ee;const ae={t:r.getFixedT(R,o.nsMode==="fallback"?p:p[0],c),ready:O,lng:R,keyPrefix:c,revision:G};return g.current=ae,ae}
59,[r,p,c,o,e.lng]),[x,v]=k.useState(0),{t:w,ready:S}=ig.useSyncExternalStore(h,y,y);k.useEffect(()=>{if(r&&!S&&!l){const O=()=>v(R=>R+1);e.lng?fA(r,e.lng,p,O):kv(r,p,O)}},[r,e.lng,p,S,l,x]);const T=r||{},P=k.useRef(null),M=k.useRef(),C=O=>{const R=Object.getOwnPropertyDescriptors(O);R.__original&&delete R.__original;const G=Object.create(Object.getPrototypeOf(O),R);if(!Object.prototype.hasOwnProperty.call(G,"__original"))try{Object.defineProperty(G,"__original",{value:O,writable:!1,enumerable:!1,configurable:!1})}catch{}return G},E=k.useMemo(()=>{const O=T,R=O==null?void 0:O.language;let G=O;O&&(P.current&&P.current.__original===O?M.current!==R?(G=C(O),P.current=G,M.current=R):G=P.current:(G=C(O),P.current=G,M.current=R));const ee=[w,G,S];return ee.t=w,ee.i18n=G,ee.ready=S,ee},[w,T,S,T.resolvedLanguage,T.language,T.languages]);if(r&&l&&!S)throw new Promise(O=>{const R=()=>O();e.lng?fA(r,e.lng,p,R):kv(r,p,R)});return E};function PH(){const{openModal:t}=oa(),{t:e,i18n:a}=$(),[n,i]=k.useState(!1),[r,o]=k.useState(!1);k.useEffect(()=>{const u=()=>{o(window.scrollY>50)};return window.addEventListener("scroll",u),()=>window.removeEventListener("scroll",u)},[]);const l=u=>{u.preventDefault(),t(e("contactModal.title")),i(!1)},c=()=>{const u=a.language==="es"?"en":"es";a.changeLanguage(u),localStorage.setItem("language",u)},d=()=>{i(!1)};return s.jsx("header",{className:`sticky top-0 z-50 bg-darkGray backdrop-blur-md transition-all duration-300 ${r?"py-2":"py-4"}`,children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:[s.jsxs("div",{className:`flex justify-between items-center transition-all duration-300 ${r?"h-12":"h-14"}`,children:[s.jsx(Te,{to:"/",id:"header-logo-link",className:"flex items-center gap-3 hover:opacity-80 transition-opacity",children:s.jsx("img",{id:"image-logo-haka",src:"/imagenes/logo_haka.png",alt:"HakaLab",className:`w-auto transition-all duration-300 ${r?"h-10":"h-16"}`})}),s.jsxs("nav",{className:`hidden md:flex gap-8 items-center transition-all duration-300 ${r?"text-sm":"text-base"}`,children:[s.jsx(Te,{id:"header-servicios-link",to:"/servicios",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.servicios")}),s.jsx(Te,{id:"header-nosotros-link",to:"/nosotros",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.nosotros")}),s.jsx(Te,{id:"header-casos-link",to:"/casosdeexito",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.casosDeExito")}),s.jsx(Te,{id:"header-productos-link",to:"/productos",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.productos")}),s.jsx("button",{id:"header-contacto-button",onClick:l,className:"text-gray-300 hover:text-primary transition-colors bg-none border-none cursor-pointer",children:e("nav.contacto")}),s.jsx("button",{id:"header-language-toggle",onClick:c,className:`ml-4 px-3 py-1 bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 ${r?"text-xs":"text-sm"}`,children:a.language==="es"?"EN":"ES"})]}),s.jsx("button",{id:"header-mobile-menu-toggle",onClick:()=>i(!n),className:"md:hidden text-primary text-2xl",children:n?"â":"â°"})]}),n&&s.jsxs("nav",{className:"md:hidden pb-4 space-y-2 text-center mt-4",children:[s.jsx(Te,{to:"/servicios",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.servicios")}),s.jsx(Te,{to:"/nosotros",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.nosotros")}),s.jsx(Te,{to:"/casosdeexito",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.casosDeExito")}),s.jsx(Te,{to:"/productos",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.productos")}),s.jsx(Te,{to:"/blog",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:"Blog"}),s.jsx("button",{onClick:l,className:"w-full text-center px-4 py-2 text-gray-300 hover:text-primary transition-colors bg-none border-none cursor-pointer border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.contacto")}),s.jsx("div",{className:"px-4 py-2 flex justify-center",children:s.jsx("button",{onClick:c,className:"px-3 py-1 bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold rounded-full text-sm transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50",children:a.language==="es"?"EN":"ES"})})]})]})})}const nw=k.createContext({});function zr(t){const e=k.useRef(null);return e.current===null&&(e.current=t()),e.current}const $P=typeof window<"u",rg=$P?k.useLayoutEffect:k.useEffect,og=k.createContext(null);function iw(t,e){t.indexOf(e)===-1&&t.push(e)}function rw(t,e){const a=t.indexOf(e);a>-1&&t.splice(a,1)}
vendor: 27,829 bytes, line 59
59const On=(t,e,a)=>a>e?e:a<t?t:a;let Jd=()=>{};const qi={},WP=t=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(t);function GP(t){return typeof t=="object"&&t!==null}const KP=t=>/^0[^.\s]+$/u.test(t);function ow(t){let e;return()=>(e===void 0&&(e=t()),e)}const Ta=t=>t,RH=(t,e)=>a=>e(t(a)),Tu=(...t)=>t.reduce(RH),bl=(t,e,a)=>{const n=e-t;return n===0?1:(a-t)/n};class sw{constructor(){this.subscriptions=[]}add(e){return iw(this.subscriptions,e),()=>rw(this.subscriptions,e)}notify(e,a,n){const i=this.subscriptions.length;if(i)if(i===1)this.subscriptions[0](e,a,n);else for(let r=0;r<i;r++){const o=this.subscriptions[r];o&&o(e,a,n)}}getSize(){return this.subscriptions.length}clear(){this.subscriptions.length=0}}const ji=t=>t*1e3,ln=t=>t/1e3;function lw(t,e){return e?t*(1e3/e):0}const JP=(t,e,a)=>(((1-3*a+3*e)*t+(3*a-6*e))*t+3*e)*t,LH=1e-7,OH=12;function MH(t,e,a,n,i){let r,o,l=0;do o=e+(a-e)/2,r=JP(o,n,i)-t,r>0?a=o:e=o;while(Math.abs(r)>LH&&++l<OH);return o}function Nu(t,e,a,n){if(t===e&&a===n)return Ta;const i=r=>MH(r,0,1,t,a);return r=>r===0||r===1?r:JP(i(r),e,n)}const QP=t=>e=>e<=.5?t(2*e)/2:(2-t(2*(1-e)))/2,XP=t=>e=>1-t(1-e),YP=Nu(.33,1.53,.69,.99),cw=XP(YP),ZP=QP(cw),e4=t=>(t*=2)<1?.5*cw(t):.5*(2-Math.pow(2,-10*(t-1))),dw=t=>1-Math.sin(Math.acos(t)),t4=XP(dw),a4=QP(dw),DH=Nu(.42,0,1,1),qH=Nu(0,0,.58,1),n4=Nu(.42,0,.58,1),zH=t=>Array.isArray(t)&&typeof t[0]!="number",i4=t=>Array.isArray(t)&&typeof t[0]=="number",VH={linear:Ta,easeIn:DH,easeInOut:n4,easeOut:qH,circIn:dw,circInOut:a4,circOut:t4,backIn:cw,backInOut:ZP,backOut:YP,anticipate:e4},HH=t=>typeof t=="string",gA=t=>{if(i4(t)){Jd(t.length===4);const[e,a,n,i]=t;return Nu(e,a,n,i)}else if(HH(t))return VH[t];return t},Op=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"];function FH(t,e){let a=new Set,n=new Set,i=!1,r=!1;const o=new WeakSet;let l={delta:0,timestamp:0,isProcessing:!1};function c(u){o.has(u)&&(d.schedule(u),t()),u(l)}const d={schedule:(u,p=!1,m=!1)=>{const g=m&&i?a:n;return p&&o.add(u),g.has(u)||g.add(u),u},cancel:u=>{n.delete(u),o.delete(u)},process:u=>{if(l=u,i){r=!0;return}i=!0,[a,n]=[n,a],a.forEach(c),a.clear(),i=!1,r&&(r=!1,d.process(u))}};return d}const BH=40;function r4(t,e){let a=!1,n=!0;const i={delta:0,timestamp:0,isProcessing:!1},r=()=>a=!0,o=Op.reduce((S,T)=>(S[T]=FH(r),S),{}),{setup:l,read:c,resolveKeyframes:d,preUpdate:u,update:p,preRender:m,render:h,postRender:g}=o,y=()=>{const S=qi.useManualTiming?i.timestamp:performance.now();a=!1,qi.useManualTiming||(i.delta=n?1e3/60:Math.max(Math.min(S-i.timestamp,BH),1)),i.timestamp=S,i.isProcessing=!0,l.process(i),c.process(i),d.process(i),u.process(i),p.process(i),m.process(i),h.process(i),g.process(i),i.isProcessing=!1,a&&e&&(n=!1,t(y))},x=()=>{a=!0,n=!0,i.isProcessing||t(y)};return{schedule:Op.reduce((S,T)=>{const P=o[T];return S[T]=(M,C=!1,E=!1)=>(a||x(),P.schedule(M,C,E)),S},{}),cancel:S=>{for(let T=0;T<Op.length;T++)o[Op[T]].cancel(S)},state:i,steps:o}}const{schedule:Ne,cancel:Mn,state:Et,steps:r0}=r4(typeof requestAnimationFrame<"u"?requestAnimationFrame:Ta,!0);let Cm;function UH(){Cm=void 0}const pa={now:()=>(Cm===void 0&&pa.set(Et.isProcessing||qi.useManualTiming?Et.timestamp:performance.now()),Cm),set:t=>{Cm=t,queueMicrotask(UH)}},o4=t=>e=>typeof e=="string"&&e.startsWith(t),s4=o4("--"),$H=o4("var(--"),uw=t=>$H(t)?WH.test(t.split("/*")[0].trim()):!1,WH=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;function yA(t){return typeof t!="string"?!1:t.split("/*")[0].includes("var(--")}const Ul={test:t=>typeof t=="number",parse:parseFloat,transform:t=>t},Qd={...Ul,transform:t=>On(0,1,t)},Mp={...Ul,default:1},od=t=>Math.round(t*1e5)/1e5,pw=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;function GH(t){return t==null}const KH=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,mw=(t,e)=>a=>!!(typeof a=="string"&&KH.test(a)&&a.startsWith(t)||e&&!GH(a)&&Object.prototype.hasOwnProperty.call(a,e)),l4=(t,e,a)=>n=>{if(typeof n!="string")return n;const[i,r,o,l]=n.match(pw);return{[t]:parseFloat(i),[e]:parseFloat(r),[a]:parseFloat(o),alpha:l!==void 0?parseFloat(l):1}},JH=t=>On(0,255,t),o0={...Ul,transform:t=>Math.round(JH(t))},wo={test:mw("rgb","red"),parse:l4("red","green","blue"),transform:({red:t,green:e,blue:a,alpha:n=1})=>"rgba("+o0.transform(t)+", "+o0.transform(e)+", "+o0.transform(a)+", "+od(Qd.transform(n))+")"};function QH(t){let e="",a="",n="",i="";return t.length>5?(e=t.substring(1,3),a=t.substring(3,5),n=t.substring(5,7),i=t.substring(7,9)):(e=t.substring(1,2),a=t.substring(2,3),n=t.substring(3,4),i=t.substring(4,5),e+=e,a+=a,n+=n,i+=i),{red:parseInt(e,16),green:parseInt(a,16),blue:parseInt(n,16),alpha:i?parseInt(i,16)/255:1}}const _v={test:mw("#"),parse:QH,transform:wo.transform},Iu=t=>({test:e=>typeof e=="string"&&e.endsWith(t)&&e.split(" ").length===1,parse:parseFloat,transform:e=>`${e}${t}`}),Yi=Iu("deg"),Zn=Iu("%"),J=Iu("px"),XH=Iu("vh"),YH=Iu("vw"),xA={...Zn,parse:t=>Zn.parse(t)/100,transform:t=>Zn.transform(t*100)},$s={test:mw("hsl","hue"),parse:l4("hue","saturation","lightness"),transform:({hue:t,saturation:e,lightness:a,alpha:n=1})=>"hsla("+Math.round(t)+", "+Zn.transform(od(e))+", "+Zn.transform(od(a))+", "+od(Qd.transform(n))+")"},ht={test:t=>wo.test(t)||_v.test(t)||$s.test(t),parse:t=>wo.test(t)?wo.parse(t):$s.test(t)?$s.parse(t):_v.parse(t),transform:t=>typeof t=="string"?t:t.hasOwnProperty("red")?wo.transform(t):$s.transform(t),getAnimatableNone:t=>{const e=ht.parse(t);return e.alpha=0,ht.transform(e)}},ZH=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;function eF(t){var e,a;return isNaN(t)&&typeof t=="string"&&(((e=t.match(pw))==null?void 0:e.length)||0)+(((a=t.match(ZH))==null?void 0:a.length)||0)>0}const c4="number",d4="color",tF="var",aF="var(",vA="${}",nF=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function Xd(t){const e=t.toString(),a=[],n={color:[],number:[],var:[]},i=[];let r=0;const l=e.replace(nF,c=>(ht.test(c)?(n.color.push(r),i.push(d4),a.push(ht.parse(c))):c.startsWith(aF)?(n.var.push(r),i.push(tF),a.push(c)):(n.number.push(r),i.push(c4),a.push(parseFloat(c))),++r,vA)).split(vA);return{values:a,split:l,indexes:n,types:i}}function u4(t){return Xd(t).values}function p4(t){const{split:e,types:a}=Xd(t),n=e.length;return i=>{let r="";for(let o=0;o<n;o++)if(r+=e[o],i[o]!==void 0){const l=a[o];l===c4?r+=od(i[o]):l===d4?r+=ht.transform(i[o]):r+=i[o]}return r}}const iF=t=>typeof t=="number"?0:ht.test(t)?ht.getAnimatableNone(t):t;function rF(t){const e=u4(t);return p4(t)(e.map(iF))}const Vr={test:eF,parse:u4,createTransformer:p4,getAnimatableNone:rF};function s0(t,e,a){return a<0&&(a+=1),a>1&&(a-=1),a<1/6?t+(e-t)*6*a:a<1/2?e:a<2/3?t+(e-t)*(2/3-a)*6:t}function oF({hue:t,saturation:e,lightness:a,alpha:n}){t/=360,e/=100,a/=100;let i=0,r=0,o=0;if(!e)i=r=o=a;else{const l=a<.5?a*(1+e):a+e-a*e,c=2*a-l;i=s0(c,l,t+1/3),r=s0(c,l,t),o=s0(c,l,t-1/3)}return{red:Math.round(i*255),green:Math.round(r*255),blue:Math.round(o*255),alpha:n}}function wh(t,e){return a=>a>0?e:t}const Xe=(t,e,a)=>t+(e-t)*a,l0=(t,e,a)=>{const n=t*t,i=a*(e*e-n)+n;return i<0?0:Math.sqrt(i)},sF=[_v,wo,$s],lF=t=>sF.find(e=>e.test(t));function bA(t){const e=lF(t);if(!e)return!1;let a=e.parse(t);return e===$s&&(a=oF(a)),a}const wA=(t,e)=>{const a=bA(t),n=bA(e);if(!a||!n)return wh(t,e);const i={...a};return r=>(i.red=l0(a.red,n.red,r),i.green=l0(a.green,n.green,r),i.blue=l0(a.blue,n.blue,r),i.alpha=Xe(a.alpha,n.alpha,r),wo.transform(i))},Av=new Set(["none","hidden"]);function cF(t,e){return Av.has(t)?a=>a<=0?t:e:a=>a>=1?e:t}function dF(t,e){return a=>Xe(t,e,a)}function hw(t){return typeof t=="number"?dF:typeof t=="string"?uw(t)?wh:ht.test(t)?wA:mF:Array.isArray(t)?m4:typeof t=="object"?ht.test(t)?wA:uF:wh}function m4(t,e){const a=[...t],n=a.length,i=t.map((r,o)=>hw(r)(r,e[o]));return r=>{for(let o=0;o<n;o++)a[o]=i[o](r);return a}}function uF(t,e){const a={...t,...e},n={};for(const i in a)t[i]!==void 0&&e[i]!==void 0&&(n[i]=hw(t[i])(t[i],e[i]));return i=>{for(const r in n)a[r]=n[r](i);return a}}function pF(t,e){const a=[],n={color:0,var:0,number:0};for(let i=0;i<e.values.length;i++){const r=e.types[i],o=t.indexes[r][n[r]],l=t.values[o]??0;a[i]=l,n[r]++}return a}const mF=(t,e)=>{const a=Vr.createTransformer(e),n=Xd(t),i=Xd(e);return n.indexes.var.length===i.indexes.var.length&&n.indexes.color.length===i.indexes.color.length&&n.indexes.number.length>=i.indexes.number.length?Av.has(t)&&!i.values.length||Av.has(e)&&!n.values.length?cF(t,e):Tu(m4(pF(n,i),i.values),a):wh(t,e)};function h4(t,e,a){return typeof t=="number"&&typeof e=="number"&&typeof a=="number"?Xe(t,e,a):hw(t)(t,e)}const hF=t=>{const e=({timestamp:a})=>t(a);return{start:(a=!0)=>Ne.update(e,a),stop:()=>Mn(e),now:()=>Et.isProcessing?Et.timestamp:pa.now()}},f4=(t,e,a=10)=>{let n="";const i=Math.max(Math.round(e/a),2);for(let r=0;r<i;r++)n+=Math.round(t(r/(i-1))*1e4)/1e4+", ";return`linear(${n.substring(0,n.length-2)})`},kh=2e4;function fw(t){let e=0;const a=50;let n=t.next(e);for(;!n.done&&e<kh;)e+=a,n=t.next(e);return e>=kh?1/0:e}function fF(t,e=100,a){const n=a({...t,keyframes:[0,e]}),i=Math.min(fw(n),kh);return{type:"keyframes",ease:r=>n.next(i*r).value/e,duration:ln(i)}}const gF=5;function g4(t,e,a){const n=Math.max(e-gF,0);return lw(a-t(n),e-n)}const rt={stiffness:100,damping:10,mass:1,velocity:0,duration:800,bounce:.3,visualDuration:.3,restSpeed:{granular:.01,default:2},restDelta:{granular:.005,default:.5},minDuration:.01,maxDuration:10,minDamping:.05,maxDamping:1},c0=.001;function yF({duration:t=rt.duration,bounce:e=rt.bounce,velocity:a=rt.velocity,mass:n=rt.mass}){let i,r,o=1-e;o=On(rt.minDamping,rt.maxDamping,o),t=On(rt.minDuration,rt.maxDuration,ln(t)),o<1?(i=d=>{const u=d*o,p=u*t,m=u-a,h=Ev(d,o),g=Math.exp(-p);return c0-m/h*g},r=d=>{const p=d*o*t,m=p*a+a,h=Math.pow(o,2)*Math.pow(d,2)*t,g=Math.exp(-p),y=Ev(Math.pow(d,2),o);return(-i(d)+c0>0?-1:1)*((m-h)*g)/y}):(i=d=>{const u=Math.exp(-d*t),p=(d-a)*t+1;return-c0+u*p},r=d=>{const u=Math.exp(-d*t),p=(a-d)*(t*t);return u*p});const l=5/t,c=vF(i,r,l);if(t=ji(t),isNaN(c))return{stiffness:rt.stiffness,damping:rt.damping,duration:t};{const d=Math.pow(c,2)*n;return{stiffness:d,damping:o*2*Math.sqrt(n*d),duration:t}}}const xF=12;function vF(t,e,a){let n=a;for(let i=1;i<xF;i++)n=n-t(n)/e(n);return n}function Ev(t,e){return t*Math.sqrt(1-e*e)}const bF=["duration","bounce"],wF=["stiffness","damping","mass"];function kA(t,e){return e.some(a=>t[a]!==void 0)}function kF(t){let e={velocity:rt.velocity,stiffness:rt.stiffness,damping:rt.damping,mass:rt.mass,isResolvedFromDuration:!1,...t};if(!kA(t,wF)&&kA(t,bF))if(t.visualDuration){const a=t.visualDuration,n=2*Math.PI/(a*1.2),i=n*n,r=2*On(.05,1,1-(t.bounce||0))*Math.sqrt(i);e={...e,mass:rt.mass,stiffness:i,damping:r}}else{const a=yF(t);e={...e,...a,mass:rt.mass},e.isResolvedFromDuration=!0}return e}function Sh(t=rt.visualDuration,e=rt.bounce){const a=typeof t!="object"?{visualDuration:t,keyframes:[0,1],bounce:e}:t;let{restSpeed:n,restDelta:i}=a;const r=a.keyframes[0],o=a.keyframes[a.keyframes.length-1],l={done:!1,value:r},{stiffness:c,damping:d,mass:u,duration:p,velocity:m,isResolvedFromDuration:h}=kF({...a,velocity:-ln(a.velocity||0)}),g=m||0,y=d/(2*Math.sqrt(c*u)),x=o-r,v=ln(Math.sqrt(c/u)),w=Math.abs(x)<5;n||(n=w?rt.restSpeed.granular:rt.restSpeed.default),i||(i=w?rt.restDelta.granular:rt.restDelta.default);let S;if(y<1){const P=Ev(v,y);S=M=>{const C=Math.exp(-y*v*M);return o-C*((g+y*v*x)/P*Math.sin(P*M)+x*Math.cos(P*M))}}else if(y===1)S=P=>o-Math.exp(-v*P)*(x+(g+v*x)*P);else{const P=v*Math.sqrt(y*y-1);S=M=>{const C=Math.exp(-y*v*M),E=Math.min(P*M,300);return o-C*((g+y*v*x)*Math.sinh(E)+P*x*Math.cosh(E))/P}}const T={calculatedDuration:h&&p||null,next:P=>{const M=S(P);if(h)l.done=P>=p;else{let C=P===0?g:0;y<1&&(C=P===0?ji(g):g4(S,P,M));const E=Math.abs(C)<=n,j=Math.abs(o-M)<=i;l.done=E&&j}return l.value=l.done?o:M,l},toString:()=>{const P=Math.min(fw(T),kh),M=f4(C=>T.next(P*C).value,P,30);return P+"ms "+M},toTransition:()=>{}};return T}Sh.applyToOptions=t=>{const e=fF(t,100,Sh);return t.ease=e.ease,t.duration=ji(e.duration),t.type="keyframes",t};function Cv({keyframes:t,velocity:e=0,power:a=.8,timeConstant:n=325,bounceDamping:i=10,bounceStiffness:r=500,modifyTarget:o,min:l,max:c,restDelta:d=.5,restSpeed:u}){const p=t[0],m={done:!1,value:p},h=E=>l!==void 0&&E<l||c!==void 0&&E>c,g=E=>l===void 0?c:c===void 0||Math.abs(l-E)<Math.abs(c-E)?l:c;let y=a*e;const x=p+y,v=o===void 0?x:o(x);v!==x&&(y=v-p);const w=E=>-y*Math.exp(-E/n),S=E=>v+w(E),T=E=>{const j=w(E),N=S(E);m.done=Math.abs(j)<=d,m.value=m.done?v:N};let P,M;const C=E=>{h(m.value)&&(P=E,M=Sh({keyframes:[m.value,g(m.value)],velocity:g4(S,E,m.value),damping:i,stiffness:r,restDelta:d,restSpeed:u}))};return C(0),{calculatedDuration:null,next:E=>{let j=!1;return!M&&P===void 0&&(j=!0,T(E),C(E)),P!==void 0&&E>=P?M.next(E-P):(!j&&T(E),m)}}}function SF(t,e,a){const n=[],i=a||qi.mix||h4,r=t.length-1;for(let o=0;o<r;o++){let l=i(t[o],t[o+1]);if(e){const c=Array.isArray(e)?e[o]||Ta:e;l=Tu(c,l)}n.push(l)}return n}function gw(t,e,{clamp:a=!0,ease:n,mixer:i}={}){const r=t.length;if(Jd(r===e.length),r===1)return()=>e[0];if(r===2&&e[0]===e[1])return()=>e[1];const o=t[0]===t[1];t[0]>t[r-1]&&(t=[...t].reverse(),e=[...e].reverse());const l=SF(e,n,i),c=l.length,d=u=>{if(o&&u<t[0])return e[0];let p=0;if(c>1)for(;p<t.length-2&&!(u<t[p+1]);p++);const m=bl(t[p],t[p+1],u);return l[p](m)};return a?u=>d(On(t[0],t[r-1],u)):d}function _F(t,e){const a=t[t.length-1];for(let n=1;n<=e;n++){const i=bl(0,e,n);t.push(Xe(a,1,i))}}function y4(t){const e=[0];return _F(e,t.length-1),e}function AF(t,e){return t.map(a=>a*e)}function EF(t,e){return t.map(()=>e||n4).splice(0,t.length-1)}function sd({duration:t=300,keyframes:e,times:a,ease:n="easeInOut"}){const i=zH(n)?n.map(gA):gA(n),r={done:!1,value:e[0]},o=AF(a&&a.length===e.length?a:y4(e),t),l=gw(o,e,{ease:Array.isArray(i)?i:EF(e,i)});return{calculatedDuration:t,next:c=>(r.value=l(c),r.done=c>=t,r)}}const CF=t=>t!==null;function yw(t,{repeat:e,repeatType:a="loop"},n,i=1){const r=t.filter(CF),l=i<0||e&&a!=="loop"&&e%2===1?0:r.length-1;return!l||n===void 0?r[l]:n}const jF={decay:Cv,inertia:Cv,tween:sd,keyframes:sd,spring:Sh};function x4(t){typeof t.type=="string"&&(t.type=jF[t.type])}class xw{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(e=>{this.resolve=e})}notifyFinished(){this.resolve()}then(e,a){return this.finished.then(e,a)}}const TF=t=>t/100;class vw extends xw{constructor(e){super(),this.state="idle",this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.stop=()=>{var n,i;const{motionValue:a}=this.options;a&&a.updatedAt!==pa.now()&&this.tick(pa.now()),this.isStopped=!0,this.state!=="idle"&&(this.teardown(),(i=(n=this.options).onStop)==null||i.call(n))},this.options=e,this.initAnimation(),this.play(),e.autoplay===!1&&this.pause()}initAnimation(){const{options:e}=this;x4(e);const{type:a=sd,repeat:n=0,repeatDelay:i=0,repeatType:r,velocity:o=0}=e;let{keyframes:l}=e;const c=a||sd;c!==sd&&typeof l[0]!="number"&&(this.mixKeyframes=Tu(TF,h4(l[0],l[1])),l=[0,100]);const d=c({...e,keyframes:l});r==="mirror"&&(this.mirroredGenerator=c({...e,keyframes:[...l].reverse(),velocity:-o})),d.calculatedDuration===null&&(d.calculatedDuration=fw(d));const{calculatedDuration:u}=d;this.calculatedDuration=u,this.resolvedDuration=u+i,this.totalDuration=this.resolvedDuration*(n+1)-i,this.generator=d}updateTime(e){const a=Math.round(e-this.startTime)*this.playbackSpeed;this.holdTime!==null?this.currentTime=this.holdTime:this.currentTime=a}tick(e,a=!1){const{generator:n,totalDuration:i,mixKeyframes:r,mirroredGenerator:o,resolvedDuration:l,calculatedDuration:c}=this;if(this.startTime===null)return n.next(0);const{delay:d=0,keyframes:u,repeat:p,repeatType:m,repeatDelay:h,type:g,onUpdate:y,finalKeyframe:x}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,e):this.speed<0&&(this.startTime=Math.min(e-i/this.speed,this.startTime)),a?this.currentTime=e:this.updateTime(e);const v=this.currentTime-d*(this.playbackSpeed>=0?1:-1),w=this.playbackSpeed>=0?v<0:v>i;this.currentTime=Math.max(v,0),this.state==="finished"&&this.holdTime===null&&(this.currentTime=i);let S=this.currentTime,T=n;if(p){const E=Math.min(this.currentTime,i)/l;let j=Math.floor(E),N=E%1;!N&&E>=1&&(N=1),N===1&&j--,j=Math.min(j,p+1),!!(j%2)&&(m==="reverse"?(N=1-N,h&&(N-=h/l)):m==="mirror"&&(T=o)),S=On(0,1,N)*l}const P=w?{done:!1,value:u[0]}:T.next(S);r&&(P.value=r(P.value));let{done:M}=P;!w&&c!==null&&(M=this.playbackSpeed>=0?this.currentTime>=i:this.currentTime<=0);const C=this.holdTime===null&&(this.state==="finished"||this.state==="running"&&M);return C&&g!==Cv&&(P.value=yw(u,this.options,x,this.speed)),y&&y(P.value),C&&this.finish(),P}then(e,a){return this.finished.then(e,a)}get duration(){return ln(this.calculatedDuration)}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+ln(e)}get time(){return ln(this.currentTime)}set time(e){var a;e=ji(e),this.currentTime=e,this.startTime===null||this.holdTime!==null||this.playbackSpeed===0?this.holdTime=e:this.driver&&(this.startTime=this.driver.now()-e/this.playbackSpeed),(a=this.driver)==null||a.start(!1)}get speed(){return this.playbackSpeed}set speed(e){this.updateTime(pa.now());const a=this.playbackSpeed!==e;this.playbackSpeed=e,a&&(this.time=ln(this.currentTime))}play(){var i,r;if(this.isStopped)return;const{driver:e=hF,startTime:a}=this.options;this.driver||(this.driver=e(o=>this.tick(o))),(r=(i=this.options).onPlay)==null||r.call(i);const n=this.driver.now();this.state==="finished"?(this.updateFinished(),this.startTime=n):this.holdTime!==null?this.startTime=n-this.holdTime:this.startTime||(this.startTime=a??n),this.state==="finished"&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state="running",this.driver.start()}pause(){this.state="paused",this.updateTime(pa.now()),this.holdTime=this.currentTime}complete(){this.state!=="running"&&this.play(),this.state="finished",this.holdTime=null}finish(){var e,a;this.notifyFinished(),this.teardown(),this.state="finished",(a=(e=this.options).onComplete)==null||a.call(e)}cancel(){var e,a;this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),(a=(e=this.options).onCancel)==null||a.call(e)}teardown(){this.state="idle",this.stopDriver(),this.startTime=this.holdTime=null}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(e){return this.startTime=0,this.tick(e,!0)}attachTimeline(e){var a;return this.options.allowFlatten&&(this.options.type="keyframes",this.options.ease="linear",this.initAnimation()),(a=this.driver)==null||a.stop(),e.observe(this)}}function NF(t){for(let e=1;e<t.length;e++)t[e]??(t[e]=t[e-1])}const ko=t=>t*180/Math.PI,jv=t=>{const e=ko(Math.atan2(t[1],t[0]));return Tv(e)},IF={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:t=>(Math.abs(t[0])+Math.abs(t[3]))/2,rotate:jv,rotateZ:jv,skewX:t=>ko(Math.atan(t[1])),skewY:t=>ko(Math.atan(t[2])),skew:t=>(Math.abs(t[1])+Math.abs(t[2]))/2},Tv=t=>(t=t%360,t<0&&(t+=360),t),SA=jv,_A=t=>Math.sqrt(t[0]*t[0]+t[1]*t[1]),AA=t=>Math.sqrt(t[4]*t[4]+t[5]*t[5]),PF={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:_A,scaleY:AA,scale:t=>(_A(t)+AA(t))/2,rotateX:t=>Tv(ko(Math.atan2(t[6],t[5]))),rotateY:t=>Tv(ko(Math.atan2(-t[2],t[0]))),rotateZ:SA,rotate:SA,skewX:t=>ko(Math.atan(t[4])),skewY:t=>ko(Math.atan(t[1])),skew:t=>(Math.abs(t[1])+Math.abs(t[4]))/2};function Nv(t){return t.includes("scale")?1:0}function Iv(t,e){if(!t||t==="none")return Nv(e);const a=t.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);let n,i;if(a)n=PF,i=a;else{const l=t.match(/^matrix\(([-\d.e\s,]+)\)$/u);n=IF,i=l}if(!i)return Nv(e);const r=n[e],o=i[1].split(",").map(LF);return typeof r=="function"?r(o):o[r]}const RF=(t,e)=>{const{transform:a="none"}=getComputedStyle(t);return Iv(a,e)};function LF(t){return parseFloat(t.trim())}const $l=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],Wl=new Set($l),EA=t=>t===Ul||t===J,OF=new Set(["x","y","z"]),MF=$l.filter(t=>!OF.has(t));function DF(t){const e=[];return MF.forEach(a=>{const n=t.getValue(a);n!==void 0&&(e.push([a,n.get()]),n.set(a.startsWith("scale")?1:0))}),e}const gr={width:({x:t},{paddingLeft:e="0",paddingRight:a="0"})=>t.max-t.min-parseFloat(e)-parseFloat(a),height:({y:t},{paddingTop:e="0",paddingBottom:a="0"})=>t.max-t.min-parseFloat(e)-parseFloat(a),top:(t,{top:e})=>parseFloat(e),left:(t,{left:e})=>parseFloat(e),bottom:({y:t},{top:e})=>parseFloat(e)+(t.max-t.min),right:({x:t},{left:e})=>parseFloat(e)+(t.max-t.min),x:(t,{transform:e})=>Iv(e,"x"),y:(t,{transform:e})=>Iv(e,"y")};gr.translateX=gr.x;gr.translateY=gr.y;const Ro=new Set;let Pv=!1,Rv=!1,Lv=!1;function v4(){if(Rv){const t=Array.from(Ro).filter(n=>n.needsMeasurement),e=new Set(t.map(n=>n.element)),a=new Map;e.forEach(n=>{const i=DF(n);i.length&&(a.set(n,i),n.render())}),t.forEach(n=>n.measureInitialState()),e.forEach(n=>{n.render();const i=a.get(n);i&&i.forEach(([r,o])=>{var l;(l=n.getValue(r))==null||l.set(o)})}),t.forEach(n=>n.measureEndState()),t.forEach(n=>{n.suspendedScrollY!==void 0&&window.scrollTo(0,n.suspendedScrollY)})}Rv=!1,Pv=!1,Ro.forEach(t=>t.complete(Lv)),Ro.clear()}function b4(){Ro.forEach(t=>{t.readKeyframes(),t.needsMeasurement&&(Rv=!0)})}function qF(){Lv=!0,b4(),v4(),Lv=!1}class bw{constructor(e,a,n,i,r,o=!1){this.state="pending",this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...e],this.onComplete=a,this.name=n,this.motionValue=i,this.element=r,this.isAsync=o}scheduleResolve(){this.state="scheduled",this.isAsync?(Ro.add(this),Pv||(Pv=!0,Ne.read(b4),Ne.resolveKeyframes(v4))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:e,name:a,element:n,motionValue:i}=this;if(e[0]===null){const r=i==null?void 0:i.get(),o=e[e.length-1];if(r!==void 0)e[0]=r;else if(n&&a){const l=n.readValue(a,o);l!=null&&(e[0]=l)}e[0]===void 0&&(e[0]=o),i&&r===void 0&&i.set(e[0])}NF(e)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(e=!1){this.state="complete",this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,e),Ro.delete(this)}cancel(){this.state==="scheduled"&&(Ro.delete(this),this.state="pending")}resume(){this.state==="pending"&&this.scheduleResolve()}}const zF=t=>t.startsWith("--");function VF(t,e,a){zF(e)?t.style.setProperty(e,a):t.style[e]=a}const w4=ow(()=>window.ScrollTimeline!==void 0),HF={};function FF(t,e){const a=ow(t);return()=>HF[e]??a()}const k4=FF(()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch{return!1}return!0},"linearEasing"),qc=([t,e,a,n])=>`cubic-bezier(${t}, ${e}, ${a}, ${n})`,CA={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:qc([0,.65,.55,1]),circOut:qc([.55,0,1,.45]),backIn:qc([.31,.01,.66,-.59]),backOut:qc([.33,1.53,.69,.99])};function S4(t,e){if(t)return typeof t=="function"?k4()?f4(t,e):"ease-out":i4(t)?qc(t):Array.isArray(t)?t.map(a=>S4(a,e)||CA.easeOut):CA[t]}function BF(t,e,a,{delay:n=0,duration:i=300,repeat:r=0,repeatType:o="loop",ease:l="easeOut",times:c}={},d=void 0){const u={[e]:a};c&&(u.offset=c);const p=S4(l,i);Array.isArray(p)&&(u.easing=p);const m={delay:n,duration:i,easing:Array.isArray(p)?"linear":p,fill:"both",iterations:r+1,direction:o==="reverse"?"alternate":"normal"};return d&&(m.pseudoElement=d),t.animate(u,m)}function _4(t){return typeof t=="function"&&"applyToOptions"in t}function UF({type:t,...e}){return _4(t)&&k4()?t.applyToOptions(e):(e.duration??(e.duration=300),e.ease??(e.ease="easeOut"),e)}class $F extends xw{constructor(e){if(super(),this.finishedTime=null,this.isStopped=!1,this.manualStartTime=null,!e)return;const{element:a,name:n,keyframes:i,pseudoElement:r,allowFlatten:o=!1,finalKeyframe:l,onComplete:c}=e;this.isPseudoElement=!!r,this.allowFlatten=o,this.options=e,Jd(typeof e.type!="string");const d=UF(e);this.animation=BF(a,n,i,d,r),d.autoplay===!1&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!r){const u=yw(i,this.options,l,this.speed);this.updateMotionValue?this.updateMotionValue(u):VF(a,n,u),this.animation.cancel()}c==null||c(),this.notifyFinished()}}play(){this.isStopped||(this.manualStartTime=null,this.animation.play(),this.state==="finished"&&this.updateFinished())}pause(){this.animation.pause()}complete(){var e,a;(a=(e=this.animation).finish)==null||a.call(e)}cancel(){try{this.animation.cancel()}catch{}}stop(){if(this.isStopped)return;this.isStopped=!0;const{state:e}=this;e==="idle"||e==="finished"||(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){var e,a;this.isPseudoElement||(a=(e=this.animation).commitStyles)==null||a.call(e)}get duration(){var a,n;const e=((n=(a=this.animation.effect)==null?void 0:a.getComputedTiming)==null?void 0:n.call(a).duration)||0;return ln(Number(e))}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+ln(e)}get time(){return ln(Number(this.animation.currentTime)||0)}set time(e){this.manualStartTime=null,this.finishedTime=null,this.animation.currentTime=ji(e)}get speed(){return this.animation.playbackRate}set speed(e){e<0&&(this.finishedTime=null),this.animation.playbackRate=e}get state(){return this.finishedTime!==null?"finished":this.animation.playState}get startTime(){return this.manualStartTime??Number(this.animation.startTime)}set startTime(e){this.manualStartTime=this.animation.startTime=e}attachTimeline({timeline:e,observe:a}){var n;return this.allowFlatten&&((n=this.animation.effect)==null||n.updateTiming({easing:"linear"})),this.animation.onfinish=null,e&&w4()?(this.animation.timeline=e,Ta):a(this)}}const A4={anticipate:e4,backInOut:ZP,circInOut:a4};function WF(t){return t in A4}function GF(t){typeof t.ease=="string"&&WF(t.ease)&&(t.ease=A4[t.ease])}const d0=10;class KF extends $F{constructor(e){GF(e),x4(e),super(e),e.startTime!==void 0&&(this.startTime=e.startTime),this.options=e}updateMotionValue(e){const{motionValue:a,onUpdate:n,onComplete:i,element:r,...o}=this.options;if(!a)return;if(e!==void 0){a.set(e);return}const l=new vw({...o,autoplay:!1}),c=Math.max(d0,pa.now()-this.startTime),d=On(0,d0,c-d0);a.setWithVelocity(l.sample(Math.max(0,c-d)).value,l.sample(c).value,d),l.stop()}}const jA=(t,e)=>e==="zIndex"?!1:!!(typeof t=="number"||Array.isArray(t)||typeof t=="string"&&(Vr.test(t)||t==="0")&&!t.startsWith("url("));function JF(t){const e=t[0];if(t.length===1)return!0;for(let a=0;a<t.length;a++)if(t[a]!==e)return!0}function QF(t,e,a,n){const i=t[0];if(i===null)return!1;if(e==="display"||e==="visibility")return!0;const r=t[t.length-1],o=jA(i,e),l=jA(r,e);return!o||!l?!1:JF(t)||(a==="spring"||_4(a))&&n}function Ov(t){t.duration=0,t.type="keyframes"}const XF=new Set(["opacity","clipPath","filter","transform"]),YF=ow(()=>Object.hasOwnProperty.call(Element.prototype,"animate"));function ZF(t){var u;const{motionValue:e,name:a,repeatDelay:n,repeatType:i,damping:r,type:o}=t;if(!(((u=e==null?void 0:e.owner)==null?void 0:u.current)instanceof HTMLElement))return!1;const{onUpdate:c,transformTemplate:d}=e.owner.getProps();return YF()&&a&&XF.has(a)&&(a!=="transform"||!d)&&!c&&!n&&i!=="mirror"&&r!==0&&o!=="inertia"}const e7=40;class t7 extends xw{constructor({autoplay:e=!0,delay:a=0,type:n="keyframes",repeat:i=0,repeatDelay:r=0,repeatType:
59o="loop",keyframes:l,name:c,motionValue:d,element:u,...p}){var g;super(),this.stop=()=>{var y,x;this._animation&&(this._animation.stop(),(y=this.stopTimeline)==null||y.call(this)),(x=this.keyframeResolver)==null||x.cancel()},this.createdAt=pa.now();const m={autoplay:e,delay:a,type:n,repeat:i,repeatDelay:r,repeatType:o,name:c,motionValue:d,element:u,...p},h=(u==null?void 0:u.KeyframeResolver)||bw;this.keyframeResolver=new h(l,(y,x,v)=>this.onKeyframesResolved(y,x,m,!v),c,d,u),(g=this.keyframeResolver)==null||g.scheduleResolve()}onKeyframesResolved(e,a,n,i){this.keyframeResolver=void 0;const{name:r,type:o,velocity:l,delay:c,isHandoff:d,onUpdate:u}=n;this.resolvedAt=pa.now(),QF(e,r,o,l)||((qi.instantAnimations||!c)&&(u==null||u(yw(e,n,a))),e[0]=e[e.length-1],Ov(n),n.repeat=0);const m={startTime:i?this.resolvedAt?this.resolvedAt-this.createdAt>e7?this.resolvedAt:this.createdAt:this.createdAt:void 0,finalKeyframe:a,...n,keyframes:e},h=!d&&ZF(m)?new KF({...m,element:m.motionValue.owner.current}):new vw(m);h.finished.then(()=>this.notifyFinished()).catch(Ta),this.pendingTimeline&&(this.stopTimeline=h.attachTimeline(this.pendingTimeline),this.pendingTimeline=void 0),this._animation=h}get finished(){return this._animation?this.animation.finished:this._finished}then(e,a){return this.finished.finally(e).then(()=>{})}get animation(){var e;return this._animation||((e=this.keyframeResolver)==null||e.resume(),qF()),this._animation}get duration(){return this.animation.duration}get iterationDuration(){return this.animation.iterationDuration}get time(){return this.animation.time}set time(e){this.animation.time=e}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(e){this.animation.speed=e}get startTime(){return this.animation.startTime}attachTimeline(e){return this._animation?this.stopTimeline=this.animation.attachTimeline(e):this.pendingTimeline=e,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){var e;this._animation&&this.animation.cancel(),(e=this.keyframeResolver)==null||e.cancel()}}const a7=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function n7(t){const e=a7.exec(t);if(!e)return[,];const[,a,n,i]=e;return[`--${a??n}`,i]}function E4(t,e,a=1){const[n,i]=n7(t);if(!n)return;const r=window.getComputedStyle(e).getPropertyValue(n);if(r){const o=r.trim();return WP(o)?parseFloat(o):o}return uw(i)?E4(i,e,a+1):i}function ww(t,e){return(t==null?void 0:t[e])??(t==null?void 0:t.default)??t}const i7={type:"spring",stiffness:500,damping:25,restSpeed:10},r7=t=>({type:"spring",stiffness:550,damping:t===0?2*Math.sqrt(550):30,restSpeed:10}),o7={type:"keyframes",duration:.8},s7={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},l7=(t,{keyframes:e})=>e.length>2?o7:Wl.has(t)?t.startsWith("scale")?r7(e[1]):i7:s7;function c7({when:t,delay:e,delayChildren:a,staggerChildren:n,staggerDirection:i,repeat:r,repeatType:o,repeatDelay:l,from:c,elapsed:d,...u}){return!!Object.keys(u).length}const d7=t=>t!==null;function u7(t,{repeat:e,repeatType:a="loop"},n){const i=t.filter(d7),r=e&&a!=="loop"&&e%2===1?0:i.length-1;return i[r]}function C4(t,e,a,n=0,i=1){const r=Array.from(t).sort((d,u)=>d.sortNodePosition(u)).indexOf(e),o=t.size,l=(o-1)*n;return typeof a=="function"?a(r,o):i===1?r*n:l-r*n}const kw=(t,e,a,n={},i,r)=>o=>{const l=ww(n,t)||{},c=l.delay||n.delay||0;let{elapsed:d=0}=n;d=d-ji(c);const u={keyframes:Array.isArray(a)?a:[null,a],ease:"easeOut",velocity:e.getVelocity(),...l,delay:-d,onUpdate:m=>{e.set(m),l.onUpdate&&l.onUpdate(m)},onComplete:()=>{o(),l.onComplete&&l.onComplete()},name:t,motionValue:e,element:r?void 0:i};c7(l)||Object.assign(u,l7(t,u)),u.duration&&(u.duration=ji(u.duration)),u.repeatDelay&&(u.repeatDelay=ji(u.repeatDelay)),u.from!==void 0&&(u.keyframes[0]=u.from);let p=!1;if((u.type===!1||u.duration===0&&!u.repeatDelay)&&(Ov(u),u.delay===0&&(p=!0)),(qi.instantAnimations||qi.skipAnimations)&&(p=!0,Ov(u),u.delay=0),u.allowFlatten=!l.type&&!l.ease,p&&!r&&e.get()!==void 0){const m=u7(u.keyframes,l);if(m!==void 0){Ne.update(()=>{u.onUpdate(m),u.onComplete()});return}}return l.isSync?new vw(u):new t7(u)},j4=new Set(["width","height","top","left","right","bottom",...$l]),TA=30,p7=t=>!isNaN(parseFloat(t)),ld={current:void 0};class m7{constructor(e,a={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=n=>{var r;const i=pa.now();if(this.updatedAt!==i&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(n),this.current!==this.prev&&((r=this.events.change)==null||r.notify(this.current),this.dependents))for(const o of this.dependents)o.dirty()},this.hasAnimated=!1,this.setCurrent(e),this.owner=a.owner}setCurrent(e){this.current=e,this.updatedAt=pa.now(),this.canTrackVelocity===null&&e!==void 0&&(this.canTrackVelocity=p7(this.current))}setPrevFrameValue(e=this.current){this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt}onChange(e){return this.on("change",e)}on(e,a){this.events[e]||(this.events[e]=new sw);const n=this.events[e].add(a);return e==="change"?()=>{n(),Ne.read(()=>{this.events.change.getSize()||this.stop()})}:n}clearListeners(){for(const e in this.events)this.events[e].clear()}attach(e,a){this.passiveEffect=e,this.stopPassiveEffect=a}set(e){this.passiveEffect?this.passiveEffect(e,this.updateAndNotify):this.updateAndNotify(e)}setWithVelocity(e,a,n){this.set(a),this.prev=void 0,this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt-n}jump(e,a=!0){this.updateAndNotify(e),this.prev=e,this.prevUpdatedAt=this.prevFrameValue=void 0,a&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){var e;(e=this.events.change)==null||e.notify(this.current)}addDependent(e){this.dependents||(this.dependents=new Set),this.dependents.add(e)}removeDependent(e){this.dependents&&this.dependents.delete(e)}get(){return ld.current&&ld.current.push(this),this.current}getPrevious(){return this.prev}getVelocity(){const e=pa.now();if(!this.canTrackVelocity||this.prevFrameValue===void 0||e-this.updatedAt>TA)return 0;const a=Math.min(this.updatedAt-this.prevUpdatedAt,TA);return lw(parseFloat(this.current)-parseFloat(this.prevFrameValue),a)}start(e){return this.stop(),new Promise(a=>
vendor: 7,426 bytes, line 59
59{this.hasAnimated=!0,this.animation=e(a),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){var e,a;(e=this.dependents)==null||e.clear(),(a=this.events.destroy)==null||a.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function Cn(t,e){return new m7(t,e)}function NA(t){const e=[{},{}];return t==null||t.values.forEach((a,n)=>{e[0][n]=a.get(),e[1][n]=a.getVelocity()}),e}function Sw(t,e,a,n){if(typeof e=="function"){const[i,r]=NA(n);e=e(a!==void 0?a:t.custom,i,r)}if(typeof e=="string"&&(e=t.variants&&t.variants[e]),typeof e=="function"){const[i,r]=NA(n);e=e(a!==void 0?a:t.custom,i,r)}return e}function rl(t,e,a){const n=t.getProps();return Sw(n,e,a!==void 0?a:n.custom,t)}const Mv=t=>Array.isArray(t);function h7(t,e,a){t.hasValue(e)?t.getValue(e).set(a):t.addValue(e,Cn(a))}function f7(t){return Mv(t)?t[t.length-1]||0:t}function g7(t,e){const a=rl(t,e);let{transitionEnd:n={},transition:i={},...r}=a||{};r={...r,...n};for(const o in r){const l=f7(r[o]);h7(t,o,l)}}const na=t=>!!(t&&t.getVelocity);function y7(t){return!!(na(t)&&t.add)}function Dv(t,e){const a=t.getValue("willChange");if(y7(a))return a.add(e);if(!a&&qi.WillChange){const n=new qi.WillChange("auto");t.addValue("willChange",n),n.add(e)}}function _w(t){return t.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`)}const x7="framerAppearId",T4="data-"+_w(x7);function N4(t){return t.props[T4]}function v7({protectedKeys:t,needsAnimating:e},a){const n=t.hasOwnProperty(a)&&e[a]!==!0;return e[a]=!1,n}function I4(t,e,{delay:a=0,transitionOverride:n,type:i}={}){let{transition:r=t.getDefaultTransition(),transitionEnd:o,...l}=e;n&&(r=n);const c=[],d=i&&t.animationState&&t.animationState.getState()[i];for(const u in l){const p=t.getValue(u,t.latestValues[u]??null),m=l[u];if(m===void 0||d&&v7(d,u))continue;const h={delay:a,...ww(r||{},u)},g=p.get();if(g!==void 0&&!p.isAnimating&&!Array.isArray(m)&&m===g&&!h.velocity)continue;let y=!1;if(window.MotionHandoffAnimation){const v=N4(t);if(v){const w=window.MotionHandoffAnimation(v,u,Ne);w!==null&&(h.startTime=w,y=!0)}}Dv(t,u),p.start(kw(u,p,m,t.shouldReduceMotion&&j4.has(u)?{type:!1}:h,t,y));const x=p.animation;x&&c.push(x)}return o&&Promise.all(c).then(()=>{Ne.update(()=>{o&&g7(t,o)})}),c}function qv(t,e,a={}){var c;const n=rl(t,e,a.type==="exit"?(c=t.presenceContext)==null?void 0:c.custom:void 0);let{transition:i=t.getDefaultTransition()||{}}=n||{};a.transitionOverride&&(i=a.transitionOverride);const r=n?()=>Promise.all(I4(t,n,a)):()=>Promise.resolve(),o=t.variantChildren&&t.variantChildren.size?(d=0)=>{const{delayChildren:u=0,staggerChildren:p,staggerDirection:m}=i;return b7(t,e,d,u,p,m,a)}:()=>Promise.resolve(),{when:l}=i;if(l){const[d,u]=l==="beforeChildren"?[r,o]:[o,r];return d().then(()=>u())}else return Promise.all([r(),o(a.delay)])}function b7(t,e,a=0,n=0,i=0,r=1,o){const l=[];for(const c of t.variantChildren)c.notify("AnimationStart",e),l.push(qv(c,e,{...o,delay:a+(typeof n=="function"?0:n)+C4(t.variantChildren,c,n,i,r)}).then(()=>c.notify("AnimationComplete",e)));return Promise.all(l)}function w7(t,e,a={}){t.notify("AnimationStart",e);let n;if(Array.isArray(e)){const i=e.map(r=>qv(t,r,a));n=Promise.all(i)}else if(typeof e=="string")n=qv(t,e,a);else{const i=typeof e=="function"?rl(t,e,a.custom):e;n=Promise.all(I4(t,i,a))}return n.then(()=>{t.notify("AnimationComplete",e)})}const k7={test:t=>t==="auto",parse:t=>t},P4=t=>e=>e.test(t),R4=[Ul,J,Zn,Yi,YH,XH,k7],IA=t=>R4.find(P4(t));function S7(t){return typeof t=="number"?t===0:t!==null?t==="none"||t==="0"||KP(t):!0}const _7=new Set(["brightness","contrast","saturate","opacity"]);function A7(t){const[e,a]=t.slice(0,-1).split("(");if(e==="drop-shadow")return t;const[n]=a.match(pw)||[];if(!n)return t;const i=a.replace(n,"");let r=_7.has(e)?1:0;return n!==a&&(r*=100),e+"("+r+i+")"}const E7=/\b([a-z-]*)\(.*?\)/gu,zv={...Vr,getAnimatableNone:t=>{const e=t.match(E7);return e?e.map(A7).join(" "):t}},PA={...Ul,transform:Math.round},C7={rotate:Yi,rotateX:Yi,rotateY:Yi,rotateZ:Yi,scale:Mp,scaleX:Mp,scaleY:Mp,scaleZ:Mp,skew:Yi,skewX:Yi,skewY:Yi,distance:J,translateX:J,translateY:J,translateZ:J,x:J,y:J,z:J,perspective:J,transformPerspective:J,opacity:Qd,originX:xA,originY:xA,originZ:J},Aw={borderWidth:J,borderTopWidth:J,borderRightWidth:J,borderBottomWidth:J,borderLeftWidth:J,borderRadius:J,radius:J,borderTopLeftRadius:J,borderTopRightRadius:J,borderBottomRightRadius:J,borderBottomLeftRadius:J,width:J,maxWidth:J,height:J,maxHeight:J,top:J,right:J,bottom:J,left:J,inset:J,insetBlock:J,insetBlockStart:J,insetBlockEnd:J,insetInline:J,insetInlineStart:J,insetInlineEnd:J,padding:J,paddingTop:J,paddingRight:J,paddingBottom:J,paddingLeft:J,paddingBlock:J,paddingBlockStart:J,paddingBlockEnd:J,paddingInline:J,paddingInlineStart:J,paddingInlineEnd:J,margin:J,marginTop:J,marginRight:J,marginBottom:J,marginLeft:J,marginBlock:J,marginBlockStart:J,marginBlockEnd:J,marginInline:J,marginInlineStart:J,marginInlineEnd:J,backgroundPositionX:J,backgroundPositionY:J,...C7,zIndex:PA,fillOpacity:Qd,strokeOpacity:Qd,numOctaves:PA},j7={...Aw,color:ht,backgroundColor:ht,outlineColor:ht,fill:ht,stroke:ht,borderColor:ht,borderTopColor:ht,borderRightColor:ht,borderBottomColor:ht,borderLeftColor:ht,filter:zv,WebkitFilter:zv},L4=t=>j7[t];function O4(t,e){let a=L4(t);return a!==zv&&(a=Vr),a.getAnimatableNone?a.getAnimatableNone(e):void 0}const T7=new Set(["auto","none","0"]);function N7(t,e,a){let n=0,i;for(;n<t.length&&!i;){const r=t[n];typeof r=="string"&&!T7.has(r)&&Xd(r).values.length&&(i=t[n]),n++}if(i&&a)for(const r of e)t[r]=O4(a,i)}class I7 extends bw{constructor(e,a,n,i,r){super(e,a,n,i,r,!0)}readKeyframes(){const{unresolvedKeyframes:e,element:a,name:n}=this;if(!a||!a.current)return;super.readKeyframes();for(let u=0;u<e.length;u++){let p=e[u];if(typeof p=="string"&&(p=p.trim(),uw(p))){const m=E4(p,a.current);m!==void 0&&(e[u]=m),u===e.length-1&&(this.finalKeyframe=p)}}if(this.resolveNoneKeyframes(),!j4.has(n)||e.length!==2)return;const[i,r]=e,o=IA(i),l=IA(r),c=yA(i),d=yA(r);if(c!==d&&gr[n]){this.needsMeasurement=!0;return}if(o!==l)if(EA(o)&&EA(l))for(let u=0;u<e.length;u++){const p=e[u];typeof p=="string"&&(e[u]=parseFloat(p))}else gr[n]&&(this.needsMeasurement=!0)}resolveNoneKeyframes(){const{unresolvedKeyframes:e,name:a}=this,n=[];for(let i=0;i<e.length;i++)(e[i]===null||S7(e[i]))&&n.push(i);n.length&&N7(e,n,a)}measureInitialState(){const{element:e,unresolvedKeyframes:a,name:n}=this;if(!e||!e.current)return;n==="height"&&(this.suspendedScrollY=window.pageYOffset),this.measuredOrigin=gr[n](e.measureViewportBox(),window.getComputedStyle(e.current)),a[0]=this.measuredOrigin;const i=a[a.length-1];i!==void 0&&e.getValue(n,i).jump(i,!1)}measureEndState(){var l;const{element:e,name:a,unresolvedKeyframes:n}=this;if(!e||!e.current)return;const i=e.getValue(a);i&&i.jump(this.measuredOrigin,!1);const r=n.length-1,o=n[r];n[r]=gr[a](e.measureViewportBox(),window.getComputedStyle(e.current)),o!==null&&this.finalKeyframe===void 0&&(this.finalKeyframe=o),(l=this.removedTransforms)!=null&&l.length&&this.removedTransforms.forEac
vendor: 6,863 bytes, line 59
59h(([c,d])=>{e.getValue(c).set(d)}),this.resolveNoneKeyframes()}}function Ew(t,e,a){if(t instanceof EventTarget)return[t];if(typeof t=="string"){const i=document.querySelectorAll(t);return i?Array.from(i):[]}return Array.from(t)}const M4=(t,e)=>e&&typeof t=="number"?e.transform(t):t;function Cw(t){return GP(t)&&"offsetHeight"in t}const{schedule:jw}=r4(queueMicrotask,!1),wn={x:!1,y:!1};function D4(){return wn.x||wn.y}function P7(t){return t==="x"||t==="y"?wn[t]?null:(wn[t]=!0,()=>{wn[t]=!1}):wn.x||wn.y?null:(wn.x=wn.y=!0,()=>{wn.x=wn.y=!1})}function q4(t,e){const a=Ew(t),n=new AbortController,i={passive:!0,...e,signal:n.signal};return[a,i,()=>n.abort()]}function RA(t){return!(t.pointerType==="touch"||D4())}function R7(t,e,a={}){const[n,i,r]=q4(t,a),o=l=>{if(!RA(l))return;const{target:c}=l,d=e(c,l);if(typeof d!="function"||!c)return;const u=p=>{RA(p)&&(d(p),c.removeEventListener("pointerleave",u))};c.addEventListener("pointerleave",u,i)};return n.forEach(l=>{l.addEventListener("pointerenter",o,i)}),r}const z4=(t,e)=>e?t===e?!0:z4(t,e.parentElement):!1,Tw=t=>t.pointerType==="mouse"?typeof t.button!="number"||t.button<=0:t.isPrimary!==!1,L7=new Set(["BUTTON","INPUT","SELECT","TEXTAREA","A"]);function V4(t){return L7.has(t.tagName)||t.isContentEditable===!0}const jm=new WeakSet;function LA(t){return e=>{e.key==="Enter"&&t(e)}}function u0(t,e){t.dispatchEvent(new PointerEvent("pointer"+e,{isPrimary:!0,bubbles:!0}))}const O7=(t,e)=>{const a=t.currentTarget;if(!a)return;const n=LA(()=>{if(jm.has(a))return;u0(a,"down");const i=LA(()=>{u0(a,"up")}),r=()=>u0(a,"cancel");a.addEventListener("keyup",i,e),a.addEventListener("blur",r,e)});a.addEventListener("keydown",n,e),a.addEventListener("blur",()=>a.removeEventListener("keydown",n),e)};function OA(t){return Tw(t)&&!D4()}function M7(t,e,a={}){const[n,i,r]=q4(t,a),o=l=>{const c=l.currentTarget;if(!OA(l))return;jm.add(c);const d=e(c,l),u=(h,g)=>{window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",m),jm.has(c)&&jm.delete(c),OA(h)&&typeof d=="function"&&d(h,{success:g})},p=h=>{u(h,c===window||c===document||a.useGlobalTarget||z4(c,h.target))},m=h=>{u(h,!1)};window.addEventListener("pointerup",p,i),window.addEventListener("pointercancel",m,i)};return n.forEach(l=>{(a.useGlobalTarget?window:l).addEventListener("pointerdown",o,i),Cw(l)&&(l.addEventListener("focus",d=>O7(d,i)),!V4(l)&&!l.hasAttribute("tabindex")&&(l.tabIndex=0))}),r}function Nw(t){return GP(t)&&"ownerSVGElement"in t}const Tm=new WeakMap;let Zi;const H4=(t,e,a)=>(n,i)=>i&&i[0]?i[0][t+"Size"]:Nw(n)&&"getBBox"in n?n.getBBox()[e]:n[a],D7=H4("inline","width","offsetWidth"),q7=H4("block","height","offsetHeight");function z7({target:t,borderBoxSize:e}){var a;(a=Tm.get(t))==null||a.forEach(n=>{n(t,{get width(){return D7(t,e)},get height(){return q7(t,e)}})})}function V7(t){t.forEach(z7)}function H7(){typeof ResizeObserver>"u"||(Zi=new ResizeObserver(V7))}function F7(t,e){Zi||H7();const a=Ew(t);return a.forEach(n=>{let i=Tm.get(n);i||(i=new Set,Tm.set(n,i)),i.add(e),Zi==null||Zi.observe(n)}),()=>{a.forEach(n=>{const i=Tm.get(n);i==null||i.delete(e),i!=null&&i.size||Zi==null||Zi.unobserve(n)})}}const Nm=new Set;let Ws;function B7(){Ws=()=>{const t={get width(){return window.innerWidth},get height(){return window.innerHeight}};Nm.forEach(e=>e(t))},window.addEventListener("resize",Ws)}function U7(t){return Nm.add(t),Ws||B7(),()=>{Nm.delete(t),!Nm.size&&typeof Ws=="function"&&(window.removeEventListener("resize",Ws),Ws=void 0)}}function $7(t,e){return typeof t=="function"?U7(t):F7(t,e)}function F4(t,e){let a;const n=()=>{const{currentTime:i}=e,o=(i===null?0:i.value)/100;a!==o&&t(o),a=o};return Ne.preUpdate(n,!0),()=>Mn(n)}function W7(t){return Nw(t)&&t.tagName==="svg"}function G7(...t){const e=!Array.isArray(t[0]),a=e?0:-1,n=t[0+a],i=t[1+a],r=t[2+a],o=t[3+a],l=gw(i,r,o);return e?l(n):l}const K7=[...R4,ht,Vr],J7=t=>K7.find(P4(t)),MA=()=>({translate:0,scale:1,origin:0,originPoint:0}),Gs=()=>({x:MA(),y:MA()}),DA=()=>({min:0,max:0}),bt=()=>({x:DA(),y:DA()}),Vv={current:null},B4={current:!1},Q7=typeof window<"u";function X7(){if(B4.current=!0,!!Q7)if(window.matchMedia){const t=window.matchMedia("(prefers-reduced-motion)"),e=()=>Vv.current=t.matches;t.addEventListener("change",e),e()}else Vv.current=!1}const Y7=new WeakMap;function sg(t){return t!==null&&typeof t=="object"&&typeof t.start=="function"}function Yd(t){return typeof t=="string"||Array.isArray(t)}const Iw=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],Pw=["initial",...Iw];function lg(t){return sg(t.animate)||Pw.some(e=>Yd(t[e]))}function U4(t){return!!(lg(t)||t.variants)}function Z7(t,e,a){for(const n in e){const i=e[n],r=a[n];if(na(i))t.addValue(n,i);else if(na(r))t.addValue(n,Cn(i,{owner:t}));else if(r!==i)if(t.hasValue(n)){const o=t.getValue(n);o.liveStyle===!0?o.jump(i):o.hasAnimated||o.set(i)}else{const o=t.getStaticValue(n);t.addValue(n,Cn(o!==void 0?o:i,{owner:t}))}}for(const n in a)e[n]===void 0&&t.removeValue(n);return e}const qA=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];let _h={};function $4(t){_h=t}function eB(){return _h}class tB{scrapeMotionValuesFromProps(e,a,n){return{}}constructor({parent:e,props:a,presenceContext:n,reducedMotionConfig:i,blockInitialAnimation:r,visualState:o},l={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.values=new Map,this.KeyframeResolver=bw,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const m=pa.now();this.renderScheduledAt<m&&(this.renderScheduledAt=m,Ne.render(this.render,!1,!0))};const{latestValues:c,renderState:d}=o;this.latestValues=c,this.baseTarget={...c},this.initialValues=a.initial?{...c}:{},this.renderState=d,this.parent=e,this.props=a,this.presenceContext=n,this.depth=e?e.depth+1:0,this.reducedMotionConfig=i,this.options=l,this.blockInitialAnimation=!!r,this.isControllingVariants=lg(a),this.isVariantNode=U4(a),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(e&&e.current);const{willChange:u,...p}=this.scrapeMotionValuesFromProps(a,{},this);for(const m in p){const h=p[m];c[m]!==void 0&&na(h)&&h.set(c[m])}}mount(e){var a;this.current=e,Y7.set(e,this),this.projection&&!this.projection.instance&&this.projection.mount(e),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEac
vendor: 10,081 bytes, line 59
59h((n,i)=>this.bindToMotionValue(i,n)),this.reducedMotionConfig==="never"?this.shouldReduceMotion=!1:this.reducedMotionConfig==="always"?this.shouldReduceMotion=!0:(B4.current||X7(),this.shouldReduceMotion=Vv.current),(a=this.parent)==null||a.addChild(this),this.update(this.props,this.presenceContext)}unmount(){var e;this.projection&&this.projection.unmount(),Mn(this.notifyUpdate),Mn(this.render),this.valueSubscriptions.forEach(a=>a()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),(e=this.parent)==null||e.removeChild(this);for(const a in this.events)this.events[a].clear();for(const a in this.features){const n=this.features[a];n&&(n.unmount(),n.isMounted=!1)}this.current=null}addChild(e){this.children.add(e),this.enteringChildren??(this.enteringChildren=new Set),this.enteringChildren.add(e)}removeChild(e){this.children.delete(e),this.enteringChildren&&this.enteringChildren.delete(e)}bindToMotionValue(e,a){this.valueSubscriptions.has(e)&&this.valueSubscriptions.get(e)();const n=Wl.has(e);n&&this.onBindTransform&&this.onBindTransform();const i=a.on("change",o=>{this.latestValues[e]=o,this.props.onUpdate&&Ne.preRender(this.notifyUpdate),n&&this.projection&&(this.projection.isTransformDirty=!0),this.scheduleRender()});let r;typeof window<"u"&&window.MotionCheckAppearSync&&(r=window.MotionCheckAppearSync(this,e,a)),this.valueSubscriptions.set(e,()=>{i(),r&&r(),a.owner&&a.stop()})}sortNodePosition(e){return!this.current||!this.sortInstanceNodePosition||this.type!==e.type?0:this.sortInstanceNodePosition(this.current,e.current)}updateFeatures(){let e="animation";for(e in _h){const a=_h[e];if(!a)continue;const{isEnabled:n,Feature:i}=a;if(!this.features[e]&&i&&n(this.props)&&(this.features[e]=new i(this)),this.features[e]){const r=this.features[e];r.isMounted?r.update():(r.mount(),r.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):bt()}getStaticValue(e){return this.latestValues[e]}setStaticValue(e,a){this.latestValues[e]=a}update(e,a){(e.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=e,this.prevPresenceContext=this.presenceContext,this.presenceContext=a;for(let n=0;n<qA.length;n++){const i=qA[n];this.propEventSubscriptions[i]&&(this.propEventSubscriptions[i](),delete this.propEventSubscriptions[i]);const r="on"+i,o=e[r];o&&(this.propEventSubscriptions[i]=this.on(i,o))}this.prevMotionValues=Z7(this,this.scrapeMotionValuesFromProps(e,this.prevProps||{},this),this.prevMotionValues),this.handleChildMotionValue&&this.handleChildMotionValue()}getProps(){return this.props}getVariant(e){return this.props.variants?this.props.variants[e]:void 0}getDefaultTransition(){return this.props.transition}getTransformPagePoint(){return this.props.transformPagePoint}getClosestVariantNode(){return this.isVariantNode?this:this.parent?this.parent.getClosestVariantNode():void 0}addVariantChild(e){const a=this.getClosestVariantNode();if(a)return a.variantChildren&&a.variantChildren.add(e),()=>a.variantChildren.delete(e)}addValue(e,a){const n=this.values.get(e);a!==n&&(n&&this.removeValue(e),this.bindToMotionValue(e,a),this.values.set(e,a),this.latestValues[e]=a.get())}removeValue(e){this.values.delete(e);const a=this.valueSubscriptions.get(e);a&&(a(),this.valueSubscriptions.delete(e)),delete this.latestValues[e],this.removeValueFromRenderState(e,this.renderState)}hasValue(e){return this.values.has(e)}getValue(e,a){if(this.props.values&&this.props.values[e])return this.props.values[e];let n=this.values.get(e);return n===void 0&&a!==void 0&&(n=Cn(a===null?void 0:a,{owner:this}),this.addValue(e,n)),n}readValue(e,a){let n=this.latestValues[e]!==void 0||!this.current?this.latestValues[e]:this.getBaseTargetFromProps(this.props,e)??this.readValueFromInstance(this.current,e,this.options);return n!=null&&(typeof n=="string"&&(WP(n)||KP(n))?n=parseFloat(n):!J7(n)&&Vr.test(a)&&(n=O4(e,a)),this.setBaseTarget(e,na(n)?n.get():n)),na(n)?n.get():n}setBaseTarget(e,a){this.baseTarget[e]=a}getBaseTarget(e){var r;const{initial:a}=this.props;let n;if(typeof a=="string"||typeof a=="object"){const o=Sw(this.props,a,(r=this.presenceContext)==null?void 0:r.custom);o&&(n=o[e])}if(a&&n!==void 0)return n;const i=this.getBaseTargetFromProps(this.props,e);return i!==void 0&&!na(i)?i:this.initialValues[e]!==void 0&&n===void 0?void 0:this.baseTarget[e]}on(e,a){return this.events[e]||(this.events[e]=new sw),this.events[e].add(a)}notify(e,...a){this.events[e]&&this.events[e].notify(...a)}scheduleRenderMicrotask(){jw.render(this.render)}}class Jr{constructor(e){this.isMounted=!1,this.node=e}update(){}}class W4 extends tB{constructor(){super(...arguments),this.KeyframeResolver=I7}sortInstanceNodePosition(e,a){return e.compareDocumentPosition(a)&2?1:-1}getBaseTargetFromProps(e,a){const n=e.style;return n?n[a]:void 0}removeValueFromRenderState(e,{vars:a,style:n}){delete a[e],delete n[e]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:e}=this.props;na(e)&&(this.childSubscription=e.on("change",a=>{this.current&&(this.current.textContent=`${a}`)}))}}function G4({top:t,left:e,right:a,bottom:n}){return{x:{min:e,max:a},y:{min:t,max:n}}}function aB({x:t,y:e}){return{top:e.min,right:t.max,bottom:e.max,left:t.min}}function nB(t,e){if(!e)return t;const a=e({x:t.left,y:t.top}),n=e({x:t.right,y:t.bottom});return{top:a.y,left:a.x,bottom:n.y,right:n.x}}function p0(t){return t===void 0||t===1}function Hv({scale:t,scaleX:e,scaleY:a}){return!p0(t)||!p0(e)||!p0(a)}function ho(t){return Hv(t)||K4(t)||t.z||t.rotate||t.rotateX||t.rotateY||t.skewX||t.skewY}function K4(t){return zA(t.x)||zA(t.y)}function zA(t){return t&&t!=="0%"}function Ah(t,e,a){const n=t-a,i=e*n;return a+i}function VA(t,e,a,n,i){return i!==void 0&&(t=Ah(t,i,n)),Ah(t,a,n)+e}function Fv(t,e=0,a=1,n,i){t.min=VA(t.min,e,a,n,i),t.max=VA(t.max,e,a,n,i)}function J4(t,{x:e,y:a}){Fv(t.x,e.translate,e.scale,e.originPoint),Fv(t.y,a.translate,a.scale,a.originPoint)}const HA=.999999999999,FA=1.0000000000001;function iB(t,e,a,n=!1){const i=a.length;if(!i)return;e.x=e.y=1;let r,o;for(let l=0;l<i;l++){r=a[l],o=r.projectionDelta;const{visualElement:c}=r.options;c&&c.props.style&&c.props.style.display==="contents"||(n&&r.options.layoutScroll&&r.scroll&&r!==r.root&&Js(t,{x:-r.scroll.offset.x,y:-r.scroll.offset.y}),o&&(e.x*=o.x.scale,e.y*=o.y.scale,J4(t,o)),n&&ho(r.latestValues)&&Js(t,r.latestValues))}e.x<FA&&e.x>HA&&(e.x=1),e.y<FA&&e.y>HA&&(e.y=1)}function Ks(t,e){t.min=t.min+e,t.max=t.max+e}function BA(t,e,a,n,i=.5){const r=Xe(t.min,t.max,i);Fv(t,e,a,r,n)}function Js(t,e){BA(t.x,e.x,e.scaleX,e.scale,e.originX),BA(t.y,e.y,e.scaleY,e.scale,e.originY)}function Q4(t,e){return G4(nB(t.getBoundingClientRect(),e))}function rB(t,e,a){const n=Q4(t,a),{scroll:i}=e;return i&&(Ks(n.x,i.offset.x),Ks(n.y,i.offset.y)),n}const oB={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},sB=$l.length;function lB(t,e,a){let n="",i=!0;for(let r=0;r<sB;r++){const o=$l[r],l=t[o];if(l===void 0)continue;let c=!0;if(typeof l=="number"?c=l===(o.startsWith("scale")?1:0):c=parseFloat(l)===0,!c||a){const d=M4(l,Aw[o]);if(!c){i=!1;const u=oB[o]||o;n+=`${u}(${d}) `}a&&(e[o]=d)}}return n=n.trim(),a?n=a(e,i?"":n):i&&(n="none"),n}function Rw(t,e,a){const{style:n,vars:i,transformOrigin:r}=t;let o=!1,l=!1;for(const c in e){const d=e[c];if(Wl.has(c)){o=!0;continue}else if(s4(c)){i[c]=d;continue}else{const u=M4(d,Aw[c]);c.startsWith("origin")?(l=!0,r[c]=u):n[c]=u}}if(e.transform||(o||a?n.transform=lB(e,t.transform,a):n.transform&&(n.transform="none")),l){const{originX:c="50%",originY:d="50%",originZ:u=0}=r;n.transformOrigin=`${c} ${d} ${u}`}}function X4(t,{style:e,vars:a},n,i){const r=t.style;let o;for(o in e)r[o]=e[o];i==null||i.applyProjectionStyles(r,n);for(o in a)r.setProperty(o,a[o])}function UA(t,e){return e.max===e.min?0:t/(e.max-e.min)*100}const Ec={correct:(t,e)=>{if(!e.target)return t;if(typeof t=="string")if(J.test(t))t=parseFloat(t);else return t;const a=UA(t,e.target.x),n=UA(t,e.target.y);return`${a}% ${n}%`}},cB={correct:(t,{treeScale:e,projectionDelta:a})=>{const n=t,i=Vr.parse(t);if(i.length>5)return n;const r=Vr.createTransformer(t),o=typeof i[0]!="number"?1:0,l=a.x.scale*e.x,c=a.y.scale*e.y;i[0+o]/=l,i[1+o]/=c;const d=Xe(l,c,.5);return typeof i[2+o]=="number"&&(i[2+o]/=d),typeof i[3+o]=="number"&&(i[3+o]/=d),r(i)}},Bv={borderRadius:{...Ec,applyTo:["borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"]},borderTopLeftRadius:Ec,borderTopRightRadius:Ec,borderBottomLeftRadius:Ec,borderBottomRightRadius:Ec,boxShadow:cB};function Y4(t,{layout:e,layoutId:a}){return Wl.has(t)||t.startsWith("origin")||(e||a!==void 0)&&(!!Bv[t]||t==="opacity")}function Lw(t,e,a){var o;const n=t.style,i=e==null?void 0:e.style,r={};if(!n)return r;for(const l in n)(na(n[l])||i&&na(i[l])||Y4(l,t)||((o=a==null?void 0:a.getValue(l))==null?void 0:o.liveStyle)!==void 0)&&(r[l]=n[l]);return r}function dB(t){return window.getComputedStyle(t)}class uB extends W4{constructor(){super(...arguments),this.type="html",this.renderInstance=X4}readValueFromInstance(e,a){var n;if(Wl.has(a))return(n=this.projection)!=null&&n.isProjecting?Nv(a):RF(e,a);{const i=dB(e),r=(s4(a)?i.getPropertyValue(a):i[a])||0;return typeof r=="string"?r.trim():r}}measureInstanceViewportBox(e,{transformPagePoint:a}){return Q4(e,a)}build(e,a,n){Rw(e,a,n.transformTemplate)}scrapeMotionValuesFromProps(e,a,n){return Lw(e,a,n)}}const pB={offset:"stroke-dashoffset",array:"stroke-dasharray"},mB={offset:"strokeDashoffset",array:"strokeDasharray"};function hB(t,e,a=1,n=0,i=!0){t.pathLength=1;const r=i?pB:mB;t[r.offset]=J.transform(-n);const o=J.transform(e),l=J.transform(a);t[r.array]=`${o} ${l}`}const fB=["offsetDistance","offsetPath","offsetRotate","offsetAnchor"];function Z4(t,{attrX:e,attrY:a,attrScale:n,pathLength:i,pathSpacing:r=1,pathOffset:o=0,...l}
vendor: 1,571 bytes, line 59
59,c,d,u){if(Rw(t,l,d),c){t.style.viewBox&&(t.attrs.viewBox=t.style.viewBox);return}t.attrs=t.style,t.style={};const{attrs:p,style:m}=t;p.transform&&(m.transform=p.transform,delete p.transform),(m.transform||p.transformOrigin)&&(m.transformOrigin=p.transformOrigin??"50% 50%",delete p.transformOrigin),m.transform&&(m.transformBox=(u==null?void 0:u.transformBox)??"fill-box",delete p.transformBox);for(const h of fB)p[h]!==void 0&&(m[h]=p[h],delete p[h]);e!==void 0&&(p.x=e),a!==void 0&&(p.y=a),n!==void 0&&(p.scale=n),i!==void 0&&hB(p,i,r,o,!1)}const eR=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]),tR=t=>typeof t=="string"&&t.toLowerCase()==="svg";function gB(t,e,a,n){X4(t,e,void 0,n);for(const i in e.attrs)t.setAttribute(eR.has(i)?i:_w(i),e.attrs[i])}function aR(t,e,a){const n=Lw(t,e,a);for(const i in t)if(na(t[i])||na(e[i])){const r=$l.indexOf(i)!==-1?"attr"+i.charAt(0).toUpperCase()+i.substring(1):i;n[r]=t[i]}return n}class yB extends W4{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=bt}getBaseTargetFromProps(e,a){return e[a]}readValueFromInstance(e,a){if(Wl.has(a)){const n=L4(a);return n&&n.default||0}return a=eR.has(a)?a:_w(a),e.getAttribute(a)}scrapeMotionValuesFromProps(e,a,n){return aR(e,a,n)}
vendor: 2,932 bytes, line 59
59build(e,a,n){Z4(e,a,this.isSVGTag,n.transformTemplate,n.style)}renderInstance(e,a,n,i){gB(e,a,n,i)}mount(e){this.isSVGTag=tR(e.tagName),super.mount(e)}}const xB=Pw.length;function nR(t){if(!t)return;if(!t.isControllingVariants){const a=t.parent?nR(t.parent)||{}:{};return t.props.initial!==void 0&&(a.initial=t.props.initial),a}const e={};for(let a=0;a<xB;a++){const n=Pw[a],i=t.props[n];(Yd(i)||i===!1)&&(e[n]=i)}return e}function iR(t,e){if(!Array.isArray(e))return!1;const a=e.length;if(a!==t.length)return!1;for(let n=0;n<a;n++)if(e[n]!==t[n])return!1;return!0}const vB=[...Iw].reverse(),bB=Iw.length;function wB(t){return e=>Promise.all(e.map(({animation:a,options:n})=>w7(t,a,n)))}function kB(t){let e=wB(t),a=$A(),n=!0;const i=c=>(d,u)=>{var m;const p=rl(t,u,c==="exit"?(m=t.presenceContext)==null?void 0:m.custom:void 0);if(p){const{transition:h,transitionEnd:g,...y}=p;d={...d,...y,...g}}return d};function r(c){e=c(t)}function o(c){const{props:d}=t,u=nR(t.parent)||{},p=[],m=new Set;let h={},g=1/0;for(let x=0;x<bB;x++){const v=vB[x],w=a[v],S=d[v]!==void 0?d[v]:u[v],T=Yd(S),P=v===c?w.isActive:null;P===!1&&(g=x);let M=S===u[v]&&S!==d[v]&&T;if(M&&n&&t.manuallyAnimateOnMount&&(M=!1),w.protectedKeys={...h},!w.isActive&&P===null||!S&&!w.prevProp||sg(S)||typeof S=="boolean")continue;const C=SB(w.prevProp,S);let E=C||v===c&&w.isActive&&!M&&T||x>g&&T,j=!1;const N=Array.isArray(S)?S:[S];let L=N.reduce(i(v),{});P===!1&&(L={});const{prevResolvedValues:O={}}=w,R={...O,...L},G=ae=>{E=!0,m.has(ae)&&(j=!0,m.delete(ae)),w.needsAnimating[ae]=!0;const F=t.getValue(ae);F&&(F.liveStyle=!1)};for(const ae in R){const F=L[ae],Z=O[ae];if(h.hasOwnProperty(ae))continue;let re=!1;Mv(F)&&Mv(Z)?re=!iR(F,Z):re=F!==Z,re?F!=null?G(ae):m.add(ae):F!==void 0&&m.has(ae)?G(ae):w.protectedKeys[ae]=!0}w.prevProp=S,w.prevResolvedValues=L,w.isActive&&(h={...h,...L}),n&&t.blockInitialAnimation&&(E=!1);const ee=M&&C;E&&(!ee||j)&&p.push(...N.map(ae=>{const F={type:v};if(typeof ae=="string"&&n&&!ee&&t.manuallyAnimateOnMount&&t.parent){const{parent:Z}=t,re=rl(Z,ae);if(Z.enteringChildren&&re){const{delayChildren:fe}=re.transition||{};F.delay=C4(Z.enteringChildren,t,fe)}}return{animation:ae,options:F}}))}if(m.size){const x={};if(typeof d.initial!="boolean"){const v=rl(t,Array.isArray(d.initial)?d.initial[0]:d.initial);v&&v.transition&&(x.transition=v.transition)}m.forEach(v=>{const w=t.getBaseTarget(v),S=t.getValue(v);S&&(S.liveStyle=!0),x[v]=w??null}),p.push({animation:x})}let y=!!p.length;return n&&(d.initial===!1||d.initial===d.animate)&&!t.manuallyAnimateOnMount&&(y=!1),n=!1,y?e(p):Promise.resolve()}function l(c,d){var p;if(a[c].isActive===d)return Promise.resolve();(p=t.variantChildren)==null||p.forEach(m=>{var h;return(h=m.animationState)==null?void 0:h.setActive(c,d)}),a[c].isActive=d;const u=o(c);for(const m in a)a[m].protectedKeys={};return u}return{animateChanges:o,setActive:l,setAnimateFunction:r,getState:()=>a,reset:()=>
vendor: 4,136 bytes, line 59
59{a=$A()}}}function SB(t,e){return typeof e=="string"?e!==t:Array.isArray(e)?!iR(e,t):!1}function co(t=!1){return{isActive:t,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function $A(){return{animate:co(!0),whileInView:co(),whileHover:co(),whileTap:co(),whileDrag:co(),whileFocus:co(),exit:co()}}const rR=1e-4,_B=1-rR,AB=1+rR,oR=.01,EB=0-oR,CB=0+oR;function ma(t){return t.max-t.min}function jB(t,e,a){return Math.abs(t-e)<=a}function WA(t,e,a,n=.5){t.origin=n,t.originPoint=Xe(e.min,e.max,t.origin),t.scale=ma(a)/ma(e),t.translate=Xe(a.min,a.max,t.origin)-t.originPoint,(t.scale>=_B&&t.scale<=AB||isNaN(t.scale))&&(t.scale=1),(t.translate>=EB&&t.translate<=CB||isNaN(t.translate))&&(t.translate=0)}function cd(t,e,a,n){WA(t.x,e.x,a.x,n?n.originX:void 0),WA(t.y,e.y,a.y,n?n.originY:void 0)}function GA(t,e,a){t.min=a.min+e.min,t.max=t.min+ma(e)}function TB(t,e,a){GA(t.x,e.x,a.x),GA(t.y,e.y,a.y)}function KA(t,e,a){t.min=e.min-a.min,t.max=t.min+ma(e)}function Eh(t,e,a){KA(t.x,e.x,a.x),KA(t.y,e.y,a.y)}function JA(t,e,a,n,i){return t-=e,t=Ah(t,1/a,n),i!==void 0&&(t=Ah(t,1/i,n)),t}function NB(t,e=0,a=1,n=.5,i,r=t,o=t){if(Zn.test(e)&&(e=parseFloat(e),e=Xe(o.min,o.max,e/100)-o.min),typeof e!="number")return;let l=Xe(r.min,r.max,n);t===r&&(l-=e),t.min=JA(t.min,e,a,l,i),t.max=JA(t.max,e,a,l,i)}function QA(t,e,[a,n,i],r,o){NB(t,e[a],e[n],e[i],e.scale,r,o)}const IB=["x","scaleX","originX"],PB=["y","scaleY","originY"];function XA(t,e,a,n){QA(t.x,e,IB,a?a.x:void 0,n?n.x:void 0),QA(t.y,e,PB,a?a.y:void 0,n?n.y:void 0)}function YA(t,e){t.min=e.min,t.max=e.max}function vn(t,e){YA(t.x,e.x),YA(t.y,e.y)}function ZA(t,e){t.translate=e.translate,t.scale=e.scale,t.originPoint=e.originPoint,t.origin=e.origin}function eE(t){return t.translate===0&&t.scale===1}function sR(t){return eE(t.x)&&eE(t.y)}function tE(t,e){return t.min===e.min&&t.max===e.max}function RB(t,e){return tE(t.x,e.x)&&tE(t.y,e.y)}function aE(t,e){return Math.round(t.min)===Math.round(e.min)&&Math.round(t.max)===Math.round(e.max)}function lR(t,e){return aE(t.x,e.x)&&aE(t.y,e.y)}function nE(t){return ma(t.x)/ma(t.y)}function iE(t,e){return t.translate===e.translate&&t.scale===e.scale&&t.originPoint===e.originPoint}function Za(t){return[t("x"),t("y")]}function LB(t,e,a){let n="";const i=t.x.translate/e.x,r=t.y.translate/e.y,o=(a==null?void 0:a.z)||0;if((i||r||o)&&(n=`translate3d(${i}px, ${r}px, ${o}px) `),(e.x!==1||e.y!==1)&&(n+=`scale(${1/e.x}, ${1/e.y}) `),a){const{transformPerspective:d,rotate:u,rotateX:p,rotateY:m,skewX:h,skewY:g}=a;d&&(n=`perspective(${d}px) ${n}`),u&&(n+=`rotate(${u}deg) `),p&&(n+=`rotateX(${p}deg) `),m&&(n+=`rotateY(${m}deg) `),h&&(n+=`skewX(${h}deg) `),g&&(n+=`skewY(${g}deg) `)}const l=t.x.scale*e.x,c=t.y.scale*e.y;return(l!==1||c!==1)&&(n+=`scale(${l}, ${c})`),n||"none"}const cR=["TopLeft","TopRight","BottomLeft","BottomRight"],OB=cR.length,rE=t=>typeof t=="string"?parseFloat(t):t,oE=t=>typeof t=="number"||J.test(t);function MB(t,e,a,n,i,r){i?(t.opacity=Xe(0,a.opacity??1,DB(n)),t.opacityExit=Xe(e.opacity??1,0,qB(n))):r&&(t.opacity=Xe(e.opacity??1,a.opacity??1,n));for(let o=0;o<OB;o++){const l=`border${cR[o]}Radius`;let c=sE(e,l),d=sE(a,l);if(c===void 0&&d===void 0)continue;c||(c=0),d||(d=0),c===0||d===0||oE(c)===oE(d)?(t[l]=Math.max(Xe(rE(c),rE(d),n),0),(Zn.test(d)||Zn.test(c))&&(t[l]+="%")):t[l]=d}(e.rotate||a.rotate)&&(t.rotate=Xe(e.rotate||0,a.rotate||0,n))}function sE(t,e){return t[e]!==void 0?t[e]:t.borderRadius}const DB=dR(0,.5,t4),qB=dR(.5,.95,Ta);function dR(t,e,a){return n=>n<t?0:n>e?1:a(bl(t,e,n))}function zB(t,e){const a=pa.now(),n=({timestamp:i})=>{const r=i-a;r>=e&&(Mn(n),t(r-e))};return Ne.setup(n,!0),()=>Mn(n)}function Zd(t,e,a,n={passive:!0}){return t.addEventListener(e,a,n),()=>t.removeEventListener(e,a)}function Im(t){return na(t)?t.get():t}function VB(t,e,a){const n=na(t)?t:Cn(t);return n.start(kw("",n,e,a)),n.animation}const HB=(t,e)=>t.depth-e.depth;class FB{constructor(){this.children=[],this.isDirty=!1}add(e){iw(this.children,e),this.isDirty=!0}remove(e){rw(this.children,e),this.isDirty=!0}forEach(e){this.isDirty&&this.children.sort(HB),this.isDirty=!1,this.children.forEac
vendor: 17,284 bytes, line 59
59h(e)}}class BB{constructor(){this.members=[]}add(e){iw(this.members,e),e.scheduleRender()}remove(e){if(rw(this.members,e),e===this.prevLead&&(this.prevLead=void 0),e===this.lead){const a=this.members[this.members.length-1];a&&this.promote(a)}}relegate(e){const a=this.members.findIndex(i=>e===i);if(a===0)return!1;let n;for(let i=a;i>=0;i--){const r=this.members[i];if(r.isPresent!==!1){n=r;break}}return n?(this.promote(n),!0):!1}promote(e,a){const n=this.lead;if(e!==n&&(this.prevLead=n,this.lead=e,e.show(),n)){n.instance&&n.scheduleRender(),e.scheduleRender(),e.resumeFrom=n,a&&(e.resumeFrom.preserveOpacity=!0),n.snapshot&&(e.snapshot=n.snapshot,e.snapshot.latestValues=n.animationValues||n.latestValues),e.root&&e.root.isUpdating&&(e.isLayoutDirty=!0);const{crossfade:i}=e.options;i===!1&&n.hide()}}exitAnimationComplete(){this.members.forEach(e=>{const{options:a,resumingFrom:n}=e;a.onExitComplete&&a.onExitComplete(),n&&n.options.onExitComplete&&n.options.onExitComplete()})}scheduleRender(){this.members.forEach(e=>{e.instance&&e.scheduleRender(!1)})}removeLeadSnapshot(){this.lead&&this.lead.snapshot&&(this.lead.snapshot=void 0)}}const Pm={hasAnimatedSinceResize:!0,hasEverUpdated:!1},m0=["","X","Y","Z"],UB=1e3;let $B=0;function h0(t,e,a,n){const{latestValues:i}=e;i[t]&&(a[t]=i[t],e.setStaticValue(t,0),n&&(n[t]=0))}function uR(t){if(t.hasCheckedOptimisedAppear=!0,t.root===t)return;const{visualElement:e}=t.options;if(!e)return;const a=N4(e);if(window.MotionHasOptimisedAnimation(a,"transform")){const{layout:i,layoutId:r}=t.options;window.MotionCancelOptimisedAnimation(a,"transform",Ne,!(i||r))}const{parent:n}=t;n&&!n.hasCheckedOptimisedAppear&&uR(n)}function pR({attachResizeListener:t,defaultParent:e,measureScroll:a,checkIsScrollRoot:n,resetTransform:i}){return class{constructor(o={},l=e==null?void 0:e()){this.id=$B++,this.animationId=0,this.animationCommitId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.hasCheckedOptimisedAppear=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.layoutVersion=0,this.updateScheduled=!1,this.scheduleUpdate=()=>this.update(),this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,this.nodes.forEach(KB),this.nodes.forEach(YB),this.nodes.forEach(ZB),this.nodes.forEach(JB)},this.resolvedRelativeTargetAt=0,this.linkedParentVersion=0,this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=o,this.root=l?l.root||l:this,this.path=l?[...l.path,l]:[],this.parent=l,this.depth=l?l.depth+1:0;for(let c=0;c<this.path.length;c++)this.path[c].shouldResetTransform=!0;this.root===this&&(this.nodes=new FB)}addEventListener(o,l){return this.eventHandlers.has(o)||this.eventHandlers.set(o,new sw),this.eventHandlers.get(o).add(l)}notifyListeners(o,...l){const c=this.eventHandlers.get(o);c&&c.notify(...l)}hasListeners(o){return this.eventHandlers.has(o)}mount(o){if(this.instance)return;this.isSVG=Nw(o)&&!W7(o),this.instance=o;const{layoutId:l,layout:c,visualElement:d}=this.options;if(d&&!d.current&&d.mount(o),this.root.nodes.add(this),this.parent&&this.parent.children.add(this),this.root.hasTreeAnimated&&(c||l)&&(this.isLayoutDirty=!0),t){let u,p=0;const m=()=>this.root.updateBlockedByResize=!1;Ne.read(()=>{p=window.innerWidth}),t(o,()=>{const h=window.innerWidth;h!==p&&(p=h,this.root.updateBlockedByResize=!0,u&&u(),u=zB(m,250),Pm.hasAnimatedSinceResize&&(Pm.hasAnimatedSinceResize=!1,this.nodes.forEach(dE)))})}l&&this.root.registerSharedNode(l,this),this.options.animate!==!1&&d&&(l||c)&&this.addEventListener("didUpdate",({delta:u,hasLayoutChanged:p,hasRelativeLayoutChanged:m,layout:h})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const g=this.options.transition||d.getDefaultTransition()||i9,{onLayoutAnimationStart:y,onLayoutAnimationComplete:x}=d.getProps(),v=!this.targetLayout||!lR(this.targetLayout,h),w=!p&&m;if(this.options.layoutRoot||this.resumeFrom||w||p&&(v||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0);const S={...ww(g,"layout"),onPlay:y,onComplete:x};(d.shouldReduceMotion||this.options.layoutRoot)&&(S.delay=0,S.type=!1),this.startAnimation(S),this.setAnimationOrigin(u,w)}else p||dE(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=h})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const o=this.getStack();o&&o.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,this.eventHandlers.clear(),Mn(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(e9),this.animationId++)}getTransformTemplate(){const{visualElement:o}=this.options;return o&&o.getProps().transformTemplate}willUpdate(o=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(window.MotionCancelOptimisedAnimation&&!this.hasCheckedOptimisedAppear&&uR(this),!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let u=0;u<this.path.length;u++){const p=this.path[u];p.shouldResetTransform=!0,p.updateScroll("snapshot"),p.options.layoutRoot&&p.willUpdate(!1)}const{layoutId:l,layout:c}=this.options;if(l===void 0&&!c)return;const d=this.getTransformTemplate();this.prevTransformTemplateValue=d?d(this.latestValues,""):void 0,this.updateSnapshot(),o&&this.notifyListeners("willUpdate")}update(){if(this.updateScheduled=!1,this.isUpdateBlocked()){this.unblockUpdate(),this.clearAllSnapshots(),this.nodes.forEach(lE);return}if(this.animationId<=this.animationCommitId){this.nodes.forEach(cE);return}this.animationCommitId=this.animationId,this.isUpdating?(this.isUpdating=!1,this.nodes.forEach(XB),this.nodes.forEach(WB),this.nodes.forEach(GB)):this.nodes.forEach(cE),this.clearAllSnapshots();const l=pa.now();Et.delta=On(0,1e3/60,l-Et.timestamp),Et.timestamp=l,Et.isProcessing=!0,r0.update.process(Et),r0.preRender.process(Et),r0.render.process(Et),Et.isProcessing=!1}didUpdate(){this.updateScheduled||(this.updateScheduled=!0,jw.read(this.scheduleUpdate))}clearAllSnapshots(){this.nodes.forEach(QB),this.sharedNodes.forEach(t9)}scheduleUpdateProjection(){this.projectionUpdateScheduled||(this.projectionUpdateScheduled=!0,Ne.preRender(this.updateProjection,!1,!0))}scheduleCheckAfterUnmount(){Ne.postRender(()=>{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure(),this.snapshot&&!ma(this.snapshot.measuredBox.x)&&!ma(this.snapshot.measuredBox.y)&&(this.snapshot=void 0))}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let c=0;c<this.path.length;c++)this.path[c].updateScroll();const o=this.layout;this.layout=this.measure(!1),this.layoutVersion++,this.layoutCorrected=bt(),this.isLayoutDirty=!1,this.projectionDelta=void 0,this.notifyListeners("measure",this.layout.layoutBox);const{visualElement:l}=this.options;l&&l.notify("LayoutMeasure",this.layout.layoutBox,o?o.layoutBox:void 0)}updateScroll(o="measure"){let l=!!(this.options.layoutScroll&&this.instance);if(this.scroll&&this.scroll.animationId===this.root.animationId&&this.scroll.phase===o&&(l=!1),l&&this.instance){const c=n(this.instance);this.scroll={animationId:this.root.animationId,phase:o,isRoot:c,offset:a(this.instance),wasRoot:this.scroll?this.scroll.isRoot:c}}}resetTransform(){if(!i)return;const o=this.isLayoutDirty||this.shouldResetTransform||this.options.alwaysMeasureLayout,l=this.projectionDelta&&!sR(this.projectionDelta),c=this.getTransformTemplate(),d=c?c(this.latestValues,""):void 0,u=d!==this.prevTransformTemplateValue;o&&this.instance&&(l||ho(this.latestValues)||u)&&(i(this.instance,d),this.shouldResetTransform=!1,this.scheduleRender())}measure(o=!0){const l=this.measurePageBox();let c=this.removeElementScroll(l);return o&&(c=this.removeTransform(c)),r9(c),{animationId:this.root.animationId,measuredBox:l,layoutBox:c,latestValues:{},source:this.id}}measurePageBox(){var d;const{visualElement:o}=this.options;if(!o)return bt();const l=o.measureViewportBox();if(!(((d=this.scroll)==null?void 0:d.wasRoot)||this.path.some(o9))){const{scroll:u}=this.root;u&&(Ks(l.x,u.offset.x),Ks(l.y,u.offset.y))}return l}removeElementScroll(o){var c;const l=bt();if(vn(l,o),(c=this.scroll)!=null&&c.wasRoot)return l;for(let d=0;d<this.path.length;d++){const u=this.path[d],{scroll:p,options:m}=u;u!==this.root&&p&&m.layoutScroll&&(p.wasRoot&&vn(l,o),Ks(l.x,p.offset.x),Ks(l.y,p.offset.y))}return l}applyTransform(o,l=!1){const c=bt();vn(c,o);for(let d=0;d<this.path.length;d++){const u=this.path[d];!l&&u.options.layoutScroll&&u.scroll&&u!==u.root&&Js(c,{x:-u.scroll.offset.x,y:-u.scroll.offset.y}),ho(u.latestValues)&&Js(c,u.latestValues)}return ho(this.latestValues)&&Js(c,this.latestValues),c}removeTransform(o){const l=bt();vn(l,o);for(let c=0;c<this.path.length;c++){const d=this.path[c];if(!d.instance||!ho(d.latestValues))continue;Hv(d.latestValues)&&d.updateSnapshot();const u=bt(),p=d.measurePageBox();vn(u,p),XA(l,d.latestValues,d.snapshot?d.snapshot.layoutBox:void 0,u)}return ho(this.latestValues)&&XA(l,this.latestValues),l}setTargetDelta(o){this.targetDelta=o,this.root.scheduleUpdateProjection(),this.isProjectionDirty=!0}setOptions(o){this.options={...this.options,...o,crossfade:o.crossfade!==void 0?o.crossfade:!0}}clearMeasurements(){this.scroll=void 0,this.layout=void 0,this.snapshot=void 0,this.prevTransformTemplateValue=void 0,this.targetDelta=void 0,this.target=void 0,this.isLayoutDirty=!1}forceRelativeParentToResolveTarget(){this.relativeParent&&this.relativeParent.resolvedRelativeTargetAt!==Et.timestamp&&this.relativeParent.resolveTargetDelta(!0)}resolveTargetDelta(o=!1){var h;const l=this.getLead();this.isProjectionDirty||(this.isProjectionDirty=l.isProjectionDirty),this.isTransformDirty||(this.isTransformDirty=l.isTransformDirty),this.isSharedProjectionDirty||(this.isSharedProjectionDirty=l.isSharedProjectionDirty);const c=!!this.resumingFrom||this!==l;if(!(o||c&&this.isSharedProjectionDirty||this.isProjectionDirty||(h=this.parent)!=null&&h.isProjectionDirty||this.attemptToResolveRelativeTarget||this.root.updateBlockedByResize))return;const{layout:u,layoutId:p}=this.options;if(!this.layout||!(u||p))return;this.resolvedRelativeTargetAt=Et.timestamp;const m=this.getClosestProjectingParent();m&&this.linkedParentVersion!==m.layoutVersion&&!m.options.layoutRoot&&this.removeRelativeTarget(),!this.targetDelta&&!this.relativeTarget&&(m&&m.layout?this.createRelativeTarget(m,this.layout.layoutBox,m.layout.layoutBox):this.removeRelativeTarget()),!(!this.relativeTarget&&!this.targetDelta)&&(this.target||(this.target=bt(),this.targetWithTransforms=bt()),this.relativeTarget&&this.relativeTargetOrigin&&this.relativeParent&&this.relativeParent.target?(this.forceRelativeParentToResolveTarget(),TB(this.target,this.relativeTarget,this.relativeParent.target)):this.targetDelta?(this.resumingFrom?this.target=this.applyTransform(this.layout.layoutBox):vn(this.target,this.layout.layoutBox),J4(this.target,this.targetDelta)):vn(this.target,this.layout.layoutBox),this.attemptToResolveRelativeTarget&&(this.attemptToResolveRelativeTarget=!1,m&&!!m.resumingFrom==!!this.resumingFrom&&!m.options.layoutScroll&&m.target&&this.animationProgress!==1?this.createRelativeTarget(m,this.target,m.target):this.relativeParent=this.relativeTarget=void 0))}getClosestProjectingParent(){if(!(!this.parent||Hv(this.parent.latestValues)||K4(this.parent.latestValues)))return this.parent.isProjecting()?this.parent:this.parent.getClosestProjectingParent()}isProjecting(){return!!((this.relativeTarget||this.targetDelta||this.options.layoutRoot)&&this.layout)}createRelativeTarget(o,l,c){this.relativeParent=o,this.linkedParentVersion=o.layoutVersion,this.forceRelativeParentToResolveTarget(),this.relativeTarget=bt(),this.relativeTargetOrigin=bt(),Eh(this.relativeTargetOrigin,l,c),vn(this.relativeTarget,this.relativeTargetOrigin)}removeRelativeTarget(){this.relativeParent=this.relativeTarget=void 0}calcProjection(){var g;const o=this.getLead(),l=!!this.resumingFrom||this!==o;let c=!0;if((this.isProjectionDirty||(g=this.parent)!=null&&g.isProjectionDirty)&&(c=!1),l&&(this.isSharedProjectionDirty||this.isTransformDirty)&&(c=!1),this.resolvedRelativeTargetAt===Et.timestamp&&(c=!1),c)return;const{layout:d,layoutId:u}=this.options;if(this.isTreeAnimating=!!(this.parent&&this.parent.isTreeAnimating||this.currentAnimation||this.pendingAnimation),this.isTreeAnimating||(this.targetDelta=this.relativeTarget=void 0),!this.layout||!(d||u))return;vn(this.layoutCorrected,this.layout.layoutBox);const p=this.treeScale.x,m=this.treeScale.y;iB(this.layoutCorrected,this.treeScale,this.path,l),o.layout&&!o.target&&(this.treeScale.x!==1||this.treeScale.y!==1)&&(o.target=o.layout.layoutBox,o.targetWithTransforms=bt());const{target:h}=o;if(!h){this.prevProjectionDelta&&(this.createProjectionDeltas(),this.scheduleRender());return}!this.projectionDelta||!this.prevProjectionDelta?this.createProjectionDeltas():(ZA(this.prevProjectionDelta.x,this.projectionDelta.x),ZA(this.prevProjectionDelta.y,this.projectionDelta.y)),cd(this.projectionDelta,this.layoutCorrected,h,this.latestValues),(this.treeScale.x!==p||this.treeScale.y!==m||!iE(this.projectionDelta.x,this.prevProjectionDelta.x)||!iE(this.projectionDelta.y,this.prevProjectionDelta.y))&&(this.hasProjected=!0,this.scheduleRender(),this.notifyListeners("projectionUpdate",h))}hide(){this.isVisible=!1}show(){this.isVisible=!0}scheduleRender(o=!0){var l;if((l=this.options.visualElement)==null||l.scheduleRender(),o){const c=this.getStack();c&&c.scheduleRender()}this.resumingFrom&&!this.resumingFrom.instance&&(this.resumingFrom=void 0)}createProjectionDeltas(){this.prevProjectionDelta=Gs(),this.projectionDelta=Gs(),this.projectionDeltaWithTransform=Gs()}setAnimationOrigin(o,l=!1){const c=this.snapshot,d=c?c.latestValues:{},u={...this.latestValues},p=Gs();(!this.relativeParent||!this.relativeParent.options.layoutRoot)&&(this.relativeTarget=this.relativeTargetOrigin=void 0),this.attemptToResolveRelativeTarget=!l;const m=bt(),h=c?c.source:void 0,g=this.layout?this.layout.source:void 0,y=h!==g,x=this.getStack(),v=!x||x.members.length<=1,w=!!(y&&!v&&this.options.crossfade===!0&&!this.path.some(n9));this.animationProgress=0;let S;this.mixTargetDelta=T=>{const P=T/1e3;uE(p.x,o.x,P),uE(p.y,o.y,P),this.setTargetDelta(p),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(Eh(m,this.layout.layoutBox,this.relativeParent.layout.layoutBox),a9(this.relativeTarget,this.relativeTargetOrigin,m,P),S&&RB(this.relativeTarget,S)&&(this.isProjectionDirty=!1),S||(S=bt()),vn(S,this.relativeTarget)),y&&(this.animationValues=u,MB(u,d,this.latestValues,P,w,v)),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=P},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(o){var l,c,d;this.notifyListeners("animationStart"),(l=this.currentAnimation)==null||l.stop(),(d=(c=this.resumingFrom)==null?void 0:c.currentAnimation)==null||d.stop(),this.pendingAnimation&&(Mn(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=Ne.update(()=>{Pm.hasAnimatedSinceResize=!0,this.motionValue||(this.motionValue=Cn(0)),this.currentAnimation=VB(this.motionValue,[0,1e3],{...o,velocity:0,isSync:!0,onUpdate:u=>{this.mixTargetDelta(u),o.onUpdate&&o.onUpdate(u)},onStop:()=>{},onComplete:()=>{o.onComplete&&o.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const o=this.getStack();o&&o.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(UB),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const o=this.getLead();let{targetWithTransforms:l,target:c,layout:d,latestValues:u}=o;if(!(!l||!c||!d)){if(this!==o&&this.layout&&d&&mR(this.options.animationType,this.layout.layoutBox,d.layoutBox)){c=this.target||bt();const p=ma(this.layout.layoutBox.x);
vendor: 4,672 bytes, line 59
59c.x.min=o.target.x.min,c.x.max=c.x.min+p;const m=ma(this.layout.layoutBox.y);c.y.min=o.target.y.min,c.y.max=c.y.min+m}vn(l,c),Js(l,u),cd(this.projectionDeltaWithTransform,this.layoutCorrected,l,u)}}registerSharedNode(o,l){this.sharedNodes.has(o)||this.sharedNodes.set(o,new BB),this.sharedNodes.get(o).add(l);const d=l.options.initialPromotionConfig;l.promote({transition:d?d.transition:void 0,preserveFollowOpacity:d&&d.shouldPreserveFollowOpacity?d.shouldPreserveFollowOpacity(l):void 0})}isLead(){const o=this.getStack();return o?o.lead===this:!0}getLead(){var l;const{layoutId:o}=this.options;return o?((l=this.getStack())==null?void 0:l.lead)||this:this}getPrevLead(){var l;const{layoutId:o}=this.options;return o?(l=this.getStack())==null?void 0:l.prevLead:void 0}getStack(){const{layoutId:o}=this.options;if(o)return this.root.sharedNodes.get(o)}promote({needsReset:o,transition:l,preserveFollowOpacity:c}={}){const d=this.getStack();d&&d.promote(this,c),o&&(this.projectionDelta=void 0,this.needsReset=!0),l&&this.setOptions({transition:l})}relegate(){const o=this.getStack();return o?o.relegate(this):!1}resetSkewAndRotation(){const{visualElement:o}=this.options;if(!o)return;let l=!1;const{latestValues:c}=o;if((c.z||c.rotate||c.rotateX||c.rotateY||c.rotateZ||c.skewX||c.skewY)&&(l=!0),!l)return;const d={};c.z&&h0("z",o,d,this.animationValues);for(let u=0;u<m0.length;u++)h0(`rotate${m0[u]}`,o,d,this.animationValues),h0(`skew${m0[u]}`,o,d,this.animationValues);o.render();for(const u in d)o.setStaticValue(u,d[u]),this.animationValues&&(this.animationValues[u]=d[u]);o.scheduleRender()}applyProjectionStyles(o,l){if(!this.instance||this.isSVG)return;if(!this.isVisible){o.visibility="hidden";return}const c=this.getTransformTemplate();if(this.needsReset){this.needsReset=!1,o.visibility="",o.opacity="",o.pointerEvents=Im(l==null?void 0:l.pointerEvents)||"",o.transform=c?c(this.latestValues,""):"none";return}const d=this.getLead();if(!this.projectionDelta||!this.layout||!d.target){this.options.layoutId&&(o.opacity=this.latestValues.opacity!==void 0?this.latestValues.opacity:1,o.pointerEvents=Im(l==null?void 0:l.pointerEvents)||""),this.hasProjected&&!ho(this.latestValues)&&(o.transform=c?c({},""):"none",this.hasProjected=!1);return}o.visibility="";const u=d.animationValues||d.latestValues;this.applyTransformsToTarget();let p=LB(this.projectionDeltaWithTransform,this.treeScale,u);c&&(p=c(u,p)),o.transform=p;const{x:m,y:h}=this.projectionDelta;o.transformOrigin=`${m.origin*100}% ${h.origin*100}% 0`,d.animationValues?o.opacity=d===this?u.opacity??this.latestValues.opacity??1:this.preserveOpacity?this.latestValues.opacity:u.opacityExit:o.opacity=d===this?u.opacity!==void 0?u.opacity:"":u.opacityExit!==void 0?u.opacityExit:0;for(const g in Bv){if(u[g]===void 0)continue;const{correct:y,applyTo:x,isCSSVariable:v}=Bv[g],w=p==="none"?u[g]:y(u[g],d);if(x){const S=x.length;for(let T=0;T<S;T++)o[x[T]]=w}else v?this.options.visualElement.renderState.vars[g]=w:o[g]=w}this.options.layoutId&&(o.pointerEvents=d===this?Im(l==null?void 0:l.pointerEvents)||"":"none")}clearSnapshot(){this.resumeFrom=this.snapshot=void 0}resetTree(){this.root.nodes.forEach(o=>{var l;return(l=o.currentAnimation)==null?void 0:l.stop()}),this.root.nodes.forEach(lE),this.root.sharedNodes.clear()}}}function WB(t){t.updateLayout()}function GB(t){var a;const e=((a=t.resumeFrom)==null?void 0:a.snapshot)||t.snapshot;if(t.isLead()&&t.layout&&e&&t.hasListeners("didUpdate")){const{layoutBox:n,measuredBox:i}=t.layout,{animationType:r}=t.options,o=e.source!==t.layout.source;r==="size"?Za(p=>{const m=o?e.measuredBox[p]:e.layoutBox[p],h=ma(m);m.min=n[p].min,m.max=m.min+h}):mR(r,e.layoutBox,n)&&Za(p=>{const m=o?e.measuredBox[p]:e.layoutBox[p],h=ma(n[p]);m.max=m.min+h,t.relativeTarget&&!t.currentAnimation&&(t.isProjectionDirty=!0,t.relativeTarget[p].max=t.relativeTarget[p].min+h)});const l=Gs();cd(l,n,e.layoutBox);const c=Gs();o?cd(c,t.applyTransform(i,!0),e.measuredBox):cd(c,n,e.layoutBox);const d=!sR(l);let u=!1;if(!t.resumeFrom){const p=t.getClosestProjectingParent();if(p&&!p.resumeFrom){const{snapshot:m,layout:h}=p;if(m&&h){const g=bt();Eh(g,e.layoutBox,m.layoutBox);const y=bt();Eh(y,n,h.layoutBox),lR(g,y)||(u=!0),p.options.layoutRoot&&(t.relativeTarget=y,t.relativeTargetOrigin=g,t.relativeParent=p)}}}t.notifyListeners("didUpdate",{layout:n,snapshot:e,delta:c,layoutDelta:l,hasLayoutChanged:d,hasRelativeLayoutChanged:u})}else if(t.isLead()){const{onExitComplete:n}=t.options;n&&n()}t.options.transition=void 0}function KB(t){t.parent&&(t.isProjecting()||(t.isProjectionDirty=t.parent.isProjectionDirty),t.isSharedProjectionDirty||(t.isSharedProjectionDirty=!!(t.
vendor: 30,936 bytes, lines 59-67
59isProjectionDirty||t.parent.isProjectionDirty||t.parent.isSharedProjectionDirty)),t.isTransformDirty||(t.isTransformDirty=t.parent.isTransformDirty))}function JB(t){t.isProjectionDirty=t.isSharedProjectionDirty=t.isTransformDirty=!1}function QB(t){t.clearSnapshot()}function lE(t){t.clearMeasurements()}function cE(t){t.isLayoutDirty=!1}function XB(t){const{visualElement:e}=t.options;e&&e.getProps().onBeforeLayoutMeasure&&e.notify("BeforeLayoutMeasure"),t.resetTransform()}function dE(t){t.finishAnimation(),t.targetDelta=t.relativeTarget=t.target=void 0,t.isProjectionDirty=!0}function YB(t){t.resolveTargetDelta()}function ZB(t){t.calcProjection()}function e9(t){t.resetSkewAndRotation()}function t9(t){t.removeLeadSnapshot()}function uE(t,e,a){t.translate=Xe(e.translate,0,a),t.scale=Xe(e.scale,1,a),t.origin=e.origin,t.originPoint=e.originPoint}function pE(t,e,a,n){t.min=Xe(e.min,a.min,n),t.max=Xe(e.max,a.max,n)}function a9(t,e,a,n){pE(t.x,e.x,a.x,n),pE(t.y,e.y,a.y,n)}function n9(t){return t.animationValues&&t.animationValues.opacityExit!==void 0}const i9={duration:.45,ease:[.4,0,.1,1]},mE=t=>typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().includes(t),hE=mE("applewebkit/")&&!mE("chrome/")?Math.round:Ta;function fE(t){t.min=hE(t.min),t.max=hE(t.max)}function r9(t){fE(t.x),fE(t.y)}function mR(t,e,a){return t==="position"||t==="preserve-aspect"&&!jB(nE(e),nE(a),.2)}function o9(t){var e;return t!==t.root&&((e=t.scroll)==null?void 0:e.wasRoot)}const s9=pR({attachResizeListener:(t,e)=>Zd(t,"resize",e),measureScroll:()=>({x:document.documentElement.scrollLeft||document.body.scrollLeft,y:document.documentElement.scrollTop||document.body.scrollTop}),checkIsScrollRoot:()=>!0}),f0={current:void 0},hR=pR({measureScroll:t=>({x:t.scrollLeft,y:t.scrollTop}),defaultParent:()=>{if(!f0.current){const t=new s9({});t.mount(window),t.setOptions({layoutScroll:!0}),f0.current=t}return f0.current},resetTransform:(t,e)=>{t.style.transform=e!==void 0?e:"none"},checkIsScrollRoot:t=>window.getComputedStyle(t).position==="fixed"}),cg=k.createContext({transformPagePoint:t=>t,isStatic:!1,reducedMotion:"never"});function gE(t,e){if(typeof t=="function")return t(e);t!=null&&(t.current=e)}function l9(...t){return e=>{let a=!1;const n=t.map(i=>{const r=gE(i,e);return!a&&typeof r=="function"&&(a=!0),r});if(a)return()=>{for(let i=0;i<n.length;i++){const r=n[i];typeof r=="function"?r():gE(t[i],null)}}}}function c9(...t){return k.useCallback(l9(...t),t)}class d9 extends k.Component{getSnapshotBeforeUpdate(e){const a=this.props.childRef.current;if(a&&e.isPresent&&!this.props.isPresent){const n=a.offsetParent,i=Cw(n)&&n.offsetWidth||0,r=this.props.sizeRef.current;r.height=a.offsetHeight||0,r.width=a.offsetWidth||0,r.top=a.offsetTop,r.left=a.offsetLeft,r.right=i-r.width-r.left}return null}componentDidUpdate(){}render(){return this.props.children}}function u9({children:t,isPresent:e,anchorX:a,root:n}){var u;const i=k.useId(),r=k.useRef(null),o=k.useRef({width:0,height:0,top:0,left:0,right:0}),{nonce:l}=k.useContext(cg),c=((u=t.props)==null?void 0:u.ref)??(t==null?void 0:t.ref),d=c9(r,c);return k.useInsertionEffect(()=>{const{width:p,height:m,top:h,left:g,right:y}=o.current;if(e||!r.current||!p||!m)return;const x=a==="left"?`left: ${g}`:`right: ${y}`;r.current.dataset.motionPopId=i;const v=document.createElement("style");l&&(v.nonce=l);const w=n??document.head;return w.appendChild(v),v.sheet&&v.sheet.insertRule(` 60 [data-motion-pop-id="${i}"] { 61 position: absolute !important; 62 width: ${p}px !important; 63 height: ${m}px !important; 64 ${x}px !important; 65 top: ${h}px !important; 66 } 67 `),()=>{w.contains(v)&&w.removeChild(v)}},[e]),s.jsx(d9,{isPresent:e,childRef:r,sizeRef:o,children:k.cloneElement(t,{ref:d})})}const p9=({children:t,initial:e,isPresent:a,onExitComplete:n,custom:i,presenceAffectsLayout:r,mode:o,anchorX:l,root:c})=>{const d=zr(m9),u=k.useId();let p=!0,m=k.useMemo(()=>(p=!1,{id:u,initial:e,isPresent:a,custom:i,onExitComplete:h=>{d.set(h,!0);for(const g of d.values())if(!g)return;n&&n()},register:h=>(d.set(h,!1),()=>d.delete(h))}),[a,d,n]);return r&&p&&(m={...m}),k.useMemo(()=>{d.forEach((h,g)=>d.set(g,!1))},[a]),k.useEffect(()=>{!a&&!d.size&&n&&n()},[a]),o==="popLayout"&&(t=s.jsx(u9,{isPresent:a,anchorX:l,root:c,children:t})),s.jsx(og.Provider,{value:m,children:t})};function m9(){return new Map}function fR(t=!0){const e=k.useContext(og);if(e===null)return[!0,null];const{isPresent:a,onExitComplete:n,register:i}=e,r=k.useId();k.useEffect(()=>{if(t)return i(r)},[t]);const o=k.useCallback(()=>t&&n&&n(r),[r,n,t]);return!a&&n?[!1,o]:[!0]}const Dp=t=>t.key||"";function yE(t){const e=[];return k.Children.forEach(t,a=>{k.isValidElement(a)&&e.push(a)}),e}const La=({children:t,custom:e,initial:a=!0,onExitComplete:n,presenceAffectsLayout:i=!0,mode:r="sync",propagate:o=!1,anchorX:l="left",root:c})=>{const[d,u]=fR(o),p=k.useMemo(()=>yE(t),[t]),m=o&&!d?[]:p.map(Dp),h=k.useRef(!0),g=k.useRef(p),y=zr(()=>new Map),x=k.useRef(new Set),[v,w]=k.useState(p),[S,T]=k.useState(p);rg(()=>{h.current=!1,g.current=p;for(let C=0;C<S.length;C++){const E=Dp(S[C]);m.includes(E)?(y.delete(E),x.current.delete(E)):y.get(E)!==!0&&y.set(E,!1)}},[S,m.length,m.join("-")]);const P=[];if(p!==v){let C=[...p];for(let E=0;E<S.length;E++){const j=S[E],N=Dp(j);m.includes(N)||(C.splice(E,0,j),P.push(j))}return r==="wait"&&P.length&&(C=P),T(yE(C)),w(p),null}const{forceRender:M}=k.useContext(nw);return s.jsx(s.Fragment,{children:S.map(C=>{const E=Dp(C),j=o&&!d?!1:p===S||m.includes(E),N=()=>{if(x.current.has(E))return;if(x.current.add(E),y.has(E))y.set(E,!0);else return;let L=!0;y.forEach(O=>{O||(L=!1)}),L&&(M==null||M(),T(g.current),o&&(u==null||u()),n&&n())};return s.jsx(p9,{isPresent:j,initial:!h.current||a?void 0:!1,custom:e,presenceAffectsLayout:i,mode:r,root:c,onExitComplete:j?void 0:N,anchorX:l,children:C},E)})})},gR=k.createContext({strict:!1}),xE={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]};let vE=!1;function h9(){if(vE)return;const t={};for(const e in xE)t[e]={isEnabled:a=>xE[e].some(n=>!!a[n])};$4(t),vE=!0}function yR(){return h9(),eB()}function f9(t){const e=yR();for(const a in t)e[a]={...e[a],...t[a]};$4(e)}const g9=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","ignoreStrict","viewport"]);function Ch(t){return t.startsWith("while")||t.startsWith("drag")&&t!=="draggable"||t.startsWith("layout")||t.startsWith("onTap")||t.startsWith("onPan")||t.startsWith("onLayout")||g9.has(t)}let xR=t=>!Ch(t);function y9(t){typeof t=="function"&&(xR=e=>e.startsWith("on")?!Ch(e):t(e))}try{y9(require("@emotion/is-prop-valid").default)}catch{}function x9(t,e,a){const n={};for(const i in t)i==="values"&&typeof t.values=="object"||(xR(i)||a===!0&&Ch(i)||!e&&!Ch(i)||t.draggable&&i.startsWith("onDrag"))&&(n[i]=t[i]);return n}const dg=k.createContext({});function v9(t,e){if(lg(t)){const{initial:a,animate:n}=t;return{initial:a===!1||Yd(a)?a:void 0,animate:Yd(n)?n:void 0}}return t.inherit!==!1?e:{}}function b9(t){const{initial:e,animate:a}=v9(t,k.useContext(dg));return k.useMemo(()=>({initial:e,animate:a}),[bE(e),bE(a)])}function bE(t){return Array.isArray(t)?t.join(" "):t}const Ow=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function vR(t,e,a){for(const n in e)!na(e[n])&&!Y4(n,a)&&(t[n]=e[n])}function w9({transformTemplate:t},e){return k.useMemo(()=>{const a=Ow();return Rw(a,e,t),Object.assign({},a.vars,a.style)},[e])}function k9(t,e){const a=t.style||{},n={};return vR(n,a,t),Object.assign(n,w9(t,e)),n}function S9(t,e){const a={},n=k9(t,e);return t.drag&&t.dragListener!==!1&&(a.draggable=!1,n.userSelect=n.WebkitUserSelect=n.WebkitTouchCallout="none",n.touchAction=t.drag===!0?"none":`pan-${t.drag==="x"?"y":"x"}`),t.tabIndex===void 0&&(t.onTap||t.onTapStart||t.whileTap)&&(a.tabIndex=0),a.style=n,a}const bR=()=>({...Ow(),attrs:{}});function _9(t,e,a,n){const i=k.useMemo(()=>{const r=bR();return Z4(r,e,tR(n),t.transformTemplate,t.style),{...r.attrs,style:{...r.style}}},[e]);if(t.style){const r={};vR(r,t.style,t),i.style={...r,...i.style}}return i}const A9=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function Mw(t){return typeof t!="string"||t.includes("-")?!1:!!(A9.indexOf(t)>-1||/[A-Z]/u.test(t))}function E9(t,e,a,{latestValues:n},i,r=!1,o){const c=(o??Mw(t)?_9:S9)(e,n,i,t),d=x9(e,typeof t=="string",r),u=t!==k.Fragment?{...d,...c,ref:a}:{},{children:p}=e,m=k.useMemo(()=>na(p)?p.get():p,[p]);return k.createElement(t,{...u,children:m})}function C9({scrapeMotionValuesFromProps:t,createRenderState:e},a,n,i){return{latestValues:j9(a,n,i,t),renderState:e()}}function j9(t,e,a,n){const i={},r=n(t,{});for(const m in r)i[m]=Im(r[m]);let{initial:o,animate:l}=t;const c=lg(t),d=U4(t);e&&d&&!c&&t.inherit!==!1&&(o===void 0&&(o=e.initial),l===void 0&&(l=e.animate));let u=a?a.initial===!1:!1;u=u||o===!1;const p=u?l:o;if(p&&typeof p!="boolean"&&!sg(p)){const m=Array.isArray(p)?p:[p];for(let h=0;h<m.length;h++){const g=Sw(t,m[h]);if(g){const{transitionEnd:y,transition:x,...v}=g;for(const w in v){let S=v[w];if(Array.isArray(S)){const T=u?S.length-1:0;S=S[T]}S!==null&&(i[w]=S)}for(const w in y)i[w]=y[w]}}}return i}const wR=t=>(e,a)=>{const n=k.useContext(dg),i=k.useContext(og),r=()=>C9(t,e,n,i);return a?r():zr(r)},T9=wR({scrapeMotionValuesFromProps:Lw,createRenderState:Ow}),N9=wR({scrapeMotionValuesFromProps:aR,createRenderState:bR}),I9=Symbol.for("motionComponentSymbol");function P9(t,e,a){const n=k.useRef(a);k.useInsertionEffect(()=>{n.current=a});const i=k.useRef(null);return k.useCallback(r=>{var l;r&&((l=t.onMount)==null||l.call(t,r)),e&&(r?e.mount(r):e.unmount());const o=n.current;if(typeof o=="function")if(r){const c=o(r);typeof c=="function"&&(i.current=c)}else i.current?(i.current(),i.current=null):o(r);else o&&(o.current=r)},[e])}const kR=k.createContext({});function zc(t){return t&&typeof t=="object"&&Object.prototype.hasOwnProperty.call(t,"current")}function R9(t,e,a,n,i,r){var x,v;const{visualElement:o}=k.useContext(dg),l=k.useContext(gR),c=k.useContext(og),d=k.useContext(cg).reducedMotion,u=k.useRef(null);n=n||l.renderer,!u.current&&n&&(u.current=n(t,{visualState:e,parent:o,props:a,presenceContext:c,blockInitialAnimation:c?c.initial===!1:!1,reducedMotionConfig:d,isSVG:r}));const p=u.current,m=k.useContext(kR);p&&!p.projection&&i&&(p.type==="html"||p.type==="svg")&&L9(u.current,a,i,m);const h=k.useRef(!1);k.useInsertionEffect(()=>{p&&h.current&&p.update(a,c)});const g=a[T4],y=k.useRef(!!g&&!((x=window.MotionHandoffIsComplete)!=null&&x.call(window,g))&&((v=window.MotionHasOptimisedAnimation)==null?void 0:v.call(window,g)));return rg(()=>{p&&(h.current=!0,window.MotionIsMounted=!0,p.updateFeatures(),p.scheduleRenderMicrotask(),y.current&&p.animationState&&p.animationState.animateChanges())}),k.useEffect(()=>{p&&(!y.current&&p.animationState&&p.animationState.animateChanges(),y.current&&(queueMicrotask(()=>{var w;(w=window.MotionHandoffMarkAsComplete)==null||w.call(window,g)}),y.current=!1),p.enteringChildren=void 0)}),p}function L9(t,e,a,n){const{layoutId:i,layout:r,drag:o,dragConstraints:l,layoutScroll:c,layoutRoot:d,layoutCrossfade:u}=e;t.projection=new a(t.latestValues,e["data-framer-portal-id"]?void 0:SR(t.parent)),t.projection.setOptions({layoutId:i,layout:r,alwaysMeasureLayout:!!o||l&&zc(l),visualElement:t,animationType:typeof r=="string"?r:"both",initialPromotionConfig:n,crossfade:u,layoutScroll:c,layoutRoot:d})}function SR(t){if(t)return t.options.allowProjection!==!1?t.projection:SR(t.parent)}function g0(t,{forwardMotionProps:e=!1,type:a}={},n,i){n&&f9(n);const r=a?a==="svg":Mw(t),o=r?N9:T9;function l(d,u){let p;const m={...k.useContext(cg),...d,layoutId:O9(d)},{isStatic:h}=m,g=b9(d),y=o(d,h);if(!h&&$P){M9();const x=D9(m);p=x.MeasureLayout,g.visualElement=R9(t,y,m,i,x.ProjectionNode,r)}return s.jsxs(dg.Provider,{value:g,children:[p&&g.visualElement?s.jsx(p,{visualElement:g.visualElement,...m}):null,E9(t,d,P9(y,g.visualElement,u),y,h,e,r)]})}l.displayName=`motion.${typeof t=="string"?t:`create(${t.displayName??t.name??""})`}`;const c=k.forwardRef(l);return c[I9]=t,c}function O9({layoutId:t}){const e=k.useContext(nw).id;return e&&t!==void 0?e+"-"+t:t}function M9(t,e){k.useContext(gR).strict}function D9(t){const e=yR(),{drag:a,layout:n}=e;if(!a&&!n)return{};const i={...a,...n};return{MeasureLayout:a!=null&&a.isEnabled(t)||n!=null&&n.isEnabled(t)?i.MeasureLayout:void 0,ProjectionNode:i.ProjectionNode}}function q9(t,e){if(typeof Proxy>"u")return g0;const a=new Map,n=(r,o)=>g0(r,o,t,e),i=(r,o)=>n(r,o);return new Proxy(i,{get:(r,o)=>o==="create"?n:(a.has(o)||a.set(o,g0(o,void 0,t,e)),a.get(o))})}const z9=(t,e)=>e.isSVG??Mw(t)?new yB(e):new uB(e,{allowProjection:t!==k.Fragment});class V9 extends Jr{constructor(e){super(e),e.animationState||(e.animationState=kB(e))}updateAnimationControlsSubscription(){const{animate:e}=this.node.getProps();sg(e)&&(this.unmountControls=e.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:e}=this.node.getProps(),{animate:a}=this.node.prevProps||{};e!==a&&this.updateAnimationControlsSubscription()}unmount(){var e;this.node.animationState.reset(),(e=this.unmountControls)==null||e.call(this)}}let H9=0;class F9 extends Jr{constructor(){super(...arguments),this.id=H9++}update(){if(!this.node.presenceContext)return;const{isPresent:e,onExitComplete:a}=this.node.presenceContext,{isPresent:n}=this.node.prevPresenceContext||{};if(!this.node.animationState||e===n)return;const i=this.node.animationState.setActive("exit",!e);a&&!e&&i.then(()=>{a(this.id)})}mount(){const{register:e,onExitComplete:a}=this.node.presenceContext||{};a&&a(this.id),e&&(this.unmount=e(this.id))}unmount(){}}const B9={animation:{Feature:V9},exit:{Feature:F9}};function Pu(t){return{point:{x:t.pageX,y:t.pageY}}}const U9=t=>e=>Tw(e)&&t(e,Pu(e));function dd(t,e,a,n){return Zd(t,e,U9(a),n)}const _R=({current:t})=>t?t.ownerDocument.defaultView:null,wE=(t,e)=>Math.abs(t-e);function $9(t,e){const a=wE(t.x,e.x),n=wE(t.y,e.y);return Math.sqrt(a**2+n**2)}const kE=new Set(["auto","scroll"]);class AR{constructor(e,a,{transformPagePoint:n,contextWindow:i=window,dragSnapToOrigin:r=!1,distanceThreshold:o=3,element:l}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=h=>{this.handleScroll(h.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const h=x0(this.lastMoveEventInfo,this.history),g=this.startEvent!==null,y=$9(h.offset,{x:0,y:0})>=this.distanceThreshold;if(!g&&!y)return;const{point:x}=h,{timestamp:v}=Et;this.history.push({...x,timestamp:v});const{onStart:w,onMove:S}=this.handlers;g||(w&&w(this.lastMoveEvent,h),this.startEvent=this.lastMoveEvent),S&&S(this.lastMoveEvent,h)},this.handlePointerMove=(h,g)=>{this.lastMoveEvent=h,this.lastMoveEventInfo=y0(g,this.transformPagePoint),Ne.update(this.updatePoint,!0)},this.handlePointerUp=(h,g)=>{this.end();const{onEnd:y,onSessionEnd:x,resumeAnimation:v}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&v&&v(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const w=x0(h.type==="pointercancel"?this.lastMoveEventInfo:y0(g,this.transformPagePoint),this.history);this.startEvent&&y&&y(h,w),x&&x(h,w)},!Tw(e))return;this.dragSnapToOrigin=r,this.handlers=a,this.transformPagePoint=n,this.distanceThreshold=o,this.contextWindow=i||window;const c=Pu(e),d=y0(c,this.transformPagePoint),{point:u}=d,{timestamp:p}=Et;this.history=[{...u,timestamp:p}];const{onSessionStart:m}=a;m&&m(e,x0(d,this.history)),this.removeListeners=Tu(dd(this.contextWindow,"pointermove",this.handlePointerMove),dd(this.contextWindow,"pointerup",this.handlePointerUp),dd(this.contextWindow,"pointercancel",this.handlePointerUp)),l&&this.startScrollTracking(l)}startScrollTracking(e){let a=e.parentElement;for(;a;){const n=getComputedStyle(a);(kE.has(n.overflowX)||kE.has(n.overflowY))&&this.scrollPositions.set(a,{x:a.scrollLeft,y:a.scrollTop}),a=a.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener("scroll",this.onElementScroll,{capture:!0,passive:!0}),window.addEventListener("scroll",this.onWindowScroll,{passive:!0}),this.removeScrollListeners=()=>{window.removeEventListener("scroll",this.onElementScroll,{capture:!0}),window.removeEventListener("scroll",this.onWindowScroll)}}handleScroll(e){const a=this.scrollPositions.get(e);if(!a)return;const n=e===window,i=n?{x:window.scrollX,y:window.scrollY}:{x:e.scrollLeft,y:e.scrollTop},r={x:i.x-a.x,y:i.y-a.y};r.x===0&&r.y===0||(n?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=r.x,this.lastMoveEventInfo.point.y+=r.y):this.history.length>0&&(this.history[0].x-=r.x,this.history[0].y-=r.y),this.scrollPositions.set(e,i),Ne.update(this.updatePoint,!0))}updateHandlers(e){this.handlers=e}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),Mn(this.updatePoint)}}function y0(t,e){return e?{point:e(t.point)}:t}function SE(t,e){return{x:t.x-e.x,y:t.y-e.y}}function x0({point:t},e){return{point:t,delta:SE(t,ER(e)),offset:SE(t,W9(e)),velocity:G9(e,.1)}}function W9(t){return t[0]}function ER(t){return t[t.length-1]}function G9(t,e){if(t.length<2)return{x:0,y:0};let a=t.length-1,n=null;const i=ER(t);for(;a>=0&&(n=t[a],!(i.timestamp-n.timestamp>ji(e)));)a--;if(!n)return{x:0,y:0};const r=ln(i.timestamp-n.timestamp);if(r===0)return{x:0,y:0};const o={x:(i.x-n.x)/r,y:(i.y-n.y)/r};return o.x===1/0&&(o.x=0),o.y===1/0&&(o.y=0),o}function K9(t,{min:e,max:a},n){return e!==void 0&&t<e?t=n?Xe(e,t,n.min):Math.max(t,e):a!==void 0&&t>a&&(t=n?Xe(a,t,n.max):Math.min(t,a)),t}function _E(t,e,a){return{min:e!==void 0?t.min+e:void 0,max:a!==void 0?t.max+a-(t.max-t.min):void 0}}function J9(t,{top:e,left:a,bottom:n,right:i}){return{x:_E(t.x,a,i),y:_E(t.y,e,n)}}function AE(t,e){let a=e.min-t.min,n=e.max-t.max;return e.max-e.min<t.max-t.min&&([a,n]=[n,a]),{min:a,max:n}}function Q9(t,e){return{x:AE(t.x,e.x),y:AE(t.y,e.y)}}function X9(t,e){let a=.5;const n=ma(t),i=ma(e);return i>n?a=bl(e.min,e.max-n,t.min):n>i&&(a=bl(t.min,t.max-i,e.min)),On(0,1,a)}function Y9(t,e){const a={};return e.min!==void 0&&(a.min=e.min-t.min),e.max!==void 0&&(a.max=e.max-t.min),a}const Uv=.35;function Z9(t=Uv){return t===!1?t=0:t===!0&&(t=Uv),{x:EE(t,"left","right"),y:EE(t,"top","bottom")}}function EE(t,e,a){return{min:CE(t,e),max:CE(t,a)}}function CE(t,e){return typeof t=="number"?t:t[e]||0}const eU=new WeakMap;class tU{constructor(e){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=bt(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=e}start(e,{snapToCursor:a=!1,distanceThreshold:n}={}){const{presenceContext:i}=this.visualElement;if(i&&i.isPresent===!1)return;const r=p=>{a?(this.stopAnimation(),this.snapToCursor(Pu(p).point)):this.pauseAnimation()},o=(p,m)=>{this.stopAnimation();const{drag:h,dragPropagation:g,onDragStart:y}=this.getProps();if(h&&!g&&(this.openDragLock&&this.openDragLock(),this.openDragLock=P7(h),!this.openDragLock))return;this.latestPointerEvent=p,this.latestPanInfo=m,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),Za(v=>{let w=this.getAxisMotionValue(v).get()||0;if(Zn.test(w)){const{projection:S}=this.visualElement;if(S&&S.layout){const T=S.layout.layoutBox[v];T&&(w=ma(T)*(parseFloat(w)/100))}}this.originPoint[v]=w}),y&&Ne.postRender(()=>y(p,m)),Dv(this.visualElement,"transform");const{animationState:x}=this.visualElement;x&&x.setActive("whileDrag",!0)},l=(p,m)=>{this.latestPointerEvent=p,this.latestPanInfo=m;const{dragPropagation:h,dragDirectionLock:g,onDirectionLock:y,onDrag:x}=this.getProps();if(!h&&!this.openDragLock)return;const{offset:v}=m;if(g&&this.currentDirection===null){this.currentDirection=aU(v),this.currentDirection!==null&&y&&y(this.currentDirection);return}this.updateAxis("x",m.point,v),this.updateAxis("y",m.point,v),this.visualElement.render(),x&&x(p,m)},c=(p,m)=>{this.latestPointerEvent=p,this.latestPanInfo=m,this.stop(p,m),this.latestPointerEvent=null,this.latestPanInfo=null},d=()=>Za(p=>{var m;return this.getAnimationState(p)==="paused"&&((m=this.getAxisMotionValue(p).animation)==null?void 0:m.play())}),{dragSnapToOrigin:u}=this.getProps();this.panSession=new AR(e,{onSessionStart:r,onStart:o,onMove:l,onSessionEnd:c,resumeAnimation:d},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:u,distanceThreshold:n,contextWindow:_R(this.visualElement),element:this.visualElement.current})}stop(e,a){const n=e||this.latestPointerEvent,i=a||this.latestPanInfo,r=this.isDragging;if(this.cancel(),!r||!i||!n)return;const{velocity:o}=i;this.startAnimation(o);const{onDragEnd:l}=this.getProps();l&&Ne.postRender(()=>l(n,i))}cancel(){this.isDragging=!1;const{projection:e,animationState:a}=this.visualElement;e&&(e.isAnimationBlocked=!1),this.panSession&&this.panSession.end(),this.panSession=void 0;const{dragPropagation:n}=this.getProps();!n&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),a&&a.setActive("whileDrag",!1)}updateAxis(e,a,n){const{drag:i}=this.getProps();if(!n||!qp(e,i,this.currentDirection))return;const r=this.getAxisMotionValue(e);let o=this.originPoint[e]+n[e];this.constraints&&this.constraints[e]&&(o=K9(o,this.constraints[e],this.elastic[e])),r.set(o)}resolveConstraints(){var r;const{dragConstraints:e,dragElastic:a}=this.getProps(),n=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):(r=this.visualElement.projection)==null?void 0:r.layout,i=this.constraints;e&&zc(e)?this.constraints||(this.constraints=this.resolveRefConstraints()):e&&n?this.constraints=J9(n.layoutBox,e):this.constraints=!1,this.elastic=Z9(a),i!==this.constraints&&n&&this.constraints&&!this.hasMutatedConstraints&&Za(o=>{this.constraints!==!1&&this.getAxisMotionValue(o)&&(this.constraints[o]=Y9(n.layoutBox[o],this.constraints[o]))})}resolveRefConstraints(){const{dragConstraints:e,onMeasureDragConstraints:a}=this.getProps();if(!e||!zc(e))return!1;const n=e.current,{projection:i}=this.visualElement;if(!i||!i.layout)return!1;const r=rB(n,i.root,this.visualElement.getTransformPagePoint());let o=Q9(i.layout.layoutBox,r);if(a){const l=a(aB(o));this.hasMutatedConstraints=!!l,l&&(o=G4(l))}return o}startAnimation(e){const{drag:a,dragMomentum:n,dragElastic:i,dragTransition:r,dragSnapToOrigin:o,onDragTransitionEnd:l}=this.getProps(),c=this.constraints||{},d=Za(u=>{if(!qp(u,a,this.currentDirection))return;let p=c&&c[u]||{};o&&(p={min:0,max:0});const m=i?200:1e6,h=i?40:1e7,g={type:"inertia",velocity:n?e[u]:0,bounceStiffness:m,bounceDamping:h,timeConstant:750,restDelta:1,restSpeed:10,...r,...p};return this.startAxisValueAnimation(u,g)});return Promise.all(d).then(l)}startAxisValueAnimation(e,a){const n=this.getAxisMotionValue(e);return Dv(this.visualElement,e),n.start(kw(e,n,0,a,this.visualElement,!1))}stopAnimation(){Za(e=>this.getAxisMotionValue(e).stop())}pauseAnimation(){Za(e=>{var a;return(a=this.getAxisMotionValue(e).animation)==null?void 0:a.pause()})}getAnimationState(e){var a;return(a=this.getAxisMotionValue(e).animation)==null?void 0:a.state}getAxisMotionValue(e){const a=`_drag${e.toUpperCase()}`,n=this.visualElement.getProps(),i=n[a];return i||this.visualElement.getValue(e,(n.initial?n.initial[e]:void 0)||0)}snapToCursor(e){Za(a=>{const{drag:n}=this.getProps();if(!qp(a,n,this.currentDirection))return;const{projection:i}=this.visualElement,r=this.getAxisMotionValue(a);if(i&&i.layout){const{min:o,max:l}=i.layout.layoutBox[a],c=r.get()||0;r.set(e[a]-Xe(o,l,.5)+c)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:e,dragConstraints:a}=this.getProps(),{projection:n}=this.visualElement;if(!zc(a)||!n||!this.constraints)return;this.stopAnimation();const i={x:0,y:0};Za(o=>{const l=this.getAxisMotionValue(o);if(l&&this.constraints!==!1){const c=l.get();i[o]=X9({min:c,max:c},this.constraints[o])}});const{transformTemplate:r}=this.visualElement.getProps();this.visualElement.current.style.transform=r?r({},""):"none",n.root&&n.root.updateScroll(),n.updateLayout(),this.resolveConstraints(),Za(o=>{if(!qp(o,e,null))return;const l=this.getAxisMotionValue(o),{min:c,max:d}=this.constraints[o];l.set(Xe(c,d,i[o]))})}addListeners(){if(!this.visualElement.current)return;eU.set(this.visualElement,this);const e=this.visualElement.current,a=dd(e,"pointerdown",c=>{const{drag:d,dragListener:u=!0}=this.getProps();d&&u&&!V4(c.target)&&this.start(c)}),n=()=>{const{dragConstraints:c}=this.getProps();zc(c)&&c.current&&(this.constraints=this.resolveRefConstraints())},{projection:i}=this.visualElement,r=i.addEventListener("measure",n);i&&!i.layout&&(i.root&&i.root.updateScroll(),i.updateLayout()),Ne.read(n);const o=Zd(window,"resize",()=>this.scalePositionWithinConstraints()),l=i.addEventListener("didUpdate",({delta:c,hasLayoutChanged:d})=>{this.isDragging&&d&&(Za(u=>{const p=this.getAxisMotionValue(u);p&&(this.originPoint[u]+=c[u].translate,p.set(p.get()+c[u].translate))}),this.visualElement.render())});return()=>{o(),a(),r(),l&&l()}}getProps(){const e=this.visualElement.getProps(),{drag:a=!1,dragDirectionLock:n=!1,dragPropagation:i=!1,dragConstraints:r=!1,dragElastic:o=Uv,dragMomentum:l=!0}=e;return{...e,drag:a,dragDirectionLock:n,dragPropagation:i,dragConstraints:r,dragElastic:o,dragMomentum:l}}}function qp(t,e,a){return(e===!0||e===t)&&(a===null||a===t)}function aU(t,e=10){let a=null;return Math.abs(t.y)>e?a="y":Math.abs(t.x)>e&&(a="x"),a}class nU extends Jr{constructor(e){super(e),this.removeGroupControls=Ta,this.removeListeners=Ta,this.controls=new tU(e)}mount(){const{dragControls:e}=this.node.getProps();e&&(this.removeGroupControls=e.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||Ta}update(){const{dragControls:e}=this.node.getProps(),{dragControls:a}=this.node.prevProps||{};e!==a&&(this.removeGroupControls(),e&&(this.removeGroupControls=e.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners()}}const jE=t=>(e,a)=>{t&&Ne.postRender(()=>t(e,a))};class iU extends Jr{constructor(){super(...arguments),this.removePointerDownListener=Ta}onPointerDown(e){this.session=new AR(e,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:_R(this.node)})}createPanHandlers(){const{onPanSessionStart:e,onPanStart:a,onPan:n,onPanEnd:i}=this.node.getProps();return{onSessionStart:jE(e),onStart:jE(a),onMove:n,onEnd:(r,o)=>{delete this.session,i&&Ne.postRender(()=>i(r,o))}}}mount(){this.removePointerDownListener=dd(this.node.current,"pointerdown",e=>this.onPointerDown(e))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}let v0=!1;class rU extends k.Component{componentDidMount(){const{visualElement:e,layoutGroup:a,switchLayoutGroup:n,layoutId:i}=this.props,{projection:r}=e;r&&(a.group&&a.group.add(r),n&&n.register&&i&&n.register(r),v0&&r.root.didUpdate(),r.addEventListener("animationComplete",()=>{this.safeToRemove()}),r.setOptions({...r.options,onExitComplete:()=>this.safeToRemove()})),Pm.hasEverUpdated=!0}getSnapshotBeforeUpdate(e){const{layoutDependency:a,visualElement:n,drag:i,isPresent:r}=this.props,{projection:o}=n;return o&&(o.isPresent=r,v0=!0,i||e.layoutDependency!==a||a===void 0||e.isPresent!==r?o.willUpdate():this.safeToRemove(),e.isPresent!==r&&(r?o.promote():o.relegate()||Ne.postRender(()=>{const l=o.getStack();(!l||!l.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{projection:e}=this.props.visualElement;e&&(e.root.didUpdate(),jw.postRender(()=>{!e.currentAnimation&&e.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:e,layoutGroup:a,switchLayoutGroup:n}=this.props,{projection:i}=e;v0=!0,i&&(i.scheduleCheckAfterUnmount(),a&&a.group&&a.group.remove(i),n&&n.deregister&&n.deregister(i))}safeToRemove(){const{safeToRemove:e}=this.props;e&&e()}render(){return null}}function CR(t){const[e,a]=fR(),n=k.useContext(nw);return s.jsx(rU,{...t,layoutGroup:n,switchLayoutGroup:k.useContext(kR),isPresent:e,safeToRemove:a})}const oU={pan:{Feature:iU},drag:{Feature:nU,ProjectionNode:hR,MeasureLayout:CR}};function TE(t,e,a){const{props:n}=t;t.animationState&&n.whileHover&&t.animationState.setActive("whileHover",a==="Start");const i="onHover"+a,r=n[i];r&&Ne.postRender(()=>r(e,Pu(e)))}class sU extends Jr{mount(){const{current:e}=this.node;e&&(this.unmount=R7(e,(a,n)=>(TE(this.node,n,"Start"),i=>TE(this.node,i,"End"))))}unmount(){}}class lU extends Jr{constructor(){super(...arguments),this.isActive=!1}onFocus(){let e=!1;try{e=this.node.current.matches(":focus-visible")}catch{e=!0}!e||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=Tu(Zd(this.node.current,"focus",()=>this.onFocus()),Zd(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}function NE(t,e,a){const{props:n}=t;if(t.current instanceof HTMLButtonElement&&t.current.disabled)return;t.animationState&&n.whileTap&&t.animationState.setActive("whileTap",a==="Start");const i="onTap"+(a==="End"?"":a),r=n[i];r&&Ne.postRender(()=>r(e,Pu(e)))}class cU extends Jr{mount(){const{current:e}=this.node;e&&(this.unmount=M7(e,(a,n)=>(NE(this.node,n,"Start"),(i,{success:r})=>NE(this.node,i,r?"End":"Cancel")),{useGlobalTarget:this.node.props.globalTapTarget}))}unmount(){}}const $v=new WeakMap,b0=new WeakMap,dU=t=>{const e=$v.get(t.target);e&&e(t)}
67,uU=t=>{t.forEach(dU)};function pU({root:t,...e}){const a=t||document;b0.has(a)||b0.set(a,{});const n=b0.get(a),i=JSON.stringify(e);return n[i]||(n[i]=new IntersectionObserver(uU,{root:t,...e})),n[i]}function mU(t,e,a){const n=pU(e);return $v.set(t,a),n.observe(t),()=>{$v.delete(t),n.unobserve(t)}}const hU={some:0,all:1};class fU extends Jr{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.unmount();const{viewport:e={}}=this.node.getProps(),{root:a,margin:n,amount:i="some",once:r}=e,o={root:a?a.current:void 0,rootMargin:n,threshold:typeof i=="number"?i:hU[i]},l=c=>{const{isIntersecting:d}=c;if(this.isInView===d||(this.isInView=d,r&&!d&&this.hasEnteredView))return;d&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",d);const{onViewportEnter:u,onViewportLeave:p}=this.node.getProps(),m=d?u:p;m&&m(c)};return mU(this.node.current,o,l)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:e,prevProps:a}=this.node;["amount","margin","root"].some(gU(e,a))&&this.startObserver()}unmount(){}}function gU({viewport:t={}},{viewport:e={}}={}){return a=>t[a]!==e[a]}const yU={inView:{Feature:fU},tap:{Feature:cU},focus:{Feature:lU},hover:{Feature:sU}},xU={layout:{ProjectionNode:hR,MeasureLayout:CR}},vU={...B9,...yU,...oU,...xU},_=q9(vU,z9),bU=50,IE=()=>({current:0,offset:[],progress:0,scrollLength:0,targetOffset:0,targetLength:0,containerLength:0,velocity:0}),wU=()=>({time:0,x:IE(),y:IE()}),kU={x:{length:"Width",position:"Left"},y:{length:"Height",position:"Top"}};function PE(t,e,a,n){const i=a[e],{length:r,position:o}=kU[e],l=i.current,c=a.time;i.current=t[`scroll${o}`],i.scrollLength=t[`scroll${r}`]-t[`client${r}`],i.offset.length=0,i.offset[0]=0,i.offset[1]=i.scrollLength,i.progress=bl(0,i.scrollLength,i.current);const d=n-c;i.velocity=d>bU?0:lw(i.current-l,d)}function SU(t,e,a){PE(t,"x",e,a),PE(t,"y",e,a),e.time=a}function _U(t,e){const a={x:0,y:0};let n=t;for(;n&&n!==e;)if(Cw(n))a.x+=n.offsetLeft,a.y+=n.offsetTop,n=n.offsetParent;else if(n.tagName==="svg"){const i=n.getBoundingClientRect();n=n.parentElement;const r=n.getBoundingClientRect();a.x+=i.left-r.left,a.y+=i.top-r.top}else if(n instanceof SVGGraphicsElement){const{x:i,y:r}=n.getBBox();a.x+=i,a.y+=r;let o=null,l=n.parentNode;for(;!o;)l.tagName==="svg"&&(o=l),l=n.parentNode;n=o}else break;return a}const Wv={start:0,center:.5,end:1};function RE(t,e,a=0){let n=0;if(t in Wv&&(t=Wv[t]),typeof t=="string"){const i=parseFloat(t);t.endsWith("px")?n=i:t.endsWith("%")?t=i/100:t.endsWith("vw")?n=i/100*document.documentElement.clientWidth:t.endsWith("vh")?n=i/100*document.documentElement.clientHeight:t=i}return typeof t=="number"&&(n=e*t),a+n}const AU=[0,0];function EU(t,e,a,n){let i=Array.isArray(t)?t:AU,r=0,o=0;return typeof t=="number"?i=[t,t]:typeof t=="string"&&(t=t.trim(),t.includes(" ")?i=t.split(" "):i=[t,Wv[t]?t:"0"]),r=RE(i[0],a,n),o=RE(i[1],e),r-o}const CU={All:[[0,0],[1,1]]},jU={x:0,y:0};function TU(t){return"getBBox"in t&&t.tagName!=="svg"?t.getBBox():{width:t.clientWidth,height:t.clientHeight}}function NU(t,e,a){const{offset:n=CU.All}=a,{target:i=t,axis:r="y"}=a,o=r==="y"?"height":"width",l=i!==t?_U(i,t):jU,c=i===t?{width:t.scrollWidth,height:t.scrollHeight}:TU(i),d={width:t.clientWidth,height:t.clientHeight};e[r].offset.length=0;let u=!e[r].interpolate;const p=n.length;for(let m=0;m<p;m++){const h=EU(n[m],d[o],c[o],l[r]);!u&&h!==e[r].interpolatorOffsets[m]&&(u=!0),e[r].offset[m]=h}u&&(e[r].interpolate=gw(e[r].offset,y4(n),{clamp:!1}),e[r].interpolatorOffsets=[...e[r].offset]),e[r].progress=On(0,1,e[r].interpolate(e[r].current))}function IU(t,e=t,a){if(a.x.targetOffset=0,a.y.targetOffset=0,e!==t){let n=e;for(;n&&n!==t;)a.x.targetOffset+=n.offsetLeft,a.y.targetOffset+=n.offsetTop,n=n.offsetParent}a.x.targetLength=e===t?e.scrollWidth:e.clientWidth,a.y.targetLength=e===t?e.scrollHeight:e.clientHeight,a.x.containerLength=t.clientWidth,a.y.containerLength=t.clientHeight}function PU(t,e,a,n={}){return{measure:i=>{IU(t,n.target,a),SU(t,a,i),(n.offset||n.target)&&NU(t,a,n)},notify:()=>e(a)}}const Cc=new WeakMap,LE=new WeakMap,w0=new WeakMap,OE=t=>t===document.scrollingElement?window:t;function jR(t,{container:e=document.scrollingElement,...a}={}){if(!e)return Ta;let n=w0.get(e);n||(n=new Set,w0.set(e,n));const i=wU(),r=PU(e,t,i,a);if(n.add(r),!Cc.has(e)){const l=()=>{for(const p of n)p.measure(Et.timestamp);Ne.preUpdate(c)},c=()=>{for(const p of n)p.notify()},d=()=>Ne.read(l);Cc.set(e,d);const u=OE(e);window.addEventListener("resize",d,{passive:!0}),e!==document.documentElement&&LE.set(e,$7(e,d)),u.addEventListener("scroll",d,{passive:!0}),d()}const o=Cc.get(e);return Ne.read(o,!1,!0),()=>{var d;Mn(o);const l=w0.get(e);if(!l||(l.delete(r),l.size))return;const c=Cc.get(e);Cc.delete(e),c&&(OE(e).removeEventListener("scroll",c),(d=LE.get(e))==null||d(),window.removeEventListener("resize",c))}}const ME=new Map;function RU(t){const e={value:0},a=jR(n=>{e.value=n[t.axis].progress*100},t);return{currentTime:e,cancel:a}}function TR({source:t,container:e,...a}){const{axis:n}=a;t&&(e=t);const i=ME.get(e)??new Map;ME.set(e,i);const r=a.target??"self",o=i.get(r)??{},l=n+(a.offset??[]).join(",");return o[l]||(o[l]=!a.target&&w4()?new ScrollTimeline({source:e,axis:n}):RU({container:e,...a})),o[l]}function LU(t,e){const a=TR(e);return t.attachTimeline({timeline:e.target?void 0:a,observe:n=>(n.pause(),F4(i=>{n.time=n.iterationDuration*i},a))})}function OU(t){return t.length===2}function MU(t,e){return OU(t)?jR(a=>{t(a[e.axis].progress,a)},e):F4(t,TR(e))}function DU(t,{axis:e="y",container:a=document.scrollingElement,...n}={}){if(!a)return Ta;const i={axis:e,container:a,...n};return typeof t=="function"?MU(t,i):LU(t,i)}const qU=()=>({scrollX:Cn(0),scrollY:Cn(0),scrollXProgress:Cn(0),scrollYProgress:Cn(0)}),zp=t=>t?!t.current:!1;function zU({container:t,target:e,...a}={}){const n=zr(qU),i=k.useRef(null),r=k.useRef(!1),o=k.useCallback(()=>(i.current=DU((l,{x:c,y:d})=>{n.scrollX.set(c.current),n.scrollXProgress.set(c.progress),n.scrollY.set(d.current),n.scrollYProgress.set(d.progress)},{...a,container:(t==null?void 0:t.current)||void 0,target:(e==null?void 0:e.current)||void 0}),()=>{var l;(l=i.current)==null||l.call(i)}),[t,e,JSON.stringify(a.offset)]);return rg(()=>{if(r.current=!1,zp(t)||zp(e)){r.current=!0;return}else return o()},[o]),k.useEffect(()=>{if(r.current)return Jd(!zp(t)),Jd(!zp(e)),o()},[o]),n}function VU(t){const e=zr(()=>Cn(t)),{isStatic:a}=k.useContext(cg);if(a){const[,n]=k.useState(t);k.useEffect(()=>e.on("change",n),[])}return e}function NR(t,e){const a=VU(e()),n=()=>a.set(e());return n(),rg(()=>{const i=()=>Ne.preRender(n,!1,!0),r=t.map(o=>
67o.on("change",i));return()=>{r.forEach(o=>o()),Mn(n)}}),a}function HU(t){ld.current=[],t();const e=NR(ld.current,t);return ld.current=void 0,e}function IR(t,e,a,n){if(typeof t=="function")return HU(t);if(a!==void 0&&!Array.isArray(a)&&typeof e!="function")return FU(t,e,a,n);const o=typeof e=="function"?e:G7(e,a,n);return Array.isArray(t)?DE(t,o):DE([t],([l])=>o(l))}function DE(t,e){const a=zr(()=>[]);return NR(t,()=>{a.length=0;const n=t.length;for(let i=0;i<n;i++)a[i]=t[i].get();return e(a)})}function FU(t,e,a,n){const i=zr(()=>Object.keys(a)),r=zr(()=>({}));for(const o of i)r[o]=IR(t,e,a[o],n);return r}const BU={some:0,all:1};function UU(t,e,{root:a,margin:n,amount:i="some"}={}){const r=Ew(t),o=new WeakMap,l=d=>{d.forEach(u=>{const p=o.get(u.target);if(u.isIntersecting!==!!p)if(u.isIntersecting){const m=e(u.target,u);typeof m=="function"?o.set(u.target,m):c.unobserve(u.target)}else typeof p=="function"&&(p(u),o.delete(u.target))})},c=new IntersectionObserver(l,{root:a,rootMargin:n,threshold:typeof i=="number"?i:BU[i]});return r.forEach(d=>c.observe(d)),()=>c.disconnect()}function we(t,{root:e,margin:a,amount:n,once:i=!1,initial:r=!1}={}){const[o,l]=k.useState(r);return k.useEffect(()=>{if(!t.current||i&&o)return;const c=()=>(l(!0),i?void 0:()=>l(!1)),d={root:e&&e.current||void 0,margin:a,amount:n};return UU(t.current,c,d)},[e,t,a,i,n]),o}var qE={};/** 68 * @license 69 * Copyright 2017 Google LLC 70 * 71 * Licensed under the Apache License, Version 2.0 (the "License"); 72 * you may not use this file except in compliance with the License. 73 * You may obtain a copy of the License at 74 * 75 * http://www.apache.org/licenses/LICENSE-2.0 76 * 77 * Unless required by applicable law or agreed to in writing, software 78 * distributed under the License is distributed on an "AS IS" BASIS, 79 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 80 * See the License for the specific language governing permissions and 81 * limitations under the License. 82 */const PR=function(t){const e=[];let a=0;for(let n=0;n<t.length;n++){let i=t.charCodeAt(n);i<128?e[a++]=i:i<2048?(e[a++]=i>>6|192,e[a++]=i&63|128):(i&64512)===55296&&n+1<t.length&&(t.charCodeAt(n+1)&64512)===56320?(i=65536+((i&1023)<<10)+(t.charCodeAt(++n)&1023),e[a++]=i>>18|240,e[a++]=i>>12&63|128,e[a++]=i>>6&63|128,e[a++]=i&63|128):(e[a++]=i>>12|224,e[a++]=i>>6&63|128,e[a++]=i&63|128)}return e},$U=function(t){const e=[];let a=0,n=0;for(;a<t.length;){const i=t[a++];if(i<128)e[n++]=String.fromCharCode(i);else if(i>191&&i<224){const r=t[a++];e[n++]=String.fromCharCode((i&31)<<6|r&63)}else if(i>239&&i<365){const r=t[a++],o=t[a++],l=t[a++],c=((i&7)<<18|(r&63)<<12|(o&63)<<6|l&63)-65536;e[n++]=String.fromCharCode(55296+(c>>10)),e[n++]=String.fromCharCode(56320+(c&1023))}else{const r=t[a++],o=t[a++];e[n++]=String.fromCharCode((i&15)<<12|(r&63)<<6|o&63)}}return e.join("")},RR={byteToCharMap_:null,charToByteMap_:null,byteToCharMapWebSafe_:null,charToByteMapWebSafe_:null,ENCODED_VALS_BASE:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",get ENCODED_VALS(){return this.ENCODED_VALS_BASE+"+/="},get ENCODED_VALS_WEBSAFE(){return this.ENCODED_VALS_BASE+"-_."},HAS_NATIVE_SUPPORT:typeof atob=="function",encodeByteArray(t,e){if(!Array.isArray(t))throw Error("encodeByteArray takes an array as a parameter");this.init_();const a=e?this.byteToCharMapWebSafe_:this.byteToCharMap_,n=[];for(let i=0;i<t.length;i+=3){const r=t[i],o=i+1<t.length,l=o?t[i+1]:0,c=i+2<t.length,d=c?t[i+2]:0,u=r>>2,p=(r&3)<<4|l>>4;let m=(l&15)<<2|d>>6,h=d&63;c||(h=64,o||(m=64)),n.push(a[u],a[p],a[m],a[h])}return n.join("")},encodeString(t,e){return this.HAS_NATIVE_SUPPORT&&!e?btoa(t):this.encodeByteArray(PR(t),e)},decodeString(t,e){return this.HAS_NATIVE_SUPPORT&&!e?atob(t):$U(this.decodeStringToByteArray(t,e))},decodeStringToByteArray(t,e){this.init_();const a=e?this.charToByteMapWebSafe_:this.charToByteMap_,n=[];for(let i=0;i<t.length;){const r=a[t.charAt(i++)],l=i<t.length?a[t.charAt(i)]:0;++i;const d=i<t.length?a[t.charAt(i)]:64;++i;const p=i<t.length?a[t.charAt(i)]:64;if(++i,r==null||l==null||d==null||p==null)throw new WU;const m=r<<2|l>>4;if(n.push(m),d!==64){const h=l<<4&240|d>>2;if(n.push(h),p!==64){const g=d<<6&192|p;n.push(g)}}}return n},init_(){if(!this.byteToCharMap_){this.byteToCharMap_={},this.charToByteMap_={},this.byteToCharMapWebSafe_={},this.charToByteMapWebSafe_={};for(let t=0;t<this.ENCODED_VALS.length;t++)this.byteToCharMap_[t]=this.ENCODED_VALS.charAt(t),this.charToByteMap_[this.byteToCharMap_[t]]=t,this.byteToCharMapWebSafe_[t]=this.ENCODED_VALS_WEBSAFE.charAt(t),this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[t]]=t,t>=this.ENCODED_VALS_BASE.length&&(this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(t)]=t,this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(t)]=t)}}};
82class WU extends Error{constructor(){super(...arguments),this.name="DecodeBase64StringError"}}const GU=function(t){const e=PR(t);return RR.encodeByteArray(e,!0)},jh=function(t){return GU(t).replace(/\./g,"")},LR=function(t){try{return RR.decodeString(t,!0)}catch(e){console.error("base64Decode failed: ",e)}return null};/** 83 * @license 84 * Copyright 2022 Google LLC 85 * 86 * Licensed under the Apache License, Version 2.0 (the "License"); 87 * you may not use this file except in compliance with the License. 88 * You may obtain a copy of the License at 89 * 90 * http://www.apache.org/licenses/LICENSE-2.0 91 * 92 * Unless required by applicable law or agreed to in writing, software 93 * distributed under the License is distributed on an "AS IS" BASIS, 94 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 95 * See the License for the specific language governing permissions and 96 * limitations under the License. 97 */function KU(){if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global;throw new Error("Unable to locate global object.")}/** 98 * @license 99 * Copyright 2022 Google LLC 100 * 101 * Licensed under the Apache License, Version 2.0 (the "License"); 102 * you may not use this file except in compliance with the License. 103 * You may obtain a copy of the License at 104 * 105 * http://www.apache.org/licenses/LICENSE-2.0 106 * 107 * Unless required by applicable law or agreed to in writing, software 108 * distributed under the License is distributed on an "AS IS" BASIS, 109 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 110 * See the License for the specific language governing permissions and 111 * limitations under the License. 112 */const JU=()=>KU().__FIREBASE_DEFAULTS__,QU=()=>{if(typeof process>"u"||typeof qE>"u")return;const t=qE.__FIREBASE_DEFAULTS__;if(t)return JSON.parse(t)},XU=()=>{if(typeof document>"u")return;let t;try{t=document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/)}catch{return}const e=t&&LR(t[1]);return e&&JSON.parse(e)},ug=()=>{try{return JU()||QU()||XU()}catch(t){console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${t}`);return}},OR=t=>{var e,a;return(a=(e=ug())===null||e===void 0?void 0:e.emulatorHosts)===null||a===void 0?void 0:a[t]},MR=t=>{const e=OR(t);if(!e)return;const a=e.lastIndexOf(":");if(a<=0||a+1===e.length)throw new Error(`Invalid host ${e} with no separate hostname and port!`);const n=parseInt(e.substring(a+1),10);return e[0]==="["?[e.substring(1,a-1),n]:[e.substring(0,a),n]},DR=()=>{var t;return(t=ug())===null||t===void 0?void 0:t.config},qR=t=>{var e;return(e=ug())===null||e===void 0?void 0:e[`_${t}`]};/** 113 * @license 114 * Copyright 2017 Google LLC 115 * 116 * Licensed under the Apache License, Version 2.0 (the "License"); 117 * you may not use this file except in compliance with the License. 118 * You may obtain a copy of the License at 119 * 120 * http://www.apache.org/licenses/LICENSE-2.0 121 * 122 * Unless required by applicable law or agreed to in writing, software 123 * distributed under the License is distributed on an "AS IS" BASIS, 124 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125 * See the License for the specific language governing permissions and 126 * limitations under the License. 127 */class YU{constructor(){this.reject=()=>{},this.resolve=()=>{},this.promise=new Promise((e,a)=>{this.resolve=e,this.reject=a})}wrapCallback(e){return(a,n)=>{a?this.reject(a):this.resolve(n),typeof e=="function"&&(this.promise.catch(()=>{}),e.length===1?e(a):e(a,n))}}}/** 128 * @license 129 * Copyright 2021 Google LLC 130 * 131 * Licensed under the Apache License, Version 2.0 (the "License"); 132 * you may not use this file except in compliance with the License. 133 * You may obtain a copy of the License at 134 * 135 * http://www.apache.org/licenses/LICENSE-2.0 136 * 137 * Unless required by applicable law or agreed to in writing, software 138 * distributed under the License is distributed on an "AS IS" BASIS, 139 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140 * See the License for the specific language governing permissions and 141 * limitations under the License. 142 */function zR(t,e){if(t.uid)throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.');const a={alg:"none",type:"JWT"}
142,n=e||"demo-project",i=t.iat||0,r=t.sub||t.user_id;if(!r)throw new Error("mockUserToken must contain 'sub' or 'user_id' field!");const o=Object.assign({iss:`https://securetoken.google.com/${n}`,aud:n,iat:i,exp:i+3600,auth_time:i,sub:r,user_id:r,firebase:{sign_in_provider:"custom",identities:{}}},t);return[jh(JSON.stringify(a)),jh(JSON.stringify(o)),""].join(".")}/** 143 * @license 144 * Copyright 2017 Google LLC 145 * 146 * Licensed under the Apache License, Version 2.0 (the "License"); 147 * you may not use this file except in compliance with the License. 148 * You may obtain a copy of the License at 149 * 150 * http://www.apache.org/licenses/LICENSE-2.0 151 * 152 * Unless required by applicable law or agreed to in writing, software 153 * distributed under the License is distributed on an "AS IS" BASIS, 154 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 155 * See the License for the specific language governing permissions and 156 * limitations under the License. 157 */function ra(){return typeof navigator<"u"&&typeof navigator.userAgent=="string"?navigator.userAgent:""}function ZU(){return typeof window<"u"&&!!(window.cordova||window.phonegap||window.PhoneGap)&&/ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(ra())}function e$(){var t;const e=(t=ug())===null||t===void 0?void 0:t.forceEnvironment;if(e==="node")return!0;if(e==="browser")return!1;try{return Object.prototype.toString.call(global.process)==="[object process]"}catch{return!1}}function t$(){return typeof navigator<"u"&&navigator.userAgent==="Cloudflare-Workers"}function Dw(){const t=typeof chrome=="object"?chrome.runtime:typeof browser=="object"?browser.runtime:void 0;return typeof t=="object"&&t.id!==void 0}function a$(){return typeof navigator=="object"&&navigator.product==="ReactNative"}function n$(){const t=ra();return t.indexOf("MSIE ")>=0||t.indexOf("Trident/")>=0}function i$(){return!e$()&&!!navigator.userAgent&&navigator.userAgent.includes("Safari")&&!navigator.userAgent.includes("Chrome")}function qw(){try{return typeof indexedDB=="object"}catch{return!1}}function zw(){return new Promise((t,e)=>{try{let a=!0;const n="validate-browser-context-for-indexeddb-analytics-module",i=self.indexedDB.open(n);i.onsuccess=()=>{i.result.close(),a||self.indexedDB.deleteDatabase(n),t(!0)},i.onupgradeneeded=()=>{a=!1},i.onerror=()=>{var r;e(((r=i.error)===null||r===void 0?void 0:r.message)||"")}}catch(a){e(a)}})}function VR(){return!(typeof navigator>"u"||!navigator.cookieEnabled)}/** 158 * @license 159 * Copyright 2017 Google LLC 160 * 161 * Licensed under the Apache License, Version 2.0 (the "License"); 162 * you may not use this file except in compliance with the License. 163 * You may obtain a copy of the License at 164 * 165 * http://www.apache.org/licenses/LICENSE-2.0 166 * 167 * Unless required by applicable law or agreed to in writing, software 168 * distributed under the License is distributed on an "AS IS" BASIS, 169 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 170 * See the License for the specific language governing permissions and 171 * limitations under the License. 172 */const r$="FirebaseError";class gn extends Error{constructor(e,a,n){super(a),this.code=e,this.customData=n,this.name=r$,Object.setPrototypeOf(this,gn.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,ds.prototype.create)}}class ds{constructor(e,a,n){this.service=e,this.serviceName=a,this.errors=n}create(e,...a){const n=a[0]||{},i=`${this.service}/${e}`,r=this.errors[e],o=r?o$(r,n):"Error",l=`${this.serviceName}: ${o} (${i}).`;return new gn(i,l,n)}}function o$(t,e){return t.replace(s$,(a,n)=>{const i=e[n];return i!=null?String(i):`<${n}?>`})}const s$=/\{\$([^}]+)}/g;function l$(t){for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e))return!1;return!0}function eu(t,e){if(t===e)return!0;const a=Object.keys(t),n=Object.keys(e);for(const i of a){if(!n.includes(i))return!1;const r=t[i],o=e[i];if(zE(r)&&zE(o)){if(!eu(r,o))return!1}else if(r!==o)return!1}for(const i of n)if(!a.includes(i))return!1;return!0}function zE(t){return t!==null&&typeof t=="object"}/** 173 * @license 174 * Copyright 2017 Google LLC 175 * 176 * Licensed under the Apache License, Version 2.0 (the "License");
177 * you may not use this file except in compliance with the License. 178 * You may obtain a copy of the License at 179 * 180 * http://www.apache.org/licenses/LICENSE-2.0 181 * 182 * Unless required by applicable law or agreed to in writing, software 183 * distributed under the License is distributed on an "AS IS" BASIS, 184 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 185 * See the License for the specific language governing permissions and 186 * limitations under the License. 187 */function Ru(t){const e=[];for(const[a,n]of Object.entries(t))Array.isArray(n)?n.forEach(i=>{e.push(encodeURIComponent(a)+"="+encodeURIComponent(i))}):e.push(encodeURIComponent(a)+"="+encodeURIComponent(n));return e.length?"&"+e.join("&"):""}function c$(t,e){const a=new d$(t,e);return a.subscribe.bind(a)}class d${constructor(e,a){this.observers=[],this.unsubscribes=[],this.observerCount=0,this.task=Promise.resolve(),this.finalized=!1,this.onNoObservers=a,this.task.then(()=>{e(this)}).catch(n=>{this.error(n)})}next(e){this.forEachObserver(a=>{a.next(e)})}error(e){this.forEachObserver(a=>{a.error(e)}),this.close(e)}complete(){this.forEachObserver(e=>{e.complete()}),this.close()}subscribe(e,a,n){let i;if(e===void 0&&a===void 0&&n===void 0)throw new Error("Missing Observer.");u$(e,["next","error","complete"])?i=e:i={next:e,error:a,complete:n},i.next===void 0&&(i.next=k0),i.error===void 0&&(i.error=k0),i.complete===void 0&&(i.complete=k0);const r=this.unsubscribeOne.bind(this,this.observers.length);return this.finalized&&this.task.then(()=>{try{this.finalError?i.error(this.finalError):i.complete()}catch{}}),this.observers.push(i),r}unsubscribeOne(e){this.observers===void 0||this.observers[e]===void 0||(delete this.observers[e],this.observerCount-=1,this.observerCount===0&&this.onNoObservers!==void 0&&this.onNoObservers(this))}forEachObserver(e){if(!this.finalized)for(let a=0;a<this.observers.length;a++)this.sendOne(a,e)}sendOne(e,a){this.task.then(()=>{if(this.observers!==void 0&&this.observers[e]!==void 0)try{a(this.observers[e])}catch(n){typeof console<"u"&&console.error&&console.error(n)}})}close(e){this.finalized||(this.finalized=!0,e!==void 0&&(this.finalError=e),this.task.then(()=>{this.observers=void 0,this.onNoObservers=void 0}))}}function u$(t,e){if(typeof t!="object"||t===null)return!1;for(const a of e)if(a in t&&typeof t[a]=="function")return!0;return!1}function k0(){}/** 188 * @license 189 * Copyright 2019 Google LLC 190 * 191 * Licensed under the Apache License, Version 2.0 (the "License"); 192 * you may not use this file except in compliance with the License. 193 * You may obtain a copy of the License at 194 * 195 * http://www.apache.org/licenses/LICENSE-2.0 196 * 197 * Unless required by applicable law or agreed to in writing, software 198 * distributed under the License is distributed on an "AS IS" BASIS, 199 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 * See the License for the specific language governing permissions and 201 * limitations under the License. 202 */const p$=1e3,m$=2,h$=4*60*60*1e3,f$=.5;function VE(t,e=p$,a=m$){const n=e*Math.pow(a,t),i=Math.round(f$*n*(Math.random()-.5)*2);return Math.min(h$,n+i)}/** 203 * @license 204 * Copyright 2021 Google LLC 205 * 206 * Licensed under the Apache License, Version 2.0 (the "License"); 207 * you may not use this file except in compliance with the License. 208 * You may obtain a copy of the License at 209 * 210 * http://www.apache.org/licenses/LICENSE-2.0 211 * 212 * Unless required by applicable law or agreed to in writing, software 213 * distributed under the License is distributed on an "AS IS" BASIS, 214 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 215 * See the License for the specific language governing permissions and 216 * limitations under the License. 217 */function et(t){return t&&t._delegate?t._delegate:t}class hn{constructor(e,a,n){this.name=e,this.instanceFactory=a,this.type=n,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(e){return this.instantiationMode=e,this}setMultipleInstances(e){return this.multipleInstances=e,this}setServiceProps(e){return this.serviceProps=e,this}setInstanceCreatedCallback(e){return this.onInstanceCreated=e,this}}/** 218 * @license 219 * Copyright 2019 Google LLC 220 * 221 * Licensed under the Apache License, Version 2.0 (the "License");
222 * you may not use this file except in compliance with the License. 223 * You may obtain a copy of the License at 224 * 225 * http://www.apache.org/licenses/LICENSE-2.0 226 * 227 * Unless required by applicable law or agreed to in writing, software 228 * distributed under the License is distributed on an "AS IS" BASIS, 229 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 230 * See the License for the specific language governing permissions and 231 * limitations under the License. 232 */const fo="[DEFAULT]";/** 233 * @license 234 * Copyright 2019 Google LLC 235 * 236 * Licensed under the Apache License, Version 2.0 (the "License"); 237 * you may not use this file except in compliance with the License. 238 * You may obtain a copy of the License at 239 * 240 * http://www.apache.org/licenses/LICENSE-2.0 241 * 242 * Unless required by applicable law or agreed to in writing, software 243 * distributed under the License is distributed on an "AS IS" BASIS, 244 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 245 * See the License for the specific language governing permissions and 246 * limitations under the License. 247 */class g${constructor(e,a){this.name=e,this.container=a,this.component=null,this.instances=new Map,this.instancesDeferred=new Map,this.instancesOptions=new Map,this.onInitCallbacks=new Map}get(e){const a=this.normalizeInstanceIdentifier(e);if(!this.instancesDeferred.has(a)){const n=new YU;if(this.instancesDeferred.set(a,n),this.isInitialized(a)||this.shouldAutoInitialize())try{const i=this.getOrInitializeService({instanceIdentifier:a});i&&n.resolve(i)}catch{}}return this.instancesDeferred.get(a).promise}getImmediate(e){var a;const n=this.normalizeInstanceIdentifier(e==null?void 0:e.identifier),i=(a=e==null?void 0:e.optional)!==null&&a!==void 0?a:!1;if(this.isInitialized(n)||this.shouldAutoInitialize())try{return this.getOrInitializeService({instanceIdentifier:n})}catch(r){if(i)return null;throw r}else{if(i)return null;throw Error(`Service ${this.name} is not available`)}}getComponent(){return this.component}setComponent(e){if(e.name!==this.name)throw Error(`Mismatching Component ${e.name} for Provider ${this.name}.`);if(this.component)throw Error(`Component for ${this.name} has already been provided`);if(this.component=e,!!this.shouldAutoInitialize()){if(x$(e))try{this.getOrInitializeService({instanceIdentifier:fo})}catch{}for(const[a,n]of this.instancesDeferred.entries()){const i=this.normalizeInstanceIdentifier(a);try{const r=this.getOrInitializeService({instanceIdentifier:i});n.resolve(r)}catch{}}}}clearInstance(e=fo){this.instancesDeferred.delete(e),this.instancesOptions.delete(e),this.instances.delete(e)}async delete(){const e=Array.from(this.instances.values());await Promise.all([...e.filter(a=>"INTERNAL"in a).map(a=>a.INTERNAL.delete()),...e.filter(a=>"_delete"in a).map(a=>a._delete())])}isComponentSet(){return this.component!=null}isInitialized(e=fo){return this.instances.has(e)}getOptions(e=fo){return this.instancesOptions.get(e)||{}}initialize(e={}){const{options:a={}}=e,n=this.normalizeInstanceIdentifier(e.instanceIdentifier);if(this.isInitialized(n))throw Error(`${this.name}(${n}) has already been initialized`);if(!this.isComponentSet())throw Error(`Component ${this.name} has not been registered yet`);const i=this.getOrInitializeService({instanceIdentifier:n,options:a});for(const[r,o]of this.instancesDeferred.entries()){const l=this.normalizeInstanceIdentifier(r);n===l&&o.resolve(i)}return i}onInit(e,a){var n;const i=this.normalizeInstanceIdentifier(a),r=(n=this.onInitCallbacks.get(i))!==null&&n!==void 0?n:new Set;r.add(e),this.onInitCallbacks.set(i,r);const o=this.instances.get(i);return o&&e(o,i),()=>{r.delete(e)}}invokeOnInitCallbacks(e,a){const n=this.onInitCallbacks.get(a);if(n)for(const i of n)try{i(e,a)}catch{}}getOrInitializeService({instanceIdentifier:e,options:a={}}){let n=this.instances.get(e);if(!n&&this.component&&(n=this.component.instanceFactory(this.container,{instanceIdentifier:y$(e),options:a}),this.instances.set(e,n),this.instancesOptions.set(e,a),this.invokeOnInitCallbacks(n,e),this.component.onInstanceCreated))try{this.component.onInstanceCreated(this.container,e,n)}catch{}return n||null}normalizeInstanceIdentifier(e=fo){return this.component?this.component.multipleInstances?e:fo:e}shouldAutoInitialize(){return!!this.component&&this.component.instantiationMode!=="EXPLICIT"}}function y$(t){return t===fo?void 0:t}function x$(t){return t.instantiationMode==="EAGER"}/** 248 * @license 249 * Copyright 2019 Google LLC 250 * 251 * Licensed under the Apache License, Version 2.0 (the "License");
252 * you may not use this file except in compliance with the License. 253 * You may obtain a copy of the License at 254 * 255 * http://www.apache.org/licenses/LICENSE-2.0 256 * 257 * Unless required by applicable law or agreed to in writing, software 258 * distributed under the License is distributed on an "AS IS" BASIS, 259 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 260 * See the License for the specific language governing permissions and 261 * limitations under the License. 262 */class v${constructor(e){this.name=e,this.providers=new Map}addComponent(e){const a=this.getProvider(e.name);if(a.isComponentSet())throw new Error(`Component ${e.name} has already been registered with ${this.name}`);a.setComponent(e)}addOrOverwriteComponent(e){this.getProvider(e.name).isComponentSet()&&this.providers.delete(e.name),this.addComponent(e)}getProvider(e){if(this.providers.has(e))return this.providers.get(e);const a=new g$(e,this);return this.providers.set(e,a),a}getProviders(){return Array.from(this.providers.values())}}/** 263 * @license 264 * Copyright 2017 Google LLC 265 * 266 * Licensed under the Apache License, Version 2.0 (the "License"); 267 * you may not use this file except in compliance with the License. 268 * You may obtain a copy of the License at 269 * 270 * http://www.apache.org/licenses/LICENSE-2.0 271 * 272 * Unless required by applicable law or agreed to in writing, software 273 * distributed under the License is distributed on an "AS IS" BASIS, 274 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 275 * See the License for the specific language governing permissions and 276 * limitations under the License. 277 */var _e;(function(t){t[t.DEBUG=0]="DEBUG",t[t.VERBOSE=1]="VERBOSE",t[t.INFO=2]="INFO",t[t.WARN=3]="WARN",t[t.ERROR=4]="ERROR",t[t.SILENT=5]="SILENT"})(_e||(_e={}));const b$={debug:_e.DEBUG,verbose:_e.VERBOSE,info:_e.INFO,warn:_e.WARN,error:_e.ERROR,silent:_e.SILENT},w$=_e.INFO,k$={[_e.DEBUG]:"log",[_e.VERBOSE]:"log",[_e.INFO]:"info",[_e.WARN]:"warn",[_e.ERROR]:"error"},S$=(t,e,...a)=>{if(e<t.logLevel)return;const n=new Date().toISOString(),i=k$[e];if(i)console[i](`[${n}] ${t.name}:`,...a);else throw new Error(`Attempted to log a message with an invalid logType (value: ${e})`)};class pg{constructor(e){this.name=e,this._logLevel=w$,this._logHandler=S$,this._userLogHandler=null}get logLevel(){return this._logLevel}set logLevel(e){if(!(e in _e))throw new TypeError(`Invalid value "${e}" assigned to \`logLevel\``);this._logLevel=e}setLogLevel(e){this._logLevel=typeof e=="string"?b$[e]:e}get logHandler(){return this._logHandler}set logHandler(e){if(typeof e!="function")throw new TypeError("Value assigned to `logHandler` must be a function");this._logHandler=e}get userLogHandler(){return this._userLogHandler}set userLogHandler(e){this._userLogHandler=e}debug(...e){this._userLogHandler&&this._userLogHandler(this,_e.DEBUG,...e),this._logHandler(this,_e.DEBUG,...e)}log(...e){this._userLogHandler&&this._userLogHandler(this,_e.VERBOSE,...e),this._logHandler(this,_e.VERBOSE,...e)}info(...e){this._userLogHandler&&this._userLogHandler(this,_e.INFO,...e),this._logHandler(this,_e.INFO,...e)}warn(...e){this._userLogHandler&&this._userLogHandler(this,_e.WARN,...e),this._logHandler(this,_e.WARN,...e)}error(...e){this._userLogHandler&&this._userLogHandler(this,_e.ERROR,...e),this._logHandler(this,_e.ERROR,...e)}}const _$=(t,e)=>e.some(a=>t instanceof a);let HE,FE;function A$(){return HE||(HE=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function E$(){return FE||(FE=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const HR=new WeakMap,Gv=new WeakMap,FR=new WeakMap,S0=new WeakMap,Vw=new WeakMap;function C$(t){const e=new Promise((a,n)=>{const i=()=>{t.removeEventListener("success",r),t.removeEventListener("error",o)},r=()=>{a(Tr(t.result)),i()},o=()=>{n(t.error),i()};t.addEventListener("success",r),t.addEventListener("error",o)});return e.then(a=>{a instanceof IDBCursor&&HR.set(a,t)}).catch(()=>{}),Vw.set(e,t),e}function j$(t){if(Gv.has(t))return;const e=new Promise((a,n)=>{const i=()=>{t.removeEventListener("complete",r),t.removeEventListener("error",o),t.removeEventListener("abort",o)},r=()=>{a(),i()},o=()=>{n(t.error||new DOMException("AbortError","AbortError")),i()};t.addEventListener("complete",r),t.addEventListener("error",o),t.addEventListener("abort",o)});Gv.set(t,e)}let Kv={get(t,e,a){if(t instanceof IDBTransaction){if(e==="done")return Gv.get(t);if(e==="objectStoreNames")return t.objectStoreNames||FR.get(t);if(e==="store")return a.objectStoreNames[1]?void 0:a.objectStore(a.objectStoreNames[0])}return Tr(t[e])},set(t,e,a){return t[e]=a,!0},has(t,e){return t instanceof IDBTransaction&&(e==="done"||e==="store")?!0:e in t}};function T$(t){Kv=t(Kv)}function N$(t){return t===IDBDatabase.prototype.transaction&&!("objectStoreNames"in IDBTransaction.prototype)?function(e,...a){const n=t.call(_0(this),e,...a);return FR.set(n,e.sort?e.sort():[e]),Tr(n)}:E$().includes(t)?function(...e){return t.apply(_0(this),e),Tr(HR.get(this))}:function(...e){return Tr(t.apply(_0(this),e))}}function I$(t){return typeof t=="function"?N$(t):(t instanceof IDBTransaction&&j$(t),_$(t,A$())?new Proxy(t,Kv):t)}function Tr(t){if(t instanceof IDBRequest)return C$(t);if(S0.has(t))return S0.get(t);const e=I$(t);return e!==t&&(S0.set(t,e),Vw.set(e,t)),e}const _0=t=>Vw.get(t);function BR(t,e,{blocked:a,upgrade:n,blocking:i,terminated:r}={}){const o=indexedDB.open(t,e),l=Tr(o);return n&&o.addEventListener("upgradeneeded",c=>{n(Tr(o.result),c.oldVersion,c.newVersion,Tr(o.transaction),c)}),a&&o.addEventListener("blocked",c=>a(c.oldVersion,c.newVersion,c)),l.then(c=>{r&&c.addEventListener("close",()=>r()),i&&c.addEventListener("versionchange",d=>i(d.oldVersion,d.newVersion,d))}).catch(()=>{}),l}const P$=["get","getKey","getAll","getAllKeys","count"],R$=["put","add","delete","clear"],A0=new Map;function BE(t,e){if(!(t instanceof IDBDatabase&&!(e in t)&&typeof e=="string"))return;if(A0.get(e))return A0.get(e);const a=e.replace(/FromIndex$/,""),n=e!==a,i=R$.includes(a);if(!(a in(n?IDBIndex:IDBObjectStore).prototype)||!(i||P$.includes(a)))return;const r=async function(o,...l){const c=this.transaction(o,i?"readwrite":"readonly");let d=c.store;
277return n&&(d=d.index(l.shift())),(await Promise.all([d[a](...l),i&&c.done]))[0]};return A0.set(e,r),r}T$(t=>({...t,get:(e,a,n)=>BE(e,a)||t.get(e,a,n),has:(e,a)=>!!BE(e,a)||t.has(e,a)}));/** 278 * @license 279 * Copyright 2019 Google LLC 280 * 281 * Licensed under the Apache License, Version 2.0 (the "License"); 282 * you may not use this file except in compliance with the License. 283 * You may obtain a copy of the License at 284 * 285 * http://www.apache.org/licenses/LICENSE-2.0 286 * 287 * Unless required by applicable law or agreed to in writing, software 288 * distributed under the License is distributed on an "AS IS" BASIS, 289 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 290 * See the License for the specific language governing permissions and 291 * limitations under the License. 292 */class L${constructor(e){this.container=e}getPlatformInfoString(){return this.container.getProviders().map(a=>{if(O$(a)){const n=a.getImmediate();return`${n.library}/${n.version}`}else return null}).filter(a=>a).join(" ")}}function O$(t){const e=t.getComponent();return(e==null?void 0:e.type)==="VERSION"}const Jv="@firebase/app",UE="0.10.13";/** 293 * @license 294 * Copyright 2019 Google LLC 295 * 296 * Licensed under the Apache License, Version 2.0 (the "License"); 297 * you may not use this file except in compliance with the License. 298 * You may obtain a copy of the License at 299 * 300 * http://www.apache.org/licenses/LICENSE-2.0 301 * 302 * Unless required by applicable law or agreed to in writing, software 303 * distributed under the License is distributed on an "AS IS" BASIS, 304 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 305 * See the License for the specific language governing permissions and 306 * limitations under the License. 307 */const zi=new pg("@firebase/app"),M$="@firebase/app-compat",D$="@firebase/analytics-compat",q$="@firebase/analytics",z$="@firebase/app-check-compat",V$="@firebase/app-check",H$="@firebase/auth",F$="@firebase/auth-compat",B$="@firebase/database",U$="@firebase/data-connect",$$="@firebase/database-compat",W$="@firebase/functions",G$="@firebase/functions-compat",K$="@firebase/installations",J$="@firebase/installations-compat",Q$="@firebase/messaging",X$="@firebase/messaging-compat",Y$="@firebase/performance",Z$="@firebase/performance-compat",eW="@firebase/remote-config",tW="@firebase/remote-config-compat",aW="@firebase/storage",nW="@firebase/storage-compat",iW="@firebase/firestore",rW="@firebase/vertexai-preview",oW="@firebase/firestore-compat",sW="firebase",lW="10.14.1";/** 308 * @license 309 * Copyright 2019 Google LLC 310 * 311 * Licensed under the Apache License, Version 2.0 (the "License"); 312 * you may not use this file except in compliance with the License. 313 * You may obtain a copy of the License at 314 * 315 * http://www.apache.org/licenses/LICENSE-2.0 316 * 317 * Unless required by applicable law or agreed to in writing, software 318 * distributed under the License is distributed on an "AS IS" BASIS, 319 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 320 * See the License for the specific language governing permissions and 321 * limitations under the License. 322 */const Qv="[DEFAULT]",cW={[Jv]:"fire-core",[M$]:"fire-core-compat",[q$]:"fire-analytics",[D$]:"fire-analytics-compat",[V$]:"fire-app-check",[z$]:"fire-app-check-compat",[H$]:"fire-auth",[F$]:"fire-auth-compat",[B$]:"fire-rtdb",[U$]:"fire-data-connect",[$$]:"fire-rtdb-compat",[W$]:"fire-fn",[G$]:"fire-fn-compat",[K$]:"fire-iid",[J$]:"fire-iid-compat",[Q$]:"fire-fcm",[X$]:"fire-fcm-compat",[Y$]:"fire-perf",[Z$]:"fire-perf-compat",[eW]:"fire-rc",[tW]:"fire-rc-compat",[aW]:"fire-gcs",[nW]:"fire-gcs-compat",[iW]:"fire-fst",[oW]:"fire-fst-compat",[rW]:"fire-vertex","fire-js":"fire-js",[sW]:"fire-js-all"};/** 323 * @license 324 * Copyright 2019 Google LLC 325 * 326 * Licensed under the Apache License, Version 2.0 (the "License"); 327 * you may not use this file except in compliance with the License. 328 * You may obtain a copy of the License at 329 * 330 * http://www.apache.org/licenses/LICENSE-2.0 331 * 332 * Unless required by applicable law or agreed to in writing, software 333 * distributed under the License is distributed on an "AS IS" BASIS, 334 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 335 * See the License for the specific language governing permissions and 336 * limitations under the License. 337 */const Th=new Map,dW=new Map,Xv=new Map;function $E(t,e){try{t.container.addComponent(e)}catch(a){zi.debug(`Component ${e.name} failed to register with FirebaseApp ${t.name}`,a)}}function Dn(t){const e=t.name;if(Xv.has(e))return zi.debug(`There were multiple attempts to register component ${e}.`),!1;Xv.set(e,t);for(const a of Th.values())$E(a,t);for(const a of dW.values())$E(a,t);return!0}function Qr(t,e){const a=t.container.getProvider("heartbeat").getImmediate({optional:!0});return a&&a.triggerHeartbeat(),t.container.getProvider(e)}function wi(t){return t.settings!==void 0}/** 338 * @license 339 * Copyright 2019 Google LLC 340 * 341 * Licensed under the Apache License, Version 2.0 (the "License");
342 * you may not use this file except in compliance with the License. 343 * You may obtain a copy of the License at 344 * 345 * http://www.apache.org/licenses/LICENSE-2.0 346 * 347 * Unless required by applicable law or agreed to in writing, software 348 * distributed under the License is distributed on an "AS IS" BASIS, 349 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 350 * See the License for the specific language governing permissions and 351 * limitations under the License. 352 */const uW={"no-app":"No Firebase App '{$appName}' has been created - call initializeApp() first","bad-app-name":"Illegal App name: '{$appName}'","duplicate-app":"Firebase App named '{$appName}' already exists with different options or config","app-deleted":"Firebase App named '{$appName}' already deleted","server-app-deleted":"Firebase Server App has been deleted","no-options":"Need to provide options, when not being deployed to hosting via source.","invalid-app-argument":"firebase.{$appName}() takes either no argument or a Firebase App instance.","invali
352d-log-argument":"First argument to `onLog` must be null or a function.","idb-open":"Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.","idb-get":"Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.","idb-set":"Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.","idb-delete":"Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.","finalization-registry-not-supported":"FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.","invalid-server-app-environment":"FirebaseServerApp is not for use in browser environments."},Nr=new ds("app","Firebase",uW);/** 353 * @license 354 * Copyright 2019 Google LLC 355 * 356 * Licensed under the Apache License, Version 2.0 (the "License"); 357 * you may not use this file except in compliance with the License. 358 * You may obtain a copy of the License at 359 * 360 * http://www.apache.org/licenses/LICENSE-2.0 361 * 362 * Unless required by applicable law or agreed to in writing, software 363 * distributed under the License is distributed on an "AS IS" BASIS, 364 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 365 * See the License for the specific language governing permissions and 366 * limitations under the License. 367 */class pW{constructor(e,a,n){this._isDeleted=!1,this._options=Object.assign({},e),this._config=Object.assign({},a),this._name=a.name,this._automaticDataCollectionEnabled=a.automaticDataCollectionEnabled,this._container=n,this.container.addComponent(new hn("app",()=>this,"PUBLIC"))}get automaticDataCollectionEnabled(){return this.checkDestroyed(),this._automaticDataCollectionEnabled}set automaticDataCollectionEnabled(e){this.checkDestroyed(),this._automaticDataCollectionEnabled=e}get name(){return this.checkDestroyed(),this._name}get options(){return this.checkDestroyed(),this._options}get config(){return this.checkDestroyed(),this._config}get container(){return this._container}get isDeleted(){return this._isDeleted}set isDeleted(e){this._isDeleted=e}checkDestroyed(){if(this.isDeleted)throw Nr.create("app-deleted",{appName:this._name})}}/** 368 * @license 369 * Copyright 2019 Google LLC 370 * 371 * Licensed under the Apache License, Version 2.0 (the "License"); 372 * you may not use this file except in compliance with the License. 373 * You may obtain a copy of the License at 374 * 375 * http://www.apache.org/licenses/LICENSE-2.0 376 * 377 * Unless required by applicable law or agreed to in writing, software 378 * distributed under the License is distributed on an "AS IS" BASIS, 379 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 380 * See the License for the specific language governing permissions and 381 * limitations under the License. 382 */const us=lW;function UR(t,e={}){let a=t;typeof e!="object"&&(e={name:e});const n=Object.assign({name:Qv,automaticDataCollectionEnabled:!1},e),i=n.name;if(typeof i!="string"||!i)throw Nr.create("bad-app-name",{appName:String(i)});if(a||(a=DR()),!a)throw Nr.create("no-options");const r=Th.get(i);if(r){if(eu(a,r.options)&&eu(n,r.config))return r;throw Nr.create("duplicate-app",{appName:i})}const o=new v$(i);for(const c of Xv.values())o.addComponent(c);const l=new pW(a,n,o);return Th.set(i,l),l}function mg(t=Qv){const e=Th.get(t);if(!e&&t===Qv&&DR())return UR();if(!e)throw Nr.create("no-app",{appName:t});return e}function Na(t,e,a){var n;let i=(n=cW[t])!==null&&n!==void 0?n:t;a&&(i+=`-${a}`);const r=i.match(/\s|\//),o=e.match(/\s|\//);if(r||o){const l=[`Unable to register library "${i}" with version "${e}":`];r&&l.push(`library name "${i}" contains illegal characters (whitespace or "/")`),r&&o&&l.push("and"),o&&l.push(`version name "${e}" contains illegal characters (whitespace or "/")`),zi.warn(l.join(" "));return}Dn(new hn(`${i}-version`,()=>({library:i,version:e}),"VERSION"))}/** 383 * @license 384 * Copyright 2021 Google LLC 385 * 386 * Licensed under the Apache License, Version 2.0 (the "License"); 387 * you may not use this file except in compliance with the License. 388 * You may obtain a copy of the License at 389 * 390 * http://www.apache.org/licenses/LICENSE-2.0 391 * 392 * Unless required by applicable law or agreed to in writing, softw
392are 393 * distributed under the License is distributed on an "AS IS" BASIS, 394 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 395 * See the License for the specific language governing permissions and 396 * limitations under the License. 397 */const mW="firebase-heartbeat-database",hW=1,tu="firebase-heartbeat-store";let E0=null;function $R(){return E0||(E0=BR(mW,hW,{upgrade:(t,e)=>{switch(e){case 0:try{t.createObjectStore(tu)}catch(a){console.warn(a)}}}}).catch(t=>{throw Nr.create("idb-open",{originalErrorMessage:t.message})})),E0}async function fW(t){try{const a=(await $R()).transaction(tu),n=await a.objectStore(tu).get(WR(t));return await a.done,n}catch(e){if(e instanceof gn)zi.warn(e.message);else{const a=Nr.create("idb-get",{originalErrorMessage:e==null?void 0:e.message});zi.warn(a.message)}}}async function WE(t,e){try{const n=(await $R()).transaction(tu,"readwrite");await n.objectStore(tu).put(e,WR(t)),await n.done}catch(a){if(a instanceof gn)zi.warn(a.message);else{const n=Nr.create("idb-set",{originalErrorMessage:a==null?void 0:a.message});zi.warn(n.message)}}}function WR(t){return`${t.name}!${t.options.appId}`}/** 398 * @license 399 * Copyright 2021 Google LLC 400 * 401 * Licensed under the Apache License, Version 2.0 (the "License"); 402 * you may not use this file except in compliance with the License. 403 * You may obtain a copy of the License at 404 * 405 * http://www.apache.org/licenses/LICENSE-2.0 406 * 407 * Unless required by applicable law or agreed to in writing, software 408 * distributed under the License is distributed on an "AS IS" BASIS, 409 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 410 * See the License for the specific language governing permissions and 411 * limitations under the License. 412 */const gW=1024,yW=30*24*60*60*1e3;class xW{constructor(e){this.container=e,this._heartbeatsCache=null;const a=this.container.getProvider("app").getImmediate();this._storage=new bW(a),this._heartbeatsCachePromise=this._storage.read().then(n=>(this._heartbeatsCache=n,n))}async triggerHeartbeat(){var e,a;try{const i=this.container.getProvider("platform-logger").getImmediate().getPlatformInfoString(),r=GE();return((e=this._heartbeatsCache)===null||e===void 0?void 0:e.heartbeats)==null&&(this._heartbeatsCache=await this._heartbeatsCachePromise,((a=this._heartbeatsCache)===null||a===void 0?void 0:a.heartbeats)==null)||this._heartbeatsCache.lastSentHeartbeatDate===r||this._heartbeatsCache.heartbeats.some(o=>o.date===r)?void 0:(this._heartbeatsCache.heartbeats.push({date:r,agent:i}),this._heartbeatsCache.heartbeats=this._heartbeatsCache.heartbeats.filter(o=>{const l=new Date(o.date).valueOf();return Date.now()-l<=yW}),this._storage.overwrite(this._heartbeatsCache))}catch(n){zi.warn(n)}}async getHeartbeatsHeader(){var e;try{if(this._heartbeatsCache===null&&await this._heartbeatsCachePromise,((e=this._heartbeatsCache)===null||e===void 0?void 0:e.heartbeats)==null||this._heartbeatsCache.heartbeats.length===0)return"";const a=GE(),{heartbeatsToSend:n,unsentEntries:i}=vW(this._heartbeatsCache.heartbeats),r=jh(JSON.stringify({version:2,heartbeats:n}));return this._heartbeatsCache.lastSentHeartbeatDate=a,i.length>0?(this._heartbeatsCache.heartbeats=i,await this._storage.overwrite(this._heartbeatsCache)):(this._heartbeatsCache.heartbeats=[],this._storage.overwrite(this._heartbeatsCache)),r}catch(a){return zi.warn(a),""}}}function GE(){return new Date().toISOString().substring(0,10)}function vW(t,e=gW){const a=[];let n=t.slice();for(const i of t){const r=a.find(o=>o.agent===i.agent);if(r){if(r.dates.push(i.date),KE(a)>e){r.dates.pop();break}}else if(a.push({agent:i.agent,dates:[i.date]}),KE(a)>e){a.pop();break}n=n.slice(1)}return{heartbeatsToSend:a,unsentEntries:n}}class bW{constructor(e){this.app=e,this._canUseIndexedDBPromise=this.runIndexedDBEnvironmentCheck()}async runIndexedDBEnvironmentCheck(){return qw()?zw().then(()=>!0).catch(()=>!1):!1}async read(){if(await this._canUseIndexedDBPromise){const a=await fW(this.app);return a!=null&&a.heartbeats?a:{heartbeats:[]}}else return{heartbeats:[]}}async overwrite(e){var a;if(await this._canUseIndexedDBPromise){const i=await this.read();return WE(this.app,{lastSentHeartbeatDate:(a=e.lastSentHeartbeatDate)!==null&&a!==void 0?a:i.lastSentHeartbeatDate,heartbeats:e.heartbeats})}else return}async add(e){var a;if(await this._canUseIndexedDBPromise){const i=await this.read();return WE(this.app,{lastSentHeartbeatDate:(a=e.lastSentHeartbeatDate)!==null&&a!==void 0?a:i.lastSentHeartbeatDate,heartbeats:[...i.heartbeats,...e.heartbeats]})}else return}}function KE(t){return jh(JSON.stringify({version:2,heartbeats:t})).length}/** 413 * @license 414 * Copyright 2019 Google LLC 415 * 416 * Licensed under the Apache License, Version 2.0 (the "License");
417 * you may not use this file except in compliance with the License. 418 * You may obtain a copy of the License at 419 * 420 * http://www.apache.org/licenses/LICENSE-2.0 421 * 422 * Unless required by applicable law or agreed to in writing, software 423 * distributed under the License is distributed on an "AS IS" BASIS, 424 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 425 * See the License for the specific language governing permissions and 426 * limitations under the License. 427 */function wW(t){Dn(new hn("platform-logger",e=>new L$(e),"PRIVATE")),Dn(new hn("heartbeat",e=>new xW(e),"PRIVATE")),Na(Jv,UE,t),Na(Jv,UE,"esm2017"),Na("fire-js","")}wW("");var JE=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};/** @license 428Copyright The Closure Library Authors. 429SPDX-License-Identifier: Apache-2.0 430*/var Lo,GR;(function(){var t;/** @license 431 432 Copyright The Closure Library Authors. 433 SPDX-License-Identifier: Apache-2.0 434*/function e(C,E){function j(){}j.prototype=E.prototype,C.D=E.prototype,C.prototype=new j,C.prototype.constructor=C,C.C=function(N,L,O){for(var R=Array(arguments.length-2),G=2;G<arguments.length;G++)R[G-2]=arguments[G];return E.prototype[L].apply(N,R)}}function a(){this.blockSize=-1}function n(){this.blockSize=-1,this.blockSize=64,this.g=Array(4),this.B=Array(this.blockSize),this.o=this.h=0,this.s()}e(n,a),n.prototype.s=function(){this.g[0]=1732584193,this.g[1]=4023233417,this.g[2]=2562383102,this.g[3]=271733878,this.o=this.h=0};function i(C,E,j){j||(j=0);var N=Array(16);if(typeof E=="string")for(var L=0;16>L;++L)N[L]=E.charCodeAt(j++)|E.charCodeAt(j++)<<8|E.charCodeAt(j++)<<16|E.charCo
vendor: 51,538 bytes, lines 434-453
434deAt(j++)<<24;else for(L=0;16>L;++L)N[L]=E[j++]|E[j++]<<8|E[j++]<<16|E[j++]<<24;E=C.g[0],j=C.g[1],L=C.g[2];var O=C.g[3],R=E+(O^j&(L^O))+N[0]+3614090360&4294967295;E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[1]+3905402710&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[2]+606105819&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[3]+3250441966&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(O^j&(L^O))+N[4]+4118548399&4294967295,E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[5]+1200080426&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[6]+2821735955&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[7]+4249261313&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(O^j&(L^O))+N[8]+1770035416&4294967295,E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[9]+2336552879&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[10]+4294925233&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[11]+2304563134&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(O^j&(L^O))+N[12]+1804603682&4294967295,E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[13]+4254626195&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[14]+2792965006&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[15]+1236535329&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(L^O&(j^L))+N[1]+4129170786&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[6]+3225465664&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[11]+643717713&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[0]+3921069994&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(L^O&(j^L))+N[5]+3593408605&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[10]+38016083&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[15]+3634488961&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[4]+3889429448&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(L^O&(j^L))+N[9]+568446438&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[14]+3275163606&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[3]+4107603335&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[8]+1163531501&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(L^O&(j^L))+N[13]+2850285829&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[2]+4243563512&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[7]+1735328473&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[12]+2368359562&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(j^L^O)+N[5]+4294588738&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[8]+2272392833&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[11]+1839030562&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[14]+4259657740&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(j^L^O)+N[1]+2763975236&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[4]+1272893353&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[7]+4139469664&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[10]+3200236656&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(j^L^O)+N[13]+681279174&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[0]+3936430074&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[3]+3572445317&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[6]+76029189&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(j^L^O)+N[9]+3654602809&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[12]+3873151461&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[15]+530742520&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[2]+3299628645&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(L^(j|~O))+N[0]+4096336452&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[7]+1126891415&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[14]+2878612391&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[5]+4237533241&4294967295,j=L+(R<<21&4294967295|R>>>11),R=E+(L^(j|~O))+N[12]+1700485571&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[3]+2399980690&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[10]+4293915773&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[1]+2240044497&4294967295,j=L+(R<<21&4294967295|R>>>11),R=E+(L^(j|~O))+N[8]+1873313359&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[15]+4264355552&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[6]+2734768916&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[13]+1309151649&4294967295,j=L+(R<<21&4294967295|R>>>11),R=E+(L^(j|~O))+N[4]+4149444226&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[11]+3174756917&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[2]+718787259&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[9]+3951481745&4294967295,C.g[0]=C.g[0]+E&4294967295,C.g[1]=C.g[1]+(L+(R<<21&4294967295|R>>>11))&4294967295,C.g[2]=C.g[2]+L&4294967295,C.g[3]=C.g[3]+O&4294967295}n.prototype.u=function(C,E){E===void 0&&(E=C.length);for(var j=E-this.blockSize,N=this.B,L=this.h,O=0;O<E;){if(L==0)for(;O<=j;)i(this,C,O),O+=this.blockSize;if(typeof C=="string"){for(;O<E;)if(N[L++]=C.charCodeAt(O++),L==this.blockSize){i(this,N),L=0;break}}else for(;O<E;)if(N[L++]=C[O++],L==this.blockSize){i(this,N),L=0;break}}this.h=L,this.o+=E},n.prototype.v=function(){var C=Array((56>this.h?this.blockSize:2*this.blockSize)-this.h);C[0]=128;for(var E=1;E<C.length-8;++E)C[E]=0;var j=8*this.o;for(E=C.length-8;E<C.length;++E)C[E]=j&255,j/=256;for(this.u(C),C=Array(16),E=j=0;4>E;++E)for(var N=0;32>N;N+=8)C[j++]=this.g[E]>>>N&255;return C};function r(C,E){var j=l;return Object.prototype.hasOwnProperty.call(j,C)?j[C]:j[C]=E(C)}function o(C,E){this.h=E;for(var j=[],N=!0,L=C.length-1;0<=L;L--){var O=C[L]|0;N&&O==E||(j[L]=O,N=!1)}this.g=j}var l={};function c(C){return-128<=C&&128>C?r(C,function(E){return new o([E|0],0>E?-1:0)}):new o([C|0],0>C?-1:0)}function d(C){if(isNaN(C)||!isFinite(C))return p;if(0>C)return x(d(-C));for(var E=[],j=1,N=0;C>=j;N++)E[N]=C/j|0,j*=4294967296;return new o(E,0)}function u(C,E){if(C.length==0)throw Error("number format error: empty string");if(E=E||10,2>E||36<E)throw Error("radix out of range: "+E);if(C.charAt(0)=="-")return x(u(C.substring(1),E));if(0<=C.indexOf("-"))throw Error('number format error: interior "-" character');for(var j=d(Math.pow(E,8)),N=p,L=0;L<C.length;L+=8){var O=Math.min(8,C.length-L),R=parseInt(C.substring(L,L+O),E);8>O?(O=d(Math.pow(E,O)),N=N.j(O).add(d(R))):(N=N.j(j),N=N.add(d(R)))}return N}var p=c(0),m=c(1),h=c(16777216);t=o.prototype,t.m=function(){if(y(this))return-x(this).m();for(var C=0,E=1,j=0;j<this.g.length;j++){var N=this.i(j);C+=(0<=N?N:4294967296+N)*E,E*=4294967296}return C},t.toString=function(C){if(C=C||10,2>C||36<C)throw Error("radix out of range: "+C);if(g(this))return"0";if(y(this))return"-"+x(this).toString(C);for(var E=d(Math.pow(C,6)),j=this,N="";;){var L=T(j,E).g;j=v(j,L.j(E));var O=((0<j.g.length?j.g[0]:j.h)>>>0).toString(C);if(j=L,g(j))return O+N;for(;6>O.length;)O="0"+O;N=O+N}},t.i=function(C){return 0>C?0:C<this.g.length?this.g[C]:this.h};function g(C){if(C.h!=0)return!1;for(var E=0;E<C.g.length;E++)if(C.g[E]!=0)return!1;return!0}function y(C){return C.h==-1}t.l=function(C){return C=v(this,C),y(C)?-1:g(C)?0:1};function x(C){for(var E=C.g.length,j=[],N=0;N<E;N++)j[N]=~C.g[N];return new o(j,~C.h).add(m)}t.abs=function(){return y(this)?x(this):this},t.add=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0,L=0;L<=E;L++){var O=N+(this.i(L)&65535)+(C.i(L)&65535),R=(O>>>16)+(this.i(L)>>>16)+(C.i(L)>>>16);N=R>>>16,O&=65535,R&=65535,j[L]=R<<16|O}return new o(j,j[j.length-1]&-2147483648?-1:0)};function v(C,E){return C.add(x(E))}t.j=function(C){if(g(this)||g(C))return p;if(y(this))return y(C)?x(this).j(x(C)):x(x(this).j(C));if(y(C))return x(this.j(x(C)));if(0>this.l(h)&&0>C.l(h))return d(this.m()*C.m());for(var E=this.g.length+C.g.length,j=[],N=0;N<2*E;N++)j[N]=0;for(N=0;N<this.g.length;N++)for(var L=0;L<C.g.length;L++){var O=this.i(N)>>>16,R=this.i(N)&65535,G=C.i(L)>>>16,ee=C.i(L)&65535;j[2*N+2*L]+=R*ee,w(j,2*N+2*L),j[2*N+2*L+1]+=O*ee,w(j,2*N+2*L+1),j[2*N+2*L+1]+=R*G,w(j,2*N+2*L+1),j[2*N+2*L+2]+=O*G,w(j,2*N+2*L+2)}for(N=0;N<E;N++)j[N]=j[2*N+1]<<16|j[2*N];for(N=E;N<2*E;N++)j[N]=0;return new o(j,0)};function w(C,E){for(;(C[E]&65535)!=C[E];)C[E+1]+=C[E]>>>16,C[E]&=65535,E++}function S(C,E){this.g=C,this.h=E}function T(C,E){if(g(E))throw Error("division by zero");if(g(C))return new S(p,p);if(y(C))return E=T(x(C),E),new S(x(E.g),x(E.h));if(y(E))return E=T(C,x(E)),new S(x(E.g),E.h);if(30<C.g.length){if(y(C)||y(E))throw Error("slowDivide_ only works with positive integers.");for(var j=m,N=E;0>=N.l(C);)j=P(j),N=P(N);var L=M(j,1),O=M(N,1);for(N=M(N,2),j=M(j,2);!g(N);){var R=O.add(N);0>=R.l(C)&&(L=L.add(j),O=R),N=M(N,1),j=M(j,1)}return E=v(C,L.j(E)),new S(L,E)}for(L=p;0<=C.l(E);){for(j=Math.max(1,Math.floor(C.m()/E.m())),N=Math.ceil(Math.log(j)/Math.LN2),N=48>=N?1:Math.pow(2,N-48),O=d(j),R=O.j(E);y(R)||0<R.l(C);)j-=N,O=d(j),R=O.j(E);g(O)&&(O=m),L=L.add(O),C=v(C,R)}return new S(L,C)}t.A=function(C){return T(this,C).h},t.and=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0;N<E;N++)j[N]=this.i(N)&C.i(N);return new o(j,this.h&C.h)},t.or=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0;N<E;N++)j[N]=this.i(N)|C.i(N);return new o(j,this.h|C.h)},t.xor=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0;N<E;N++)j[N]=this.i(N)^C.i(N);return new o(j,this.h^C.h)};function P(C){for(var E=C.g.length+1,j=[],N=0;N<E;N++)j[N]=C.i(N)<<1|C.i(N-1)>>>31;return new o(j,C.h)}function M(C,E){var j=E>>5;E%=32;for(var N=C.g.length-j,L=[],O=0;O<N;O++)L[O]=0<E?C.i(O+j)>>>E|C.i(O+j+1)<<32-E:C.i(O+j);return new o(L,C.h)}n.prototype.digest=n.prototype.v,n.prototype.reset=n.prototype.s,n.prototype.update=n.prototype.u,GR=n,o.prototype.add=o.prototype.add,o.prototype.multiply=o.prototype.j,o.prototype.modulo=o.prototype.A,o.prototype.compare=o.prototype.l,o.prototype.toNumber=o.prototype.m,o.prototype.toString=o.prototype.toString,o.prototype.getBits=o.prototype.i,o.fromNumber=d,o.fromString=u,Lo=o}).apply(typeof JE<"u"?JE:typeof self<"u"?self:typeof window<"u"?window:{});var Vp=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};/** @license 435Copyright The Closure Library Authors. 436SPDX-License-Identifier: Apache-2.0 437*/var KR,Vc,JR,Rm,Yv,QR,XR,YR;(function(){var t,e=typeof Object.defineProperties=="function"?Object.defineProperty:function(f,b,A){return f==Array.prototype||f==Object.prototype||(f[b]=A.value),f};function a(f){f=[typeof globalThis=="object"&&globalThis,f,typeof window=="object"&&window,typeof self=="object"&&self,typeof Vp=="object"&&Vp];for(var b=0;b<f.length;++b){var A=f[b];if(A&&A.Math==Math)return A}throw Error("Cannot find global object")}var n=a(this);function i(f,b){if(b)e:{var A=n;f=f.split(".");for(var I=0;I<f.length-1;I++){var D=f[I];if(!(D in A))break e;A=A[D]}f=f[f.length-1],I=A[f],b=b(I),b!=I&&b!=null&&e(A,f,{configurable:!0,writable:!0,value:b})}}function r(f,b){f instanceof String&&(f+="");var A=0,I=!1,D={next:function(){if(!I&&A<f.length){var q=A++;return{value:b(q,f[q]),done:!1}}return I=!0,{done:!0,value:void 0}}};return D[Symbol.iterator]=function(){return D},D}i("Array.prototype.values",function(f){return f||function(){return r(this,function(b,A){return A})}});/** @license 438 439 Copyright The Closure Library Authors. 440 SPDX-License-Identifier: Apache-2.0 441*/var o=o||{},l=this||self;function c(f){var b=typeof f;return b=b!="object"?b:f?Array.isArray(f)?"array":b:"null",b=="array"||b=="object"&&typeof f.length=="number"}function d(f){var b=typeof f;return b=="object"&&f!=null||b=="function"}function u(f,b,A){return f.call.apply(f.bind,arguments)}function p(f,b,A){if(!f)throw Error();if(2<arguments.length){var I=Array.prototype.slice.call(arguments,2);return function(){var D=Array.prototype.slice.call(arguments);return Array.prototype.unshift.apply(D,I),f.apply(b,D)}}return function(){return f.apply(b,arguments)}}function m(f,b,A){return m=Function.prototype.bind&&Function.prototype.bind.toString().indexOf("native code")!=-1?u:p,m.apply(null,arguments)}function h(f,b){var A=Array.prototype.slice.call(arguments,1);return function(){var I=A.slice();return I.push.apply(I,arguments),f.apply(this,I)}}function g(f,b){function A(){}A.prototype=b.prototype,f.aa=b.prototype,f.prototype=new A,f.prototype.constructor=f,f.Qb=function(I,D,q){for(var W=Array(arguments.length-2),De=2;De<arguments.length;De++)W[De-2]=arguments[De];return b.prototype[D].apply(I,W)}}function y(f){const b=f.length;if(0<b){const A=Array(b);for(let I=0;I<b;I++)A[I]=f[I];return A}return[]}function x(f,b){for(let A=1;A<arguments.length;A++){const I=arguments[A];if(c(I)){const D=f.length||0,q=I.length||0;f.length=D+q;for(let W=0;W<q;W++)f[D+W]=I[W]}else f.push(I)}}class v{constructor(b,A){this.i=b,this.j=A,this.h=0,this.g=null}get(){let b;return 0<this.h?(this.h--,b=this.g,this.g=b.next,b.next=null):b=this.i(),b}}function w(f){return/^[\s\xa0]*$/.test(f)}function S(){var f=l.navigator;return f&&(f=f.userAgent)?f:""}function T(f){return T[" "](f),f}T[" "]=function(){};var P=S().indexOf("Gecko")!=-1&&!(S().toLowerCase().indexOf("webkit")!=-1&&S().indexOf("Edge")==-1)&&!(S().indexOf("Trident")!=-1||S().indexOf("MSIE")!=-1)&&S().indexOf("Edge")==-1;function M(f,b,A){for(const I in f)b.call(A,f[I],I,f)}function C(f,b){for(const A in f)b.call(void 0,f[A],A,f)}function E(f){const b={};for(const A in f)b[A]=f[A];return b}const j="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");function N(f,b){let A,I;for(let D=1;D<arguments.length;D++){I=arguments[D];for(A in I)f[A]=I[A];for(let q=0;q<j.length;q++)A=j[q],Object.prototype.hasOwnProperty.call(I,A)&&(f[A]=I[A])}}function L(f){var b=1;f=f.split(":");const A=[];for(;0<b&&f.length;)A.push(f.shift()),b--;return f.length&&A.push(f.join(":")),A}function O(f){l.setTimeout(()=>{throw f},0)}function R(){var f=Z;let b=null;return f.g&&(b=f.g,f.g=f.g.next,f.g||(f.h=null),b.next=null),b}class G{constructor(){this.h=this.g=null}add(b,A){const I=ee.get();I.set(b,A),this.h?this.h.next=I:this.g=I,this.h=I}}var ee=new v(()=>new ke,f=>f.reset());class ke{constructor(){this.next=this.g=this.h=null}set(b,A){this.h=b,this.g=A,this.next=null}reset(){this.next=this.g=this.h=null}}let ae,F=!1,Z=new G,re=()=>{const f=l.Promise.resolve(void 0);ae=()=>{f.then(fe)}};var fe=()=>{for(var f;f=R();){try{f.h.call(f.g)}catch(A){O(A)}var b=ee;b.j(f),100>b.h&&(b.h++,f.next=b.g,b.g=f)}F=!1};function ve(){this.s=this.s,this.C=this.C}ve.prototype.s=!1,ve.prototype.ma=function(){this.s||(this.s=!0,this.N())},ve.prototype.N=function(){if(this.C)for(;this.C.length;)this.C.shift()()};function Ie(f,b){this.type=f,this.g=this.target=b,this.defaultPrevented=!1}Ie.prototype.h=function(){this.defaultPrevented=!0};var ne=function(){if(!l.addEventListener||!Object.defineProperty)return!1;var f=!1,b=Object.defineProperty({},"passive",{get:function(){f=!0}});try{const A=()=>{};l.addEventListener("test",A,b),l.removeEventListener("test",A,b)}catch{}return f}();function ge(f,b){if(Ie.call(this,f?f.type:""),this.relatedTarget=this.g=this.target=null,this.button=this.screenY=this.screenX=this.clientY=this.clientX=0,this.key="",this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1,this.state=null,this.pointerId=0,this.pointerType="",this.i=null,f){var A=this.type=f.type,I=f.changedTouches&&f.changedTouches.length?f.changedTouches[0]:null;if(this.target=f.target||f.srcElement,this.g=b,b=f.relatedTarget){if(P){e:{try{T(b.nodeName);var D=!0;break e}catch{}D=!1}D||(b=null)}}else A=="mouseover"?b=f.fromElement:A=="mouseout"&&(b=f.toElement);this.relatedTarget=b,I?(this.clientX=I.clientX!==void 0?I.clientX:I.pageX,this.clientY=I.clientY!==void 0?I.clientY:I.pageY,this.screenX=I.screenX||0,this.screenY=I.screenY||0):(this.clientX=f.clientX!==void 0?f.clientX:f.pageX,this.clientY=f.clientY!==void 0?f.clientY:f.pageY,this.screenX=f.screenX||0,this.screenY=f.screenY||0),this.button=f.button,this.key=f.key||"",this.ctrlKey=f.ctrlKey,this.altKey=f.altKey,this.shiftKey=f.shiftKey,this.metaKey=f.metaKey,this.pointerId=f.pointerId||0,this.pointerType=typeof f.pointerType=="string"?f.pointerType:Me[f.pointerType]||"",this.state=f.state,this.i=f,f.defaultPrevented&&ge.aa.h.call(this)}}g(ge,Ie);var Me={2:"touch",3:"pen",4:"mouse"};ge.prototype.h=function(){ge.aa.h.call(this);var f=this.i;f.preventDefault?f.preventDefault():f.returnValue=!1};var We="closure_listenable_"+(1e6*Math.random()|0),si=0;function Vn(f,b,A,I,D){this.listener=f,this.proxy=null,this.src=b,this.type=A,this.capture=!!I,this.ha=D,this.key=++si,this.da=this.fa=!1}function Xu(f){f.da=!0,f.listener=null,f.proxy=null,f.src=null,f.ha=null}function Yu(f){this.src=f,this.g={},this.h=0}Yu.prototype.add=function(f,b,A,I,D){var q=f.toString();f=this.g[q],f||(f=this.g[q]=[],this.h++);var W=ey(f,b,I,D);return-1<W?(b=f[W],A||(b.fa=!1)):(b=new Vn(b,this.src,q,!!I,D),b.fa=A,f.push(b)),b};function Zg(f,b){var A=b.type;if(A in f.g){var I=f.g[A],D=Array.prototype.indexOf.call(I,b,void 0),q;(q=0<=D)&&Array.prototype.splice.call(I,D,1),q&&(Xu(b),f.g[A].length==0&&(delete f.g[A],f.h--))}}function ey(f,b,A,I){for(var D=0;D<f.length;++D){var q=f[D];if(!q.da&&q.listener==b&&q.capture==!!A&&q.ha==I)return D}return-1}var ty="closure_lm_"+(1e6*Math.random()|0),ay={};function LS(f,b,A,I,D){if(Array.isArray(b)){for(var q=0;q<b.length;q++)LS(f,b[q],A,I,D);return null}return A=DS(A),f&&f[We]?f.K(b,A,d(I)?!!I.capture:!1,D):TD(f,b,A,!1,I,D)}function TD(f,b,A,I,D,q){if(!b)throw Error("Invalid event type");var W=d(D)?!!D.capture:!!D,De=iy(f);if(De||(f[ty]=De=new Yu(f)),A=De.add(b,A,I,W,q),A.proxy)return A;if(I=ND(),A.proxy=I,I.src=f,I.listener=A,f.addEventListener)ne||(D=W),D===void 0&&(D=!1),f.addEventListener(b.toString(),I,D);else if(f.attachEvent)f.attachEvent(MS(b.toString()),I);else if(f.addListener&&f.removeListener)f.addListener(I);else throw Error("addEventListener and attachEvent are unavailable.");return A}function ND(){function f(A){return b.call(f.src,f.listener,A)}const b=ID;return f}function OS(f,b,A,I,D){if(Array.isArray(b))for(var q=0;q<b.length;q++)OS(f,b[q],A,I,D);else I=d(I)?!!I.capture:!!I,A=DS(A),f&&f[We]?(f=f.i,b=String(b).toString(),b in f.g&&(q=f.g[b],A=ey(q,A,I,D),-1<A&&(Xu(q[A]),Array.prototype.splice.call(q,A,1),q.length==0&&(delete f.g[b],f.h--)))):f&&(f=iy(f))&&(b=f.g[b.toString()],f=-1,b&&(f=ey(b,A,I,D)),(A=-1<f?b[f]:null)&&ny(A))}function ny(f){if(typeof f!="number"&&f&&!f.da){var b=f.src;if(b&&b[We])Zg(b.i,f);else{var A=f.type,I=f.proxy;b.removeEventListener?b.removeEventListener(A,I,f.capture):b.detachEvent?b.detachEvent(MS(A),I):b.addListener&&b.removeListener&&b.removeListener(I),(A=iy(b))?(Zg(A,f),A.h==0&&(A.src=null,b[ty]=null)):Xu(f)}}}function MS(f){return f in ay?ay[f]:ay[f]="on"+f}function ID(f,b){if(f.da)f=!0;else{b=new ge(b,this);var A=f.listener,I=f.ha||f.src;f.fa&&ny(f),f=A.call(I,b)}return f}function iy(f){return f=f[ty],f instanceof Yu?f:null}var ry="__closure_events_fn_"+(1e9*Math.random()>>>0);function DS(f){return typeof f=="function"?f:(f[ry]||(f[ry]=function(b){return f.handleEvent(b)}),f[ry])}function Gt(){ve.call(this),this.i=new Yu(this),this.M=this,this.F=null}g(Gt,ve),Gt.prototype[We]=!0,Gt.prototype.removeEventListener=function(f,b,A,I){OS(this,f,b,A,I)};function la(f,b){var A,I=f.F;if(I)for(A=[];I;I=I.F)A.push(I);if(f=f.M,I=b.type||b,typeof b=="string")b=new Ie(b,f);else if(b instanceof Ie)b.target=b.target||f;else{var D=b;b=new Ie(I,f),N(b,D)}if(D=!0,A)for(var q=A.length-1;0<=q;q--){var W=b.g=A[q];D=Zu(W,I,!0,b)&&D}if(W=b.g=f,D=Zu(W,I,!0,b)&&D,D=Zu(W,I,!1,b)&&D,A)for(q=0;q<A.length;q++)W=b.g=A[q],D=Zu(W,I,!1,b)&&D}Gt.prototype.N=function(){if(Gt.aa.N.call(this),this.i){var f=this.i,b;for(b in f.g){for(var A=f.g[b],I=0;I<A.length;I++)Xu(A[I]);delete f.g[b],f.h--}}this.F=null},Gt.prototype.K=function(f,b,A,I){return this.i.add(String(f),b,!1,A,I)},Gt.prototype.L=function(f,b,A,I){return this.i.add(String(f),b,!0,A,I)};function Zu(f,b,A,I){if(b=f.i.g[String(b)],!b)return!0;b=b.concat();for(var D=!0,q=0;q<b.length;++q){var W=b[q];if(W&&!W.da&&W.capture==A){var De=W.listener,Lt=W.ha||W.src;W.fa&&Zg(f.i,W),D=De.call(Lt,I)!==!1&&D}}return D&&!I.defaultPrevented}function qS(f,b,A){if(typeof f=="function")A&&(f=m(f,A));else if(f&&typeof f.handleEvent=="function")f=m(f.handleEvent,f);else throw Error("Invalid listener argument");return 2147483647<Number(b)?-1:l.setTimeout(f,b||0)}function zS(f){f.g=qS(()=>{f.g=null,f.i&&(f.i=!1,zS(f))},f.l);const b=f.h;f.h=null,f.m.apply(null,b)}class PD extends ve{constructor(b,A){super(),this.m=b,this.l=A,this.h=null,this.i=!1,this.g=null}j(b){this.h=arguments,this.g?this.i=!0:zS(this)}N(){super.N(),this.g&&(l.clearTimeout(this.g),this.g=null,this.i=!1,this.h=null)}}function tc(f){ve.call(this),this.h=f,this.g={}}g(tc,ve);var VS=[];function HS(f){M(f.g,function(b,A){this.g.hasOwnProperty(A)&&ny(b)},f),f.g={}}tc.prototype.N=function(){tc.aa.N.call(this),HS(this)},tc.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented")};var oy=l.JSON.stringify,RD=l.JSON.parse,LD=class{stringify(f){return l.JSON.stringify(f,void 0)}parse(f){return l.JSON.parse(f,void 0)}};function sy(){}sy.prototype.h=null;function FS(f){return f.h||(f.h=f.i())}function BS(){}var ac={OPEN:"a",kb:"b",Ja:"c",wb:"d"};function ly(){Ie.call(this,"d")}g(ly,Ie);function cy(){Ie.call(this,"c")}g(cy,Ie);var io={},US=null;function ep(){return US=US||new Gt}io.La="serverreachability";function $S(f){Ie.call(this,io.La,f)}g($S,Ie);function nc(f){const b=ep();la(b,new $S(b))}io.STAT_EVENT="statevent";function WS(f,b){Ie.call(this,io.STAT_EVENT,f),this.stat=b}g(WS,Ie);function ca(f){const b=ep();la(b,new WS(b,f))}io.Ma="timingevent";function GS(f,b){Ie.call(this,io.Ma,f),this.size=b}g(GS,Ie);function ic(f,b){if(typeof f!="function")throw Error("Fn must not be null and must be a function");return l.setTimeout(function(){f()},b)}function rc(){this.g=!0}rc.prototype.xa=function(){this.g=!1};function OD(f,b,A,I,D,q){f.info(function(){if(f.g)if(q)for(var W="",De=q.split("&"),Lt=0;Lt<De.length;Lt++){var Ce=De[Lt].split("=");if(1<Ce.length){var Kt=Ce[0];Ce=Ce[1];var Jt=Kt.split("_");W=2<=Jt.length&&Jt[1]=="type"?W+(Kt+"="+Ce+"&"):W+(Kt+"=redacted&")}}else W=null;else W=q;return"XMLHTTP REQ ("+I+") [attempt "+D+"]: "+b+` 442`+A+` 443`+W})}function MD(f,b,A,I,D,q,W){f.info(function(){return"XMLHTTP RESP ("+I+") [ attempt "+D+"]: "+b+` 444`+A+` 445`+q+" "+W})}function ys(f,b,A,I){f.info(function(){return"XMLHTTP TEXT ("+b+"): "+qD(f,A)+(I?" "+I:"")})}function DD(f,b){f.info(function(){return"TIMEOUT: "+b})}rc.prototype.info=function(){};function qD(f,b){if(!f.g)return b;if(!b)return null;try{var A=JSON.parse(b);if(A){for(f=0;f<A.length;f++)if(Array.isArray(A[f])){var I=A[f];if(!(2>I.length)){var D=I[1];if(Array.isArray(D)&&!(1>D.length)){var q=D[0];if(q!="noop"&&q!="stop"&&q!="close")for(var W=1;W<D.length;W++)D[W]=""}}}}return oy(A)}catch{return b}}var tp={NO_ERROR:0,gb:1,tb:2,sb:3,nb:4,rb:5,ub:6,Ia:7,TIMEOUT:8,xb:9},KS={lb:"complete",Hb:"success",Ja:"error",Ia:"abort",zb:"ready",Ab:"readystatechange",TIMEOUT:"timeout",vb:"incrementaldata",yb:"progress",ob:"downloadprogress",Pb:"uploadprogress"},dy;function ap(){}g(ap,sy),ap.prototype.g=function(){return new XMLHttpRequest},ap.prototype.i=function(){return{}},dy=new ap;function Wi(f,b,A,I){this.j=f,this.i=b,this.l=A,this.R=I||1,this.U=new tc(this),this.I=45e3,this.H=null,this.o=!1,this.m=this.A=this.v=this.L=this.F=this.S=this.B=null,this.D=[],this.g=null,this.C=0,this.s=this.u=null,this.X=-1,this.J=!1,this.O=0,this.M=null,this.W=this.K=this.T=this.P=!1,this.h=new JS}function JS(){this.i=null,this.g="",this.h=!1}var QS={},uy={};function py(f,b,A){f.L=1,f.v=op(li(b)),f.m=A,f.P=!0,XS(f,null)}function XS(f,b){f.F=Date.now(),np(f),f.A=li(f.v);var A=f.A,I=f.R;Array.isArray(I)||(I=[String(I)]),u2(A.i,"t",I),f.C=0,A=f.j.J,f.h=new JS,f.g=T2(f.j,A?b:null,!f.m),0<f.O&&(f.M=new PD(m(f.Y,f,f.g),f.O)),b=f.U,A=f.g,I=f.ca;var D="readystatechange";Array.isArray(D)||(D&&(VS[0]=D.toString()),D=VS);for(var q=0;q<D.length;q++){var W=LS(A,D[q],I||b.handleEvent,!1,b.h||b);if(!W)break;b.g[W.key]=W}b=f.H?E(f.H):{},f.m?(f.u||(f.u="POST"),b["Content-Type"]="application/x-www-form-urlencoded",f.g.ea(f.A,f.u,f.m,b)):(f.u="GET",f.g.ea(f.A,f.u,null,b)),nc(),OD(f.i,f.u,f.A,f.l,f.R,f.m)}Wi.prototype.ca=function(f){f=f.target;const b=this.M;b&&ci(f)==3?b.j():this.Y(f)},Wi.prototype.Y=function(f){try{if(f==this.g)e:{const Jt=ci(this.g);var b=this.g.Ba();const bs=this.g.Z();if(!(3>Jt)&&(Jt!=3||this.g&&(this.h.h||this.g.oa()||x2(this.g)))){this.J||Jt!=4||b==7||(b==8||0>=bs?nc(3):nc(2)),my(this);var A=this.g.Z();this.X=A;t:if(YS(this)){var I=x2(this.g);f="";var D=I.length,q=ci(this.g)==4;if(!this.h.i){if(typeof TextDecoder>"u"){ro(this),oc(this);var W="";break t}this.h.i=new l.TextDecoder}for(b=0;b<D;b++)this.h.h=!0,f+=this.h.i.decode(I[b],{stream:!(q&&b==D-1)});I.length=0,this.h.g+=f,this.C=0,W=this.h.g}else W=this.g.oa();if(this.o=A==200,MD(this.i,this.u,this.A,this.l,this.R,Jt,A),this.o){if(this.T&&!this.K){t:{if(this.g){var De,Lt=this.g;if((De=Lt.g?Lt.g.getResponseHeader("X-HTTP-Initial-Response"):null)&&!w(De)){var Ce=De;break t}}Ce=null}if(A=Ce)ys(this.i,this.l,A,"Initial handshake response via X-HTTP-Initial-Response"),this.K=!0,hy(this,A);else{this.o=!1,this.s=3,ca(12),ro(this),oc(this);break e}}if(this.P){A=!0;let yn;for(;!this.J&&this.C<W.length;)if(yn=zD(this,W),yn==uy){Jt==4&&(this.s=4,ca(14),A=!1),ys(this.i,this.l,null,"[Incomplete Response]");break}else if(yn==QS){this.s=4,ca(15),ys(this.i,this.l,W,"[Invalid Chunk]"),A=!1;break}else ys(this.i,this.l,yn,null),hy(this,yn);if(YS(this)&&this.C!=0&&(this.h.g=this.h.g.slice(this.C),this.C=0),Jt!=4||W.length!=0||this.h.h||(this.s=1,ca(16),A=!1),this.o=this.o&&A,!A)ys(this.i,this.l,W,"[Invalid Chunked Response]"),ro(this),oc(this);else if(0<W.length&&!this.W){this.W=!0;var Kt=this.j;Kt.g==this&&Kt.ba&&!Kt.M&&(Kt.j.info("Great, no buffering proxy detected. Bytes received: "+W.length),by(Kt),Kt.M=!0,ca(11))}}else ys(this.i,this.l,W,null),hy(this,W);Jt==4&&ro(this),this.o&&!this.J&&(Jt==4?A2(this.j,this):(this.o=!1,np(this)))}else aq(this.g),A==400&&0<W.indexOf("Unknown SID")?(this.s=3,ca(12)):(this.s=0,ca(13)),ro(this),oc(this)}}}catch{}finally{}};function YS(f){return f.g?f.u=="GET"&&f.L!=2&&f.j.Ca:!1}function zD(f,b){var A=f.C,I=b.indexOf(` 446`,A);return I==-1?uy:(A=Number(b.substring(A,I)),isNaN(A)?QS:(I+=1,I+A>b.length?uy:(b=b.slice(I,I+A),f.C=I+A,b)))}Wi.prototype.cancel=function(){this.J=!0,ro(this)};function np(f){f.S=Date.now()+f.I,ZS(f,f.I)}function ZS(f,b){if(f.B!=null)throw Error("WatchDog timer not null");f.B=ic(m(f.ba,f),b)}function my(f){f.B&&(l.clearTimeout(f.B),f.B=null)}Wi.prototype.ba=function(){this.B=null;const f=Date.now();0<=f-this.S?(DD(this.i,this.A),this.L!=2&&(nc(),ca(17)),ro(this),this.s=2,oc(this)):ZS(this,this.S-f)};function oc(f){f.j.G==0||f.J||A2(f.j,f)}function ro(f){my(f);var b=f.M;b&&typeof b.ma=="function"&&b.ma(),f.M=null,HS(f.U),f.g&&(b=f.g,f.g=null,b.abort(),b.ma())}function hy(f,b){try{var A=f.j;if(A.G!=0&&(A.g==f||fy(A.h,f))){if(!f.K&&fy(A.h,f)&&A.G==3){try{var I=A.Da.g.parse(b)}catch{I=null}if(Array.isArray(I)&&I.length==3){var D=I;if(D[0]==0){e:if(!A.u){if(A.g)if(A.g.F+3e3<f.F)pp(A),dp(A);else break e;vy(A),ca(18)}}else A.za=D[1],0<A.za-A.T&&37500>D[2]&&A.F&&A.v==0&&!A.C&&(A.C=ic(m(A.Za,A),6e3));if(1>=a2(A.h)&&A.ca){try{A.ca()}catch{}A.ca=void 0}}else so(A,11)}else if((f.K||A.g==f)&&pp(A),!w(b))for(D=A.Da.g.parse(b),b=0;b<D.length;b++){let Ce=D[b];if(A.T=Ce[0],Ce=Ce[1],A.G==2)if(Ce[0]=="c"){A.K=Ce[1],A.ia=Ce[2];const Kt=Ce[3];Kt!=null&&(A.la=Kt,A.j.info("VER="+A.la));const Jt=Ce[4];Jt!=null&&(A.Aa=Jt,A.j.info("SVER="+A.Aa));const bs=Ce[5];bs!=null&&typeof bs=="number"&&0<bs&&(I=1.5*bs,A.L=I,A.j.info("backChannelRequestTimeoutMs_="+I)),I=A;const yn=f.g;if(yn){const hp=yn.g?yn.g.getResponseHeader("X-Client-Wire-Protocol"):null;if(hp){var q=I.h;q.g||hp.indexOf("spdy")==-1&&hp.indexOf("quic")==-1&&hp.indexOf("h2")==-1||(q.j=q.l,q.g=new Set,q.h&&(gy(q,q.h),q.h=null))}if(I.D){const wy=yn.g?yn.g.getResponseHeader("X-HTTP-Session-Id"):null;wy&&(I.ya=wy,He(I.I,I.D,wy))}}A.G=3,A.l&&A.l.ua(),A.ba&&(A.R=Date.now()-f.F,A.j.info("Handshake RTT: "+A.R+"ms")),I=A;var W=f;if(I.qa=j2(I,I.J?I.ia:null,I.W),W.K){n2(I.h,W);var De=W,Lt=I.L;Lt&&(De.I=Lt),De.B&&(my(De),np(De)),I.g=W}else S2(I);0<A.i.length&&up(A)}else Ce[0]!="stop"&&Ce[0]!="close"||so(A,7);else A.G==3&&(Ce[0]=="stop"||Ce[0]=="close"?Ce[0]=="stop"?so(A,7):xy(A):Ce[0]!="noop"&&A.l&&A.l.ta(Ce),A.v=0)}}nc(4)}catch{}}var VD=class{constructor(f,b){this.g=f,this.map=b}};function e2(f){this.l=f||10,l.PerformanceNavigationTiming?(f=l.performance.getEntriesByType("navigation"),f=0<f.length&&(f[0].nextHopProtocol=="hq"||f[0].nextHopProtocol=="h2")):f=!!(l.chrome&&l.chrome.loadTimes&&l.chrome.loadTimes()&&l.chrome.loadTimes().wasFetchedViaSpdy),this.j=f?this.l:1,this.g=null,1<this.j&&(this.g=new Set),this.h=null,this.i=[]}function t2(f){return f.h?!0:f.g?f.g.size>=f.j:!1}function a2(f){return f.h?1:f.g?f.g.size:0}function fy(f,b){return f.h?f.h==b:f.g?f.g.has(b):!1}function gy(f,b){f.g?f.g.add(b):f.h=b}function n2(f,b){f.h&&f.h==b?f.h=null:f.g&&f.g.has(b)&&f.g.delete(b)}e2.prototype.cancel=function(){if(this.i=i2(this),this.h)this.h.cancel(),this.h=null;else if(this.g&&this.g.size!==0){for(const f of this.g.values())f.cancel();this.g.clear()}};function i2(f){if(f.h!=null)return f.i.concat(f.h.D);if(f.g!=null&&f.g.size!==0){let b=f.i;for(const A of f.g.values())b=b.concat(A.D);return b}return y(f.i)}function HD(f){if(f.V&&typeof f.V=="function")return f.V();if(typeof Map<"u"&&f instanceof Map||typeof Set<"u"&&f instanceof Set)return Array.from(f.values());if(typeof f=="string")return f.split("");if(c(f)){for(var b=[],A=f.length,I=0;I<A;I++)b.push(f[I]);return b}b=[],A=0;for(I in f)b[A++]=f[I];return b}function FD(f){if(f.na&&typeof f.na=="function")return f.na();if(!f.V||typeof f.V!="function"){if(typeof Map<"u"&&f instanceof Map)return Array.from(f.keys());if(!(typeof Set<"u"&&f instanceof Set)){if(c(f)||typeof f=="string"){var b=[];f=f.length;for(var A=0;A<f;A++)b.push(A);return b}b=[],A=0;for(const I in f)b[A++]=I;return b}}}function r2(f,b){if(f.forEach&&typeof f.forEach=="function")f.forEach(b,void 0);else if(c(f)||typeof f=="string")Array.prototype.forEach.call(f,b,void 0);else for(var A=FD(f),I=HD(f),D=I.length,q=0;q<D;q++)b.call(void 0,I[q],A&&A[q],f)}var o2=RegExp("^(?:([^:/?#.]+):)?(?://(?:([^\\\\/?#]*)@)?([^\\\\/?#]*?)(?::([0-9]+))?(?=[\\\\/?#]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$");function BD(f,b){if(f){f=f.split("&");for(var A=0;A<f.length;A++){var I=f[A].indexOf("="),D=null;if(0<=I){var q=f[A].substring(0,I);D=f[A].substring(I+1)}else q=f[A];b(q,D?decodeURIComponent(D.replace(/\+/g," ")):"")}}}function oo(f){if(this.g=this.o=this.j="",this.s=null,this.m=this.l="",this.h=!1,f instanceof oo){this.h=f.h,ip(this,f.j),this.o=f.o,this.g=f.g,rp(this,f.s),this.l=f.l;var b=f.i,A=new cc;A.i=b.i,b.g&&(A.g=new Map(b.g),A.h=b.h),s2(this,A),this.m=f.m}else f&&(b=String(f).match(o2))?(this.h=!1,ip(this,b[1]||"",!0),this.o=sc(b[2]||""),this.g=sc(b[3]||"",!0),rp(this,b[4]),this.l=sc(b[5]||"",!0),s2(this,b[6]||"",!0),this.m=sc(b[7]||"")):(this.h=!1,this.i=new cc(null,this.h))}oo.prototype.toString=function(){var f=[],b=this.j;b&&f.push(lc(b,l2,!0),":");var A=this.g;return(A||b=="file")&&(f.push("//"),(b=this.o)&&f.push(lc(b,l2,!0),"@"),f.push(encodeURIComponent(String(A)).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),A=this.s,A!=null&&f.push(":",String(A))),(A=this.l)&&(this.g&&A.charAt(0)!="/"&&f.push("/"),f.push(lc(A,A.charAt(0)=="/"?WD:$D,!0))),(A=this.i.toString())&&f.push("?",A),(A=this.m)&&f.push("#",lc(A,KD)),f.join("")};function li(f){return new oo(f)}function ip(f,b,A){f.j=A?sc(b,!0):b,f.j&&(f.j=f.j.replace(/:$/,""))}function rp(f,b){if(b){if(b=Number(b),isNaN(b)||0>b)throw Error("Bad port number "+b);f.s=b}else f.s=null}function s2(f,b,A){b instanceof cc?(f.i=b,JD(f.i,f.h)):(A||(b=lc(b,GD)),f.i=new cc(b,f.h))}function He(f,b,A){f.i.set(b,A)}function op(f){return He(f,"zx",Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^Date.now()).toString(36)),f}function sc(f,b){return f?b?decodeURI(f.replace(/%25/g,"%2525")):decodeURIComponent(f):""}function lc(f,b,A){return typeof f=="string"?(f=encodeURI(f).replace(b,UD),A&&(f=f.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),f):null}function UD(f){return f=f.charCodeAt(0),"%"+(f>>4&15).toString(16)+(f&15).toString(16)}var l2=/[#\/\?@]/g,$D=/[#\?:]/g,WD=/[#\?]/g,GD=/[#\?@]/g,KD=/#/g;function cc(f,b){this.h=this.g=null,this.i=f||null,this.j=!!b}function Gi(f){f.g||(f.g=new Map,f.h=0,f.i&&BD(f.i,function(b,A){f.add(decodeURIComponent(b.replace(/\+/g," ")),A)}))}t=cc.prototype,t.add=function(f,b){Gi(this),this.i=null,f=xs(this,f);var A=this.g.get(f);return A||this.g.set(f,A=[]),A.push(b),this.h+=1,this};function c2(f,b){Gi(f),b=xs(f,b),f.g.has(b)&&(f.i=null,f.h-=f.g.get(b).length,f.g.delete(b))}function d2(f,b){return Gi(f),b=xs(f,b),f.g.has(b)}t.forEach=function(f,b){Gi(this),this.g.forEach(function(A,I){A.forEach(function(D){f.call(b,D,I,this)},this)},this)},t.na=function(){Gi(this);const f=Array.from(this.g.values()),b=Array.from(this.g.keys()),A=[];for(let I=0;I<b.length;I++){const D=f[I];for(let q=0;q<D.length;q++)A.push(b[I])}return A},t.V=function(f){Gi(this);let b=[];if(typeof f=="string")d2(this,f)&&(b=b.concat(this.g.get(xs(this,f))));else{f=Array.from(this.g.values());for(let A=0;A<f.length;A++)b=b.concat(f[A])}return b},t.set=function(f,b){return Gi(this),this.i=null,f=xs(this,f),d2(this,f)&&(this.h-=this.g.get(f).length),this.g.set(f,[b]),this.h+=1,this},t.get=function(f,b){return f?(f=this.V(f),0<f.length?String(f[0]):b):b};function u2(f,b,A){c2(f,b),0<A.length&&(f.i=null,f.g.set(xs(f,b),y(A)),f.h+=A.length)}t.toString=function(){if(this.i)return this.i;if(!this.g)return"";const f=[],b=Array.from(this.g.keys());for(var A=0;A<b.length;A++){var I=b[A];const q=encodeURIComponent(String(I)),W=this.V(I);for(I=0;I<W.length;I++){var D=q;W[I]!==""&&(D+="="+encodeURIComponent(String(W[I]))),f.push(D)}}return this.i=f.join("&")};function xs(f,b){return b=String(b),f.j&&(b=b.toLowerCase()),b}function JD(f,b){b&&!f.j&&(Gi(f),f.i=null,f.g.forEach(function(A,I){var D=I.toLowerCase();I!=D&&(c2(this,I),u2(this,D,A))},f)),f.j=b}function QD(f,b){const A=new rc;if(l.Image){const I=new Image;I.onload=h(Ki,A,"TestLoadImage: loaded",!0,b,I),I.onerror=h(Ki,A,"TestLoadImage: error",!1,b,I),I.onabort=h(Ki,A,"TestLoadImage: abort",!1,b,I),I.ontimeout=h(Ki,A,"TestLoadImage: timeout",!1,b,I),l.setTimeout(function(){I.ontimeout&&I.ontimeout()},1e4),I.src=f}else b(!1)}function XD(f,b){const A=new rc,I=new AbortController,D=setTimeout(()=>{I.abort(),Ki(A,"TestPingServer: timeout",!1,b)},1e4);fetch(f,{signal:I.signal}).then(q=>{clearTimeout(D),q.ok?Ki(A,"TestPingServer: ok",!0,b):Ki(A,"TestPingServer: server error",!1,b)}).catch(()=>{clearTimeout(D),Ki(A,"TestPingServer: error",!1,b)})}function Ki(f,b,A,I,D){try{D&&(D.onload=null,D.onerror=null,D.onabort=null,D.ontimeout=null),I(A)}catch{}}function YD(){this.g=new LD}function ZD(f,b,A){const I=A||"";try{r2(f,function(D,q){let W=D;d(D)&&(W=oy(D)),b.push(I+q+"="+encodeURIComponent(W))})}catch(D){throw b.push(I+"type="+encodeURIComponent("_badmap")),D}}function sp(f){this.l=f.Ub||null,this.j=f.eb||!1}g(sp,sy),sp.prototype.g=function(){return new lp(this.l,this.j)},sp.prototype.i=function(f){return function(){return f}}({});function lp(f,b){Gt.call(this),this.D=f,this.o=b,this.m=void 0,this.status=this.readyState=0,this.responseType=this.responseText=this.response=this.statusText="",this.onreadystatechange=null,this.u=new Headers,this.h=null,this.B="GET",this.A="",this.g=!1,this.v=this.j=this.l=null}g(lp,Gt),t=lp.prototype,t.open=function(f,b){if(this.readyState!=0)throw this.abort(),Error("Error reopening a connection");this.B=f,this.A=b,this.readyState=1,uc(this)},t.send=function(f){if(this.readyState!=1)throw this.abort(),Error("need to call open() first. ");this.g=!0;const b={headers:this.u,method:this.B,credentials:this.m,cache:void 0};f&&(b.body=f),(this.D||l).fetch(new Request(this.A,b)).then(this.Sa.bind(this),this.ga.bind(this))},t.abort=function(){this.response=this.responseText="",this.u=new Headers,this.status=0,this.j&&this.j.cancel("Request was aborted.").catch(()=>{}),1<=this.readyState&&this.g&&this.readyState!=4&&(this.g=!1,dc(this)),this.readyState=0},t.Sa=function(f){if(this.g&&(this.l=f,this.h||(this.status=this.l.status,this.statusText=this.l.statusText,this.h=f.headers,this.readyState=2,uc(this)),this.g&&(this.readyState=3,uc(this),this.g)))if(this.responseType==="arraybuffer")f.arrayBuffer().then(this.Qa.bind(this),this.ga.bind(this));else if(typeof l.ReadableStream<"u"&&"body"in f){if(this.j=f.body.getReader(),this.o){if(this.responseType)throw Error('responseType must be empty for "streamBinaryChunks" mode responses.');this.response=[]}else this.response=this.responseText="",this.v=new TextDecoder;p2(this)}else f.text().then(this.Ra.bind(this),this.ga.bind(this))};function p2(f){f.j.read().then(f.Pa.bind(f)).catch(f.ga.bind(f))}t.Pa=function(f){if(this.g){if(this.o&&f.value)this.response.push(f.value);else if(!this.o){var b=f.value?f.value:new Uint8Array(0);(b=this.v.decode(b,{stream:!f.done}))&&(this.response=this.responseText+=b)}f.done?dc(this):uc(this),this.readyState==3&&p2(this)}},t.Ra=function(f){this.g&&(this.response=this.responseText=f,dc(this))},t.Qa=function(f){this.g&&(this.response=f,dc(this))},t.ga=function(){this.g&&dc(this)};function dc(f){f.readyState=4,f.l=null,f.j=null,f.v=null,uc(f)}t.setRequestHeader=function(f,b){this.u.append(f,b)},t.getResponseHeader=function(f){return this.h&&this.h.get(f.toLowerCase())||""},t.getAllResponseHeaders=function(){if(!this.h)return"";const f=[],b=this.h.entries();for(var A=b.next();!A.done;)A=A.value,f.push(A[0]+": "+A[1]),A=b.next();return f.join(`\r 447`)};function uc(f){f.onreadystatechange&&f.onreadystatechange.call(f)}Object.defineProperty(lp.prototype,"withCredentials",{get:function(){return this.m==="include"},set:function(f){this.m=f?"include":"same-origin"}});function m2(f){let b="";return M(f,function(A,I){b+=I,b+=":",b+=A,b+=`\r 448`}),b}function yy(f,b,A){e:{for(I in A){var I=!1;break e}I=!0}I||(A=m2(A),typeof f=="string"?A!=null&&encodeURIComponent(String(A)):He(f,b,A))}function nt(f){Gt.call(this),this.headers=new Map,this.o=f||null,this.h=!1,this.v=this.g=null,this.D="",this.m=0,this.l="",this.j=this.B=this.u=this.A=!1,this.I=null,this.H="",this.J=!1}g(nt,Gt);var eq=/^https?$/i,tq=["POST","PUT"];t=nt.prototype,t.Ha=function(f){this.J=f},t.ea=function(f,b,A,I){if(this.g)throw Error("[goog.net.XhrIo] Object is active with another request="+this.D+"; newUri="+f);b=b?b.toUpperCase():"GET",this.D=f,this.l="",this.m=0,this.A=!1,this.h=!0,this.g=this.o?this.o.g():dy.g(),this.v=this.o?FS(this.o):FS(dy),this.g.onreadystatechange=m(this.Ea,this);try{this.B=!0,this.g.open(b,String(f),!0),this.B=!1}catch(q){h2(this,q);return}if(f=A||"",A=new Map(this.headers),I)if(Object.getPrototypeOf(I)===Object.prototype)for(var D in I)A.set(D,I[D]);else if(typeof I.keys=="function"&&typeof I.get=="function")for(const q of I.keys())A.set(q,I.get(q));else throw Error("Unknown input type for opt_headers: "+String(I));I=Array.from(A.keys()).find(q=>q.toLowerCase()=="content-type"),D=l.FormData&&f instanceof l.FormData,!(0<=Array.prototype.indexOf.call(tq,b,void 0))||I||D||A.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");for(const[q,W]of A)this.g.setRequestHeader(q,W);this.H&&(this.g.responseType=this.H),"withCredentials"in this.g&&this.g.withCredentials!==this.J&&(this.g.withCredentials=this.J);try{y2(this),this.u=!0,this.g.send(f),this.u=!1}catch(q){h2(this,q)}};function h2(f,b){f.h=!1,f.g&&(f.j=!0,f.g.abort(),f.j=!1),f.l=b,f.m=5,f2(f),cp(f)}function f2(f){f.A||(f.A=!0,la(f,"complete"),la(f,"error"))}t.abort=function(f){this.g&&this.h&&(this.h=!1,this.j=!0,this.g.abort(),this.j=!1,this.m=f||7,la(this,"complete"),la(this,"abort"),cp(this))},t.N=function(){this.g&&(this.h&&(this.h=!1,this.j=!0,this.g.abort(),this.j=!1),cp(this,!0)),nt.aa.N.call(this)},t.Ea=function(){this.s||(this.B||this.u||this.j?g2(this):this.bb())},t.bb=function(){g2(this)};function g2(f){if(f.h&&typeof o<"u"&&(!f.v[1]||ci(f)!=4||f.Z()!=2)){if(f.u&&ci(f)==4)qS(f.Ea,0,f);else if(la(f,"readystatechange"),ci(f)==4){f.h=!1;try{const W=f.Z();e:switch(W){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:var b=!0;break e;default:b=!1}var A;if(!(A=b)){var I;if(I=W===0){var D=String(f.D).match(o2)[1]||null;!D&&l.self&&l.self.location&&(D=l.self.location.protocol.slice(0,-1)),I=!eq.test(D?D.toLowerCase():"")}A=I}if(A)la(f,"complete"),la(f,"success");else{f.m=6;try{var q=2<ci(f)?f.g.statusText:""}catch{q=""}f.l=q+" ["+f.Z()+"]",f2(f)}}finally{cp(f)}}}}function cp(f,b){if(f.g){y2(f);const A=f.g,I=f.v[0]?()=>{}:null;f.g=null,f.v=null,b||la(f,"ready");try{A.onreadystatechange=I}catch{}}}function y2(f){f.I&&(l.clearTimeout(f.I),f.I=null)}t.isActive=function(){return!!this.g};function ci(f){return f.g?f.g.readyState:0}t.Z=function(){try{return 2<ci(this)?this.g.status:-1}catch{return-1}},t.oa=function(){try{return this.g?this.g.responseText:""}catch{return""}},t.Oa=function(f){if(this.g){var b=this.g.responseText;return f&&b.indexOf(f)==0&&(b=b.substring(f.length)),RD(b)}};function x2(f){try{if(!f.g)return null;if("response"in f.g)return f.g.response;switch(f.H){case"":case"text":return f.g.responseText;case"arraybuffer":if("mozResponseArrayBuffer"in f.g)return f.g.mozResponseArrayBuffer}return null}catch{return null}}function aq(f){const b={};f=(f.g&&2<=ci(f)&&f.g.getAllResponseHeaders()||"").split(`\r 449`);for(let I=0;I<f.length;I++){if(w(f[I]))continue;var A=L(f[I]);const D=A[0];if(A=A[1],typeof A!="string")continue;A=A.trim();const q=b[D]||[];b[D]=q,q.push(A)}C(b,function(I){return I.join(", ")})}t.Ba=function(){return this.m},t.Ka=function(){return typeof this.l=="string"?this.l:String(this.l)};function pc(f,b,A){return A&&A.internalChannelParams&&A.internalChannelParams[f]||b}function v2(f){this.Aa=0,this.i=[],this.j=new rc,this.ia=this.qa=this.I=this.W=this.g=this.ya=this.D=this.H=this.m=this.S=this.o=null,this.Ya=this.U=0,this.Va=pc("failFast",!1,f),this.F=this.C=this.u=this.s=this.l=null,this.X=!0,this.za=this.T=-1,this.Y=this.v=this.B=0,this.Ta=pc("baseRetryDelayMs",5e3,f),this.cb=pc("retryDelaySeedMs",1e4,f),this.Wa=pc("forwardChannelMaxRetries",2,f),this.wa=pc("forwardChannelRequestTimeoutMs",2e4,f),this.pa=f&&f.xmlHttpFactory||void 0,this.Xa=f&&f.Tb||void 0,this.Ca=f&&f.useFetchStreams||!1,this.L=void 0,this.J=f&&f.supportsCrossDomainXhr||!1,this.K="",this.h=new e2(f&&f.concurrentRequestLimit),this.Da=new YD,this.P=f&&f.fastHandshake||!1,this.O=f&&f.encodeInitMessageHeaders||!1,this.P&&this.O&&(this.O=!1),this.Ua=f&&f.Rb||!1,f&&f.xa&&this.j.xa(),f&&f.forceLongPolling&&(this.X=!1),this.ba=!this.P&&this.X&&f&&f.detectBufferingProxy||!1,this.ja=void 0,f&&f.longPollingTimeout&&0<f.longPollingTimeout&&(this.ja=f.longPollingTimeout),this.ca=void 0,this.R=0,this.M=!1,this.ka=this.A=null}t=v2.prototype,t.la=8,t.G=1,t.connect=function(f,b,A,I){ca(0),this.W=f,this.H=b||{},A&&I!==void 0&&(this.H.OSID=A,this.H.OAID=I),this.F=this.X,this.I=j2(this,null,this.W),up(this)};function xy(f){if(b2(f),f.G==3){var b=f.U++,A=li(f.I);if(He(A,"SID",f.K),He(A,"RID",b),He(A,"TYPE","terminate"),mc(f,A),b=new Wi(f,f.j,b),b.L=2,b.v=op(li(A)),A=!1,l.navigator&&l.navigator.sendBeacon)try{A=l.navigator.sendBeacon(b.v.toString(),"")}catch{}!A&&l.Image&&(new Image().src=b.v,A=!0),A||(b.g=T2(b.j,null),b.g.ea(b.v)),b.F=Date.now(),np(b)}C2(f)}function dp(f){f.g&&(by(f),f.g.cancel(),f.g=null)}function b2(f){dp(f),f.u&&(l.clearTimeout(f.u),f.u=null),pp(f),f.h.cancel(),f.s&&(typeof f.s=="number"&&l.clearTimeout(f.s),f.s=null)}function up(f){if(!t2(f.h)&&!f.s){f.s=!0;var b=f.Ga;ae||re(),F||(ae(),F=!0),Z.add(b,f),f.B=0}}function nq(f,b){return a2(f.h)>=f.h.j-(f.s?1:0)?!1:f.s?(f.i=b.D.concat(f.i),!0):f.G==1||f.G==2||f.B>=(f.Va?0:f.Wa)?!1:(f.s=ic(m(f.Ga,f,b),E2(f,f.B)),f.B++,!0)}t.Ga=function(f){if(this.s)if(this.s=null,this.G==1){if(!f){this.U=Math.floor(1e5*Math.random()),f=this.U++;const D=new Wi(this,this.j,f);let q=this.o;if(this.S&&(q?(q=E(q),N(q,this.S)):q=this.S),this.m!==null||this.O||(D.H=q,q=null),this.P)e:{for(var b=0,A=0;A<this.i.length;A++){t:{var I=this.i[A];if("__data__"in I.map&&(I=I.map.__data__,typeof I=="string")){I=I.length;break t}I=void 0}if(I===void 0)break;if(b+=I,4096<b){b=A;break e}if(b===4096||A===this.i.length-1){b=A+1;break e}}b=1e3}else b=1e3;b=k2(this,D,b),A=li(this.I),He(A,"RID",f),He(A,"CVER",22),this.D&&He(A,"X-HTTP-Session-Id",this.D),mc(this,A),q&&(this.O?b="headers="+encodeURIComponent(String(m2(q)))+"&"+b:this.m&&yy(A,this.m,q)),gy(this.h,D),this.Ua&&He(A,"TYPE","init"),this.P?(He(A,"$req",b),He(A,"SID","null"),D.T=!0,py(D,A,null)):py(D,A,b),this.G=2}}else this.G==3&&(f?w2(this,f):this.i.length==0||t2(this.h)||w2(this))};function w2(f,b){var A;b?A=b.l:A=f.U++;const I=li(f.I);He(I,"SID",f.K),He(I,"RID",A),He(I,"AID",f.T),mc(f,I),f.m&&f.o&&yy(I,f.m,f.o),A=new Wi(f,f.j,A,f.B+1),f.m===null&&(A.H=f.o),b&&(f.i=b.D.concat(f.i)),b=k2(f,A,1e3),A.I=Math.round(.5*f.wa)+Math.round(.5*f.wa*Math.random()),gy(f.h,A),py(A,I,b)}function mc(f,b){f.H&&M(f.H,function(A,I){He(b,I,A)}),f.l&&r2({},function(A,I){He(b,I,A)})}function k2(f,b,A){A=Math.min(f.i.length,A);var I=f.l?m(f.l.Na,f.l,f):null;e:{var D=f.i;let q=-1;for(;;){const W=["count="+A];q==-1?0<A?(q=D[0].g,W.push("ofs="+q)):q=0:W.push("ofs="+q);let De=!0;for(let Lt=0;Lt<A;Lt++){let Ce=D[Lt].g;const Kt=D[Lt].map;if(Ce-=q,0>Ce)q=Math.max(0,D[Lt].g-100),De=!1;else try{ZD(Kt,W,"req"+Ce+"_")}catch{I&&I(Kt)}}if(De){I=W.join("&");break e}}}return f=f.i.splice(0,A),b.D=f,I}function S2(f){if(!f.g&&!f.u){f.Y=1;var b=f.Fa;ae||re(),F||(ae(),F=!0),Z.add(b,f),f.v=0}}function vy(f){return f.g||f.u||3<=f.v?!1:(f.Y++,f.u=ic(m(f.Fa,f),E2(f,f.v)),f.v++,!0)}t.Fa=function(){if(this.u=null,_2(this),this.ba&&!(this.M||this.g==null||0>=this.R)){var f=2*this.R;this.j.info("BP detection timer enabled: "+f),this.A=ic(m(this.ab,this),f)}},t.ab=function(){this.A&&(this.A=null,this.j.info("BP detection timeout reached."),this.j.info("Buffering proxy detected and switch to long-polling!"),this.F=!1,this.M=!0,ca(10),dp(this),_2(this))};function by(f){f.A!=null&&(l.clearTimeout(f.A),f.A=null)}function _2(f){f.g=new Wi(f,f.j,"rpc",f.Y),f.m===null&&(f.g.H=f.o),f.g.O=0;var b=li(f.qa);He(b,"RID","rpc"),He(b,"SID",f.K),He(b,"AID",f.T),He(b,"CI",f.F?"0":"1"),!f.F&&f.ja&&He(b,"TO",f.ja),He(b,"TYPE","xmlhttp"),mc(f,b),f.m&&f.o&&yy(b,f.m,f.o),f.L&&(f.g.I=f.L);var A=f.g;f=f.ia,A.L=1,A.v=op(li(b)),A.m=null,A.P=!0,XS(A,f)}t.Za=function(){this.C!=null&&(this.C=null,dp(this),vy(this),ca(19))};function pp(f){f.C!=null&&(l.clearTimeout(f.C),f.C=null)}function A2(f,b){var A=null;if(f.g==b){pp(f),by(f),f.g=null;var I=2}else if(fy(f.h,b))A=b.D,n2(f.h,b),I=1;else return;if(f.G!=0){if(b.o)if(I==1){A=b.m?b.m.length:0,b=Date.now()-b.F;var D=f.B;I=ep(),la(I,new GS(I,A)),up(f)}else S2(f);else if(D=b.s,D==3||D==0&&0<b.X||!(I==1&&nq(f,b)||I==2&&vy(f)))switch(A&&0<A.length&&(b=f.h,b.i=b.i.concat(A)),D){case 1:so(f,5);break;case 4:so(f,10);break;case 3:so(f,6);break;default:so(f,2)}}}function E2(f,b){let A=f.Ta+Math.floor(Math.random()*f.cb);return f.isActive()||(A*=2),A*b}function so(f,b){if(f.j.info("Error code "+b),b==2){var A=m(f.fb,f),I=f.Xa;const D=!I;I=new oo(I||"//www.google.com/images/cleardot.gif"),l.location&&l.location.protocol=="http"||ip(I,"https"),op(I),D?QD(I.toString(),A):XD(I.toString(),A)}else ca(2);f.G=0,f.l&&f.l.sa(b),C2(f),b2(f)}t.fb=function(f){f?(this.j.info("Successfully pinged google.com"),ca(2)):(this.j.info("Failed to ping google.com"),ca(1))};function C2(f){if(f.G=0,f.ka=[],f.l){const b=i2(f.h);(b.length!=0||f.i.length!=0)&&(x(f.ka,b),x(f.ka,f.i),f.h.i.length=0,y(f.i),f.i.length=0),f.l.ra()}}function j2(f,b,A){var I=A instanceof oo?li(A):new oo(A);if(I.g!="")b&&(I.g=b+"."+I.g),rp(I,I.s);else{var D=l.location;I=D.protocol,b=b?b+"."+D.hostname:D.hostname,D=+D.port;var q=new oo(null);I&&ip(q,I),b&&(q.g=b),D&&rp(q,D),A&&(q.l=A),I=q}return A=f.D,b=f.ya,A&&b&&He(I,A,b),He(I,"VER",f.la),mc(f,I),I}function T2(f,b,A){if(b&&!f.J)throw Error("Can't create secondary domain capable XhrIo object.");return b=f.Ca&&!f.pa?new nt(new sp({eb:A})):new nt(f.pa),b.Ha(f.J),b}t.isActive=function(){return!!this.l&&this.l.isActive(this)};function N2(){}t=N2.prototype,t.ua=function(){},t.ta=function(){},t.sa=function(){},t.ra=function(){},t.isActive=function(){return!0},t.Na=function(){};function mp(){}mp.prototype.g=function(f,b){return new Ma(f,b)};function Ma(f,b){Gt.call(this),this.g=new v2(b),this.l=f,this.h=b&&b.messageUrlParams||null,f=b&&b.messageHeaders||null,b&&b.clientProtocolHeaderRequired&&(f?f["X-Client-Protocol"]="webchannel":f={"X-Client-Protocol":"webchannel"}),this.g.o=f,f=b&&b.initMessageHeaders||null,b&&b.messageContentType&&(f?f["X-WebChannel-Content-Type"]=b.messageContentType:f={"X-WebChannel-Content-Type":b.messageContentType}),b&&b.va&&(f?f["X-WebChannel-Client-Profile"]=b.va:f={"X-WebChannel-Client-Profile":b.va}),this.g.S=f,(f=b&&b.Sb)&&!w(f)&&(this.g.m=f),this.v=b&&b.supportsCrossDomainXhr||!1,this.u=b&&b.sendRawJson||!1,(b=b&&b.httpSessionIdParam)&&!w(b)&&(this.g.D=b,f=this.h,f!==null&&b in f&&(f=this.h,b in f&&delete f[b])),this.j=new vs(this)}g(Ma,Gt),Ma.prototype.m=function(){this.g.l=this.j,this.v&&(this.g.J=!0),this.g.connect(this.l,this.h||void 0)},Ma.prototype.close=function(){xy(this.g)},Ma.prototype.o=function(f){var b=this.g;if(typeof f=="string"){var A={};A.__data__=f,f=A}else this.u&&(A={},A.__data__=oy(f),f=A);b.i.push(new VD(b.Ya++,f)),b.G==3&&up(b)},Ma.prototype.N=function(){this.g.l=null,delete this.j,xy(this.g),delete this.g,Ma.aa.N.call(this)};function I2(f){ly.call(this),f.__headers__&&(this.headers=f.__headers__,this.statusCode=f.__status__,delete f.__headers__,delete f.__status__);var b=f.__sm__;if(b){e:{for(const A in b){f=A;break e}f=void 0}(this.i=f)&&(f=this.i,b=b!==null&&f in b?b[f]:void 0),this.data=b}else this.data=f}g(I2,ly);function P2(){cy.call(this),this.status=1}g(P2,cy);function vs(f){this.g=f}g(vs,N2),vs.prototype.ua=function(){la(this.g,"a")},vs.prototype.ta=function(f){la(this.g,new I2(f))},vs.prototype.sa=function(f){la(this.g,new P2)},vs.prototype.ra=function(){la(this.g,"b")},mp.prototype.createWebChannel=mp.prototype.g,Ma.prototype.send=Ma.prototype.o,Ma.prototype.open=Ma.prototype.m,Ma.prototype.close=Ma.prototype.close,YR=function(){return new mp},XR=function(){return ep()},QR=io,Yv={mb:0,pb:1,qb:2,Jb:3,Ob:4,Lb:5,Mb:6,Kb:7,Ib:8,Nb:9,PROXY:10,NOPROXY:11,Gb:12,Cb:13,Db:14,Bb:15,Eb:16,Fb:17,ib:18,hb:19,jb:20},tp.NO_ERROR=0,tp.TIMEOUT=8,tp.HTTP_ERROR=6,Rm=tp,KS.COMPLETE="complete",JR=KS,BS.EventType=ac,ac.OPEN="a",ac.CLOSE="b",ac.ERROR="c",ac.MESSAGE="d",Gt.prototype.listen=Gt.prototype.K,Vc=BS,nt.prototype.listenOnce=nt.prototype.L,nt.prototype.getLastError=nt.prototype.Ka,nt.prototype.getLastErrorCode=nt.prototype.Ba,nt.prototype.getStatus=nt.prototype.Z,nt.prototype.getResponseJson=nt.prototype.Oa,nt.prototype.getResponseText=nt.prototype.oa,nt.prototype.send=nt.prototype.ea,nt.prototype.setWithCredentials=nt.prototype.Ha,KR=nt}).apply(typeof Vp<"u"?Vp:typeof self<"u"?self:typeof window<"u"?window:{});const QE="@firebase/firestore";/** 450 * @license 451 * Copyright 2017 Google LLC 452 * 453 * Licensed under the Apache License, Version 2.0 (the "License");
454 * you may not use this file except in compliance with the License. 455 * You may obtain a copy of the License at 456 * 457 * http://www.apache.org/licenses/LICENSE-2.0 458 * 459 * Unless required by applicable law or agreed to in writing, software 460 * distributed under the License is distributed on an "AS IS" BASIS, 461 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 462 * See the License for the specific language governing permissions and 463 * limitations under the License. 464 */class ea{constructor(e){this.uid=e}isAuthenticated(){return this.uid!=null}toKey(){return this.isAuthenticated()?"uid:"+this.uid:"anonymous-user"}isEqual(e){return e.uid===this.uid}}ea.UNAUTHENTICATED=new ea(null),ea.GOOGLE_CREDENTIALS=new ea("google-credentials-uid"),ea.FIRST_PARTY=new ea("first-party-uid"),ea.MOCK_USER=new ea("mock-user");/** 465 * @license 466 * Copyright 2017 Google LLC 467 * 468 * Licensed under the Apache License, Version 2.0 (the "License"); 469 * you may not use this file except in compliance with the License. 470 * You may obtain a copy of the License at 471 * 472 * http://www.apache.org/licenses/LICENSE-2.0 473 * 474 * Unless required by applicable law or agreed to in writing, software 475 * distributed under the License is distributed on an "AS IS" BASIS, 476 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 477 * See the License for the specific language governing permissions and 478 * limitations under the License. 479 */let Gl="10.14.0";/** 480 * @license 481 * Copyright 2017 Google LLC 482 * 483 * Licensed under the Apache License, Version 2.0 (the "License"); 484 * you may not use this file except in compliance with the License. 485 * You may obtain a copy of the License at 486 * 487 * http://www.apache.org/licenses/LICENSE-2.0 488 * 489 * Unless required by applicable law or agreed to in writing, software 490 * distributed under the License is distributed on an "AS IS" BASIS, 491 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 492 * See the License for the specific language governing permissions and 493 * limitations under the License. 494 */const Jo=new pg("@firebase/firestore");function jc(){return Jo.logLevel}function Y(t,...e){if(Jo.logLevel<=_e.DEBUG){const a=e.map(Hw);Jo.debug(`Firestore (${Gl}): ${t}`,...a)}}function Vi(t,...e){if(Jo.logLevel<=_e.ERROR){const a=e.map(Hw);Jo.error(`Firestore (${Gl}): ${t}`,...a)}}function wl(t,...e){if(Jo.logLevel<=_e.WARN){const a=e.map(Hw);Jo.warn(`Firestore (${Gl}): ${t}`,...a)}}function Hw(t){if(typeof t=="string")return t;try{/** 495* @license 496* Copyright 2020 Google LLC 497* 498* Licensed under the Apache License, Version 2.0 (the "License"); 499* you may not use this file except in compliance with the License. 500* You may obtain a copy of the License at 501* 502* http://www.apache.org/licenses/LICENSE-2.0 503* 504* Unless required by applicable law or agreed to in writing, software 505* distributed under the License is distributed on an "AS IS" BASIS, 506* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 507* See the License for the specific language governing permissions and 508* limitations under the License. 509*/return function(a){return JSON.stringify(a)}(t)}catch{return t}}/** 510 * @license 511 * Copyright 2017 Google LLC 512 * 513 * Licensed under the Apache License, Version 2.0 (the "License"); 514 * you may not use this file except in compliance with the License. 515 * You may obtain a copy of the License at 516 * 517 * http://www.apache.org/licenses/LICENSE-2.0 518 * 519 * Unless required by applicable law or agreed to in writing, software 520 * distributed under the License is distributed on an "AS IS" BASIS, 521 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 522 * See the License for the specific language governing permissions and 523 * limitations under the License. 524 */function pe(t="Unexpected state"){const e=`FIRESTORE (${Gl}) INTERNAL ASSERTION FAILED: `+t;throw Vi(e),new Error(e)}function Oe(t,e){t||pe()}function he(t,e){return t}/** 525 * @license 526 * Copyright 2017 Google LLC 527 * 528 * Licensed under the Apache License, Version 2.0 (the "License"); 529 * you may not use this file except in compliance with the License. 530 * You may obtain a copy of the License at 531 * 532 * http://www.apache.org/licenses/LICENSE-2.0 533 * 534 * Unless required by applicable law or agreed to in writing, softw
534are 535 * distributed under the License is distributed on an "AS IS" BASIS, 536 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 537 * See the License for the specific language governing permissions and 538 * limitations under the License. 539 */const z={OK:"ok",CANCELLED:"cancelled",UNKNOWN:"unknown",INVALID_ARGUMENT:"invalid-argument",DEADLINE_EXCEEDED:"deadline-exceeded",NOT_FOUND:"not-found",ALREADY_EXISTS:"already-exists",PERMISSION_DENIED:"permission-denied",UNAUTHENTICATED:"unauthenticated",RESOURCE_EXHAUSTED:"resource-exhausted",FAILED_PRECONDITION:"failed-precondition",ABORTED:"aborted",OUT_OF_RANGE:"out-of-range",UNIMPLEMENTED:"unimplemented",INTERNAL:"internal",UNAVAILABLE:"unavailable",DATA_LOSS:"data-loss"};class X extends gn{constructor(e,a){super(e,a),this.code=e,this.message=a,this.toString=()=>`${this.name}: [code=${this.code}]: ${this.message}`}}/** 540 * @license 541 * Copyright 2017 Google LLC 542 * 543 * Licensed under the Apache License, Version 2.0 (the "License"); 544 * you may not use this file except in compliance with the License. 545 * You may obtain a copy of the License at 546 * 547 * http://www.apache.org/licenses/LICENSE-2.0 548 * 549 * Unless required by applicable law or agreed to in writing, software 550 * distributed under the License is distributed on an "AS IS" BASIS, 551 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 552 * See the License for the specific language governing permissions and 553 * limitations under the License. 554 */class Ti{constructor(){this.promise=new Promise((e,a)=>{this.resolve=e,this.reject=a})}}/** 555 * @license 556 * Copyright 2017 Google LLC 557 * 558 * Licensed under the Apache License, Version 2.0 (the "License"); 559 * you may not use this file except in compliance with the License. 560 * You may obtain a copy of the License at 561 * 562 * http://www.apache.org/licenses/LICENSE-2.0 563 * 564 * Unless required by applicable law or agreed to in writing, software 565 * distributed under the License is distributed on an "AS IS" BASIS, 566 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 567 * See the License for the specific language governing permissions and 568 * limitations under the License. 569 */class ZR{constructor(e,a){this.user=a,this.type="OAuth",this.headers=new Map,this.headers.set("Authorization",`Bearer ${e}`)}}class kW{getToken(){return Promise.resolve(null)}invalidateToken(){}start(e,a){e.enqueueRetryable(()=>a(ea.UNAUTHENTICATED))}shutdown(){}}class SW{constructor(e){this.token=e,this.changeListener=null}getToken(){return Promise.resolve(this.token)}invalidateToken(){}start(e,a){this.changeListener=a,e.enqueueRetryable(()=>a(this.token.user))}shutdown(){this.changeListener=null}}class _W{constructor(e){this.t=e,this.currentUser=ea.UNAUTHENTICATED,this.i=0,this.forceRefresh=!1,this.auth=null}start(e,a){Oe(this.o===void 0);let n=this.i;const i=c=>this.i!==n?(n=this.i,a(c)):Promise.resolve();let r=new Ti;this.o=()=>{this.i++,this.currentUser=this.u(),r.resolve(),r=new Ti,e.enqueueRetryable(()=>i(this.currentUser))};const o=()=>{const c=r;e.enqueueRetryable(async()=>{await c.promise,await i(this.currentUser)})},l=c=>{Y("FirebaseAuthCredentialsProvider","Auth detected"),this.auth=c,this.o&&(this.auth.addAuthTokenListener(this.o),o())};this.t.onInit(c=>l(c)),setTimeout(()=>{if(!this.auth){const c=this.t.getImmediate({optional:!0});c?l(c):(Y("FirebaseAuthCredentialsProvider","Auth not yet detected"),r.resolve(),r=new Ti)}},0),o()}getToken(){const e=this.i,a=this.forceRefresh;return this.forceRefresh=!1,this.auth?this.auth.getToken(a).then(n=>this.i!==e?(Y("FirebaseAuthCredentialsProvider","getToken aborted due to token change."),this.getToken()):n?(Oe(typeof n.accessToken=="string"),new ZR(n.accessToken,this.currentUser)):null):Promise.resolve(null)}invalidateToken(){this.forceRefresh=!0}shutdown(){this.auth&&this.o&&this.auth.removeAuthTokenListener(this.o),this.o=void 0}u(){const e=this.auth&&this.auth.getUid();return Oe(e===null||typeof e=="string"),new ea(e)}}class AW{constructor(e,a,n){this.l=e,this.h=a,this.P=n,this.type="FirstParty",this.user=ea.FIRST_PARTY,this.I=new Map}T(){return this.P?this.P():null}get headers(){this.I.set("X-Goog-AuthUser",this.l);const e=this.T();return e&&this.I.set("Authorization",e),this.h&&this.I.set("X-Goog-Iam-Authorization-Token",this.h),this.I}}class EW{constructor(e,a,n){this.l=e,this.h=a,this.P=n}getToken(){return Promise.resolve(new AW(this.l,this.h,this.P))}start(e,a){e.enqueueRetryable(()=>a(ea.FIRST_PARTY))}shutdown(){}invalidateToken(){}}class CW{constructor(e){this.value=e,this.type="AppCheck",this.headers=new Map,e&&e.length>0&&this.headers.set("x-firebase-appcheck",this.value)}}class jW{constructor(e){this.A=e,this.forceRefresh=!1,this.appCheck=null,this.R=null}start(e,a){Oe(this.o===void 0);const n=r=>{r.error!=null&&Y("FirebaseAppCheckTokenProvider",`Error getting App Check token; using placeholder token instead. Error: ${r.error.message}`);const o=r.token!==this.R;return this.R=r.token,Y("FirebaseAppCheckTokenProvider",`Received ${o?"new":"existing"} token.`),o?a(r.token):Promise.resolve()};this.o=r=>{e.enqueueRetryable(()=>n(r))};const i=r=>{Y("FirebaseAppCheckTokenProvider","AppCheck detected"),this.appCheck=r,this.o&&this.appCheck.addTokenListener(this.o)};this.A.onInit(r=>i(r)),setTimeout(()=>{if(!this.appCheck){const r=this.A.getImmediate({optional:!0});r?i(r):Y("FirebaseAppCheckTokenProvider","AppCheck not yet detected")}},0)}getToken(){const e=this.forceRefresh;return this.forceRefresh=!1,this.appCheck?this.appCheck.getToken(e).then(a=>a?(Oe(typeof a.token=="string"),this.R=a.token,new CW(a.token)):null):Promise.resolve(null)}invalidateToken(){this.forceRefresh=!0}shutdown(){this.appCheck&&this.o&&this.appCheck.removeTokenListener(this.o),this.o=void 0}}/** 570 * @license 571 * Copyright 2020 Google LLC 572 * 573 * Licensed under the Apache License, Version 2.0 (the "License");
574 * you may not use this file except in compliance with the License. 575 * You may obtain a copy of the License at 576 * 577 * http://www.apache.org/licenses/LICENSE-2.0 578 * 579 * Unless required by applicable law or agreed to in writing, software 580 * distributed under the License is distributed on an "AS IS" BASIS, 581 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 582 * See the License for the specific language governing permissions and 583 * limitations under the License. 584 */function TW(t){const e=typeof self<"u"&&(self.crypto||self.msCrypto),a=new Uint8Array(t);if(e&&typeof e.getRandomValues=="function")e.getRandomValues(a);else for(let n=0;n<t;n++)a[n]=Math.floor(256*Math.random());return a}/** 585 * @license 586 * Copyright 2017 Google LLC 587 * 588 * Licensed under the Apache License, Version 2.0 (the "License"); 589 * you may not use this file except in compliance with the License. 590 * You may obtain a copy of the License at 591 * 592 * http://www.apache.org/licenses/LICENSE-2.0 593 * 594 * Unless required by applicable law or agreed to in writing, software 595 * distributed under the License is distributed on an "AS IS" BASIS, 596 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 597 * See the License for the specific language governing permissions and 598 * limitations under the License. 599 */class eL{static newId(){const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",a=Math.floor(256/e.length)*e.length;let n="";for(;n.length<20;){const i=TW(40);for(let r=0;r<i.length;++r)n.length<20&&i[r]<a&&(n+=e.charAt(i[r]%e.length))}return n}}function je(t,e){return t<e?-1:t>e?1:0}function kl(t,e,a){return t.length===e.length&&t.every((n,i)=>a(n,e[i]))}/** 600 * @license 601 * Copyright 2017 Google LLC 602 * 603 * Licensed under the Apache License, Version 2.0 (the "License"); 604 * you may not use this file except in compliance with the License. 605 * You may obtain a copy of the License at 606 * 607 * http://www.apache.org/licenses/LICENSE-2.0 608 * 609 * Unless required by applicable law or agreed to in writing, software 610 * distributed under the License is distributed on an "AS IS" BASIS, 611 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 612 * See the License for the specific language governing permissions and 613 * limitations under the License. 614 */class xt{constructor(e,a){if(this.seconds=e,this.nanoseconds=a,a<0)throw new X(z.INVALID_ARGUMENT,"Timestamp nanoseconds out of range: "+a);if(a>=1e9)throw new X(z.INVALID_ARGUMENT,"Timestamp nanoseconds out of range: "+a);if(e<-62135596800)throw new X(z.INVALID_ARGUMENT,"Timestamp seconds out of range: "+e);if(e>=253402300800)throw new X(z.INVALID_ARGUMENT,"Timestamp seconds out of range: "+e)}static now(){return xt.fromMillis(Date.now())}static fromDate(e){return xt.fromMillis(e.getTime())}static fromMillis(e){const a=Math.floor(e/1e3),n=Math.floor(1e6*(e-1e3*a));return new xt(a,n)}toDate(){return new Date(this.toMillis())}toMillis(){return 1e3*this.seconds+this.nanoseconds/1e6}_compareTo(e){return this.seconds===e.seconds?je(this.nanoseconds,e.nanoseconds):je(this.seconds,e.seconds)}isEqual(e){return e.seconds===this.seconds&&e.nanoseconds===this.nanoseconds}toString(){return"Timestamp(seconds="+this.seconds+", nanoseconds="+this.nanoseconds+")"}toJSON(){return{seconds:this.seconds,nanoseconds:this.nanoseconds}}valueOf(){const e=this.seconds- -62135596800;return String(e).padStart(12,"0")+"."+String(this.nanoseconds).padStart(9,"0")}}/** 615 * @license 616 * Copyright 2017 Google LLC 617 * 618 * Licensed under the Apache License, Version 2.0 (the "License"); 619 * you may not use this file except in compliance with the License. 620 * You may obtain a copy of the License at 621 * 622 * http://www.apache.org/licenses/LICENSE-2.0 623 * 624 * Unless required by applicable law or agreed to in writing, software 625 * distributed under the License is distributed on an "AS IS" BASIS, 626 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 627 * See the License for the specific language governing permissions and 628 * limitations under the License. 629 */class me{constructor(e){this.timestamp=e}static fromTimestamp(e){return new me(e)}static min(){return new me(new xt(0,0))}static max(){return new me(new xt(253402300799,999999999))}compareTo(e){return this.timestamp._compareTo(e.timestamp)}isEqual(e){return this.timestamp.isEqual(e.timestamp)}toMicroseconds(){return 1e6*this.timestamp.seconds+this.timestamp.nanoseconds/1e3}toString(){return"SnapshotVersion("+this.timestamp.toString()+")"}toTimestamp(){return this.timestamp}}/** 630 * @license 631 * Copyright 2017 Google LLC 632 * 633 * Licensed under the Apache License, Version 2.0 (the "License");
634 * you may not use this file except in compliance with the License. 635 * You may obtain a copy of the License at 636 * 637 * http://www.apache.org/licenses/LICENSE-2.0 638 * 639 * Unless required by applicable law or agreed to in writing, software 640 * distributed under the License is distributed on an "AS IS" BASIS, 641 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 642 * See the License for the specific language governing permissions and 643 * limitations under the License. 644 */class au{constructor(e,a,n){a===void 0?a=0:a>e.length&&pe(),n===void 0?n=e.length-a:n>e.length-a&&pe(),this.segments=e,this.offset=a,this.len=n}get length(){return this.len}isEqual(e){return au.comparator(this,e)===0}child(e){const a=this.segments.slice(this.offset,this.limit());return e instanceof au?e.forEach(n=>{a.push(n)}):a.push(e),this.construct(a)}limit(){return this.offset+this.length}popFirst(e){return e=e===void 0?1:e,this.construct(this.segments,this.offset+e,this.length-e)}popLast(){return this.construct(this.segments,this.offset,this.length-1)}firstSegment(){return this.segments[this.offset]}lastSegment(){return this.get(this.length-1)}get(e){return this.segments[this.offset+e]}isEmpty(){return this.length===0}isPrefixOf(e){if(e.length<this.length)return!1;for(let a=0;a<this.length;a++)if(this.get(a)!==e.get(a))return!1;return!0}isImmediateParentOf(e){if(this.length+1!==e.length)return!1;for(let a=0;a<this.length;a++)if(this.get(a)!==e.get(a))return!1;return!0}forEach(e){for(let a=this.offset,n=this.limit();a<n;a++)e(this.segments[a])}toArray(){return this.segments.slice(this.offset,this.limit())}static comparator(e,a){const n=Math.min(e.length,a.length);for(let i=0;i<n;i++){const r=e.get(i),o=a.get(i);if(r<o)return-1;if(r>o)return 1}return e.length<a.length?-1:e.length>a.length?1:0}}class Ue extends au{construct(e,a,n){return new Ue(e,a,n)}canonicalString(){return this.toArray().join("/")}toString(){return this.canonicalString()}toUriEncodedString(){return this.toArray().map(encodeURIComponent).join("/")}static fromString(...e){const a=[];for(const n of e){if(n.indexOf("//")>=0)throw new X(z.INVALID_ARGUMENT,`Invalid segment (${n}). Paths must not contain // in them.`);a.push(...n.split("/").filter(i=>i.length>0))}return new Ue(a)}static emptyPath(){return new Ue([])}}const NW=/^[_a-zA-Z][_a-zA-Z0-9]*$/;class Ht extends au{construct(e,a,n){return new Ht(e,a,n)}static isValidIdentifier(e){return NW.test(e)}canonicalString(){return this.toArray().map(e=>(e=e.replace(/\\/g,"\\\\").replace(/`/g,"\\`"),Ht.isValidIdentifier(e)||(e="`"+e+"`"),e)).join(".")}toString(){return this.canonicalString()}isKeyField(){return this.length===1&&this.get(0)==="__name__"}static keyField(){return new Ht(["__name__"])}static fromServerFormat(e){const a=[];let n="",i=0;const r=()=>{if(n.length===0)throw new X(z.INVALID_ARGUMENT,`Invalid field path (${e}). Paths must not be empty, begin with '.', end with '.', or contain '..'`);a.push(n),n=""};let o=!1;for(;i<e.length;){const l=e[i];if(l==="\\"){if(i+1===e.length)throw new X(z.INVALID_ARGUMENT,"Path has trailing escape character: "+e);const c=e[i+1];if(c!=="\\"&&c!=="."&&c!=="`")throw new X(z.INVALID_ARGUMENT,"Path has invalid escape sequence: "+e);n+=c,i+=2}else l==="`"?(o=!o,i++):l!=="."||o?(n+=l,i++):(r(),i++)}if(r(),o)throw new X(z.INVALID_ARGUMENT,"Unterminated ` in path: "+e);return new Ht(a)}static emptyPath(){return new Ht([])}}/** 645 * @license 646 * Copyright 2017 Google LLC 647 * 648 * Licensed under the Apache License, Version 2.0 (the "License"); 649 * you may not use this file except in compliance with the License. 650 * You may obtain a copy of the License at 651 * 652 * http://www.apache.org/licenses/LICENSE-2.0 653 * 654 * Unless required by applicable law or agreed to in writing, software 655 * distributed under the License is distributed on an "AS IS" BASIS, 656 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 657 * See the License for the specific language governing permissions and 658 * limitations under the License. 659 */class oe{constructor(e){this.path=e}static fromPath(e){return new oe(Ue.fromString(e))}static fromName(e){return new oe(Ue.fromString(e).popFirst(5))}static empty(){return new oe(Ue.emptyPath())}get collectionGroup(){return this.path.popLast().lastSegment()}hasCollectionId(e){return this.path.length>=2&&this.path.get(this.path.length-2)===e}getCollectionGroup(){return this.path.get(this.path.length-2)}getCollectionPath(){return this.path.popLast()}isEqual(e){return e!==null&&Ue.comparator(this.path,e.path)===0}toString(){return this.path.toString()}static comparator(e,a){return Ue.comparator(e.path,a.path)}static isDocumentKey(e){return e.length%2==0}static fromSegments(e){return new oe(new Ue(e.slice()))}}function IW(t,e){const a=t.toTimestamp().seconds,n=t.toTimestamp().nanoseconds+1,i=me.fromTimestamp(n===1e9?new xt(a+1,0):new xt(a,n));return new Hr(i,oe.empty(),e)}function PW(t){return new Hr(t.readTime,t.key,-1)}class Hr{constructor(e,a,n){this.readTime=e,this.documentKey=a,this.largestBatchId=n}static min(){return new Hr(me.min(),oe.empty(),-1)}static max(){return new Hr(me.max(),oe.empty(),-1)}}function RW(t,e){let a=t.readTime.compareTo(e.readTime);return a!==0?a:(a=oe.comparator(t.documentKey,e.documentKey),a!==0?a:je(t.largestBatchId,e.largestBatchId))}/** 660 * @license 661 * Copyright 2020 Google LLC 662 * 663 * Licensed under the Apache License, Version 2.0 (the "License");
664 * you may not use this file except in compliance with the License. 665 * You may obtain a copy of the License at 666 * 667 * http://www.apache.org/licenses/LICENSE-2.0 668 * 669 * Unless required by applicable law or agreed to in writing, software 670 * distributed under the License is distributed on an "AS IS" BASIS, 671 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 672 * See the License for the specific language governing permissions and 673 * limitations under the License. 674 */const LW="The current tab is not in the required state to perform this operation. It might be necessary to refresh the browser tab.";class OW{constructor(){this.onCommittedListeners=[]}addOnCommittedListener(e){this.onCommittedListeners.push(e)}raiseOnCommittedEvent(){this.onCommittedListeners.forEach(e=>e())}}/** 675 * @license 676 * Copyright 2017 Google LLC 677 * 678 * Licensed under the Apache License, Version 2.0 (the "License"); 679 * you may not use this file except in compliance with the License. 680 * You may obtain a copy of the License at 681 * 682 * http://www.apache.org/licenses/LICENSE-2.0 683 * 684 * Unless required by applicable law or agreed to in writing, software 685 * distributed under the License is distributed on an "AS IS" BASIS, 686 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 687 * See the License for the specific language governing permissions and 688 * limitations under the License. 689 */async function Lu(t){if(t.code!==z.FAILED_PRECONDITION||t.message!==LW)throw t;Y("LocalStore","Unexpectedly lost primary lease")}/** 690 * @license 691 * Copyright 2017 Google LLC 692 * 693 * Licensed under the Apache License, Version 2.0 (the "License"); 694 * you may not use this file except in compliance with the License. 695 * You may obtain a copy of the License at 696 * 697 * http://www.apache.org/licenses/LICENSE-2.0 698 * 699 * Unless required by applicable law or agreed to in writing, software 700 * distributed under the License is distributed on an "AS IS" BASIS, 701 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 702 * See the License for the specific language governing permissions and 703 * limitations under the License. 704 */class H{constructor(e){this.nextCallback=null,this.catchCallback=null,this.result=void 0,this.error=void 0,this.isDone=!1,this.callbackAttached=!1,e(a=>{this.isDone=!0,this.result=a,this.nextCallback&&this.nextCallback(a)},a=>{this.isDone=!0,this.error=a,this.catchCallback&&this.catchCallback(a)})}catch(e){return this.next(void 0,e)}next(e,a){return this.callbackAttached&&pe(),this.callbackAttached=!0,this.isDone?this.error?this.wrapFailure(a,this.error):this.wrapSuccess(e,this.result):new H((n,i)=>{this.nextCallback=r=>{this.wrapSuccess(e,r).next(n,i)},this.catchCallback=r=>{this.wrapFailure(a,r).next(n,i)}})}toPromise(){return new Promise((e,a)=>{this.next(e,a)})}wrapUserFunction(e){try{const a=e();return a instanceof H?a:H.resolve(a)}catch(a){return H.reject(a)}}wrapSuccess(e,a){return e?this.wrapUserFunction(()=>e(a)):H.resolve(a)}wrapFailure(e,a){return e?this.wrapUserFunction(()=>e(a)):H.reject(a)}static resolve(e){return new H((a,n)=>{a(e)})}static reject(e){return new H((a,n)=>{n(e)})}static waitFor(e){return new H((a,n)=>{let i=0,r=0,o=!1;e.forEach(l=>{++i,l.next(()=>{++r,o&&r===i&&a()},c=>n(c))}),o=!0,r===i&&a()})}static or(e){let a=H.resolve(!1);for(const n of e)a=a.next(i=>i?H.resolve(i):n());return a}static forEach(e,a){const n=[];return e.forEach((i,r)=>{n.push(a.call(this,i,r))}),this.waitFor(n)}static mapArray(e,a){return new H((n,i)=>{const r=e.length,o=new Array(r);let l=0;for(let c=0;c<r;c++){const d=c;a(e[d]).next(u=>{o[d]=u,++l,l===r&&n(o)},u=>i(u))}})}static doWhile(e,a){return new H((n,i)=>{const r=()=>{e()===!0?a().next(()=>{r()},i):n()};r()})}}function MW(t){const e=t.match(/Android ([\d.]+)/i),a=e?e[1].split(".").slice(0,2).join("."):"-1";return Number(a)}function Ou(t){return t.name==="IndexedDbTransactionError"}/** 705 * @license 706 * Copyright 2018 Google LLC 707 * 708 * Licensed under the Apache License, Version 2.0 (the "License"); 709 * you may not use this file except in compliance with the License. 710 * You may obtain a copy of the License at 711 * 712 * http://www.apache.org/licenses/LICENSE-2.0 713 * 714 * Unless required by applicable law or agreed to in writing, softw
714are 715 * distributed under the License is distributed on an "AS IS" BASIS, 716 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 717 * See the License for the specific language governing permissions and 718 * limitations under the License. 719 */class Fw{constructor(e,a){this.previousValue=e,a&&(a.sequenceNumberHandler=n=>this.ie(n),this.se=n=>a.writeSequenceNumber(n))}ie(e){return this.previousValue=Math.max(e,this.previousValue),this.previousValue}next(){const e=++this.previousValue;return this.se&&this.se(e),e}}Fw.oe=-1;function hg(t){return t==null}function Nh(t){return t===0&&1/t==-1/0}function DW(t){return typeof t=="number"&&Number.isInteger(t)&&!Nh(t)&&t<=Number.MAX_SAFE_INTEGER&&t>=Number.MIN_SAFE_INTEGER}/** 720 * @license 721 * Copyright 2017 Google LLC 722 * 723 * Licensed under the Apache License, Version 2.0 (the "License"); 724 * you may not use this file except in compliance with the License. 725 * You may obtain a copy of the License at 726 * 727 * http://www.apache.org/licenses/LICENSE-2.0 728 * 729 * Unless required by applicable law or agreed to in writing, software 730 * distributed under the License is distributed on an "AS IS" BASIS, 731 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 732 * See the License for the specific language governing permissions and 733 * limitations under the License. 734 */function XE(t){let e=0;for(const a in t)Object.prototype.hasOwnProperty.call(t,a)&&e++;return e}function ps(t,e){for(const a in t)Object.prototype.hasOwnProperty.call(t,a)&&e(a,t[a])}function tL(t){for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e))return!1;return!0}/** 735 * @license 736 * Copyright 2017 Google LLC 737 * 738 * Licensed under the Apache License, Version 2.0 (the "License"); 739 * you may not use this file except in compliance with the License. 740 * You may obtain a copy of the License at 741 * 742 * http://www.apache.org/licenses/LICENSE-2.0 743 * 744 * Unless required by applicable law or agreed to in writing, software 745 * distributed under the License is distributed on an "AS IS" BASIS, 746 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 747 * See the License for the specific language governing permissions and 748 * limitations under the License. 749 */class tt{constructor(e,a){this.comparator=e,this.root=a||qt.EMPTY}insert(e,a){return new tt(this.comparator,this.root.insert(e,a,this.comparator).copy(null,null,qt.BLACK,null,null))}remove(e){return new tt(this.comparator,this.root.remove(e,this.comparator).copy(null,null,qt.BLACK,null,null))}get(e){let a=this.root;for(;!a.isEmpty();){const n=this.comparator(e,a.key);if(n===0)return a.value;n<0?a=a.left:n>0&&(a=a.right)}return null}indexOf(e){let a=0,n=this.root;for(;!n.isEmpty();){const i=this.comparator(e,n.key);if(i===0)return a+n.left.size;i<0?n=n.left:(a+=n.left.size+1,n=n.right)}return-1}isEmpty(){return this.root.isEmpty()}get size(){return this.root.size}minKey(){return this.root.minKey()}maxKey(){return this.root.maxKey()}inorderTraversal(e){return this.root.inorderTraversal(e)}forEach(e){this.inorderTraversal((a,n)=>(e(a,n),!1))}toString(){const e=[];return this.inorderTraversal((a,n)=>(e.push(`${a}:${n}`),!1)),`{${e.join(", ")}}`}reverseTraversal(e){return this.root.reverseTraversal(e)}getIterator(){return new Hp(this.root,null,this.comparator,!1)}getIteratorFrom(e){return new Hp(this.root,e,this.comparator,!1)}getReverseIterator(){return new Hp(this.root,null,this.comparator,!0)}getReverseIteratorFrom(e){return new Hp(this.root,e,this.comparator,!0)}}class Hp{constructor(e,a,n,i){this.isReverse=i,this.nodeStack=[];let r=1;for(;!e.isEmpty();)if(r=a?n(e.key,a):1,a&&i&&(r*=-1),r<0)e=this.isReverse?e.left:e.right;else{if(r===0){this.nodeStack.push(e);break}this.nodeStack.push(e),e=this.isReverse?e.right:e.left}}getNext(){let e=this.nodeStack.pop();const a={key:e.key,value:e.value};if(this.isReverse)for(e=e.left;!e.isEmpty();)this.nodeStack.push(e),e=e.right;else for(e=e.right;!e.isEmpty();)this.nodeStack.push(e),e=e.left;return a}hasNext(){return this.nodeStack.length>0}peek(){if(this.nodeStack.length===0)return null;const e=this.nodeStack[this.nodeStack.length-1];return{key:e.key,value:e.value}}}class qt{constructor(e,a,n,i,r){this.key=e,this.value=a,this.color=n??qt.RED,this.left=i??qt.EMPTY,this.right=r??qt.EMPTY,this.size=this.left.size+1+this.right.size}
vendor: 5,036 bytes, lines 749-764
749copy(e,a,n,i,r){return new qt(e??this.key,a??this.value,n??this.color,i??this.left,r??this.right)}isEmpty(){return!1}inorderTraversal(e){return this.left.inorderTraversal(e)||e(this.key,this.value)||this.right.inorderTraversal(e)}reverseTraversal(e){return this.right.reverseTraversal(e)||e(this.key,this.value)||this.left.reverseTraversal(e)}min(){return this.left.isEmpty()?this:this.left.min()}minKey(){return this.min().key}maxKey(){return this.right.isEmpty()?this.key:this.right.maxKey()}insert(e,a,n){let i=this;const r=n(e,i.key);return i=r<0?i.copy(null,null,null,i.left.insert(e,a,n),null):r===0?i.copy(null,a,null,null,null):i.copy(null,null,null,null,i.right.insert(e,a,n)),i.fixUp()}removeMin(){if(this.left.isEmpty())return qt.EMPTY;let e=this;return e.left.isRed()||e.left.left.isRed()||(e=e.moveRedLeft()),e=e.copy(null,null,null,e.left.removeMin(),null),e.fixUp()}remove(e,a){let n,i=this;if(a(e,i.key)<0)i.left.isEmpty()||i.left.isRed()||i.left.left.isRed()||(i=i.moveRedLeft()),i=i.copy(null,null,null,i.left.remove(e,a),null);else{if(i.left.isRed()&&(i=i.rotateRight()),i.right.isEmpty()||i.right.isRed()||i.right.left.isRed()||(i=i.moveRedRight()),a(e,i.key)===0){if(i.right.isEmpty())return qt.EMPTY;n=i.right.min(),i=i.copy(n.key,n.value,null,null,i.right.removeMin())}i=i.copy(null,null,null,null,i.right.remove(e,a))}return i.fixUp()}isRed(){return this.color}fixUp(){let e=this;return e.right.isRed()&&!e.left.isRed()&&(e=e.rotateLeft()),e.left.isRed()&&e.left.left.isRed()&&(e=e.rotateRight()),e.left.isRed()&&e.right.isRed()&&(e=e.colorFlip()),e}moveRedLeft(){let e=this.colorFlip();return e.right.left.isRed()&&(e=e.copy(null,null,null,null,e.right.rotateRight()),e=e.rotateLeft(),e=e.colorFlip()),e}moveRedRight(){let e=this.colorFlip();return e.left.left.isRed()&&(e=e.rotateRight(),e=e.colorFlip()),e}rotateLeft(){const e=this.copy(null,null,qt.RED,null,this.right.left);return this.right.copy(null,null,this.color,e,null)}rotateRight(){const e=this.copy(null,null,qt.RED,this.left.right,null);return this.left.copy(null,null,this.color,null,e)}colorFlip(){const e=this.left.copy(null,null,!this.left.color,null,null),a=this.right.copy(null,null,!this.right.color,null,null);return this.copy(null,null,!this.color,e,a)}checkMaxDepth(){const e=this.check();return Math.pow(2,e)<=this.size+1}check(){if(this.isRed()&&this.left.isRed()||this.right.isRed())throw pe();const e=this.left.check();if(e!==this.right.check())throw pe();return e+(this.isRed()?0:1)}}qt.EMPTY=null,qt.RED=!0,qt.BLACK=!1;qt.EMPTY=new class{constructor(){this.size=0}get key(){throw pe()}get value(){throw pe()}get color(){throw pe()}get left(){throw pe()}get right(){throw pe()}copy(e,a,n,i,r){return this}insert(e,a,n){return new qt(e,a)}remove(e,a){return this}isEmpty(){return!0}inorderTraversal(e){return!1}reverseTraversal(e){return!1}minKey(){return null}maxKey(){return null}isRed(){return!1}checkMaxDepth(){return!0}check(){return 0}};/** 750 * @license 751 * Copyright 2017 Google LLC 752 * 753 * Licensed under the Apache License, Version 2.0 (the "License"); 754 * you may not use this file except in compliance with the License. 755 * You may obtain a copy of the License at 756 * 757 * http://www.apache.org/licenses/LICENSE-2.0 758 * 759 * Unless required by applicable law or agreed to in writing, software 760 * distributed under the License is distributed on an "AS IS" BASIS, 761 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 762 * See the License for the specific language governing permissions and 763 * limitations under the License. 764 */class Bt{constructor(e){this.comparator=e,this.data=new tt(this.comparator)}has(e){return this.data.get(e)!==null}first(){return this.data.minKey()}last(){return this.data.maxKey()}get size(){return this.data.size}indexOf(e){return this.data.indexOf(e)}forEach(e){this.data.inorderTraversal((a,n)=>(e(a),!1))}forEachInRange(e,a){const n=this.data.getIteratorFrom(e[0]);for(;n.hasNext();){const i=n.getNext();if(this.comparator(i.key,e[1])>=0)return;a(i.key)}}forEachWhile(e,a){let n;for(n=a!==void 0?this.data.getIteratorFrom(a):this.data.getIterator();n.hasNext();)if(!e(n.getNext().key))return}firstAfterOrEqual(e){const a=this.data.getIteratorFrom(e);return a.hasNext()?a.getNext().key:null}getIterator(){return new YE(this.data.getIterator())}getIteratorFrom(e){return new YE(this.data.getIteratorFrom(e))}add(e){return this.copy(this.data.remove(e).insert(e,!0))}delete(e){return this.has(e)?this.copy(this.data.remove(e)):this}isEmpty(){return this.data.isEmpty()}unionWith(e){let a=this;return a.size<e.size&&(a=e,e=this),e.forEach(n=>{a=a.add(n)}),a}isEqual(e){if(!(e instanceof Bt)||this.size!==e.size)return!1;const a=this.data.getIterator(),n=e.data.getIterator();for(;a.hasNext();){const i=a.getNext().key,r=n.getNext().key;if(this.comparator(i,r)!==0)return!1}return!0}toArray(){const e=[];return this.forEach(a=>{e.push(a)}),e}toString(){const e=[];return this.forEach(a=>e.push(a)),"SortedSet("+e.toString()+")"}copy(e){const a=new Bt(this.comparator);return a.data=e,a}}
764class YE{constructor(e){this.iter=e}getNext(){return this.iter.getNext().key}hasNext(){return this.iter.hasNext()}}/** 765 * @license 766 * Copyright 2020 Google LLC 767 * 768 * Licensed under the Apache License, Version 2.0 (the "License"); 769 * you may not use this file except in compliance with the License. 770 * You may obtain a copy of the License at 771 * 772 * http://www.apache.org/licenses/LICENSE-2.0 773 * 774 * Unless required by applicable law or agreed to in writing, software 775 * distributed under the License is distributed on an "AS IS" BASIS, 776 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 777 * See the License for the specific language governing permissions and 778 * limitations under the License. 779 */class Va{constructor(e){this.fields=e,e.sort(Ht.comparator)}static empty(){return new Va([])}unionWith(e){let a=new Bt(Ht.comparator);for(const n of this.fields)a=a.add(n);for(const n of e)a=a.add(n);return new Va(a.toArray())}covers(e){for(const a of this.fields)if(a.isPrefixOf(e))return!0;return!1}isEqual(e){return kl(this.fields,e.fields,(a,n)=>a.isEqual(n))}}/** 780 * @license 781 * Copyright 2023 Google LLC 782 * 783 * Licensed under the Apache License, Version 2.0 (the "License"); 784 * you may not use this file except in compliance with the License. 785 * You may obtain a copy of the License at 786 * 787 * http://www.apache.org/licenses/LICENSE-2.0 788 * 789 * Unless required by applicable law or agreed to in writing, software 790 * distributed under the License is distributed on an "AS IS" BASIS, 791 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 792 * See the License for the specific language governing permissions and 793 * limitations under the License. 794 */class aL extends Error{constructor(){super(...arguments),this.name="Base64DecodeError"}}/** 795 * @license 796 * Copyright 2020 Google LLC 797 * 798 * Licensed under the Apache License, Version 2.0 (the "License"); 799 * you may not use this file except in compliance with the License. 800 * You may obtain a copy of the License at 801 * 802 * http://www.apache.org/licenses/LICENSE-2.0 803 * 804 * Unless required by applicable law or agreed to in writing, software 805 * distributed under the License is distributed on an "AS IS" BASIS, 806 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 807 * See the License for the specific language governing permissions and 808 * limitations under the License. 809 */class $t{constructor(e){this.binaryString=e}static fromBase64String(e){const a=function(i){try{return atob(i)}catch(r){throw typeof DOMException<"u"&&r instanceof DOMException?new aL("Invalid base64 string: "+r):r}}(e);return new $t(a)}static fromUint8Array(e){const a=function(i){let r="";for(let o=0;o<i.length;++o)r+=String.fromCharCode(i[o]);return r}(e);return new $t(a)}[Symbol.iterator](){let e=0;return{next:()=>e<this.binaryString.length?{value:this.binaryString.charCodeAt(e++),done:!1}:{value:void 0,done:!0}}}toBase64(){return function(a){return btoa(a)}(this.binaryString)}toUint8Array(){return function(a){const n=new Uint8Array(a.length);for(let i=0;i<a.length;i++)n[i]=a.charCodeAt(i);return n}(this.binaryString)}approximateByteSize(){return 2*this.binaryString.length}compareTo(e){return je(this.binaryString,e.binaryString)}isEqual(e){return this.binaryString===e.binaryString}}$t.EMPTY_BYTE_STRING=new $t("");const qW=new RegExp(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.(\d+))?Z$/);function Fr(t){if(Oe(!!t),typeof t=="string"){let e=0;const a=qW.exec(t);if(Oe(!!a),a[1]){let i=a[1];i=(i+"000000000").substr(0,9),e=Number(i)}const n=new Date(t);return{seconds:Math.floor(n.getTime()/1e3),nanos:e}}return{seconds:ut(t.seconds),nanos:ut(t.nanos)}}function ut(t){return typeof t=="number"?t:typeof t=="string"?Number(t):0}function Qo(t){return typeof t=="string"?$t.fromBase64String(t):$t.fromUint8Array(t)}/** 810 * @license 811 * Copyright 2020 Google LLC 812 * 813 * Licensed under the Apache License, Version 2.0 (the "License"); 814 * you may not use this file except in compliance with the License. 815 * You may obtain a copy of the License at 816 * 817 * http://www.apache.org/licenses/LICENSE-2.0 818 * 819 * Unless required by applicable law or agreed to in writing, softw
819are 820 * distributed under the License is distributed on an "AS IS" BASIS, 821 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 822 * See the License for the specific language governing permissions and 823 * limitations under the License. 824 */function Bw(t){var e,a;return((a=(((e=t==null?void 0:t.mapValue)===null||e===void 0?void 0:e.fields)||{}).__type__)===null||a===void 0?void 0:a.stringValue)==="server_timestamp"}function Uw(t){const e=t.mapValue.fields.__previous_value__;return Bw(e)?Uw(e):e}function nu(t){const e=Fr(t.mapValue.fields.__local_write_time__.timestampValue);return new xt(e.seconds,e.nanos)}/** 825 * @license 826 * Copyright 2017 Google LLC 827 * 828 * Licensed under the Apache License, Version 2.0 (the "License"); 829 * you may not use this file except in compliance with the License. 830 * You may obtain a copy of the License at 831 * 832 * http://www.apache.org/licenses/LICENSE-2.0 833 * 834 * Unless required by applicable law or agreed to in writing, software 835 * distributed under the License is distributed on an "AS IS" BASIS, 836 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 837 * See the License for the specific language governing permissions and 838 * limitations under the License. 839 */class zW{constructor(e,a,n,i,r,o,l,c,d){this.databaseId=e,this.appId=a,this.persistenceKey=n,this.host=i,this.ssl=r,this.forceLongPolling=o,this.autoDetectLongPolling=l,this.longPollingOptions=c,this.useFetchStreams=d}}class iu{constructor(e,a){this.projectId=e,this.database=a||"(default)"}static empty(){return new iu("","")}get isDefaultDatabase(){return this.database==="(default)"}isEqual(e){return e instanceof iu&&e.projectId===this.projectId&&e.database===this.database}}/** 840 * @license 841 * Copyright 2020 Google LLC 842 * 843 * Licensed under the Apache License, Version 2.0 (the "License"); 844 * you may not use this file except in compliance with the License. 845 * You may obtain a copy of the License at 846 * 847 * http://www.apache.org/licenses/LICENSE-2.0 848 * 849 * Unless required by applicable law or agreed to in writing, software 850 * distributed under the License is distributed on an "AS IS" BASIS, 851 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 852 * See the License for the specific language governing permissions and 853 * limitations under the License. 854 */const Fp={mapValue:{}};function Xo(t){return"nullValue"in t?0:"booleanValue"in t?1:"integerValue"in t||"doubleValue"in t?2:"timestampValue"in t?3:"stringValue"in t?5:"bytesValue"in t?6:"referenceValue"in t?7:"geoPointValue"in t?8:"arrayValue"in t?9:"mapValue"in t?Bw(t)?4:HW(t)?9007199254740991:VW(t)?10:11:pe()}function ni(t,e){if(t===e)return!0;const a=Xo(t);if(a!==Xo(e))return!1;switch(a){case 0:case 9007199254740991:return!0;case 1:return t.booleanValue===e.booleanValue;case 4:return nu(t).isEqual(nu(e));case 3:return function(i,r){if(typeof i.timestampValue=="string"&&typeof r.timestampValue=="string"&&i.timestampValue.length===r.timestampValue.length)return i.timestampValue===r.timestampValue;const o=Fr(i.timestampValue),l=Fr(r.timestampValue);return o.seconds===l.seconds&&o.nanos===l.nanos}(t,e);case 5:return t.stringValue===e.stringValue;case 6:return function(i,r){return Qo(i.bytesValue).isEqual(Qo(r.bytesValue))}(t,e);case 7:return t.referenceValue===e.referenceValue;case 8:return function(i,r){return ut(i.geoPointValue.latitude)===ut(r.geoPointValue.latitude)&&ut(i.geoPointValue.longitude)===ut(r.geoPointValue.longitude)}(t,e);case 2:return function(i,r){if("integerValue"in i&&"integerValue"in r)return ut(i.integerValue)===ut(r.integerValue);if("doubleValue"in i&&"doubleValue"in r){const o=ut(i.doubleValue),l=ut(r.doubleValue);return o===l?Nh(o)===Nh(l):isNaN(o)&&isNaN(l)}return!1}(t,e);case 9:return kl(t.arrayValue.values||[],e.arrayValue.values||[],ni);case 10:case 11:return function(i,r){const o=i.mapValue.fields||{},l=r.mapValue.fields||{};if(XE(o)!==XE(l))return!1;for(const c in o)if(o.hasOwnProperty(c)&&(l[c]===void 0||!ni(o[c],l[c])))return!1;return!0}(t,e);default:return pe()}}function ru(t,e){return(t.values||[]).find(a=>ni(a,e))!==void 0}function Sl(t,e){if(t===e)return 0;const a=Xo(t),n=Xo(e);if(a!==n)return je(a,n);switch(a){case 0:case 9007199254740991:return 0;case 1:return je(t.booleanValue,e.booleanValue);case 2:return function(r,o){const l=ut(r.integerValue||r.doubleValue),c=ut(o.integerValue||o.doubleValue);return l<c?-1:l>c?1:l===c?0:isNaN(l)?isNaN(c)?0:-1:1}(t,e);
854case 3:return ZE(t.timestampValue,e.timestampValue);case 4:return ZE(nu(t),nu(e));case 5:return je(t.stringValue,e.stringValue);case 6:return function(r,o){const l=Qo(r),c=Qo(o);return l.compareTo(c)}(t.bytesValue,e.bytesValue);case 7:return function(r,o){const l=r.split("/"),c=o.split("/");for(let d=0;d<l.length&&d<c.length;d++){const u=je(l[d],c[d]);if(u!==0)return u}return je(l.length,c.length)}(t.referenceValue,e.referenceValue);case 8:return function(r,o){const l=je(ut(r.latitude),ut(o.latitude));return l!==0?l:je(ut(r.longitude),ut(o.longitude))}(t.geoPointValue,e.geoPointValue);case 9:return eC(t.arrayValue,e.arrayValue);case 10:return function(r,o){var l,c,d,u;const p=r.fields||{},m=o.fields||{},h=(l=p.value)===null||l===void 0?void 0:l.arrayValue,g=(c=m.value)===null||c===void 0?void 0:c.arrayValue,y=je(((d=h==null?void 0:h.values)===null||d===void 0?void 0:d.length)||0,((u=g==null?void 0:g.values)===null||u===void 0?void 0:u.length)||0);return y!==0?y:eC(h,g)}(t.mapValue,e.mapValue);case 11:return function(r,o){if(r===Fp.mapValue&&o===Fp.mapValue)return 0;if(r===Fp.mapValue)return 1;if(o===Fp.mapValue)return-1;const l=r.fields||{},c=Object.keys(l),d=o.fields||{},u=Object.keys(d);c.sort(),u.sort();for(let p=0;p<c.length&&p<u.length;++p){const m=je(c[p],u[p]);if(m!==0)return m;const h=Sl(l[c[p]],d[u[p]]);if(h!==0)return h}return je(c.length,u.length)}(t.mapValue,e.mapValue);default:throw pe()}}function ZE(t,e){if(typeof t=="string"&&typeof e=="string"&&t.length===e.length)return je(t,e);const a=Fr(t),n=Fr(e),i=je(a.seconds,n.seconds);return i!==0?i:je(a.nanos,n.nanos)}function eC(t,e){const a=t.values||[],n=e.values||[];for(let i=0;i<a.length&&i<n.length;++i){const r=Sl(a[i],n[i]);if(r)return r}return je(a.length,n.length)}function _l(t){return Zv(t)}function Zv(t){return"nullValue"in t?"null":"booleanValue"in t?""+t.booleanValue:"integerValue"in t?""+t.integerValue:"doubleValue"in t?""+t.doubleValue:"timestampValue"in t?function(a){const n=Fr(a);return`time(${n.seconds},${n.nanos})`}(t.timestampValue):"stringValue"in t?t.stringValue:"bytesValue"in t?function(a){return Qo(a).toBase64()}(t.bytesValue):"referenceValue"in t?function(a){return oe.fromName(a).toString()}(t.referenceValue):"geoPointValue"in t?function(a){return`geo(${a.latitude},${a.longitude})`}(t.geoPointValue):"arrayValue"in t?function(a){let n="[",i=!0;for(const r of a.values||[])i?i=!1:n+=",",n+=Zv(r);return n+"]"}(t.arrayValue):"mapValue"in t?function(a){const n=Object.keys(a.fields||{}).sort();let i="{",r=!0;for(const o of n)r?r=!1:i+=",",i+=`${o}:${Zv(a.fields[o])}`;return i+"}"}(t.mapValue):pe()}function tC(t,e){return{referenceValue:`projects/${t.projectId}/databases/${t.database}/documents/${e.path.canonicalString()}`}}function eb(t){return!!t&&"integerValue"in t}function $w(t){return!!t&&"arrayValue"in t}function aC(t){return!!t&&"nullValue"in t}function nC(t){return!!t&&"doubleValue"in t&&isNaN(Number(t.doubleValue))}function Lm(t){return!!t&&"mapValue"in t}function VW(t){var e,a;return((a=(((e=t==null?void 0:t.mapValue)===null||e===void 0?void 0:e.fields)||{}).__type__)===null||a===void 0?void 0:a.stringValue)==="__vector__"}function ud(t){if(t.geoPointValue)return{geoPointValue:Object.assign({},t.geoPointValue)};if(t.timestampValue&&typeof t.timestampValue=="object")return{timestampValue:Object.assign({},t.timestampValue)};if(t.mapValue){const e={mapValue:{fields:{}}};return ps(t.mapValue.fields,(a,n)=>e.mapValue.fields[a]=ud(n)),e}if(t.arrayValue){const e={arrayValue:{values:[]}};for(let a=0;a<(t.arrayValue.values||[]).length;++a)e.arrayValue.values[a]=ud(t.arrayValue.values[a]);return e}return Object.assign({},t)}function HW(t){return(((t.mapValue||{}).fields||{}).__type__||{}).stringValue==="__max__"}/** 855 * @license 856 * Copyright 2017 Google LLC 857 * 858 * Licensed under the Apache License, Version 2.0 (the "License"); 859 * you may not use this file except in compliance with the License. 860 * You may obtain a copy of the License at 861 * 862 * http://www.apache.org/licenses/LICENSE-2.0 863 * 864 * Unless required by applicable law or agreed to in writing, softw
864are 865 * distributed under the License is distributed on an "AS IS" BASIS, 866 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 867 * See the License for the specific language governing permissions and 868 * limitations under the License. 869 */class _a{constructor(e){this.value=e}static empty(){return new _a({mapValue:{}})}field(e){if(e.isEmpty())return this.value;{let a=this.value;for(let n=0;n<e.length-1;++n)if(a=(a.mapValue.fields||{})[e.get(n)],!Lm(a))return null;return a=(a.mapValue.fields||{})[e.lastSegment()],a||null}}set(e,a){this.getFieldsMap(e.popLast())[e.lastSegment()]=ud(a)}setAll(e){let a=Ht.emptyPath(),n={},i=[];e.forEach((o,l)=>{if(!a.isImmediateParentOf(l)){const c=this.getFieldsMap(a);this.applyChanges(c,n,i),n={},i=[],a=l.popLast()}o?n[l.lastSegment()]=ud(o):i.push(l.lastSegment())});const r=this.getFieldsMap(a);this.applyChanges(r,n,i)}delete(e){const a=this.field(e.popLast());Lm(a)&&a.mapValue.fields&&delete a.mapValue.fields[e.lastSegment()]}isEqual(e){return ni(this.value,e.value)}getFieldsMap(e){let a=this.value;a.mapValue.fields||(a.mapValue={fields:{}});for(let n=0;n<e.length;++n){let i=a.mapValue.fields[e.get(n)];Lm(i)&&i.mapValue.fields||(i={mapValue:{fields:{}}},a.mapValue.fields[e.get(n)]=i),a=i}return a.mapValue.fields}applyChanges(e,a,n){ps(a,(i,r)=>e[i]=r);for(const i of n)delete e[i]}clone(){return new _a(ud(this.value))}}function nL(t){const e=[];return ps(t.fields,(a,n)=>{const i=new Ht([a]);if(Lm(n)){const r=nL(n.mapValue).fields;
vendor: 4,180 bytes, lines 869-909
869if(r.length===0)e.push(i);else for(const o of r)e.push(i.child(o))}else e.push(i)}),new Va(e)}/** 870 * @license 871 * Copyright 2017 Google LLC 872 * 873 * Licensed under the Apache License, Version 2.0 (the "License"); 874 * you may not use this file except in compliance with the License. 875 * You may obtain a copy of the License at 876 * 877 * http://www.apache.org/licenses/LICENSE-2.0 878 * 879 * Unless required by applicable law or agreed to in writing, software 880 * distributed under the License is distributed on an "AS IS" BASIS, 881 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 882 * See the License for the specific language governing permissions and 883 * limitations under the License. 884 */class aa{constructor(e,a,n,i,r,o,l){this.key=e,this.documentType=a,this.version=n,this.readTime=i,this.createTime=r,this.data=o,this.documentState=l}static newInvalidDocument(e){return new aa(e,0,me.min(),me.min(),me.min(),_a.empty(),0)}static newFoundDocument(e,a,n,i){return new aa(e,1,a,me.min(),n,i,0)}static newNoDocument(e,a){return new aa(e,2,a,me.min(),me.min(),_a.empty(),0)}static newUnknownDocument(e,a){return new aa(e,3,a,me.min(),me.min(),_a.empty(),2)}convertToFoundDocument(e,a){return!this.createTime.isEqual(me.min())||this.documentType!==2&&this.documentType!==0||(this.createTime=e),this.version=e,this.documentType=1,this.data=a,this.documentState=0,this}convertToNoDocument(e){return this.version=e,this.documentType=2,this.data=_a.empty(),this.documentState=0,this}convertToUnknownDocument(e){return this.version=e,this.documentType=3,this.data=_a.empty(),this.documentState=2,this}setHasCommittedMutations(){return this.documentState=2,this}setHasLocalMutations(){return this.documentState=1,this.version=me.min(),this}setReadTime(e){return this.readTime=e,this}get hasLocalMutations(){return this.documentState===1}get hasCommittedMutations(){return this.documentState===2}get hasPendingWrites(){return this.hasLocalMutations||this.hasCommittedMutations}isValidDocument(){return this.documentType!==0}isFoundDocument(){return this.documentType===1}isNoDocument(){return this.documentType===2}isUnknownDocument(){return this.documentType===3}isEqual(e){return e instanceof aa&&this.key.isEqual(e.key)&&this.version.isEqual(e.version)&&this.documentType===e.documentType&&this.documentState===e.documentState&&this.data.isEqual(e.data)}mutableCopy(){return new aa(this.key,this.documentType,this.version,this.readTime,this.createTime,this.data.clone(),this.documentState)}toString(){return`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, {createTime: ${this.createTime}}), {documentType: ${this.documentType}}), {documentState: ${this.documentState}})`}}/** 885 * @license 886 * Copyright 2022 Google LLC 887 * 888 * Licensed under the Apache License, Version 2.0 (the "License"); 889 * you may not use this file except in compliance with the License. 890 * You may obtain a copy of the License at 891 * 892 * http://www.apache.org/licenses/LICENSE-2.0 893 * 894 * Unless required by applicable law or agreed to in writing, software 895 * distributed under the License is distributed on an "AS IS" BASIS, 896 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 897 * See the License for the specific language governing permissions and 898 * limitations under the License. 899 */class Ih{constructor(e,a){this.position=e,this.inclusive=a}}function iC(t,e,a){let n=0;for(let i=0;i<t.position.length;i++){const r=e[i],o=t.position[i];if(r.field.isKeyField()?n=oe.comparator(oe.fromName(o.referenceValue),a.key):n=Sl(o,a.data.field(r.field)),r.dir==="desc"&&(n*=-1),n!==0)break}return n}function rC(t,e){if(t===null)return e===null;if(e===null||t.inclusive!==e.inclusive||t.position.length!==e.position.length)return!1;for(let a=0;a<t.position.length;a++)if(!ni(t.position[a],e.position[a]))return!1;return!0}/** 900 * @license 901 * Copyright 2022 Google LLC 902 * 903 * Licensed under the Apache License, Version 2.0 (the "License"); 904 * you may not use this file except in compliance with the License. 905 * You may obtain a copy of the License at 906 * 907 * http://www.apache.org/licenses/LICENSE-2.0 908 * 909 * Unless required by applicable law or agreed to in writing, softw
909are 910 * distributed under the License is distributed on an "AS IS" BASIS, 911 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 912 * See the License for the specific language governing permissions and 913 * limitations under the License. 914 */class Ph{constructor(e,a="asc"){this.field=e,this.dir=a}}function FW(t,e){return t.dir===e.dir&&t.field.isEqual(e.field)}/** 915 * @license 916 * Copyright 2022 Google LLC 917 * 918 * Licensed under the Apache License, Version 2.0 (the "License"); 919 * you may not use this file except in compliance with the License. 920 * You may obtain a copy of the License at 921 * 922 * http://www.apache.org/licenses/LICENSE-2.0 923 * 924 * Unless required by applicable law or agreed to in writing, software 925 * distributed under the License is distributed on an "AS IS" BASIS, 926 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 927 * See the License for the specific language governing permissions and 928 * limitations under the License. 929 */class iL{}class gt extends iL{constructor(e,a,n){super(),this.field=e,this.op=a,this.value=n}static create(e,a,n){return e.isKeyField()?a==="in"||a==="not-in"?this.createKeyFieldInFilter(e,a,n):new UW(e,a,n):a==="array-contains"?new GW(e,n):a==="in"?new KW(e,n):a==="not-in"?new JW(e,n):a==="array-contains-any"?new QW(e,n):new gt(e,a,n)}static createKeyFieldInFilter(e,a,n){return a==="in"?new $W(e,n):new WW(e,n)}matches(e){const a=e.data.field(this.field);return this.op==="!="?a!==null&&this.matchesComparison(Sl(a,this.value)):a!==null&&Xo(this.value)===Xo(a)&&this.matchesComparison(Sl(a,this.value))}matchesComparison(e){switch(this.op){case"<":return e<0;case"<=":return e<=0;case"==":return e===0;case"!=":return e!==0;case">":return e>0;case">=":return e>=0;default:return pe()}}isInequality(){return["<","<=",">",">=","!=","not-in"].indexOf(this.op)>=0}getFlattenedFilters(){return[this]}getFilters(){return[this]}}class qn extends iL{constructor(e,a){super(),this.filters=e,this.op=a,this.ae=null}static create(e,a){return new qn(e,a)}matches(e){return rL(this)?this.filters.find(a=>!a.matches(e))===void 0:this.filters.find(a=>a.matches(e))!==void 0}getFlattenedFilters(){return this.ae!==null||(this.ae=this.filters.reduce((e,a)=>e.concat(a.getFlattenedFilters()),[])),this.ae}getFilters(){return Object.assign([],this.filters)}}function rL(t){return t.op==="and"}function oL(t){return BW(t)&&rL(t)}function BW(t){for(const e of t.filters)if(e instanceof qn)return!1;return!0}function tb(t){if(t instanceof gt)return t.field.canonicalString()+t.op.toString()+_l(t.value);if(oL(t))return t.filters.map(e=>tb(e)).join(",");{const e=t.filters.map(a=>tb(a)).join(",");return`${t.op}(${e})`}}function sL(t,e){return t instanceof gt?function(n,i){return i instanceof gt&&n.op===i.op&&n.field.isEqual(i.field)&&ni(n.value,i.value)}(t,e):t instanceof qn?function(n,i){return i instanceof qn&&n.op===i.op&&n.filters.length===i.filters.length?n.filters.reduce((r,o,l)=>r&&sL(o,i.filters[l]),!0):!1}(t,e):void pe()}function lL(t){return t instanceof gt?function(a){return`${a.field.canonicalString()} ${a.op} ${_l(a.value)}`}(t):t instanceof qn?function(a){return a.op.toString()+" {"+a.getFilters().map(lL).join(" ,")+"}"}(t):"Filter"}class UW extends gt{constructor(e,a,n){super(e,a,n),this.key=oe.fromName(n.referenceValue)}matches(e){const a=oe.comparator(e.key,this.key);return this.matchesComparison(a)}}class $W extends gt{constructor(e,a){super(e,"in",a),this.keys=cL("in",a)}matches(e){return this.keys.some(a=>a.isEqual(e.key))}}class WW extends gt{constructor(e,a){super(e,"not-in",a),this.keys=cL("not-in",a)}matches(e){return!this.keys.some(a=>a.isEqual(e.key))}}function cL(t,e){var a;return(((a=e.arrayValue)===null||a===void 0?void 0:a.values)||[]).map(n=>oe.fromName(n.referenceValue))}class GW extends gt{constructor(e,a){super(e,"array-contains",a)}matches(e){const a=e.data.field(this.field);return $w(a)&&ru(a.arrayValue,this.value)}}class KW extends gt{constructor(e,a){super(e,"in",a)}matches(e){const a=e.data.field(this.field);return a!==null&&ru(this.value.arrayValue,a)}}class JW extends gt{constructor(e,a){super(e,"not-in",a)}matches(e){if(ru(this.value.arrayValue,{nullValue:"NULL_VALUE"}))return!1;const a=e.data.field(this.field);return a!==null&&!ru(this.value.arrayValue,a)}}class QW extends gt{constructor(e,a){super(e,"array-contains-any",a)}matches(e){const a=e.data.field(this.field);return!(!$w(a)||!a.arrayValue.values)&&a.arrayValue.values.some(n=>ru(this.value.arrayValue,n))}}/** 930 * @license 931 * Copyright 2019 Google LLC 932 * 933 * Licensed under the Apache License, Version 2.0 (the "License");
934 * you may not use this file except in compliance with the License. 935 * You may obtain a copy of the License at 936 * 937 * http://www.apache.org/licenses/LICENSE-2.0 938 * 939 * Unless required by applicable law or agreed to in writing, software 940 * distributed under the License is distributed on an "AS IS" BASIS, 941 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 942 * See the License for the specific language governing permissions and 943 * limitations under the License. 944 */class XW{constructor(e,a=null,n=[],i=[],r=null,o=null,l=null){this.path=e,this.collectionGroup=a,this.orderBy=n,this.filters=i,this.limit=r,this.startAt=o,this.endAt=l,this.ue=null}}function oC(t,e=null,a=[],n=[],i=null,r=null,o=null){return new XW(t,e,a,n,i,r,o)}function Ww(t){const e=he(t);if(e.ue===null){let a=e.path.canonicalString();e.collectionGroup!==null&&(a+="|cg:"+e.collectionGroup),a+="|f:",a+=e.filters.map(n=>tb(n)).join(","),a+="|ob:",a+=e.orderBy.map(n=>function(r){return r.field.canonicalString()+r.dir}(n)).join(","),hg(e.limit)||(a+="|l:",a+=e.limit),e.startAt&&(a+="|lb:",a+=e.startAt.inclusive?"b:":"a:",a+=e.startAt.position.map(n=>_l(n)).join(",")),e.endAt&&(a+="|ub:",a+=e.endAt.inclusive?"a:":"b:",a+=e.endAt.position.map(n=>_l(n)).join(",")),e.ue=a}return e.ue}function Gw(t,e){if(t.limit!==e.limit||t.orderBy.length!==e.orderBy.length)return!1;for(let a=0;a<t.orderBy.length;a++)if(!FW(t.orderBy[a],e.orderBy[a]))return!1;if(t.filters.length!==e.filters.length)return!1;for(let a=0;a<t.filters.length;a++)if(!sL(t.filters[a],e.filters[a]))return!1;return t.collectionGroup===e.collectionGroup&&!!t.path.isEqual(e.path)&&!!rC(t.startAt,e.startAt)&&rC(t.endAt,e.endAt)}function ab(t){return oe.isDocumentKey(t.path)&&t.collectionGroup===null&&t.filters.length===0}/** 945 * @license 946 * Copyright 2017 Google LLC 947 * 948 * Licensed under the Apache License, Version 2.0 (the "License"); 949 * you may not use this file except in compliance with the License. 950 * You may obtain a copy of the License at 951 * 952 * http://www.apache.org/licenses/LICENSE-2.0 953 * 954 * Unless required by applicable law or agreed to in writing, software 955 * distributed under the License is distributed on an "AS IS" BASIS, 956 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 957 * See the License for the specific language governing permissions and 958 * limitations under the License. 959 */class Mu{constructor(e,a=null,n=[],i=[],r=null,o="F",l=null,c=null){this.path=e,this.collectionGroup=a,this.explicitOrderBy=n,this.filters=i,this.limit=r,this.limitType=o,this.startAt=l,this.endAt=c,this.ce=null,this.le=null,this.he=null,this.startAt,this.endAt}}function YW(t,e,a,n,i,r,o,l){return new Mu(t,e,a,n,i,r,o,l)}function Kw(t){return new Mu(t)}function sC(t){return t.filters.length===0&&t.limit===null&&t.startAt==null&&t.endAt==null&&(t.explicitOrderBy.length===0||t.explicitOrderBy.length===1&&t.explicitOrderBy[0].field.isKeyField())}function dL(t){return t.collectionGroup!==null}function pd(t){const e=he(t);if(e.ce===null){e.ce=[];const a=new Set;for(const r of e.explicitOrderBy)e.ce.push(r),a.add(r.field.canonicalString());const n=e.explicitOrderBy.length>0?e.explicitOrderBy[e.explicitOrderBy.length-1].dir:"asc";(function(o){let l=new Bt(Ht.comparator);return o.filters.forEach(c=>{c.getFlattenedFilters().forEach(d=>{d.isInequality()&&(l=l.add(d.field))})}),l})(e).forEach(r=>{a.has(r.canonicalString())||r.isKeyField()||e.ce.push(new Ph(r,n))}),a.has(Ht.keyField().canonicalString())||e.ce.push(new Ph(Ht.keyField(),n))}return e.ce}function ei(t){const e=he(t);return e.le||(e.le=ZW(e,pd(t))),e.le}function ZW(t,e){if(t.limitType==="F")return oC(t.path,t.collectionGroup,e,t.filters,t.limit,t.startAt,t.endAt);{e=e.map(i=>{const r=i.dir==="desc"?"asc":"desc";return new Ph(i.field,r)});const a=t.endAt?new Ih(t.endAt.position,t.endAt.inclusive):null,n=t.startAt?new Ih(t.startAt.position,t.startAt.inclusive):null;return oC(t.path,t.collectionGroup,e,t.filters,t.limit,a,n)}}function nb(t,e){const a=t.filters.concat([e]);return new Mu(t.path,t.collectionGroup,t.explicitOrderBy.slice(),a,t.limit,t.limitType,t.startAt,t.endAt)}function ib(t,e,a){return new Mu(t.path,t.collectionGroup,t.explicitOrderBy.slice(),t.filters.slice(),e,a,t.startAt,t.endAt)}function fg(t,e){return Gw(ei(t),ei(e))&&t.limitType===e.limitType}function uL(t){return`${Ww(ei(t))}|lt:${t.limitType}`}function Cs(t){return`Query(target=${function(a){let n=a.path.canonicalString();return a.collectionGroup!==null&&(n+=" collectionGroup="+a.collectionGroup),a.filters.length>0&&(n+=`, filters: [${a.filters.map(i=>lL(i)).join(", ")}]`),hg(a.limit)||(n+=", limit: "+a.limit),a.orderBy.length>0&&(n+=`, orderBy: [${a.orderBy.map(i=>function(o){return`${o.field.canonicalString()} (${o.dir})`}(i)).join(", ")}]`),a.startAt&&(n+=", startAt: ",n+=a.startAt.inclusive?"b:":"a:",n+=a.startAt.position.map(i=>_l(i)).join(",")),a.endAt&&(n+=", endAt: ",n+=a.endAt.inclusive?"a:":"b:",n+=a.endAt.position.map(i=>_l(i)).join(",")),`Target(${n})`}(ei(t))}; limitType=${t.limitType})`}function gg(t,e){return e.isFoundDocument()&&function(n,i){const r=i.key.path;return n.collectionGroup!==null?i.key.hasCollectionId(n.collectionGroup)&&n.path.isPrefixOf(r):oe.isDocumentKey(n.path)?n.path.isEqual(r):n.path.isImmediateParentOf(r)}(t,e)&&function(n,i){for(const r of pd(n))if(!r.field.isKeyField()&&i.data.field(r.field)===null)return!1;return!0}(t,e)&&function(n,i){for(const r of n.filters)if(!r.matches(i))return!1;return!0}(t,e)&&function(n,i){return!(n.startAt&&!function(o,l,c){const d=iC(o,l,c);return o.inclusive?d<=0:d<0}(n.startAt,pd(n),i)||n.endAt&&!function(o,l,c){const d=iC(o,l,c);return o.inclusive?d>=0:d>0}(n.endAt,pd(n),i))}(t,e)}function eG(t){return t.collectionGroup||(t.path.length%2==1?t.path.lastSegment():t.path.get(t.path.length-2))}function pL(t){return(e,a)=>{let n=!1;for(const i of pd(t)){const r=tG(i,e,a);if(r!==0)return r;n=n||i.field.isKeyField()}return 0}}function tG(t,e,a){const n=t.field.isKeyField()?oe.comparator(e.key,a.key):function(r,o,l){const c=o.data.field(r),d=l.data.field(r);return c!==null&&d!==null?Sl(c,d):pe()}(t.field,e,a);switch(t.dir){case"asc":return n;
959case"desc":return-1*n;default:return pe()}}/** 960 * @license 961 * Copyright 2017 Google LLC 962 * 963 * Licensed under the Apache License, Version 2.0 (the "License"); 964 * you may not use this file except in compliance with the License. 965 * You may obtain a copy of the License at 966 * 967 * http://www.apache.org/licenses/LICENSE-2.0 968 * 969 * Unless required by applicable law or agreed to in writing, software 970 * distributed under the License is distributed on an "AS IS" BASIS, 971 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 972 * See the License for the specific language governing permissions and 973 * limitations under the License. 974 */class Kl{constructor(e,a){this.mapKeyFn=e,this.equalsFn=a,this.inner={},this.innerSize=0}get(e){const a=this.mapKeyFn(e),n=this.inner[a];if(n!==void 0){for(const[i,r]of n)if(this.equalsFn(i,e))return r}}has(e){return this.get(e)!==void 0}set(e,a){const n=this.mapKeyFn(e),i=this.inner[n];if(i===void 0)return this.inner[n]=[[e,a]],void this.innerSize++;for(let r=0;r<i.length;r++)if(this.equalsFn(i[r][0],e))return void(i[r]=[e,a]);i.push([e,a]),this.innerSize++}delete(e){const a=this.mapKeyFn(e),n=this.inner[a];if(n===void 0)return!1;for(let i=0;i<n.length;i++)if(this.equalsFn(n[i][0],e))return n.length===1?delete this.inner[a]:n.splice(i,1),this.innerSize--,!0;return!1}forEach(e){ps(this.inner,(a,n)=>{for(const[i,r]of n)e(i,r)})}isEmpty(){return tL(this.inner)}size(){return this.innerSize}}/** 975 * @license 976 * Copyright 2017 Google LLC 977 * 978 * Licensed under the Apache License, Version 2.0 (the "License"); 979 * you may not use this file except in compliance with the License. 980 * You may obtain a copy of the License at 981 * 982 * http://www.apache.org/licenses/LICENSE-2.0 983 * 984 * Unless required by applicable law or agreed to in writing, software 985 * distributed under the License is distributed on an "AS IS" BASIS, 986 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 987 * See the License for the specific language governing permissions and 988 * limitations under the License. 989 */const aG=new tt(oe.comparator);function Hi(){return aG}const mL=new tt(oe.comparator);function Hc(...t){let e=mL;for(const a of t)e=e.insert(a.key,a);return e}function hL(t){let e=mL;return t.forEach((a,n)=>e=e.insert(a,n.overlayedDocument)),e}function So(){return md()}function fL(){return md()}function md(){return new Kl(t=>t.toString(),(t,e)=>t.isEqual(e))}const nG=new tt(oe.comparator),iG=new Bt(oe.comparator);function Se(...t){let e=iG;for(const a of t)e=e.add(a);return e}const rG=new Bt(je);function oG(){return rG}/** 990 * @license 991 * Copyright 2020 Google LLC 992 * 993 * Licensed under the Apache License, Version 2.0 (the "License"); 994 * you may not use this file except in compliance with the License. 995 * You may obtain a copy of the License at 996 * 997 * http://www.apache.org/licenses/LICENSE-2.0 998 * 999 * Unless required by applicable law or agreed to in writing, software 1000 * distributed under the License is distributed on an "AS IS" BASIS, 1001 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1002 * See the License for the specific language governing permissions and 1003 * limitations under the License. 1004 */function Jw(t,e){if(t.useProto3Json){if(isNaN(e))return{doubleValue:"NaN"};if(e===1/0)return{doubleValue:"Infinity"};if(e===-1/0)return{doubleValue:"-Infinity"}}return{doubleValue:Nh(e)?"-0":e}}function gL(t){return{integerValue:""+t}}function sG(t,e){return DW(e)?gL(e):Jw(t,e)}/** 1005 * @license 1006 * Copyright 2018 Google LLC 1007 * 1008 * Licensed under the Apache License, Version 2.0 (the "License"); 1009 * you may not use this file except in compliance with the License. 1010 * You may obtain a copy of the License at 1011 * 1012 * http://www.apache.org/licenses/LICENSE-2.0 1013 * 1014 * Unless required by applicable law or agreed to in writing, software 1015 * distributed under the License is distributed on an "AS IS" BASIS, 1016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1017 * See the License for the specific language governing permissions and 1018 * limitations under the License. 1019 */class yg{constructor(){this._=void 0}}function lG(t,e,a){return t instanceof Rh?function(i,r){const o={fields:{__type__:{stringValue:"server_timestamp"},__local_write_time__:{timestampValue:{seconds:i.seconds,nanos:i.nanoseconds}}}};return r&&Bw(r)&&(r=Uw(r)),r&&(o.fields.__previous_value__=r),{mapValue:o}}(a,e):t instanceof ou?xL(t,e):t instanceof su?vL(t,e):function(i,r){const o=yL(i,r),l=lC(o)+lC(i.Pe);return eb(o)&&eb(i.Pe)?gL(l):Jw(i.serializer,l)}(t,e)}function cG(t,e,a){return t instanceof ou?xL(t,e):t instanceof su?vL(t,e):a}function yL(t,e){return t instanceof Lh?function(n){return eb(n)||function(r){return!!r&&"doubleValue"in r}(n)}(e)?e:{integerValue:0}:null}class Rh extends yg{}class ou extends yg{constructor(e){super(),this.elements=e}}function xL(t,e){const a=bL(e);for(const n of t.elements)a.some(i=>ni(i,n))||a.push(n);return{arrayValue:{values:a}}}class su extends yg{constructor(e){super(),this.elements=e}}function vL(t,e){let a=bL(e);for(const n of t.elements)a=a.filter(i=>!ni(i,n));return{arrayValue:{values:a}}}
1019class Lh extends yg{constructor(e,a){super(),this.serializer=e,this.Pe=a}}function lC(t){return ut(t.integerValue||t.doubleValue)}function bL(t){return $w(t)&&t.arrayValue.values?t.arrayValue.values.slice():[]}function dG(t,e){return t.field.isEqual(e.field)&&function(n,i){return n instanceof ou&&i instanceof ou||n instanceof su&&i instanceof su?kl(n.elements,i.elements,ni):n instanceof Lh&&i instanceof Lh?ni(n.Pe,i.Pe):n instanceof Rh&&i instanceof Rh}(t.transform,e.transform)}class uG{constructor(e,a){this.version=e,this.transformResults=a}}class In{constructor(e,a){this.updateTime=e,this.exists=a}static none(){return new In}static exists(e){return new In(void 0,e)}static updateTime(e){return new In(e)}get isNone(){return this.updateTime===void 0&&this.exists===void 0}isEqual(e){return this.exists===e.exists&&(this.updateTime?!!e.updateTime&&this.updateTime.isEqual(e.updateTime):!e.updateTime)}}function Om(t,e){return t.updateTime!==void 0?e.isFoundDocument()&&e.version.isEqual(t.updateTime):t.exists===void 0||t.exists===e.isFoundDocument()}class xg{}function wL(t,e){if(!t.hasLocalMutations||e&&e.fields.length===0)return null;if(e===null)return t.isNoDocument()?new Qw(t.key,In.none()):new Du(t.key,t.data,In.none());{const a=t.data,n=_a.empty();let i=new Bt(Ht.comparator);for(let r of e.fields)if(!i.has(r)){let o=a.field(r);o===null&&r.length>1&&(r=r.popLast(),o=a.field(r)),o===null?n.delete(r):n.set(r,o),i=i.add(r)}return new Xr(t.key,n,new Va(i.toArray()),In.none())}}function pG(t,e,a){t instanceof Du?function(i,r,o){const l=i.value.clone(),c=dC(i.fieldTransforms,r,o.transformResults);l.setAll(c),r.convertToFoundDocument(o.version,l).setHasCommittedMutations()}(t,e,a):t instanceof Xr?function(i,r,o){if(!Om(i.precondition,r))return void r.convertToUnknownDocument(o.version);const l=dC(i.fieldTransforms,r,o.transformResults),c=r.data;c.setAll(kL(i)),c.setAll(l),r.convertToFoundDocument(o.version,c).setHasCommittedMutations()}(t,e,a):function(i,r,o){r.convertToNoDocument(o.version).setHasCommittedMutations()}(0,e,a)}function hd(t,e,a,n){return t instanceof Du?function(r,o,l,c){if(!Om(r.precondition,o))return l;const d=r.value.clone(),u=uC(r.fieldTransforms,c,o);return d.setAll(u),o.convertToFoundDocument(o.version,d).setHasLocalMutations(),null}(t,e,a,n):t instanceof Xr?function(r,o,l,c){if(!Om(r.precondition,o))return l;const d=uC(r.fieldTransforms,c,o),u=o.data;return u.setAll(kL(r)),u.setAll(d),o.convertToFoundDocument(o.version,u).setHasLocalMutations(),l===null?null:l.unionWith(r.fieldMask.fields).unionWith(r.fieldTransforms.map(p=>p.field))}(t,e,a,n):function(r,o,l){return Om(r.precondition,o)?(o.convertToNoDocument(o.version).setHasLocalMutations(),null):l}(t,e,a)}function mG(t,e){let a=null;for(const n of t.fieldTransforms){const i=e.data.field(n.field),r=yL(n.transform,i||null);r!=null&&(a===null&&(a=_a.empty()),a.set(n.field,r))}return a||null}function cC(t,e){return t.type===e.type&&!!t.key.isEqual(e.key)&&!!t.precondition.isEqual(e.precondition)&&!!function(n,i){return n===void 0&&i===void 0||!(!n||!i)&&kl(n,i,(r,o)=>dG(r,o))}(t.fieldTransforms,e.fieldTransforms)&&(t.type===0?t.value.isEqual(e.value):t.type!==1||t.data.isEqual(e.data)&&t.fieldMask.isEqual(e.fieldMask))}class Du extends xg{constructor(e,a,n,i=[]){super(),this.key=e,this.value=a,this.prec
1019ondition=n,this.fieldTransforms=i,this.type=0}getFieldMask(){return null}}class Xr extends xg{constructor(e,a,n,i,r=[]){super(),this.key=e,this.data=a,this.fieldMask=n,this.precondition=i,this.fieldTransforms=r,this.type=1}getFieldMask(){return this.fieldMask}}function kL(t){const e=new Map;return t.fieldMask.fields.forEach(a=>{if(!a.isEmpty()){const n=t.data.field(a);e.set(a,n)}}),e}function dC(t,e,a){const n=new Map;Oe(t.length===a.length);for(let i=0;i<a.length;i++){const r=t[i],o=r.transform,l=e.data.field(r.field);n.set(r.field,cG(o,l,a[i]))}return n}function uC(t,e,a){const n=new Map;for(const i of t){const r=i.transform,o=a.data.field(i.field);n.set(i.field,lG(r,o,e))}return n}class Qw extends xg{constructor(e,a){super(),this.key=e,this.precondition=a,this.type=2,this.fieldTransforms=[]}getFieldMask(){return null}}class hG extends xg{constructor(e,a){super(),this.key=e,this.precondition=a,this.type=3,this.fieldTransforms=[]}getFieldMask(){return null}}/** 1020 * @license 1021 * Copyright 2017 Google LLC 1022 * 1023 * Licensed under the Apache License, Version 2.0 (the "License"); 1024 * you may not use this file except in compliance with the License. 1025 * You may obtain a copy of the License at 1026 * 1027 * http://www.apache.org/licenses/LICENSE-2.0 1028 * 1029 * Unless required by applicable law or agreed to in writing, software 1030 * distributed under the License is distributed on an "AS IS" BASIS, 1031 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1032 * See the License for the specific language governing permissions and 1033 * limitations under the License. 1034 */class fG{constructor(e,a,n,i){this.batchId=e,this.localWriteTime=a,this.baseMutations=n,this.mutations=i}applyToRemoteDocument(e,a){const n=a.mutationResults;for(let i=0;i<this.mutations.length;i++){const r=this.mutations[i];r.key.isEqual(e.key)&&pG(r,e,n[i])}}applyToLocalView(e,a){for(const n of this.baseMutations)n.key.isEqual(e.key)&&(a=hd(n,e,a,this.localWriteTime));for(const n of this.mutations)n.key.isEqual(e.key)&&(a=hd(n,e,a,this.localWriteTime));return a}applyToLocalDocumentSet(e,a){const n=fL();return this.mutations.forEach(i=>{const r=e.get(i.key),o=r.overlayedDocument;let l=this.applyToLocalView(o,r.mutatedFields);l=a.has(i.key)?null:l;const c=wL(o,l);c!==null&&n.set(i.key,c),o.isValidDocument()||o.convertToNoDocument(me.min())}),n}keys(){return this.mutations.reduce((e,a)=>e.add(a.key),Se())}isEqual(e){return this.batchId===e.batchId&&kl(this.mutations,e.mutations,(a,n)=>cC(a,n))&&kl(this.baseMutations,e.baseMutations,(a,n)=>cC(a,n))}}class Xw{constructor(e,a,n,i){this.batch=e,this.commitVersion=a,this.mutationResults=n,this.docVersions=i}static from(e,a,n){Oe(e.mutations.length===n.length);let i=function(){return nG}();const r=e.mutations;for(let o=0;o<r.length;o++)i=i.insert(r[o].key,n[o].version);return new Xw(e,a,n,i)}}/** 1035 * @license 1036 * Copyright 2022 Google LLC 1037 * 1038 * Licensed under the Apache License, Version 2.0 (the "License"); 1039 * you may not use this file except in compliance with the License. 1040 * You may obtain a copy of the License at 1041 * 1042 * http://www.apache.org/licenses/LICENSE-2.0 1043 * 1044 * Unless required by applicable law or agreed to in writing, software 1045 * distributed under the License is distributed on an "AS IS" BASIS, 1046 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1047 * See the License for the specific language governing permissions and 1048 * limitations under the License. 1049 */class gG{constructor(e,a){this.largestBatchId=e,this.mutation=a}getKey(){return this.mutation.key}isEqual(e){return e!==null&&this.mutation===e.mutation}toString(){return`Overlay{ 1050 largestBatchId: ${this.largestBatchId}, 1051 mutation: ${this.mutation.toString()} 1052 }`}}/** 1053 * @license 1054 * Copyright 2017 Google LLC 1055 * 1056 * Licensed under the Apache License, Version 2.0 (the "License"); 1057 * you may not use this file except in compliance with the License. 1058 * You may obtain a copy of the License at 1059 * 1060 * http://www.apache.org/licenses/LICENSE-2.0 1061 * 1062 * Unless required by applicable law or agreed to in writing, software 1063 * distributed under the License is distributed on an "AS IS" BASIS, 1064 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1065 * See the License for the specific language governing permissions and 1066 * limitations under the License. 1067 */class yG{constructor(e,a){this.count=e,this.unchangedNames=a}}/** 1068 * @license 1069 * Copyright 2017 Google LLC 1070 * 1071 * Licensed under the Apache License, Version 2.0 (the "License");
1072 * you may not use this file except in compliance with the License. 1073 * You may obtain a copy of the License at 1074 * 1075 * http://www.apache.org/licenses/LICENSE-2.0 1076 * 1077 * Unless required by applicable law or agreed to in writing, software 1078 * distributed under the License is distributed on an "AS IS" BASIS, 1079 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1080 * See the License for the specific language governing permissions and 1081 * limitations under the License. 1082 */var mt,Ae;function xG(t){switch(t){default:return pe();case z.CANCELLED:case z.UNKNOWN:case z.DEADLINE_EXCEEDED:case z.RESOURCE_EXHAUSTED:case z.INTERNAL:case z.UNAVAILABLE:case z.UNAUTHENTICATED:return!1;case z.INVALID_ARGUMENT:case z.NOT_FOUND:case z.ALREADY_EXISTS:case z.PERMISSION_DENIED:case z.FAILED_PRECONDITION:case z.ABORTED:case z.OUT_OF_RANGE:case z.UNIMPLEMENTED:case z.DATA_LOSS:return!0}}function SL(t){if(t===void 0)return Vi("GRPC error has no .code"),z.UNKNOWN;switch(t){case mt.OK:return z.OK;case mt.CANCELLED:return z.CANCELLED;case mt.UNKNOWN:return z.UNKNOWN;case mt.DEADLINE_EXCEEDED:return z.DEADLINE_EXCEEDED;case mt.RESOURCE_EXHAUSTED:return z.RESOURCE_EXHAUSTED;case mt.INTERNAL:return z.INTERNAL;case mt.UNAVAILABLE:return z.UNAVAILABLE;case mt.UNAUTHENTICATED:return z.UNAUTHENTICATED;case mt.INVALID_ARGUMENT:return z.INVALID_ARGUMENT;case mt.NOT_FOUND:return z.NOT_FOUND;case mt.ALREADY_EXISTS:return z.ALREADY_EXISTS;case mt.PERMISSION_DENIED:return z.PERMISSION_DENIED;case mt.FAILED_PRECONDITION:return z.FAILED_PRECONDITION;case mt.ABORTED:return z.ABORTED;case mt.OUT_OF_RANGE:return z.OUT_OF_RANGE;case mt.UNIMPLEMENTED:return z.UNIMPLEMENTED;case mt.DATA_LOSS:return z.DATA_LOSS;default:return pe()}}(Ae=mt||(mt={}))[Ae.OK=0]="OK",Ae[Ae.CANCELLED=1]="CANCELLED",Ae[Ae.UNKNOWN=2]="UNKNOWN",Ae[Ae.INVALID_ARGUMENT=3]="INVALID_ARGUMENT",Ae[Ae.DEADLINE_EXCEEDED=4]="DEADLINE_EXCEEDED",Ae[Ae.NOT_FOUND=5]="NOT_FOUND",Ae[Ae.ALREADY_EXISTS=6]="ALREADY_EXISTS",Ae[Ae.PERMISSION_DENIED=7]="PERMISSION_DENIED",Ae[Ae.UNAUTHENTICATED=16]="UNAUTHENTICATED",Ae[Ae.RESOURCE_EXHAUSTED=8]="RESOURCE_EXHAUSTED",Ae[Ae.FAILED_PRECONDITION=9]="FAILED_PRECONDITION",Ae[Ae.ABORTED=10]="ABORTED",Ae[Ae.OUT_OF_RANGE=11]="OUT_OF_RANGE",Ae[Ae.UNIMPLEMENTED=12]="UNIMPLEMENTED",Ae[Ae.INTERNAL=13]="INTERNAL",Ae[Ae.UNAVAILABLE=14]="UNAVAILABLE",Ae[Ae.DATA_LOSS=15]="DATA_LOSS";/** 1083 * @license 1084 * Copyright 2023 Google LLC 1085 * 1086 * Licensed under the Apache License, Version 2.0 (the "License"); 1087 * you may not use this file except in compliance with the License. 1088 * You may obtain a copy of the License at 1089 * 1090 * http://www.apache.org/licenses/LICENSE-2.0 1091 * 1092 * Unless required by applicable law or agreed to in writing, software 1093 * distributed under the License is distributed on an "AS IS" BASIS, 1094 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1095 * See the License for the specific language governing permissions and 1096 * limitations under the License. 1097 */function vG(){return new TextEncoder}/** 1098 * @license 1099 * Copyright 2022 Google LLC 1100 * 1101 * Licensed under the Apache License, Version 2.0 (the "License"); 1102 * you may not use this file except in compliance with the License. 1103 * You may obtain a copy of the License at 1104 * 1105 * http://www.apache.org/licenses/LICENSE-2.0 1106 * 1107 * Unless required by applicable law or agreed to in writing, software 1108 * distributed under the License is distributed on an "AS IS" BASIS, 1109 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1110 * See the License for the specific language governing permissions and 1111 * limitations under the License.
1112 */const bG=new Lo([4294967295,4294967295],0);function pC(t){const e=vG().encode(t),a=new GR;return a.update(e),new Uint8Array(a.digest())}function mC(t){const e=new DataView(t.buffer),a=e.getUint32(0,!0),n=e.getUint32(4,!0),i=e.getUint32(8,!0),r=e.getUint32(12,!0);return[new Lo([a,n],0),new Lo([i,r],0)]}class Yw{constructor(e,a,n){if(this.bitmap=e,this.padding=a,this.hashCount=n,a<0||a>=8)throw new Fc(`Invalid padding: ${a}`);if(n<0)throw new Fc(`Invalid hash count: ${n}`);if(e.length>0&&this.hashCount===0)throw new Fc(`Invalid hash count: ${n}`);if(e.length===0&&a!==0)throw new Fc(`Invalid padding when bitmap length is 0: ${a}`);this.Ie=8*e.length-a,this.Te=Lo.fromNumber(this.Ie)}Ee(e,a,n){let i=e.add(a.multiply(Lo.fromNumber(n)));return i.compare(bG)===1&&(i=new Lo([i.getBits(0),i.getBits(1)],0)),i.modulo(this.Te).toNumber()}de(e){return(this.bitmap[Math.floor(e/8)]&1<<e%8)!=0}mightContain(e){if(this.Ie===0)return!1;const a=pC(e),[n,i]=mC(a);for(let r=0;r<this.hashCount;r++){const o=this.Ee(n,i,r);if(!this.de(o))return!1}return!0}static create(e,a,n){const i=e%8==0?0:8-e%8,r=new Uint8Array(Math.ceil(e/8)),o=new Yw(r,i,a);return n.forEach(l=>o.insert(l)),o}insert(e){if(this.Ie===0)return;const a=pC(e),[n,i]=mC(a);for(let r=0;r<this.hashCount;r++){const o=this.Ee(n,i,r);this.Ae(o)}}Ae(e){const a=Math.floor(e/8),n=e%8;this.bitmap[a]|=1<<n}}
1112class Fc extends Error{constructor(){super(...arguments),this.name="BloomFilterError"}}/** 1113 * @license 1114 * Copyright 2017 Google LLC 1115 * 1116 * Licensed under the Apache License, Version 2.0 (the "License"); 1117 * you may not use this file except in compliance with the License. 1118 * You may obtain a copy of the License at 1119 * 1120 * http://www.apache.org/licenses/LICENSE-2.0 1121 * 1122 * Unless required by applicable law or agreed to in writing, software 1123 * distributed under the License is distributed on an "AS IS" BASIS, 1124 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1125 * See the License for the specific language governing permissions and 1126 * limitations under the License. 1127 */class vg{constructor(e,a,n,i,r){this.snapshotVersion=e,this.targetChanges=a,this.targetMismatches=n,this.documentUpdates=i,this.resolvedLimboDocuments=r}static createSynthesizedRemoteEventForCurrentChange(e,a,n){const i=new Map;return i.set(e,qu.createSynthesizedTargetChangeForCurrentChange(e,a,n)),new vg(me.min(),i,new tt(je),Hi(),Se())}}class qu{constructor(e,a,n,i,r){this.resumeToken=e,this.current=a,this.addedDocuments=n,this.modifiedDocuments=i,this.removedDocuments=r}static createSynthesizedTargetChangeForCurrentChange(e,a,n){return new qu(n,a,Se(),Se(),Se())}}/** 1128 * @license 1129 * Copyright 2017 Google LLC 1130 * 1131 * Licensed under the Apache License, Version 2.0 (the "License"); 1132 * you may not use this file except in compliance with the License. 1133 * You may obtain a copy of the License at 1134 * 1135 * http://www.apache.org/licenses/LICENSE-2.0 1136 * 1137 * Unless required by applicable law or agreed to in writing, software 1138 * distributed under the License is distributed on an "AS IS" BASIS, 1139 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1140 * See the License for the specific language governing permissions and 1141 * limitations under the License. 1142 */class Mm{constructor(e,a,n,i){this.Re=e,this.removedTargetIds=a,this.key=n,this.Ve=i}}class _L{constructor(e,a){this.targetId=e,this.me=a}}class AL{constructor(e,a,n=$t.EMPTY_BYTE_STRING,i=null){this.state=e,this.targetIds=a,this.resumeToken=n,this.cause=i}}class hC{constructor(){this.fe=0,this.ge=gC(),this.pe=$t.EMPTY_BYTE_STRING,this.ye=!1,this.we=!0}get current(){return this.ye}get resumeToken(){return this.pe}get Se(){return this.fe!==0}get be(){return this.we}De(e){e.approximateByteSize()>0&&(this.we=!0,this.pe=e)}ve(){let e=Se(),a=Se(),n=Se();return this.ge.forEach((i,r)=>{switch(r){case 0:e=e.add(i);break;case 2:a=a.add(i);break;case 1:n=n.add(i);break;default:pe()}}),new qu(this.pe,this.ye,e,a,n)}Ce(){this.we=!1,this.ge=gC()}Fe(e,a){this.we=!0,this.ge=this.ge.insert(e,a)}Me(e){this.we=!0,this.ge=this.ge.remove(e)}xe(){this.fe+=1}Oe(){this.fe-=1,Oe(this.fe>=0)}Ne(){this.we=!0,this.ye=!0}}class wG{constructor(e){this.Le=e,this.Be=new Map,this.ke=Hi(),this.qe=fC(),this.Qe=new tt(je)}Ke(e){for(const a of e.Re)e.Ve&&e.Ve.isFoundDocument()?this.$e(a,e.Ve):this.Ue(a,e.key,e.Ve);for(const a of e.removedTargetIds)this.Ue(a,e.key,e.Ve)}We(e){this.forEachTarget(e,a=>{const n=this.Ge(a);switch(e.state){case 0:this.ze(a)&&n.De(e.resumeToken);break;case 1:n.Oe(),n.Se||n.Ce(),n.De(e.resumeToken);break;case 2:n.Oe(),n.Se||this.removeTarget(a);break;case 3:this.ze(a)&&(n.Ne(),n.De(e.resumeToken));break;case 4:this.ze(a)&&(this.je(a),n.De(e.resumeToken));break;default:pe()}})}forEachTarget(e,a){e.targetIds.length>0?e.targetIds.forEach(a):this.Be.forEach((n,i)=>{this.ze(i)&&a(i)})}He(e){const a=e.targetId,n=e.me.count,i=this.Je(a);if(i){const r=i.target;if(ab(r))if(n===0){const o=new oe(r.path);this.Ue(a,o,aa.newNoDocument(o,me.min()))}else Oe(n===1);else{const o=this.Ye(a);if(o!==n){const l=this.Ze(e),c=l?this.Xe(l,e,o):1;if(c!==0){this.je(a);const d=c===2?"TargetPurposeExistenceFilterMismatchBloom":"TargetPurposeExistenceFilterMismatch";this.Qe=this.Qe.insert(a,d)}}}}}Ze(e){const a=e.me.unchangedNames;if(!a||!a.bits)return null;const{bits:{bitmap:n="",padding:i=0},hashCount:r=0}=a;let o,l;try{o=Qo(n).toUint8Array()}catch(c){if(c instanceof aL)return wl("Decoding the base64 bloom filter in existence filter failed ("+c.message+"); ignoring the bloom filter and falling back to full re-query."),null;throw c}try{l=new Yw(o,i,r)}catch(c){return wl(c instanceof Fc?"BloomFilter error: ":"Applying bloom filter failed: ",c),null}return l.Ie===0?null:l}Xe(e,a,n){return a.me.count===n-this.nt(e,a.targetId)?0:2}nt(e,a){const n=this.Le.getRemoteKeysForTarget(a);let i=0;
1142return n.forEach(r=>{const o=this.Le.tt(),l=`projects/${o.projectId}/databases/${o.database}/documents/${r.path.canonicalString()}`;e.mightContain(l)||(this.Ue(a,r,null),i++)}),i}rt(e){const a=new Map;this.Be.forEach((r,o)=>{const l=this.Je(o);if(l){if(r.current&&ab(l.target)){const c=new oe(l.target.path);this.ke.get(c)!==null||this.it(o,c)||this.Ue(o,c,aa.newNoDocument(c,e))}r.be&&(a.set(o,r.ve()),r.Ce())}});let n=Se();this.qe.forEach((r,o)=>{let l=!0;o.forEachWhile(c=>{const d=this.Je(c);return!d||d.purpose==="TargetPurposeLimboResolution"||(l=!1,!1)}),l&&(n=n.add(r))}),this.ke.forEach((r,o)=>o.setReadTime(e));const i=new vg(e,a,this.Qe,this.ke,n);return this.ke=Hi(),this.qe=fC(),this.Qe=new tt(je),i}$e(e,a){if(!this.ze(e))return;const n=this.it(e,a.key)?2:0;this.Ge(e).Fe(a.key,n),this.ke=this.ke.insert(a.key,a),this.qe=this.qe.insert(a.key,this.st(a.key).add(e))}Ue(e,a,n){if(!this.ze(e))return;const i=this.Ge(e);this.it(e,a)?i.Fe(a,1):i.Me(a),this.qe=this.qe.insert(a,this.st(a).delete(e)),n&&(this.ke=this.ke.insert(a,n))}removeTarget(e){this.Be.delete(e)}Ye(e){const a=this.Ge(e).ve();return this.Le.getRemoteKeysForTarget(e).size+a.addedDocuments.size-a.removedDocuments.size}xe(e){this.Ge(e).xe()}Ge(e){let a=this.Be.get(e);return a||(a=new hC,this.Be.set(e,a)),a}st(e){let a=this.qe.get(e);return a||(a=new Bt(je),this.qe=this.qe.insert(e,a)),a}ze(e){const a=this.Je(e)!==null;return a||Y("WatchChangeAggregator","Detected inactive target",e),a}Je(e){const a=this.Be.get(e);return a&&a.Se?null:this.Le.ot(e)}je(e){this.Be.set(e,new hC),this.Le.getRemoteKeysForTarget(e).forEach(a=>{this.Ue(e,a,null)})}it(e,a){return this.Le.getRemoteKeysForTarget(e).has(a)}}function fC(){return new tt(oe.comparator)}function gC(){return new tt(oe.comparator)}const kG={asc:"ASCENDING",desc:"DESCENDING"},SG={"<":"LESS_THAN","<=":"LESS_THAN_OR_EQUAL",">":"GREATER_THAN",">=":"GREATER_THAN_OR_EQUAL","==":"EQUAL","!=":"NOT_EQUAL","array-contains":"ARRAY_CONTAINS",in:"IN","not-in":"NOT_IN","array-contains-any":"ARRAY_CONTAINS_ANY"},_G={and:"AND",or:"OR"};class AG{constructor(e,a){this.databaseId=e,this.useProto3Json=a}}function rb(t,e){return t.useProto3Json||hg(e)?e:{value:e}}function Oh(t,e){return t.useProto3Json?`${new Date(1e3*e.seconds).toISOString().replace(/\.\d*/,"").replace("Z","")}.${("000000000"+e.nanoseconds).slice(-9)}Z`:{seconds:""+e.seconds,nanos:e.nanoseconds}}function EL(t,e){return t.useProto3Json?e.toBase64():e.toUint8Array()}function EG(t,e){return Oh(t,e.toTimestamp())}function ti(t){return Oe(!!t),me.fromTimestamp(function(a){const n=Fr(a);return new xt(n.seconds,n.nanos)}(t))}function Zw(t,e){return ob(t,e).canonicalString()}function ob(t,e){const a=function(i){return new Ue(["projects",i.projectId,"databases",i.database])}(t).child("documents");return e===void 0?a:a.child(e)}function CL(t){const e=Ue.fromString(t);return Oe(PL(e)),e}function sb(t,e){return Zw(t.databaseId,e.path)}function C0(t,e){const a=CL(e);if(a.get(1)!==t.databaseId.projectId)throw new X(z.INVALID_ARGUMENT,"Tried to deserialize key from different project: "+a.get(1)+" vs "+t.databaseId.projectId);if(a.get(3)!==t.databaseId.database)throw new X(z.INVALID_ARGUMENT,"Tried to deserialize key from different database: "+a.get(3)+" vs "+t.databaseId.database);return new oe(TL(a))}function jL(t,e){return Zw(t.databaseId,e)}function CG(t){const e=CL(t);return e.length===4?Ue.emptyPath():TL(e)}function lb(t){return new Ue(["projects",t.databaseId.projectId,"databases",t.databaseId.database]).canonicalString()}function TL(t){return Oe(t.length>4&&t.get(4)==="documents"),t.popFirst(5)}function yC(t,e,a){return{name:sb(t,e),fields:a.value.mapValue.fields}}function jG(t,e){let a;if("targetChange"in e){e.targetChange;const n=function(d){return d==="NO_CHANGE"?0:d==="ADD"?1:d==="REMOVE"?2:d==="CURRENT"?3:d==="RESET"?4:pe()}(e.targetChange.targetChangeType||"NO_CHANGE"),i=e.targetChange.targetIds||[],r=function(d,u){return d.useProto3Json?(Oe(u===void 0||typeof u=="string"),$t.fromBase64String(u||"")):(Oe(u===void 0||u instanceof Buffer||u instanceof Uint8Array),$t.fromUint8Array(u||new Uint8Array))}(t,e.targetChange.resumeToken),o=e.targetChange.cause,l=o&&function(d){const u=d.code===void 0?z.UNKNOWN:SL(d.c
1142ode);return new X(u,d.message||"")}(o);a=new AL(n,i,r,l||null)}else if("documentChange"in e){e.documentChange;const n=e.documentChange;n.document,n.document.name,n.document.updateTime;const i=C0(t,n.document.name),r=ti(n.document.updateTime),o=n.document.createTime?ti(n.document.createTime):me.min(),l=new _a({mapValue:{fields:n.document.fields}}),c=aa.newFoundDocument(i,r,o,l),d=n.targetIds||[],u=n.removedTargetIds||[];a=new Mm(d,u,c.key,c)}else if("documentDelete"in e){e.documentDelete;const n=e.documentDelete;n.document;const i=C0(t,n.document),r=n.readTime?ti(n.readTime):me.min(),o=aa.newNoDocument(i,r),l=n.removedTargetIds||[];a=new Mm([],l,o.key,o)}else if("documentRemove"in e){e.documentRemove;const n=e.documentRemove;n.document;const i=C0(t,n.document),r=n.removedTargetIds||[];a=new Mm([],r,i,null)}else{if(!("filter"in e))return pe();{e.filter;const n=e.filter;n.targetId;const{count:i=0,unchangedNames:r}=n,o=new yG(i,r),l=n.targetId;a=new _L(l,o)}}return a}function TG(t,e){let a;if(e instanceof Du)a={update:yC(t,e.key,e.value)};else if(e instanceof Qw)a={delete:sb(t,e.key)};else if(e instanceof Xr)a={update:yC(t,e.key,e.data),updateMask:qG(e.fieldMask)};else{if(!(e instanceof hG))return pe();a={verify:sb(t,e.key)}}return e.fieldTransforms.length>0&&(a.updateTransforms=e.fieldTransforms.map(n=>function(r,o){const l=o.transform;if(l instanceof Rh)return{fieldPath:o.field.canonicalString(),setToServerValue:"REQUEST_TIME"};if(l instanceof ou)return{fieldPath:o.field.canonicalString(),appendMissingElements:{values:l.elements}};if(l instanceof su)return{fieldPath:o.field.canonicalString(),removeAllFromArray:{values:l.elements}};if(l instanceof Lh)return{fieldPath:o.field.canonicalString(),increment:l.Pe};throw pe()}(0,n))),e.precondition.isNone||(a.currentDocument=function(i,r){return r.updateTime!==void 0?{updateTime:EG(i,r.updateTime)}:r.exists!==void 0?{exists:r.exists}:pe()}(t,e.precondition)),a}function NG(t,e){return t&&t.length>0?(Oe(e!==void 0),t.map(a=>function(i,r){let o=i.updateTime?ti(i.updateTime):ti(r);return o.isEqual(me.min())&&(o=ti(r)),new uG(o,i.transformResults||[])}(a,e))):[]}function IG(t,e){return{documents:[jL(t,e.path)]}}function PG(t,e){const a={structuredQuery:{}},n=e.path;let i;e.collectionGroup!==null?(i=n,a.structuredQuery.from=[{collectionId:e.collectionGroup,allDescendants:!0}]):(i=n.popLast(),a.structuredQuery.from=[{collectionId:n.lastSegment()}]),a.parent=jL(t,i);const r=function(d){if(d.length!==0)return IL(qn.create(d,"and"))}(e.filters);r&&(a.structuredQuery.where=r);const o=function(d){if(d.length!==0)return d.map(u=>function(m){return{field:js(m.field),direction:OG(m.dir)}}(u))}(e.orderBy);o&&(a.structuredQuery.orderBy=o);const l=rb(t,e.limit);return l!==null&&(a.structuredQuery.limit=l),e.startAt&&(a.structuredQuery.startAt=function(d){return{before:d.inclusive,values:d.position}}(e.startAt)),e.endAt&&(a.structuredQuery.endAt=function(d){return{before:!d.inclusive,values:d.position}}(e.endAt)),{_t:a,parent:i}}function RG(t){let e=CG(t.parent);const a=t.structuredQuery,n=a.from?a.from.length:0;let i=null;if(n>0){Oe(n===1);const u=a.from[0];u.allDescendants?i=u.collectionId:e=e.child(u.collectionId)}let r=[];a.where&&(r=function(p){const m=NL(p);return m instanceof qn&&oL(m)?m.getFilters():[m]}(a.where));let o=[];a.orderBy&&(o=function(p){return p.map(m=>function(g){return new Ph(Ts(g.field),function(x){switch(x){case"ASCENDING":return"asc";case"DESCENDING":return"desc";default:return}}(g.direction))}(m))}(a.orderBy));let l=null;a.limit&&(l=function(p){let m;return m=typeof p=="object"?p.value:p,hg(m)?null:m}(a.limit));let c=null;a.startAt&&(c=function(p){const m=!!p.before,h=p.values||[];return new Ih(h,m)}(a.startAt));let d=null;return a.endAt&&(d=function(p){const m=!p.before,h=p.values||[];return new Ih(h,m)}(a.endAt)),YW(e,i,o,r,l,"F",c,d)}function LG(t,e){const a=function(i){switch(i){case"TargetPurposeListen":return null;case"TargetPurposeExistenceFilterMismatch":return"existence-filter-mismatch";case"TargetPurposeExistenceFilterMismatchBloom":return"existence-filter-mismatch-bloom";case"TargetPurposeLimboResolution":return"limbo-document";default:return pe()}}(e.purpose);return a==null?null:{"goog-listen-tags":a}}function NL(t){return t.unaryFilter!==void 0?function(a){switch(a.unaryFilter.op){case"IS_NAN":const n=Ts(a.unaryFilter.field);return gt.create(n,"==",{doubleValue:NaN});case"IS_NULL":const i=Ts(a.unaryFilter.field);return gt.create(i,"==",{nullValue:"NULL_VALUE"});
1142case"IS_NOT_NAN":const r=Ts(a.unaryFilter.field);return gt.create(r,"!=",{doubleValue:NaN});case"IS_NOT_NULL":const o=Ts(a.unaryFilter.field);return gt.create(o,"!=",{nullValue:"NULL_VALUE"});default:return pe()}}(t):t.fieldFilter!==void 0?function(a){return gt.create(Ts(a.fieldFilter.field),function(i){switch(i){case"EQUAL":return"==";case"NOT_EQUAL":return"!=";case"GREATER_THAN":return">";case"GREATER_THAN_OR_EQUAL":return">=";case"LESS_THAN":return"<";case"LESS_THAN_OR_EQUAL":return"<=";case"ARRAY_CONTAINS":return"array-contains";case"IN":return"in";case"NOT_IN":return"not-in";case"ARRAY_CONTAINS_ANY":return"array-contains-any";default:return pe()}}(a.fieldFilter.op),a.fieldFilter.value)}(t):t.compositeFilter!==void 0?function(a){return qn.create(a.compositeFilter.filters.map(n=>NL(n)),function(i){switch(i){case"AND":return"and";case"OR":return"or";default:return pe()}}(a.compositeFilter.op))}(t):pe()}function OG(t){return kG[t]}function MG(t){return SG[t]}function DG(t){return _G[t]}function js(t){return{fieldPath:t.canonicalString()}}function Ts(t){return Ht.fromServerFormat(t.fieldPath)}function IL(t){return t instanceof gt?function(a){if(a.op==="=="){if(nC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NAN"}};if(aC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NULL"}}}else if(a.op==="!="){if(nC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NOT_NAN"}};if(aC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NOT_NULL"}}}return{fieldFilter:{field:js(a.field),op:MG(a.op),value:a.value}}}(t):t instanceof qn?function(a){const n=a.getFilters().map(i=>IL(i));return n.length===1?n[0]:{compositeFilter:{op:DG(a.op),filters:n}}}(t):pe()}function qG(t){const e=[];return t.fields.forEach(a=>e.push(a.canonicalString())),{fieldPaths:e}}function PL(t){return t.length>=4&&t.get(0)==="projects"&&t.get(2)==="databases"}/** 1143 * @license 1144 * Copyright 2017 Google LLC 1145 * 1146 * Licensed under the Apache License, Version 2.0 (the "License"); 1147 * you may not use this file except in compliance with the License. 1148 * You may obtain a copy of the License at 1149 * 1150 * http://www.apache.org/licenses/LICENSE-2.0 1151 * 1152 * Unless required by applicable law or agreed to in writing, software 1153 * distributed under the License is distributed on an "AS IS" BASIS, 1154 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1155 * See the License for the specific language governing permissions and 1156 * limitations under the License. 1157 */class yr{constructor(e,a,n,i,r=me.min(),o=me.min(),l=$t.EMPTY_BYTE_STRING,c=null){this.target=e,this.targetId=a,this.purpose=n,this.sequenceNumber=i,this.snapshotVersion=r,this.lastLimboFreeSnapshotVersion=o,this.resumeToken=l,this.expectedCount=c}withSequenceNumber(e){return new yr(this.target,this.targetId,this.purpose,e,this.snapshotVersion,this.lastLimboFreeSnapshotVersion,this.resumeToken,this.expectedCount)}withResumeToken(e,a){return new yr(this.target,this.targetId,this.purpose,this.sequenceNumber,a,this.lastLimboFreeSnapshotVersion,e,null)}withExpectedCount(e){return new yr(this.target,this.targetId,this.purpose,this.sequenceNumber,this.snapshotVersion,this.lastLimboFreeSnapshotVersion,this.resumeToken,e)}withLastLimboFreeSnapshotVersion(e){return new yr(this.target,this.targetId,this.purpose,this.sequenceNumber,this.snapshotVersion,e,this.resumeToken,this.expectedCount)}}/** 1158 * @license 1159 * Copyright 2017 Google LLC 1160 * 1161 * Licensed under the Apache License, Version 2.0 (the "License"); 1162 * you may not use this file except in compliance with the License. 1163 * You may obtain a copy of the License at 1164 * 1165 * http://www.apache.org/licenses/LICENSE-2.0 1166 * 1167 * Unless required by applicable law or agreed to in writing, software 1168 * distributed under the License is distributed on an "AS IS" BASIS, 1169 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1170 * See the License for the specific language governing permissions and 1171 * limitations under the License. 1172 */class zG{constructor(e){this.ct=e}}function VG(t){const e=RG({parent:t.parent,structuredQuery:t.structuredQuery});return t.limitType==="LAST"?ib(e,e.limit,"L"):e}/** 1173 * @license 1174 * Copyright 2019 Google LLC 1175 * 1176 * Licensed under the Apache License, Version 2.0 (the "License");
1177 * you may not use this file except in compliance with the License. 1178 * You may obtain a copy of the License at 1179 * 1180 * http://www.apache.org/licenses/LICENSE-2.0 1181 * 1182 * Unless required by applicable law or agreed to in writing, software 1183 * distributed under the License is distributed on an "AS IS" BASIS, 1184 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1185 * See the License for the specific language governing permissions and 1186 * limitations under the License. 1187 */class HG{constructor(){this.un=new FG}addToCollectionParentIndex(e,a){return this.un.add(a),H.resolve()}getCollectionParents(e,a){return H.resolve(this.un.getEntries(a))}addFieldIndex(e,a){return H.resolve()}deleteFieldIndex(e,a){return H.resolve()}deleteAllFieldIndexes(e){return H.resolve()}createTargetIndexes(e,a){return H.resolve()}getDocumentsMatchingTarget(e,a){return H.resolve(null)}getIndexType(e,a){return H.resolve(0)}getFieldIndexes(e,a){return H.resolve([])}getNextCollectionGroupToUpdate(e){return H.resolve(null)}getMinOffset(e,a){return H.resolve(Hr.min())}getMinOffsetFromCollectionGroup(e,a){return H.resolve(Hr.min())}updateCollectionGroup(e,a,n){return H.resolve()}updateIndexEntries(e,a){return H.resolve()}}class FG{constructor(){this.index={}}add(e){const a=e.lastSegment(),n=e.popLast(),i=this.index[a]||new Bt(Ue.comparator),r=!i.has(n);return this.index[a]=i.add(n),r}has(e){const a=e.lastSegment(),n=e.popLast(),i=this.index[a];return i&&i.has(n)}getEntries(e){return(this.index[e]||new Bt(Ue.comparator)).toArray()}}/** 1188 * @license 1189 * Copyright 2017 Google LLC 1190 * 1191 * Licensed under the Apache License, Version 2.0 (the "License"); 1192 * you may not use this file except in compliance with the License. 1193 * You may obtain a copy of the License at 1194 * 1195 * http://www.apache.org/licenses/LICENSE-2.0 1196 * 1197 * Unless required by applicable law or agreed to in writing, software 1198 * distributed under the License is distributed on an "AS IS" BASIS, 1199 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1200 * See the License for the specific language governing permissions and 1201 * limitations under the License. 1202 */class Al{constructor(e){this.Ln=e}next(){return this.Ln+=2,this.Ln}static Bn(){return new Al(0)}static kn(){return new Al(-1)}}/** 1203 * @license 1204 * Copyright 2017 Google LLC 1205 * 1206 * Licensed under the Apache License, Version 2.0 (the "License"); 1207 * you may not use this file except in compliance with the License. 1208 * You may obtain a copy of the License at 1209 * 1210 * http://www.apache.org/licenses/LICENSE-2.0 1211 * 1212 * Unless required by applicable law or agreed to in writing, software 1213 * distributed under the License is distributed on an "AS IS" BASIS, 1214 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1215 * See the License for the specific language governing permissions and 1216 * limitations under the License. 1217 */class BG{constructor(){this.changes=new Kl(e=>e.toString(),(e,a)=>e.isEqual(a)),this.changesApplied=!1}addEntry(e){this.assertNotApplied(),this.changes.set(e.key,e)}removeEntry(e,a){this.assertNotApplied(),this.changes.set(e,aa.newInvalidDocument(e).setReadTime(a))}getEntry(e,a){this.assertNotApplied();const n=this.changes.get(a);return n!==void 0?H.resolve(n):this.getFromCache(e,a)}getEntries(e,a){return this.getAllFromCache(e,a)}apply(e){return this.assertNotApplied(),this.changesApplied=!0,this.applyChanges(e)}assertNotApplied(){}}/** 1218 * @license 1219 * Copyright 2017 Google LLC 1220 * 1221 * Licensed under the Apache License, Version 2.0 (the "License"); 1222 * you may not use this file except in compliance with the License. 1223 * You may obtain a copy of the License at 1224 * 1225 * http://www.apache.org/licenses/LICENSE-2.0 1226 * 1227 * Unless required by applicable law or agreed to in writing, software 1228 * distributed under the License is distributed on an "AS IS" BASIS, 1229 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1230 * See the License for the specific language governing permissions and 1231 * limitations under the License. 1232 *//** 1233 * @license 1234 * Copyright 2022 Google LLC 1235 * 1236 * Licensed under the Apache License, Version 2.0 (the "License");
1237 * you may not use this file except in compliance with the License. 1238 * You may obtain a copy of the License at 1239 * 1240 * http://www.apache.org/licenses/LICENSE-2.0 1241 * 1242 * Unless required by applicable law or agreed to in writing, software 1243 * distributed under the License is distributed on an "AS IS" BASIS, 1244 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1245 * See the License for the specific language governing permissions and 1246 * limitations under the License. 1247 */class UG{constructor(e,a){this.overlayedDocument=e,this.mutatedFields=a}}/** 1248 * @license 1249 * Copyright 2017 Google LLC 1250 * 1251 * Licensed under the Apache License, Version 2.0 (the "License"); 1252 * you may not use this file except in compliance with the License. 1253 * You may obtain a copy of the License at 1254 * 1255 * http://www.apache.org/licenses/LICENSE-2.0 1256 * 1257 * Unless required by applicable law or agreed to in writing, software 1258 * distributed under the License is distributed on an "AS IS" BASIS, 1259 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1260 * See the License for the specific language governing permissions and 1261 * limitations under the License. 1262 */class $G{constructor(e,a,n,i){this.remoteDocumentCache=e,this.mutationQueue=a,this.documentOverlayCache=n,this.indexManager=i}getDocument(e,a){let n=null;return this.documentOverlayCache.getOverlay(e,a).next(i=>(n=i,this.remoteDocumentCache.getEntry(e,a))).next(i=>(n!==null&&hd(n.mutation,i,Va.empty(),xt.now()),i))}getDocuments(e,a){return this.remoteDocumentCache.getEntries(e,a).next(n=>this.getLocalViewOfDocuments(e,n,Se()).next(()=>n))}getLocalViewOfDocuments(e,a,n=Se()){const i=So();return this.populateOverlays(e,i,a).next(()=>this.computeViews(e,a,i,n).next(r=>{let o=Hc();return r.forEach((l,c)=>{o=o.insert(l,c.overlayedDocument)}),o}))}getOverlayedDocuments(e,a){const n=So();return this.populateOverlays(e,n,a).next(()=>this.computeViews(e,a,n,Se()))}populateOverlays(e,a,n){const i=[];return n.forEach(r=>{a.has(r)||i.push(r)}),this.documentOverlayCache.getOverlays(e,i).next(r=>{r.forEach((o,l)=>{a.set(o,l)})})}computeViews(e,a,n,i){let r=Hi();const o=md(),l=function(){return md()}();return a.forEach((c,d)=>{const u=n.get(d.key);i.has(d.key)&&(u===void 0||u.mutation instanceof Xr)?r=r.insert(d.key,d):u!==void 0?(o.set(d.key,u.mutation.getFieldMask()),hd(u.mutation,d,u.mutation.getFieldMask(),xt.now())):o.set(d.key,Va.empty())}),this.recalculateAndSaveOverlays(e,r).next(c=>(c.forEach((d,u)=>o.set(d,u)),a.forEach((d,u)=>{var p;return l.set(d,new UG(u,(p=o.get(d))!==null&&p!==void 0?p:null))}),l))}recalculateAndSaveOverlays(e,a){const n=md();let i=new tt((o,l)=>o-l),r=Se();return this.mutationQueue.getAllMutationBatchesAffectingDocumentKeys(e,a).next(o=>{for(const l of o)l.keys().forEach(c=>{const d=a.get(c);if(d===null)return;let u=n.get(c)||Va.empty();u=l.applyToLocalView(d,u),n.set(c,u);const p=(i.get(l.batchId)||Se()).add(c);i=i.insert(l.batchId,p)})}).next(()=>{const o=[],l=i.getReverseIterator();for(;l.hasNext();){const c=l.getNext(),d=c.key,u=c.value,p=fL();u.forEach(m=>{if(!r.has(m)){const h=wL(a.get(m),n.get(m));h!==null&&p.set(m,h),r=r.add(m)}}),o.push(this.documentOverlayCache.saveOverlays(e,d,p))}return H.waitFor(o)}).next(()=>n)}recalculateAndSaveOverlaysForDocumentKeys(e,a){return this.remoteDocumentCache.getEntries(e,a).next(n=>this.recalculateAndSaveOverlays(e,n))}getDocumentsMatchingQuery(e,a,n,i){return function(o){return oe.isDocumentKey(o.path)&&o.collectionGroup===null&&o.filters.length===0}(a)?this.getDocumentsMatchingDocumentQuery(e,a.path):dL(a)?this.getDocumentsMatchingCollectionGroupQuery(e,a,n,i):this.getDocumentsMatchingCollectionQuery(e,a,n,i)}getNextDocuments(e,a,n,i){return this.remoteDocumentCache.getAllFromCollectionGroup(e,a,n,i).next(r=>{const o=i-r.size>0?this.documentOverlayCache.getOverlaysForCollectionGroup(e,a,n.largestBatchId,i-r.size):H.resolve(So());let l=-1,c=r;return o.next(d=>H.forEach(d,(u,p)=>(l<p.largestBatchId&&(l=p.largestBatchId),r.get(u)?H.resolve():this.remoteDocumentCache.getEntry(e,u).next(m=>{c=c.insert(u,m)}))).next(()=>this.populateOverlays(e,d,r)).next(()=>this.computeViews(e,c,d,Se())).next(u=>({batchId:l,changes:hL(u)})))})}getDocumentsMatchingDocumentQuery(e,a){return this.getDocument(e,new oe(a)).next(n=>{let i=Hc();
vendor: 4,204 bytes, lines 1262-1296
1262return n.isFoundDocument()&&(i=i.insert(n.key,n)),i})}getDocumentsMatchingCollectionGroupQuery(e,a,n,i){const r=a.collectionGroup;let o=Hc();return this.indexManager.getCollectionParents(e,r).next(l=>H.forEach(l,c=>{const d=function(p,m){return new Mu(m,null,p.explicitOrderBy.slice(),p.filters.slice(),p.limit,p.limitType,p.startAt,p.endAt)}(a,c.child(r));return this.getDocumentsMatchingCollectionQuery(e,d,n,i).next(u=>{u.forEach((p,m)=>{o=o.insert(p,m)})})}).next(()=>o))}getDocumentsMatchingCollectionQuery(e,a,n,i){let r;return this.documentOverlayCache.getOverlaysForCollection(e,a.path,n.largestBatchId).next(o=>(r=o,this.remoteDocumentCache.getDocumentsMatchingQuery(e,a,n,r,i))).next(o=>{r.forEach((c,d)=>{const u=d.getKey();o.get(u)===null&&(o=o.insert(u,aa.newInvalidDocument(u)))});let l=Hc();return o.forEach((c,d)=>{const u=r.get(c);u!==void 0&&hd(u.mutation,d,Va.empty(),xt.now()),gg(a,d)&&(l=l.insert(c,d))}),l})}}/** 1263 * @license 1264 * Copyright 2020 Google LLC 1265 * 1266 * Licensed under the Apache License, Version 2.0 (the "License"); 1267 * you may not use this file except in compliance with the License. 1268 * You may obtain a copy of the License at 1269 * 1270 * http://www.apache.org/licenses/LICENSE-2.0 1271 * 1272 * Unless required by applicable law or agreed to in writing, software 1273 * distributed under the License is distributed on an "AS IS" BASIS, 1274 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1275 * See the License for the specific language governing permissions and 1276 * limitations under the License. 1277 */class WG{constructor(e){this.serializer=e,this.hr=new Map,this.Pr=new Map}getBundleMetadata(e,a){return H.resolve(this.hr.get(a))}saveBundleMetadata(e,a){return this.hr.set(a.id,function(i){return{id:i.id,version:i.version,createTime:ti(i.createTime)}}(a)),H.resolve()}getNamedQuery(e,a){return H.resolve(this.Pr.get(a))}saveNamedQuery(e,a){return this.Pr.set(a.name,function(i){return{name:i.name,query:VG(i.bundledQuery),readTime:ti(i.readTime)}}(a)),H.resolve()}}/** 1278 * @license 1279 * Copyright 2022 Google LLC 1280 * 1281 * Licensed under the Apache License, Version 2.0 (the "License"); 1282 * you may not use this file except in compliance with the License. 1283 * You may obtain a copy of the License at 1284 * 1285 * http://www.apache.org/licenses/LICENSE-2.0 1286 * 1287 * Unless required by applicable law or agreed to in writing, software 1288 * distributed under the License is distributed on an "AS IS" BASIS, 1289 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1290 * See the License for the specific language governing permissions and 1291 * limitations under the License. 1292 */class GG{constructor(){this.overlays=new tt(oe.comparator),this.Ir=new Map}getOverlay(e,a){return H.resolve(this.overlays.get(a))}getOverlays(e,a){const n=So();return H.forEach(a,i=>this.getOverlay(e,i).next(r=>{r!==null&&n.set(i,r)})).next(()=>n)}saveOverlays(e,a,n){return n.forEach((i,r)=>{this.ht(e,a,r)}),H.resolve()}removeOverlaysForBatchId(e,a,n){const i=this.Ir.get(n);return i!==void 0&&(i.forEach(r=>this.overlays=this.overlays.remove(r)),this.Ir.delete(n)),H.resolve()}getOverlaysForCollection(e,a,n){const i=So(),r=a.length+1,o=new oe(a.child("")),l=this.overlays.getIteratorFrom(o);for(;l.hasNext();){const c=l.getNext().value,d=c.getKey();if(!a.isPrefixOf(d.path))break;d.path.length===r&&c.largestBatchId>n&&i.set(c.getKey(),c)}return H.resolve(i)}getOverlaysForCollectionGroup(e,a,n,i){let r=new tt((d,u)=>d-u);const o=this.overlays.getIterator();for(;o.hasNext();){const d=o.getNext().value;if(d.getKey().getCollectionGroup()===a&&d.largestBatchId>n){let u=r.get(d.largestBatchId);u===null&&(u=So(),r=r.insert(d.largestBatchId,u)),u.set(d.getKey(),d)}}const l=So(),c=r.getIterator();for(;c.hasNext()&&(c.getNext().value.forEach((d,u)=>l.set(d,u)),!(l.size()>=i)););return H.resolve(l)}ht(e,a,n){const i=this.overlays.get(n.key);if(i!==null){const o=this.Ir.get(i.largestBatchId).delete(n.key);this.Ir.set(i.largestBatchId,o)}this.overlays=this.overlays.insert(n.key,new gG(a,n));let r=this.Ir.get(a);r===void 0&&(r=Se(),this.Ir.set(a,r)),this.Ir.set(a,r.add(n.key))}}/** 1293 * @license 1294 * Copyright 2024 Google LLC 1295 * 1296 * Licensed under the Apache License, Version 2.0 (the "License");
1297 * you may not use this file except in compliance with the License. 1298 * You may obtain a copy of the License at 1299 * 1300 * http://www.apache.org/licenses/LICENSE-2.0 1301 * 1302 * Unless required by applicable law or agreed to in writing, software 1303 * distributed under the License is distributed on an "AS IS" BASIS, 1304 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1305 * See the License for the specific language governing permissions and 1306 * limitations under the License. 1307 */class KG{constructor(){this.sessionToken=$t.EMPTY_BYTE_STRING}getSessionToken(e){return H.resolve(this.sessionToken)}setSessionToken(e,a){return this.sessionToken=a,H.resolve()}}/** 1308 * @license 1309 * Copyright 2017 Google LLC 1310 * 1311 * Licensed under the Apache License, Version 2.0 (the "License"); 1312 * you may not use this file except in compliance with the License. 1313 * You may obtain a copy of the License at 1314 * 1315 * http://www.apache.org/licenses/LICENSE-2.0 1316 * 1317 * Unless required by applicable law or agreed to in writing, software 1318 * distributed under the License is distributed on an "AS IS" BASIS, 1319 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320 * See the License for the specific language governing permissions and 1321 * limitations under the License. 1322 */class ek{constructor(){this.Tr=new Bt(Ct.Er),this.dr=new Bt(Ct.Ar)}isEmpty(){return this.Tr.isEmpty()}addReference(e,a){const n=new Ct(e,a);this.Tr=this.Tr.add(n),this.dr=this.dr.add(n)}Rr(e,a){e.forEach(n=>this.addReference(n,a))}removeReference(e,a){this.Vr(new Ct(e,a))}mr(e,a){e.forEach(n=>this.removeReference(n,a))}gr(e){const a=new oe(new Ue([])),n=new Ct(a,e),i=new Ct(a,e+1),r=[];return this.dr.forEachInRange([n,i],o=>{this.Vr(o),r.push(o.key)}),r}pr(){this.Tr.forEach(e=>this.Vr(e))}Vr(e){this.Tr=this.Tr.delete(e),this.dr=this.dr.delete(e)}yr(e){const a=new oe(new Ue([])),n=new Ct(a,e),i=new Ct(a,e+1);let r=Se();return this.dr.forEachInRange([n,i],o=>{r=r.add(o.key)}),r}containsKey(e){const a=new Ct(e,0),n=this.Tr.firstAfterOrEqual(a);return n!==null&&e.isEqual(n.key)}}class Ct{constructor(e,a){this.key=e,this.wr=a}static Er(e,a){return oe.comparator(e.key,a.key)||je(e.wr,a.wr)}static Ar(e,a){return je(e.wr,a.wr)||oe.comparator(e.key,a.key)}}/** 1323 * @license 1324 * Copyright 2017 Google LLC 1325 * 1326 * Licensed under the Apache License, Version 2.0 (the "License"); 1327 * you may not use this file except in compliance with the License. 1328 * You may obtain a copy of the License at 1329 * 1330 * http://www.apache.org/licenses/LICENSE-2.0 1331 * 1332 * Unless required by applicable law or agreed to in writing, software 1333 * distributed under the License is distributed on an "AS IS" BASIS, 1334 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1335 * See the License for the specific language governing permissions and 1336 * limitations under the License. 1337 */class JG{constructor(e,a){this.indexManager=e,this.referenceDelegate=a,this.mutationQueue=[],this.Sr=1,this.br=new Bt(Ct.Er)}checkEmpty(e){return H.resolve(this.mutationQueue.length===0)}addMutationBatch(e,a,n,i){const r=this.Sr;this.Sr++,this.mutationQueue.length>0&&this.mutationQueue[this.mutationQueue.length-1];const o=new fG(r,a,n,i);this.mutationQueue.push(o);for(const l of i)this.br=this.br.add(new Ct(l.key,r)),this.indexManager.addToCollectionParentIndex(e,l.key.path.popLast());return H.resolve(o)}lookupMutationBatch(e,a){return H.resolve(this.Dr(a))}getNextMutationBatchAfterBatchId(e,a){const n=a+1,i=this.vr(n),r=i<0?0:i;return H.resolve(this.mutationQueue.length>r?this.mutationQueue[r]:null)}getHighestUnacknowledgedBatchId(){return H.resolve(this.mutationQueue.length===0?-1:this.Sr-1)}getAllMutationBatches(e){return H.resolve(this.mutationQueue.slice())}getAllMutationBatchesAffectingDocumentKey(e,a){const n=new Ct(a,0),i=new Ct(a,Number.POSITIVE_INFINITY),r=[];return this.br.forEachInRange([n,i],o=>{const l=this.Dr(o.wr);r.push(l)}),H.resolve(r)}getAllMutationBatchesAffectingDocumentKeys(e,a){let n=new Bt(je);return a.forEach(i=>{const r=new Ct(i,0),o=new Ct(i,Number.POSITIVE_INFINITY);this.br.forEachInRange([r,o],l=>{n=n.add(l.wr)})}),H.resolve(this.Cr(n))}getAllMutationBatchesAffectingQuery(e,a){const n=a.path,i=n.length+1;let r=n;oe.isDocumentKey(r)||(r=r.child(""));const o=new Ct(new oe(r),0);let l=new Bt(je);return this.br.forEachWhile(c=>{const d=c.key.path;return!!n.isPrefixOf(d)&&(d.length===i&&(l=l.add(c.wr)),!0)},o),H.resolve(this.Cr(l))}Cr(e){const a=[];return e.forEach(n=>{const i=this.Dr(n);i!==null&&a.push(i)}),a}removeMutationBatch(e,a){Oe(this.Fr(a.batchId,"removed")===0),this.mutation
1337Queue.shift();let n=this.br;return H.forEach(a.mutations,i=>{const r=new Ct(i.key,a.batchId);return n=n.delete(r),this.referenceDelegate.markPotentiallyOrphaned(e,i.key)}).next(()=>{this.br=n})}On(e){}containsKey(e,a){const n=new Ct(a,0),i=this.br.firstAfterOrEqual(n);return H.resolve(a.isEqual(i&&i.key))}performConsistencyCheck(e){return this.mutationQueue.length,H.resolve()}Fr(e,a){return this.vr(e)}vr(e){return this.mutationQueue.length===0?0:e-this.mutationQueue[0].batchId}Dr(e){const a=this.vr(e);return a<0||a>=this.mutationQueue.length?null:this.mutationQueue[a]}}/** 1338 * @license 1339 * Copyright 2017 Google LLC 1340 * 1341 * Licensed under the Apache License, Version 2.0 (the "License"); 1342 * you may not use this file except in compliance with the License. 1343 * You may obtain a copy of the License at 1344 * 1345 * http://www.apache.org/licenses/LICENSE-2.0 1346 * 1347 * Unless required by applicable law or agreed to in writing, software 1348 * distributed under the License is distributed on an "AS IS" BASIS, 1349 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1350 * See the License for the specific language governing permissions and 1351 * limitations under the License. 1352 */class QG{constructor(e){this.Mr=e,this.docs=function(){return new tt(oe.comparator)}(),this.size=0}setIndexManager(e){this.indexManager=e}addEntry(e,a){const n=a.key,i=this.docs.get(n),r=i?i.size:0,o=this.Mr(a);return this.docs=this.docs.insert(n,{document:a.mutableCopy(),size:o}),this.size+=o-r,this.indexManager.addToCollectionParentIndex(e,n.path.popLast())}removeEntry(e){const a=this.docs.get(e);a&&(this.docs=this.docs.remove(e),this.size-=a.size)}getEntry(e,a){const n=this.docs.get(a);return H.resolve(n?n.document.mutableCopy():aa.newInvalidDocument(a))}getEntries(e,a){let n=Hi();return a.forEach(i=>{const r=this.docs.get(i);n=n.insert(i,r?r.document.mutableCopy():aa.newInvalidDocument(i))}),H.resolve(n)}getDocumentsMatchingQuery(e,a,n,i){let r=Hi();const o=a.path,l=new oe(o.child("")),c=this.docs.getIteratorFrom(l);for(;c.hasNext();){const{key:d,value:{document:u}}=c.getNext();if(!o.isPrefixOf(d.path))break;d.path.length>o.length+1||RW(PW(u),n)<=0||(i.has(u.key)||gg(a,u))&&(r=r.insert(u.key,u.mutableCopy()))}return H.resolve(r)}getAllFromCollectionGroup(e,a,n,i){pe()}Or(e,a){return H.forEach(this.docs,n=>a(n))}newChangeBuffer(e){return new XG(this)}getSize(e){return H.resolve(this.size)}}class XG extends BG{constructor(e){super(),this.cr=e}applyChanges(e){const a=[];
vendor: 10,236 bytes, lines 1352-1427
1352return this.changes.forEach((n,i)=>{i.isValidDocument()?a.push(this.cr.addEntry(e,i)):this.cr.removeEntry(n)}),H.waitFor(a)}getFromCache(e,a){return this.cr.getEntry(e,a)}getAllFromCache(e,a){return this.cr.getEntries(e,a)}}/** 1353 * @license 1354 * Copyright 2017 Google LLC 1355 * 1356 * Licensed under the Apache License, Version 2.0 (the "License"); 1357 * you may not use this file except in compliance with the License. 1358 * You may obtain a copy of the License at 1359 * 1360 * http://www.apache.org/licenses/LICENSE-2.0 1361 * 1362 * Unless required by applicable law or agreed to in writing, software 1363 * distributed under the License is distributed on an "AS IS" BASIS, 1364 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365 * See the License for the specific language governing permissions and 1366 * limitations under the License. 1367 */class YG{constructor(e){this.persistence=e,this.Nr=new Kl(a=>Ww(a),Gw),this.lastRemoteSnapshotVersion=me.min(),this.highestTargetId=0,this.Lr=0,this.Br=new ek,this.targetCount=0,this.kr=Al.Bn()}forEachTarget(e,a){return this.Nr.forEach((n,i)=>a(i)),H.resolve()}getLastRemoteSnapshotVersion(e){return H.resolve(this.lastRemoteSnapshotVersion)}getHighestSequenceNumber(e){return H.resolve(this.Lr)}allocateTargetId(e){return this.highestTargetId=this.kr.next(),H.resolve(this.highestTargetId)}setTargetsMetadata(e,a,n){return n&&(this.lastRemoteSnapshotVersion=n),a>this.Lr&&(this.Lr=a),H.resolve()}Kn(e){this.Nr.set(e.target,e);const a=e.targetId;a>this.highestTargetId&&(this.kr=new Al(a),this.highestTargetId=a),e.sequenceNumber>this.Lr&&(this.Lr=e.sequenceNumber)}addTargetData(e,a){return this.Kn(a),this.targetCount+=1,H.resolve()}updateTargetData(e,a){return this.Kn(a),H.resolve()}removeTargetData(e,a){return this.Nr.delete(a.target),this.Br.gr(a.targetId),this.targetCount-=1,H.resolve()}removeTargets(e,a,n){let i=0;const r=[];return this.Nr.forEach((o,l)=>{l.sequenceNumber<=a&&n.get(l.targetId)===null&&(this.Nr.delete(o),r.push(this.removeMatchingKeysForTargetId(e,l.targetId)),i++)}),H.waitFor(r).next(()=>i)}getTargetCount(e){return H.resolve(this.targetCount)}getTargetData(e,a){const n=this.Nr.get(a)||null;return H.resolve(n)}addMatchingKeys(e,a,n){return this.Br.Rr(a,n),H.resolve()}removeMatchingKeys(e,a,n){this.Br.mr(a,n);const i=this.persistence.referenceDelegate,r=[];return i&&a.forEach(o=>{r.push(i.markPotentiallyOrphaned(e,o))}),H.waitFor(r)}removeMatchingKeysForTargetId(e,a){return this.Br.gr(a),H.resolve()}getMatchingKeysForTargetId(e,a){const n=this.Br.yr(a);return H.resolve(n)}containsKey(e,a){return H.resolve(this.Br.containsKey(a))}}/** 1368 * @license 1369 * Copyright 2017 Google LLC 1370 * 1371 * Licensed under the Apache License, Version 2.0 (the "License"); 1372 * you may not use this file except in compliance with the License. 1373 * You may obtain a copy of the License at 1374 * 1375 * http://www.apache.org/licenses/LICENSE-2.0 1376 * 1377 * Unless required by applicable law or agreed to in writing, software 1378 * distributed under the License is distributed on an "AS IS" BASIS, 1379 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1380 * See the License for the specific language governing permissions and 1381 * limitations under the License. 1382 */class ZG{constructor(e,a){this.qr={},this.overlays={},this.Qr=new Fw(0),this.Kr=!1,this.Kr=!0,this.$r=new KG,this.referenceDelegate=e(this),this.Ur=new YG(this),this.indexManager=new HG,this.remoteDocumentCache=function(i){return new QG(i)}(n=>this.referenceDelegate.Wr(n)),this.serializer=new zG(a),this.Gr=new WG(this.serializer)}start(){return Promise.resolve()}shutdown(){return this.Kr=!1,Promise.resolve()}get started(){return this.Kr}setDatabaseDeletedListener(){}setNetworkEnabled(){}getIndexManager(e){return this.indexManager}getDocumentOverlayCache(e){let a=this.overlays[e.toKey()];return a||(a=new GG,this.overlays[e.toKey()]=a),a}getMutationQueue(e,a){let n=this.qr[e.toKey()];return n||(n=new JG(a,this.referenceDelegate),this.qr[e.toKey()]=n),n}getGlobalsCache(){return this.$r}getTargetCache(){return this.Ur}getRemoteDocumentCache(){return this.remoteDocumentCache}getBundleCache(){return this.Gr}runTransaction(e,a,n){Y("MemoryPersistence","Starting transaction:",e);const i=new eK(this.Qr.next());return this.referenceDelegate.zr(),n(i).next(r=>this.referenceDelegate.jr(i).next(()=>r)).toPromise().then(r=>(i.raiseOnCommittedEvent(),r))}Hr(e,a){return H.or(Object.values(this.qr).map(n=>()=>n.containsKey(e,a)))}}class eK extends OW{constructor(e){super(),this.currentSequenceNumber=e}}class tk{constructor(e){this.persistence=e,this.Jr=new ek,this.Yr=null}static Zr(e){return new tk(e)}get Xr(){if(this.Yr)return this.Yr;throw pe()}addReference(e,a,n){return this.Jr.addReference(n,a),this.Xr.delete(n.toString()),H.resolve()}removeReference(e,a,n){return this.Jr.removeReference(n,a),this.Xr.add(n.toString()),H.resolve()}markPotentiallyOrphaned(e,a){return this.Xr.add(a.toString()),H.resolve()}removeTarget(e,a){this.Jr.gr(a.targetId).forEach(i=>this.Xr.add(i.toString()));const n=this.persistence.getTargetCache();return n.getMatchingKeysForTargetId(e,a.targetId).next(i=>{i.forEach(r=>this.Xr.add(r.toString()))}).next(()=>n.removeTargetData(e,a))}zr(){this.Yr=new Set}jr(e){const a=this.persistence.getRemoteDocumentCache().newChangeBuffer();return H.forEach(this.Xr,n=>{const i=oe.fromPath(n);return this.ei(e,i).next(r=>{r||a.removeEntry(i,me.min())})}).next(()=>(this.Yr=null,a.apply(e)))}updateLimboDocument(e,a){return this.ei(e,a).next(n=>{n?this.Xr.delete(a.toString()):this.Xr.add(a.toString())})}Wr(e){return 0}ei(e,a){return H.or([()=>H.resolve(this.Jr.containsKey(a)),()=>this.persistence.getTargetCache().containsKey(e,a),()=>this.persistence.Hr(e,a)])}}/** 1383 * @license 1384 * Copyright 2017 Google LLC 1385 * 1386 * Licensed under the Apache License, Version 2.0 (the "License"); 1387 * you may not use this file except in compliance with the License. 1388 * You may obtain a copy of the License at 1389 * 1390 * http://www.apache.org/licenses/LICENSE-2.0 1391 * 1392 * Unless required by applicable law or agreed to in writing, software 1393 * distributed under the License is distributed on an "AS IS" BASIS, 1394 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1395 * See the License for the specific language governing permissions and 1396 * limitations under the License. 1397 */class ak{constructor(e,a,n,i){this.targetId=e,this.fromCache=a,this.$i=n,this.Ui=i}static Wi(e,a){let n=Se(),i=Se();for(const r of a.docChanges)switch(r.type){case 0:n=n.add(r.doc.key);break;case 1:i=i.add(r.doc.key)}return new ak(e,a.fromCache,n,i)}}/** 1398 * @license 1399 * Copyright 2023 Google LLC 1400 * 1401 * Licensed under the Apache License, Version 2.0 (the "License"); 1402 * you may not use this file except in compliance with the License. 1403 * You may obtain a copy of the License at 1404 * 1405 * http://www.apache.org/licenses/LICENSE-2.0 1406 * 1407 * Unless required by applicable law or agreed to in writing, software 1408 * distributed under the License is distributed on an "AS IS" BASIS, 1409 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1410 * See the License for the specific language governing permissions and 1411 * limitations under the License. 1412 */class tK{constructor(){this._documentReadCount=0}get documentReadCount(){return this._documentReadCount}incrementDocumentReadCount(e){this._documentReadCount+=e}}/** 1413 * @license 1414 * Copyright 2019 Google LLC 1415 * 1416 * Licensed under the Apache License, Version 2.0 (the "License"); 1417 * you may not use this file except in compliance with the License. 1418 * You may obtain a copy of the License at 1419 * 1420 * http://www.apache.org/licenses/LICENSE-2.0 1421 * 1422 * Unless required by applicable law or agreed to in writing, software 1423 * distributed under the License is distributed on an "AS IS" BASIS, 1424 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1425 * See the License for the specific language governing permissions and 1426 * limitations under the License. 1427 */class aK{constructor(){this.Gi=!1,this.zi=!1,this.ji=100,this.Hi=function(){return i$()?8:MW(ra())>0?6:4}()}initialize(e,a){this.Ji=e,this.indexManager=a,this.Gi=!0}getDocumentsMatchingQuery(e,a,n,i){const r={result:null};return this.Yi(e,a).next(o=>{r.result=o}).next(()=>{if(!r.result)return this.Zi(e,a,i,n).next(o=>{r.result=o})}).next(()=>{if(r.result)return;const o=new tK;return this.Xi(e,a,o).next(l=>{if(r.result=l,this.zi)return this.es(e,a,o,l.size)})}).next(()=>r.result)}es(e,a,n,i){return n.documentReadCount<this.ji?(jc()<=_e.DEBUG&&Y("QueryEngine","SDK will not create cache indexes for query:",Cs(a),"since it only creates cache indexes for collection contains","more than or equal to",this.ji,"documents"),H.resolve()):(jc()<=_e.DEBUG&&Y("QueryEngine","Query:",Cs(a),"scans",n.documentReadCount,"local documents and returns",i,"documents as results."),n.documentReadCount>this.Hi*i?(jc()<=_e.DEBUG&&Y("QueryEngine","The SDK decides to create cache indexes for query:",Cs(a),"as using cache indexes may help improve performance."),this.indexManager.createTargetIndexes(e,ei(a))):H.resolve())}Yi(e,a){if(sC(a))return H.resolve(null);let n=ei(a);return this.indexManager.getIndexType(e,n).next(i=>i===0?null:(a.limit!==null&&i===1&&(a=ib(a,null,"F"),n=ei(a)),this.indexManager.getDocumentsMatchingTarget(e,n).next(r=>{const o=Se(...r);return this.Ji.getDocuments(e,o).next(l=>this.indexManager.getMinOffset(e,n).next(c=>{const d=this.ts(a,l);return this.ns(a,d,o,c.readTime)?this.Yi(e,ib(a,null,"F")):this.rs(e,d,a,c)}))})))}Zi(e,a,n,i){return sC(a)||i.isEqual(me.min())?H.resolve(null):this.Ji.getDocuments(e,n).next(r=>{const o=this.ts(a,r);return this.ns(a,o,n,i)?H.resolve(null):(jc()<=_e.DEBUG&&Y("QueryEngine","Re-using previous result from %s to execute query: %s",i.toString(),Cs(a)),this.rs(e,o,a,IW(i,-1)).next(l=>l))})}ts(e,a){let n=new Bt(pL(e));return a.forEach((i,r)=>{gg(e,r)&&(n=n.add(r))}),n}ns(e,a,n,i){if(e.limit===null)return!1;if(n.size!==a.size)return!0;const r=e.limitType==="F"?a.last():a.first();return!!r&&(r.hasPendingWrites||r.version.compareTo(i)>0)}Xi(e,a,n){return jc()<=_e.DEBUG&&Y("QueryEngine","Using full collection scan to execute query:",Cs(a)),this.Ji.getDocumentsMatchingQuery(e,a,Hr.min(),n)}rs(e,a,n,i){return this.Ji.getDocumentsMatchingQuery(e,n,i).next(r=>
1427(a.forEach(o=>{r=r.insert(o.key,o)}),r))}}/** 1428 * @license 1429 * Copyright 2020 Google LLC 1430 * 1431 * Licensed under the Apache License, Version 2.0 (the "License"); 1432 * you may not use this file except in compliance with the License. 1433 * You may obtain a copy of the License at 1434 * 1435 * http://www.apache.org/licenses/LICENSE-2.0 1436 * 1437 * Unless required by applicable law or agreed to in writing, software 1438 * distributed under the License is distributed on an "AS IS" BASIS, 1439 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1440 * See the License for the specific language governing permissions and 1441 * limitations under the License. 1442 */class nK{constructor(e,a,n,i){this.persistence=e,this.ss=a,this.serializer=i,this.os=new tt(je),this._s=new Kl(r=>Ww(r),Gw),this.us=new Map,this.cs=e.getRemoteDocumentCache(),this.Ur=e.getTargetCache(),this.Gr=e.getBundleCache(),this.ls(n)}ls(e){this.documentOverlayCache=this.persistence.getDocumentOverlayCache(e),this.indexManager=this.persistence.getIndexManager(e),this.mutationQueue=this.persistence.getMutationQueue(e,this.indexManager),this.localDocuments=new $G(this.cs,this.mutationQueue,this.documentOverlayCache,this.indexManager),this.cs.setIndexManager(this.indexManager),this.ss.initialize(this.localDocuments,this.indexManager)}collectGarbage(e){return this.persistence.runTransaction("Collect garbage","readwrite-primary",a=>e.collect(a,this.os))}}function iK(t,e,a,n){return new nK(t,e,a,n)}async function RL(t,e){const a=he(t);return await a.persistence.runTransaction("Handle user change","readonly",n=>{let i;return a.mutationQueue.getAllMutationBatches(n).next(r=>(i=r,a.ls(e),a.mutationQueue.getAllMutationBatches(n))).next(r=>{const o=[],l=[];let c=Se();for(const d of i){o.push(d.batchId);for(const u of d.mutations)c=c.add(u.key)}for(const d of r){l.push(d.batchId);for(const u of d.mutations)c=c.add(u.key)}return a.localDocuments.getDocuments(n,c).next(d=>({hs:d,removedBatchIds:o,addedBatchIds:l}))})})}function rK(t,e){const a=he(t);return a.persistence.runTransaction("Acknowledge batch","readwrite-primary",n=>{const i=e.batch.keys(),r=a.cs.newChangeBuffer({trackRemovals:!0});return function(l,c,d,u){const p=d.batch,m=p.keys();let h=H.resolve();return m.forEach(g=>{h=h.next(()=>u.getEntry(c,g)).next(y=>{const x=d.docVersions.get(g);Oe(x!==null),y.version.compareTo(x)<0&&(p.applyToRemoteDocument(y,d),y.isValidDocument()&&(y.setReadTime(d.commitVersion),u.addEntry(y)))})}),h.next(()=>l.mutationQueue.removeMutationBatch(c,p))}(a,n,e,r).next(()=>r.apply(n)).next(()=>a.mutationQueue.performConsistencyCheck(n)).next(()=>a.documentOverlayCache.removeOverlaysForBatchId(n,i,e.batch.batchId)).next(()=>a.localDocuments.recalculateAndSaveOverlaysForDocumentKeys(n,function(l){let c=Se();for(let d=0;d<l.mutationResults.length;++d)l.mutationResults[d].transformResults.length>0&&(c=c.add(l.batch.mutations[d].key));return c}(e))).next(()=>a.localDocuments.getDocuments(n,i))})}function LL(t){const e=he(t);return e.persistence.runTransaction("Get last remote snapshot version","readonly",a=>e.Ur.getLastRemoteSnapshotVersion(a))}function oK(t,e){const a=he(t),n=e.snapshotVersion;let i=a.os;return a.persistence.runTransaction("Apply remote event","readwrite-primary",r=>{const o=a.cs.newChangeBuffer({trackRemovals:!0});i=a.os;const l=[];
vendor: 4,425 bytes, lines 1442-1446
1442e.targetChanges.forEach((u,p)=>{const m=i.get(p);if(!m)return;l.push(a.Ur.removeMatchingKeys(r,u.removedDocuments,p).next(()=>a.Ur.addMatchingKeys(r,u.addedDocuments,p)));let h=m.withSequenceNumber(r.currentSequenceNumber);e.targetMismatches.get(p)!==null?h=h.withResumeToken($t.EMPTY_BYTE_STRING,me.min()).withLastLimboFreeSnapshotVersion(me.min()):u.resumeToken.approximateByteSize()>0&&(h=h.withResumeToken(u.resumeToken,n)),i=i.insert(p,h),function(y,x,v){return y.resumeToken.approximateByteSize()===0||x.snapshotVersion.toMicroseconds()-y.snapshotVersion.toMicroseconds()>=3e8?!0:v.addedDocuments.size+v.modifiedDocuments.size+v.removedDocuments.size>0}(m,h,u)&&l.push(a.Ur.updateTargetData(r,h))});let c=Hi(),d=Se();if(e.documentUpdates.forEach(u=>{e.resolvedLimboDocuments.has(u)&&l.push(a.persistence.referenceDelegate.updateLimboDocument(r,u))}),l.push(sK(r,o,e.documentUpdates).next(u=>{c=u.Ps,d=u.Is})),!n.isEqual(me.min())){const u=a.Ur.getLastRemoteSnapshotVersion(r).next(p=>a.Ur.setTargetsMetadata(r,r.currentSequenceNumber,n));l.push(u)}return H.waitFor(l).next(()=>o.apply(r)).next(()=>a.localDocuments.getLocalViewOfDocuments(r,c,d)).next(()=>c)}).then(r=>(a.os=i,r))}function sK(t,e,a){let n=Se(),i=Se();return a.forEach(r=>n=n.add(r)),e.getEntries(t,n).next(r=>{let o=Hi();return a.forEach((l,c)=>{const d=r.get(l);c.isFoundDocument()!==d.isFoundDocument()&&(i=i.add(l)),c.isNoDocument()&&c.version.isEqual(me.min())?(e.removeEntry(l,c.readTime),o=o.insert(l,c)):!d.isValidDocument()||c.version.compareTo(d.version)>0||c.version.compareTo(d.version)===0&&d.hasPendingWrites?(e.addEntry(c),o=o.insert(l,c)):Y("LocalStore","Ignoring outdated watch update for ",l,". Current version:",d.version," Watch version:",c.version)}),{Ps:o,Is:i}})}function lK(t,e){const a=he(t);return a.persistence.runTransaction("Get next mutation batch","readonly",n=>(e===void 0&&(e=-1),a.mutationQueue.getNextMutationBatchAfterBatchId(n,e)))}function cK(t,e){const a=he(t);return a.persistence.runTransaction("Allocate target","readwrite",n=>{let i;return a.Ur.getTargetData(n,e).next(r=>r?(i=r,H.resolve(i)):a.Ur.allocateTargetId(n).next(o=>(i=new yr(e,o,"TargetPurposeListen",n.currentSequenceNumber),a.Ur.addTargetData(n,i).next(()=>i))))}).then(n=>{const i=a.os.get(n.targetId);return(i===null||n.snapshotVersion.compareTo(i.snapshotVersion)>0)&&(a.os=a.os.insert(n.targetId,n),a._s.set(e,n.targetId)),n})}async function cb(t,e,a){const n=he(t),i=n.os.get(e),r=a?"readwrite":"readwrite-primary";try{a||await n.persistence.runTransaction("Release target",r,o=>n.persistence.referenceDelegate.removeTarget(o,i))}catch(o){if(!Ou(o))throw o;Y("LocalStore",`Failed to update sequence numbers for target ${e}: ${o}`)}n.os=n.os.remove(e),n._s.delete(i.target)}function xC(t,e,a){const n=he(t);let i=me.min(),r=Se();return n.persistence.runTransaction("Execute query","readwrite",o=>function(c,d,u){const p=he(c),m=p._s.get(u);return m!==void 0?H.resolve(p.os.get(m)):p.Ur.getTargetData(d,u)}(n,o,ei(e)).next(l=>{if(l)return i=l.lastLimboFreeSnapshotVersion,n.Ur.getMatchingKeysForTargetId(o,l.targetId).next(c=>{r=c})}).next(()=>n.ss.getDocumentsMatchingQuery(o,e,a?i:me.min(),a?r:Se())).next(l=>(dK(n,eG(e),l),{documents:l,Ts:r})))}function dK(t,e,a){let n=t.us.get(e)||me.min();a.forEach((i,r)=>{r.readTime.compareTo(n)>0&&(n=r.readTime)}),t.us.set(e,n)}class vC{constructor(){this.activeTargetIds=oG()}fs(e){this.activeTargetIds=this.activeTargetIds.add(e)}gs(e){this.activeTargetIds=this.activeTargetIds.delete(e)}Vs(){const e={activeTargetIds:this.activeTargetIds.toArray(),updateTimeMs:Date.now()};return JSON.stringify(e)}}class uK{constructor(){this.so=new vC,this.oo={},this.onlineStateHandler=null,this.sequenceNumberHandler=null}addPendingMutation(e){}updateMutationState(e,a,n){}addLocalQueryTarget(e,a=!0){return a&&this.so.fs(e),this.oo[e]||"not-current"}updateQueryState(e,a,n){this.oo[e]=a}removeLocalQueryTarget(e){this.so.gs(e)}isLocalQueryTarget(e){return this.so.activeTargetIds.has(e)}clearQueryState(e){delete this.oo[e]}getAllActiveQueryTargets(){return this.so.activeTargetIds}isActiveQueryTarget(e){return this.so.activeTargetIds.has(e)}start(){return this.so=new vC,Promise.resolve()}handleUserChange(e,a,n){}setOnlineState(e){}shutdown(){}writeSequenceNumber(e){}notifyBundleLoaded(e){}}/** 1443 * @license 1444 * Copyright 2019 Google LLC 1445 * 1446 * Licensed under the Apache License, Version 2.0 (the "License");
1447 * you may not use this file except in compliance with the License. 1448 * You may obtain a copy of the License at 1449 * 1450 * http://www.apache.org/licenses/LICENSE-2.0 1451 * 1452 * Unless required by applicable law or agreed to in writing, software 1453 * distributed under the License is distributed on an "AS IS" BASIS, 1454 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1455 * See the License for the specific language governing permissions and 1456 * limitations under the License. 1457 */class pK{_o(e){}shutdown(){}}/** 1458 * @license 1459 * Copyright 2019 Google LLC 1460 * 1461 * Licensed under the Apache License, Version 2.0 (the "License"); 1462 * you may not use this file except in compliance with the License. 1463 * You may obtain a copy of the License at 1464 * 1465 * http://www.apache.org/licenses/LICENSE-2.0 1466 * 1467 * Unless required by applicable law or agreed to in writing, software 1468 * distributed under the License is distributed on an "AS IS" BASIS, 1469 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1470 * See the License for the specific language governing permissions and 1471 * limitations under the License. 1472 */class bC{constructor(){this.ao=()=>this.uo(),this.co=()=>this.lo(),this.ho=[],this.Po()}_o(e){this.ho.push(e)}shutdown(){window.removeEventListener("online",this.ao),window.removeEventListener("offline",this.co)}Po(){window.addEventListener("online",this.ao),window.addEventListener("offline",this.co)}uo(){Y("ConnectivityMonitor","Network connectivity changed: AVAILABLE");for(const e of this.ho)e(0)}lo(){Y("ConnectivityMonitor","Network connectivity changed: UNAVAILABLE");for(const e of this.ho)e(1)}static D(){return typeof window<"u"&&window.addEventListener!==void 0&&window.removeEventListener!==void 0}}/** 1473 * @license 1474 * Copyright 2023 Google LLC 1475 * 1476 * Licensed under the Apache License, Version 2.0 (the "License"); 1477 * you may not use this file except in compliance with the License. 1478 * You may obtain a copy of the License at 1479 * 1480 * http://www.apache.org/licenses/LICENSE-2.0 1481 * 1482 * Unless required by applicable law or agreed to in writing, software 1483 * distributed under the License is distributed on an "AS IS" BASIS, 1484 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1485 * See the License for the specific language governing permissions and 1486 * limitations under the License. 1487 */let Bp=null;function j0(){return Bp===null?Bp=function(){return 268435456+Math.round(2147483648*Math.random())}():Bp++,"0x"+Bp.toString(16)}/** 1488 * @license 1489 * Copyright 2020 Google LLC 1490 * 1491 * Licensed under the Apache License, Version 2.0 (the "License"); 1492 * you may not use this file except in compliance with the License. 1493 * You may obtain a copy of the License at 1494 * 1495 * http://www.apache.org/licenses/LICENSE-2.0 1496 * 1497 * Unless required by applicable law or agreed to in writing, software 1498 * distributed under the License is distributed on an "AS IS" BASIS, 1499 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1500 * See the License for the specific language governing permissions and 1501 * limitations under the License. 1502 */const mK={BatchGetDocuments:"batchGet",Commit:"commit",RunQuery:"runQuery",RunAggregationQuery:"runAggregationQuery"};/** 1503 * @license 1504 * Copyright 2017 Google LLC 1505 * 1506 * Licensed under the Apache License, Version 2.0 (the "License"); 1507 * you may not use this file except in compliance with the License. 1508 * You may obtain a copy of the License at 1509 * 1510 * http://www.apache.org/licenses/LICENSE-2.0 1511 * 1512 * Unless required by applicable law or agreed to in writing, software 1513 * distributed under the License is distributed on an "AS IS" BASIS, 1514 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1515 * See the License for the specific language governing permissions and 1516 * limitations under the License. 1517 */class hK{constructor(e){this.Io=e.Io,this.To=e.To}Eo(e){this.Ao=e}Ro(e){this.Vo=e}mo(e){this.fo=e}onMessage(e){this.po=e}close(){this.To()}send(e){this.Io(e)}yo(){this.Ao()}wo(){this.Vo()}So(e){this.fo(e)}bo(e){this.po(e)}}/** 1518 * @license 1519 * Copyright 2017 Google LLC 1520 * 1521 * Licensed under the Apache License, Version 2.0 (the "License");
1522 * you may not use this file except in compliance with the License. 1523 * You may obtain a copy of the License at 1524 * 1525 * http://www.apache.org/licenses/LICENSE-2.0 1526 * 1527 * Unless required by applicable law or agreed to in writing, software 1528 * distributed under the License is distributed on an "AS IS" BASIS, 1529 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1530 * See the License for the specific language governing permissions and 1531 * limitations under the License. 1532 */const Yt="WebChannelConnection";class fK extends class{constructor(a){this.databaseInfo=a,this.databaseId=a.databaseId;const n=a.ssl?"https":"http",i=encodeURIComponent(this.databaseId.projectId),r=encodeURIComponent(this.databaseId.database);this.Do=n+"://"+a.host,this.vo=`projects/${i}/databases/${r}`,this.Co=this.databaseId.database==="(default)"?`project_id=${i}`:`project_id=${i}&database_id=${r}`}get Fo(){return!1}Mo(a,n,i,r,o){const l=j0(),c=this.xo(a,n.toUriEncodedString());Y("RestConnection",`Sending RPC '${a}' ${l}:`,c,i);const d={"google-cloud-resource-prefix":this.vo,"x-goog-request-params":this.Co};return this.Oo(d,r,o),this.No(a,c,d,i).then(u=>(Y("RestConnection",`Received RPC '${a}' ${l}: `,u),u),u=>{throw wl("RestConnection",`RPC '${a}' ${l} failed with error: `,u,"url: ",c,"request:",i),u})}Lo(a,n,i,r,o,l){return this.Mo(a,n,i,r,o)}Oo(a,n,i){a["X-Goog-Api-Client"]=function(){return"gl-js/ fire/"+Gl}(),a["Content-Type"]="text/plain",this.databaseInfo.appId&&(a["X-Firebase-GMPID"]=this.databaseInfo.appId),n&&n.headers.forEach((r,o)=>a[o]=r),i&&i.headers.forEach((r,o)=>a[o]=r)}xo(a,n){const i=mK[a];return`${this.Do}/v1/${n}:${i}`}terminate(){}}{constructor(e){super(e),this.forceLongPolling=e.forceLongPolling,this.autoDetectLongPolling=e.autoDetectLongPolling,this.useFetchStreams=e.useFetchStreams,this.longPollingOptions=e.longPollingOptions}No(e,a,n,i){const r=j0();return new Promise((o,l)=>{const c=new KR;c.setWithCredentials(!0),c.listenOnce(JR.COMPLETE,()=>{try{switch(c.getLastErrorCode()){case Rm.NO_ERROR:const u=c.getResponseJson();Y(Yt,`XHR for RPC '${e}' ${r} received:`,JSON.stringify(u)),o(u);break;case Rm.TIMEOUT:Y(Yt,`RPC '${e}' ${r} timed out`),l(new X(z.DEADLINE_EXCEEDED,"Request time out"));break;case Rm.HTTP_ERROR:const p=c.getStatus();if(Y(Yt,`RPC '${e}' ${r} failed with status:`,p,"response text:",c.getResponseText()),p>0){let m=c.getResponseJson();Array.isArray(m)&&(m=m[0]);const h=m==null?void 0:m.error;if(h&&h.status&&h.message){const g=function(x){const v=x.toLowerCase().replace(/_/g,"-");return Object.values(z).indexOf(v)>=0?v:z.UNKNOWN}(h.status);l(new X(g,h.message))}else l(new X(z.UNKNOWN,"Server responded with status "+c.getStatus()))}else l(new X(z.UNAVAILABLE,"Connection failed."));break;default:pe()}}finally{Y(Yt,`RPC '${e}' ${r} completed.`)}});const d=JSON.stringify(i);Y(Yt,`RPC '${e}' ${r} sending request:`,i),c.send(a,"POST",d,n,15)})}Bo(e,a,n){const i=j0(),r=[this.Do,"/","google.firestore.v1.Firestore","/",e,"/channel"],o=YR(),l=XR(),c={httpSessionIdParam:"gsessionid",initMessageHeaders:{},messageUrlParams:{database:`projects/${this.databaseId.projectId}/databases/${this.databaseId.database}`},sendRawJson:!0,supportsCrossDomainXhr:!0,internalChannelParams:{forwardChannelRequestTimeoutMs:6e5},forceLongPolling:this.forceLongPolling,detectBufferingProxy:this.autoDetectLongPolling},d=this.longPollingOptions.timeoutSeconds;d!==void 0&&(c.longPollingTimeout=Math.round(1e3*d)),this.useFetchStreams&&(c.useFetchStreams=!0),this.Oo(c.initMessageHeaders,a,n),c.encodeInitMessageHeaders=!0;const u=r.join("");Y(Yt,`Creating RPC '${e}' stream ${i}: ${u}`,c);const p=o.createWebChannel(u,c);let m=!1,h=!1;const g=new hK({Io:x=>{h?Y(Yt,`Not sending because RPC '${e}' stream ${i} is closed:`,x):(m||(Y(Yt,`Opening RPC '${e}' stream ${i} transport.`),p.open(),m=!0),Y(Yt,`RPC '${e}' stream ${i} sending:`,x),p.send(x))},To:()=>p.close()}),y=(x,v,w)=>{x.listen(v,S=>{try{w(S)}catch(T){setTimeout(()=>{throw T},0)}})};return y(p,Vc.EventType.OPEN,()=>{h||(Y(Yt,`RPC '${e}' stream ${i} transport opened.`),g.yo())}),y(p,Vc.EventType.CLOSE,()=>{h||(h=!0,Y(Yt,`RPC '${e}' stream ${i} transport closed`),g.So())}
1532),y(p,Vc.EventType.ERROR,x=>{h||(h=!0,wl(Yt,`RPC '${e}' stream ${i} transport errored:`,x),g.So(new X(z.UNAVAILABLE,"The operation could not be completed")))}),y(p,Vc.EventType.MESSAGE,x=>{var v;if(!h){const w=x.data[0];Oe(!!w);const S=w,T=S.error||((v=S[0])===null||v===void 0?void 0:v.error);if(T){Y(Yt,`RPC '${e}' stream ${i} received error:`,T);const P=T.status;let M=function(j){const N=mt[j];if(N!==void 0)return SL(N)}(P),C=T.message;M===void 0&&(M=z.INTERNAL,C="Unknown error status: "+P+" with message "+T.message),h=!0,g.So(new X(M,C)),p.close()}else Y(Yt,`RPC '${e}' stream ${i} received:`,w),g.bo(w)}}),y(l,QR.STAT_EVENT,x=>{x.stat===Yv.PROXY?Y(Yt,`RPC '${e}' stream ${i} detected buffering proxy`):x.stat===Yv.NOPROXY&&Y(Yt,`RPC '${e}' stream ${i} detected no buffering proxy`)}),setTimeout(()=>{g.wo()},0),g}}function T0(){return typeof document<"u"?document:null}/** 1533 * @license 1534 * Copyright 2020 Google LLC 1535 * 1536 * Licensed under the Apache License, Version 2.0 (the "License"); 1537 * you may not use this file except in compliance with the License. 1538 * You may obtain a copy of the License at 1539 * 1540 * http://www.apache.org/licenses/LICENSE-2.0 1541 * 1542 * Unless required by applicable law or agreed to in writing, software 1543 * distributed under the License is distributed on an "AS IS" BASIS, 1544 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1545 * See the License for the specific language governing permissions and 1546 * limitations under the License. 1547 */function bg(t){return new AG(t,!0)}/** 1548 * @license 1549 * Copyright 2017 Google LLC 1550 * 1551 * Licensed under the Apache License, Version 2.0 (the "License"); 1552 * you may not use this file except in compliance with the License. 1553 * You may obtain a copy of the License at 1554 * 1555 * http://www.apache.org/licenses/LICENSE-2.0 1556 * 1557 * Unless required by applicable law or agreed to in writing, software 1558 * distributed under the License is distributed on an "AS IS" BASIS, 1559 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1560 * See the License for the specific language governing permissions and 1561 * limitations under the License. 1562 */class OL{constructor(e,a,n=1e3,i=1.5,r=6e4){this.ui=e,this.timerId=a,this.ko=n,this.qo=i,this.Qo=r,this.Ko=0,this.$o=null,this.Uo=Date.now(),this.reset()}reset(){this.Ko=0}Wo(){this.Ko=this.Qo}Go(e){this.cancel();const a=Math.floor(this.Ko+this.zo()),n=Math.max(0,Date.now()-this.Uo),i=Math.max(0,a-n);i>0&&Y("ExponentialBackoff",`Backing off for ${i} ms (base delay: ${this.Ko} ms, delay with jitter: ${a} ms, last attempt: ${n} ms ago)`),this.$o=this.ui.enqueueAfterDelay(this.timerId,i,()=>(this.Uo=Date.now(),e())),this.Ko*=this.qo,this.Ko<this.ko&&(this.Ko=this.ko),this.Ko>this.Qo&&(this.Ko=this.Qo)}jo(){this.$o!==null&&(this.$o.skipDelay(),this.$o=null)}cancel(){this.$o!==null&&(this.$o.cancel(),this.$o=null)}zo(){return(Math.random()-.5)*this.Ko}}/** 1563 * @license 1564 * Copyright 2017 Google LLC 1565 * 1566 * Licensed under the Apache License, Version 2.0 (the "License"); 1567 * you may not use this file except in compliance with the License. 1568 * You may obtain a copy of the License at 1569 * 1570 * http://www.apache.org/licenses/LICENSE-2.0 1571 * 1572 * Unless required by applicable law or agreed to in writing, software 1573 * distributed under the License is distributed on an "AS IS" BASIS, 1574 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1575 * See the License for the specific language governing permissions and 1576 * limitations under the License. 1577 */class ML{constructor(e,a,n,i,r,o,l,c){this.ui=e,this.Ho=n,this.Jo=i,this.connection=r,this.authCredentialsProvider=o,this.appCheckCredentialsProvider=l,this.listener=c,this.state=0,this.Yo=0,this.Zo=null,this.Xo=null,this.stream=null,this.e_=0,this.t_=new OL(e,a)}n_(){return this.state===1||this.state===5||this.r_()}r_(){return this.state===2||this.state===3}start(){this.e_=0,this.state!==4?this.auth():this.i_()}async stop(){this.n_()&&await this.close(0)}s_(){this.state=0,this.t_.reset()}o_(){this.r_()&&this.Zo===null&&(this.Zo=this.ui.enqueueAfterDelay(this.Ho,6e4,()=>this.__()))}a_(e){this.u_(),this.stream.send(e)}async __(){if(this.r_())return this.close(0)}u_(){this.Zo&&(this.Zo.cancel(),this.Zo=null)}
1577c_(){this.Xo&&(this.Xo.cancel(),this.Xo=null)}async close(e,a){this.u_(),this.c_(),this.t_.cancel(),this.Yo++,e!==4?this.t_.reset():a&&a.code===z.RESOURCE_EXHAUSTED?(Vi(a.toString()),Vi("Using maximum backoff delay to prevent overloading the backend."),this.t_.Wo()):a&&a.code===z.UNAUTHENTICATED&&this.state!==3&&(this.authCredentialsProvider.invalidateToken(),this.appCheckCredentialsProvider.invalidateToken()),this.stream!==null&&(this.l_(),this.stream.close(),this.stream=null),this.state=e,await this.listener.mo(a)}l_(){}auth(){this.state=1;const e=this.h_(this.Yo),a=this.Yo;Promise.all([this.authCredentialsProvider.getToken(),this.appCheckCredentialsProvider.getToken()]).then(([n,i])=>{this.Yo===a&&this.P_(n,i)},n=>{e(()=>{const i=new X(z.UNKNOWN,"Fetching auth token failed: "+n.message);return this.I_(i)})})}P_(e,a){const n=this.h_(this.Yo);this.stream=this.T_(e,a),this.stream.Eo(()=>{n(()=>this.listener.Eo())}),this.stream.Ro(()=>{n(()=>(this.state=2,this.Xo=this.ui.enqueueAfterDelay(this.Jo,1e4,()=>(this.r_()&&(this.state=3),Promise.resolve())),this.listener.Ro()))}),this.stream.mo(i=>{n(()=>this.I_(i))}),this.stream.onMessage(i=>{n(()=>++this.e_==1?this.E_(i):this.onNext(i))})}i_(){this.state=5,this.t_.Go(async()=>{this.state=0,this.start()})}I_(e){return Y("PersistentStream",`close with error: ${e}`),this.stream=null,this.close(4,e)}h_(e){return a=>{this.ui.enqueueAndForget(()=>this.Yo===e?a():(Y("PersistentStream","stream callback skipped by getCloseGuardedDispatcher."),Promise.resolve()))}}}class gK extends ML{constructor(e,a,n,i,r,o){super(e,"listen_stream_connection_backoff","listen_stream_idle","health_check_timeout",a,n,i,o),this.serializer=r}T_(e,a){return this.connection.Bo("Listen",e,a)}E_(e){return this.onNext(e)}onNext(e){this.t_.reset();const a=jG(this.serializer,e),n=function(r){if(!("targetChange"in r))return me.min();const o=r.targetChange;return o.targetIds&&o.targetIds.length?me.min():o.readTime?ti(o.readTime):me.min()}(e);return this.listener.d_(a,n)}A_(e){const a={};a.database=lb(this.serializer),a.addTarget=function(r,o){let l;const c=o.target;if(l=ab(c)?{documents:IG(r,c)}:{query:PG(r,c)._t},l.targetId=o.targetId,o.resumeToken.approximateByteSize()>0){l.resumeToken=EL(r,o.resumeToken);const d=rb(r,o.expectedCount);d!==null&&(l.expectedCount=d)}else if(o.snapshotVersion.compareTo(me.min())>0){l.readTime=Oh(r,o.snapshotVersion.toTimestamp());const d=rb(r,o.expectedCount);d!==null&&(l.expectedCount=d)}return l}(this.serializer,e);const n=LG(this.serializer,e);n&&(a.labels=n),this.a_(a)}R_(e){const a={};a.database=lb(this.serializer),a.removeTarget=e,this.a_(a)}}class yK extends ML{constructor(e,a,n,i,r,o){super(e,"write_stream_connection_backoff","write_stream_idle","health_check_timeout",a,n,i,o),this.serializer=r}get V_(){return this.e_>0}start(){this.lastStreamToken=void 0,super.start()}l_(){this.V_&&this.m_([])}T_(e,a){return this.connection.Bo("Write",e,a)}E_(e){return Oe(!!e.streamToken),this.lastStreamToken=e.streamToken,Oe(!e.writeResults||e.writeResults.length===0),this.listener.f_()}onNext(e){Oe(!!e.streamToken),this.lastStreamToken=e.streamToken,this.t_.reset();const a=NG(e.writeResults,e.commitTime),n=ti(e.commitTime);return this.listener.g_(n,a)}p_(){const e={};e.database=lb(this.serializer),this.a_(e)}m_(e){const a={streamToken:this.lastStreamToken,writes:e.map(n=>TG(this.serializer,n))};this.a_(a)}}/** 1578 * @license 1579 * Copyright 2017 Google LLC 1580 * 1581 * Licensed under the Apache License, Version 2.0 (the "License"); 1582 * you may not use this file except in compliance with the License. 1583 * You may obtain a copy of the License at 1584 * 1585 * http://www.apache.org/licenses/LICENSE-2.0 1586 * 1587 * Unless required by applicable law or agreed to in writing, software 1588 * distributed under the License is distributed on an "AS IS" BASIS, 1589 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1590 * See the License for the specific language governing permissions and 1591 * limitations under the License. 1592 */class xK extends class{}{constructor(e,a,n,i){super(),this.authCredentials=e,this.appCheckCredentials=a,this.connection=n,this.serializer
1592=i,this.y_=!1}w_(){if(this.y_)throw new X(z.FAILED_PRECONDITION,"The client has already been terminated.")}Mo(e,a,n,i){return this.w_(),Promise.all([this.authCredentials.getToken(),this.appCheckCredentials.getToken()]).then(([r,o])=>this.connection.Mo(e,ob(a,n),i,r,o)).catch(r=>{throw r.name==="FirebaseError"?(r.code===z.UNAUTHENTICATED&&(this.authCredentials.invalidateToken(),this.appCheckCredentials.invalidateToken()),r):new X(z.UNKNOWN,r.toString())})}Lo(e,a,n,i,r){return this.w_(),Promise.all([this.authCredentials.getToken(),this.appCheckCredentials.getToken()]).then(([o,l])=>this.connection.Lo(e,ob(a,n),i,o,l,r)).catch(o=>{throw o.name==="FirebaseError"?(o.code===z.UNAUTHENTICATED&&(this.authCredentials.invalidateToken(),this.appCheckCredentials.invalidateToken()),o):new X(z.UNKNOWN,o.toString())})}terminate(){this.y_=!0,this.connection.terminate()}}class vK{constructor(e,a){this.asyncQueue=e,this.onlineStateHandler=a,this.state="Unknown",this.S_=0,this.b_=null,this.D_=!0}v_(){this.S_===0&&(this.C_("Unknown"),this.b_=this.asyncQueue.enqueueAfterDelay("online_state_timeout",1e4,()=>(this.b_=null,this.F_("Backend didn't respond within 10 seconds."),this.C_("Offline"),Promise.resolve())))}M_(e){this.state==="Online"?this.C_("Unknown"):(this.S_++,this.S_>=1&&(this.x_(),this.F_(`Connection failed 1 times. Most recent error: ${e.toString()}`),this.C_("Offline")))}set(e){this.x_(),this.S_=0,e==="Online"&&(this.D_=!1),this.C_(e)}C_(e){e!==this.state&&(this.state=e,this.onlineStateHandler(e))}F_(e){const a=`Could not reach Cloud Firestore backend. ${e} 1593This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.`;this.D_?(Vi(a),this.D_=!1):Y("OnlineStateTracker",a)}x_(){this.b_!==null&&(this.b_.cancel(),this.b_=null)}}/** 1594 * @license 1595 * Copyright 2017 Google LLC 1596 * 1597 * Licensed under the Apache License, Version 2.0 (the "License"); 1598 * you may not use this file except in compliance with the License. 1599 * You may obtain a copy of the License at 1600 * 1601 * http://www.apache.org/licenses/LICENSE-2.0 1602 * 1603 * Unless required by applicable law or agreed to in writing, software 1604 * distributed under the License is distributed on an "AS IS" BASIS, 1605 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1606 * See the License for the specific language governing permissions and 1607 * limitations under the License. 1608 */class bK{constructor(e,a,n,i,r){this.localStore=e,this.datastore=a,this.asyncQueue=n,this.remoteSyncer={},this.O_=[],this.N_=new Map,this.L_=new Set,this.B_=[],this.k_=r,this.k_._o(o=>{n.enqueueAndForget(async()=>{ms(this)&&(Y("RemoteStore","Restarting streams for network reachability change."),await async function(c){const d=he(c);d.L_.add(4),await zu(d),d.q_.set("Unknown"),d.L_.delete(4),await wg(d)}(this))})}),this.q_=new vK(n,i)}}async function wg(t){if(ms(t))for(const e of t.B_)await e(!0)}async function zu(t){for(const e of t.B_)await e(!1)}function DL(t,e){const a=he(t);a.N_.has(e.targetId)||(a.N_.set(e.targetId,e),ok(a)?rk(a):Jl(a).r_()&&ik(a,e))}function nk(t,e){const a=he(t),n=Jl(a);a.N_.delete(e),n.r_()&&qL(a,e),a.N_.size===0&&(n.r_()?n.o_():ms(a)&&a.q_.set("Unknown"))}function ik(t,e){if(t.Q_.xe(e.targetId),e.resumeToken.approximateByteSize()>0||e.snapshotVersion.compareTo(me.min())>0){const a=t.remoteSyncer.getRemoteKeysForTarget(e.targetId).size;e=e.withExpectedCount(a)}Jl(t).A_(e)}function qL(t,e){t.Q_.xe(e),Jl(t).R_(e)}function rk(t){t.Q_=new wG({getRemoteKeysForTarget:e=>t.remoteSyncer.getRemoteKeysForTarget(e),ot:e=>t.N_.get(e)||null,tt:()=>t.datastore.serializer.databaseId}),Jl(t).start(),t.q_.v_()}function ok(t){return ms(t)&&!Jl(t).n_()&&t.N_.size>0}function ms(t){return he(t).L_.size===0}function zL(t){t.Q_=void 0}async function wK(t){t.q_.set("Online")}async function kK(t){t.N_.forEach((e,a)=>{ik(t,e)})}async function SK(t,e){zL(t),ok(t)?(t.q_.M_(e),rk(t)):t.q_.set("Unknown")}async function _K(t,e,a){if(t.q_.set("Online"),e instanceof AL&&e.state===2&&e.cause)try{await async function(i,r){const o=r.cause;for(const l of r.targetIds)i.N_.has(l)&&(await i.remoteSyncer.rejectListen(l,o),i.N_.delete(l),i.Q_.removeTarget(l))}(t,e)}catch(n){Y("RemoteStore","Failed to remove targets %s: %s ",e.targetIds.join(","),n),await Mh(t,n)}else if(e instanceof Mm?t.Q_.Ke(e):e instanceof _L?t.Q_.He(e):t.Q_.We(e),!a.isEqual(me.min()))try{const n=await LL(t.localStore);a.compareTo(n)>=0&&await function(r,o){const l=r.Q_.rt(o);
1608return l.targetChanges.forEach((c,d)=>{if(c.resumeToken.approximateByteSize()>0){const u=r.N_.get(d);u&&r.N_.set(d,u.withResumeToken(c.resumeToken,o))}}),l.targetMismatches.forEach((c,d)=>{const u=r.N_.get(c);if(!u)return;r.N_.set(c,u.withResumeToken($t.EMPTY_BYTE_STRING,u.snapshotVersion)),qL(r,c);const p=new yr(u.target,c,d,u.sequenceNumber);ik(r,p)}),r.remoteSyncer.applyRemoteEvent(l)}(t,a)}catch(n){Y("RemoteStore","Failed to raise snapshot:",n),await Mh(t,n)}}async function Mh(t,e,a){if(!Ou(e))throw e;t.L_.add(1),await zu(t),t.q_.set("Offline"),a||(a=()=>LL(t.localStore)),t.asyncQueue.enqueueRetryable(async()=>{Y("RemoteStore","Retrying IndexedDB access"),await a(),t.L_.delete(1),await wg(t)})}function VL(t,e){return e().catch(a=>Mh(t,a,e))}async function kg(t){const e=he(t),a=Br(e);let n=e.O_.length>0?e.O_[e.O_.length-1].batchId:-1;for(;AK(e);)try{const i=await lK(e.localStore,n);if(i===null){e.O_.length===0&&a.o_();break}n=i.batchId,EK(e,i)}catch(i){await Mh(e,i)}HL(e)&&FL(e)}function AK(t){return ms(t)&&t.O_.length<10}function EK(t,e){t.O_.push(e);const a=Br(t);a.r_()&&a.V_&&a.m_(e.mutations)}function HL(t){return ms(t)&&!Br(t).n_()&&t.O_.length>0}function FL(t){Br(t).start()}async function CK(t){Br(t).p_()}async function jK(t){const e=Br(t);for(const a of t.O_)e.m_(a.mutations)}async function TK(t,e,a){const n=t.O_.shift(),i=Xw.from(n,e,a);await VL(t,()=>t.remoteSyncer.applySuccessfulWrite(i)),await kg(t)}async function NK(t,e){e&&Br(t).V_&&await async function(n,i){if(function(o){return xG(o)&&o!==z.ABORTED}(i.code)){const r=n.O_.shift();Br(n).s_(),await VL(n,()=>n.remoteSyncer.rejectFailedWrite(r.batchId,i)),await kg(n)}}(t,e),HL(t)&&FL(t)}async function wC(t,e){const a=he(t);a.asyncQueue.verifyOperationInProgress(),Y("RemoteStore","RemoteStore received new credentials");const n=ms(a);a.L_.add(3),await zu(a),n&&a.q_.set("Unknown"),await a.remoteSyncer.handleCredentialChange(e),a.L_.delete(3),await wg(a)}async function IK(t,e){const a=he(t);e?(a.L_.delete(2),await wg(a)):e||(a.L_.add(2),await zu(a),a.q_.set("Unknown"))}function Jl(t){return t.K_||(t.K_=function(a,n,i){const r=he(a);return r.w_(),new gK(n,r.connection,r.authCredentials,r.appCheckCredentials,r.serializer,i)}(t.datastore,t.asyncQueue,{Eo:wK.bind(null,t),Ro:kK.bind(null,t),mo:SK.bind(null,t),d_:_K.bind(null,t)}),t.B_.push(async e=>{e?(t.K_.s_(),ok(t)?rk(t):t.q_.set("Unknown")):(await t.K_.stop(),zL(t))})),t.K_}function Br(t){return t.U_||(t.U_=function(a,n,i){const r=he(a);return r.w_(),new yK(n,r.connection,r.authCredentials,r.appCheckCredentials,r.serializer,i)}(t.datastore,t.asyncQueue,{Eo:()=>Promise.resolve(),Ro:CK.bind(null,t),mo:NK.bind(null,t),f_:jK.bind(null,t),g_:TK.bind(null,t)}),t.B_.push(async e=>{e?(t.U_.s_(),await kg(t)):(await t.U_.stop(),t.O_.length>0&&(Y("RemoteStore",`Stopping write stream with ${t.O_.length} pending writes`),t.O_=[]))})),t.U_}/** 1609 * @license 1610 * Copyright 2017 Google LLC 1611 * 1612 * Licensed under the Apache License, Version 2.0 (the "License"); 1613 * you may not use this file except in compliance with the License. 1614 * You may obtain a copy of the License at 1615 * 1616 * http://www.apache.org/licenses/LICENSE-2.0 1617 * 1618 * Unless required by applicable law or agreed to in writing, software 1619 * distributed under the License is distributed on an "AS IS" BASIS, 1620 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1621 * See the License for the specific language governing permissions and 1622 * limitations under the License. 1623 */class sk{constructor(e,a,n,i,r){this.asyncQueue=e,this.timerId=a,this.targetTimeMs=n,this.op=i,this.removalCallback=r,this.deferred=new Ti,this.then=this.deferred.promise.then.bind(this.deferred.promise),this.deferred.promise.catch(o=>{})}get promise(){return this.deferred.promise}static createAndSchedule(e,a,n,i,r){const o=Date.now()+n,l=new sk(e,a,o,i,r);return l.start(n),l}start(e){this.timerHandle=setTimeout(()=>this.handleDelayElapsed(),e)}skipDelay(){return this.handleDelayElapsed()}cancel(e){this.timerHandle!==null&&(this.clearTimeout(),this.deferred.reject(new X(z.CANCELLED,"Operation cancelled"+(e?": "+e:""))))}handleDelayElapsed(){this.asyncQueue.enqueueAndForget(()=>this.timerHandle!==null?(this.clearTimeout(),this.op().then(e=>this.deferred.resolve(e))):Promise.resolve())}clearTimeout(){this.timerHandle!==null&&(this.removalCallback(this),clearTimeout(this.timerHandle),this.timerHandle=null)}}function lk(t,e){if(Vi("AsyncQueue",`${e}: ${t}`),Ou(t))return new X(z.UNAVAILABLE,`${e}: ${t}`);throw t}/** 1624 * @license 1625 * Copyright 2017 Google LLC 1626 * 1627 * Licensed under the Apache License, Version 2.0 (the "License");
1628 * you may not use this file except in compliance with the License. 1629 * You may obtain a copy of the License at 1630 * 1631 * http://www.apache.org/licenses/LICENSE-2.0 1632 * 1633 * Unless required by applicable law or agreed to in writing, software 1634 * distributed under the License is distributed on an "AS IS" BASIS, 1635 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1636 * See the License for the specific language governing permissions and 1637 * limitations under the License. 1638 */class ol{constructor(e){this.comparator=e?(a,n)=>e(a,n)||oe.comparator(a.key,n.key):(a,n)=>oe.comparator(a.key,n.key),this.keyedMap=Hc(),this.sortedSet=new tt(this.comparator)}static emptySet(e){return new ol(e.comparator)}has(e){return this.keyedMap.get(e)!=null}get(e){return this.keyedMap.get(e)}first(){return this.sortedSet.minKey()}last(){return this.sortedSet.maxKey()}isEmpty(){return this.sortedSet.isEmpty()}indexOf(e){const a=this.keyedMap.get(e);return a?this.sortedSet.indexOf(a):-1}get size(){return this.sortedSet.size}forEach(e){this.sortedSet.inorderTraversal((a,n)=>(e(a),!1))}add(e){const a=this.delete(e.key);return a.copy(a.keyedMap.insert(e.key,e),a.sortedSet.insert(e,null))}delete(e){const a=this.get(e);return a?this.copy(this.keyedMap.remove(e),this.sortedSet.remove(a)):this}isEqual(e){if(!(e instanceof ol)||this.size!==e.size)return!1;const a=this.sortedSet.getIterator(),n=e.sortedSet.getIterator();for(;a.hasNext();){const i=a.getNext().key,r=n.getNext().key;if(!i.isEqual(r))return!1}return!0}toString(){const e=[];return this.forEach(a=>{e.push(a.toString())}),e.length===0?"DocumentSet ()":`DocumentSet ( 1639 `+e.join(` 1640`)+` 1641)`}copy(e,a){const n=new ol;return n.comparator=this.comparator,n.keyedMap=e,n.sortedSet=a,n}}/** 1642 * @license 1643 * Copyright 2017 Google LLC 1644 * 1645 * Licensed under the Apache License, Version 2.0 (the "License"); 1646 * you may not use this file except in compliance with the License. 1647 * You may obtain a copy of the License at 1648 * 1649 * http://www.apache.org/licenses/LICENSE-2.0 1650 * 1651 * Unless required by applicable law or agreed to in writing, software 1652 * distributed under the License is distributed on an "AS IS" BASIS, 1653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1654 * See the License for the specific language governing permissions and 1655 * limitations under the License. 1656 */class kC{constructor(){this.W_=new tt(oe.comparator)}track(e){const a=e.doc.key,n=this.W_.get(a);n?e.type!==0&&n.type===3?this.W_=this.W_.insert(a,e):e.type===3&&n.type!==1?this.W_=this.W_.insert(a,{type:n.type,doc:e.doc}):e.type===2&&n.type===2?this.W_=this.W_.insert(a,{type:2,doc:e.doc}):e.type===2&&n.type===0?this.W_=this.W_.insert(a,{type:0,doc:e.doc}):e.type===1&&n.type===0?this.W_=this.W_.remove(a):e.type===1&&n.type===2?this.W_=this.W_.insert(a,{type:1,doc:n.doc}):e.type===0&&n.type===1?this.W_=this.W_.insert(a,{type:2,doc:e.doc}):pe():this.W_=this.W_.insert(a,e)}G_(){const e=[];return this.W_.inorderTraversal((a,n)=>{e.push(n)}),e}}class El{constructor(e,a,n,i,r,o,l,c,d){this.query=e,this.docs=a,this.oldDocs=n,this.docChanges=i,this.mutatedKeys=r,this.fromCache=o,this.syncStateChanged=l,this.excludesMetadataChanges=c,this.hasCachedResults=d}static fromInitialDocuments(e,a,n,i,r){const o=[];return a.forEach(l=>{o.push({type:0,doc:l})}),new El(e,a,ol.emptySet(a),o,n,i,!0,!1,r)}get hasPendingWrites(){return!this.mutatedKeys.isEmpty()}isEqual(e){if(!(this.fromCache===e.fromCache&&this.hasCachedResults===e.hasCachedResults&&this.syncStateChanged===e.syncStateChanged&&this.mutatedKeys.isEqual(e.mutatedKeys)&&fg(this.query,e.query)&&this.docs.isEqual(e.docs)&&this.oldDocs.isEqual(e.oldDocs)))return!1;const a=this.docChanges,n=e.docChanges;if(a.length!==n.length)return!1;for(let i=0;i<a.length;i++)if(a[i].type!==n[i].type||!a[i].doc.isEqual(n[i].doc))return!1;return!0}}/** 1657 * @license 1658 * Copyright 2017 Google LLC 1659 * 1660 * Licensed under the Apache License, Version 2.0 (the "License"); 1661 * you may not use this file except in compliance with the License. 1662 * You may obtain a copy of the License at 1663 * 1664 * http://www.apache.org/licenses/LICENSE-2.0 1665 * 1666 * Unless required by applicable law or agreed to in writing, softw
1666are 1667 * distributed under the License is distributed on an "AS IS" BASIS, 1668 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1669 * See the License for the specific language governing permissions and 1670 * limitations under the License. 1671 */class PK{constructor(){this.z_=void 0,this.j_=[]}H_(){return this.j_.some(e=>e.J_())}}class RK{constructor(){this.queries=SC(),this.onlineState="Unknown",this.Y_=new Set}terminate(){(function(a,n){const i=he(a),r=i.queries;i.queries=SC(),r.forEach((o,l)=>{for(const c of l.j_)c.onError(n)})})(this,new X(z.ABORTED,"Firestore shutting down"))}}function SC(){return new Kl(t=>uL(t),fg)}async function BL(t,e){const a=he(t);let n=3;const i=e.query;let r=a.queries.get(i);r?!r.H_()&&e.J_()&&(n=2):(r=new PK,n=e.J_()?0:1);try{switch(n){case 0:r.z_=await a.onListen(i,!0);break;case 1:r.z_=await a.onListen(i,!1);break;case 2:await a.onFirstRemoteStoreListen(i)}}catch(o){const l=lk(o,`Initialization of query '${Cs(e.query)}' failed`);return void e.onError(l)}a.queries.set(i,r),r.j_.push(e),e.Z_(a.onlineState),r.z_&&e.X_(r.z_)&&ck(a)}async function UL(t,e){const a=he(t),n=e.query;let i=3;const r=a.queries.get(n);if(r){const o=r.j_.indexOf(e);o>=0&&(r.j_.splice(o,1),r.j_.length===0?i=e.J_()?0:1:!r.H_()&&e.J_()&&(i=2))}switch(i){case 0:return a.queries.delete(n),a.onUnlisten(n,!0);case 1:return a.queries.delete(n),a.onUnlisten(n,!1);case 2:return a.onLastRemoteStoreUnlisten(n);default:return}}function LK(t,e){const a=he(t);let n=!1;for(const i of e){const r=i.query,o=a.queries.get(r);if(o){for(const l of o.j_)l.X_(i)&&(n=!0);o.z_=i}}n&&ck(a)}function OK(t,e,a){const n=he(t),i=n.queries.get(e);if(i)for(const r of i.j_)r.onError(a);n.queries.delete(e)}function ck(t){t.Y_.forEach(e=>{e.next()})}var db,_C;(_C=db||(db={})).ea="default",_C.Cache="cache";class $L{constructor(e,a,n){this.query=e,this.ta=a,this.na=!1,this.ra=null,this.onlineState="Unknown",this.options=n||{}}X_(e){if(!this.options.includeMetadataChanges){const n=[];for(const i of e.docChanges)i.type!==3&&n.push(i);e=new El(e.query,e.docs,e.oldDocs,n,e.mutatedKeys,e.fromCache,e.syncStateChanged,!0,e.hasCachedResults)}let a=!1;return this.na?this.ia(e)&&(this.ta.next(e),a=!0):this.sa(e,this.onlineState)&&(this.oa(e),a=!0),this.ra=e,a}onError(e){this.ta.error(e)}Z_(e){this.onlineState=e;let a=!1;return this.ra&&!this.na&&this.sa(this.ra,e)&&(this.oa(this.ra),a=!0),a}sa(e,a){if(!e.fromCache||!this.J_())return!0;const n=a!=="Offline";return(!this.options._a||!n)&&(!e.docs.isEmpty()||e.hasCachedResults||a==="Offline")}ia(e){if(e.docChanges.length>0)return!0;const a=this.ra&&this.ra.hasPendingWrites!==e.hasPendingWrites;return!(!e.syncStateChanged&&!a)&&this.options.includeMetadataChanges===!0}oa(e){e=El.fromInitialDocuments(e.query,e.docs,e.mutatedKeys,e.fromCache,e.hasCachedResults),this.na=!0,this.ta.next(e)}J_(){return this.options.source!==db.Cache}}/** 1672 * @license 1673 * Copyright 2017 Google LLC 1674 * 1675 * Licensed under the Apache License, Version 2.0 (the "License"); 1676 * you may not use this file except in compliance with the License. 1677 * You may obtain a copy of the License at 1678 * 1679 * http://www.apache.org/licenses/LICENSE-2.0 1680 * 1681 * Unless required by applicable law or agreed to in writing, software 1682 * distributed under the License is distributed on an "AS IS" BASIS, 1683 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1684 * See the License for the specific language governing permissions and 1685 * limitations under the License. 1686 */class WL{constructor(e){this.key=e}}class GL{constructor(e){this.key=e}}class MK{constructor(e,a){this.query=e,this.Ta=a,this.Ea=null,this.hasCachedResults=!1,this.current=!1,this.da=Se(),this.mutatedKeys=Se(),this.Aa=pL(e),this.Ra=new ol(this.Aa)}get Va(){return this.Ta}ma(e,a){const n=a?a.fa:new kC,i=a?a.Ra:this.Ra;let r=a?a.mutatedKeys:this.mutatedKeys,o=i,l=!1;const c=this.query.limitType==="F"&&i.size===this.query.limit?i.last():null,d=this.query.limitType==="L"&&i.size===this.query.limit?i.first():null;if(e.inorderTraversal((u,p)=>{const m=i.get(u),h=gg(this.query,p)?p:null,g=!!m&&this.mutatedKeys.has(m.ke
1686y),y=!!h&&(h.hasLocalMutations||this.mutatedKeys.has(h.key)&&h.hasCommittedMutations);let x=!1;m&&h?m.data.isEqual(h.data)?g!==y&&(n.track({type:3,doc:h}),x=!0):this.ga(m,h)||(n.track({type:2,doc:h}),x=!0,(c&&this.Aa(h,c)>0||d&&this.Aa(h,d)<0)&&(l=!0)):!m&&h?(n.track({type:0,doc:h}),x=!0):m&&!h&&(n.track({type:1,doc:m}),x=!0,(c||d)&&(l=!0)),x&&(h?(o=o.add(h),r=y?r.add(u):r.delete(u)):(o=o.delete(u),r=r.delete(u)))}),this.query.limit!==null)for(;o.size>this.query.limit;){const u=this.query.limitType==="F"?o.last():o.first();o=o.delete(u.key),r=r.delete(u.key),n.track({type:1,doc:u})}return{Ra:o,fa:n,ns:l,mutatedKeys:r}}ga(e,a){return e.hasLocalMutations&&a.hasCommittedMutations&&!a.hasLocalMutations}applyChanges(e,a,n,i){const r=this.Ra;this.Ra=e.Ra,this.mutatedKeys=e.mutatedKeys;const o=e.fa.G_();o.sort((u,p)=>function(h,g){const y=x=>{switch(x){case 0:return 1;case 2:case 3:return 2;case 1:return 0;default:return pe()}};return y(h)-y(g)}(u.type,p.type)||this.Aa(u.doc,p.doc)),this.pa(n),i=i!=null&&i;const l=a&&!i?this.ya():[],c=this.da.size===0&&this.current&&!i?1:0,d=c!==this.Ea;return this.Ea=c,o.length!==0||d?{snapshot:new El(this.query,e.Ra,r,o,e.mutatedKeys,c===0,d,!1,!!n&&n.resumeToken.approximateByteSize()>0),wa:l}:{wa:l}}Z_(e){return this.current&&e==="Offline"?(this.current=!1,this.applyChanges({Ra:this.Ra,fa:new kC,mutatedKeys:this.mutatedKeys,ns:!1},!1)):{wa:[]}}Sa(e){return!this.Ta.has(e)&&!!this.Ra.has(e)&&!this.Ra.get(e).hasLocalMutations}pa(e){e&&(e.addedDocuments.forEach(a=>this.Ta=this.Ta.add(a)),e.modifiedDocuments.forEach(a=>{}),e.removedDocuments.forEach(a=>this.Ta=this.Ta.delete(a)),this.current=e.current)}ya(){if(!this.current)return[];const e=this.da;this.da=Se(),this.Ra.forEach(n=>{this.Sa(n.key)&&(this.da=this.da.add(n.key))});const a=[];return e.forEach(n=>{this.da.has(n)||a.push(new GL(n))}),this.da.forEach(n=>{e.has(n)||a.push(new WL(n))}),a}ba(e){this.Ta=e.Ts,this.da=Se();const a=this.ma(e.documents);return this.applyChanges(a,!0)}Da(){return El.fromInitialDocuments(this.query,this.Ra,this.mutatedKeys,this.Ea===0,this.hasCachedResults)}}class DK{constructor(e,a,n){this.query=e,this.targetId=a,this.view=n}}class qK{constructor(e){this.key=e,this.va=!1}}class zK{constructor(e,a,n,i,r,o){this.localStore=e,this.remoteStore=a,this.eventManager=n,this.sharedClientState=i,this.currentUser=r,this.maxConcurrentLimboResolutions=o,this.Ca={},this.Fa=new Kl(l=>uL(l),fg),this.Ma=new Map,this.xa=new Set,this.Oa=new tt(oe.comparator),this.Na=new Map,this.La=new ek,this.Ba={},this.ka=new Map,this.qa=Al.kn(),this.onlineState="Unknown",this.Qa=void 0}get isPrimaryClient(){return this.Qa===!0}}async function VK(t,e,a=!0){const n=ZL(t);let i;const r=n.Fa.get(e);return r?(n.sharedClientState.addLocalQueryTarget(r.targetId),i=r.view.Da()):i=await KL(n,e,a,!0),i}async function HK(t,e){const a=ZL(t);await KL(a,e,!0,!1)}async function KL(t,e,a,n){const i=await cK(t.localStore,ei(e)),r=i.targetId,o=t.sharedClientState.addLocalQueryTarget(r,a);let l;return n&&(l=await FK(t,e,r,o==="current",i.resumeToken)),t.isPrimaryClient&&a&&DL(t.remoteStore,i),l}async function FK(t,e,a,n,i){t.Ka=(p,m,h)=>async function(y,x,v,w){let S=x.view.ma(v);S.ns&&(S=await xC(y.localStore,x.query,!1).then(({documents:C})=>x.view.ma(C,S)));const T=w&&w.targetChanges.get(x.targetId),P=w&&w.targetMismatches.get(x.targetId)!=null,M=x.view.applyChanges(S,y.isPrimaryClient,T,P);return EC(y,x.targetId,M.wa),M.snapshot}(t,p,m,h);const r=await xC(t.localStore,e,!0),o=new MK(e,r.Ts),l=o.ma(r.documents),c=qu.createSynthesizedTargetChangeForCurrentChange(a,n&&t.onlineState!=="Offline",i),d=o.applyChanges(l,t.isPrimaryClient,c);EC(t,a,d.wa);const u=new DK(e,a,o);return t.Fa.set(e,u),t.Ma.has(a)?t.Ma.get(a).push(e):t.Ma.set(a,[e]),d.snapshot}async function BK(t,e,a){const n=he(t),i=n.Fa.get(e),r=n.Ma.get(i.targetId);if(r.length>1)return n.Ma.set(i.targetId,r.filter(o=>!fg(o,e))),void n.Fa.delete(e);n.isPrimaryClient?(n.sharedClientState.removeLocalQueryTarget(i.targetId),n.sharedClientState.isActiveQueryTarget(i.targetId)||await cb(n.localStore,i.targetId,!1).then(()=>
1686{n.sharedClientState.clearQueryState(i.targetId),a&&nk(n.remoteStore,i.targetId),ub(n,i.targetId)}).catch(Lu)):(ub(n,i.targetId),await cb(n.localStore,i.targetId,!0))}async function UK(t,e){const a=he(t),n=a.Fa.get(e),i=a.Ma.get(n.targetId);a.isPrimaryClient&&i.length===1&&(a.sharedClientState.removeLocalQueryTarget(n.targetId),nk(a.remoteStore,n.targetId))}async function $K(t,e,a){const n=YK(t);try{const i=await function(o,l){const c=he(o),d=xt.now(),u=l.reduce((h,g)=>h.add(g.key),Se());let p,m;return c.persistence.runTransaction("Locally write mutations","readwrite",h=>{let g=Hi(),y=Se();return c.cs.getEntries(h,u).next(x=>{g=x,g.forEach((v,w)=>{w.isValidDocument()||(y=y.add(v))})}).next(()=>c.localDocuments.getOverlayedDocuments(h,g)).next(x=>{p=x;const v=[];for(const w of l){const S=mG(w,p.get(w.key).overlayedDocument);S!=null&&v.push(new Xr(w.key,S,nL(S.value.mapValue),In.exists(!0)))}return c.mutationQueue.addMutationBatch(h,d,v,l)}).next(x=>{m=x;const v=x.applyToLocalDocumentSet(p,y);return c.documentOverlayCache.saveOverlays(h,x.batchId,v)})}).then(()=>({batchId:m.batchId,changes:hL(p)}))}(n.localStore,e);n.sharedClientState.addPendingMutation(i.batchId),function(o,l,c){let d=o.Ba[o.currentUser.toKey()];d||(d=new tt(je)),d=d.insert(l,c),o.Ba[o.currentUser.toKey()]=d}(n,i.batchId,a),await Vu(n,i.changes),await kg(n.remoteStore)}catch(i){const r=lk(i,"Failed to persist write");a.reject(r)}}async function JL(t,e){const a=he(t);try{const n=await oK(a.localStore,e);
1686e.targetChanges.forEach((i,r)=>{const o=a.Na.get(r);o&&(Oe(i.addedDocuments.size+i.modifiedDocuments.size+i.removedDocuments.size<=1),i.addedDocuments.size>0?o.va=!0:i.modifiedDocuments.size>0?Oe(o.va):i.removedDocuments.size>0&&(Oe(o.va),o.va=!1))}),await Vu(a,n,e)}catch(n){await Lu(n)}}function AC(t,e,a){const n=he(t);if(n.isPrimaryClient&&a===0||!n.isPrimaryClient&&a===1){const i=[];n.Fa.forEach((r,o)=>{const l=o.view.Z_(e);l.snapshot&&i.push(l.snapshot)}),function(o,l){const c=he(o);c.onlineState=l;let d=!1;c.queries.forEach((u,p)=>{for(const m of p.j_)m.Z_(l)&&(d=!0)}),d&&ck(c)}(n.eventManager,e),i.length&&n.Ca.d_(i),n.onlineState=e,n.isPrimaryClient&&n.sharedClientState.setOnlineState(e)}}async function WK(t,e,a){const n=he(t);n.sharedClientState.updateQueryState(e,"rejected",a);const i=n.Na.get(e),r=i&&i.key;if(r){let o=new tt(oe.comparator);o=o.insert(r,aa.newNoDocument(r,me.min()));const l=Se().add(r),c=new vg(me.min(),new Map,new tt(je),o,l);await JL(n,c),n.Oa=n.Oa.remove(r),n.Na.delete(e),dk(n)}else await cb(n.localStore,e,!1).then(()=>ub(n,e,a)).catch(Lu)}async function GK(t,e){const a=he(t),n=e.batch.batchId;try{const i=await rK(a.localStore,e);XL(a,n,null),QL(a,n),a.sharedClientState.updateMutationState(n,"acknowledged"),await Vu(a,i)}catch(i){await Lu(i)}}async function KK(t,e,a){const n=he(t);try{const i=await function(o,l){const c=he(o);return c.persistence.runTransaction("Reject batch","readwrite-primary",d=>{let u;return c.mutationQueue.lookupMutationBatch(d,l).next(p=>
1686(Oe(p!==null),u=p.keys(),c.mutationQueue.removeMutationBatch(d,p))).next(()=>c.mutationQueue.performConsistencyCheck(d)).next(()=>c.documentOverlayCache.removeOverlaysForBatchId(d,u,l)).next(()=>c.localDocuments.recalculateAndSaveOverlaysForDocumentKeys(d,u)).next(()=>c.localDocuments.getDocuments(d,u))})}(n.localStore,e);XL(n,e,a),QL(n,e),n.sharedClientState.updateMutationState(e,"rejected",a),await Vu(n,i)}catch(i){await Lu(i)}}function QL(t,e){(t.ka.get(e)||[]).forEach(a=>{a.resolve()}),t.ka.delete(e)}function XL(t,e,a){const n=he(t);let i=n.Ba[n.currentUser.toKey()];if(i){const r=i.get(e);r&&(a?r.reject(a):r.resolve(),i=i.remove(e)),n.Ba[n.currentUser.toKey()]=i}}function ub(t,e,a=null){t.sharedClientState.removeLocalQueryTarget(e);for(const n of t.Ma.get(e))t.Fa.delete(n),a&&t.Ca.$a(n,a);t.Ma.delete(e),t.isPrimaryClient&&t.La.gr(e).forEach(n=>{t.La.containsKey(n)||YL(t,n)})}function YL(t,e){t.xa.delete(e.path.canonicalString());const a=t.Oa.get(e);a!==null&&(nk(t.remoteStore,a),t.Oa=t.Oa.remove(e),t.Na.delete(a),dk(t))}function EC(t,e,a){for(const n of a)n instanceof WL?(t.La.addReference(n.key,e),JK(t,n)):n instanceof GL?(Y("SyncEngine","Document no longer in limbo: "+n.key),t.La.removeReference(n.key,e),t.La.containsKey(n.key)||YL(t,n.key)):pe()}function JK(t,e){const a=e.key,n=a.path.canonicalString();t.Oa.get(a)||t.xa.has(n)||(Y("SyncEngine","New document in limbo: "+a),t.xa.add(n),dk(t))}function dk(t){for(;t.xa.size>0&&t.Oa.size<t.maxConcurrentLimboResolutions;){const e=t.xa.values().next().value;t.xa.delete(e);const a=new oe(Ue.fromString(e)),n=t.qa.next();t.Na.set(n,new qK(a)),t.Oa=t.Oa.insert(a,n),DL(t.remoteStore,new yr(ei(Kw(a.path)),n,"TargetPurposeLimboResolution",Fw.oe))}}async function Vu(t,e,a){const n=he(t),i=[],r=[],o=[];n.Fa.isEmpty()||(n.Fa.forEach((l,c)=>{o.push(n.Ka(c,e,a).then(d=>{var u;if((d||a)&&n.isPrimaryClient){const p=d?!d.fromCache:(u=a==null?void 0:a.targetChanges.get(c.targetId))===null||u===void 0?void 0:u.current;n.sharedClientState.updateQueryState(c.targetId,p?"current":"not-current")}if(d){i.push(d);const p=ak.Wi(c.targetId,d);r.push(p)}}))}),await Promise.all(o),n.Ca.d_(i),await async function(c,d){const u=he(c);try{await u.persistence.runTransaction("notifyLocalViewChanges","readwrite",p=>H.forEach(d,m=>H.forEach(m.$i,h=>u.persistence.referenceDelegate.addReference(p,m.targetId,h)).next(()=>H.forEach(m.Ui,h=>u.persistence.referenceDelegate.removeReference(p,m.targetId,h)))))}catch(p){if(!Ou(p))throw p;Y("LocalStore","Failed to update sequence numbers: "+p)}for(const p of d){const m=p.targetId;if(!p.fromCache){const h=u.os.get(m),g=h.snapshotVersion,y=h.withLastLimboFreeSnapshotVersion(g);u.os=u.os.insert(m,y)}}}(n.localStore,r))}async function QK(t,e){const a=he(t);if(!a.currentUser.isEqual(e)){Y("SyncEngine","User change. New user:",e.toKey());const n=await RL(a.localStore,e);a.currentUser=e,function(r,o){r.ka.forEach(l=>{l.forEach(c=>{c.reject(new X(z.CANCELLED,o))})}),r.ka.clear()}(a,"'waitForPendingWrites' promise is rejected due to a user change."),a.sharedClientState.handleUserChange(e,n.removedBatchIds,n.addedBatchIds),await Vu(a,n.hs)}}function XK(t,e){const a=he(t),n=a.Na.get(e);if(n&&n.va)return Se().add(n.key);{let i=Se();const r=a.Ma.get(e);if(!r)return i;for(const o of r){const l=a.Fa.get(o);i=i.unionWith(l.view.Va)}return i}}function ZL(t){const e=he(t);return e.remoteStore.remoteSyncer.applyRemoteEvent=JL.bind(null,e),e.remoteStore.remoteSyncer.getRemoteKeysForTarget=XK.bind(null,e),e.remoteStore.remoteSyncer.rejectListen=WK.bind(null,e),e.Ca.d_=LK.bind(null,e.eventManager),e.Ca.$a=OK.bind(null,e.eventManager),e}function YK(t){const e=he(t);return e.remoteStore.remoteSyncer.applySuccessfulWrite=GK.bind(null,e),e.remoteStore.remoteSyncer.rejectFailedWrite=KK.bind(null,e),e}class Dh{constructor(){this.kind="memory",this.synchronizeTabs=!1}async initialize(e){this.serializer=bg(e.databaseInfo.databaseId),this.sharedClientState=this.Wa(e),this.persistence=this.Ga(e),await this.persistence.start(),this.localStore=this.za(e),this.gcScheduler=this.ja(e,this.localStore),this.indexBackfillerScheduler
1686=this.Ha(e,this.localStore)}ja(e,a){return null}Ha(e,a){return null}za(e){return iK(this.persistence,new aK,e.initialUser,this.serializer)}Ga(e){return new ZG(tk.Zr,this.serializer)}Wa(e){return new uK}async terminate(){var e,a;(e=this.gcScheduler)===null||e===void 0||e.stop(),(a=this.indexBackfillerScheduler)===null||a===void 0||a.stop(),this.sharedClientState.shutdown(),await this.persistence.shutdown()}}Dh.provider={build:()=>new Dh};class pb{async initialize(e,a){this.localStore||(this.localStore=e.localStore,this.sharedClientState=e.sharedClientState,this.datastore=this.createDatastore(a),this.remoteStore=this.createRemoteStore(a),this.eventManager=this.createEventManager(a),this.syncEngine=this.createSyncEngine(a,!e.synchronizeTabs),this.sharedClientState.onlineStateHandler=n=>AC(this.syncEngine,n,1),this.remoteStore.remoteSyncer.handleCredentialChange=QK.bind(null,this.syncEngine),await IK(this.remoteStore,this.syncEngine.isPrimaryClient))}createEventManager(e){return function(){return new RK}()}createDatastore(e){const a=bg(e.databaseInfo.databaseId),n=function(r){return new fK(r)}(e.databaseInfo);return function(r,o,l,c){return new xK(r,o,l,c)}(e.authCredentials,e.appCheckCredentials,n,a)}createRemoteStore(e){return function(n,i,r,o,l){return new bK(n,i,r,o,l)}(this.localStore,this.datastore,e.asyncQueue,a=>AC(this.syncEngine,a,0),function(){return bC.D()?new bC:new pK}())}createSyncEngine(e,a){return function(i,r,o,l,c,d,u){const p=new zK(i,r,o,l,c,d);return u&&(p.Qa=!0),p}(this.localStore,this.remoteStore,this.eventManager,this.sharedClientState,e.initialUser,e.maxConcurrentLimboResolutions,a)}async terminate(){var e,a;await async function(i){const r=he(i);Y("RemoteStore","RemoteStore shutting down."),r.L_.add(5),await zu(r),r.k_.shutdown(),r.q_.set("Unknown")}(this.remoteStore),(e=this.datastore)===null||e===void 0||e.terminate(),(a=this.eventManager)===null||a===void 0||a.terminate()}}pb.provider={build:()=>new pb};/** 1687 * @license 1688 * Copyright 2020 Google LLC 1689 * 1690 * Licensed under the Apache License, Version 2.0 (the "License"); 1691 * you may not use this file except in compliance with the License. 1692 * You may obtain a copy of the License at 1693 * 1694 * http://www.apache.org/licenses/LICENSE-2.0 1695 * 1696 * Unless required by applicable law or agreed to in writing, software 1697 * distributed under the License is distributed on an "AS IS" BASIS, 1698 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1699 * See the License for the specific language governing permissions and 1700 * limitations under the License. 1701 *//** 1702 * @license 1703 * Copyright 2017 Google LLC 1704 * 1705 * Licensed under the Apache License, Version 2.0 (the "License"); 1706 * you may not use this file except in compliance with the License. 1707 * You may obtain a copy of the License at 1708 * 1709 * http://www.apache.org/licenses/LICENSE-2.0 1710 * 1711 * Unless required by applicable law or agreed to in writing, software 1712 * distributed under the License is distributed on an "AS IS" BASIS, 1713 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1714 * See the License for the specific language governing permissions and 1715 * limitations under the License. 1716 */class e3{constructor(e){this.observer=e,this.muted=!1}next(e){this.muted||this.observer.next&&this.Ya(this.observer.next,e)}error(e){this.muted||(this.observer.error?this.Ya(this.observer.error,e):Vi("Uncaught Error in snapshot listener:",e.toString()))}Za(){this.muted=!0}Ya(e,a){setTimeout(()=>{this.muted||e(a)},0)}}/** 1717 * @license 1718 * Copyright 2017 Google LLC 1719 * 1720 * Licensed under the Apache License, Version 2.0 (the "License"); 1721 * you may not use this file except in compliance with the License. 1722 * You may obtain a copy of the License at 1723 * 1724 * http://www.apache.org/licenses/LICENSE-2.0 1725 * 1726 * Unless required by applicable law or agreed to in writing, software 1727 * distributed under the License is distributed on an "AS IS" BASIS, 1728 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1729 * See the License for the specific language governing permissions and 1730 * limitations under the License. 1731 */class ZK{constructor(e,a,n,i,r){this.authCredentials=e,this.appCheckCredentials=a,this.asyncQueue=n,this.databaseInfo=i,this.user=ea.UNAUTHENTICATED,this.clientId=eL.newId(),this.authCredentialListener=()=>Promise.resolve(),this.appCheckCredentialListener=()=>Promise.resolve(),this._uninitializedComponentsProvider=r,this.authCredentials.start(n,async o=>{Y("FirestoreClient","Received user=",o.uid),await this.authCredentialListener(o),this.user=o}),this.appCheckCredentials.start(n,o=>(Y("FirestoreClient","Received new app check token=",o),this.appCheckCredentialListener(o,this.user)))}get configuration(){return{asyncQueue:this.asyncQueue,databaseInfo:this.databaseInfo,clientId:this.clientId,authCredentials:this.authCredentials,appCheckCredentials:this.appCheckCredentials,initialUser:this.user,maxConcurrentLimboResolutions:100}}setCredentialChangeListener(e){this.authCredentialListener=e}setAppCheckTokenChangeListener(e){this.appCheckCredentialListener=e}terminate(){this.asyncQueue.enterRestrictedMode();const e=new Ti;return this.asyncQueue.enqueueAndForgetEvenWhileRestricted(async()=>{try{this._onlineComponents&&await this._onlineComponents.terminate(),this._offlineComponents&&await this._offlineComponents.terminate(),this.authCredentials.shutdown(),this.appCheckCredentials.shutdown(),e.resolve()}catch(a){const n=lk(a,"Failed to shutdown persistence");e.reject(n)}}),e.promise}}async function N0(t,e){t.asyncQueue.verifyOperationInProgress(),Y("FirestoreClient","Initializing OfflineComponentProvider");const a=t.configuration;await e.initialize(a);let n=a.initialUser;t.setCredentialChangeListener(async i=>{n.isEqual(i)||(await RL(e.localStore,i),n=i)}),e.persistence.setDatabaseDeletedListener(()=>t.terminate()),t._offlineComponents=e}async function CC(t,e){t.asyncQueue.verifyOperationInProgress();const a=await eJ(t);Y("FirestoreClient","Initializing OnlineComponentProvider"),await e.initialize(a,t.configuration),t.setCredentialChangeListener(n=>wC(e.remoteStore,n)),t.setAppCheckTokenChangeListener((n,i)=>wC(e.remoteStore,i)),t._onlineComponents=e}async function eJ(t){if(!t._offlineComponents)if(t._uninitializedComponentsProvider){Y("FirestoreClient","Using user provided OfflineComponentProvider");try{await N0(t,t._uninitializedComponentsProvider._offline)}catch(e){const a=e;if(!function(i){return i.name==="FirebaseError"?i.code===z.FAILED_PRECONDITION||i.code===z.UNIMPLEMENT
1731ED:!(typeof DOMException<"u"&&i instanceof DOMException)||i.code===22||i.code===20||i.code===11}(a))throw a;wl("Error using user provided cache. Falling back to memory cache: "+a),await N0(t,new Dh)}}else Y("FirestoreClient","Using default OfflineComponentProvider"),await N0(t,new Dh);return t._offlineComponents}async function t3(t){return t._onlineComponents||(t._uninitializedComponentsProvider?(Y("FirestoreClient","Using user provided OnlineComponentProvider"),await CC(t,t._uninitializedComponentsProvider._online)):(Y("FirestoreClient","Using default OnlineComponentProvider"),await CC(t,new pb))),t._onlineComponents}function tJ(t){return t3(t).then(e=>e.syncEngine)}async function a3(t){const e=await t3(t),a=e.eventManager;return a.onListen=VK.bind(null,e.syncEngine),a.onUnlisten=BK.bind(null,e.syncEngine),a.onFirstRemoteStoreListen=HK.bind(null,e.syncEngine),a.onLastRemoteStoreUnlisten=UK.bind(null,e.syncEngine),a}function aJ(t,e,a={}){const n=new Ti;return t.asyncQueue.enqueueAndForget(async()=>function(r,o,l,c,d){const u=new e3({next:m=>{u.Za(),o.enqueueAndForget(()=>UL(r,p));const h=m.docs.has(l);!h&&m.fromCache?d.reject(new X(z.UNAVAILABLE,"Failed to get document because the client is offline.")):h&&m.fromCache&&c&&c.source==="server"?d.reject(new X(z.UNAVAILABLE,'Failed to get document from server. (However, this document does exist in the local cache. Run again without setting source to "server" to retrieve the cached document.)')):d.resolve(m)},error:m=>d.reject(m)}),p=new $L(Kw(l.path),u,{includeMetadataChanges:!0,_a:!0});return BL(r,p)}(await a3(t),t.asyncQueue,e,a,n)),n.promise}function nJ(t,e,a={}){const n=new Ti;return t.asyncQueue.enqueueAndForget(async()=>function(r,o,l,c,d){const u=new e3({next:m=>{u.Za(),o.enqueueAndForget(()=>UL(r,p)),m.fromCache&&c.source==="server"?d.reject(new X(z.UNAVAILABLE,'Failed to get documents from server. (However, these documents may exist in the local cache. Run again without setting source to "server" to retrieve the cached documents.)')):d.resolve(m)},error:m=>d.reject(m)}),p=new $L(l,u,{includeMetadataChanges:!0,_a:!0});return BL(r,p)}(await a3(t),t.asyncQueue,e,a,n)),n.promise}/** 1732 * @license 1733 * Copyright 2023 Google LLC 1734 * 1735 * Licensed under the Apache License, Version 2.0 (the "License"); 1736 * you may not use this file except in compliance with the License. 1737 * You may obtain a copy of the License at 1738 * 1739 * http://www.apache.org/licenses/LICENSE-2.0 1740 * 1741 * Unless required by applicable law or agreed to in writing, software 1742 * distributed under the License is distributed on an "AS IS" BASIS, 1743 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1744 * See the License for the specific language governing permissions and 1745 * limitations under the License. 1746 */function n3(t){const e={};return t.timeoutSeconds!==void 0&&(e.timeoutSeconds=t.timeoutSeconds),e}/** 1747 * @license 1748 * Copyright 2020 Google LLC 1749 * 1750 * Licensed under the Apache License, Version 2.0 (the "License"); 1751 * you may not use this file except in compliance with the License. 1752 * You may obtain a copy of the License at 1753 * 1754 * http://www.apache.org/licenses/LICENSE-2.0 1755 * 1756 * Unless required by applicable law or agreed to in writing, software 1757 * distributed under the License is distributed on an "AS IS" BASIS, 1758 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1759 * See the License for the specific language governing permissions and 1760 * limitations under the License. 1761 */const jC=new Map;/** 1762 * @license 1763 * Copyright 2017 Google LLC 1764 * 1765 * Licensed under the Apache License, Version 2.0 (the "License"); 1766 * you may not use this file except in compliance with the License. 1767 * You may obtain a copy of the License at 1768 * 1769 * http://www.apache.org/licenses/LICENSE-2.0 1770 * 1771 * Unless required by applicable law or agreed to in writing, software 1772 * distributed under the License is distributed on an "AS IS" BASIS, 1773 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1774 * See the License for the specific language governing permissions and 1775 * limitations under the License. 1776 */function i3(t,e,a){if(!a)throw new X(z.INVALID_ARGUMENT,`Function ${t}() cannot be called with an empty ${e}.`)}function iJ(t,e,a,n){if(e===!0&&n===!0)throw new X(z.INVALID_ARGUMENT,`${t} and ${a} cannot be used together.`)}function TC(t){if(!oe.isDocumentKey(t))throw new X(z.INVALID_ARGUMENT,`Invalid document reference. Document references must have an even number of segments, but ${t} has ${t.length}.`)}function NC(t){if(oe.isDocumentKey(t))throw new X(z.INVALID_ARGUMENT,`Invalid collection reference. Collection references must have an odd number of segments, but ${t} has ${t.length}.`)}function Sg(t){if(t===void 0)return"undefined";if(t===null)return"null";if(typeof t=="string")return t.length>20&&(t=`${t.substring(0,20)}...`),JSON.stringify(t);if(typeof t=="number"||typeof t=="boolean")return""+t;if(typeof t=="object"){if(t instanceof Array)return"an array";{const e=function(n){return n.constructor?n.constructor.name:null}(t);return e?`a custom ${e} object`:"an object"}}return typeof t=="function"?"a function":pe()}function Fi(t,e){if("_delegate"in t&&(t=t._delegate),!(t instanceof e)){if(e.name===t.constructor.name)throw new X(z.INVALID_ARGUMENT,"Type does not match the expected instance. Did you pass a reference from a different Firestore SDK?");{const a=Sg(t);throw new X(z.INVALID_ARGUMENT,`Expected type '${e.name}', but it was: ${a}`)}}return t}/** 1777 * @license 1778 * Copyright 2020 Google LLC 1779 * 1780 * Licensed under the Apache License, Version 2.0 (the "License");
1781 * you may not use this file except in compliance with the License. 1782 * You may obtain a copy of the License at 1783 * 1784 * http://www.apache.org/licenses/LICENSE-2.0 1785 * 1786 * Unless required by applicable law or agreed to in writing, software 1787 * distributed under the License is distributed on an "AS IS" BASIS, 1788 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1789 * See the License for the specific language governing permissions and 1790 * limitations under the License. 1791 */class IC{constructor(e){var a,n;if(e.host===void 0){if(e.ssl!==void 0)throw new X(z.INVALID_ARGUMENT,"Can't provide ssl option if host option is not set");this.host="firestore.googleapis.com",this.ssl=!0}else this.host=e.host,this.ssl=(a=e.ssl)===null||a===void 0||a;if(this.credentials=e.credentials,this.ignoreUndefinedProperties=!!e.ignoreUndefinedProperties,this.localCache=e.localCache,e.cacheSizeBytes===void 0)this.cacheSizeBytes=41943040;else{if(e.cacheSizeBytes!==-1&&e.cacheSizeBytes<1048576)throw new X(z.INVALID_ARGUMENT,"cacheSizeBytes must be at least 1048576");this.cacheSizeBytes=e.cacheSizeBytes}iJ("experimentalForceLongPolling",e.experimentalForceLongPolling,"experimentalAutoDetectLongPolling",e.experimentalAutoDetectLongPolling),this.experimentalForceLongPolling=!!e.experimentalForceLongPolling,this.experimentalForceLongPolling?this.experimentalAutoDetectLongPolling=!1:e.experimentalAutoDetectLongPolling===void 0?this.experimentalAutoDetectLongPolling=!0:this.experimentalAutoDetectLongPolling=!!e.experimentalAutoDetectLongPolling,this.experimentalLongPollingOptions=n3((n=e.experimentalLongPollingOptions)!==null&&n!==void 0?n:{}),function(r){if(r.timeoutSeconds!==void 0){if(isNaN(r.timeoutSeconds))throw new X(z.INVALID_ARGUMENT,`invalid long polling timeout: ${r.timeoutSeconds} (must not be NaN)`);if(r.timeoutSeconds<5)throw new X(z.INVALID_ARGUMENT,`invalid long polling timeout: ${r.timeoutSeconds} (minimum allowed value is 5)`);if(r.timeoutSeconds>30)throw new X(z.INVALID_ARGUMENT,`invalid long polling timeout: ${r.timeoutSeconds} (maximum allowed value is 30)`)}}(this.experimentalLongPollingOptions),this.useFetchStreams=!!e.useFetchStreams}isEqual(e){return this.host===e.host&&this.ssl===e.ssl&&this.credentials===e.credentials&&this.cacheSizeBytes===e.cacheSizeBytes&&this.experimentalForceLongPolling===e.experimentalForceLongPolling&&this.experimentalAutoDetectLongPolling===e.experimentalAutoDetectLongPolling&&function(n,i){return n.timeoutSeconds===i.timeoutSeconds}(this.experimentalLongPollingOptions,e.experimentalLongPollingOptions)&&this.ignoreUndefinedProperties===e.ignoreUndefinedProperties&&this.useFetchStreams===e.useFetchStreams}}class _g{constructor(e,a,n,i){this._authCredentials=e,this._appCheckCredentials=a,this._databaseId=n,this._app=i,this.type="firestore-lite",this._persistenceKey="(lite)",this._settings=new IC({}),this._settingsFrozen=!1,this._terminateTask="notTerminated"}get app(){if(!this._app)throw new X(z.FAILED_PRECONDITION,"Firestore was not initialized using the Firebase SDK. 'app' is not available");return this._app}get _initialized(){return this._settingsFrozen}get _terminated(){return this._terminateTask!=="notTerminated"}_setSettings(e){if(this._settingsFrozen)throw new X(z.FAILED_PRECONDITION,"Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.");this._settings=new IC(e),e.credentials!==void 0&&(this._authCredentials=function(n){if(!n)return new kW;switch(n.type){case"firstParty":return new EW(n.sessionIndex||"0",n.iamToken||null,n.authTokenFactory||null);case"provider":return n.client;default:throw new X(z.INVALID_ARGUMENT,"makeAuthCredentialsProvider failed due to invalid credential type")}}(e.credentials))}_getSettings(){return this._settings}_freezeSettings(){return this._settingsFrozen=!0,this._settings}_delete(){return this._terminateTask==="notTerminated"&&(this._terminateTask=this._terminate()),this._terminateTask}async _restart(){this._terminateTask==="notTerminated"?await this._terminate():this._terminateTask="notTerminated"}toJSON(){return{app:this._app,databaseId:this._databaseId,settings:this._settings}}_terminate(){return function(a){const n=jC.get(a);n&&(Y("ComponentProvider","Removing Datastore"),jC.delete(a),n.terminate())}(this),Promise.resolve()}}function rJ(t,e,a,n={}){var i;const r=(t=Fi(t,_g))._getSettings(),o=`${e}:${a}`;if(r.host!=="firestore.googleapis.com"&&r.host!==o&&wl("Host has been set in both settings() and connectFirestoreEmulator(), emulator host will be used."),t._setSettings(Object.assign(Object.assign({},r),{host:o,ssl:!1})),n.mockUserToken){let l,c;if(typeof n.mockUserToken=="string")l=n.mockUserToken,c=ea.MOCK_USER;else{l=zR(n.mockUserToken,(i=t._app)===null||i===void 0?void 0:i.options.projectId);const d=n.mockUserToken.sub||n.mockUserToken.user_id;if(!d)throw new X(z.INVALID_ARGUMENT,"mockUserToken must contain 'sub' or 'user_id' field!");c=new ea(d)}
1791t._authCredentials=new SW(new ZR(l,c))}}/** 1792 * @license 1793 * Copyright 2020 Google LLC 1794 * 1795 * Licensed under the Apache License, Version 2.0 (the "License"); 1796 * you may not use this file except in compliance with the License. 1797 * You may obtain a copy of the License at 1798 * 1799 * http://www.apache.org/licenses/LICENSE-2.0 1800 * 1801 * Unless required by applicable law or agreed to in writing, software 1802 * distributed under the License is distributed on an "AS IS" BASIS, 1803 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1804 * See the License for the specific language governing permissions and 1805 * limitations under the License. 1806 */class Ql{constructor(e,a,n){this.converter=a,this._query=n,this.type="query",this.firestore=e}withConverter(e){return new Ql(this.firestore,e,this._query)}}class Ia{constructor(e,a,n){this.converter=a,this._key=n,this.type="document",this.firestore=e}get _path(){return this._key.path}get id(){return this._key.path.lastSegment()}get path(){return this._key.path.canonicalString()}get parent(){return new Ir(this.firestore,this.converter,this._key.path.popLast())}withConverter(e){return new Ia(this.firestore,e,this._key)}}class Ir extends Ql{constructor(e,a,n){super(e,a,Kw(n)),this._path=n,this.type="collection"}get id(){return this._query.path.lastSegment()}get path(){return this._query.path.canonicalString()}get parent(){const e=this._path.popLast();return e.isEmpty()?null:new Ia(this.firestore,null,new oe(e))}withConverter(e){return new Ir(this.firestore,e,this._path)}}function ga(t,e,...a){if(t=et(t),i3("collection","path",e),t instanceof _g){const n=Ue.fromString(e,...a);return NC(n),new Ir(t,null,n)}{if(!(t instanceof Ia||t instanceof Ir))throw new X(z.INVALID_ARGUMENT,"Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore");const n=t._path.child(Ue.fromString(e,...a));return NC(n),new Ir(t.firestore,null,n)}}function lu(t,e,...a){if(t=et(t),arguments.length===1&&(e=eL.newId()),i3("doc","path",e),t instanceof _g){const n=Ue.fromString(e,...a);return TC(n),new Ia(t,null,new oe(n))}{if(!(t instanceof Ia||t instanceof Ir))throw new X(z.INVALID_ARGUMENT,"Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore");const n=t._path.child(Ue.fromString(e,...a));return TC(n),new Ia(t.firestore,t instanceof Ir?t.converter:null,new oe(n))}}/** 1807 * @license 1808 * Copyright 2020 Google LLC 1809 * 1810 * Licensed under the Apache License, Version 2.0 (the "License"); 1811 * you may not use this file except in compliance with the License. 1812 * You may obtain a copy of the License at 1813 * 1814 * http://www.apache.org/licenses/LICENSE-2.0 1815 * 1816 * Unless required by applicable law or agreed to in writing, software 1817 * distributed under the License is distributed on an "AS IS" BASIS, 1818 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1819 * See the License for the specific language governing permissions and 1820 * limitations under the License. 1821 */class PC{constructor(e=Promise.resolve()){this.Pu=[],this.Iu=!1,this.Tu=[],this.Eu=null,this.du=!1,this.Au=!1,this.Ru=[],this.t_=new OL(this,"async_queue_retry"),this.Vu=()=>{const n=T0();n&&Y("AsyncQueue","Visibility state changed to "+n.visibilityState),this.t_.jo()},this.mu=e;const a=T0();a&&typeof a.addEventListener=="function"&&a.addEventListener("visibilitychange",this.Vu)}get isShuttingDown(){return this.Iu}enqueueAndForget(e){this.enqueue(e)}enqueueAndForgetEvenWhileRestricted(e){this.fu(),this.gu(e)}enterRestrictedMode(e){if(!this.Iu){this.Iu=!0,this.Au=e||!1;const a=T0();a&&typeof a.removeEventListener=="function"&&a.removeEventListener("visibilitychange",this.Vu)}}enqueue(e){if(this.fu(),this.Iu)return new Promise(()=>{});const a=new Ti;return this.gu(()=>this.Iu&&this.Au?Promise.resolve():(e().then(a.resolve,a.reject),a.promise)).then(()=>a.promise)}enqueueRetryable(e){this.enqueueAndForget(()=>(this.Pu.push(e),this.pu()))}async pu(){if(this.Pu.length!==0){try{await this.Pu[0](),this.Pu.shift(),this.t_.reset()}catch(e){if(!Ou(e))throw e;Y("AsyncQueue","Operation failed with retryable error: "+e)}this.Pu.length>0&&this.t_.Go(()=>this.pu())}}gu(e){const a=this.mu.then(()=>(this.du=!0,e().catch(n=>{this.Eu=n,this.du=!1;const i=function(o){let l=o.message||"";return o.stack&&(l=o.stack.includes(o.message)?o.stack:o.message+` 1822`+o.stack),l}(n);throw Vi("INTERNAL UNHANDLED ERROR: ",i),n}).then(n=>(this.du=!1,n))));return this.mu=a,a}enqueueAfterDelay(e,a,n){this.fu(),this.Ru.indexOf(e)>-1&&(a=0);const i=sk.createAndSchedule(this,e,a,n,r=>this.yu(r));return this.Tu.push(i),i}fu(){this.Eu&&pe()}verifyOperationInProgress(){}async wu(){let e;do e=this.mu,await e;while(e!==this.mu)}Su(e){for(const a of this.Tu)if(a.timerId===e)return!0;return!1}bu(e){return this.wu().then(()=>{this.Tu.sort((a,n)=>a.targetTimeMs-n.targetTimeMs);for(const a of this.Tu)if(a.skipDelay(),e!=="all"&&a.timerId===e)break;return this.wu()})}Du(e){this.Ru.push(e)}yu(e){const a=this.Tu.indexOf(e);this.Tu.splice(a,1)}}class Xl extends _g{constructor(e,a,n,i){super(e,a,n,i),this.type="firestore",this._queue=new PC,this._persistenceKey=(i==null?void 0:i.name)||"[DEFAULT]"}async _terminate(){if(this._firestoreClient){const e=this._firestoreClient.terminate();this._queue=new PC(e),this._firestoreClient=void 0,await e}}}function oJ(t,e){const a=typeof t=="object"?t:mg(),n=typeof t=="string"?t:"(default)",i=Qr(a,"f
1822irestore").getImmediate({identifier:n});if(!i._initialized){const r=MR("firestore");r&&rJ(i,...r)}return i}function uk(t){if(t._terminated)throw new X(z.FAILED_PRECONDITION,"The client has already been terminated.");return t._firestoreClient||sJ(t),t._firestoreClient}function sJ(t){var e,a,n;const i=t._freezeSettings(),r=function(l,c,d,u){return new zW(l,c,d,u.host,u.ssl,u.experimentalForceLongPolling,u.experimentalAutoDetectLongPolling,n3(u.experimentalLongPollingOptions),u.useFetchStreams)}(t._databaseId,((e=t._app)===null||e===void 0?void 0:e.options.appId)||"",t._persistenceKey,i);t._componentsProvider||!((a=i.localCache)===null||a===void 0)&&a._offlineComponentProvider&&(!((n=i.localCache)===null||n===void 0)&&n._onlineComponentProvider)&&(t._componentsProvider={_offline:i.localCache._offlineComponentProvider,_online:i.localCache._onlineComponentProvider}),t._firestoreClient=new ZK(t._authCredentials,t._appCheckCredentials,t._queue,r,t._componentsProvider&&function(l){const c=l==null?void 0:l._online.build();return{_offline:l==null?void 0:l._offline.build(c),_online:c}}(t._componentsProvider))}/** 1823 * @license 1824 * Copyright 2020 Google LLC 1825 * 1826 * Licensed under the Apache License, Version 2.0 (the "License"); 1827 * you may not use this file except in compliance with the License. 1828 * You may obtain a copy of the License at 1829 * 1830 * http://www.apache.org/licenses/LICENSE-2.0 1831 * 1832 * Unless required by applicable law or agreed to in writing, software 1833 * distributed under the License is distributed on an "AS IS" BASIS, 1834 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1835 * See the License for the specific language governing permissions and 1836 * limitations under the License. 1837 */class Cl{constructor(e){this._byteString=e}static fromBase64String(e){try{return new Cl($t.fromBase64String(e))}catch(a){throw new X(z.INVALID_ARGUMENT,"Failed to construct data from Base64 string: "+a)}}static fromUint8Array(e){return new Cl($t.fromUint8Array(e))}toBase64(){return this._byteString.toBase64()}toUint8Array(){return this._byteString.toUint8Array()}toString(){return"Bytes(base64: "+this.toBase64()+")"}isEqual(e){return this._byteString.isEqual(e._byteString)}}/** 1838 * @license 1839 * Copyright 2020 Google LLC 1840 * 1841 * Licensed under the Apache License, Version 2.0 (the "License"); 1842 * you may not use this file except in compliance with the License. 1843 * You may obtain a copy of the License at 1844 * 1845 * http://www.apache.org/licenses/LICENSE-2.0 1846 * 1847 * Unless required by applicable law or agreed to in writing, software 1848 * distributed under the License is distributed on an "AS IS" BASIS, 1849 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1850 * See the License for the specific language governing permissions and 1851 * limitations under the License. 1852 */class Ag{constructor(...e){for(let a=0;a<e.length;++a)if(e[a].length===0)throw new X(z.INVALID_ARGUMENT,"Invalid field name at argument $(i + 1). Field names must not be empty.");this._internalPath=new Ht(e)}isEqual(e){return this._internalPath.isEqual(e._internalPath)}}/** 1853 * @license 1854 * Copyright 2020 Google LLC 1855 * 1856 * Licensed under the Apache License, Version 2.0 (the "License"); 1857 * you may not use this file except in compliance with the License. 1858 * You may obtain a copy of the License at 1859 * 1860 * http://www.apache.org/licenses/LICENSE-2.0 1861 * 1862 * Unless required by applicable law or agreed to in writing, software 1863 * distributed under the License is distributed on an "AS IS" BASIS, 1864 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1865 * See the License for the specific language governing permissions and 1866 * limitations under the License. 1867 */class pk{constructor(e){this._methodName=e}}/** 1868 * @license 1869 * Copyright 2017 Google LLC 1870 * 1871 * Licensed under the Apache License, Version 2.0 (the "License"); 1872 * you may not use this file except in compliance with the License. 1873 * You may obtain a copy of the License at 1874 * 1875 * http://www.apache.org/licenses/LICENSE-2.0 1876 * 1877 * Unless required by applicable law or agreed to in writing, software 1878 * distributed under the License is distributed on an "AS IS" BASIS, 1879 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1880 * See the License for the specific language governing permissions and 1881 * limitations under the License. 1882 */class mk{constructor(e,a){if(!isFinite(e)||e<-90||e>90)throw new X(z.INVALID_ARGUMENT,"Latitude must be a number between -90 and 90, but was: "+e);if(!isFinite(a)||a<-180||a>180)throw new X(z.INVALID_ARGUMENT,"Longitude must be a number between -180 and 180, but was: "+a);this._lat=e,this._long=a}get latitude(){return this._lat}get longitude(){return this._long}isEqual(e){return this._lat===e._lat&&this._long===e._long}toJSON(){return{latitude:this._lat,longitude:this._long}}_compareTo(e){return je(this._lat,e._lat)||je(this._long,e._long)}}/** 1883 * @license 1884 * Copyright 2024 Google LLC 1885 * 1886 * Licensed under the Apache License, Version 2.0 (the "License");
1887 * you may not use this file except in compliance with the License. 1888 * You may obtain a copy of the License at 1889 * 1890 * http://www.apache.org/licenses/LICENSE-2.0 1891 * 1892 * Unless required by applicable law or agreed to in writing, software 1893 * distributed under the License is distributed on an "AS IS" BASIS, 1894 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1895 * See the License for the specific language governing permissions and 1896 * limitations under the License. 1897 */class hk{constructor(e){this._values=(e||[]).map(a=>a)}toArray(){return this._values.map(e=>e)}isEqual(e){return function(n,i){if(n.length!==i.length)return!1;for(let r=0;r<n.length;++r)if(n[r]!==i[r])return!1;return!0}(this._values,e._values)}}/** 1898 * @license 1899 * Copyright 2017 Google LLC 1900 * 1901 * Licensed under the Apache License, Version 2.0 (the "License"); 1902 * you may not use this file except in compliance with the License. 1903 * You may obtain a copy of the License at 1904 * 1905 * http://www.apache.org/licenses/LICENSE-2.0 1906 * 1907 * Unless required by applicable law or agreed to in writing, software 1908 * distributed under the License is distributed on an "AS IS" BASIS, 1909 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1910 * See the License for the specific language governing permissions and 1911 * limitations under the License. 1912 */const lJ=/^__.*__$/;class cJ{constructor(e,a,n){this.data=e,this.fieldMask=a,this.fieldTransforms=n}toMutation(e,a){return this.fieldMask!==null?new Xr(e,this.data,this.fieldMask,a,this.fieldTransforms):new Du(e,this.data,a,this.fieldTransforms)}}class r3{constructor(e,a,n){this.data=e,this.fieldMask=a,this.fieldTransforms=n}toMutation(e,a){return new Xr(e,this.data,this.fieldMask,a,this.fieldTransforms)}}function o3(t){switch(t){case 0:case 2:case 1:return!0;case 3:case 4:return!1;default:throw pe()}}class fk{constructor(e,a,n,i,r,o){this.settings=e,this.databaseId=a,this.serializer=n,this.ignoreUndefinedProperties=i,r===void 0&&this.vu(),this.fieldTransforms=r||[],this.fieldMask=o||[]}get path(){return this.settings.path}get Cu(){return this.settings.Cu}Fu(e){return new fk(Object.assign(Object.assign({},this.settings),e),this.databaseId,this.serializer,this.ignoreUndefinedProperties,this.fieldTransforms,this.fieldMask)}Mu(e){var a;const n=(a=this.path)===null||a===void 0?void 0:a.child(e),i=this.Fu({path:n,xu:!1});return i.Ou(e),i}Nu(e){var a;const n=(a=this.path)===null||a===void 0?void 0:a.child(e),i=this.Fu({path:n,xu:!1});return i.vu(),i}Lu(e){return this.Fu({path:void 0,xu:!0})}Bu(e){return qh(e,this.settings.methodName,this.settings.ku||!1,this.path,this.settings.qu)}contains(e){return this.fieldMask.find(a=>e.isPrefixOf(a))!==void 0||this.fieldTransforms.find(a=>e.isPrefixOf(a.field))!==void 0}vu(){if(this.path)for(let e=0;e<this.path.length;e++)this.Ou(this.path.get(e))}Ou(e){if(e.length===0)throw this.Bu("Document fields must not be empty");if(o3(this.Cu)&&lJ.test(e))throw this.Bu('Document fields cannot begin and end with "__"')}}class dJ{constructor(e,a,n){this.databaseId=e,this.ignoreUndefinedProperties=a,this.serializer=n||bg(e)}Qu(e,a,n,i=!1){return new fk({Cu:e,methodName:a,qu:n,path:Ht.emptyPath(),xu:!1,ku:i},this.databaseId,this.serializer,this.ignoreUndefinedProperties)}}function gk(t){const e=t._freezeSettings(),a=bg(t._databaseId);return new dJ(t._databaseId,!!e.ignoreUndefinedProperties,a)}function uJ(t,e,a,n,i,r={}){const o=t.Qu(r.merge||r.mergeFields?2:0,e,a,i);yk("Data must be an object, but it was:",o,n);const l=s3(n,o);let c,d;if(r.merge)c=new Va(o.fieldMask),d=o.fieldTransforms;else if(r.mergeFields){const u=[];for(const p of r.mergeFields){const m=mb(e,p,a);if(!o.contains(m))throw new X(z.INVALID_ARGUMENT,`Field '${m}' is specified in your field mask but missing from your input data.`);c3(u,m)||u.push(m)}c=new Va(u),d=o.fieldTransforms.filter(p=>c.covers(p.field))}else c=null,d=o.fieldTransforms;return new cJ(new _a(l),c,d)}class Eg extends pk{_toFieldTransform(e){if(e.Cu!==2)throw e.Cu===1?e.Bu(`${this._methodName}() can only appear at the top level of your update data`):e.Bu(`${this._methodName}() cannot be used with set() unless you pass {merge:true}`);return e.fieldMask.push(e.path),null}isEqual(e){return e instanceof Eg}}function pJ(t,e,a,n){const i=t.Qu(1,e,a);
1912yk("Data must be an object, but it was:",i,n);const r=[],o=_a.empty();ps(n,(c,d)=>{const u=xk(e,c,a);d=et(d);const p=i.Nu(u);if(d instanceof Eg)r.push(u);else{const m=Hu(d,p);m!=null&&(r.push(u),o.set(u,m))}});const l=new Va(r);return new r3(o,l,i.fieldTransforms)}function mJ(t,e,a,n,i,r){const o=t.Qu(1,e,a),l=[mb(e,n,a)],c=[i];if(r.length%2!=0)throw new X(z.INVALID_ARGUMENT,`Function ${e}() needs to be called with an even number of arguments that alternate between field names and values.`);for(let m=0;m<r.length;m+=2)l.push(mb(e,r[m])),c.push(r[m+1]);const d=[],u=_a.empty();for(let m=l.length-1;m>=0;--m)if(!c3(d,l[m])){const h=l[m];let g=c[m];g=et(g);const y=o.Nu(h);if(g instanceof Eg)d.push(h);else{const x=Hu(g,y);x!=null&&(d.push(h),u.set(h,x))}}const p=new Va(d);return new r3(u,p,o.fieldTransforms)}function hJ(t,e,a,n=!1){return Hu(a,t.Qu(n?4:3,e))}function Hu(t,e){if(l3(t=et(t)))return yk("Unsupported field value:",e,t),s3(t,e);if(t instanceof pk)return function(n,i){if(!o3(i.Cu))throw i.Bu(`${n._methodName}() can only be used with update() and set()`);if(!i.path)throw i.Bu(`${n._methodName}() is not currently supported inside arrays`);const r=n._toFieldTransform(i);r&&i.fieldTransforms.push(r)}(t,e),null;if(t===void 0&&e.ignoreUndefinedProperties)return null;if(e.path&&e.fieldMask.push(e.path),t instanceof Array){if(e.settings.xu&&e.Cu!==4)throw e.Bu("Nested arrays are not supported");return function(n,i){const r=[];let o=0;for(const l of n){let c=Hu(l,i.Lu(o));c==null&&(c={nullValue:"NULL_VALUE"}),r.push(c),o++}return{arrayValue:{values:r}}}(t,e)}return function(n,i){if((n=et(n))===null)return{nullValue:"NULL_VALUE"};if(typeof n=="number")return sG(i.serializer,n);if(typeof n=="boolean")return{booleanValue:n};if(typeof n=="string")return{stringValue:n};if(n instanceof Date){const r=xt.fromDate(n);return{timestampValue:Oh(i.serializer,r)}}if(n instanceof xt){const r=new xt(n.seconds,1e3*Math.floor(n.nanoseconds/1e3));return{timestampValue:Oh(i.serializer,r)}}if(n instanceof mk)return{geoPointValue:{latitude:n.latitude,longitude:n.longitude}};if(n instanceof Cl)return{bytesValue:EL(i.serializer,n._byteString)};if(n instanceof Ia){const r=i.databaseId,o=n.firestore._databaseId;if(!o.isEqual(r))throw i.Bu(`Document reference is for database ${o.projectId}/${o.database} but should be for database ${r.projectId}/${r.database}`);return{referenceValue:Zw(n.firestore._databaseId||i.databaseId,n._key.path)}}if(n instanceof hk)return function(o,l){return{mapValue:{fields:{__type__:{stringValue:"__vector__"},value:{arrayValue:{values:o.toArray().map(c=>{if(typeof c!="number")throw l.Bu("VectorValues must only contain numeric values.");return Jw(l.serializer,c)})}}}}}}(n,i);throw i.Bu(`Unsupported field value: ${Sg(n)}`)}(t,e)}function s3(t,e){const a={};return tL(t)?e.path&&e.path.length>0&&e.fieldMask.push(e.path):ps(t,(n,i)=>{const r=Hu(i,e.Mu(n));r!=null&&(a[n]=r)}),{mapValue:{fields:a}}}function l3(t){return!(typeof t!="object"||t===null||t instanceof Array||t instanceof Date||t instanceof xt||t instanceof mk||t instanceof Cl||t instanceof Ia||t instanceof pk||t instanceof hk)}function yk(t,e,a){if(!l3(a)||!function(i){return typeof i=="object"&&i!==null&&(Object.getPrototypeOf(i)===Object.prototype||Object.getPrototypeOf(i)===null)}(a)){const n=Sg(a);throw n==="an object"?e.Bu(t+" a custom object"):e.Bu(t+" "+n)}}function mb(t,e,a){if((e=et(e))instanceof Ag)return e._internalPath;if(typeof e=="string")return xk(t,e);throw qh("Field path arguments must be of type string or ",t,!1,void 0,a)}const fJ=new RegExp("[~\\*/\\[\\]]");function xk(t,e,a){if(e.search(fJ)>=0)throw qh(`Invalid field path (${e}). Paths must not contain '~', '*', '/', '[', or ']'`,t,!1,void 0,a);try{return new Ag(...e.split("."))._internalPath}catch{throw qh(`Invalid field path (${e}). Paths must not be empty, begin with '.', end with '.', or contain '..'`,t,!1,void 0,a)}}function qh(t,e,a,n,i){const r=n&&!n.isEmpty(),o=i!==void 0;let l=`Function ${e}() called with invalid data`;a&&(l+=" (via `toFirestore()`)"),l+=". ";let c="";return(r||o)&&(c+=" (found",r&&(c+=` in field ${n}`),o&&(c+=` in document ${i}`),c+=")"),new X(z.INVALID_ARGUMENT,l+t+c)}function c3(t,e){return t.some(a=>a.isEqual(e))}/** 1913 * @license 1914 * Copyright 2020 Google LLC 1915 * 1916 * Licensed under the Apache License, Version 2.0 (the "License");
1917 * you may not use this file except in compliance with the License. 1918 * You may obtain a copy of the License at 1919 * 1920 * http://www.apache.org/licenses/LICENSE-2.0 1921 * 1922 * Unless required by applicable law or agreed to in writing, software 1923 * distributed under the License is distributed on an "AS IS" BASIS, 1924 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1925 * See the License for the specific language governing permissions and 1926 * limitations under the License. 1927 */class d3{constructor(e,a,n,i,r){this._firestore=e,this._userDataWriter=a,this._key=n,this._document=i,this._converter=r}get id(){return this._key.path.lastSegment()}get ref(){return new Ia(this._firestore,this._converter,this._key)}exists(){return this._document!==null}data(){if(this._document){if(this._converter){const e=new gJ(this._firestore,this._userDataWriter,this._key,this._document,null);return this._converter.fromFirestore(e)}return this._userDataWriter.convertValue(this._document.data.value)}}get(e){if(this._document){const a=this._document.data.field(vk("DocumentSnapshot.get",e));if(a!==null)return this._userDataWriter.convertValue(a)}}}class gJ extends d3{data(){return super.data()}}function vk(t,e){return typeof e=="string"?xk(t,e):e instanceof Ag?e._internalPath:e._delegate._internalPath}/** 1928 * @license 1929 * Copyright 2020 Google LLC 1930 * 1931 * Licensed under the Apache License, Version 2.0 (the "License"); 1932 * you may not use this file except in compliance with the License. 1933 * You may obtain a copy of the License at 1934 * 1935 * http://www.apache.org/licenses/LICENSE-2.0 1936 * 1937 * Unless required by applicable law or agreed to in writing, software 1938 * distributed under the License is distributed on an "AS IS" BASIS, 1939 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1940 * See the License for the specific language governing permissions and 1941 * limitations under the License. 1942 */function yJ(t){if(t.limitType==="L"&&t.explicitOrderBy.length===0)throw new X(z.UNIMPLEMENTED,"limitToLast() queries require specifying at least one orderBy() clause")}class bk{}class xJ extends bk{}function jl(t,e,...a){let n=[];e instanceof bk&&n.push(e),n=n.concat(a),function(r){const o=r.filter(c=>c instanceof wk).length,l=r.filter(c=>c instanceof Cg).length;if(o>1||o>0&&l>0)throw new X(z.INVALID_ARGUMENT,"InvalidQuery. When using composite filters, you cannot use more than one filter at the top level. Consider nesting the multiple filters within an `and(...)` statement. For example: change `query(query, where(...), or(...))` to `query(query, and(where(...), or(...)))`.")}(n);for(const i of n)t=i._apply(t);return t}class Cg extends xJ{constructor(e,a,n){super(),this._field=e,this._op=a,this._value=n,this.type="where"}static _create(e,a,n){return new Cg(e,a,n)}_apply(e){const a=this._parse(e);return u3(e._query,a),new Ql(e.firestore,e.converter,nb(e._query,a))}_parse(e){const a=gk(e.firestore);return function(r,o,l,c,d,u,p){let m;if(d.isKeyField()){if(u==="array-contains"||u==="array-contains-any")throw new X(z.INVALID_ARGUMENT,`Invalid Query. You can't perform '${u}' queries on documentId().`);if(u==="in"||u==="not-in"){LC(p,u);const h=[];for(const g of p)h.push(RC(c,r,g));m={arrayValue:{values:h}}}else m=RC(c,r,p)}else u!=="in"&&u!=="not-in"&&u!=="array-contains-any"||LC(p,u),m=hJ(l,o,p,u==="in"||u==="not-in");return gt.create(d,u,m)}(e._query,"where",a,e.firestore._databaseId,this._field,this._op,this._value)}}function Gn(t,e,a){const n=e,i=vk("where",t);return Cg._create(i,n,a)}class wk extends bk{constructor(e,a){super(),this.type=e,this._queryConstraints=a}static _create(e,a){return new wk(e,a)}_parse(e){const a=this._queryConstraints.map(n=>n._parse(e)).filter(n=>n.getFilters().length>0);return a.length===1?a[0]:qn.create(a,this._getOperator())}_apply(e){const a=this._parse(e);return a.getFilters().length===0?e:(function(i,r){let o=i;const l=r.getFlattenedFilters();for(const c of l)u3(o,c),o=nb(o,c)}(e._query,a),new Ql(e.firestore,e.converter,nb(e._query,a)))}_getQueryConstraints(){return this._queryConstraints}_getOperator(){return this.type==="and"?"and":"or"}}
1942function RC(t,e,a){if(typeof(a=et(a))=="string"){if(a==="")throw new X(z.INVALID_ARGUMENT,"Invalid query. When querying with documentId(), you must provide a valid document ID, but it was an empty string.");if(!dL(e)&&a.indexOf("/")!==-1)throw new X(z.INVALID_ARGUMENT,`Invalid query. When querying a collection by documentId(), you must provide a plain document ID, but '${a}' contains a '/' character.`);const n=e.path.child(Ue.fromString(a));if(!oe.isDocumentKey(n))throw new X(z.INVALID_ARGUMENT,`Invalid query. When querying a collection group by documentId(), the value provided must result in a valid document path, but '${n}' is not because it has an odd number of segments (${n.length}).`);return tC(t,new oe(n))}if(a instanceof Ia)return tC(t,a._key);throw new X(z.INVALID_ARGUMENT,`Invalid query. When querying with documentId(), you must provide a valid string or a DocumentReference, but it was: ${Sg(a)}.`)}function LC(t,e){if(!Array.isArray(t)||t.length===0)throw new X(z.INVALID_ARGUMENT,`Invalid Query. A non-empty array is required for '${e.toString()}' filters.`)}function u3(t,e){const a=function(i,r){for(const o of i)for(const l of o.getFlattenedFilters())if(r.indexOf(l.op)>=0)return l.op;return null}(t.filters,function(i){switch(i){case"!=":return["!=","not-in"];case"array-contains-any":case"in":return["not-in"];case"not-in":return["array-contains-any","in","not-in","!="];default:return[]}}(e.op));if(a!==null)throw a===e.op?new X(z.INVALID_ARGUMENT,`Invalid query. You cannot use more than one '${e.op.toString()}' filter.`):new X(z.INVALID_ARGUMENT,`Invalid query. You cannot use '${e.op.toString()}' filters with '${a.toString()}' filters.`)}class vJ{convertValue(e,a="none"){switch(Xo(e)){case 0:return null;case 1:return e.booleanValue;case 2:return ut(e.integerValue||e.doubleValue);case 3:return this.convertTimestamp(e.timestampValue);case 4:return this.convertServerTimestamp(e,a);case 5:return e.stringValue;case 6:return this.convertBytes(Qo(e.bytesValue));case 7:return this.convertReference(e.referenceValue);case 8:return this.convertGeoPoint(e.geoPointValue);case 9:return this.convertArray(e.arrayValue,a);case 11:return this.convertObject(e.mapValue,a);case 10:return this.convertVectorValue(e.mapValue);default:throw pe()}}convertObject(e,a){return this.convertObjectMap(e.fields,a)}convertObjectMap(e,a="none"){const n={};return ps(e,(i,r)=>{n[i]=this.convertValue(r,a)}),n}convertVectorValue(e){var a,n,i;const r=(i=(n=(a=e.fields)===null||a===void 0?void 0:a.value.arrayValue)===null||n===void 0?void 0:n.values)===null||i===void 0?void 0:i.map(o=>ut(o.doubleValue));return new hk(r)}convertGeoPoint(e){return new mk(ut(e.latitude),ut(e.longitude))}convertArray(e,a){return(e.values||[]).map(n=>this.convertValue(n,a))}convertServerTimestamp(e,a){switch(a){case"previous":const n=Uw(e);return n==null?null:this.convertValue(n,a);case"estimate":return this.convertTimestamp(nu(e));default:return null}}convertTimestamp(e){const a=Fr(e);return new xt(a.seconds,a.nanos)}convertDocumentKey(e,a){const n=Ue.fromString(e);Oe(PL(n));const i=new iu(n.get(1),n.get(3)),r=new oe(n.popFirst(5));return i.isEqual(a)||Vi(`Document ${r} contains a document reference within a different database (${i.projectId}/${i.database}) which is not supported. It will be treated as a reference in the current database (${a.projectId}/${a.database}) instead.`),r}}/** 1943 * @license 1944 * Copyright 2020 Google LLC 1945 * 1946 * Licensed under the Apache License, Version 2.0 (the "License"); 1947 * you may not use this file except in compliance with the License. 1948 * You may obtain a copy of the License at 1949 * 1950 * http://www.apache.org/licenses/LICENSE-2.0 1951 * 1952 * Unless required by applicable law or agreed to in writing, software 1953 * distributed under the License is distributed on an "AS IS" BASIS, 1954 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1955 * See the License for the specific language governing permissions and 1956 * limitations under the License. 1957 */function bJ(t,e,a){let n;return n=t?t.toFirestore(e):e,n}/** 1958 * @license 1959 * Copyright 2020 Google LLC 1960 * 1961 * Licensed under the Apache License, Version 2.0 (the "License");
1962 * you may not use this file except in compliance with the License. 1963 * You may obtain a copy of the License at 1964 * 1965 * http://www.apache.org/licenses/LICENSE-2.0 1966 * 1967 * Unless required by applicable law or agreed to in writing, software 1968 * distributed under the License is distributed on an "AS IS" BASIS, 1969 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1970 * See the License for the specific language governing permissions and 1971 * limitations under the License. 1972 */class Bc{constructor(e,a){this.hasPendingWrites=e,this.fromCache=a}isEqual(e){return this.hasPendingWrites===e.hasPendingWrites&&this.fromCache===e.fromCache}}class p3 extends d3{constructor(e,a,n,i,r,o){super(e,a,n,i,o),this._firestore=e,this._firestoreImpl=e,this.metadata=r}exists(){return super.exists()}data(e={}){if(this._document){if(this._converter){const a=new Dm(this._firestore,this._userDataWriter,this._key,this._document,this.metadata,null);return this._converter.fromFirestore(a,e)}return this._userDataWriter.convertValue(this._document.data.value,e.serverTimestamps)}}get(e,a={}){if(this._document){const n=this._document.data.field(vk("DocumentSnapshot.get",e));if(n!==null)return this._userDataWriter.convertValue(n,a.serverTimestamps)}}}class Dm extends p3{data(e={}){return super.data(e)}}class wJ{constructor(e,a,n,i){this._firestore=e,this._userDataWriter=a,this._snapshot=i,this.metadata=new Bc(i.hasPendingWrites,i.fromCache),this.query=n}get docs(){const e=[];return this.forEach(a=>e.push(a)),e}get size(){return this._snapshot.docs.size}get empty(){return this.size===0}forEach(e,a){this._snapshot.docs.forEach(n=>{e.call(a,new Dm(this._firestore,this._userDataWriter,n.key,n,new Bc(this._snapshot.mutatedKeys.has(n.key),this._snapshot.fromCache),this.query.converter))})}docChanges(e={}){const a=!!e.includeMetadataChanges;if(a&&this._snapshot.excludesMetadataChanges)throw new X(z.INVALID_ARGUMENT,"To include metadata changes with your document changes, you must also pass { includeMetadataChanges:true } to onSnapshot().");return this._cachedChanges&&this._cachedChangesIncludeMetadataChanges===a||(this._cachedChanges=function(i,r){if(i._snapshot.oldDocs.isEmpty()){let o=0;return i._snapshot.docChanges.map(l=>{const c=new Dm(i._firestore,i._userDataWriter,l.doc.key,l.doc,new Bc(i._snapshot.mutatedKeys.has(l.doc.key),i._snapshot.fromCache),i.query.converter);return l.doc,{type:"added",doc:c,oldIndex:-1,newIndex:o++}})}{let o=i._snapshot.oldDocs;return i._snapshot.docChanges.filter(l=>r||l.type!==3).map(l=>{const c=new Dm(i._firestore,i._userDataWriter,l.doc.key,l.doc,new Bc(i._snapshot.mutatedKeys.has(l.doc.key),i._snapshot.fromCache),i.query.converter);let d=-1,u=-1;return l.type!==0&&(d=o.indexOf(l.doc.key),o=o.delete(l.doc.key)),l.type!==1&&(o=o.add(l.doc),u=o.indexOf(l.doc.key)),{type:kJ(l.type),doc:c,oldIndex:d,newIndex:u}})}}(this,a),this._cachedChangesIncludeMetadataChanges=a),this._cachedChanges}}function kJ(t){switch(t){case 0:return"added";case 2:case 3:return"modified";case 1:return"removed";default:return pe()}}/** 1973 * @license 1974 * Copyright 2020 Google LLC 1975 * 1976 * Licensed under the Apache License, Version 2.0 (the "License"); 1977 * you may not use this file except in compliance with the License. 1978 * You may obtain a copy of the License at 1979 * 1980 * http://www.apache.org/licenses/LICENSE-2.0 1981 * 1982 * Unless required by applicable law or agreed to in writing, software 1983 * distributed under the License is distributed on an "AS IS" BASIS, 1984 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1985 * See the License for the specific language governing permissions and 1986 * limitations under the License. 1987 */function SJ(t){t=Fi(t,Ia);const e=Fi(t.firestore,Xl);return aJ(uk(e),t._key).then(a=>AJ(e,t,a))}class m3 extends vJ{constructor(e){super(),this.firestore=e}convertBytes(e){return new Cl(e)}convertReference(e){const a=this.convertDocumentKey(e,this.firestore._databaseId);return new Ia(this.firestore,null,a)}}function Ni(t){t=Fi(t,Ql);const e=Fi(t.firestore,Xl),a=uk(e),n=new m3(e);return yJ(t._query),nJ(a,t._query).then(i=>new wJ(e,n,t,i))}
1987function h3(t,e,a,...n){t=Fi(t,Ia);const i=Fi(t.firestore,Xl),r=gk(i);let o;return o=typeof(e=et(e))=="string"||e instanceof Ag?mJ(r,"updateDoc",t._key,e,a,n):pJ(r,"updateDoc",t._key,e),kk(i,[o.toMutation(t._key,In.exists(!0))])}function _J(t){return kk(Fi(t.firestore,Xl),[new Qw(t._key,In.none())])}function Tl(t,e){const a=Fi(t.firestore,Xl),n=lu(t),i=bJ(t.converter,e);return kk(a,[uJ(gk(t.firestore),"addDoc",n._key,i,t.converter!==null,{}).toMutation(n._key,In.exists(!1))]).then(()=>n)}function kk(t,e){return function(n,i){const r=new Ti;return n.asyncQueue.enqueueAndForget(async()=>$K(await tJ(n),i,r)),r.promise}(uk(t),e)}function AJ(t,e,a){const n=a.docs.get(e._key),i=new m3(t);return new p3(t,i,e._key,n,new Bc(a.hasPendingWrites,a.fromCache),e.converter)}(function(e,a=!0){(function(i){Gl=i})(us),Dn(new hn("firestore",(n,{instanceIdentifier:i,options:r})=>{const o=n.getProvider("app").getImmediate(),l=new Xl(new _W(n.getProvider("auth-internal")),new jW(n.getProvider("app-check-internal")),function(d,u){if(!Object.prototype.hasOwnProperty.apply(d.options,["projectId"]))throw new X(z.INVALID_ARGUMENT,'"projectId" not provided in firebase.initializeApp.');return new iu(d.options.projectId,u)}(o,i),o);return r=Object.assign({useFetchStreams:a},r),l._setSettings(r),l},"PUBLIC").setMultipleInstances(!0)),Na(QE,"4.7.3",e),Na(QE,"4.7.3","esm2017")})();/** 1988 * @license 1989 * Copyright 2017 Google LLC 1990 * 1991 * Licensed under the Apache License, Version 2.0 (the "License"); 1992 * you may not use this file except in compliance with the License. 1993 * You may obtain a copy of the License at 1994 * 1995 * http://www.apache.org/licenses/LICENSE-2.0 1996 * 1997 * Unless required by applicable law or agreed to in writing, software 1998 * distributed under the License is distributed on an "AS IS" BASIS, 1999 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2000 * See the License for the specific language governing permissions and 2001 * limitations under the License. 2002 */const f3="firebasestorage.googleapis.com",g3="storageBucket",EJ=2*60*1e3,CJ=10*60*1e3;/** 2003 * @license 2004 * Copyright 2017 Google LLC 2005 * 2006 * Licensed under the Apache License, Version 2.0 (the "License"); 2007 * you may not use this file except in compliance with the License. 2008 * You may obtain a copy of the License at 2009 * 2010 * http://www.apache.org/licenses/LICENSE-2.0 2011 * 2012 * Unless required by applicable law or agreed to in writing, software 2013 * distributed under the License is distributed on an "AS IS" BASIS, 2014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2015 * See the License for the specific language governing permissions and 2016 * limitations under the License. 2017 */class dt extends gn{constructor(e,a,n=0){super(I0(e),`Firebase Storage: ${a} (${I0(e)})`),this.status_=n,this.customData={serverResponse:null},this._baseMessage=this.message,Object.setPrototypeOf(this,dt.prototype)}get status(){return this.status_}set status(e){this.status_=e}_codeEquals(e){return I0(e)===this.code}get serverResponse(){return this.customData.serverResponse}set serverResponse(e){this.customData.serverResponse=e,this.customData.serverResponse?this.message=`${this._baseMessage} 2018${this.customData.serverResponse}`:this.message=this._baseMessage}}var lt;(function(t){t.UNKNOWN="unknown",t.OBJECT_NOT_FOUND="object-not-found",t.BUCKET_NOT_FOUND="bucket-not-found",t.PROJECT_NOT_FOUND="project-not-found",t.QUOTA_EXCEEDED="quota-exceeded",t.UNAUTHENTICATED="unauthenticated",t.UNAUTHORIZED="unauthorized",t.UNAUTHORIZED_APP="unauthorized-app",t.RETRY_LIMIT_EXCEEDED="retry-limit-exceeded",t.INVALID_CHECKSUM="invalid-checksum",t.CANCELED="canceled",t.INVALID_EVENT_NAME="invalid-event-name",t.INVALID_URL="invalid-url",t.INVALID_DEFAULT_BUCKET="invalid-default-bucket",t.NO_DEFAULT_BUCKET="no-default-bucket",t.CANNOT_SLICE_BLOB="cannot-slice-blob",t.SERVER_FILE_WRONG_SIZE="server-file-wrong-size",t.NO_DOWNLOAD_URL="no-download-url",t.INVALID_ARGUMENT="invalid-argument",t.INVALID_ARGUMENT_COUNT="invalid-argument-count",t.APP_DELETED="app-deleted",t.INVALID_ROOT_OPERATION="invalid-root-operation",t.INVALID_FORMAT="invalid-format",t.INTERNAL_ERROR="internal-error",t.UNSUPPORTED_ENVIRONMENT="unsupported-environment"})(lt||(lt={}));function I0(t){return"storage/"+t}function Sk(){const t="An unknown error occurred, please check the error payload for server response.";return new dt(lt.UNKNOWN,t)}function jJ(t){return new dt(lt.OBJECT_NOT_FOUND,"Object '"+t+"' does not exist.")}function TJ(t){return new dt(lt.QUOTA_EXCEEDED,"Quota for bucket '"+t+"' exceeded, please view quota on https://firebase.google.com/pricing/.")}function NJ(){const t="User is not authenticated, please authenticate using Firebase Authentication and try again.";return new dt(lt.UNAUTHENTICATED,t)}function IJ(){return new dt(lt.UNAUTHORIZED_APP,"This app does not have permission to access Firebase Storage on this project.")}function PJ(t){return new dt(lt.UNAUTHORIZED,"User does not have permission to access '"+t+"'.")}function RJ(){return new dt(lt.RETRY_LIMIT_EXCEEDED,"Max retry time for operation exceeded, please try again.")}function LJ(){return new dt(lt.CANCELED,"User canceled the upload/download.")}
vendor: 4,432 bytes, lines 2018-2052
2018function OJ(t){return new dt(lt.INVALID_URL,"Invalid URL '"+t+"'.")}function MJ(t){return new dt(lt.INVALID_DEFAULT_BUCKET,"Invalid default bucket '"+t+"'.")}function DJ(){return new dt(lt.NO_DEFAULT_BUCKET,"No default bucket found. Did you set the '"+g3+"' property when initializing the app?")}function qJ(){return new dt(lt.CANNOT_SLICE_BLOB,"Cannot slice blob for upload. Please retry the upload.")}function zJ(){return new dt(lt.NO_DOWNLOAD_URL,"The given file does not have any download URLs.")}function VJ(t){return new dt(lt.UNSUPPORTED_ENVIRONMENT,`${t} is missing. Make sure to install the required polyfills. See https://firebase.google.com/docs/web/environments-js-sdk#polyfills for more information.`)}function hb(t){return new dt(lt.INVALID_ARGUMENT,t)}function y3(){return new dt(lt.APP_DELETED,"The Firebase app was deleted.")}function HJ(t){return new dt(lt.INVALID_ROOT_OPERATION,"The operation '"+t+"' cannot be performed on a root reference, create a non-root reference using child, such as .child('file.png').")}function fd(t,e){return new dt(lt.INVALID_FORMAT,"String does not match format '"+t+"': "+e)}function Tc(t){throw new dt(lt.INTERNAL_ERROR,"Internal error: "+t)}/** 2019 * @license 2020 * Copyright 2017 Google LLC 2021 * 2022 * Licensed under the Apache License, Version 2.0 (the "License"); 2023 * you may not use this file except in compliance with the License. 2024 * You may obtain a copy of the License at 2025 * 2026 * http://www.apache.org/licenses/LICENSE-2.0 2027 * 2028 * Unless required by applicable law or agreed to in writing, software 2029 * distributed under the License is distributed on an "AS IS" BASIS, 2030 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2031 * See the License for the specific language governing permissions and 2032 * limitations under the License. 2033 */class Ha{constructor(e,a){this.bucket=e,this.path_=a}get path(){return this.path_}get isRoot(){return this.path.length===0}fullServerUrl(){const e=encodeURIComponent;return"/b/"+e(this.bucket)+"/o/"+e(this.path)}bucketOnlyServerUrl(){return"/b/"+encodeURIComponent(this.bucket)+"/o"}static makeFromBucketSpec(e,a){let n;try{n=Ha.makeFromUrl(e,a)}catch{return new Ha(e,"")}if(n.path==="")return n;throw MJ(e)}static makeFromUrl(e,a){let n=null;const i="([A-Za-z0-9.\\-_]+)";function r(T){T.path.charAt(T.path.length-1)==="/"&&(T.path_=T.path_.slice(0,-1))}const o="(/(.*))?$",l=new RegExp("^gs://"+i+o,"i"),c={bucket:1,path:3};function d(T){T.path_=decodeURIComponent(T.path)}const u="v[A-Za-z0-9_]+",p=a.replace(/[.]/g,"\\."),m="(/([^?#]*).*)?$",h=new RegExp(`^https?://${p}/${u}/b/${i}/o${m}`,"i"),g={bucket:1,path:3},y=a===f3?"(?:storage.googleapis.com|storage.cloud.google.com)":a,x="([^?#]*)",v=new RegExp(`^https?://${y}/${i}/${x}`,"i"),S=[{regex:l,indices:c,postModify:r},{regex:h,indices:g,postModify:d},{regex:v,indices:{bucket:1,path:2},postModify:d}];for(let T=0;T<S.length;T++){const P=S[T],M=P.regex.exec(e);if(M){const C=M[P.indices.bucket];let E=M[P.indices.path];E||(E=""),n=new Ha(C,E),P.postModify(n);break}}if(n==null)throw OJ(e);return n}}class FJ{constructor(e){this.promise_=Promise.reject(e)}getPromise(){return this.promise_}cancel(e=!1){}}/** 2034 * @license 2035 * Copyright 2017 Google LLC 2036 * 2037 * Licensed under the Apache License, Version 2.0 (the "License"); 2038 * you may not use this file except in compliance with the License. 2039 * You may obtain a copy of the License at 2040 * 2041 * http://www.apache.org/licenses/LICENSE-2.0 2042 * 2043 * Unless required by applicable law or agreed to in writing, software 2044 * distributed under the License is distributed on an "AS IS" BASIS, 2045 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2046 * See the License for the specific language governing permissions and 2047 * limitations under the License. 2048 */function BJ(t,e,a){let n=1,i=null,r=null,o=!1,l=0;function c(){return l===2}let d=!1;function u(...x){d||(d=!0,e.apply(null,x))}function p(x){i=setTimeout(()=>{i=null,t(h,c())},x)}function m(){r&&clearTimeout(r)}function h(x,...v){if(d){m();return}if(x){m(),u.call(null,x,...v);return}if(c()||o){m(),u.call(null,x,...v);return}n<64&&(n*=2);let S;l===1?(l=2,S=0):S=(n+Math.random())*1e3,p(S)}let g=!1;function y(x){g||(g=!0,m(),!d&&(i!==null?(x||(l=2),clearTimeout(i),p(0)):x||(l=1)))}return p(0),r=setTimeout(()=>{o=!0,y(!0)},a),y}function UJ(t){t(!1)}/** 2049 * @license 2050 * Copyright 2017 Google LLC 2051 * 2052 * Licensed under the Apache License, Version 2.0 (the "License");
2053 * you may not use this file except in compliance with the License. 2054 * You may obtain a copy of the License at 2055 * 2056 * http://www.apache.org/licenses/LICENSE-2.0 2057 * 2058 * Unless required by applicable law or agreed to in writing, software 2059 * distributed under the License is distributed on an "AS IS" BASIS, 2060 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2061 * See the License for the specific language governing permissions and 2062 * limitations under the License. 2063 */function $J(t){return t!==void 0}function WJ(t){return typeof t=="object"&&!Array.isArray(t)}function _k(t){return typeof t=="string"||t instanceof String}function OC(t){return Ak()&&t instanceof Blob}function Ak(){return typeof Blob<"u"}function MC(t,e,a,n){if(n<e)throw hb(`Invalid value for '${t}'. Expected ${e} or greater.`);if(n>a)throw hb(`Invalid value for '${t}'. Expected ${a} or less.`)}/** 2064 * @license 2065 * Copyright 2017 Google LLC 2066 * 2067 * Licensed under the Apache License, Version 2.0 (the "License"); 2068 * you may not use this file except in compliance with the License. 2069 * You may obtain a copy of the License at 2070 * 2071 * http://www.apache.org/licenses/LICENSE-2.0 2072 * 2073 * Unless required by applicable law or agreed to in writing, software 2074 * distributed under the License is distributed on an "AS IS" BASIS, 2075 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2076 * See the License for the specific language governing permissions and 2077 * limitations under the License. 2078 */function Ek(t,e,a){let n=e;return a==null&&(n=`https://${e}`),`${a}://${n}/v0${t}`}function x3(t){const e=encodeURIComponent;let a="?";for(const n in t)if(t.hasOwnProperty(n)){const i=e(n)+"="+e(t[n]);a=a+i+"&"}return a=a.slice(0,-1),a}var Oo;(function(t){t[t.NO_ERROR=0]="NO_ERROR",t[t.NETWORK_ERROR=1]="NETWORK_ERROR",t[t.ABORT=2]="ABORT"})(Oo||(Oo={}));/** 2079 * @license 2080 * Copyright 2022 Google LLC 2081 * 2082 * Licensed under the Apache License, Version 2.0 (the "License"); 2083 * you may not use this file except in compliance with the License. 2084 * You may obtain a copy of the License at 2085 * 2086 * http://www.apache.org/licenses/LICENSE-2.0 2087 * 2088 * Unless required by applicable law or agreed to in writing, software 2089 * distributed under the License is distributed on an "AS IS" BASIS, 2090 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2091 * See the License for the specific language governing permissions and 2092 * limitations under the License. 2093 */function GJ(t,e){const a=t>=500&&t<600,i=[408,429].indexOf(t)!==-1,r=e.indexOf(t)!==-1;return a||i||r}/** 2094 * @license 2095 * Copyright 2017 Google LLC 2096 * 2097 * Licensed under the Apache License, Version 2.0 (the "License"); 2098 * you may not use this file except in compliance with the License. 2099 * You may obtain a copy of the License at 2100 * 2101 * http://www.apache.org/licenses/LICENSE-2.0 2102 * 2103 * Unless required by applicable law or agreed to in writing, software 2104 * distributed under the License is distributed on an "AS IS" BASIS, 2105 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2106 * See the License for the specific language governing permissions and 2107 * limitations under the License. 2108 */class KJ{constructor(e,a,n,i,r,o,l,c,d,u,p,m=!0){this.url_=e,this.method_=a,this.headers_=n,this.body_=i,this.successCodes_=r,this.additionalRetryCodes_=o,this.callback_=l,this.errorCallback_=c,this.timeout_=d,this.progressCallback_=u,this.connectionFactory_=p,this.retry=m,this.pendingConnection_=null,this.backoffId_=null,this.canceled_=!1,this.appDelete_=!1,this.promise_=new Promise((h,g)=>{this.resolve_=h,this.reject_=g,this.start_()})}start_(){const e=(n,i)=>{if(i){n(!1,new Up(!1,null,!0));return}const r=this.connectionFactory_();this.pendingConnection_=r;const o=l=>{const c=l.loaded,d=l.lengthComputable?l.total:-1;this.progressCallback_!==null&&this.progressCallback_(c,d)};this.progressCallback_!==null&&r.addUploadProgressListener(o),r.send(this.url_,this.method_,this.body_,this.headers_).then(()=>{this.progressCallback_!==null&&r.removeUploadProgressListener(o),this.pendingConnection_=null;const l=r.getErrorCode()===Oo.NO_ERROR,c=r.getStatus();if(!l||GJ(c,this.additionalRetryCodes_)&&this.retry){const u=r.getErrorCode()===Oo.ABORT;n(!1,new Up(!1,null,u));return}const d=this.successCodes_.indexOf(c)!==-1;n(!0,new Up(d,r))})},a=(n,i)=>{const r=this.resolve_,o=this.reject_,l=i.connection;if(i.wasSuccessCode)try{const c=this.callback_(l,l.getResponse());$J(c)?r(c):r()}catch(c){o(c)}else if(l!==null){const c=Sk();c.serverResponse=l.getErrorText(),this.errorCallback_?o(this.errorCallback_(l,c)):o(c)}else if(i.canceled){const c=this.appDelete_?y3():LJ();o(c)}else{const c=RJ();o(c)}};this.canceled_?a(!1,new Up(!1,null,!0)):this.backoffId_=BJ(e,a,this.timeout_)}getPromise(){return this.promise_}cancel(e){this.canceled_=!0,this.appDelete_=e||!1,this.backoffId_!==null&&UJ(this.backoffId_),this.pendingConnection_!==null&&this.pendingConnection_.abort()}}class Up{constructor(e,a,n){this.wasSuccessCode=e,this.connection=a,this.canceled=!!n}}function JJ(t,e){e!==null&&e.length>0&&(t.Authorization="Firebase "+e)}function QJ(t,e){t["X-Firebase-Storage-Version"]="webjs/"+(e??"AppManager")}function XJ(t,e){e&&(t["X-Firebase-GMPID"]=e)}function YJ(t,e){e!==null&&(t["X-Firebase-AppCheck"]=e)}
2108function ZJ(t,e,a,n,i,r,o=!0){const l=x3(t.urlParams),c=t.url+l,d=Object.assign({},t.headers);return XJ(d,e),JJ(d,a),QJ(d,r),YJ(d,n),new KJ(c,t.method,d,t.body,t.successCodes,t.additionalRetryCodes,t.handler,t.errorHandler,t.timeout,t.progressCallback,i,o)}/** 2109 * @license 2110 * Copyright 2017 Google LLC 2111 * 2112 * Licensed under the Apache License, Version 2.0 (the "License"); 2113 * you may not use this file except in compliance with the License. 2114 * You may obtain a copy of the License at 2115 * 2116 * http://www.apache.org/licenses/LICENSE-2.0 2117 * 2118 * Unless required by applicable law or agreed to in writing, software 2119 * distributed under the License is distributed on an "AS IS" BASIS, 2120 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2121 * See the License for the specific language governing permissions and 2122 * limitations under the License. 2123 */function eQ(){return typeof BlobBuilder<"u"?BlobBuilder:typeof WebKitBlobBuilder<"u"?WebKitBlobBuilder:void 0}function tQ(...t){const e=eQ();if(e!==void 0){const a=new e;for(let n=0;n<t.length;n++)a.append(t[n]);return a.getBlob()}else{if(Ak())return new Blob(t);throw new dt(lt.UNSUPPORTED_ENVIRONMENT,"This browser doesn't seem to support creating Blobs")}}function aQ(t,e,a){return t.webkitSlice?t.webkitSlice(e,a):t.mozSlice?t.mozSlice(e,a):t.slice?t.slice(e,a):null}/** 2124 * @license 2125 * Copyright 2021 Google LLC 2126 * 2127 * Licensed under the Apache License, Version 2.0 (the "License"); 2128 * you may not use this file except in compliance with the License. 2129 * You may obtain a copy of the License at 2130 * 2131 * http://www.apache.org/licenses/LICENSE-2.0 2132 * 2133 * Unless required by applicable law or agreed to in writing, software 2134 * distributed under the License is distributed on an "AS IS" BASIS, 2135 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2136 * See the License for the specific language governing permissions and 2137 * limitations under the License. 2138 */function nQ(t){if(typeof atob>"u")throw VJ("base-64");return atob(t)}/** 2139 * @license 2140 * Copyright 2017 Google LLC 2141 * 2142 * Licensed under the Apache License, Version 2.0 (the "License"); 2143 * you may not use this file except in compliance with the License. 2144 * You may obtain a copy of the License at 2145 * 2146 * http://www.apache.org/licenses/LICENSE-2.0 2147 * 2148 * Unless required by applicable law or agreed to in writing, software 2149 * distributed under the License is distributed on an "AS IS" BASIS, 2150 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2151 * See the License for the specific language governing permissions and 2152 * limitations under the License. 2153 */const Qn={RAW:"raw",BASE64:"base64",BASE64URL:"base64url",DATA_URL:"data_url"};class P0{constructor(e,a){this.data=e,this.contentType=a||null}}function iQ(t,e){switch(t){case Qn.RAW:return new P0(v3(e));case Qn.BASE64:case Qn.BASE64URL:return new P0(b3(t,e));case Qn.DATA_URL:return new P0(oQ(e),sQ(e))}throw Sk()}function v3(t){const e=[];for(let a=0;a<t.length;a++){let n=t.charCodeAt(a);if(n<=127)e.push(n);else if(n<=2047)e.push(192|n>>6,128|n&63);else if((n&64512)===55296)if(!(a<t.length-1&&(t.charCodeAt(a+1)&64512)===56320))e.push(239,191,189);else{const r=n,o=t.charCodeAt(++a);n=65536|(r&1023)<<10|o&1023,e.push(240|n>>18,128|n>>12&63,128|n>>6&63,128|n&63)}else(n&64512)===56320?e.push(239,191,189):e.push(224|n>>12,128|n>>6&63,128|n&63)}return new Uint8Array(e)}function rQ(t){let e;try{e=decodeURIComponent(t)}catch{throw fd(Qn.DATA_URL,"Malformed data URL.")}return v3(e)}function b3(t,e){switch(t){case Qn.BASE64:{const i=e.indexOf("-")!==-1,r=e.indexOf("_")!==-1;if(i||r)throw fd(t,"Invalid character '"+(i?"-":"_")+"' found: is it base64url encoded?");break}case Qn.BASE64URL:{const i=e.indexOf("+")!==-1,r=e.indexOf("/")!==-1;if(i||r)throw fd(t,"Invalid character '"+(i?"+":"/")+"' found: is it base64 encoded?");e=e.replace(/-/g,"+").replace(/_/g,"/");break}}let a;try{a=nQ(e)}catch(i){throw i.message.includes("polyfill")?i:fd(t,"Invalid character found")}const n=new Uint8Array(a.length);for(let i=0;i<a.length;i++)n[i]=a.charCodeAt(i);return n}class w3{constructor(e){this.base64=!1,this.contentType=null;const a=e.match(/^data:([^,]+)?,/);if(a===null)throw fd(Qn.DATA_URL,"Must be formatted 'data:[<mediatype>][;base64],<data>");const n=a[1]||null;n!=null&&(this.base64=lQ(n,";base64"),this.contentType=this.base64?n.substring(0,n.length-7):n),this.rest=e.substring(e.indexOf(",")+1)}}function oQ(t){const e=new w3(t);return e.base64?b3(Qn.BASE64,e.rest):rQ(e.rest)}function sQ(t){return new w3(t).contentType}function lQ(t,e){return t.length>=e.length?t.substring(t.length-e.length)===e:!1}/** 2154 * @license 2155 * Copyright 2017 Google LLC 2156 * 2157 * Licensed under the Apache License, Version 2.0 (the "License");
2158 * you may not use this file except in compliance with the License. 2159 * You may obtain a copy of the License at 2160 * 2161 * http://www.apache.org/licenses/LICENSE-2.0 2162 * 2163 * Unless required by applicable law or agreed to in writing, software 2164 * distributed under the License is distributed on an "AS IS" BASIS, 2165 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2166 * See the License for the specific language governing permissions and 2167 * limitations under the License. 2168 */class lr{constructor(e,a){let n=0,i="";OC(e)?(this.data_=e,n=e.size,i=e.type):e instanceof ArrayBuffer?(a?this.data_=new Uint8Array(e):(this.data_=new Uint8Array(e.byteLength),this.data_.set(new Uint8Array(e))),n=this.data_.length):e instanceof Uint8Array&&(a?this.data_=e:(this.data_=new Uint8Array(e.length),this.data_.set(e)),n=e.length),this.size_=n,this.type_=i}size(){return this.size_}type(){return this.type_}slice(e,a){if(OC(this.data_)){const n=this.data_,i=aQ(n,e,a);return i===null?null:new lr(i)}else{const n=new Uint8Array(this.data_.buffer,e,a-e);return new lr(n,!0)}}static getBlob(...e){if(Ak()){const a=e.map(n=>n instanceof lr?n.data_:n);return new lr(tQ.apply(null,a))}else{const a=e.map(o=>_k(o)?iQ(Qn.RAW,o).data:o.data_);let n=0;a.forEach(o=>{n+=o.byteLength});const i=new Uint8Array(n);let r=0;return a.forEach(o=>{for(let l=0;l<o.length;l++)i[r++]=o[l]}),new lr(i,!0)}}uploadData(){return this.data_}}/** 2169 * @license 2170 * Copyright 2017 Google LLC 2171 * 2172 * Licensed under the Apache License, Version 2.0 (the "License"); 2173 * you may not use this file except in compliance with the License. 2174 * You may obtain a copy of the License at 2175 * 2176 * http://www.apache.org/licenses/LICENSE-2.0 2177 * 2178 * Unless required by applicable law or agreed to in writing, software 2179 * distributed under the License is distributed on an "AS IS" BASIS, 2180 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2181 * See the License for the specific language governing permissions and 2182 * limitations under the License. 2183 */function k3(t){let e;try{e=JSON.parse(t)}catch{return null}return WJ(e)?e:null}/** 2184 * @license 2185 * Copyright 2017 Google LLC 2186 * 2187 * Licensed under the Apache License, Version 2.0 (the "License"); 2188 * you may not use this file except in compliance with the License. 2189 * You may obtain a copy of the License at 2190 * 2191 * http://www.apache.org/licenses/LICENSE-2.0 2192 * 2193 * Unless required by applicable law or agreed to in writing, software 2194 * distributed under the License is distributed on an "AS IS" BASIS, 2195 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2196 * See the License for the specific language governing permissions and 2197 * limitations under the License. 2198 */function cQ(t){if(t.length===0)return null;const e=t.lastIndexOf("/");return e===-1?"":t.slice(0,e)}function dQ(t,e){const a=e.split("/").filter(n=>n.length>0).join("/");return t.length===0?a:t+"/"+a}function S3(t){const e=t.lastIndexOf("/",t.length-2);return e===-1?t:t.slice(e+1)}/** 2199 * @license 2200 * Copyright 2017 Google LLC 2201 * 2202 * Licensed under the Apache License, Version 2.0 (the "License"); 2203 * you may not use this file except in compliance with the License. 2204 * You may obtain a copy of the License at 2205 * 2206 * http://www.apache.org/licenses/LICENSE-2.0 2207 * 2208 * Unless required by applicable law or agreed to in writing, software 2209 * distributed under the License is distributed on an "AS IS" BASIS, 2210 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2211 * See the License for the specific language governing permissions and 2212 * limitations under the License. 2213 */function uQ(t,e){return e}let da=class{constructor(e,a,n,i){this.server=e,this.local=a||e,this.writable=!!n,this.xform=i||uQ}},$p=null;function pQ(t){return!_k(t)||t.length<2?t:S3(t)}function _3(){if($p)return $p;const t=[];t.push(new da("bucket")),t.push(new da("generation")),t.push(new da("metageneration")),t.push(new da("name","fullPath",!0));function e(r,o){return pQ(o)}const a=new da("name");a.xform=e,t.push(a);function n(r,o){return o!==void 0?Number(o):o}const i=new da("size");return i.xform=n,t.push(i),t.push(new da("timeCreated")),t.push(new da("updated")),t.push(new da("md5Hash",null,!0)),t.push(new da("cacheControl",null,!0)),t.push(new da("contentDisposition",null,!0)),t.push(new da("contentEncoding",null,!0)),t.push(new da("contentLanguage",null,!0)),t.push(new da("contentType",null,!0)),t.push(new da("metadata","customMetadata",!0)),$p=t,$p}function mQ(t,e){function a(){const n=t.bucket,i=t.fullPath,r=new Ha(n,i);return e._makeStorageReference(r)}Object.defineProperty(t,"ref",{get:a})}function hQ(t,e,a){const n={};n.type="file";const i=a.length;for(let r=0;r<i;r++){const o=a[r];n[o.local]=o.xform(n,e[o.server])}return mQ(n,t),n}function A3(t,e,a){const n=k3(e);return n===null?null:hQ(t,n,a)}function fQ(t,e,a,n){const i=k3(e);if(i===null||!_k(i.downloadTokens))return null;const r=i.downloadTokens;if(r.length===0)return null;const o=encodeURIComponent;return r.split(",").map(d=>{const u=t.bucket,p=t.fullPath,m="/b/"+o(u)+"/o/"+o(p),h=Ek(m,a,n),g=x3({alt:"media",token:d});return h+g})[0]}function gQ(t,e){const a={},n=e.length;for(let i=0;i<n;i++){const r=e[i];r.writable&&(a[r.server]=t[r.local])}return JSON.stringify(a)}class E3{constructor(e,a,n,i){this.url=e,this.method=a,this.handler=n,this.timeout=i,this.urlParam
vendor: 1,504 bytes, lines 2213-2228
2213s={},this.headers={},this.body=null,this.errorHandler=null,this.progressCallback=null,this.successCodes=[200],this.additionalRetryCodes=[]}}/** 2214 * @license 2215 * Copyright 2017 Google LLC 2216 * 2217 * Licensed under the Apache License, Version 2.0 (the "License"); 2218 * you may not use this file except in compliance with the License. 2219 * You may obtain a copy of the License at 2220 * 2221 * http://www.apache.org/licenses/LICENSE-2.0 2222 * 2223 * Unless required by applicable law or agreed to in writing, software 2224 * distributed under the License is distributed on an "AS IS" BASIS, 2225 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2226 * See the License for the specific language governing permissions and 2227 * limitations under the License. 2228 */function C3(t){if(!t)throw Sk()}function yQ(t,e){function a(n,i){const r=A3(t,i,e);return C3(r!==null),r}return a}function xQ(t,e){function a(n,i){const r=A3(t,i,e);return C3(r!==null),fQ(r,i,t.host,t._protocol)}return a}function j3(t){function e(a,n){let i;return a.getStatus()===401?a.getErrorText().includes("Firebase App Check token is invalid")?i=IJ():i=NJ():a.getStatus()===402?i=TJ(t.bucket):a.getStatus()===403?i=PJ(t.path):i=n,i.status=a.getStatus(),i.serverResponse=n.serverResponse,i}return e}function vQ(t){const e=j3(t);function a(n,i){let r=e(n,i);return n.getStatus()===404&&(r=jJ(t.path)),r.serverResponse=i.serverResponse,r}return a}function bQ(t,e,a){const n=e.fullServerUrl(),i=Ek(n,t.host,t._protocol),r="GET",o=t.maxOperationRetryTime,l=ne
2228w E3(i,r,xQ(t,a),o);return l.errorHandler=vQ(e),l}function wQ(t,e){return t&&t.contentType||e&&e.type()||"application/octet-stream"}function kQ(t,e,a){const n=Object.assign({},a);return n.fullPath=t.path,n.size=e.size(),n.contentType||(n.contentType=wQ(null,e)),n}function SQ(t,e,a,n,i){const r=e.bucketOnlyServerUrl(),o={"X-Goog-Upload-Protocol":"multipart"};function l(){let S="";for(let T=0;T<2;T++)S=S+Math.random().toString().slice(2);return S}const c=l();o["Content-Type"]="multipart/related; boundary="+c;const d=kQ(e,n,i),u=gQ(d,a),p="--"+c+`\r 2229Content-Type: application/json; charset=utf-8\r 2230\r 2231`+u+`\r 2232--`+c+`\r 2233Content-Type: `+d.contentType+`\r 2234\r 2235`,m=`\r 2236--`+c+"--",h=lr.getBlob(p,n,m);if(h===null)throw qJ();const g={name:d.fullPath},y=Ek(r,t.host,t._protocol),x="POST",v=t.maxUploadRetryTime,w=new E3(y,x,yQ(t,a),v);return w.urlParams=g,w.headers=o,w.body=h.uploadData(),w.errorHandler=j3(e),w}class _Q{constructor(){this.sent_=!1,this.xhr_=new XMLHttpRequest,this.initXhr(),this.errorCode_=Oo.NO_ERROR,this.sendPromise_=new Promise(e=>{this.xhr_.addEventListener("abort",()=>{this.errorCode_=Oo.ABORT,e()}),this.xhr_.addEventListener("error",()=>{this.errorCode_=Oo.NETWORK_ERROR,e()}),this.xhr_.addEventListener("load",()=>{e()})})}send(e,a,n,i){if(this.sent_)throw Tc("cannot .send() more than once");if(this.sent_=!0,this.xhr_.open(a,e,!0),i!==void 0)for(const r in i)i.hasOwnProperty(r)&&this.xhr_.setRequestHeader(r,i[r].toString());return n!==void 0?this.xhr_.send(n):this.xhr_.send(),this.sendPromise_}getErrorCode(){if(!this.sent_)throw Tc("cannot .getErrorCode() before sending");return this.errorCode_}getStatus(){if(!this.sent_)throw Tc("cannot .getStatus() before sending");try{return this.xhr_.status}catch{return-1}}getResponse(){if(!this.sent_)throw Tc("cannot .getResponse() before sending");return this.xhr_.response}getErrorText(){if(!this.sent_)throw Tc("cannot .getErrorText() before sending");return this.xhr_.statusText}abort(){this.xhr_.abort()}getResponseHeader(e){return this.xhr_.getResponseHeader(e)}addUploadProgressListener(e){this.xhr_.upload!=null&&this.xhr_.upload.addEventListener("progress",e)}removeUploadProgressListener(e){this.xhr_.upload!=null&&this.xhr_.upload.removeEventListener("progress",e)}}class AQ extends _Q{initXhr(){this.xhr_.responseType="text"}}function T3(){return new AQ}/** 2237 * @license 2238 * Copyright 2019 Google LLC 2239 * 2240 * Licensed under the Apache License, Version 2.0 (the "License"); 2241 * you may not use this file except in compliance with the License. 2242 * You may obtain a copy of the License at 2243 * 2244 * http://www.apache.org/licenses/LICENSE-2.0 2245 * 2246 * Unless required by applicable law or agreed to in writing, software 2247 * distributed under the License is distributed on an "AS IS" BASIS, 2248 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2249 * See the License for the specific language governing permissions and 2250 * limitations under the License. 2251 */class Yo{constructor(e,a){this._service=e,a instanceof Ha?this._location=a:this._location=Ha.makeFromUrl(a,e.host)}toString(){return"gs://"+this._location.bucket+"/"+this._location.path}_newRef(e,a){return new Yo(e,a)}get root(){const e=new Ha(this._location.bucket,"");return this._newRef(this._service,e)}get bucket(){return this._location.bucket}get fullPath(){return this._location.path}get name(){return S3(this._location.path)}get storage(){return this._service}get parent(){const e=cQ(this._location.path);if(e===null)return null;const a=new Ha(this._location.bucket,e);return new Yo(this._service,a)}_throwIfRoot(e){if(this._location.path==="")throw HJ(e)}}function EQ(t,e,a){t._throwIfRoot("uploadBytes");const n=SQ(t.storage,t._location,_3(),new lr(e,!0),a);return t.storage.makeRequestWithTokens(n,T3).then(i=>({metadata:i,ref:t}))}function CQ(t){t._throwIfRoot("getDownloadURL");const e=bQ(t.storage,t._location,_3());return t.storage.makeRequestWithTokens(e,T3).then(a=>{if(a===null)throw zJ();return a})}function jQ(t,e){const a=dQ(t._location.path,e),n=new Ha(t._location.bucket,a);return new Yo(t.storage,n)}/** 2252 * @license 2253 * Copyright 2017 Google LLC 2254 * 2255 * Licensed under the Apache License, Version 2.0 (the "License");
2256 * you may not use this file except in compliance with the License. 2257 * You may obtain a copy of the License at 2258 * 2259 * http://www.apache.org/licenses/LICENSE-2.0 2260 * 2261 * Unless required by applicable law or agreed to in writing, software 2262 * distributed under the License is distributed on an "AS IS" BASIS, 2263 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2264 * See the License for the specific language governing permissions and 2265 * limitations under the License. 2266 */function TQ(t){return/^[A-Za-z]+:\/\//.test(t)}function NQ(t,e){return new Yo(t,e)}function N3(t,e){if(t instanceof Ck){const a=t;if(a._bucket==null)throw DJ();const n=new Yo(a,a._bucket);return e!=null?N3(n,e):n}else return e!==void 0?jQ(t,e):t}function IQ(t,e){if(e&&TQ(e)){if(t instanceof Ck)return NQ(t,e);throw hb("To use ref(service, url), the first argument must be a Storage instance.")}else return N3(t,e)}function DC(t,e){const a=e==null?void 0:e[g3];return a==null?null:Ha.makeFromBucketSpec(a,t)}function PQ(t,e,a,n={}){t.host=`${e}:${a}`,t._protocol="http";const{mockUserToken:i}=n;i&&(t._overrideAuthToken=typeof i=="string"?i:zR(i,t.app.options.projectId))}class Ck{constructor(e,a,n,i,r){this.app=e,this._authProvider=a,this._appCheckProvider=n,this._url=i,this._firebaseVersion=r,this._bucket=null,this._host=f3,this._protocol="https",this._appId=null,this._deleted=!1,this._maxOperationRetryTime=EJ,this._maxUploadRetryTime=CJ,this._requests=new Set,i!=null?this._bucket=Ha.makeFromBucketSpec(i,this._host):this._bucket=DC(this._host,this.app.options)}get host(){return this._host}set host(e){this._host=e,this._url!=null?this._bucket=Ha.makeFromBucketSpec(this._url,e):this._bucket=DC(e,this.app.options)}get maxUploadRetryTime(){return this._maxUploadRetryTime}set maxUploadRetryTime(e){MC("time",0,Number.POSITIVE_INFINITY,e),this._maxUploadRetryTime=e}get maxOperationRetryTime(){return this._maxOperationRetryTime}set maxOperationRetryTime(e){MC("time",0,Number.POSITIVE_INFINITY,e),this._maxOperationRetryTime=e}async _getAuthToken(){if(this._overrideAuthToken)return this._overrideAuthToken;const e=this._authProvider.getImmediate({optional:!0});if(e){const a=await e.getToken();if(a!==null)return a.accessToken}return null}async _getAppCheckToken(){const e=this._appCheckProvider.getImmediate({optional:!0});return e?(await e.getToken()).token:null}_delete(){return this._deleted||(this._deleted=!0,this._requests.forEach(e=>e.cancel()),this._requests.clear()),Promise.resolve()}_makeStorageReference(e){return new Yo(this,e)}_makeRequest(e,a,n,i,r=!0){if(this._deleted)return new FJ(y3());{const o=ZJ(e,this._appId,n,i,a,this._firebaseVersion,r);return this._requests.add(o),o.getPromise().then(()=>this._requests.delete(o),()=>this._requests.delete(o)),o}}async makeRequestWithTokens(e,a){const[n,i]=await Promise.all([this._getAuthToken(),this._getAppCheckToken()]);return this._makeRequest(e,a,n,i).getPromise()}}const qC="@firebase/storage",zC="0.13.2";/** 2267 * @license 2268 * Copyright 2020 Google LLC 2269 * 2270 * Licensed under the Apache License, Version 2.0 (the "License"); 2271 * you may not use this file except in compliance with the License. 2272 * You may obtain a copy of the License at 2273 * 2274 * http://www.apache.org/licenses/LICENSE-2.0 2275 * 2276 * Unless required by applicable law or agreed to in writing, software 2277 * distributed under the License is distributed on an "AS IS" BASIS, 2278 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2279 * See the License for the specific language governing permissions and 2280 * limitations under the License. 2281 */const I3="storage";function jk(t,e,a){return t=et(t),EQ(t,e,a)}function Tk(t){return t=et(t),CQ(t)}function Nk(t,e){return t=et(t),IQ(t,e)}function RQ(t=mg(),e){t=et(t);const n=Qr(t,I3).getImmediate({identifier:e}),i=MR("storage");return i&&LQ(n,...i),n}function LQ(t,e,a,n={}){PQ(t,e,a,n)}function OQ(t,{instanceIdentifier:e}){const a=t.getProvider("app").getImmediate(),n=t.getProvider("auth-internal"),i=t.getProvider("app-check-internal");return new Ck(a,n,i,e,us)}function MQ(){Dn(new hn(I3,OQ,"PUBLIC").setMultipleInstances(!0)),Na(qC,zC,""),Na(qC,zC,"esm2017")}MQ();var DQ="firebase",qQ="10.14.1";/** 2282 * @license 2283 * Copyright 2020 Google LLC 2284 * 2285 * Licensed under the Apache License, Version 2.0 (the "License");
2286 * you may not use this file except in compliance with the License. 2287 * You may obtain a copy of the License at 2288 * 2289 * http://www.apache.org/licenses/LICENSE-2.0 2290 * 2291 * Unless required by applicable law or agreed to in writing, software 2292 * distributed under the License is distributed on an "AS IS" BASIS, 2293 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2294 * See the License for the specific language governing permissions and 2295 * limitations under the License. 2296 */Na(DQ,qQ,"app");function Ik(t,e){var a={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&e.indexOf(n)<0&&(a[n]=t[n]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,n=Object.getOwnPropertySymbols(t);i<n.length;i++)e.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(t,n[i])&&(a[n[i]]=t[n[i]]);return a}function P3(){return{"dependent-sdk-initialized-before-auth":"Another Firebase SDK was initialized and is trying to use Auth before Auth is initialized. Please be sure to call `initializeAuth` or `getAuth` before starting any other Firebase SDK."}}const zQ=P3,R3=new ds("auth","Firebase",P3());/** 2297 * @license 2298 * Copyright 2020 Google LLC 2299 * 2300 * Licensed under the Apache License, Version 2.0 (the "License"); 2301 * you may not use this file except in compliance with the License. 2302 * You may obtain a copy of the License at 2303 * 2304 * http://www.apache.org/licenses/LICENSE-2.0 2305 * 2306 * Unless required by applicable law or agreed to in writing, software 2307 * distributed under the License is distributed on an "AS IS" BASIS, 2308 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2309 * See the License for the specific language governing permissions and 2310 * limitations under the License. 2311 */const zh=new pg("@firebase/auth");function VQ(t,...e){zh.logLevel<=_e.WARN&&zh.warn(`Auth (${us}): ${t}`,...e)}function qm(t,...e){zh.logLevel<=_e.ERROR&&zh.error(`Auth (${us}): ${t}`,...e)}/** 2312 * @license 2313 * Copyright 2020 Google LLC 2314 * 2315 * Licensed under the Apache License, Version 2.0 (the "License"); 2316 * you may not use this file except in compliance with the License. 2317 * You may obtain a copy of the License at 2318 * 2319 * http://www.apache.org/licenses/LICENSE-2.0 2320 * 2321 * Unless required by applicable law or agreed to in writing, software 2322 * distributed under the License is distributed on an "AS IS" BASIS, 2323 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2324 * See the License for the specific language governing permissions and 2325 * limitations under the License. 2326 */function ii(t,...e){throw Rk(t,...e)}function Pn(t,...e){return Rk(t,...e)}function Pk(t,e,a){const n=Object.assign(Object.assign({},zQ()),{[e]:a});return new ds("auth","Firebase",n).create(e,{appName:t.name})}function Mo(t){return Pk(t,"operation-not-supported-in-this-environment","Operations that alter the current user are not supported in conjunction with FirebaseServerApp")}function HQ(t,e,a){const n=a;if(!(e instanceof n))throw n.name!==e.constructor.name&&ii(t,"argument-error"),Pk(t,"argument-error",`Type of ${e.constructor.name} does not match expected instance.Did you pass a reference from a different Auth SDK?`)}function Rk(t,...e){if(typeof t!="string"){const a=e[0],n=[...e.slice(1)];return n[0]&&(n[0].appName=t.name),t._errorFactory.create(a,...n)}return R3.create(t,...e)}function ue(t,e,...a){if(!t)throw Rk(e,...a)}function ki(t){const e="INTERNAL ASSERTION FAILED: "+t;throw qm(e),new Error(e)}function Bi(t,e){t||ki(e)}/** 2327 * @license 2328 * Copyright 2020 Google LLC 2329 * 2330 * Licensed under the Apache License, Version 2.0 (the "License"); 2331 * you may not use this file except in compliance with the License. 2332 * You may obtain a copy of the License at 2333 * 2334 * http://www.apache.org/licenses/LICENSE-2.0 2335 * 2336 * Unless required by applicable law or agreed to in writing, software 2337 * distributed under the License is distributed on an "AS IS" BASIS, 2338 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2339 * See the License for the specific language governing permissions and 2340 * limitations under the License. 2341 */function fb(){var t;return typeof self<"u"&&((t=self.location)===null||t===void 0?void 0:t.href)||""}function FQ(){return VC()==="http:"||VC()==="https:"}function VC(){var t;return typeof self<"u"&&((t=self.location)===null||t===void 0?void 0:t.protocol)||null}/** 2342 * @license 2343 * Copyright 2020 Google LLC 2344 * 2345 * Licensed under the Apache License, Version 2.0 (the "License");
2346 * you may not use this file except in compliance with the License. 2347 * You may obtain a copy of the License at 2348 * 2349 * http://www.apache.org/licenses/LICENSE-2.0 2350 * 2351 * Unless required by applicable law or agreed to in writing, software 2352 * distributed under the License is distributed on an "AS IS" BASIS, 2353 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2354 * See the License for the specific language governing permissions and 2355 * limitations under the License. 2356 */function BQ(){return typeof navigator<"u"&&navigator&&"onLine"in navigator&&typeof navigator.onLine=="boolean"&&(FQ()||Dw()||"connection"in navigator)?navigator.onLine:!0}function UQ(){if(typeof navigator>"u")return null;const t=navigator;return t.languages&&t.languages[0]||t.language||null}/** 2357 * @license 2358 * Copyright 2020 Google LLC 2359 * 2360 * Licensed under the Apache License, Version 2.0 (the "License"); 2361 * you may not use this file except in compliance with the License. 2362 * You may obtain a copy of the License at 2363 * 2364 * http://www.apache.org/licenses/LICENSE-2.0 2365 * 2366 * Unless required by applicable law or agreed to in writing, software 2367 * distributed under the License is distributed on an "AS IS" BASIS, 2368 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2369 * See the License for the specific language governing permissions and 2370 * limitations under the License. 2371 */class Fu{constructor(e,a){this.shortDelay=e,this.longDelay=a,Bi(a>e,"Short delay should be less than long delay!"),this.isMobile=ZU()||a$()}get(){return BQ()?this.isMobile?this.longDelay:this.shortDelay:Math.min(5e3,this.shortDelay)}}/** 2372 * @license 2373 * Copyright 2020 Google LLC 2374 * 2375 * Licensed under the Apache License, Version 2.0 (the "License"); 2376 * you may not use this file except in compliance with the License. 2377 * You may obtain a copy of the License at 2378 * 2379 * http://www.apache.org/licenses/LICENSE-2.0 2380 * 2381 * Unless required by applicable law or agreed to in writing, software 2382 * distributed under the License is distributed on an "AS IS" BASIS, 2383 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2384 * See the License for the specific language governing permissions and 2385 * limitations under the License. 2386 */function Lk(t,e){Bi(t.emulator,"Emulator should always be set here");const{url:a}=t.emulator;return e?`${a}${e.startsWith("/")?e.slice(1):e}`:a}/** 2387 * @license 2388 * Copyright 2020 Google LLC 2389 * 2390 * Licensed under the Apache License, Version 2.0 (the "License"); 2391 * you may not use this file except in compliance with the License. 2392 * You may obtain a copy of the License at 2393 * 2394 * http://www.apache.org/licenses/LICENSE-2.0 2395 * 2396 * Unless required by applicable law or agreed to in writing, software 2397 * distributed under the License is distributed on an "AS IS" BASIS, 2398 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2399 * See the License for the specific language governing permissions and 2400 * limitations under the License. 2401 */class L3{static initialize(e,a,n){this.fetchImpl=e,a&&(this.headersImpl=a),n&&(this.responseImpl=n)}static fetch(){if(this.fetchImpl)return this.fetchImpl;if(typeof self<"u"&&"fetch"in self)return self.fetch;if(typeof globalThis<"u"&&globalThis.fetch)return globalThis.fetch;if(typeof fetch<"u")return fetch;ki("Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}static headers(){if(this.headersImpl)return this.headersImpl;if(typeof self<"u"&&"Headers"in self)return self.Headers;if(typeof globalThis<"u"&&globalThis.Headers)return globalThis.Headers;if(typeof Headers<"u")return Headers;ki("Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}static response(){if(this.responseImpl)return this.responseImpl;if(typeof self<"u"&&"Response"in self)return self.Response;if(typeof globalThis<"u"&&globalThis.Response)return globalThis.Response;if(typeof Response<"u")return Response;ki("Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}}/** 2402 * @license 2403 * Copyright 2020 Google LLC 2404 * 2405 * Licensed under the Apache License, Version 2.0 (the "License");
2406 * you may not use this file except in compliance with the License. 2407 * You may obtain a copy of the License at 2408 * 2409 * http://www.apache.org/licenses/LICENSE-2.0 2410 * 2411 * Unless required by applicable law or agreed to in writing, software 2412 * distributed under the License is distributed on an "AS IS" BASIS, 2413 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2414 * See the License for the specific language governing permissions and 2415 * limitations under the License. 2416 */const $Q={CREDENTIAL_MISMATCH:"custom-token-mismatch",MISSING_CUSTOM_TOKEN:"internal-error",INVALID_IDENTIFIER:"invalid-email",MISSING_CONTINUE_URI:"internal-error",INVALID_PASSWORD:"wrong-password",MISSING_PASSWORD:"missing-password",INVALID_LOGIN_CREDENTIALS:"invalid-credential",EMAIL_EXISTS:"email-already-in-use",PASSWORD_LOGIN_DISABLED:"operation-not-allowed",INVALID_IDP_RESPONSE:"invalid-credential",INVALID_PENDING_TOKEN:"invalid-credential",FEDERATED_USER_ID_ALREADY_LINKED:"credential-already-in-use",MISSING_REQ_TYPE:"internal-error",EMAIL_NOT_FOUND:"user-not-found",RESET_PASSWORD_EXCEED_LIMIT:"too-many-requests",EXPIRED_OOB_CODE:"expired-action-code",INVALID_OOB_CODE:"invalid-action-code",MISSING_OOB_CODE:"internal-error",CREDENTIAL_TOO_OLD_LOGIN_AGAIN:"requires-recent-login",INVALID_ID_TOKEN:"invalid-user-token",TOKEN_EXPIRED:"user-token-expired",USER_NOT_FOUND:"user-token-expired",TOO_MANY_ATTEMPTS_TRY_LATER:"too-many-requests",PASSWORD_DOES_NOT_MEET_REQUIREMENTS:"password-does-not-meet-requirements",INVALID_CODE:"invalid-verification-code",INVALID_SESSION_INFO:"invalid-verification-id",INVALID_TEMPORARY_PROOF:"invalid-credential",MISSING_SESSION_INFO:"missing-verification-id",SESSION_EXPIRED:"code-expired",MISSING_ANDROID_PACKAGE_NAME:"missing-android-pkg-name",UNAUTHORIZED_DOMAIN:"unauthorized-continue-uri",INVALID_OAUTH_CLIENT_ID:"invalid-oauth-client-id",ADMIN_ONLY_OPERATION:"admin-restricted-operation",INVALID_MFA_PENDING_CREDENTIAL:"invalid-multi-factor-session",MFA_ENROLLMENT_NOT_FOUND:"multi-factor-info-not-found",MISSING_MFA_ENROLLMENT_ID:"missing-multi-factor-info",MISSING_MFA_PENDING_CREDENTIAL:"missing-multi-factor-session",SECOND_FACTOR_EXISTS:"second-factor-already-in-use",SECOND_FACTOR_LIMIT_EXCEEDED:"maximum-second-factor-count-exceeded",BLOCKING_FUNCTION_ERROR_RESPONSE:"internal-error",RECAPTCHA_NOT_ENABLED:"recaptcha-not-enabled",MISSING_RECAPTCHA_TOKEN:"missing-recaptcha-token",INVALID_RECAPTCHA_TOKEN:"invalid-recaptcha-token",INVALID_RECAPTCHA_ACTION:"invalid-recaptcha-action",MISSING_CLIENT_TYPE:"missing-client-type",MISSING_RECAPTCHA_VERSION:"missing-recaptcha-version",INVALID_RECAPTCHA_VERSION:"invalid-recaptcha-version",INVALID_REQ_TYPE:"invalid-req-type"};/** 2417 * @license 2418 * Copyright 2020 Google LLC 2419 * 2420 * Licensed under the Apache License, Version 2.0 (the "License"); 2421 * you may not use this file except in compliance with the License. 2422 * You may obtain a copy of the License at 2423 * 2424 * http://www.apache.org/licenses/LICENSE-2.0 2425 * 2426 * Unless required by applicable law or agreed to in writing, software 2427 * distributed under the License is distributed on an "AS IS" BASIS, 2428 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2429 * See the License for the specific language governing permissions and 2430 * limitations under the License. 2431 */const WQ=new Fu(3e4,6e4);function Ok(t,e){return t.tenantId&&!e.tenantId?Object.assign(Object.assign({},e),{tenantId:t.tenantId}):e}async function Yl(t,e,a,n,i={}){return O3(t,i,async()=>{let r={},o={};n&&(e==="GET"?o=n:r={body:JSON.stringify(n)});const l=Ru(Object.assign({key:t.config.apiKey},o)).slice(1),c=await t._getAdditionalHeaders();c["Content-Type"]="application/json",t.languageCode&&(c["X-Firebase-Locale"]=t.languageCode);const d=Object.assign({method:e,headers:c},r);return t$()||(d.referrerPolicy="no-referrer"),L3.fetch()(M3(t,t.config.apiHost,a,l),d)})}async function O3(t,e,a){t._canInitEmulator=!1;const n=Object.assign(Object.assign({},$Q),e);try{const i=new KQ(t),r=await Promise.race([a(),i.promise]);i.clearNetworkTimeout();const o=await r.json();if("needConfirmation"in o)throw Wp(t,"account-exists-with-different-credential",o);if(r.ok&&!("errorMessage"in o))return o;{const l=r.ok?o.errorMessage:o.error.message,[c,d]=l.split(" : ");if(c==="FEDERATED_USER_ID_ALREADY_LINKED")throw Wp(t,"credential-already-in-use",o);if(c==="EMAIL_EXISTS")throw Wp(t,"email-already-in-use",o);if(c==="USER_DISABLED")throw Wp(t,"user-disabled",o);const u=n[c]||c.toLowerCase().replace(/[_\s]+/g,"-");if(d)throw Pk(t,u,d);ii(t,u)}}catch(i){if(i instanceof gn)throw i;ii(t,"network-request-failed",{message:String(i)})}}async function GQ(t,e,a,n,i={}){const r=await Yl(t,e,a,n,i);return"mfaPendingCredential"in r&&ii(t,"multi-factor-auth-required",{_serverResponse:r}),r}function M3(t,e,a,n){const i=`${e}${a}?${n}`;return t.config.emulator?Lk(t.config,i):`${t.config.apiScheme}://${i}`}class KQ{constructor(e){this.auth=e,this.timer=null,this.promise=new Promise((a,n)=>{this.timer=setTimeout(()=>n(Pn(this.auth,"network-request-failed")),WQ.get())})}clearNetworkTimeout(){clearTimeout(this.timer)}}function Wp(t,e,a){const n={appName:t.name};a.email&&(n.email=a.email),a.phoneNumber&&(n.phoneNumber=a.phoneNumber);const i=Pn(t,e,n);return i.customData._tokenResponse=a,i}/** 2432 * @license 2433 * Copyright 2020 Google LLC 2434 * 2435 * Licensed under the Apache License, Version 2.0 (the "License");
2436 * you may not use this file except in compliance with the License. 2437 * You may obtain a copy of the License at 2438 * 2439 * http://www.apache.org/licenses/LICENSE-2.0 2440 * 2441 * Unless required by applicable law or agreed to in writing, software 2442 * distributed under the License is distributed on an "AS IS" BASIS, 2443 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2444 * See the License for the specific language governing permissions and 2445 * limitations under the License. 2446 */async function JQ(t,e){return Yl(t,"POST","/v1/accounts:delete",e)}async function D3(t,e){return Yl(t,"POST","/v1/accounts:lookup",e)}/** 2447 * @license 2448 * Copyright 2020 Google LLC 2449 * 2450 * Licensed under the Apache License, Version 2.0 (the "License"); 2451 * you may not use this file except in compliance with the License. 2452 * You may obtain a copy of the License at 2453 * 2454 * http://www.apache.org/licenses/LICENSE-2.0 2455 * 2456 * Unless required by applicable law or agreed to in writing, software 2457 * distributed under the License is distributed on an "AS IS" BASIS, 2458 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2459 * See the License for the specific language governing permissions and 2460 * limitations under the License. 2461 */function gd(t){if(t)try{const e=new Date(Number(t));if(!isNaN(e.getTime()))return e.toUTCString()}catch{}}async function QQ(t,e=!1){const a=et(t),n=await a.getIdToken(e),i=Mk(n);ue(i&&i.exp&&i.auth_time&&i.iat,a.auth,"internal-error");const r=typeof i.firebase=="object"?i.firebase:void 0,o=r==null?void 0:r.sign_in_provider;return{claims:i,token:n,authTime:gd(R0(i.auth_time)),issuedAtTime:gd(R0(i.iat)),expirationTime:gd(R0(i.exp)),signInProvider:o||null,signInSecondFactor:(r==null?void 0:r.sign_in_second_factor)||null}}function R0(t){return Number(t)*1e3}function Mk(t){const[e,a,n]=t.split(".");if(e===void 0||a===void 0||n===void 0)return qm("JWT malformed, contained fewer than 3 sections"),null;try{const i=LR(a);return i?JSON.parse(i):(qm("Failed to decode base64 JWT payload"),null)}catch(i){return qm("Caught error parsing JWT payload as JSON",i==null?void 0:i.toString()),null}}function HC(t){const e=Mk(t);return ue(e,"internal-error"),ue(typeof e.exp<"u","internal-error"),ue(typeof e.iat<"u","internal-error"),Number(e.exp)-Number(e.iat)}/** 2462 * @license 2463 * Copyright 2020 Google LLC 2464 * 2465 * Licensed under the Apache License, Version 2.0 (the "License"); 2466 * you may not use this file except in compliance with the License. 2467 * You may obtain a copy of the License at 2468 * 2469 * http://www.apache.org/licenses/LICENSE-2.0 2470 * 2471 * Unless required by applicable law or agreed to in writing, software 2472 * distributed under the License is distributed on an "AS IS" BASIS, 2473 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2474 * See the License for the specific language governing permissions and 2475 * limitations under the License. 2476 */async function cu(t,e,a=!1){if(a)return e;try{return await e}catch(n){throw n instanceof gn&&XQ(n)&&t.auth.currentUser===t&&await t.auth.signOut(),n}}function XQ({code:t}){return t==="auth/user-disabled"||t==="auth/user-token-expired"}/** 2477 * @license 2478 * Copyright 2020 Google LLC 2479 * 2480 * Licensed under the Apache License, Version 2.0 (the "License"); 2481 * you may not use this file except in compliance with the License. 2482 * You may obtain a copy of the License at 2483 * 2484 * http://www.apache.org/licenses/LICENSE-2.0 2485 * 2486 * Unless required by applicable law or agreed to in writing, software 2487 * distributed under the License is distributed on an "AS IS" BASIS, 2488 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2489 * See the License for the specific language governing permissions and 2490 * limitations under the License. 2491 */class YQ{constructor(e){this.user=e,this.isRunning=!1,this.timerId=null,this.errorBackoff=3e4}_start(){this.isRunning||(this.isRunning=!0,this.schedule())}_stop(){this.isRunning&&(this.isRunning=!1,this.timerId!==null&&clearTimeout(this.timerId))}getInterval(e){var a;if(e){const n=this.errorBackoff;return this.errorBackoff=Math.min(this.errorBackoff*2,96e4),n}else{this.errorBackoff=3e4;const i=((a=this.user.stsTokenManager.expirationTime)!==null&&a!==void 0?a:0)-Date.now()-3e5;return Math.max(0,i)}}schedule(e=!1){if(!this.isRunning)return;const a=this.getInterval(e);this.timerId=setTimeout(async()=>{await this.iteration()},a)}async iteration(){try{await this.user.getIdToken(!0)}catch(e){(e==null?void 0:e.code)==="auth/network-request-failed"&&this.schedule(!0);return}this.schedule()}}/** 2492 * @license 2493 * Copyright 2020 Google LLC 2494 * 2495 * Licensed under the Apache License, Version 2.0 (the "License");
2496 * you may not use this file except in compliance with the License. 2497 * You may obtain a copy of the License at 2498 * 2499 * http://www.apache.org/licenses/LICENSE-2.0 2500 * 2501 * Unless required by applicable law or agreed to in writing, software 2502 * distributed under the License is distributed on an "AS IS" BASIS, 2503 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2504 * See the License for the specific language governing permissions and 2505 * limitations under the License. 2506 */class gb{constructor(e,a){this.createdAt=e,this.lastLoginAt=a,this._initializeTime()}_initializeTime(){this.lastSignInTime=gd(this.lastLoginAt),this.creationTime=gd(this.createdAt)}_copy(e){this.createdAt=e.createdAt,this.lastLoginAt=e.lastLoginAt,this._initializeTime()}toJSON(){return{createdAt:this.createdAt,lastLoginAt:this.lastLoginAt}}}/** 2507 * @license 2508 * Copyright 2019 Google LLC 2509 * 2510 * Licensed under the Apache License, Version 2.0 (the "License"); 2511 * you may not use this file except in compliance with the License. 2512 * You may obtain a copy of the License at 2513 * 2514 * http://www.apache.org/licenses/LICENSE-2.0 2515 * 2516 * Unless required by applicable law or agreed to in writing, software 2517 * distributed under the License is distributed on an "AS IS" BASIS, 2518 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2519 * See the License for the specific language governing permissions and 2520 * limitations under the License. 2521 */async function Vh(t){var e;const a=t.auth,n=await t.getIdToken(),i=await cu(t,D3(a,{idToken:n}));ue(i==null?void 0:i.users.length,a,"internal-error");const r=i.users[0];t._notifyReloadListener(r);const o=!((e=r.providerUserInfo)===null||e===void 0)&&e.length?q3(r.providerUserInfo):[],l=eX(t.providerData,o),c=t.isAnonymous,d=!(t.email&&r.passwordHash)&&!(l!=null&&l.length),u=c?d:!1,p={uid:r.localId,displayName:r.displayName||null,photoURL:r.photoUrl||null,email:r.email||null,emailVerified:r.emailVerified||!1,phoneNumber:r.phoneNumber||null,tenantId:r.tenantId||null,providerData:l,metadata:new gb(r.createdAt,r.lastLoginAt),isAnonymous:u};Object.assign(t,p)}async function ZQ(t){const e=et(t);await Vh(e),await e.auth._persistUserIfCurrent(e),e.auth._notifyListenersIfCurrent(e)}function eX(t,e){return[...t.filter(n=>!e.some(i=>i.providerId===n.providerId)),...e]}function q3(t){return t.map(e=>{var{providerId:a}=e,n=Ik(e,["providerId"]);return{providerId:a,uid:n.rawId||"",displayName:n.displayName||null,email:n.email||null,phoneNumber:n.phoneNumber||null,photoURL:n.photoUrl||null}})}/** 2522 * @license 2523 * Copyright 2020 Google LLC 2524 * 2525 * Licensed under the Apache License, Version 2.0 (the "License"); 2526 * you may not use this file except in compliance with the License. 2527 * You may obtain a copy of the License at 2528 * 2529 * http://www.apache.org/licenses/LICENSE-2.0 2530 * 2531 * Unless required by applicable law or agreed to in writing, software 2532 * distributed under the License is distributed on an "AS IS" BASIS, 2533 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2534 * See the License for the specific language governing permissions and 2535 * limitations under the License. 2536 */async function tX(t,e){const a=await O3(t,{},async()=>{const n=Ru({grant_type:"refresh_token",refresh_token:e}).slice(1),{tokenApiHost:i,apiKey:r}=t.config,o=M3(t,i,"/v1/token",`key=${r}`),l=await t._getAdditionalHeaders();return l["Content-Type"]="application/x-www-form-urlencoded",L3.fetch()(o,{method:"POST",headers:l,body:n})});return{accessToken:a.access_token,expiresIn:a.expires_in,refreshToken:a.refresh_token}}async function aX(t,e){return Yl(t,"POST","/v2/accounts:revokeToken",Ok(t,e))}/** 2537 * @license 2538 * Copyright 2020 Google LLC 2539 * 2540 * Licensed under the Apache License, Version 2.0 (the "License"); 2541 * you may not use this file except in compliance with the License. 2542 * You may obtain a copy of the License at 2543 * 2544 * http://www.apache.org/licenses/LICENSE-2.0 2545 * 2546 * Unless required by applicable law or agreed to in writing, software 2547 * distributed under the License is distributed on an "AS IS" BASIS, 2548 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2549 * See the License for the specific language governing permissions and 2550 * limitations under the License. 2551 */class sl{constructor(){this.refreshToken=null,this.accessToken=null,this.expirationTime=null}get isExpired(){return!this.expirationTime||Date.now()>this.expirationTime-3e4}updateFromServerResponse(e){ue(e.idToken,"internal-error"),ue(typeof e.idToken<"u","internal-error"),ue(typeof e.refreshToken<"u","internal-error");
2551const a="expiresIn"in e&&typeof e.expiresIn<"u"?Number(e.expiresIn):HC(e.idToken);this.updateTokensAndExpiration(e.idToken,e.refreshToken,a)}updateFromIdToken(e){ue(e.length!==0,"internal-error");const a=HC(e);this.updateTokensAndExpiration(e,null,a)}async getToken(e,a=!1){return!a&&this.accessToken&&!this.isExpired?this.accessToken:(ue(this.refreshToken,e,"user-token-expired"),this.refreshToken?(await this.refresh(e,this.refreshToken),this.accessToken):null)}clearRefreshToken(){this.refreshToken=null}async refresh(e,a){const{accessToken:n,refreshToken:i,expiresIn:r}=await tX(e,a);this.updateTokensAndExpiration(n,i,Number(r))}updateTokensAndExpiration(e,a,n){this.refreshToken=a||null,this.accessToken=e||null,this.expirationTime=Date.now()+n*1e3}static fromJSON(e,a){const{refreshToken:n,accessToken:i,expirationTime:r}=a,o=new sl;return n&&(ue(typeof n=="string","internal-error",{appName:e}),o.refreshToken=n),i&&(ue(typeof i=="string","internal-error",{appName:e}),o.accessToken=i),r&&(ue(typeof r=="number","internal-error",{appName:e}),o.expirationTime=r),o}toJSON(){return{refreshToken:this.refreshToken,accessToken:this.accessToken,expirationTime:this.expirationTime}}_assign(e){this.accessToken=e.accessToken,this.refreshToken=e.refreshToken,this.expirationTime=e.expirationTime}_clone(){return Object.assign(new sl,this.toJSON())}_performRefresh(){return ki("not implemented")}}/** 2552 * @license 2553 * Copyright 2020 Google LLC 2554 * 2555 * Licensed under the Apache License, Version 2.0 (the "License"); 2556 * you may not use this file except in compliance with the License. 2557 * You may obtain a copy of the License at 2558 * 2559 * http://www.apache.org/licenses/LICENSE-2.0 2560 * 2561 * Unless required by applicable law or agreed to in writing, software 2562 * distributed under the License is distributed on an "AS IS" BASIS, 2563 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2564 * See the License for the specific language governing permissions and 2565 * limitations under the License. 2566 */function Qi(t,e){ue(typeof t=="string"||typeof t>"u","internal-error",{appName:e})}class Si{constructor(e){var{uid:a,auth:n,stsTokenManager:i}=e,r=Ik(e,["uid","auth","stsTokenManager"]);this.providerId="firebase",this.proactiveRefresh=new YQ(this),this.reloadUserInfo=null,this.reloadListener=null,this.uid=a,this.auth=n,this.stsTokenManager=i,this.accessToken=i.accessToken,this.displayName=r.displayName||null,this.email=r.email||null,this.emailVerified=r.emailVerified||!1,this.phoneNumber=r.phoneNumber||null,this.photoURL=r.photoURL||null,this.isAnonymous=r.isAnonymous||!1,this.tenantId=r.tenantId||null,this.providerData=r.providerData?[...r.providerData]:[],this.metadata=new gb(r.createdAt||void 0,r.lastLoginAt||void 0)}async getIdToken(e){const a=await cu(this,this.stsTokenManager.getToken(this.auth,e));return ue(a,this.auth,"internal-error"),this.accessToken!==a&&(this.accessToken=a,await this.auth._persistUserIfCurrent(this),this.auth._notifyListenersIfCurrent(this)),a}getIdTokenResult(e){return QQ(this,e)}reload(){return ZQ(this)}_assign(e){this!==e&&(ue(this.uid===e.uid,this.auth,"internal-error"),this.displayName=e.displayName,this.photoURL=e.photoURL,this.email=e.email,this.emailVerified=e.emailVerified,this.phoneNumber=e.phoneNumber,this.isAnonymous=e.isAnonymous,this.tenantId=e.tenantId,this.providerData=e.providerData.map(a=>Object.assign({},a)),this.metadata._copy(e.metadata),this.stsTokenManager._assign(e.stsTokenManager))}_clone(e){const a=new Si(Object.assign(Object.assign({},this),{auth:e,stsTokenManager:this.stsTokenManager._clone()}));return a.metadata._copy(this.metadata),a}_onReload(e){ue(!this.reloadListener,this.auth,"internal-error"),this.reloadListener=e,this.reloadUserInfo&&(this._notifyReloadListener(this.reloadUserInfo),this.reloadUserInfo=null)}_notifyReloadListener(e){this.reloadListener?this.reloadListener(e):this.reloadUserInfo=e}_startProactiveRefresh(){this.proactiveRefresh._start()}_stopProactiveRefresh(){this.proactiveRefresh._stop()}async _updateTokensIfNecessary(e,a=!1){let n=!1;e.idToken&&e.idToken!==this.stsTokenManager.accessToken&&(this.stsTokenManager.updateFromServerResponse(e),n=!0),a&&await Vh(this),await this.auth._persistUserIfCurrent(this),n&&this.auth._notifyListenersIfCurrent(this)}async delete(){if(wi(this.auth.app))return Promise.reject(Mo(this.auth));const e=await this.getIdToken();return await cu(this,JQ(this.auth,{idToken:e})),this.stsTokenManager.clearRefreshToken(),this.auth.signOut()}toJSON(){return Object.assign(Object.assign({uid:this.uid,email:this.email||void 0,emailVerified:this.emailVerified,displayName:this.displayName||void 0,isA
2566nonymous:this.isAnonymous,photoURL:this.photoURL||void 0,phoneNumber:this.phoneNumber||void 0,tenantId:this.tenantId||void 0,providerData:this.providerData.map(e=>Object.assign({},e)),stsTokenManager:this.stsTokenManager.toJSON(),_redirectEventId:this._redirectEventId},this.metadata.toJSON()),{apiKey:this.auth.config.apiKey,appName:this.auth.name})}get refreshToken(){return this.stsTokenManager.refreshToken||""}static _fromJSON(e,a){var n,i,r,o,l,c,d,u;const p=(n=a.displayName)!==null&&n!==void 0?n:void 0,m=(i=a.email)!==null&&i!==void 0?i:void 0,h=(r=a.phoneNumber)!==null&&r!==void 0?r:void 0,g=(o=a.photoURL)!==null&&o!==void 0?o:void 0,y=(l=a.tenantId)!==null&&l!==void 0?l:void 0,x=(c=a._redirectEventId)!==null&&c!==void 0?c:void 0,v=(d=a.createdAt)!==null&&d!==void 0?d:void 0,w=(u=a.lastLoginAt)!==null&&u!==void 0?u:void 0,{uid:S,emailVerified:T,isAnonymous:P,providerData:M,stsTokenManager:C}=a;ue(S&&C,e,"internal-error");const E=sl.fromJSON(this.name,C);ue(typeof S=="string",e,"internal-error"),Qi(p,e.name),Qi(m,e.name),ue(typeof T=="boolean",e,"internal-error"),ue(typeof P=="boolean",e,"internal-error"),Qi(h,e.name),Qi(g,e.name),Qi(y,e.name),Qi(x,e.name),Qi(v,e.name),Qi(w,e.name);const j=new Si({uid:S,auth:e,email:m,emailVerified:T,displayName:p,isAnonymous:P,photoURL:g,phoneNumber:h,tenantId:y,stsTokenManager:E,createdAt:v,lastLoginAt:w});return M&&Array.isArray(M)&&(j.providerData=M.map(N=>Object.assign({},N))),x&&(j._redirectEventId=x),j}static async _fromIdTokenResponse(e,a,n=!1){const i=new sl;i.updateFromServerResponse(a);const r=new Si({uid:a.localId,auth:e,stsTokenManager:i,isAnonymous:n});return await Vh(r),r}static async _fromGetAccountInfoResponse(e,a,n){const i=a.users[0];ue(i.localId!==void 0,"internal-error");const r=i.providerUserInfo!==void 0?q3(i.providerUserInfo):[],o=!(i.email&&i.passwordHash)&&!(r!=null&&r.length),l=new sl;l.updateFromIdToken(n);const c=new Si({uid:i.localId,auth:e,stsTokenManager:l,isAnonymous:o}),d={uid:i.localId,displayName:i.displayName||null,photoURL:i.photoUrl||null,email:i.email||null,emailVerified:i.emailVerified||!1,phoneNumber:i.phoneNumber||null,tenantId:i.tenantId||null,providerData:r,metadata:new gb(i.createdAt,i.lastLoginAt),isAnonymous:!(i.email&&i.passwordHash)&&!(r!=null&&r.length)};return Object.assign(c,d),c}}/** 2567 * @license 2568 * Copyright 2020 Google LLC 2569 * 2570 * Licensed under the Apache License, Version 2.0 (the "License"); 2571 * you may not use this file except in compliance with the License. 2572 * You may obtain a copy of the License at 2573 * 2574 * http://www.apache.org/licenses/LICENSE-2.0 2575 * 2576 * Unless required by applicable law or agreed to in writing, software 2577 * distributed under the License is distributed on an "AS IS" BASIS, 2578 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2579 * See the License for the specific language governing permissions and 2580 * limitations under the License. 2581 */const FC=new Map;function _i(t){Bi(t instanceof Function,"Expected a class definition");let e=FC.get(t);return e?(Bi(e instanceof t,"Instance stored in cache mismatched with class"),e):(e=new t,FC.set(t,e),e)}/** 2582 * @license 2583 * Copyright 2019 Google LLC 2584 * 2585 * Licensed under the Apache License, Version 2.0 (the "License"); 2586 * you may not use this file except in compliance with the License. 2587 * You may obtain a copy of the License at 2588 * 2589 * http://www.apache.org/licenses/LICENSE-2.0 2590 * 2591 * Unless required by applicable law or agreed to in writing, software 2592 * distributed under the License is distributed on an "AS IS" BASIS, 2593 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2594 * See the License for the specific language governing permissions and 2595 * limitations under the License. 2596 */class z3{constructor(){this.type="NONE",this.storage={}}async _isAvailable(){return!0}async _set(e,a){this.storage[e]=a}async _get(e){const a=this.storage[e];return a===void 0?null:a}async _remove(e){delete this.storage[e]}_addListener(e,a){}_removeListener(e,a){}}z3.type="NONE";const BC=z3;/** 2597 * @license 2598 * Copyright 2019 Google LLC 2599 * 2600 * Licensed under the Apache License, Version 2.0 (the "License");
2601 * you may not use this file except in compliance with the License. 2602 * You may obtain a copy of the License at 2603 * 2604 * http://www.apache.org/licenses/LICENSE-2.0 2605 * 2606 * Unless required by applicable law or agreed to in writing, software 2607 * distributed under the License is distributed on an "AS IS" BASIS, 2608 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2609 * See the License for the specific language governing permissions and 2610 * limitations under the License. 2611 */function zm(t,e,a){return`firebase:${t}:${e}:${a}`}class ll{constructor(e,a,n){this.persistence=e,this.auth=a,this.userKey=n;const{config:i,name:r}=this.auth;this.fullUserKey=zm(this.userKey,i.apiKey,r),this.fullPersistenceKey=zm("persistence",i.apiKey,r),this.boundEventHandler=a._onStorageEvent.bind(a),this.persistence._addListener(this.fullUserKey,this.boundEventHandler)}setCurrentUser(e){return this.persistence._set(this.fullUserKey,e.toJSON())}async getCurrentUser(){const e=await this.persistence._get(this.fullUserKey);return e?Si._fromJSON(this.auth,e):null}removeCurrentUser(){return this.persistence._remove(this.fullUserKey)}savePersistenceForRedirect(){return this.persistence._set(this.fullPersistenceKey,this.persistence.type)}async setPersistence(e){if(this.persistence===e)return;const a=await this.getCurrentUser();if(await this.removeCurrentUser(),this.persistence=e,a)return this.setCurrentUser(a)}delete(){this.persistence._removeListener(this.fullUserKey,this.boundEventHandler)}static async create(e,a,n="authUser"){if(!a.length)return new ll(_i(BC),e,n);const i=(await Promise.all(a.map(async d=>{if(await d._isAvailable())return d}))).filter(d=>d);let r=i[0]||_i(BC);const o=zm(n,e.config.apiKey,e.name);let l=null;for(const d of a)try{const u=await d._get(o);if(u){const p=Si._fromJSON(e,u);d!==r&&(l=p),r=d;break}}catch{}const c=i.filter(d=>d._shouldAllowMigration);return!r._shouldAllowMigration||!c.length?new ll(r,e,n):(r=c[0],l&&await r._set(o,l.toJSON()),await Promise.all(a.map(async d=>{if(d!==r)try{await d._remove(o)}catch{}})),new ll(r,e,n))}}/** 2612 * @license 2613 * Copyright 2020 Google LLC 2614 * 2615 * Licensed under the Apache License, Version 2.0 (the "License"); 2616 * you may not use this file except in compliance with the License. 2617 * You may obtain a copy of the License at 2618 * 2619 * http://www.apache.org/licenses/LICENSE-2.0 2620 * 2621 * Unless required by applicable law or agreed to in writing, software 2622 * distributed under the License is distributed on an "AS IS" BASIS, 2623 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2624 * See the License for the specific language governing permissions and 2625 * limitations under the License. 2626 */function UC(t){const e=t.toLowerCase();if(e.includes("opera/")||e.includes("opr/")||e.includes("opios/"))return"Opera";if(B3(e))return"IEMobile";if(e.includes("msie")||e.includes("trident/"))return"IE";if(e.includes("edge/"))return"Edge";if(V3(e))return"Firefox";if(e.includes("silk/"))return"Silk";if($3(e))return"Blackberry";if(W3(e))return"Webos";if(H3(e))return"Safari";if((e.includes("chrome/")||F3(e))&&!e.includes("edge/"))return"Chrome";if(U3(e))return"Android";{const a=/([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/,n=t.match(a);if((n==null?void 0:n.length)===2)return n[1]}return"Other"}function V3(t=ra()){return/firefox\//i.test(t)}function H3(t=ra()){const e=t.toLowerCase();return e.includes("safari/")&&!e.includes("chrome/")&&!e.includes("crios/")&&!e.includes("android")}function F3(t=ra()){return/crios\//i.test(t)}function B3(t=ra()){return/iemobile/i.test(t)}function U3(t=ra()){return/android/i.test(t)}function $3(t=ra()){return/blackberry/i.test(t)}function W3(t=ra()){return/webos/i.test(t)}function Dk(t=ra()){return/iphone|ipad|ipod/i.test(t)||/macintosh/i.test(t)&&/mobile/i.test(t)}function nX(t=ra()){var e;return Dk(t)&&!!(!((e=window.navigator)===null||e===void 0)&&e.standalone)}function iX(){return n$()&&document.documentMode===10}function G3(t=ra()){return Dk(t)||U3(t)||W3(t)||$3(t)||/windows phone/i.test(t)||B3(t)}/** 2627 * @license 2628 * Copyright 2020 Google LLC 2629 * 2630 * Licensed under the Apache License, Version 2.0 (the "License");
2631 * you may not use this file except in compliance with the License. 2632 * You may obtain a copy of the License at 2633 * 2634 * http://www.apache.org/licenses/LICENSE-2.0 2635 * 2636 * Unless required by applicable law or agreed to in writing, software 2637 * distributed under the License is distributed on an "AS IS" BASIS, 2638 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2639 * See the License for the specific language governing permissions and 2640 * limitations under the License. 2641 */function K3(t,e=[]){let a;switch(t){case"Browser":a=UC(ra());break;case"Worker":a=`${UC(ra())}-${t}`;break;default:a=t}const n=e.length?e.join(","):"FirebaseCore-web";return`${a}/JsCore/${us}/${n}`}/** 2642 * @license 2643 * Copyright 2022 Google LLC 2644 * 2645 * Licensed under the Apache License, Version 2.0 (the "License"); 2646 * you may not use this file except in compliance with the License. 2647 * You may obtain a copy of the License at 2648 * 2649 * http://www.apache.org/licenses/LICENSE-2.0 2650 * 2651 * Unless required by applicable law or agreed to in writing, software 2652 * distributed under the License is distributed on an "AS IS" BASIS, 2653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2654 * See the License for the specific language governing permissions and 2655 * limitations under the License. 2656 */class rX{constructor(e){this.auth=e,this.queue=[]}pushCallback(e,a){const n=r=>new Promise((o,l)=>{try{const c=e(r);o(c)}catch(c){l(c)}});n.onAbort=a,this.queue.push(n);const i=this.queue.length-1;return()=>{this.queue[i]=()=>Promise.resolve()}}async runMiddleware(e){if(this.auth.currentUser===e)return;const a=[];try{for(const n of this.queue)await n(e),n.onAbort&&a.push(n.onAbort)}catch(n){a.reverse();for(const i of a)try{i()}catch{}throw this.auth._errorFactory.create("login-blocked",{originalMessage:n==null?void 0:n.message})}}}/** 2657 * @license 2658 * Copyright 2023 Google LLC 2659 * 2660 * Licensed under the Apache License, Version 2.0 (the "License"); 2661 * you may not use this file except in compliance with the License. 2662 * You may obtain a copy of the License at 2663 * 2664 * http://www.apache.org/licenses/LICENSE-2.0 2665 * 2666 * Unless required by applicable law or agreed to in writing, software 2667 * distributed under the License is distributed on an "AS IS" BASIS, 2668 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2669 * See the License for the specific language governing permissions and 2670 * limitations under the License. 2671 */async function oX(t,e={}){return Yl(t,"GET","/v2/passwordPolicy",Ok(t,e))}/** 2672 * @license 2673 * Copyright 2023 Google LLC 2674 * 2675 * Licensed under the Apache License, Version 2.0 (the "License"); 2676 * you may not use this file except in compliance with the License. 2677 * You may obtain a copy of the License at 2678 * 2679 * http://www.apache.org/licenses/LICENSE-2.0 2680 * 2681 * Unless required by applicable law or agreed to in writing, software 2682 * distributed under the License is distributed on an "AS IS" BASIS, 2683 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2684 * See the License for the specific language governing permissions and 2685 * limitations under the License. 2686 */const sX=6;class lX{constructor(e){var a,n,i,r;const o=e.customStrengthOptions;this.customStrengthOptions={},this.customStrengthOptions.minPasswordLength=(a=o.minPasswordLength)!==null&&a!==void 0?a:sX,o.maxPasswordLength&&(this.customStrengthOptions.maxPasswordLength=o.maxPasswordLength),o.containsLowercaseCharacter!==void 0&&(this.customStrengthOptions.containsLowercaseLetter=o.containsLowercaseCharacter),o.containsUppercaseCharacter!==void 0&&(this.customStrengthOptions.containsUppercaseLetter=o.containsUppercaseCharacter),o.containsNumericCharacter!==void 0&&(this.customStrengthOptions.containsNumericCharacter=o.containsNumericCharacter),o.containsNonAlphanumericCharacter!==void 0&&(this.customStrengthOptions.containsNonAlphanumericCharacter=o.containsNonAlphanumericCharacter),this.enforcementState=e.enforcementState,this.enforcementState==="ENFORCEMENT_STATE_UNSPECIFIED"&&(this.enforcementState="OFF"),this.allowedNonAlphanumericCharacters=(i=(n=e.allowedNonAlphanumericCharacters)===null||n===void 0?void 0:n.join(""))!==null&&i!==void 0?i:"",this.forceUpgradeOnSignin=(r=e.forceUpgradeOnSignin)!==null&&r!==void 0?r:!1,this.schemaVersion=e.schemaVersion}validatePassword(e){var a,n,i,r,o,l;const c={isValid:!0,passwordPolicy:this};return this.validatePasswordLengthOptions(e,c),this.validatePasswordCharacterOptions(e,c),c.isValid&&
2686(c.isValid=(a=c.meetsMinPasswordLength)!==null&&a!==void 0?a:!0),c.isValid&&(c.isValid=(n=c.meetsMaxPasswordLength)!==null&&n!==void 0?n:!0),c.isValid&&(c.isValid=(i=c.containsLowercaseLetter)!==null&&i!==void 0?i:!0),c.isValid&&(c.isValid=(r=c.containsUppercaseLetter)!==null&&r!==void 0?r:!0),c.isValid&&(c.isValid=(o=c.containsNumericCharacter)!==null&&o!==void 0?o:!0),c.isValid&&(c.isValid=(l=c.containsNonAlphanumericCharacter)!==null&&l!==void 0?l:!0),c}validatePasswordLengthOptions(e,a){const n=this.customStrengthOptions.minPasswordLength,i=this.customStrengthOptions.maxPasswordLength;n&&(a.meetsMinPasswordLength=e.length>=n),i&&(a.meetsMaxPasswordLength=e.length<=i)}validatePasswordCharacterOptions(e,a){this.updatePasswordCharacterOptionsStatuses(a,!1,!1,!1,!1);let n;for(let i=0;i<e.length;i++)n=e.charAt(i),this.updatePasswordCharacterOptionsStatuses(a,n>="a"&&n<="z",n>="A"&&n<="Z",n>="0"&&n<="9",this.allowedNonAlphanumericCharacters.includes(n))}updatePasswordCharacterOptionsStatuses(e,a,n,i,r){this.customStrengthOptions.containsLowercaseLetter&&(e.containsLowercaseLetter||(e.containsLowercaseLetter=a)),this.customStrengthOptions.containsUppercaseLetter&&(e.containsUppercaseLetter||(e.containsUppercaseLetter=n)),this.customStrengthOptions.containsNumericCharacter&&(e.containsNumericCharacter||(e.containsNumericCharacter=i)),this.customStrengthOptions.containsNonAlphanumericCharacter&&(e.containsNonAlphanumericCharacter||(e.containsNonAlphanumericCharacter=r))}}/** 2687 * @license 2688 * Copyright 2020 Google LLC 2689 * 2690 * Licensed under the Apache License, Version 2.0 (the "License"); 2691 * you may not use this file except in compliance with the License. 2692 * You may obtain a copy of the License at 2693 * 2694 * http://www.apache.org/licenses/LICENSE-2.0 2695 * 2696 * Unless required by applicable law or agreed to in writing, software 2697 * distributed under the License is distributed on an "AS IS" BASIS, 2698 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2699 * See the License for the specific language governing permissions and 2700 * limitations under the License. 2701 */class cX{constructor(e,a,n,i){this.app=e,this.heartbeatServiceProvider=a,this.appCheckServiceProvider=n,this.config=i,this.currentUser=null,this.emulatorConfig=null,this.operations=Promise.resolve(),this.authStateSubscription=new $C(this),this.idTokenSubscription=new $C(this),this.beforeStateQueue=new rX(this),this.redirectUser=null,this.isProactiveRefreshEnabled=!1,this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION=1,this._canInitEmulator=!0,this._isInitialized=!1,this._deleted=!1,this._initializationPromise=null,this._popupRedirectResolver=null,this._errorFactory=R3,this._agentRecaptchaConfig=null,this._tenantRecaptchaConfigs={},this._projectPasswordPolicy=null,this._tenantPasswordPolicies={},this.lastNotifiedUid=void 0,this.languageCode=null,this.tenantId=null,this.settings={appVerificationDisabledForTesting:!1},this.frameworks=[],this.name=e.name,this.clientVersion=i.sdkClientVersion}_initializeWithPersistence(e,a){return a&&(this._popupRedirectResolver=_i(a)),this._initializationPromise=this.queue(async()=>{var n,i;if(!this._deleted&&(this.persistenceManager=await ll.create(this,e),!this._deleted)){if(!((n=this._popupRedirectResolver)===null||n===void 0)&&n._shouldInitProactively)try{await this._popupRedirectResolver._initialize(this)}catch{}await this.initializeCurrentUser(a),this.lastNotifiedUid=((i=this.currentUser)===null||i===void 0?void 0:i.uid)||null,!this._deleted&&(this._isInitialized=!0)}}),this._initializationPromise}async _onStorageEvent(){if(this._deleted)return;const e=await this.assertedPersistence.getCurrentUser();if(!(!this.currentUser&&!e)){if(this.currentUser&&e&&this.currentUser.uid===e.uid){this._currentUser._assign(e),await this.currentUser.getIdToken();return}await this._updateCurrentUser(e,!0)}}async initializeCurrentUserFromIdToken(e){try{const a=await D3(this,{idToken:e}),n=await Si._fromGetAccountInfoResponse(this,a,e);await this.directlySetCurrentUser(n)}catch(a){console.warn("FirebaseServerApp could not login user with provided authIdToken: ",a),await this.directlySetCurrentUser(null)}}async initializeCurrentUser(e){var a;if(wi(this.app)){const o=this.app.settings.authIdToken;return o?new Promise(l=>{setTimeout(()=>this.initializeCurrentUserFromIdToken(o).then(l,l))}):this.directlySetCurrentUser(null)}const n=await this.assertedPersistence.getCurrentUser();let i=n,r=!1;if(e&&this.config.authDomain){await this.getOrInitRedirectPersistenceManager();const o=(a=this.redirectUser)===null||a===void 0?void 0:a._redirectEventId,l=i==null?void 0:i._redirectEventId,c=await this.tryRedirectSignIn(e);(!o||o===l)&&(c!=null&&c.user)&&(i=c.user,r=!0)}if(!i)return this.directlySetCurrentUser(null);
2701if(!i._redirectEventId){if(r)try{await this.beforeStateQueue.runMiddleware(i)}catch(o){i=n,this._popupRedirectResolver._overrideRedirectResult(this,()=>Promise.reject(o))}return i?this.reloadAndSetCurrentUserOrClear(i):this.directlySetCurrentUser(null)}return ue(this._popupRedirectResolver,this,"argument-error"),await this.getOrInitRedirectPersistenceManager(),this.redirectUser&&this.redirectUser._redirectEventId===i._redirectEventId?this.directlySetCurrentUser(i):this.reloadAndSetCurrentUserOrClear(i)}async tryRedirectSignIn(e){let a=null;try{a=await this._popupRedirectResolver._completeRedirectFn(this,e,!0)}catch{await this._setRedirectUser(null)}return a}async reloadAndSetCurrentUserOrClear(e){try{await Vh(e)}catch(a){if((a==null?void 0:a.code)!=="auth/network-request-failed")return this.directlySetCurrentUser(null)}return this.directlySetCurrentUser(e)}useDeviceLanguage(){this.languageCode=UQ()}async _delete(){this._deleted=!0}async updateCurrentUser(e){if(wi(this.app))return Promise.reject(Mo(this));const a=e?et(e):null;return a&&ue(a.auth.config.apiKey===this.config.apiKey,this,"invalid-user-token"),this._updateCurrentUser(a&&a._clone(this))}async _updateCurrentUser(e,a=!1){if(!this._deleted)return e&&ue(this.tenantId===e.tenantId,this,"tenant-id-mismatch"),a||await this.beforeStateQueue.runMiddleware(e),this.queue(async()=>{await this.directlySetCurrentUser(e),this.notifyAuthListeners()})}async signOut(){return wi(this.app)?Promise.reject(Mo(this)):(await this.beforeStateQueue.runMiddleware(null),(this.redirectPersistenceManager||this._popupRedirectResolver)&&await this._setRedirectUser(null),this._updateCurrentUser(null,!0))}setPersistence(e){return wi(this.app)?Promise.reject(Mo(this)):this.queue(async()=>{await this.assertedPersistence.setPersistence(_i(e))})}_getRecaptchaConfig(){return this.tenantId==null?this._agentRecaptchaConfig:this._tenantRecaptchaConfigs[this.tenantId]}async validatePassword(e){this._getPasswordPolicyInternal()||await this._updatePasswordPolicy();const a=this._getPasswordPolicyInternal();return a.schemaVersion!==this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION?Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version",{})):a.validatePassword(e)}_getPasswordPolicyInternal(){return this.tenantId===null?this._projectPasswordPolicy:this._tenantPasswordPolicies[this.tenantId]}async _updatePasswordPolicy(){const e=await oX(this),a=new lX(e);this.tenantId===null?this._projectPasswordPolicy=a:this._tenantPasswordPolicies[this.tenantId]=a}_getPersistence(){return this.assertedPersistence.persistence.type}_updateErrorMap(e){this._errorFactory=new ds("auth","Firebase",e())}onAuthStateChanged(e,a,n){return this.registerStateListener(this.authStateSubscription,e,a,n)}beforeAuthStateChanged(e,a){return this.beforeStateQueue.pushCallback(e,a)}onIdTokenChanged(e,a,n){return this.registerStateListener(this.idTokenSubscription,e,a,n)}authStateReady(){return new Promise((e,a)=>{if(this.currentUser)e();else{const n=this.onAuthStateChanged(()=>{n(),e()},a)}})}async revokeAccessToken(e){if(this.currentUser){const a=await this.currentUser.getIdToken(),n={providerId:"apple.com",tokenType:"ACCESS_TOKEN",token:e,idToken:a};this.tenantId!=null&&(n.tenantId=this.tenantId),await aX(this,n)}}toJSON(){var e;return{apiKey:this.config.apiKey,authDomain:this.config.authDomain,appName:this.name,currentUser:(e=this._currentUser)===null||e===void 0?void 0:e.toJSON()}}async _setRedirectUser(e,a){const n=await this.getOrInitRedirectPersistenceManager(a);return e===null?n.removeCurrentUser():n.setCurrentUser(e)}async getOrInitRedirectPersistenceManager(e){if(!this.redirectPersistenceManager){const a=e&&_i(e)||this._popupRedirectResolver;ue(a,this,"argument-error"),this.redirectPersistenceManager=await ll.create(this,[_i(a._redirectPersistence)],"redirectUser"),this.redirectUser=await this.redirectPersistenceManager.getCurrentUser()}return this.redirectPersistenceManager}async _redirectUserForId(e){var a,n;return this._isInitialized&&await this.queue(async()=>{}),((a=this._currentUser)===null||a===void 0?void 0:a._redirectEventId)===e?this._currentUser:((n=this.redirectUser)===null||n===void 0?void 0:n._redirectEventId)===e?this.redirectUser:null}async _persistUserIfCurrent(e){if(e===this.currentUser)return this.queue(async()=>this.directlySetCurrentUser(e))}_notifyListenersIfCurrent(e){e===this.currentUser&&this.notifyAuthListeners()}_key(){return`${this.config.authDomain}:${this.config.apiKey}:${this.name}`}_startProactiveRefresh(){this.isProactiveRefreshEnabled=!0,this.currentUser&&this._currentUser._startProactiveRefresh()}_stopProactiveRefresh(){this.isProactiveRefreshEnabled=!1,this.currentUser&&this._currentUser._stopProactiveRefresh()}get _currentUser(){return this.currentUser}notifyAuthListeners(){var e,a;if(!this._isInitialized)return;this.idTokenSubscription.next(this.currentUser);const n=(a=(e=this.currentUser)===null||e===void 0?void 0:e.uid)!==null&&a!==void 0?a:null;this.lastNotifiedUid!==n&&(this.lastNotifiedUid=n,this.authStateSubscription.next(this.currentUser))}registerStateListener(e,a,n,i){if(this._deleted)return()=>{};const r=typeof a=="function"?a:a.next.bind(a);let o=!1;const l=this._isInitialized?Promise.resolve():this._initializationPromise;if(ue(l,this,"internal-error"),l.then(()=>{o||r(this.currentUser)}),typeof a=="function"){const c=e.addObserver(a,n,i);return()=>{o=!0,c()}}else{const c=e.addObserver(a);return()=>{o=!0,c()}}}async directlySetCurrentUser(e){this.currentUser&&this.currentUser!==e&&this._currentUser._stopProactiveRefresh(),e&&this.isProactiveRefreshEnabled&&e._startProactiveRefresh(),this.currentUser=e,e?await this.assertedPersistence.setCurrentUser(e):await this.assertedPersistence.removeCurrentUser()}queue(e){return this.operations=this.operations.then(e,e),this.operations}get assertedPersistence(){return ue(this.persistenceManager,this,"internal-error"),this.persistenceManager}_logFramework(e){!e||this.frameworks.includes(e)||(this.frameworks.push(e),this.frameworks.sort(),this.clientVersion=K3(this.config.clientPlatform,this._getFrameworks()))}_getFrameworks(){return this.frameworks}async _getAdditionalHeaders(){var e;const a={"X-Client-Version":this.clientVersion};this.app.options.appId&&(a["X-Firebase-gmpid"]=this.app.options.appId);const n=await((e=this.heartbeatServiceProvider.getImmediate({optional:!0}))===null||e===void 0?void 0:e.getHeartbeatsHeader());n&&(a["X-Firebase-Client"]=n);const i=await this._getAppCheckToken();return i&&(a["X-Firebase-AppCheck"]=i),a}async _getAppCheckToken(){var e;const a=await((e=this.appCheckServiceProvider.getImmediate({optional:!0}))===null||e===void 0?void 0:e.getToken());return a!=null&&a.error&&VQ(`Error while retrieving App Check token: ${a.error}`),a==null?void 0:a.token}}function jg(t){return et(t)}class $C{constructor(e){this.auth=e,this.observer=null,this.addObserver=c$(a=>this.observer=a)}get next(){return ue(this.observer,this.auth,"internal-error"),this.observer.next.bind(this.observer)}}/** 2702 * @license 2703 * Copyright 2020 Google LLC 2704 * 2705 * Licensed under the Apache License, Version 2.0 (the "License");
2706 * you may not use this file except in compliance with the License. 2707 * You may obtain a copy of the License at 2708 * 2709 * http://www.apache.org/licenses/LICENSE-2.0 2710 * 2711 * Unless required by applicable law or agreed to in writing, software 2712 * distributed under the License is distributed on an "AS IS" BASIS, 2713 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2714 * See the License for the specific language governing permissions and 2715 * limitations under the License. 2716 */let qk={async loadJS(){throw new Error("Unable to load external scripts")},recaptchaV2Script:"",recaptchaEnterpriseScript:"",gapiScript:""};function dX(t){qk=t}function uX(t){return qk.loadJS(t)}function pX(){return qk.gapiScript}function mX(t){return`__${t}${Math.floor(Math.random()*1e6)}`}/** 2717 * @license 2718 * Copyright 2020 Google LLC 2719 * 2720 * Licensed under the Apache License, Version 2.0 (the "License"); 2721 * you may not use this file except in compliance with the License. 2722 * You may obtain a copy of the License at 2723 * 2724 * http://www.apache.org/licenses/LICENSE-2.0 2725 * 2726 * Unless required by applicable law or agreed to in writing, software 2727 * distributed under the License is distributed on an "AS IS" BASIS, 2728 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2729 * See the License for the specific language governing permissions and 2730 * limitations under the License. 2731 */function hX(t,e){const a=Qr(t,"auth");if(a.isInitialized()){const i=a.getImmediate(),r=a.getOptions();if(eu(r,e??{}))return i;ii(i,"already-initialized")}return a.initialize({options:e})}function fX(t,e){const a=(e==null?void 0:e.persistence)||[],n=(Array.isArray(a)?a:[a]).map(_i);e!=null&&e.errorMap&&t._updateErrorMap(e.errorMap),t._initializeWithPersistence(n,e==null?void 0:e.popupRedirectResolver)}function gX(t,e,a){const n=jg(t);ue(n._canInitEmulator,n,"emulator-config-failed"),ue(/^https?:\/\//.test(e),n,"invalid-emulator-scheme");const i=!1,r=J3(e),{host:o,port:l}=yX(e),c=l===null?"":`:${l}`;n.config.emulator={url:`${r}//${o}${c}/`},n.settings.appVerificationDisabledForTesting=!0,n.emulatorConfig=Object.freeze({host:o,port:l,protocol:r.replace(":",""),options:Object.freeze({disableWarnings:i})}),xX()}function J3(t){const e=t.indexOf(":");return e<0?"":t.substr(0,e+1)}function yX(t){const e=J3(t),a=/(\/\/)?([^?#/]+)/.exec(t.substr(e.length));if(!a)return{host:"",port:null};const n=a[2].split("@").pop()||"",i=/^(\[[^\]]+\])(:|$)/.exec(n);if(i){const r=i[1];return{host:r,port:WC(n.substr(r.length+1))}}else{const[r,o]=n.split(":");return{host:r,port:WC(o)}}}function WC(t){if(!t)return null;const e=Number(t);return isNaN(e)?null:e}function xX(){function t(){const e=document.createElement("p"),a=e.style;e.innerText="Running in emulator mode. Do not use with production credentials.",a.position="fixed",a.width="100%",a.backgroundColor="#ffffff",a.border=".1em solid #000000",a.color="#b50000",a.bottom="0px",a.left="0px",a.margin="0px",a.zIndex="10000",a.textAlign="center",e.classList.add("firebase-emulator-warning"),document.body.appendChild(e)}typeof console<"u"&&typeof console.info=="function"&&console.info("WARNING: You are using the Auth Emulator, which is intended for local testing only. Do not use with production credentials."),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?window.addEventListener("DOMContentLoaded",t):t())}/** 2732 * @license 2733 * Copyright 2020 Google LLC 2734 * 2735 * Licensed under the Apache License, Version 2.0 (the "License"); 2736 * you may not use this file except in compliance with the License. 2737 * You may obtain a copy of the License at 2738 * 2739 * http://www.apache.org/licenses/LICENSE-2.0 2740 * 2741 * Unless required by applicable law or agreed to in writing, software 2742 * distributed under the License is distributed on an "AS IS" BASIS, 2743 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2744 * See the License for the specific language governing permissions and 2745 * limitations under the License. 2746 */class Q3{constructor(e,a){this.providerId=e,this.signInMethod=a}toJSON(){return ki("not implemented")}_getIdTokenResponse(e){return ki("not implemented")}_linkToIdToken(e,a){return ki("not implemented")}_getReauthenticationResolver(e){return ki("not implemented")}}/** 2747 * @license 2748 * Copyright 2020 Google LLC 2749 * 2750 * Licensed under the Apache License, Version 2.0 (the "License");
2751 * you may not use this file except in compliance with the License. 2752 * You may obtain a copy of the License at 2753 * 2754 * http://www.apache.org/licenses/LICENSE-2.0 2755 * 2756 * Unless required by applicable law or agreed to in writing, software 2757 * distributed under the License is distributed on an "AS IS" BASIS, 2758 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2759 * See the License for the specific language governing permissions and 2760 * limitations under the License. 2761 */async function cl(t,e){return GQ(t,"POST","/v1/accounts:signInWithIdp",Ok(t,e))}/** 2762 * @license 2763 * Copyright 2020 Google LLC 2764 * 2765 * Licensed under the Apache License, Version 2.0 (the "License"); 2766 * you may not use this file except in compliance with the License. 2767 * You may obtain a copy of the License at 2768 * 2769 * http://www.apache.org/licenses/LICENSE-2.0 2770 * 2771 * Unless required by applicable law or agreed to in writing, software 2772 * distributed under the License is distributed on an "AS IS" BASIS, 2773 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2774 * See the License for the specific language governing permissions and 2775 * limitations under the License. 2776 */const vX="http://localhost";class Zo extends Q3{constructor(){super(...arguments),this.pendingToken=null}static _fromParams(e){const a=new Zo(e.providerId,e.signInMethod);return e.idToken||e.accessToken?(e.idToken&&(a.idToken=e.idToken),e.accessToken&&(a.accessToken=e.accessToken),e.nonce&&!e.pendingToken&&(a.nonce=e.nonce),e.pendingToken&&(a.pendingToken=e.pendingToken)):e.oauthToken&&e.oauthTokenSecret?(a.accessToken=e.oauthToken,a.secret=e.oauthTokenSecret):ii("argument-error"),a}toJSON(){return{idToken:this.idToken,accessToken:this.accessToken,secret:this.secret,n
2776once:this.nonce,pendingToken:this.pendingToken,providerId:this.providerId,signInMethod:this.signInMethod}}static fromJSON(e){const a=typeof e=="string"?JSON.parse(e):e,{providerId:n,signInMethod:i}=a,r=Ik(a,["providerId","signInMethod"]);if(!n||!i)return null;const o=new Zo(n,i);return o.idToken=r.idToken||void 0,o.accessToken=r.accessToken||void 0,o.secret=r.secret,o.nonce=r.nonce,o.pendingToken=r.pendingToken||null,o}_getIdTokenResponse(e){const a=this.buildRequest();return cl(e,a)}_linkToIdToken(e,a){const n=this.buildRequest();return n.idToken=a,cl(e,n)}_getReauthenticationResolver(e){const a=this.buildRequest();return a.autoCreate=!1,cl(e,a)}buildRequest(){const e={requestUri:vX,returnSecureToken:!0};if(this.pendingToken)e.pendingToken=this.pendingToken;else{const a={};this.idToken&&(a.id_token=this.idToken),this.accessToken&&(a.access_token=this.accessToken),this.secret&&(a.oauth_token_secret=this.secret),a.providerId=this.providerId,this.nonce&&!this.pendingToken&&(a.nonce=this.nonce),e.postBody=Ru(a)}return e}}/** 2777 * @license 2778 * Copyright 2020 Google LLC 2779 * 2780 * Licensed under the Apache License, Version 2.0 (the "License"); 2781 * you may not use this file except in compliance with the License. 2782 * You may obtain a copy of the License at 2783 * 2784 * http://www.apache.org/licenses/LICENSE-2.0 2785 * 2786 * Unless required by applicable law or agreed to in writing, software 2787 * distributed under the License is distributed on an "AS IS" BASIS, 2788 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2789 * See the License for the specific language governing permissions and 2790 * limitations under the License. 2791 */class zk{constructor(e){this.providerId=e,this.defaultLanguageCode=null,this.customParameters={}}setDefaultLanguage(e){this.defaultLanguageCode=e}setCustomParameters(e){return this.customParameters=e,this}getCustomParameters(){return this.customParameters}}/** 2792 * @license 2793 * Copyright 2019 Google LLC 2794 * 2795 * Licensed under the Apache License, Version 2.0 (the "License"); 2796 * you may not use this file except in compliance with the License. 2797 * You may obtain a copy of the License at 2798 * 2799 * http://www.apache.org/licenses/LICENSE-2.0 2800 * 2801 * Unless required by applicable law or agreed to in writing, software 2802 * distributed under the License is distributed on an "AS IS" BASIS, 2803 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2804 * See the License for the specific language governing permissions and 2805 * limitations under the License. 2806 */class Bu extends zk{constructor(){super(...arguments),this.scopes=[]}addScope(e){return this.scopes.includes(e)||this.scopes.push(e),this}getScopes(){return[...this.scopes]}}/** 2807 * @license 2808 * Copyright 2020 Google LLC 2809 * 2810 * Licensed under the Apache License, Version 2.0 (the "License"); 2811 * you may not use this file except in compliance with the License. 2812 * You may obtain a copy of the License at 2813 * 2814 * http://www.apache.org/licenses/LICENSE-2.0 2815 * 2816 * Unless required by applicable law or agreed to in writing, software 2817 * distributed under the License is distributed on an "AS IS" BASIS, 2818 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2819 * See the License for the specific language governing permissions and 2820 * limitations under the License. 2821 */class cr extends Bu{constructor(){super("facebook.com")}static credential(e){return Zo._fromParams({providerId:cr.PROVIDER_ID,signInMethod:cr.FACEBOOK_SIGN_IN_METHOD,accessToken:e})}static credentialFromResult(e){return cr.credentialFromTaggedObject(e)}static credentialFromError(e){return cr.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e||!("oauthAccessToken"in e)||!e.oauthAccessToken)return null;try{return cr.credential(e.oauthAccessToken)}catch{return null}}}cr.FACEBOOK_SIGN_IN_METHOD="facebook.com";cr.PROVIDER_ID="facebook.com";/** 2822 * @license 2823 * Copyright 2020 Google LLC 2824 * 2825 * Licensed under the Apache License, Version 2.0 (the "License"); 2826 * you may not use this file except in compliance with the License. 2827 * You may obtain a copy of the License at 2828 * 2829 * http://www.apache.org/licenses/LICENSE-2.0 2830 * 2831 * Unless required by applicable law or agreed to in writing, softw
2831are 2832 * distributed under the License is distributed on an "AS IS" BASIS, 2833 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2834 * See the License for the specific language governing permissions and 2835 * limitations under the License. 2836 */class Kn extends Bu{constructor(){super("google.com"),this.addScope("profile")}static credential(e,a){return Zo._fromParams({providerId:Kn.PROVIDER_ID,signInMethod:Kn.GOOGLE_SIGN_IN_METHOD,idToken:e,accessToken:a})}static credentialFromResult(e){return Kn.credentialFromTaggedObject(e)}static credentialFromError(e){return Kn.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;const{oauthIdToken:a,oauthAccessToken:n}=e;if(!a&&!n)return null;try{return Kn.credential(a,n)}catch{return null}}}Kn.GOOGLE_SIGN_IN_METHOD="google.com";Kn.PROVIDER_ID="google.com";/** 2837 * @license 2838 * Copyright 2020 Google LLC 2839 * 2840 * Licensed under the Apache License, Version 2.0 (the "License"); 2841 * you may not use this file except in compliance with the License. 2842 * You may obtain a copy of the License at 2843 * 2844 * http://www.apache.org/licenses/LICENSE-2.0 2845 * 2846 * Unless required by applicable law or agreed to in writing, software 2847 * distributed under the License is distributed on an "AS IS" BASIS, 2848 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2849 * See the License for the specific language governing permissions and 2850 * limitations under the License. 2851 */class dr extends Bu{constructor(){super("github.com")}static credential(e){return Zo._fromParams({providerId:dr.PROVIDER_ID,signInMethod:dr.GITHUB_SIGN_IN_METHOD,accessToken:e})}static credentialFromResult(e){return dr.credentialFromTaggedObject(e)}static credentialFromError(e){return dr.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e||!("oauthAccessToken"in e)||!e.oauthAccessToken)return null;try{return dr.credential(e.oauthAccessToken)}catch{return null}}}dr.GITHUB_SIGN_IN_METHOD="github.com";dr.PROVIDER_ID="github.com";/** 2852 * @license 2853 * Copyright 2020 Google LLC 2854 * 2855 * Licensed under the Apache License, Version 2.0 (the "License"); 2856 * you may not use this file except in compliance with the License. 2857 * You may obtain a copy of the License at 2858 * 2859 * http://www.apache.org/licenses/LICENSE-2.0 2860 * 2861 * Unless required by applicable law or agreed to in writing, software 2862 * distributed under the License is distributed on an "AS IS" BASIS, 2863 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2864 * See the License for the specific language governing permissions and 2865 * limitations under the License. 2866 */class ur extends Bu{constructor(){super("twitter.com")}static credential(e,a){return Zo._fromParams({providerId:ur.PROVIDER_ID,signInMethod:ur.TWITTER_SIGN_IN_METHOD,oauthToken:e,oauthTokenSecret:a})}static credentialFromResult(e){return ur.credentialFromTaggedObject(e)}static credentialFromError(e){return ur.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;const{oauthAccessToken:a,oauthTokenSecret:n}=e;if(!a||!n)return null;try{return ur.credential(a,n)}catch{return null}}}ur.TWITTER_SIGN_IN_METHOD="twitter.com";ur.PROVIDER_ID="twitter.com";/** 2867 * @license 2868 * Copyright 2020 Google LLC 2869 * 2870 * Licensed under the Apache License, Version 2.0 (the "License"); 2871 * you may not use this file except in compliance with the License. 2872 * You may obtain a copy of the License at 2873 * 2874 * http://www.apache.org/licenses/LICENSE-2.0 2875 * 2876 * Unless required by applicable law or agreed to in writing, software 2877 * distributed under the License is distributed on an "AS IS" BASIS, 2878 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2879 * See the License for the specific language governing permissions and 2880 * limitations under the License. 2881 */class Nl{constructor(e){this.user=e.user,this.providerId=e.providerId,this._tokenResponse=e._tokenResponse,this.operationType=e.operationType}static async _fromIdTokenResponse(e,a,n,i=!1){const r=await Si._fromIdTokenResponse(e,n,i),o=GC(n);return new Nl({user:r,providerId:o,_tokenResponse:n,operationType:a})}static async _forOperation(e,a,n){await e._updateTokensIfNecessary(n,!0);const i=GC(n);return new Nl({user:e,providerId:i,_tokenResponse:n,operationType:a})}}function GC(t){return t.providerId?t.providerId:"phoneNumber"in t?"phone":null}/** 2882 * @license 2883 * Copyright 2020 Google LLC 2884 * 2885 * Licensed under the Apache License, Version 2.0 (the "License");
2886 * you may not use this file except in compliance with the License. 2887 * You may obtain a copy of the License at 2888 * 2889 * http://www.apache.org/licenses/LICENSE-2.0 2890 * 2891 * Unless required by applicable law or agreed to in writing, software 2892 * distributed under the License is distributed on an "AS IS" BASIS, 2893 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2894 * See the License for the specific language governing permissions and 2895 * limitations under the License. 2896 */class Hh extends gn{constructor(e,a,n,i){var r;super(a.code,a.message),this.operationType=n,this.user=i,Object.setPrototypeOf(this,Hh.prototype),this.customData={appName:e.name,tenantId:(r=e.tenantId)!==null&&r!==void 0?r:void 0,_serverResponse:a.customData._serverResponse,operationType:n}}static _fromErrorAndOperation(e,a,n,i){return new Hh(e,a,n,i)}}function X3(t,e,a,n){return(e==="reauthenticate"?a._getReauthenticationResolver(t):a._getIdTokenResponse(t)).catch(r=>{throw r.code==="auth/multi-factor-auth-required"?Hh._fromErrorAndOperation(t,r,e,n):r})}async function bX(t,e,a=!1){const n=await cu(t,e._linkToIdToken(t.auth,await t.getIdToken()),a);return Nl._forOperation(t,"link",n)}/** 2897 * @license 2898 * Copyright 2019 Google LLC 2899 * 2900 * Licensed under the Apache License, Version 2.0 (the "License"); 2901 * you may not use this file except in compliance with the License. 2902 * You may obtain a copy of the License at 2903 * 2904 * http://www.apache.org/licenses/LICENSE-2.0 2905 * 2906 * Unless required by applicable law or agreed to in writing, software 2907 * distributed under the License is distributed on an "AS IS" BASIS, 2908 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2909 * See the License for the specific language governing permissions and 2910 * limitations under the License. 2911 */async function wX(t,e,a=!1){const{auth:n}=t;if(wi(n.app))return Promise.reject(Mo(n));const i="reauthenticate";try{const r=await cu(t,X3(n,i,e,t),a);ue(r.idToken,n,"internal-error");const o=Mk(r.idToken);ue(o,n,"internal-error");const{sub:l}=o;return ue(t.uid===l,n,"user-mismatch"),Nl._forOperation(t,i,r)}catch(r){throw(r==null?void 0:r.code)==="auth/user-not-found"&&ii(n,"user-mismatch"),r}}/** 2912 * @license 2913 * Copyright 2020 Google LLC 2914 * 2915 * Licensed under the Apache License, Version 2.0 (the "License"); 2916 * you may not use this file except in compliance with the License. 2917 * You may obtain a copy of the License at 2918 * 2919 * http://www.apache.org/licenses/LICENSE-2.0 2920 * 2921 * Unless required by applicable law or agreed to in writing, software 2922 * distributed under the License is distributed on an "AS IS" BASIS, 2923 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2924 * See the License for the specific language governing permissions and 2925 * limitations under the License. 2926 */async function kX(t,e,a=!1){if(wi(t.app))return Promise.reject(Mo(t));const n="signIn",i=await X3(t,n,e),r=await Nl._fromIdTokenResponse(t,n,i);return a||await t._updateCurrentUser(r.user),r}function SX(t,e,a,n){return et(t).onIdTokenChanged(e,a,n)}function _X(t,e,a){return et(t).beforeAuthStateChanged(e,a)}function Y3(t,e,a,n){return et(t).onAuthStateChanged(e,a,n)}function yd(t){return et(t).signOut()}const Fh="__sak";/** 2927 * @license 2928 * Copyright 2019 Google LLC 2929 * 2930 * Licensed under the Apache License, Version 2.0 (the "License"); 2931 * you may not use this file except in compliance with the License. 2932 * You may obtain a copy of the License at 2933 * 2934 * http://www.apache.org/licenses/LICENSE-2.0 2935 * 2936 * Unless required by applicable law or agreed to in writing, software 2937 * distributed under the License is distributed on an "AS IS" BASIS, 2938 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2939 * See the License for the specific language governing permissions and 2940 * limitations under the License. 2941 */class Z3{constructor(e,a){this.storageRetriever=e,this.type=a}_isAvailable(){try{return this.storage?(this.storage.setItem(Fh,"1"),this.storage.removeItem(Fh),Promise.resolve(!0)):Promise.resolve(!1)}catch{return Promise.resolve(!1)}}_set(e,a){return this.storage.setItem(e,JSON.stringify(a)),Promise.resolve()}_get(e){const a=this.storage.getItem(e);return Promise.resolve(a?JSON.parse(a):null)}_remove(e){return this.storage.removeItem(e),Promise.resolve()}get storage(){return this.storageRetriever()}}/** 2942 * @license 2943 * Copyright 2020 Google LLC 2944 * 2945 * Licensed under the Apache License, Version 2.0 (the "License");
2946 * you may not use this file except in compliance with the License. 2947 * You may obtain a copy of the License at 2948 * 2949 * http://www.apache.org/licenses/LICENSE-2.0 2950 * 2951 * Unless required by applicable law or agreed to in writing, software 2952 * distributed under the License is distributed on an "AS IS" BASIS, 2953 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2954 * See the License for the specific language governing permissions and 2955 * limitations under the License. 2956 */const AX=1e3,EX=10;class eO extends Z3{constructor(){super(()=>window.localStorage,"LOCAL"),this.boundEventHandler=(e,a)=>this.onStorageEvent(e,a),this.listeners={},this.localCache={},this.pollTimer=null,this.fallbackToPolling=G3(),this._shouldAllowMigration=!0}forAllChangedKeys(e){for(const a of Object.keys(this.listeners)){const n=this.storage.getItem(a),i=this.localCache[a];n!==i&&e(a,i,n)}}onStorageEvent(e,a=!1){if(!e.key){this.forAllChangedKeys((o,l,c)=>{this.notifyListeners(o,c)});return}const n=e.key;a?this.detachListener():this.stopPolling();const i=()=>{const o=this.storage.getItem(n);!a&&this.localCache[n]===o||this.notifyListeners(n,o)},r=this.storage.getItem(n);iX()&&r!==e.newValue&&e.newValue!==e.oldValue?setTimeout(i,EX):i()}notifyListeners(e,a){this.localCache[e]=a;const n=this.listeners[e];if(n)for(const i of Array.from(n))i(a&&JSON.parse(a))}startPolling(){this.stopPolling(),this.pollTimer=setInterval(()=>{this.forAllChangedKeys((e,a,n)=>{this.onStorageEvent(new StorageEvent("storage",{key:e,oldValue:a,newValue:n}),!0)})},AX)}stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}attachListener(){window.addEventListener("storage",this.boundEventHandler)}detachListener(){window.removeEventListener("storage",this.boundEventHandler)}_addListener(e,a){Object.keys(this.listeners).length===0&&(this.fallbackToPolling?this.startPolling():this.attachListener()),this.listeners[e]||(this.listeners[e]=new Set,this.localCache[e]=this.storage.getItem(e)),this.listeners[e].add(a)}_removeListener(e,a){this.listeners[e]&&(this.listeners[e].delete(a),this.listeners[e].size===0&&delete this.listeners[e]),Ob
2956ject.keys(this.listeners).length===0&&(this.detachListener(),this.stopPolling())}async _set(e,a){await super._set(e,a),this.localCache[e]=JSON.stringify(a)}async _get(e){const a=await super._get(e);return this.localCache[e]=JSON.stringify(a),a}async _remove(e){await super._remove(e),delete this.localCache[e]}}eO.type="LOCAL";const CX=eO;/** 2957 * @license 2958 * Copyright 2020 Google LLC 2959 * 2960 * Licensed under the Apache License, Version 2.0 (the "License"); 2961 * you may not use this file except in compliance with the License. 2962 * You may obtain a copy of the License at 2963 * 2964 * http://www.apache.org/licenses/LICENSE-2.0 2965 * 2966 * Unless required by applicable law or agreed to in writing, software 2967 * distributed under the License is distributed on an "AS IS" BASIS, 2968 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2969 * See the License for the specific language governing permissions and 2970 * limitations under the License. 2971 */class tO extends Z3{constructor(){super(()=>window.sessionStorage,"SESSION")}_addListener(e,a){}_removeListener(e,a){}}tO.type="SESSION";const aO=tO;/** 2972 * @license 2973 * Copyright 2019 Google LLC 2974 * 2975 * Licensed under the Apache License, Version 2.0 (the "License"); 2976 * you may not use this file except in compliance with the License. 2977 * You may obtain a copy of the License at 2978 * 2979 * http://www.apache.org/licenses/LICENSE-2.0 2980 * 2981 * Unless required by applicable law or agreed to in writing, software 2982 * distributed under the License is distributed on an "AS IS" BASIS, 2983 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2984 * See the License for the specific language governing permissions and 2985 * limitations under the License. 2986 */function jX(t){return Promise.all(t.map(async e=>{try{return{fulfilled:!0,value:await e}}catch(a){return{fulfilled:!1,reason:a}}}))}/** 2987 * @license 2988 * Copyright 2019 Google LLC 2989 * 2990 * Licensed under the Apache License, Version 2.0 (the "License"); 2991 * you may not use this file except in compliance with the License. 2992 * You may obtain a copy of the License at 2993 * 2994 * http://www.apache.org/licenses/LICENSE-2.0 2995 * 2996 * Unless required by applicable law or agreed to in writing, software 2997 * distributed under the License is distributed on an "AS IS" BASIS, 2998 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2999 * See the License for the specific language governing permissions and 3000 * limitations under the License. 3001 */class Tg{constructor(e){this.eventTarget=e,this.handlersMap={},this.boundEventHandler=this.handleEvent.bind(this)}static _getInstance(e){const a=this.receivers.find(i=>i.isListeningto(e));if(a)return a;const n=new Tg(e);return this.receivers.push(n),n}isListeningto(e){return this.eventTarget===e}async handleEvent(e){const a=e,{eventId:n,eventType:i,data:r}=a.data,o=this.handlersMap[i];if(!(o!=null&&o.size))return;a.ports[0].postMessage({status:"ack",eventId:n,eventType:i});const l=Array.from(o).map(async d=>d(a.origin,r)),c=await jX(l);a.ports[0].postMessage({status:"done",eventId:n,eventType:i,response:c})}_subscribe(e,a){Object.keys(this.handlersMap).length===0&&this.eventTarget.addEventListener("message",this.boundEventHandler),this.handlersMap[e]||(this.handlersMap[e]=new Set),this.handlersMap[e].add(a)}_unsubscribe(e,a){this.handlersMap[e]&&a&&this.handlersMap[e].delete(a),(!a||this.handlersMap[e].size===0)&&delete this.handlersMap[e],Object.keys(this.handlersMap).length===0&&this.eventTarget.removeEventListener("message",this.boundEventHandler)}}Tg.receivers=[];/** 3002 * @license 3003 * Copyright 2020 Google LLC 3004 * 3005 * Licensed under the Apache License, Version 2.0 (the "License"); 3006 * you may not use this file except in compliance with the License. 3007 * You may obtain a copy of the License at 3008 * 3009 * http://www.apache.org/licenses/LICENSE-2.0 3010 * 3011 * Unless required by applicable law or agreed to in writing, software 3012 * distributed under the License is distributed on an "AS IS" BASIS, 3013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3014 * See the License for the specific language governing permissions and 3015 * limitations under the License. 3016 */function Vk(t="",e=10){let a="";for(let n=0;n<e;n++)a+=Math.floor(Math.random()*10);return t+a}/** 3017 * @license 3018 * Copyright 2019 Google LLC 3019 * 3020 * Licensed under the Apache License, Version 2.0 (the "License");
3021 * you may not use this file except in compliance with the License. 3022 * You may obtain a copy of the License at 3023 * 3024 * http://www.apache.org/licenses/LICENSE-2.0 3025 * 3026 * Unless required by applicable law or agreed to in writing, software 3027 * distributed under the License is distributed on an "AS IS" BASIS, 3028 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3029 * See the License for the specific language governing permissions and 3030 * limitations under the License. 3031 */class TX{constructor(e){this.target=e,this.handlers=new Set}removeMessageHandler(e){e.messageChannel&&(e.messageChannel.port1.removeEventListener("message",e.onMessage),e.messageChannel.port1.close()),this.handlers.delete(e)}async _send(e,a,n=50){const i=typeof MessageChannel<"u"?new MessageChannel:null;if(!i)throw new Error("connection_unavailable");let r,o;return new Promise((l,c)=>{const d=Vk("",20);i.port1.start();const u=setTimeout(()=>{c(new Error("unsupported_event"))},n);o={messageChannel:i,onMessage(p){const m=p;if(m.data.eventId===d)switch(m.data.status){case"ack":clearTimeout(u),r=setTimeout(()=>{c(new Error("timeout"))},3e3);break;case"done":clearTimeout(r),l(m.data.response);break;default:clearTimeout(u),clearTimeout(r),c(new Error("invalid_response"));break}}},this.handlers.add(o),i.port1.addEventListener("message",o.onMessage),this.target.postMessage({eventType:e,eventId:d,data:a},[i.port2])}).finally(()=>{o&&this.removeMessageHandler(o)})}}/** 3032 * @license 3033 * Copyright 2020 Google LLC 3034 * 3035 * Licensed under the Apache License, Version 2.0 (the "License"); 3036 * you may not use this file except in compliance with the License. 3037 * You may obtain a copy of the License at 3038 * 3039 * http://www.apache.org/licenses/LICENSE-2.0 3040 * 3041 * Unless required by applicable law or agreed to in writing, software 3042 * distributed under the License is distributed on an "AS IS" BASIS, 3043 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3044 * See the License for the specific language governing permissions and 3045 * limitations under the License. 3046 */function ai(){return window}function NX(t){ai().location.href=t}/** 3047 * @license 3048 * Copyright 2020 Google LLC. 3049 * 3050 * Licensed under the Apache License, Version 2.0 (the "License"); 3051 * you may not use this file except in compliance with the License. 3052 * You may obtain a copy of the License at 3053 * 3054 * http://www.apache.org/licenses/LICENSE-2.0 3055 * 3056 * Unless required by applicable law or agreed to in writing, software 3057 * distributed under the License is distributed on an "AS IS" BASIS, 3058 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3059 * See the License for the specific language governing permissions and 3060 * limitations under the License. 3061 */function nO(){return typeof ai().WorkerGlobalScope<"u"&&typeof ai().importScripts=="function"}async function IX(){if(!(navigator!=null&&navigator.serviceWorker))return null;try{return(await navigator.serviceWorker.ready).active}catch{return null}}function PX(){var t;return((t=navigator==null?void 0:navigator.serviceWorker)===null||t===void 0?void 0:t.controller)||null}function RX(){return nO()?self:null}/** 3062 * @license 3063 * Copyright 2019 Google LLC 3064 * 3065 * Licensed under the Apache License, Version 2.0 (the "License"); 3066 * you may not use this file except in compliance with the License. 3067 * You may obtain a copy of the License at 3068 * 3069 * http://www.apache.org/licenses/LICENSE-2.0 3070 * 3071 * Unless required by applicable law or agreed to in writing, software 3072 * distributed under the License is distributed on an "AS IS" BASIS, 3073 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3074 * See the License for the specific language governing permissions and 3075 * limitations under the License. 3076 */const iO="firebaseLocalStorageDb",LX=1,Bh="firebaseLocalStorage",rO="fbase_key";class Uu{constructor(e){this.request=e}toPromise(){return new Promise((e,a)=>{this.request.addEventListener("success",()=>{e(this.request.result)}),this.request.addEventListener("error",()=>{a(this.request.error)})})}}function Ng(t,e){return t.transaction([Bh],e?"readwrite":"readonly").objectStore(Bh)}function OX(){const t=indexedDB.deleteDatabase(iO);
3076return new Uu(t).toPromise()}function yb(){const t=indexedDB.open(iO,LX);return new Promise((e,a)=>{t.addEventListener("error",()=>{a(t.error)}),t.addEventListener("upgradeneeded",()=>{const n=t.result;try{n.createObjectStore(Bh,{keyPath:rO})}catch(i){a(i)}}),t.addEventListener("success",async()=>{const n=t.result;n.objectStoreNames.contains(Bh)?e(n):(n.close(),await OX(),e(await yb()))})})}async function KC(t,e,a){const n=Ng(t,!0).put({[rO]:e,value:a});return new Uu(n).toPromise()}async function MX(t,e){const a=Ng(t,!1).get(e),n=await new Uu(a).toPromise();return n===void 0?null:n.value}function JC(t,e){const a=Ng(t,!0).delete(e);return new Uu(a).toPromise()}const DX=800,qX=3;class oO{constructor(){this.type="LOCAL",this._shouldAllowMigration=!0,this.listeners={},this.localCache={},this.pollTimer=null,this.pendingWrites=0,this.receiver=null,this.sender=null,this.serviceWorkerReceiverAvailable=!1,this.activeServiceWorker=null,this._workerInitializationPromise=this.initializeServiceWorkerMessaging().then(()=>{},()=>{})}async _openDb(){return this.db?this.db:(this.db=await yb(),this.db)}async _withRetries(e){let a=0;for(;;)try{const n=await this._openDb();return await e(n)}catch(n){if(a++>qX)throw n;this.db&&(this.db.close(),this.db=void 0)}}async initializeServiceWorkerMessaging(){return nO()?this.initializeReceiver():this.initializeSender()}async initializeReceiver(){this.receiver=Tg._getInstance(RX()),this.receiver._subscribe("keyChanged",async(e,a)=>({keyProcessed:(await this._poll()).includes(a.key)})),this.receiver._subscribe("ping",async(e,a)=>["keyChanged"])}async initializeSender(){var e,a;if(this.activeServiceWorker=await IX(),!this.activeServiceWorker)return;this.sender=new TX(this.activeServiceWorker);const n=await this.sender._send("ping",{},800);n&&!((e=n[0])===null||e===void 0)&&e.fulfilled&&!((a=n[0])===null||a===void 0)&&a.value.includes("keyChanged")&&(this.serviceWorkerReceiverAvailable=!0)}async notifyServiceWorker(e){if(!(!this.sender||!this.activeServiceWorker||PX()!==this.activeServiceWorker))try{await this.sender._send("keyChanged",{key:e},this.serviceWorkerReceiverAvailable?800:50)}catch{}}async _isAvailable(){try{if(!indexedDB)return!1;const e=await yb();return await KC(e,Fh,"1"),await JC(e,Fh),!0}catch{}return!1}async _withPendingWrite(e){this.pendingWrites++;try{await e()}finally{this.pendingWrites--}}async _set(e,a){return this._withPendingWrite(async()=>(await this._withRetries(n=>KC(n,e,a)),this.localCache[e]=a,this.notifyServiceWorker(e)))}async _get(e){const a=await this._withRetries(n=>MX(n,e));return this.localCache[e]=a,a}async _remove(e){return this._withPendingWrite(async()=>(await this._withRetries(a=>JC(a,e)),delete this.localCache[e],this.notifyServiceWorker(e)))}async _poll(){const e=await this._withRetries(i=>{const r=Ng(i,!1).getAll();return new Uu(r).toPromise()});if(!e)return[];if(this.pendingWrites!==0)return[];const a=[],n=new Set;if(e.length!==0)for(const{fbase_key:i,value:r}of e)n.add(i),JSON.stringify(this.localCache[i])!==JSON.stringify(r)&&(this.notifyListeners(i,r),a.push(i));for(const i of Object.keys(this.localCache))this.localCache[i]&&!n.has(i)&&(this.notifyListeners(i,null),a.push(i));return a}notifyListeners(e,a){this.localCache[e]=a;const n=this.listeners[e];if(n)for(const i of Array.from(n))i(a)}startPolling(){this.stopPolling(),this.pollTimer=setInterval(async()=>this._poll(),DX)}stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}_addListener(e,a){Object.keys(this.listeners).length===0&&this.startPolling(),this.listeners[e]||(this.listeners[e]=new Set,this._get(e)),this.listeners[e].add(a)}_removeListener(e,a){this.listeners[e]&&(this.listeners[e].delete(a),this.listeners[e].size===0&&delete this.listeners[e]),Ob
vendor: 4,318 bytes, lines 3076-3125
3076ject.keys(this.listeners).length===0&&this.stopPolling()}}oO.type="LOCAL";const zX=oO;new Fu(3e4,6e4);/** 3077 * @license 3078 * Copyright 2021 Google LLC 3079 * 3080 * Licensed under the Apache License, Version 2.0 (the "License"); 3081 * you may not use this file except in compliance with the License. 3082 * You may obtain a copy of the License at 3083 * 3084 * http://www.apache.org/licenses/LICENSE-2.0 3085 * 3086 * Unless required by applicable law or agreed to in writing, software 3087 * distributed under the License is distributed on an "AS IS" BASIS, 3088 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3089 * See the License for the specific language governing permissions and 3090 * limitations under the License. 3091 */function sO(t,e){return e?_i(e):(ue(t._popupRedirectResolver,t,"argument-error"),t._popupRedirectResolver)}/** 3092 * @license 3093 * Copyright 2019 Google LLC 3094 * 3095 * Licensed under the Apache License, Version 2.0 (the "License"); 3096 * you may not use this file except in compliance with the License. 3097 * You may obtain a copy of the License at 3098 * 3099 * http://www.apache.org/licenses/LICENSE-2.0 3100 * 3101 * Unless required by applicable law or agreed to in writing, software 3102 * distributed under the License is distributed on an "AS IS" BASIS, 3103 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3104 * See the License for the specific language governing permissions and 3105 * limitations under the License. 3106 */class Hk extends Q3{constructor(e){super("custom","custom"),this.params=e}_getIdTokenResponse(e){return cl(e,this._buildIdpRequest())}_linkToIdToken(e,a){return cl(e,this._buildIdpRequest(a))}_getReauthenticationResolver(e){return cl(e,this._buildIdpRequest())}_buildIdpRequest(e){const a={requestUri:this.params.requestUri,sessionId:this.params.sessionId,postBody:this.params.postBody,tenantId:this.params.tenantId,pendingToken:this.params.pendingToken,returnSecureToken:!0,returnIdpCredential:!0};return e&&(a.idToken=e),a}}function VX(t){return kX(t.auth,new Hk(t),t.bypassAuthState)}function HX(t){const{auth:e,user:a}=t;return ue(a,e,"internal-error"),wX(a,new Hk(t),t.bypassAuthState)}async function FX(t){const{auth:e,user:a}=t;return ue(a,e,"internal-error"),bX(a,new Hk(t),t.bypassAuthState)}/** 3107 * @license 3108 * Copyright 2020 Google LLC 3109 * 3110 * Licensed under the Apache License, Version 2.0 (the "License"); 3111 * you may not use this file except in compliance with the License. 3112 * You may obtain a copy of the License at 3113 * 3114 * http://www.apache.org/licenses/LICENSE-2.0 3115 * 3116 * Unless required by applicable law or agreed to in writing, software 3117 * distributed under the License is distributed on an "AS IS" BASIS, 3118 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3119 * See the License for the specific language governing permissions and 3120 * limitations under the License. 3121 */class lO{constructor(e,a,n,i,r=!1){this.auth=e,this.resolver=n,this.user=i,this.bypassAuthState=r,this.pendingPromise=null,this.eventManager=null,this.filter=Array.isArray(a)?a:[a]}execute(){return new Promise(async(e,a)=>{this.pendingPromise={resolve:e,reject:a};try{this.eventManager=await this.resolver._initialize(this.auth),await this.onExecution(),this.eventManager.registerConsumer(this)}catch(n){this.reject(n)}})}async onAuthEvent(e){const{urlResponse:a,sessionId:n,postBody:i,tenantId:r,error:o,type:l}=e;if(o){this.reject(o);return}const c={auth:this.auth,requestUri:a,sessionId:n,tenantId:r||void 0,postBody:i||void 0,user:this.user,bypassAuthState:this.bypassAuthState};try{this.resolve(await this.getIdpTask(l)(c))}catch(d){this.reject(d)}}onError(e){this.reject(e)}getIdpTask(e){switch(e){case"signInViaPopup":case"signInViaRedirect":return VX;case"linkViaPopup":case"linkViaRedirect":return FX;case"reauthViaPopup":case"reauthViaRedirect":return HX;default:ii(this.auth,"internal-error")}}resolve(e){Bi(this.pendingPromise,"Pending promise was never set"),this.pendingPromise.resolve(e),this.unregisterAndCleanUp()}reject(e){Bi(this.pendingPromise,"Pending promise was never set"),this.pendingPromise.reject(e),this.unregisterAndCleanUp()}unregisterAndCleanUp(){this.eventManager&&this.eventManager.unregisterConsumer(this),this.pendingPromise=null,this.cleanUp()}}/** 3122 * @license 3123 * Copyright 2020 Google LLC 3124 * 3125 * Licensed under the Apache License, Version 2.0 (the "License");
3126 * you may not use this file except in compliance with the License. 3127 * You may obtain a copy of the License at 3128 * 3129 * http://www.apache.org/licenses/LICENSE-2.0 3130 * 3131 * Unless required by applicable law or agreed to in writing, software 3132 * distributed under the License is distributed on an "AS IS" BASIS, 3133 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3134 * See the License for the specific language governing permissions and 3135 * limitations under the License. 3136 */const BX=new Fu(2e3,1e4);async function cO(t,e,a){if(wi(t.app))return Promise.reject(Pn(t,"operation-not-supported-in-this-environment"));const n=jg(t);HQ(t,e,zk);const i=sO(n,a);return new _o(n,"signInViaPopup",e,i).executeNotNull()}class _o extends lO{constructor(e,a,n,i,r){super(e,a,i,r),this.provider=n,this.authWindow=null,this.pollId=null,_o.currentPopupAction&&_o.currentPopupAction.cancel(),_o.currentPopupAction=this}async executeNotNull(){const e=await this.execute();return ue(e,this.auth,"internal-error"),e}async onExecution(){Bi(this.filter.length===1,"Popup operations only handle one event");const e=Vk();this.authWindow=await this.resolver._openPopup(this.auth,this.provider,this.filter[0],e),this.authWindow.associatedEvent=e,this.resolver._originValidation(this.auth).catch(a=>{this.reject(a)}),this.resolver._isIframeWebStorageSupported(this.auth,a=>{a||this.reject(Pn(this.auth,"web-storage-unsupported"))}),this.pollUserCancellation()}get eventId(){var e;return((e=this.authWindow)===null||e===void 0?void 0:e.associatedEvent)||null}cancel(){this.reject(Pn(this.auth,"cancelled-popup-request"))}cleanUp(){this.authWindow&&this.authWindow.close(),this.pollId&&window.clearTimeout(this.pollId),this.authWindow=null,this.pollId=null,_o.currentPopupAction=null}pollUserCancellation(){const e=()=>{var a,n;if(!((n=(a=this.authWindow)===null||a===void 0?void 0:a.window)===null||n===void 0)&&n.closed){this.pollId=window.setTimeout(()=>{this.pollId=null,this.reject(Pn(this.auth,"popup-closed-by-user"))},8e3);return}this.pollId=window.setTimeout(e,BX.get())};e()}}_o.currentPopupAction=null;/** 3137 * @license 3138 * Copyright 2020 Google LLC 3139 * 3140 * Licensed under the Apache License, Version 2.0 (the "License"); 3141 * you may not use this file except in compliance with the License. 3142 * You may obtain a copy of the License at 3143 * 3144 * http://www.apache.org/licenses/LICENSE-2.0 3145 * 3146 * Unless required by applicable law or agreed to in writing, software 3147 * distributed under the License is distributed on an "AS IS" BASIS, 3148 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3149 * See the License for the specific language governing permissions and 3150 * limitations under the License. 3151 */const UX="pendingRedirect",Vm=new Map;class $X extends lO{constructor(e,a,n=!1){super(e,["signInViaRedirect","linkViaRedirect","reauthViaRedirect","unknown"],a,void 0,n),this.eventId=null}async execute(){let e=Vm.get(this.auth._key());if(!e){try{const n=await WX(this.resolver,this.auth)?await super.execute():null;e=()=>Promise.resolve(n)}catch(a){e=()=>Promise.reject(a)}Vm.set(this.auth._key(),e)}return this.bypassAuthState||Vm.set(this.auth._key(),()=>Promise.resolve(null)),e()}async onAuthEvent(e){if(e.type==="signInViaRedirect")return super.onAuthEvent(e);if(e.type==="unknown"){this.resolve(null);return}if(e.eventId){const a=await this.auth._redirectUserForId(e.eventId);if(a)return this.user=a,super.onAuthEvent(e);this.resolve(null)}}async onExecution(){}cleanUp(){}}async function WX(t,e){const a=JX(e),n=KX(t);if(!await n._isAvailable())return!1;const i=await n._get(a)==="true";return await n._remove(a),i}function GX(t,e){Vm.set(t._key(),e)}function KX(t){return _i(t._redirectPersistence)}function JX(t){return zm(UX,t.config.apiKey,t.name)}async function QX(t,e,a=!1){if(wi(t.app))return Promise.reject(Mo(t));const n=jg(t),i=sO(n,e),o=await new $X(n,i,a).execute();return o&&!a&&(delete o.user._redirectEventId,await n._persistUserIfCurrent(o.user),await n._setRedirectUser(null,e)),o}/** 3152 * @license 3153 * Copyright 2020 Google LLC 3154 * 3155 * Licensed under the Apache License, Version 2.0 (the "License");
3156 * you may not use this file except in compliance with the License. 3157 * You may obtain a copy of the License at 3158 * 3159 * http://www.apache.org/licenses/LICENSE-2.0 3160 * 3161 * Unless required by applicable law or agreed to in writing, software 3162 * distributed under the License is distributed on an "AS IS" BASIS, 3163 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3164 * See the License for the specific language governing permissions and 3165 * limitations under the License. 3166 */const XX=10*60*1e3;class YX{constructor(e){this.auth=e,this.cachedEventUids=new Set,this.consumers=new Set,this.queuedRedirectEvent=null,this.hasHandledPotentialRedirect=!1,this.lastProcessedEventTime=Date.now()}registerConsumer(e){this.consumers.add(e),this.queuedRedirectEvent&&this.isEventForConsumer(this.queuedRedirectEvent,e)&&(this.sendToConsumer(this.queuedRedirectEvent,e),this.saveEventToCache(this.queuedRedirectEvent),this.queuedRedirectEvent=null)}unregisterConsumer(e){this.consumers.delete(e)}onEvent(e){if(this.hasEventBeenHandled(e))return!1;let a=!1;return this.consumers.forEach(n=>{this.isEventForConsumer(e,n)&&(a=!0,this.sendToConsumer(e,n),this.saveEventToCache(e))}),this.hasHandledPotentialRedirect||!ZX(e)||(this.hasHandledPotentialRedirect=!0,a||(this.queuedRedirectEvent=e,a=!0)),a}sendToConsumer(e,a){var n;if(e.error&&!dO(e)){const i=((n=e.error.code)===null||n===void 0?void 0:n.split("auth/")[1])||"internal-error";a.onError(Pn(this.auth,i))}else a.onAuthEvent(e)}isEventForConsumer(e,a){const n=a.eventId===null||!!e.eventId&&e.eventId===a.eventId;return a.filter.includes(e.type)&&n}hasEventBeenHandled(e){return Date.now()-this.lastProcessedEventTime>=XX&&this.cachedEventUids.clear(),this.cachedEventUids.has(QC(e))}saveEventToCache(e){this.cachedEventUids.add(QC(e)),this.lastProcessedEventTime=Date.now()}}function QC(t){return[t.type,t.eventId,t.sessionId,t.tenantId].filter(e=>e).join("-")}function dO({type:t,error:e}){return t==="unknown"&&(e==null?void 0:e.code)==="auth/no-auth-event"}function ZX(t){switch(t.type){case"signInViaRedirect":case"linkViaRedirect":case"reauthViaRedirect":return!0;case"unknown":return dO(t);default:return!1}}/** 3167 * @license 3168 * Copyright 2020 Google LLC 3169 * 3170 * Licensed under the Apache License, Version 2.0 (the "License"); 3171 * you may not use this file except in compliance with the License. 3172 * You may obtain a copy of the License at 3173 * 3174 * http://www.apache.org/licenses/LICENSE-2.0 3175 * 3176 * Unless required by applicable law or agreed to in writing, software 3177 * distributed under the License is distributed on an "AS IS" BASIS, 3178 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3179 * See the License for the specific language governing permissions and 3180 * limitations under the License. 3181 */async function eY(t,e={}){return Yl(t,"GET","/v1/projects",e)}/** 3182 * @license 3183 * Copyright 2020 Google LLC 3184 * 3185 * Licensed under the Apache License, Version 2.0 (the "License"); 3186 * you may not use this file except in compliance with the License. 3187 * You may obtain a copy of the License at 3188 * 3189 * http://www.apache.org/licenses/LICENSE-2.0 3190 * 3191 * Unless required by applicable law or agreed to in writing, software 3192 * distributed under the License is distributed on an "AS IS" BASIS, 3193 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3194 * See the License for the specific language governing permissions and 3195 * limitations under the License. 3196 */const tY=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,aY=/^https?/;async function nY(t){if(t.config.emulator)return;const{authorizedDomains:e}=await eY(t);for(const a of e)try{if(iY(a))return}catch{}ii(t,"unauthorized-domain")}function iY(t){const e=fb(),{protocol:a,hostname:n}=new URL(e);if(t.startsWith("chrome-extension://")){const o=new URL(t);return o.hostname===""&&n===""?a==="chrome-extension:"&&t.replace("chrome-extension://","")===e.replace("chrome-extension://",""):a==="chrome-extension:"&&o.hostname===n}if(!aY.test(a))return!1;if(tY.test(t))return n===t;const i=t.replace(/\./g,"\\.");return new RegExp("^(.+\\."+i+"|"+i+")$","i").test(n)}/** 3197 * @license 3198 * Copyright 2020 Google LLC. 3199 * 3200 * Licensed under the Apache License, Version 2.0 (the "License");
3201 * you may not use this file except in compliance with the License. 3202 * You may obtain a copy of the License at 3203 * 3204 * http://www.apache.org/licenses/LICENSE-2.0 3205 * 3206 * Unless required by applicable law or agreed to in writing, software 3207 * distributed under the License is distributed on an "AS IS" BASIS, 3208 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3209 * See the License for the specific language governing permissions and 3210 * limitations under the License. 3211 */const rY=new Fu(3e4,6e4);function XC(){const t=ai().___jsl;if(t!=null&&t.H){for(const e of Object.keys(t.H))if(t.H[e].r=t.H[e].r||[],t.H[e].L=t.H[e].L||[],t.H[e].r=[...t.H[e].L],t.CP)for(let a=0;a<t.CP.length;a++)t.CP[a]=null}}function oY(t){return new Promise((e,a)=>{var n,i,r;function o(){XC(),gapi.load("gapi.iframes",{callback:()=>{e(gapi.iframes.getContext())},ontimeout:()=>{XC(),a(Pn(t,"network-request-failed"))},timeout:rY.get()})}if(!((i=(n=ai().gapi)===null||n===void 0?void 0:n.iframes)===null||i===void 0)&&i.Iframe)e(gapi.iframes.getContext());else if(!((r=ai().gapi)===null||r===void 0)&&r.load)o();else{const l=mX("iframefcb");return ai()[l]=()=>{gapi.load?o():a(Pn(t,"network-request-failed"))},uX(`${pX()}?onload=${l}`).catch(c=>a(c))}}).catch(e=>{throw Hm=null,e})}let Hm=null;function sY(t){return Hm=Hm||oY(t),Hm}/** 3212 * @license 3213 * Copyright 2020 Google LLC. 3214 * 3215 * Licensed under the Apache License, Version 2.0 (the "License"); 3216 * you may not use this file except in compliance with the License. 3217 * You may obtain a copy of the License at 3218 * 3219 * http://www.apache.org/licenses/LICENSE-2.0 3220 * 3221 * Unless required by applicable law or agreed to in writing, software 3222 * distributed under the License is distributed on an "AS IS" BASIS, 3223 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3224 * See the License for the specific language governing permissions and 3225 * limitations under the License. 3226 */const lY=new Fu(5e3,15e3),cY="__/auth/iframe",dY="emulator/auth/iframe",uY={style:{position:"absolute",top:"-100px",width:"1px",height:"1px"},"aria-hidden":"true",tabindex:"-1"},pY=new Map([["identitytoolkit.googleapis.com","p"],["staging-identitytoolkit.sandbox.googleapis.com","s"],["test-identitytoolkit.sandbox.googleapis.com","t"]]);function mY(t){const e=t.config;ue(e.authDomain,t,"auth-domain-config-required");const a=e.emulator?Lk(e,dY):`https://${t.config.authDomain}/${cY}`,n={apiKey:e.apiKey,appName:t.name,v:us},i=pY.get(t.config.apiHost);i&&(n.eid=i);const r=t._getFrameworks();return r.length&&(n.fw=r.join(",")),`${a}?${Ru(n).slice(1)}`}async function hY(t){const e=await sY(t),a=ai().gapi;return ue(a,t,"internal-error"),e.open({where:document.body,url:mY(t),messageHandlersFilter:a.iframes.CROSS_ORIGIN_IFRAMES_FILTER,attributes:uY,dontclear:!0},n=>new Promise(async(i,r)=>{await n.restyle({setHideOnLeave:!1});const o=Pn(t,"network-request-failed"),l=ai().setTimeout(()=>{r(o)},lY.get());function c(){ai().clearTimeout(l),i(n)}n.ping(c).then(c,()=>{r(o)})}))}/** 3227 * @license 3228 * Copyright 2020 Google LLC. 3229 * 3230 * Licensed under the Apache License, Version 2.0 (the "License"); 3231 * you may not use this file except in compliance with the License. 3232 * You may obtain a copy of the License at 3233 * 3234 * http://www.apache.org/licenses/LICENSE-2.0 3235 * 3236 * Unless required by applicable law or agreed to in writing, software 3237 * distributed under the License is distributed on an "AS IS" BASIS, 3238 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3239 * See the License for the specific language governing permissions and 3240 * limitations under the License. 3241 */const fY={location:"yes",resizable:"yes",statusbar:"yes",toolbar:"no"},gY=500,yY=600,xY="_blank",vY="http://localhost";class YC{constructor(e){this.window=e,this.associatedEvent=null}close(){if(this.window)try{this.window.close()}catch{}}}function bY(t,e,a,n=gY,i=yY){const r=Math.max((window.screen.availHeight-i)/2,0).toString(),o=Math.max((window.screen.availWidth-n)/2,0).toString();let l="";const c=Object.assign(Object.assign({},fY),{width:n.toString(),height:i.toString(),top:r,left:o}),d=ra().toLowerCase();a&&(l=F3(d)?xY:a),V3(d)&&(e=e||vY,c.scrollbars="yes");const u=Object.entries(c).reduce((m,[h,g])=>`${m}${h}=${g},`,"");if(nX(d)&&l!=="_self")return wY(e||"",l),new YC(null);const p=window.open(e||"",l,u);ue(p,t,"popup-blocked");try{p.focus()}catch{}return new YC(p)}function wY(t,e){const a=document.createElement("a");a.href=t,a.target=e;const n=document.createEvent("MouseEvent");
3241n.initMouseEvent("click",!0,!0,window,1,0,0,0,0,!1,!1,!1,!1,1,null),a.dispatchEvent(n)}/** 3242 * @license 3243 * Copyright 2021 Google LLC 3244 * 3245 * Licensed under the Apache License, Version 2.0 (the "License"); 3246 * you may not use this file except in compliance with the License. 3247 * You may obtain a copy of the License at 3248 * 3249 * http://www.apache.org/licenses/LICENSE-2.0 3250 * 3251 * Unless required by applicable law or agreed to in writing, software 3252 * distributed under the License is distributed on an "AS IS" BASIS, 3253 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3254 * See the License for the specific language governing permissions and 3255 * limitations under the License. 3256 */const kY="__/auth/handler",SY="emulator/auth/handler",_Y=encodeURIComponent("fac");async function ZC(t,e,a,n,i,r){ue(t.config.authDomain,t,"auth-domain-config-required"),ue(t.config.apiKey,t,"invalid-api-key");const o={apiKey:t.config.apiKey,appName:t.name,authType:a,redirectUrl:n,v:us,eventId:i};if(e instanceof zk){e.setDefaultLanguage(t.languageCode),o.providerId=e.providerId||"",l$(e.getCustomParameters())||(o.customParameters=JSON.stringify(e.getCustomParameters()));for(const[u,p]of Object.entries({}))o[u]=p}if(e instanceof Bu){const u=e.getScopes().filter(p=>p!=="");u.length>0&&(o.scopes=u.join(","))}t.tenantId&&(o.tid=t.tenantId);const l=o;for(const u of Object.keys(l))l[u]===void 0&&delete l[u];const c=await t._getAppCheckToken(),d=c?`#${_Y}=${encodeURIComponent(c)}`:"";return`${AY(t)}?${Ru(l).slice(1)}${d}`}function AY({config:t}){return t.emulator?Lk(t,SY):`https://${t.authDomain}/${kY}`}/** 3257 * @license 3258 * Copyright 2020 Google LLC 3259 * 3260 * Licensed under the Apache License, Version 2.0 (the "License"); 3261 * you may not use this file except in compliance with the License. 3262 * You may obtain a copy of the License at 3263 * 3264 * http://www.apache.org/licenses/LICENSE-2.0 3265 * 3266 * Unless required by applicable law or agreed to in writing, software 3267 * distributed under the License is distributed on an "AS IS" BASIS, 3268 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3269 * See the License for the specific language governing permissions and 3270 * limitations under the License. 3271 */const L0="webStorageSupport";class EY{constructor(){this.eventManagers={},this.iframes={},this.originValidationPromises={},this._redirectPersistence=aO,this._completeRedirectFn=QX,this._overrideRedirectResult=GX}async _openPopup(e,a,n,i){var r;Bi((r=this.eventManagers[e._key()])===null||r===void 0?void 0:r.manager,"_initialize() not called before _openPopup()");const o=await ZC(e,a,n,fb(),i);return bY(e,o,Vk())}async _openRedirect(e,a,n,i){await this._originValidation(e);const r=await ZC(e,a,n,fb(),i);return NX(r),new Promise(()=>{})}_initialize(e){const a=e._key();if(this.eventManagers[a]){const{manager:i,promise:r}=this.eventManagers[a];return i?Promise.resolve(i):(Bi(r,"If manager is not set, promise should be"),r)}const n=this.initAndGetManager(e);return this.eventManagers[a]={promise:n},n.catch(()=>{delete this.eventManagers[a]}),n}async initAndGetManager(e){const a=await hY(e),n=new YX(e);return a.register("authEvent",i=>(ue(i==null?void 0:i.authEvent,e,"invalid-auth-event"),{status:n.onEvent(i.authEvent)?"ACK":"ERROR"}),gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER),this.eventManagers[e._key()]={manager:n},this.iframes[e._key()]=a,n}_isIframeWebStorageSupported(e,a){this.iframes[e._key()].send(L0,{type:L0},i=>{var r;const o=(r=i==null?void 0:i[0])===null||r===void 0?void 0:r[L0];o!==void 0&&a(!!o),ii(e,"internal-error")},gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER)}_originValidation(e){const a=e._key();return this.originValidationPromises[a]||(this.originValidationPromises[a]=nY(e)),this.originValidationPromises[a]}get _shouldInitProactively(){return G3()||H3()||Dk()}}const CY=EY;var ej="@firebase/auth",tj="1.7.9";/** 3272 * @license 3273 * Copyright 2020 Google LLC 3274 * 3275 * Licensed under the Apache License, Version 2.0 (the "License"); 3276 * you may not use this file except in compliance with the License. 3277 * You may obtain a copy of the License at 3278 * 3279 * http://www.apache.org/licenses/LICENSE-2.0 3280 * 3281 * Unless required by applicable law or agreed to in writing, softw
3281are 3282 * distributed under the License is distributed on an "AS IS" BASIS, 3283 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3284 * See the License for the specific language governing permissions and 3285 * limitations under the License. 3286 */class jY{constructor(e){this.auth=e,this.internalListeners=new Map}getUid(){var e;return this.assertAuthConfigured(),((e=this.auth.currentUser)===null||e===void 0?void 0:e.uid)||null}async getToken(e){return this.assertAuthConfigured(),await this.auth._initializationPromise,this.auth.currentUser?{accessToken:await this.auth.currentUser.getIdToken(e)}:null}addAuthTokenListener(e){if(this.assertAuthConfigured(),this.internalListeners.has(e))return;const a=this.auth.onIdTokenChanged(n=>{e((n==null?void 0:n.stsTokenManager.accessToken)||null)});this.internalListeners.set(e,a),this.updateProactiveRefresh()}removeAuthTokenListener(e){this.assertAuthConfigured();const a=this.internalListeners.get(e);a&&(this.internalListeners.delete(e),a(),this.updateProactiveRefresh())}assertAuthConfigured(){ue(this.auth._initializationPromise,"dependent-sdk-initialized-before-auth")}updateProactiveRefresh(){this.internalListeners.size>0?this.auth._startProactiveRefresh():this.auth._stopProactiveRefresh()}}/** 3287 * @license 3288 * Copyright 2020 Google LLC 3289 * 3290 * Licensed under the Apache License, Version 2.0 (the "License"); 3291 * you may not use this file except in compliance with the License. 3292 * You may obtain a copy of the License at 3293 * 3294 * http://www.apache.org/licenses/LICENSE-2.0 3295 * 3296 * Unless required by applicable law or agreed to in writing, software 3297 * distributed under the License is distributed on an "AS IS" BASIS, 3298 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3299 * See the License for the specific language governing permissions and 3300 * limitations under the License. 3301 */function TY(t){switch(t){case"Node":return"node";case"ReactNative":return"rn";case"Worker":return"webworker";case"Cordova":return"cordova";case"WebExtension":return"web-extension";default:return}}function NY(t){Dn(new hn("auth",(e,{options:a})=>{const n=e.getProvider("app").getImmediate(),i=e.getProvider("heartbeat"),r=e.getProvider("app-check-internal"),{apiKey:o,authDomain:l}=n.options;ue(o&&!o.includes(":"),"invalid-api-key",{appName:n.name});const c={apiKey:o,authDomain:l,clientPlatform:t,apiHost:"identitytoolkit.googleapis.com",tokenApiHost:"securetoken.googleapis.com",apiScheme:"https",sdkClientVersion:K3(t)},d=new cX(n,i,r,c);return fX(d,a),d},"PUBLIC").setInstantiationMode("EXPLICIT").setInstanceCreatedCallback((e,a,n)=>{e.getProvider("auth-internal").initialize()})),Dn(new hn("auth-internal",e=>{const a=jg(e.getProvider("auth").getImmediate());return(n=>new jY(n))(a)},"PRIVATE").setInstantiationMode("EXPLICIT")),Na(ej,tj,TY(t)),Na(ej,tj,"esm2017")}/** 3302 * @license 3303 * Copyright 2021 Google LLC 3304 * 3305 * Licensed under the Apache License, Version 2.0 (the "License"); 3306 * you may not use this file except in compliance with the License. 3307 * You may obtain a copy of the License at 3308 * 3309 * http://www.apache.org/licenses/LICENSE-2.0 3310 * 3311 * Unless required by applicable law or agreed to in writing, software 3312 * distributed under the License is distributed on an "AS IS" BASIS, 3313 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3314 * See the License for the specific language governing permissions and 3315 * limitations under the License. 3316 */const IY=5*60,PY=qR("authIdTokenMaxAge")||IY;let aj=null;const RY=t=>async e=>{const a=e&&await e.getIdTokenResult(),n=a&&(new Date().getTime()-Date.parse(a.issuedAtTime))/1e3;if(n&&n>PY)return;const i=a==null?void 0:a.token;aj!==i&&(aj=i,await fetch(t,{method:i?"POST":"DELETE",headers:i?{Authorization:`Bearer ${i}`}:{}}))};function LY(t=mg()){const e=Qr(t,"auth");if(e.isInitialized())return e.getImmediate();const a=hX(t,{popupRedirectResolver:CY,persistence:[zX,CX,aO]}),n=qR("authTokenSyncURL");if(n&&typeof isSecureContext=="boolean"&&isSecureContext){const r=new URL(n,location.origin);if(location.origin===r.origin){const o=RY(r.toString());_X(a,o,()=>o(a.currentUser)),SX(a,l=>o(l))}}const i=OR("auth");return i&&gX(a,`http://${i}`),a}function OY(){var t,e;return(e=(t=document.getElementsByTagName("head"))===null||t===void 0?void 0:t[0])!==null&&e!==void 0?e:document}dX({loadJS(t){return new Promise((e,a)=>{const n=document.createElement("script");n.setAttribute("src",t),n.onload=e,n.onerror=i=>{const r=Pn("internal-error");r.customData=i,a(r)},n.type="text/javascript",n.charset="UTF-8",OY().appendChild(n)})},gapiScript:"https://apis.google.com/js/api.js",recaptchaV2Script:"https://www.google.com/recaptcha/api.js",recaptchaEnterpriseScript:"https://www.google.com/recaptcha/enterprise.js?render="});NY("Browser");const uO="@firebase/installations",Fk="0.6.9";/** 3317 * @license 3318 * Copyright 2019 Google LLC 3319 * 3320 * Licensed under the Apache License, Version 2.0 (the "License");
3321 * you may not use this file except in compliance with the License. 3322 * You may obtain a copy of the License at 3323 * 3324 * http://www.apache.org/licenses/LICENSE-2.0 3325 * 3326 * Unless required by applicable law or agreed to in writing, software 3327 * distributed under the License is distributed on an "AS IS" BASIS, 3328 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3329 * See the License for the specific language governing permissions and 3330 * limitations under the License. 3331 */const pO=1e4,mO=`w:${Fk}`,hO="FIS_v2",MY="https://firebaseinstallations.googleapis.com/v1",DY=60*60*1e3,qY="installations",zY="Installations";/** 3332 * @license 3333 * Copyright 2019 Google LLC 3334 * 3335 * Licensed under the Apache License, Version 2.0 (the "License"); 3336 * you may not use this file except in compliance with the License. 3337 * You may obtain a copy of the License at 3338 * 3339 * http://www.apache.org/licenses/LICENSE-2.0 3340 * 3341 * Unless required by applicable law or agreed to in writing, software 3342 * distributed under the License is distributed on an "AS IS" BASIS, 3343 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3344 * See the License for the specific language governing permissions and 3345 * limitations under the License. 3346 */const VY={"missing-app-config-values":'Missing App configuration value: "{$valueName}"',"not-registered":"Firebase Installation is not registered.","installation-not-found":"Firebase Installation not found.","request-failed":'{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',"app-offline":"Could not process request. Application offline.","delete-pending-registration":"Can't delete installation while there is a pending registration request."},es=new ds(qY,zY,VY);function fO(t){return t instanceof gn&&t.code.includes("request-failed")}/** 3347 * @license 3348 * Copyright 2019 Google LLC 3349 * 3350 * Licensed under the Apache License, Version 2.0 (the "License"); 3351 * you may not use this file except in compliance with the License. 3352 * You may obtain a copy of the License at 3353 * 3354 * http://www.apache.org/licenses/LICENSE-2.0 3355 * 3356 * Unless required by applicable law or agreed to in writing, software 3357 * distributed under the License is distributed on an "AS IS" BASIS, 3358 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3359 * See the License for the specific language governing permissions and 3360 * limitations under the License. 3361 */function gO({projectId:t}){return`${MY}/projects/${t}/installations`}function yO(t){return{token:t.token,requestStatus:2,expiresIn:FY(t.expiresIn),creationTime:Date.now()}}async function xO(t,e){const n=(await e.json()).error;return es.create("request-failed",{requestName:t,serverCode:n.code,serverMessage:n.message,serverStatus:n.status})}function vO({apiKey:t}){return new Headers({"Content-Type":"application/json",Accept:"application/json","x-goog-api-key":t})}function HY(t,{refreshToken:e}){const a=vO(t);return a.append("Authorization",BY(e)),a}async function bO(t){const e=await t();return e.status>=500&&e.status<600?t():e}function FY(t){return Number(t.replace("s","000"))}function BY(t){return`${hO} ${t}`}/** 3362 * @license 3363 * Copyright 2019 Google LLC 3364 * 3365 * Licensed under the Apache License, Version 2.0 (the "License"); 3366 * you may not use this file except in compliance with the License. 3367 * You may obtain a copy of the License at 3368 * 3369 * http://www.apache.org/licenses/LICENSE-2.0 3370 * 3371 * Unless required by applicable law or agreed to in writing, software 3372 * distributed under the License is distributed on an "AS IS" BASIS, 3373 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3374 * See the License for the specific language governing permissions and 3375 * limitations under the License. 3376 */async function UY({appConfig:t,heartbeatServiceProvider:e},{fid:a}){const n=gO(t),i=vO(t),r=e.getImmediate({optional:!0});if(r){const d=await r.getHeartbeatsHeader();d&&i.append("x-firebase-client",d)}const o={fid:a,authVersion:hO,appId:t.appId,sdkVersion:mO},l={method:"POST",headers:i,body:JSON.stringify(o)},c=await bO(()=>fetch(n,l));if(c.ok){const d=await c.json();return{fid:d.fid||a,registrationStatus:2,refreshToken:d.refreshToken,authToken:yO(d.authToken)}}else throw await xO("Create Installation",c)}/** 3377 * @license 3378 * Copyright 2019 Google LLC 3379 * 3380 * Licensed under the Apache License, Version 2.0 (the "License");
3381 * you may not use this file except in compliance with the License. 3382 * You may obtain a copy of the License at 3383 * 3384 * http://www.apache.org/licenses/LICENSE-2.0 3385 * 3386 * Unless required by applicable law or agreed to in writing, software 3387 * distributed under the License is distributed on an "AS IS" BASIS, 3388 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3389 * See the License for the specific language governing permissions and 3390 * limitations under the License. 3391 */function wO(t){return new Promise(e=>{setTimeout(e,t)})}/** 3392 * @license 3393 * Copyright 2019 Google LLC 3394 * 3395 * Licensed under the Apache License, Version 2.0 (the "License"); 3396 * you may not use this file except in compliance with the License. 3397 * You may obtain a copy of the License at 3398 * 3399 * http://www.apache.org/licenses/LICENSE-2.0 3400 * 3401 * Unless required by applicable law or agreed to in writing, software 3402 * distributed under the License is distributed on an "AS IS" BASIS, 3403 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3404 * See the License for the specific language governing permissions and 3405 * limitations under the License. 3406 */function $Y(t){return btoa(String.fromCharCode(...t)).replace(/\+/g,"-").replace(/\//g,"_")}/** 3407 * @license 3408 * Copyright 2019 Google LLC 3409 * 3410 * Licensed under the Apache License, Version 2.0 (the "License"); 3411 * you may not use this file except in compliance with the License. 3412 * You may obtain a copy of the License at 3413 * 3414 * http://www.apache.org/licenses/LICENSE-2.0 3415 * 3416 * Unless required by applicable law or agreed to in writing, software 3417 * distributed under the License is distributed on an "AS IS" BASIS, 3418 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3419 * See the License for the specific language governing permissions and 3420 * limitations under the License. 3421 */const WY=/^[cdef][\w-]{21}$/,xb="";function GY(){try{const t=new Uint8Array(17);(self.crypto||self.msCrypto).getRandomValues(t),t[0]=112+t[0]%16;const a=KY(t);return WY.test(a)?a:xb}catch{return xb}}function KY(t){return $Y(t).substr(0,22)}/** 3422 * @license 3423 * Copyright 2019 Google LLC 3424 * 3425 * Licensed under the Apache License, Version 2.0 (the "License"); 3426 * you may not use this file except in compliance with the License. 3427 * You may obtain a copy of the License at 3428 * 3429 * http://www.apache.org/licenses/LICENSE-2.0 3430 * 3431 * Unless required by applicable law or agreed to in writing, software 3432 * distributed under the License is distributed on an "AS IS" BASIS, 3433 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3434 * See the License for the specific language governing permissions and 3435 * limitations under the License. 3436 */function Ig(t){return`${t.appName}!${t.appId}`}/** 3437 * @license 3438 * Copyright 2019 Google LLC 3439 * 3440 * Licensed under the Apache License, Version 2.0 (the "License"); 3441 * you may not use this file except in compliance with the License. 3442 * You may obtain a copy of the License at 3443 * 3444 * http://www.apache.org/licenses/LICENSE-2.0 3445 * 3446 * Unless required by applicable law or agreed to in writing, software 3447 * distributed under the License is distributed on an "AS IS" BASIS, 3448 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3449 * See the License for the specific language governing permissions and 3450 * limitations under the License. 3451 */const kO=new Map;function SO(t,e){const a=Ig(t);_O(a,e),JY(a,e)}function _O(t,e){const a=kO.get(t);if(a)for(const n of a)n(e)}function JY(t,e){const a=QY();a&&a.postMessage({key:t,fid:e}),XY()}let Ao=null;function QY(){return!Ao&&"BroadcastChannel"in self&&(Ao=new BroadcastChannel("[Firebase] FID Change"),Ao.onmessage=t=>{_O(t.data.key,t.data.fid)}),Ao}function XY(){kO.size===0&&Ao&&(Ao.close(),Ao=null)}/** 3452 * @license 3453 * Copyright 2019 Google LLC 3454 * 3455 * Licensed under the Apache License, Version 2.0 (the "License"); 3456 * you may not use this file except in compliance with the License. 3457 * You may obtain a copy of the License at 3458 * 3459 * http://www.apache.org/licenses/LICENSE-2.0 3460 * 3461 * Unless required by applicable law or agreed to in writing, software 3462 * distributed under the License is distributed on an "AS IS" BASIS, 3463 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3464 * See the License for the specific language governing permissions and 3465 * limitations under the License. 3466 */const YY="firebase-installations-database",ZY=1,ts="firebase-installations-store";let O0=null;function Bk(){return O0||(O0=BR(YY,ZY,{upgrade:(t,e)=>{switch(e){case 0:t.createObjectStore(ts)}}})),O0}async function Uh(t,e){const a=Ig(t),i=(await Bk()).transaction(ts,"readwrite"),r=i.objectStore(ts),o=await r.get(a);return await r.put(e,a),await i.done,(!o||o.fid!==e.fid)&&SO(t,e.fid),e}async function AO(t){const e=Ig(t),n=(await Bk()).transaction(ts,"readwrite");await n.objectStore(ts).delete(e),await n.done}async function Pg(t,e){const a=Ig(t),i=(await Bk()).transaction(ts,"readwrite"),r=i.objectStore(ts),o=await r.get(a),l=e(o);return l===void 0?await r.delete(a):await r.put(l,a),await i.done,l&&(!o||o.fid!==l.fid)&&SO(t,l.fid),l}/** 3467 * @license 3468 * Copyright 2019 Google LLC 3469 * 3470 * Licensed under the Apache License, Version 2.0 (the "License");
3471 * you may not use this file except in compliance with the License. 3472 * You may obtain a copy of the License at 3473 * 3474 * http://www.apache.org/licenses/LICENSE-2.0 3475 * 3476 * Unless required by applicable law or agreed to in writing, software 3477 * distributed under the License is distributed on an "AS IS" BASIS, 3478 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3479 * See the License for the specific language governing permissions and 3480 * limitations under the License. 3481 */async function Uk(t){let e;const a=await Pg(t.appConfig,n=>{const i=eZ(n),r=tZ(t,i);return e=r.registrationPromise,r.installationEntry});return a.fid===xb?{installationEntry:await e}:{installationEntry:a,registrationPromise:e}}function eZ(t){const e=t||{fid:GY(),registrationStatus:0};return EO(e)}function tZ(t,e){if(e.registrationStatus===0){if(!navigator.onLine){const i=Promise.reject(es.create("app-offline"));return{installationEntry:e,registrationPromise:i}}const a={fid:e.fid,registrationStatus:1,registrationTime:Date.now()},n=aZ(t,a);return{installationEntry:a,registrationPromise:n}}else return e.registrationStatus===1?{installationEntry:e,registrationPromise:nZ(t)}:{installationEntry:e}}async function aZ(t,e){try{const a=await UY(t,e);return Uh(t.appConfig,a)}catch(a){throw fO(a)&&a.customData.serverCode===409?await AO(t.appConfig):await Uh(t.appConfig,{fid:e.fid,registrationStatus:0}),a}}async function nZ(t){let e=await nj(t.appConfig);for(;e.registrationStatus===1;)await wO(100),e=await nj(t.appConfig);if(e.registrationStatus===0){const{installationEntry:a,registrationPromise:n}=await Uk(t);return n||a}return e}function nj(t){return Pg(t,e=>{if(!e)throw es.create("installation-not-found");return EO(e)})}function EO(t){return iZ(t)?{fid:t.fid,registrationStatus:0}:t}function iZ(t){return t.registrationStatus===1&&t.registrationTime+pO<Date.now()}/** 3482 * @license 3483 * Copyright 2019 Google LLC 3484 * 3485 * Licensed under the Apache License, Version 2.0 (the "License"); 3486 * you may not use this file except in compliance with the License. 3487 * You may obtain a copy of the License at 3488 * 3489 * http://www.apache.org/licenses/LICENSE-2.0 3490 * 3491 * Unless required by applicable law or agreed to in writing, software 3492 * distributed under the License is distributed on an "AS IS" BASIS, 3493 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3494 * See the License for the specific language governing permissions and 3495 * limitations under the License. 3496 */async function rZ({appConfig:t,heartbeatServiceProvider:e},a){const n=oZ(t,a),i=HY(t,a),r=e.getImmediate({optional:!0});if(r){const d=await r.getHeartbeatsHeader();d&&i.append("x-firebase-client",d)}const o={installation:{sdkVersion:mO,appId:t.appId}},l={method:"POST",headers:i,body:JSON.stringify(o)},c=await bO(()=>fetch(n,l));if(c.ok){const d=await c.json();return yO(d)}else throw await xO("Generate Auth Token",c)}function oZ(t,{fid:e}){return`${gO(t)}/${e}/authTokens:generate`}/** 3497 * @license 3498 * Copyright 2019 Google LLC 3499 * 3500 * Licensed under the Apache License, Version 2.0 (the "License"); 3501 * you may not use this file except in compliance with the License. 3502 * You may obtain a copy of the License at 3503 * 3504 * http://www.apache.org/licenses/LICENSE-2.0 3505 * 3506 * Unless required by applicable law or agreed to in writing, software 3507 * distributed under the License is distributed on an "AS IS" BASIS, 3508 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3509 * See the License for the specific language governing permissions and 3510 * limitations under the License. 3511 */async function $k(t,e=!1){let a;const n=await Pg(t.appConfig,r=>{if(!CO(r))throw es.create("not-registered");const o=r.authToken;
3511if(!e&&cZ(o))return r;if(o.requestStatus===1)return a=sZ(t,e),r;{if(!navigator.onLine)throw es.create("app-offline");const l=uZ(r);return a=lZ(t,l),l}});return a?await a:n.authToken}async function sZ(t,e){let a=await ij(t.appConfig);for(;a.authToken.requestStatus===1;)await wO(100),a=await ij(t.appConfig);const n=a.authToken;return n.requestStatus===0?$k(t,e):n}function ij(t){return Pg(t,e=>{if(!CO(e))throw es.create("not-registered");const a=e.authToken;return pZ(a)?Object.assign(Object.assign({},e),{authToken:{requestStatus:0}}):e})}async function lZ(t,e){try{const a=await rZ(t,e),n=Object.assign(Object.assign({},e),{authToken:a});return await Uh(t.appConfig,n),a}catch(a){if(fO(a)&&(a.customData.serverCode===401||a.customData.serverCode===404))await AO(t.appConfig);else{const n=Object.assign(Object.assign({},e),{authToken:{requestStatus:0}});await Uh(t.appConfig,n)}throw a}}function CO(t){return t!==void 0&&t.registrationStatus===2}function cZ(t){return t.requestStatus===2&&!dZ(t)}function dZ(t){const e=Date.now();return e<t.creationTime||t.creationTime+t.expiresIn<e+DY}function uZ(t){const e={requestStatus:1,requestTime:Date.now()};return Object.assign(Object.assign({},t),{authToken:e})}function pZ(t){return t.requestStatus===1&&t.requestTime+pO<Date.now()}/** 3512 * @license 3513 * Copyright 2019 Google LLC 3514 * 3515 * Licensed under the Apache License, Version 2.0 (the "License"); 3516 * you may not use this file except in compliance with the License. 3517 * You may obtain a copy of the License at 3518 * 3519 * http://www.apache.org/licenses/LICENSE-2.0 3520 * 3521 * Unless required by applicable law or agreed to in writing, software 3522 * distributed under the License is distributed on an "AS IS" BASIS, 3523 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3524 * See the License for the specific language governing permissions and 3525 * limitations under the License. 3526 */async function mZ(t){const e=t,{installationEntry:a,registrationPromise:n}=await Uk(e);return n?n.catch(console.error):$k(e).catch(console.error),a.fid}/** 3527 * @license 3528 * Copyright 2019 Google LLC 3529 * 3530 * Licensed under the Apache License, Version 2.0 (the "License"); 3531 * you may not use this file except in compliance with the License. 3532 * You may obtain a copy of the License at 3533 * 3534 * http://www.apache.org/licenses/LICENSE-2.0 3535 * 3536 * Unless required by applicable law or agreed to in writing, software 3537 * distributed under the License is distributed on an "AS IS" BASIS, 3538 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3539 * See the License for the specific language governing permissions and 3540 * limitations under the License. 3541 */async function hZ(t,e=!1){const a=t;return await fZ(a),(await $k(a,e)).token}async function fZ(t){const{registrationPromise:e}=await Uk(t);e&&await e}/** 3542 * @license 3543 * Copyright 2019 Google LLC 3544 * 3545 * Licensed under the Apache License, Version 2.0 (the "License"); 3546 * you may not use this file except in compliance with the License. 3547 * You may obtain a copy of the License at 3548 * 3549 * http://www.apache.org/licenses/LICENSE-2.0 3550 * 3551 * Unless required by applicable law or agreed to in writing, software 3552 * distributed under the License is distributed on an "AS IS" BASIS, 3553 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3554 * See the License for the specific language governing permissions and 3555 * limitations under the License. 3556 */function gZ(t){if(!t||!t.options)throw M0("App Configuration");if(!t.name)throw M0("App Name");const e=["projectId","apiKey","appId"];for(const a of e)if(!t.options[a])throw M0(a);return{appName:t.name,projectId:t.options.projectId,apiKey:t.options.apiKey,appId:t.options.appId}}function M0(t){return es.create("missing-app-config-values",{valueName:t})}/** 3557 * @license 3558 * Copyright 2020 Google LLC 3559 * 3560 * Licensed under the Apache License, Version 2.0 (the "License"); 3561 * you may not use this file except in compliance with the License. 3562 * You may obtain a copy of the License at 3563 * 3564 * http://www.apache.org/licenses/LICENSE-2.0 3565 * 3566 * Unless required by applicable law or agreed to in writing, software 3567 * distributed under the License is distributed on an "AS IS" BASIS, 3568 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3569 * See the License for the specific language governing permissions and 3570 * limitations under the License. 3571 */const jO="installations",yZ="installations-internal",xZ=t=>{const e=t.getProvider("app").getImmediate(),a=gZ(e),n=Qr(e,"heartbeat");return{app:e,appConfig:a,heartbeatServiceProvider:n,_delete:()=>Promise.resolve()}},vZ=t=>{const e=t.getProvider("app").getImmediate(),a=Qr(e,jO).getImmediate();return{getId:()=>mZ(a),getToken:i=>hZ(a,i)}};function bZ(){Dn(new hn(jO,xZ,"PUBLIC")),Dn(new hn(yZ,vZ,"PRIVATE"))}bZ();Na(uO,Fk);Na(uO,Fk,"esm2017");/** 3572 * @license 3573 * Copyright 2019 Google LLC 3574 * 3575 * Licensed under the Apache License, Version 2.0 (the "License");
3576 * you may not use this file except in compliance with the License. 3577 * You may obtain a copy of the License at 3578 * 3579 * http://www.apache.org/licenses/LICENSE-2.0 3580 * 3581 * Unless required by applicable law or agreed to in writing, software 3582 * distributed under the License is distributed on an "AS IS" BASIS, 3583 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3584 * See the License for the specific language governing permissions and 3585 * limitations under the License. 3586 */const $h="analytics",wZ="firebase_id",kZ="origin",SZ=60*1e3,_Z="https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig",Wk="https://www.googletagmanager.com/gtag/js";/** 3587 * @license 3588 * Copyright 2019 Google LLC 3589 * 3590 * Licensed under the Apache License, Version 2.0 (the "License"); 3591 * you may not use this file except in compliance with the License. 3592 * You may obtain a copy of the License at 3593 * 3594 * http://www.apache.org/licenses/LICENSE-2.0 3595 * 3596 * Unless required by applicable law or agreed to in writing, software 3597 * distributed under the License is distributed on an "AS IS" BASIS, 3598 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3599 * See the License for the specific language governing permissions and 3600 * limitations under the License. 3601 */const Pa=new pg("@firebase/analytics");/** 3602 * @license 3603 * Copyright 2019 Google LLC 3604 * 3605 * Licensed under the Apache License, Version 2.0 (the "License"); 3606 * you may not use this file except in compliance with the License. 3607 * You may obtain a copy of the License at 3608 * 3609 * http://www.apache.org/licenses/LICENSE-2.0 3610 * 3611 * Unless required by applicable law or agreed to in writing, software 3612 * distributed under the License is distributed on an "AS IS" BASIS, 3613 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3614 * See the License for the specific language governing permissions and 3615 * limitations under the License. 3616 */const AZ={"already-exists":"A Firebase Analytics instance with the appId {$id} already exists. Only one Firebase Analytics instance can be created for each appId.","already-initialized":"initializeAnalytics() cannot be called again with different options than those it was initially called with. It can be called again with the same options to return the existing instance, or getAnalytics() can be used to get a reference to the already-initialized instance.","already-initialized-settings":"Firebase Analytics has already been initialized.settings() must be called before initializing any Analytics instanceor it will have no effect.","interop-component-reg-failed":"Firebase Analytics Interop Component failed to instantiate: {$reason}","invalid-analytics-context":"Firebase Analytics is not supported in this environment. Wrap initialization of analytics in analytics.isSupported() to prevent initialization in unsupported environments. Details: {$errorInfo}","indexeddb-unavailable":"IndexedDB unavailable or restricted in this environment. Wrap initialization of analytics in analytics.isSupported() to prevent initialization in unsupported environments. Details: {$errorInfo}","fetch-throttle":"The config fetch request timed out while in an exponential backoff state. Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.","config-fetch-failed":"Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}","no-api-key":'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field tocontain a valid API key.',"no-app-id":'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field tocontain a valid app ID.',"no-client-id":'The "client_id" field is empty.',"invalid-gtag-resource":"Trusted Types detected an invalid gtag resource: {$gtagURL}."},Ba=new ds("analytics","Analytics",AZ);/** 3617 * @license 3618 * Copyright 2019 Google LLC 3619 * 3620 * Licensed under the Apache License, Version 2.0 (the "License"); 3621 * you may not use this file except in compliance with the License. 3622 * You may obtain a copy of the License at 3623 * 3624 * http://www.apache.org/licenses/LICENSE-2.0 3625 * 3626 * Unless required by applicable law or agreed to in writing, softw
3626are 3627 * distributed under the License is distributed on an "AS IS" BASIS, 3628 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3629 * See the License for the specific language governing permissions and 3630 * limitations under the License. 3631 */function EZ(t){if(!t.startsWith(Wk)){const e=Ba.create("invalid-gtag-resource",{gtagURL:t});return Pa.warn(e.message),""}return t}function TO(t){return Promise.all(t.map(e=>e.catch(a=>a)))}function CZ(t,e){let a;return window.trustedTypes&&(a=window.trustedTypes.createPolicy(t,e)),a}function jZ(t,e){const a=CZ("firebase-js-sdk-policy",{createScriptURL:EZ}),n=document.createElement("script"),i=`${Wk}?l=${t}&id=${e}`;n.src=a?a==null?void 0:a.createScriptURL(i):i,n.async=!0,document.head.appendChild(n)}function TZ(t){let e=[];return Array.isArray(window[t])?e=window[t]:window[t]=e,e}async function NZ(t,e,a,n,i,r){const o=n[i];try{if(o)await e[o];else{const c=(await TO(a)).find(d=>d.measurementId===i);c&&await e[c.appId]}}catch(l){Pa.error(l)}t("config",i,r)}async function IZ(t,e,a,n,i){try{let r=[];if(i&&i.send_to){let o=i.send_to;Array.isArray(o)||(o=[o]);const l=await TO(a);for(const c of o){const d=l.find(p=>p.measurementId===c),u=d&&e[d.appId];if(u)r.push(u);else{r=[];break}}}r.length===0&&(r=Object.values(e)),await Promise.all(r),t("event",n,i||{})}catch(r){Pa.error(r)}}function PZ(t,e,a,n){async function i(r,...o){try{if(r==="event"){const[l,c]=o;await IZ(t,e,a,l,c)}else if(r==="config"){const[l,c]=o;await NZ(t,e,a,n,l,c)}else if(r==="consent"){const[l,c]=o;t("consent",l,c)}else if(r==="get"){const[l,c,d]=o;t("get",l,c,d)}else if(r==="set"){const[l]=o;t("set",l)}else t(r,...o)}catch(l){Pa.error(l)}}return i}function RZ(t,e,a,n,i){let r=function(...o){window[n].push(arguments)};return window[i]&&typeof window[i]=="function"&&(r=window[i]),window[i]=PZ(r,t,e,a),{gtagCore:r,wrappedGtag:window[i]}}function LZ(t){const e=window.document.getElementsByTagName("script");for(const a of Object.values(e))if(a.src&&a.src.includes(Wk)&&a.src.includes(t))return a;return null}/** 3632 * @license 3633 * Copyright 2020 Google LLC 3634 * 3635 * Licensed under the Apache License, Version 2.0 (the "License"); 3636 * you may not use this file except in compliance with the License. 3637 * You may obtain a copy of the License at 3638 * 3639 * http://www.apache.org/licenses/LICENSE-2.0 3640 * 3641 * Unless required by applicable law or agreed to in writing, software 3642 * distributed under the License is distributed on an "AS IS" BASIS, 3643 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3644 * See the License for the specific language governing permissions and 3645 * limitations under the License. 3646 */const OZ=30,MZ=1e3;class DZ{constructor(e={},a=MZ){this.throttleMetadata=e,this.intervalMillis=a}getThrottleMetadata(e){return this.throttleMetadata[e]}setThrottleMetadata(e,a){this.throttleMetadata[e]=a}deleteThrottleMetadata(e){delete this.throttleMetadata[e]}}const NO=new DZ;function qZ(t){return new Headers({Accept:"application/json","x-goog-api-key":t})}async function zZ(t){var e;const{appId:a,apiKey:n}=t,i={method:"GET",headers:qZ(n)},r=_Z.replace("{app-id}",a),o=await fetch(r,i);if(o.status!==200&&o.status!==304){let l="";try{const c=await o.json();!((e=c.error)===null||e===void 0)&&e.message&&(l=c.error.message)}catch{}throw Ba.create("config-fetch-failed",{httpStatus:o.status,responseMessage:l})}return o.json()}async function VZ(t,e=NO,a){const{appId:n,apiKey:i,measurementId:r}=t.options;if(!n)throw Ba.create("no-app-id");if(!i){if(r)return{measurementId:r,appId:n};throw Ba.create("no-api-key")}const o=e.getThrottleMetadata(n)||{backoffCount:0,throttleEndTimeMillis:Date.now()},l=new BZ;return setTimeout(async()=>{l.abort()},SZ),IO({appId:n,apiKey:i,measurementId:r},o,l,e)}async function IO(t,{throttleEndTimeMillis:e,backoffCount:a},n,i=NO){var r;const{appId:o,measurementId:l}=t;try{await HZ(n,e)}catch(c){if(l)return Pa.warn(`Timed out fetching this Firebase app's measurement ID from the server. Falling back to the measurement ID ${l} provided in the "measurementId" field in the local Firebase config. [${c==null?void 0:c.message}
3646]`),{appId:o,measurementId:l};throw c}try{const c=await zZ(t);return i.deleteThrottleMetadata(o),c}catch(c){const d=c;if(!FZ(d)){if(i.deleteThrottleMetadata(o),l)return Pa.warn(`Failed to fetch this Firebase app's measurement ID from the server. Falling back to the measurement ID ${l} provided in the "measurementId" field in the local Firebase config. [${d==null?void 0:d.message}]`),{appId:o,measurementId:l};throw c}const u=Number((r=d==null?void 0:d.customData)===null||r===void 0?void 0:r.httpStatus)===503?VE(a,i.intervalMillis,OZ):VE(a,i.intervalMillis),p={throttleEndTimeMillis:Date.now()+u,backoffCount:a+1};return i.setThrottleMetadata(o,p),Pa.debug(`Calling attemptFetch again in ${u} millis`),IO(t,p,n,i)}}function HZ(t,e){return new Promise((a,n)=>{const i=Math.max(e-Date.now(),0),r=setTimeout(a,i);t.addEventListener(()=>{clearTimeout(r),n(Ba.create("fetch-throttle",{throttleEndTimeMillis:e}))})})}function FZ(t){if(!(t instanceof gn)||!t.customData)return!1;const e=Number(t.customData.httpStatus);return e===429||e===500||e===503||e===504}class BZ{constructor(){this.listeners=[]}addEventListener(e){this.listeners.push(e)}abort(){this.listeners.forEach(e=>e())}}async function UZ(t,e,a,n,i){if(i&&i.global){t("event",a,n);return}else{const r=await e,o=Object.assign(Object.assign({},n),{send_to:r});t("event",a,o)}}/** 3647 * @license 3648 * Copyright 2020 Google LLC 3649 * 3650 * Licensed under the Apache License, Version 2.0 (the "License"); 3651 * you may not use this file except in compliance with the License. 3652 * You may obtain a copy of the License at 3653 * 3654 * http://www.apache.org/licenses/LICENSE-2.0 3655 * 3656 * Unless required by applicable law or agreed to in writing, software 3657 * distributed under the License is distributed on an "AS IS" BASIS, 3658 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3659 * See the License for the specific language governing permissions and 3660 * limitations under the License. 3661 */async function $Z(){if(qw())try{await zw()}catch(t){return Pa.warn(Ba.create("indexeddb-unavailable",{errorInfo:t==null?void 0:t.toString()}).message),!1}else return Pa.warn(Ba.create("indexeddb-unavailable",{errorInfo:"IndexedDB is not available in this environment."}).message),!1;return!0}async function WZ(t,e,a,n,i,r,o){var l;const c=VZ(t);c.then(h=>{a[h.measurementId]=h.appId,t.options.measurementId&&h.measurementId!==t.options.measurementId&&Pa.warn(`The measurement ID in the local Firebase config (${t.options.measurementId}) does not match the measurement ID fetched from the server (${h.measurementId}). To ensure analytics events are always sent to the correct Analytics property, update the measurement ID field in the local config or remove it from the local config.`)}).catch(h=>Pa.error(h)),e.push(c);const d=$Z().then(h=>{if(h)return n.getId()}),[u,p]=await Promise.all([c,d]);LZ(r)||jZ(r,u.measurementId),i("js",new Date);const m=(l=o==null?void 0:o.config)!==null&&l!==void 0?l:{};return m[kZ]="firebase",m.update=!0,p!=null&&(m[wZ]=p),i("config",u.measurementId,m),u.measurementId}/** 3662 * @license 3663 * Copyright 2019 Google LLC 3664 * 3665 * Licensed under the Apache License, Version 2.0 (the "License"); 3666 * you may not use this file except in compliance with the License. 3667 * You may obtain a copy of the License at 3668 * 3669 * http://www.apache.org/licenses/LICENSE-2.0 3670 * 3671 * Unless required by applicable law or agreed to in writing, software 3672 * distributed under the License is distributed on an "AS IS" BASIS, 3673 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3674 * See the License for the specific language governing permissions and 3675 * limitations under the License. 3676 */class GZ{constructor(e){this.app=e}_delete(){return delete xd[this.app.options.appId],Promise.resolve()}}let xd={},rj=[];const oj={};let D0="dataLayer",KZ="gtag",sj,PO,lj=!1;function JZ(){const t=[];if(Dw()&&t.push("This is a browser extension environment."),VR()||t.push("Cookies are not available."),t.length>0){const e=t.map((n,i)=>`(${i+1}) ${n}`).join(" "),a=Ba.create("invalid-analytics-context",{errorInfo:e});Pa.warn(a.message)}}function QZ(t,e,a){JZ();
3676const n=t.options.appId;if(!n)throw Ba.create("no-app-id");if(!t.options.apiKey)if(t.options.measurementId)Pa.warn(`The "apiKey" field is empty in the local Firebase config. This is needed to fetch the latest measurement ID for this Firebase app. Falling back to the measurement ID ${t.options.measurementId} provided in the "measurementId" field in the local Firebase config.`);else throw Ba.create("no-api-key");if(xd[n]!=null)throw Ba.create("already-exists",{id:n});if(!lj){TZ(D0);const{wrappedGtag:r,gtagCore:o}=RZ(xd,rj,oj,D0,KZ);PO=r,sj=o,lj=!0}return xd[n]=WZ(t,rj,oj,e,sj,D0,a),new GZ(t)}function RO(t=mg()){t=et(t);const e=Qr(t,$h);return e.isInitialized()?e.getImmediate():XZ(t)}function XZ(t,e={}){const a=Qr(t,$h);if(a.isInitialized()){const i=a.getImmediate();if(eu(e,a.getOptions()))return i;throw Ba.create("already-initialized")}return a.initialize({options:e})}async function LO(){if(Dw()||!VR()||!qw())return!1;try{return await zw()}catch{return!1}}function OO(t,e,a,n){t=et(t),UZ(PO,xd[t.app.options.appId],e,a,n).catch(i=>Pa.error(i))}const cj="@firebase/analytics",dj="0.10.8";function YZ(){Dn(new hn($h,(e,{options:a})=>{const n=e.getProvider("app").getImmediate(),i=e.getProvider("installations-internal").getImmediate();return QZ(n,i,a)},"PUBLIC")),Dn(new hn("analytics-internal",t,"PRIVATE")),Na(cj,dj),Na(cj,dj,"esm2017");function t(e){try{const a=e.getProvider($h).getImmediate();return{logEvent:(n,i,r)=>OO(a,n,i,r)}}catch(a){throw Ba.create("interop-component-reg-failed",{reason:a})}}}YZ();const ZZ={apiKey:"AIzaSyAnGhhCPPtwkANfLbB5XkPpQtie7v3B2qw",authDomain:"web-haka-2026.firebaseapp.com",projectId:"web-haka-2026",storageBucket:"web-haka-2026.firebasestorage.app",messagingSenderId:"786948522059",appId:"1:786948522059:web:6ffa235f89fa769208cdce",measurementId:"G-H8DW25VVF8"},Rg=UR(ZZ),xi=LY(Rg),St=oJ(Rg),Gk=RQ(Rg);LO().then(t=>t?RO(Rg):null);function eee({isOpen:t,onClose:e}){const{t:a}=$(),n=k.useRef(null),[i,r]=k.useState({nombre:"",email:"",pais:"",telefono:""}),[o,l]=k.useState(null),[c,d]=k.useState(!1),[u,p]=k.useState(null),m=x=>{r({...i,[x.target.name]:x.target.value})},h=x=>{const v=x.target.files[0];if(!v)return;if(!["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document"].includes(v.type)){alert(a("trabajaModal.archivoInvalido"));return}if(v.size>2*1024*1024){alert(a("trabajaModal.archivoGrande"));return}l(v)},g=()=>{r({nombre:"",email:"",pais:"",telefono:""}),l(null),n.current&&(n.current.value="")},y=async x=>{x.preventDefault(),d(!0),p(null);try{let v="";if(o){const w=Date.now(),S=o.name.replace(/[^a-zA-Z0-9._-]/g,"_"),T=Nk(Gk,`cv/${w}_${S}`);await jk(T,o),v=await Tk(T)}await Tl(ga(St,"mail"),{to:["[email protected]"],cc:["[email protected]"],message:{subject:"Trabaja con Nosotros - Nuevo CV recibido",html:` 3677 <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;"> 3678 <h2 style="color: #06b6d4;">Nuevo postulante - Trabaja con Nosotros</h2> 3679 <div style="background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0;"> 3680 <p><strong>Nombre:</strong> ${i.nombre}</p> 3681 <p><strong>Email:</strong> ${i.email}</p> 3682 <p><strong>PaÃs de residencia:</strong> ${i.pais}</p> 3683 <p><strong>Teléfono:</strong> ${i.telefono}</p> 3684 ${v?`<p><strong>CV:</strong> <a href="${v}" style="color: #06b6d4;">Descargar CV</a></p>`:"<p><em>No adjuntó CV</em></p>"} 3685 </div> 3686 <p style="color: #6b7280; font-size: 12px;">Este mensaje fue enviado desde el formulario "Trabaja con Nosotros" de hakalab.com</p> 3687 </div> 3688 `},timestamp:new Date}),p("success"),g(),setTimeout(()=>{e(),p(null)},2e3)}catch(v){console.error("Error al enviar postulación:",v),p("error")}finally{d(!1)}};return t?s.jsx(La,{children:t&&s.jsx(_.div,{initial:{opacity:0}
3688,animate:{opacity:1},exit:{opacity:0},onClick:e,className:"fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-4",children:s.jsxs(_.div,{initial:{opacity:0,scale:.95,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:20},onClick:x=>x.stopPropagation(),className:"bg-[#1a1d3a] rounded-3xl shadow-2xl max-w-2xl w-full relative overflow-hidden max-h-[90vh] overflow-y-auto",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative p-8 sm:p-10",children:[s.jsx("button",{onClick:e,className:"absolute top-6 right-6 text-gray-400 hover:text-white transition-colors",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-white mb-3",children:a("trabajaModal.title")}),s.jsx("p",{className:"text-gray-300 mb-8",children:a("trabajaModal.subtitle")}),s.jsxs("form",{onSubmit:y,className:"space-y-6",children:[s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-nombre",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.nombre")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"trabaja-nombre",name:"nombre",value:i.nombre,onChange:m,required:!0,placeholder:a("trabajaModal.nombrePlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-email",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none",children:s.jsx("svg",{className:"w-5 h-5 text-gray-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})}),s.jsx("input",{type:"email",id:"trabaja-email",name:"email",value:i.email,onChange:m,required:!0,placeholder:a("trabajaModal.emailPlaceholder"),className:"w-full bg-[#2a2d4a] text-white pl-12 pr-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-pais",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.pais")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"trabaja-pais",name:"pais",value:i.pais,onChange:m,required:!0,placeholder:a("trabajaModal.paisPlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-telefono",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.telefono")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"tel",id:"trabaja-telefono",name:"telefono",value:i.telefono,onChange:m,required:!0,placeholder:a("trabajaModal.telefonoPlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.cv")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{onClick:()=>{var x;return(x=n.current)==null?void 0:x.click()},className:"w-full bg-[#2a2d4a] text-white px-4 py-4 rounded-xl border-2 border-dashed border-gray-600 hover:border-cyan-400 transition-colors cursor-pointer flex items-center gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-cyan-400 flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"})}),s.jsx("span",{className:o?"text-cyan-400":"text-gray-500",children:o?o.name:a("trabajaModal.cvPlaceholder")})]}),s.jsx("input",{ref:n,type:"file",accept:".pdf,.doc,.docx",onChange:h,className:"hidden",required:!0}),s.jsx("p",{className:"text-gray-500 text-xs mt-1",children:a("trabajaModal.cvFormatos")})]}),u==="success"&&s.jsx(_.div,{initial:{opacity:0,y:-10}
3688,animate:{opacity:1,y:0},className:"bg-green-500/20 border border-green-500 text-green-400 px-4 py-3 rounded-xl",children:a("trabajaModal.exitoEnvio")}),u==="error"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-red-500/20 border border-red-500 text-red-400 px-4 py-3 rounded-xl",children:a("trabajaModal.errorEnvio")}),s.jsx("button",{type:"submit",disabled:c,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-4 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed border-2 border-cyan-400",children:c?s.jsxs("span",{className:"flex items-center justify-center gap-2",children:[s.jsxs("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[s.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),s.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),a("trabajaModal.enviando")]}):a("trabajaModal.enviar")})]})]})]})})}):null}function tee(){const{t}=$(),[e,a]=k.useState(!1);return s.jsxs("footer",{className:"bg-darkGray border-t border-slate-800 py-8 px-4 pt-10",children:[s.jsxs("div",{className:"max-w-7xl mx-auto mt-10 pt-6",children:[s.jsxs("div",{className:"flex flex-col md:flex-row items-center justify-center gap-9 mb-6 pt-10 pb-7 border-b border-slate-800 mt-10",children:[s.jsx("div",{className:"flex flex-col items-center gap-4",children:s.jsxs("div",{className:"flex flex-wrap justify-center gap-6 text-sm",children:[s.jsx("a",{id:"footer-terminos-link",href:"/productos/terms",className:"text-gray-400 hover:text-primary transition-colors",children:t("footer.terminos")}),s.jsxs("a",{href:"mailto:[email protected]",className:"text-gray-400 hover:text-primary transition-colors",children:["contacto",s.jsx("span",{children:"@"}),"hakalab.com"]}),s.jsx("a",{id:"footer-ereshaka-link",href:"https://voyager.hakalab.com/",className:"text-gray-400 hover:text-primary transition-colors",children:t("footer.ereshaka")}),s.jsx("button",{id:"footer-trabaja-link",onClick:()=>a(!0),className:"text-gray-400 hover:text-primary transition-colors",children:t("footer.trabajaConNosotros")})]})}),s.jsxs("div",{className:"flex gap-4",children:[s.jsx("a",{href:"https://www.linkedin.com/company/hakalab",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"LinkedIn",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"})})}),s.jsx("a",{href:"https://www.instagram.com/hakalab.latam",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"Instagram",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zM5.838 12a6.162 6.162 0 1 1 12.324 0 6.162 6.162 0 0 1-12.324 0zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm4.965-10.322a1.44 1.44 0 1 1 2.881.001 1.44 1.44 0 0 1-2.881-.001z"})})}),s.jsx("a",{href:"https://x.com/haka_lab",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"X",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24h-6.514l-5.106-6.694-5.829 6.694h-3.328l7.691-8.793-8.156-10.707h6.657l4.596 6.08 5.279-6.08zM16.369 20.033h1.83L7.622 3.956H5.696l10.673 16.
3688077z"})})}),s.jsx("a",{href:"https://github.com/HakaLab-2025",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"GitHub",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v 3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"})})})]})]}),s.jsxs("div",{className:"flex items-center justify-center gap-3 pb-9",children:[s.jsx("img",{id:"footer-logo",src:"/imagenes/logo_haka.png",alt:"Haka Lab",className:"h-5 w-auto"}),s.jsx("span",{className:"text-sm text-gray-400",children:t("footer.empresa")})]})]}),s.jsx(eee,{isOpen:e,onClose:()=>a(!1)})]})}function aee(){const[t,e]=k.useState(!1),a=()=>{window.scrollY>300?e(!0):e(!1)},n=()=>{window.scrollTo({top:0,behavior:"smooth"})};return k.useEffect(()=>(window.addEventListener("scroll",a),()=>{window.removeEventListener("scroll",a)}),[]),s.jsx(La,{children:t&&s.jsx(_.button,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.8},transition:{duration:.3},onClick:n,className:"fixed bottom-8 right-8 z-40 p-2 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 shadow-2xl shadow-cyan-500/50 transition-all duration-300 hover:shadow-cyan-500/70 transform hover:-translate-y-1","aria-label":"Volver al inicio",children:s.jsx("img",{src:"/imagenes/volverarriba.png",alt:"Volver arriba",className:"w-14 h-14"})})})}function Yr({isOpen:t,onClose:e,title:a="Contáctanos"}){const{t:n}=$(),[i,r]=k.useState({nombre:"",empresa:"",email:"",mensaje:""}),[o,l]=k.useState(!1),[c,d]=k.useState(null),u=m=>{r({...i,[m.target.name]:m.target.value})},p=async m=>{m.preventDefault(),l(!0),d(null);try{const h=await Tl(ga(St,"mail"),{to:["[email protected]"],message:{subject:"Contacto desde la web - HakaLab",html:` 3689 <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;"> 3690 <h2 style="color: #06b6d4;">Nueva solicitud de contacto</h2> 3691 <div style="background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0;"> 3692 <p><strong>Nombre:</strong> ${i.nombre}</p> 3693 <p><strong>Empresa:</strong> ${i.empresa}</p> 3694 <p><strong>Email:</strong> ${i.email}</p> 3695 <p><strong>Mensaje:</strong></p> 3696 <p style="white-space: pre-wrap;">${i.mensaje}</p> 3697 </div> 3698 <p style="color: #6b7280; font-size: 12px;">Este mensaje fue enviado desde el formulario de contacto de hakalab.com</p> 3699 </div> 3700 `},timestamp:new Date});console.log("Documento guardado en Firestore con ID:",h.id);const g=await fetch("https://us-central1-web-haka-2026.cloudfunctions.net/createJiraIssueFromContact",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({nombre:i.nombre,email:i.email,empresa:i.empresa,mensaje:i.mensaje})});if(!g.ok)console.warn("Advertencia: No se pudo crear el issue en Jira:",g.status);else{const y=await g.json();console.log("Issue creado en Jira:",y)}d("success"),r({nombre:"",empresa:"",email:"",mensaje:""}),setTimeout(()=>{e(),d(null)},2e3)}catch(h){console.error("Error detallado al enviar:",{message:h.message,code:h.code,fullError:h}),d("error")}finally{l(!1)}};return t?s.jsx(La,{children:t&&s.jsx(s.Fragment,{children:s.jsx(_.div,{id:"contact-modal-overlay",initial:{opacity:0}
3700,animate:{opacity:1},exit:{opacity:0},onClick:e,className:"fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-4",children:s.jsxs(_.div,{initial:{opacity:0,scale:.95,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:20},onClick:m=>m.stopPropagation(),className:"bg-[#1a1d3a] rounded-3xl shadow-2xl max-w-2xl w-full relative overflow-hidden",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative p-8 sm:p-10",children:[s.jsx("button",{id:"contact-modal-close-button",onClick:e,className:"absolute top-6 right-6 text-gray-400 hover:text-white transition-colors",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-white mb-3",children:a}),s.jsx("p",{className:"text-gray-300 mb-8",children:n("contactModal.subtitle")}),s.jsxs("form",{onSubmit:p,className:"space-y-6",children:[s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"nombre",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.nombre")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"nombre",name:"nombre",value:i.nombre,onChange:u,required:!0,placeholder:n("contactModal.nombrePlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"empresa",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.empresa")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"empresa",name:"empresa",value:i.empresa,onChange:u,required:!0,placeholder:n("contactModal.empresaPlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"email",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none",children:s.jsx("svg",{className:"w-5 h-5 text-gray-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})}),s.jsx("input",{type:"email",id:"email",name:"email",value:i.email,onChange:u,required:!0,placeholder:n("contactModal.emailPlaceholder"),className:"w-full bg-[#2a2d4a] text-white pl-12 pr-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"mensaje",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.mensaje")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("textarea",{id:"mensaje",name:"mensaje",value:i.mensaje,onChange:u,required:!0,rows:"4",placeholder:n("contactModal.mensajePlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500 resize-none"})]}),c==="success"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-green-500/20 border border-green-500 text-green-400 px-4 py-3 rounded-xl",children:n("contactModal.exitoEnvio")}),c==="error"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-red-500/20 border border-red-500 text-red-400 px-4 py-3 rounded-xl",children:n("contactModal.errorEnvio")}),s.jsx("button",{type:"submit",disabled:o,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-4 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed border-2 border-cyan-400",children:o?s.jsxs("span",{className:"flex items-center justify-center gap-2",children:[s.jsxs("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[s.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),s.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),n("contactModal.enviando")]}):n("contactModal.enviar")})]})]})]})})})}):null}const MO=k.createContext(),uj=["[email protected]","[email protected]","[email protected]","[email protected]","[email protected]"];function nee({children:t}){const[e,a]=k.useState(null),[n,i]=k.useState(!0),[r,o]=k.useState(null),[l,c]=k.useState(!1);k.useEffect(()=>Y3(xi,async h=>{try{h?uj.includes(h.email)?(a(h),c(!0)):(await yd(xi),a(null),c(!1)):(a(null),c(!1))}catch(g){console.error("Error verificando usuario:",g),o(g.message),a(null),c(!1)}finally{i(!1)}}),[]);const p={user:e,loading:n,error:r,isAdmin:l,loginWithGoogle:async()=>{try{o(null);const m=new Kn,h=await cO(xi,m);if(!uj.includes(h.user.email))throw await yd(xi),new Error(`El usuario ${h.user.email} no tiene permiso para acceder. Solo usuarios autorizados pueden ingresar.`);return a(h.user),c(!0),i(!1),h.user}catch(m){throw o(m.message),i(!1),m}},logout:async()=>{try{o(null),await yd(xi),a(null),c(!1)}catch(m){throw o(m.message),m}}};return s.jsx(MO.Provider,{value:p,children:t})}function hs(){const t=k.useContext(MO);if(!t)throw new Error("useAuth debe ser usado dentro de AuthProvider");return t}function Gp({children:t}){const{user:e,loading:a,isAdmin:n}=hs();return a?s.jsx("div",{className:"min-h-screen flex items-center justify-center bg-dark",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent roun
3700ded-full"})}):!e||!n?s.jsx(ew,{to:"/admin-blog",replace:!0}):t}function q0({children:t}){return window.location.hostname.includes("web-haka-2026.web.app")||window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"?t:s.jsx(ew,{to:"/404",replace:!0})}function ie({variant:t=1}){const e="#0a0e27ff",a={1:"M0,0L0,40L48,45.3C96,51,192,61,288,66.7C384,72,480,72,576,66.7C672,61,768,51,864,56C960,61,1056,83,1152,88C1248,93,1344,83,1392,77.3L1440,72L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",2:"M0,0L0,40L48,34.7C96,29,192,19,288,24C384,29,480,51,576,56C672,61,768,51,864,45.3C960,40,1056,40,1152,34.7C1248,29,1344,19,1392,13.3L1440,8L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",3:"M0,0L0,40L48,45.3C96,51,192,61,288,56C384,51,480,29,576,24C672,19,768,29,864,40C960,51,1056,61,1152,61.3C1248,61,1344,51,1392,45.3L1440,40L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"},n=`waveGrad-${t}`;return s.jsx("div",{className:"absolute bottom-0 left-0 w-full overflow-visible pointer-events-none",style:{height:"clamp(60px, 15vw, 120px)",transform:"translateY(100%)",zIndex:10},children:s.jsxs("svg",{className:"w-full h-full overflow-visible",viewBox:"0 0 1440 100",preserveAspectRatio:"xMidYMid slice",xmlns:"http://www.w3.org/2000/svg",style:{filter:"drop-shadow(0px 18px 10px rgba(0, 0, 0, 0.8))"},children:[s.jsx("defs",{children:s.jsxs("linearGradient",{id:n,x1:"0%",y1:"0%",x2:"0%",y2:"100%",children:[s.jsx("stop",{offset:"0%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"20%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"100%",stopColor:e,stopOpacity:"1"})]})}),s.jsx("path",{fill:`url(#${n})`,d:a[t]})]})})}function iee(){const{t}=$(),e=t("roibox",{returnObjects:!0});return s.jsxs("div",{className:`animate-float-slow absolute -bottom-4 -right-4 md:-right-10 z-20 3701 flex items-center gap-3 bg-[#0a1628]/80 backdrop-blur-md 3702 border border-white/10 p-4 rounded-2xl shadow-2xl min-w-[200px]`,children:[s.jsx("div",{className:"bg-[#0095ff] p-2 rounded-xl shadow-[0_0_15px_rgba(0,149,255,0.6)] flex items-center justify-center",children:s.jsx("svg",{className:"w-6 h-6 text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M13 10V3L4 14h7v7l9-11h-7z"})})}),s.jsxs("div",{className:"flex flex-col text-left",children:[s.jsx("span",{className:"text-[10px] font-bold text-[#0095ff] tracking-widest uppercase leading-tight",children:e.title}),s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx("span",{className:"text-xl md:text-2xl font-bold text-white",children:"+70%"}),s.jsx("span",{className:"text-sm md:text-base font-medium text-white/90",children:e.title2})]})]})]})}const Lg=({text:t})=>s.jsxs("div",{className:"w-fit inline-flex items-center gap-2 px-4 py-1 rounded-full border border-cyan-500/40 bg-cyan-950/20 backdrop-blur-md",children:[s.jsx("span",{className:"h-2 w-2 rounded-full bg-cyan-400 shadow-[0_0_8px_rgba(34,211,238,0.8)]"}),s.jsx("span",{className:"text-[10px] md:text-xs font-bold tracking-[0.15em] text-cyan-400 uppercase whitespace-nowrap",children:t})]}),ree="https://calendar.app.google/dkJfuj7MNARbfT5HA";function oee(){const{t}=$(),e=t("home.hero",{returnObjects:!0}),a=t("badges",{returnObjects:!0}),{isOpen:n,modalTitle:i,openModal:r,closeModal:o}=oa(),l=Qa(),c=()=>{window.open(ree,"_blank","width=1000,height=700,noopener")};return s.jsxs("section",{id:"home",className:"relative bg-dark",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[500px] sm:min-h-[600px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-left lg:text-left",children:[s.jsx(Lg,{text:a.lideres}),s.jsx("h1",{id:"hero-title",className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("h1",{id:"hero-title-2",class:"text-5xl md:text-7xl font-extrabold border-primary text-primary italic mt-4",children:s.jsx("span",{span:"",children:e.title2})}),s.jsx("p",{id:"hero-subtitle",className:"text-xl text-white font-normal max-w-lg leading-relaxed mt-10",itemProp:"description",children:e.subt
3702itle}),s.jsxs("div",{className:"flex flex-col sm:flex-row justify-center lg:justify-start gap-4 w-full sm:w-auto mt-7",children:[s.jsx("button",{id:"hero-schedule-call-button",onClick:c,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:e.scheduleCall}),s.jsx("button",{id:"hero-casos-exito-button",onClick:()=>{l("/casosdeexito")},className:"border-2 border-primary/50 text-primary px-6 sm:px-8 md:px-10 py-3 sm:py-2 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:e.cta})]})]}),s.jsxs("div",{className:"flex justify-center items-center mt-0 lg:mt-0 relative",children:[s.jsx(iee,{}),s.jsx("img",{id:"hero-hero-image",src:"/imagenes/home/personajeshaka_hero1.webp",alt:t("common.altHeroImage"),className:"w-full max-w-xs sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})]})]})})]}),s.jsx(ie,{variant:1}),s.jsx(Yr,{isOpen:n,onClose:o,title:i})]})}function see({className:t="w-12 h-12"}){return s.jsxs("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("path",{d:"M12 2L3 7V17L12 22L21 17V7L12 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("path",{d:"M12 22V12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("path",{d:"M21 7L12 12L3 7",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("circle",{cx:"12",cy:"9",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("path",{d:"M8 14L12 16L16 14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}function lee({className:t="w-12 h-12"}){return s.jsx("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:s.jsx("path",{d:"M13 2L3 14H12L11 22L21 10H12L13 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function cee({className:t="w-12 h-12"}){return s.jsxs("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("rect",{x:"3",y:"14",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("rect",{x:"14",y:"3",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("rect",{x:"14",y:"14",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("path",{d:"M6.5 6.5V8.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M6.5 17.5V19.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M17.5 6.5V8.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M17.5 17.5V19.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function dee({className:t="w-12 h-12"}){return s.jsxs("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"5",cy:"12",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("circle",{cx:"12",cy:"12",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("circle",{cx:"19",cy:"12",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("path",{d:"M7 12H10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M14 12H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M5 10V6C5 4.89543 5.89543 4 7 4H17C18.1046 4 19 4.89543 19 6V10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M5 14V18C5 19.1046 5.89543 20 7 20H17C18.1046 20 19 19.1046 19 18V14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function uee(){const{t}=$(),e=t("home.services",{returnObjects:!0}),a={0:see,1:lee,2:cee,3:dee},n={0:"/imagenes/salesforce.png",1:"/imagenes/sap.png"};return s.jsxs("section",{id:"services",className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark",children:[s.jsx("div",{className:"py-12 sm:py-16 md:py-20 px-4 sm:px-6 mt-9",children:s.jsxs("div",{className:"max-w-7xl mx-auto text-center",children:[s.jsxs(_.h2,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"mt-10 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[t("nav.servicios"),s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsx(_.p,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"mt-5 text-center text-base sm:text-lg md:text-xl leading-relaxed text-white mb-8 sm:mb-10 md:mb-12 font-light max-w-5xl mx-auto px-4",children:t("servicios.servicesDescription")}),s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 pt-5",children:e.map((i,r)=>{const o=a[r],l=n[r];return s.jsx(_.div,{initial:{opacity:0,y:50},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:r*.1},className:"group relative",children:s.jsx(Te,{to:"/servicios",children:s.jsxs("div",{className:"relative h-full p-6 sm:p-8 rounded-2xl bg-slate-900/50 backdrop-blur-sm border border-primary/20 hover:border-primary/50 transition-all duration-300 hover:shadow-xl hover:shadow-
3702primary/20 hover:-translate-y-2",children:[s.jsx("div",{className:"mb-6 text-primary",children:o&&s.jsx(o,{className:"w-12 h-12 sm:w-14 sm:h-14"})}),s.jsx("h3",{className:"text-xl sm:text-2xl font-bold mb-4 text-white group-hover:text-primary transition-colors",children:i.title}),s.jsx("p",{className:"text-gray-300 text-sm sm:text-base leading-relaxed mb-6",children:i.description}),l&&s.jsx("div",{className:"w-1/2 sm:w-2/5 lg:w-3/4 max-w-[100px] overflow-hidden rounded-xl border-white/10 shadow-lg",children:s.jsx("img",{src:l,alt:i.title,className:"w-full h-auto object-cover grayscale group-hover:grayscale-0 transition-all duration-500"})}),s.jsx("div",{className:"absolute inset-0 rounded-2xl bg-gradient-to-br from-primary/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none"})]})})},r)})})]})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function pee(){const{t}=$(),e=t("home.methodology",{returnObjects:!0}),[a,n]=k.useState(0);return k.useEffect(()=>{const i=setInterval(()=>{n(r=>(r+1)%e.steps.length)},3e3);return()=>clearInterval(i)},[e.steps.length]),s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark",children:[s.jsx("div",{className:"py-20 px-4 mt-9",children:s.jsxs("div",{className:"max-w-6xl mx-auto text-center",children:[s.jsxs(_.h1,{id:"methodology-title",initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"mt-10 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e.title,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsx(_.p,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"text-center text-gray-300 text-lg mb-3 text-xl pt-10",children:e.subtitle}),s.jsx(_.p,{initial:{opacity:0},whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.3},className:"text-center text-gray-400 mb-16 max-w-3xl mx-auto",children:e.description}),s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-primary",initial:{width:"0%"},animate:{width:`${a/(e.steps.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-primary rounded-full shadow-lg shadow-primary/50 z-20",animate:{left:`${a/(e.steps.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-primary animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-4 gap-3 sm:gap-4 pt-20",children:e.steps.map((i,r)=>s.jsxs(_.div,{id:`methodology-step-${r+1}`,initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:r*.1},className:"flex flex-col items-center text-center",children:[s.jsxs(_.div,{animate:{rotate:a>=r?360:0,scale:a===r?1.2:1},transition:{duration:.6},className:"mb-3 sm:mb-4 relative",children:[s.jsx("div",{className:`absolute inset-0 rounded-full blur-lg transition-opacity duration-500 ${a>=r?"opacity-100":"opacity-0"}`,style:{background:"radial-gradient(circle, #06b6d4 0%, transparent 10%)",width:"100%",height:"100%"}}),s.jsx("svg",{className:`w-8 sm:w-10 md:w-12 h-8 sm:h-10 md:h-12 transition-all duration-500 relative z-10 ${a>=r?"text-cyan-400 drop-shadow-lg":"text-gray-600"}`,style:{filter:a>=r?"drop-shadow(0 0 8px #06b6d4) drop-shadow(0 0 16px rgba(6, 182, 212, 0.5))":"none",textShadow:a>=r?"0 0 10px #06b6d4":"none"},fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{d:"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"})})]}),s.jsxs(_.div,{animate:{opacity:a>=r?1:.5,scale:a===r?1.05:1},transition:{duration:.3},className:`p-3 sm:p-4 rounded-lg border transition-all ${a>=r?"border-primary/30 bg-primary/5":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-1 sm:mb-2 text-xs sm:text-sm lg:text-base ${a>=r?"text-primary":"text-gray-400"}`,children:i.title}),s.jsx("p",{className:"text-[10px] sm:text-xs lg:text-sm text-gray-400",children:i.description})]})]},`step-${r}`))})]}),s.jsx(_.p,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.5},className:"text-center text-gray-300 mt-16 max-w-3xl mx-auto text-lg",children:e.bottomText})]})}),s.jsx(ie,{color:"#0a0e27",variant:3})]})}function mee(){var o,l,c,d,u,p,m,h,g,y,x,v,w,S,T,P;const{t}=$(),e=t("home.errorCost",{returnObjects:!0}),a=t("bugCostCycle",{returnObjects:!0}),n=[{icon:"â ï¸",title:((o=e.risks)==null?void 0:o[0])||"Integraciones que fallan sin dejar rastro"},{icon:"â ï¸",title:((l=e.risks)==null?void 0:l[1])||"Actualizaciones de Salesforce que rompen flujos crÃticos"},{icon:"â ï¸",title:((c=e.risks)==null?void 0:c[2])||"Tiempos de certificación manual insostenibles"}],i=[{label:((u=(d=a.stages)==null?void 0:d[0])==null?void 0:u.label)||"Requirements",cost:"1x",color:"from-purple-600 to-purple-700"},{label:((m=(p=a.stages)==null?void 0:p[1])==null?void 0:m.label)||"Design/Architecture",cost:"3x",color:"from-purple-500 to-purple-600"},{label:((g=(h=a.stages)==null?void 0:h[2])==null?void 0:g.label)||"Coding",cost:"7x",color:"from-purple-500 to-purple-600"},{label:((x=(y=a.stages)==null?void 0:y[3])==null?void 0:x.label)||"Testing",cost:"15x",color:"from-orange-400 to-red-500"},{label:((w=(v=a.stages)==null?void 0:v[4])==null?void 0:w.label)||"Deployment/Maintenance",cost:"30x...100x",color:"from-red-500 to-orange-400"}],r=250;return s.jsxs("section",{className:"relative bg-dark pt-10 sm:pt-20 pb-10 px-4 mt-5 sm:mt-10",children:[s.jsx("div",{className:"max-w-6xl mx-auto mt-5 sm:mt-10",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 lg:gap-20",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},className:"order-2 lg:order-1",children:[s.jsxs("h2",{id:"error-cost-title",className:"text-2xl sm:text-3xl lg:text-4xl font-bold mb-4 sm:mb-6 leading-tight pt-6",children:[s.jsx("span",{className:"text-white",children:((S=e.title)==null?void 0:S.before)||'"El costo de un error tras despliegue es '}),s.jsx("span",{className:"text-red-500",children:((T=e.title)==null?void 0:T.highlight)||"10 veces mayor"}),s.jsx("span",{className:"text-white",children:((P=e.title)==null?void 0:P.after)||' al de prevenirlo."'})]}),s.jsx("p",{className:"text-gray-300 mb-6 sm:mb-8 leading-relaxed text-sm sm:text-base",children:e.description||"Cada actualización de Salesforce sin certificar es un riesgo inaceptable para tu operación. Los errores silenciosos en integraciones y flujos destruyen la confianza del usuario y el ROI de tu inversión."}),s.jsx("div",{className:"space-y-2 sm:space-y-3",children:n.map((M,C)=>s.jsxs(_.div,{id:`error-cost-risk-${C+1}`,initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:C*.1},className:"flex items-start gap-2 sm:gap-3 p-2 sm:p-4 rounded-lg border border-red-500/30 bg-red-500/5 hover:bg-red-500/10 transition-colors",children:[s.jsx("div",{className:"text-red-500 text-lg sm:text-xl flex-shrink-0 mt-0.5",children:s.jsx("svg",{className:"w-4 h-4 sm:w-5 sm:h-5",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})})}),s.jsx("span",{className:"text-white font-medium text-xs sm:text-sm",children:M.title})]},C))})]}),s.jsxs(_.div,{initial:{opacity:0,x:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},className:"p-4 sm:p-8 rounded-lg from-primary/5 to-primary/10 order-1 lg:order-2",children:[s.jsx("h2",{className:"text-base sm:text-lg lg:text-lg mb-6 sm:mb-8 leading-tight pb-10 mt-5",children:a.subtitle}),s.jsxs("div",{id:"error-cost-chart",className:"grid grid-cols-5 gap-0.5 sm:gap-1 pt-5",children:[s.jsx("div",{className:"flex items-end justify-center gap-1 sm:gap-2 h-40 sm:h-50 mb-2 relative col-span-5",children:i.map((M,C)=>s.jsx(_.div,{initial:{height:0,opacity:0},whileInView:{height:`${(C+1)/i.length*r}px`,opacity:1},viewport:{once:!0},transition:{duration:.1,delay:C*.1},className:`flex-1 rounded-t-lg bg-gradient-to-t ${M.color} shadow-lg relative group cursor-pointer transition-all duration-300 hover:shadow-2xl hover:scale-115 hover:brightness-115`,whileHover:{y:-12},children:s.jsx("div",{className:"absolute top-1 left-1/2 transform -translate-x-1/2 text-white font-bold text-xs sm:text-md",children:M.cost})},C))}),i.map((M,C)=>s.jsx(_.div,{initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:C*.1},className:"text-center",children:s.jsx("p",{className:"text-gray-100 text-xs font-medium break-words",children:M.label})},`label-${C}`))]}),s.jsx("div",{className:"flex justify-center mb-4 sm:mb-6 mt-3 sm:mt-5",children:s.jsxs("div",{className:"w-full flex items-center gap-2",children:[s.jsx("div",{className:"flex-1 h-1 bg-gray-200"}),s.jsx("span",{className:"text-gray-200 text-xs whitespace-nowrap",children:a.ciclos})]})}),s.jsx("p",{className:"text-xs sm:text-sm text-gray-100 text-left",children:a.message})]})]})}),s.jsx(ie,{variant:1})]})}function hee(){const{t}=$(),e=t("home.testimonials",{returnObjects:!0}),[a,n]=k.useState(0);k.useEffect(()=>{const o=setInterval(()=>{n(l=>l===e.items.length-1?0:l+1)},5e3);return()=>clearInterval(o)},[e.items.length]);const i=()=>{n(o=>o===0?e.items.length-1:o-1)},r=()=>{n(o=>o===e.items.length-1?0:o+1)};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark",children:[s.jsx("div",{className:"py-20 px-4",children:s.jsxs("div",{className:"max-w-6xl mx-auto text-center",children:[s.jsx(_.h2,{id:"testimonials-title",initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center text-2xl uppercase tracking-wider text-primary mb-3 whitespace-pre-line",children:e.title}),s.jsxs(_.h2,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:1.2,delay:.1},className:"mt-5 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e.subtitle,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsxs("div",{className:"relative mt-10 text-left",children:[s.jsxs(_.div,{id:"testimonials-card",initial:{opacity:0,x:100}
3702,animate:{opacity:1,x:0},exit:{opacity:0,x:-100},transition:{duration:.5},className:"relative bg-gradient-to-br from-slate-800/50 to-slate-900/30 backdrop-blur-sm border border-primary/30 rounded-2xl p-8 lg:p-12 shadow-2xl",children:[s.jsx("div",{className:"absolute top-6 left-6 text-primary/20 text-6xl font-serif",children:'"'}),s.jsxs("div",{className:"relative z-10 pt-8",children:[s.jsx("p",{className:"text-gray-200 text-lg lg:text-xl leading-relaxed mb-8 italic whitespace-pre-line",children:e.items[a].text}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("img",{id:"testimonials-author-image",src:`/imagenes/testimonios/${e.items[a].author.split(" ")[0]}.jpeg`,alt:e.items[a].author,className:"w-12 h-12 rounded-full object-cover border-2 border-primary/40"}),s.jsxs("div",{children:[s.jsx("p",{className:"text-white font-semibold",children:e.items[a].author}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.items[a].position}),s.jsx("p",{className:"text-primary text-sm",children:e.items[a].company})]})]})]}),s.jsx("div",{className:"absolute bottom-6 right-6 text-primary/10 text-6xl font-serif rotate-180",children:'"'})]},a),s.jsxs("div",{className:"flex justify-center items-center gap-4 mt-8",children:[s.jsx("button",{id:"testimonials-prev-button",onClick:i,className:"w-12 h-12 rounded-full border-2 border-primary/40 text-primary hover:bg-primary hover:text-dark transition-all duration-300 flex items-center justify-center","aria-label":"Anterior",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),s.jsx("div",{className:"flex gap-2",children:e.items.map((o,l)=>s.jsx("button",{id:`testimonials-indicator-${l+1}`,onClick:()=>n(l),className:`h-2 rounded-full transition-all duration-300 ${l===a?"w-8 bg-primary":"w-2 bg-gray-600 hover:bg-gray-500"}`,"aria-label":`Ir al testimonio ${l+1}`},l))}),s.jsx("button",{id:"testimonials-next-button",onClick:r,className:"w-12 h-12 rounded-full border-2 border-primary/40 text-primary hover:bg-primary hover:text-dark transition-all duration-300 flex items-center justify-center","aria-label":"Siguiente",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]})]})]})}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function fee(){const{t}=$(),e=t("home.clients.title"),a=t("home.clients.description"),n={logos:[{id:1,name:"",image:"/imagenes/home/logo_abastible.png",alt:"Abastible"},{id:2,name:"",image:"/imagenes/home/logo_walmart.png",alt:"Walmart"},{id:3,name:"",image:"/imagenes/home/logo_cencosud.png",alt:"Cencosud"},{id:4,name:"Consorcio",image:"/imagenes/home/logo_falabella.png",alt:"Falabella"},{id:5,name:"",image:"/imagenes/home/logo_casaideas.png",alt:"Casa Ideas"},{id:6,name:"",image:"/imagenes/home/logo_wom.png",alt:"Wom"},{id:7,name:"",image:"/imagenes/home/log_bupa.png",alt:"Bupa"},{id:8,name:"",image:"/imagenes/home/logo_ikea.png",alt:"Ikea"},{id:9,name:"",image:"/imagenes/home/logo_colmena.png",alt:"Colmena"},{id:10,name:"",image:"/imagenes/home/logo_consorcio.png",alt:"Colmena"},{id:11,name:"",image:"/imagenes/home/logo_continuum.png",alt:"Continuum"},{id:12,name:"",image:"/imagenes/home/logo_melt.png",alt:"Melt"},{id:13,name:"",image:"/imagenes/home/logo_parque.png",alt:"Parque Arauco"},{id:14,name:"",image:"/imagenes/home/logo_scotiabank.png",alt:"Scotiabank"},{id:15,name:"",image:"/imagenes/home/logo_security.png",alt:"Security"},{id:16,name:"",image:"/imagenes/home/logo_spartan.png",alt:"Spartan"},{id:17,name:"",image:"/imagenes/home/logo_vida_security.png",alt:"Vida Security"}]},[i,r]=k.useState(0),o=4;k.useEffect(()=>{const c=setInterval(()=>{r(d=>{const u=d+o;return u>=n.logos.length?0:u})},3e3);return()=>clearInterval(c)},[n.logos.length]);const l=n.logos.slice(i,i+o);return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-hidden",children:[s.jsx("div",{className:"py-20 px-4 mt-9",children:s.jsxs("div",{className:"max-w-7xl mx-auto text-center mt-10",children:[s.jsxs(_.h1,{id:"clients-title",initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"mt-5 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsxs("div",{id:"clients-carousel",className:"relative mt-10 pt-10",children:[s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0}
3702,animate:{opacity:1},exit:{opacity:0},transition:{duration:.8,ease:"easeInOut"},className:"grid grid-cols-2 md:grid-cols-4 gap-8 lg:gap-12",children:l.map((c,d)=>s.jsx(_.div,{id:`clients-logo-${c.id}`,initial:{opacity:0,y:20,scale:.96},animate:{opacity:1,y:0,scale:1},transition:{type:"spring",stiffness:120,damping:22,delay:d*.1},whileHover:{scale:1.03},className:"flex items-center justify-center p-6 rounded-xl bg-slate-800/30 border border-primary/10 hover:border-primary/30 group",children:s.jsx("div",{className:"relative w-full h-20 flex items-center justify-center",children:s.jsx("img",{src:c.image,alt:c.alt,loading:"lazy",decoding:"async",width:"250",height:"150",className:"max-w-full max-h-full object-contain transition-all duration-300 opacity-90 group-hover:opacity-100 group-hover:scale-150"})})},c.id))},i)}),s.jsx("div",{className:"flex justify-center gap-2 mt-8",children:Array.from({length:Math.ceil(n.logos.length/o)}).map((c,d)=>s.jsx("button",{onClick:()=>r(d*o),className:`h-2 rounded-full transition-all duration-300 ${Math.floor(i/o)===d?"w-8 bg-primary":"w-2 bg-gray-600 hover:bg-gray-500"}`,"aria-label":`Ir al grupo ${d+1}`},d))})]}),s.jsx(_.p,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.8},className:"text-center text-gray-200 mt-12 max-w-2xl mx-auto",children:a})]})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}const gee="https://calendar.app.google/dkJfuj7MNARbfT5HA";function yee(){const{t}=$(),e=t("partners",{returnObjects:!0}),a=t("badges",{returnObjects:!0}),n=()=>{window.open(gee,"_blank","width=1000,height=700")},i={logos:[{id:1,name:"XRAY Partner",image:"/imagenes/XrayPartner.webp",alt:"XRAY Partner - Haka Lab"}]};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-darkpx-4",children:[s.jsxs("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 pt-16 pb-16",children:[s.jsxs(_.h2,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-3xl md:text-4xl font-extrabold text-white text-center mb-2 uppercase tracking-tight",children:[s.jsx("span",{className:"text-primary",children:"ALIANZAS"})," ESTRATÃGICAS"]}),s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mx-auto mb-10"}),s.jsxs("div",{className:"flex flex-wrap justify-center items-center gap-10 md:gap-16 mb-8",children:[s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.1},src:"/imagenes/logo chiletec.png",alt:"ChileTec",className:"h-20 md:h-28 object-contain"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},src:"/imagenes/logo_ccs_2025.png",alt:"CCS 2025",className:"h-20 md:h-28 object-contain"})]}),s.jsx(_.p,{initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.3},className:"text-center text-gray-300 text-lg max-w-3xl mx-auto leading-relaxed",children:"Formamos parte de las instituciones más relevantes del ecosistema empresarial y tecnológico de Chile, garantizando innovación y confianza en cada proyecto de QA"})]}),s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[400px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-1 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx(Lg,{text:a.partners}),s.jsx("h1",{id:"partners-title",className:"text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight mt-4",itemProp:"headline",children:e.titulo}),s.jsx("h1",{id:"partners-title-2",class:"text-3xl md:text-6xl font-extrabold text-primary leading-tight uppercase tracking-tight",children:e.titulo2}),s.jsxs("h1",{id:"partners-title-3",class:"text-2xl md:text-2xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e.titulo3,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto md:mx-0"})]}),s.jsx("p",{id:"partners-subtitle",className:"text-xl text-white font-normal max-w-lg leading-relaxed mt-10",itemProp:"description",children:e.subt
3702itulo}),s.jsx("div",{className:"flex flex-col sm:flex-row justify-center lg:justify-start gap-4 w-full sm:w-auto mt-10"})]}),s.jsx("div",{className:"flex justify-center items-center mt-0 lg:mt-0",children:s.jsx("div",{className:"flex flex-col md:flex-row items-right justify-center gap-8 sm:gap-10 md:gap-16 lg:gap-20",children:i.logos.map((r,o)=>s.jsx(_.div,{id:`partners-logo-${r.id}`,initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:o*.2},className:"w-full max-w-xs md:max-w-none md:w-auto flex items-center justify-center",children:s.jsx("div",{className:"relative w-full md:w-72 lg:w-80 h-48 sm:h-80 md:h-96 flex items-center justify-center p-6 transition-all duration-300 hover:scale-145 group",children:s.jsx("img",{src:r.image,alt:r.alt,loading:"lazy",decoding:"async",width:"324",height:"176",className:"max-w-full max-h-full object-contain filter brightness-90 group-hover:brightness-110 transition-all duration-300"})})},r.id))})})]})})]}),s.jsx("div",{className:"flex justify-center pb-16",children:s.jsx("button",{id:"partners-schedule-button",onClick:n,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:e.conversemos})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}const pj="https://hakalab.com";function Xa({title:t,description:e,path:a="/",image:n,type:i="website"}){const r=t?`${t} | HakaLab`:"HakaLab - Testing con IA, Automatización QA y Certificación Salesforce en Chile",o=`${pj}${a}`,l=n||`${pj}/imagenes/og-image.png`;return s.jsxs(gP,{children:[s.jsx("title",{children:r}),s.jsx("meta",{name:"description",content:e}),s.jsx("link",{rel:"canonical",href:o}),s.jsx("link",{rel:"alternate",hreflang:"es",href:o}),s.jsx("link",{rel:"alternate",hreflang:"x-default",href:o}),s.jsx("meta",{property:"og:type",content:i}),s.jsx("meta",{property:"og:url",content:o}),s.jsx("meta",{property:"og:title",content:r}),s.jsx("meta",{property:"og:description",content:e}),s.jsx("meta",{property:"og:image",content:l}),s.jsx("meta",{property:"og:locale",content:"es_CL"}),s.jsx("meta",{property:"og:site_name",content:"HakaLab"}),s.jsx("meta",{name:"twitter:card",content:"summary_large_image"}),s.jsx("meta",{name:"twitter:url",content:o}),s.jsx("meta",{name:"twitter:title",content:r}),s.jsx("meta",{name:"twitter:description",content:e}),s.jsx("meta",{name:"twitter:image",content:l}),s.jsx("meta",{name:"twitter:creator",content:"@hakalab"})]})}function xee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Testing con IA, Automatización QA y Certificación Salesforce en Chile",description:"HakaLab es lÃder en Chile en testing automatizado con inteligencia artificial. Acelera tu ciclo de pruebas hasta un 70% con herramientas de IA para QA.",path:"/"}),s.jsx(oee,{}),s.jsx(mee,{}),s.jsx(uee,{}),s.jsx(pee,{}),s.jsx(hee,{}),s.jsx(fee,{}),s.jsx(yee,{})]})}function vee(){const{isOpen:t,modalTitle:e,openModal:a,closeModal:n}=oa(),{t:i}=$();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{className:"relative bg-dark pt-12",children:[s.jsx("div",{className:"hero-glow-head"}),s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-20 text-center",children:[s.jsx("h1",{id:"servicios-hero-title",className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white",itemProp:"headline",children:i("servicios.titulo")}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mx-auto"}),s.jsx("p",{className:"mt-5 text-center text-md sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:i("servicios.descripcion")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("button",{id:"servicios-contacto-button",onClick:()=>a(i("contactModal.title")),className:"border-2 border-primary text-primary px-6 sm:px-8 md:px-8 py-2 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all","aria-label":i("servicios.contactanos"),children:i("servicios.contactanos")})})]}),s.jsx(ie,{variant:1})]}),s.jsx(Yr,{isOpen:t,onClose:n,title:e})]})}function bee(){const{t}=$(),e=t("servicios.performance",{returnObjects:!0});return s.jsx("section",{id:"home",className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-x-hidden",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:s.jsx("div",{className:"relative py-16 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden",children:s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsx("div",{className:"flex justify-center items-center mt-8 lg:mt-0 lg:text-left",children:s.jsx("img",{src:"/imagenes/performance.png",alt:"Equipo HakaLab - Soluciones tecnológicas innovadoras",className:"w-1/2 sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})}),s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h2",{id:"servicios-performance-title",className:"mt-5 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"text-md sm:text-base lg:text-lg text-gray-100 mb-6 sm:mb-8 leading-relaxed font-light mt-5",itemProp:"description",children:e.subt
3702itle}),s.jsx("div",{className:"mb-8 sm:mb-10 space-y-4",children:e.features.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:n*.1},className:"flex items-start gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-sm sm:text-base text-gray-200 leading-relaxed text-left",children:a})]},n))})]})]})})})})}const Wh=360/7,Gh=-90,mj=[{label:"Planificación",color:"#1e3a8a"},{label:"Diseño",color:"#1e40af"},{label:"Desarrollo",color:"#0369a1"},{label:"Testing",color:"#0891b2"},{label:"Despliegue",color:"#0e7490"},{label:"Revisión",color:"#155e75"},{label:"Lanzamiento",color:"#164e63"}].map((t,e)=>({...t,startAngle:Gh+Wh*e,endAngle:Gh+Wh*(e+1)})),_s=[{id:0,label:"Análisis de requerimientos",color:"#059669",inactiveColor:"#1e3a8a"},{id:1,label:"Diseño pruebas",color:"#0d9488",inactiveColor:"#1e40af"},{id:2,label:"Construcción",color:"#06b6d4",inactiveColor:"#2563eb"},{id:3,label:"Ejecución",color:"#0284c7",inactiveColor:"#3b82f6"},{id:4,label:"CI/CD",color:"#7c3aed",inactiveColor:"#1d4ed8"},{id:5,label:"Resultados",color:"#db2777",inactiveColor:"#0369a1"},{id:6,label:"Métricas Productivas",color:"#f59e0b",inactiveColor:"#0284c7"}].map((t,e)=>({...t,startAngle:Gh+Wh*e,endAngle:Gh+Wh*(e+1)}));function Pr(t){return t*Math.PI/180}function z0(t,e,a,n,i,r,o,l,c,d=!1,u=null){const p=Pr(r),m=Pr(o),g=i+(c&&d?8:0),y=n-(c&&d?2:0);t.save(),t.beginPath(),t.arc(e,a,g,p,m),t.arc(e,a,y,m,p,!0),t.closePath(),c&&d?t.fillStyle="#06b6d4":c&&!d?(t.fillStyle=l,t.globalAlpha=1):d&&u?(t.fillStyle=u,t.globalAlpha=.5):d?t.fillStyle=l:(t.fillStyle=l,t.globalAlpha=.3),t.fill(),t.restore()}function wee(t,e,a,n,i,r,o){const c=i+8,d=n-2,u=Pr(r),p=Pr(o),m=(d+c)/2,g=(c-d)*.9/m,y=Pr(o),x=y+g,v=Math.cos(x)*m+e,w=Math.sin(x)*m+a,S=Math.cos(y)*(c-1)+e,T=Math.sin(y)*(c-1)+a,P=Math.cos(y)*(d+1)+e,M=Math.sin(y)*(d+1)+a;t.save(),t.beginPath(),t.arc(e,a,c,u,p),t.lineTo(S,T),t.lineTo(v,w),t.lineTo(P,M),t.arc(e,a,d,p,u,!0),t.closePath(),t.strokeStyle="#22d3ee",t.lineWidth=2,t.shadowColor="#22d3ee",t.shadowBlur=20,t.stroke(),t.restore()}function kee(t,e,a,n,i,r,o,l,c){const d=Pr((r+o)/2),u=(n+i)/2,p=Math.cos(d)*u+e,m=Math.sin(d)*u+a;t.save(),t.translate(p,m),t.fillStyle="white",t.font=`${c}px sans-serif`,t.textAlign="center",t.textBaseline="middle",t.fillText(l,0,0),t.restore()}function hj(t,e,a,n,i,r,o,l,c=!1,d=null){const p=i+8,m=n-2,h=(m+p)/2,y=(p-m)*.9/h,x=Pr(r),v=x+y,w=Math.cos(v)*h+e,S=Math.sin(v)*h+a,T=Math.cos(x)*(p-1)+e,P=Math.sin(x)*(p-1)+a,M=Math.cos(x)*(m+1)+e,C=Math.sin(x)*(m+1)+a;t.save(),t.beginPath(),t.moveTo(w,S),t.lineTo(T,P),t.lineTo(M,C),t.closePath(),t.fillStyle="#06b6d4",t.fill(),t.restore()}function See(t,e,a,n,i,r,o){const l=Pr(i),c=n+35,d=Math.cos(l)*c+e,u=Math.sin(l)*c+a;t.save(),t.font=`${o?"bold ":""}14px sans-serif`,t.textAlign="center",t.textBaseline="middle";const h=t.measureText(r).width+14*2,g=28;o?(t.fillStyle="#0f172a",t.strokeStyle="#06b6d4",t.lineWidth=2):(t.fillStyle="rgba(15,23,42,0.6)",t.strokeStyle="rgba(148,163,184,0.3)",t.lineWidth=1);const y=g/2;t.beginPath(),t.moveTo(d-h/2+y,u-g/2),t.lineTo(d+h/2-y,u-g/2),t.arc(d+h/2-y,u,y,-Math.PI/2,Math.PI/2),t.lineTo(d-h/2+y,u+g/2),t.arc(d-h/2+y,u,y,Math.PI/2,-Math.PI/2),t.closePath(),t.fill(),t.stroke(),t.fillStyle=o?"#06b6d4":"#cbd5e1",t.fillText(r,d,u),t.restore()}function Og({showIntro:t=!0,light:e=!1}={}){const{t:a}=$(),n=a("servicios.agileCycle",{returnObjects:!0}),i=k.useRef(null),[r,o]=k.useState(0),[l,c]=k.useState(!0),d=n.devStages||[],u=n.qaStages||[],p=n.centerText||{line1:"",line2:""};k.useEffect(()=>{if(!l)return;const y=setInterval(()=>o(x=>(x+1)%_s.length),4e3);return()=>clearInterval(y)},[l]);const m=y=>{c(!1),o(y),setTimeout(()=>c(!0),8e3)},h=k.useCallback(()=>{const y=i.current;if(!y)return;const x=y.getContext("2d"),v=y.width,w=y.height,S=v/2,T=w/2,P=v*.34,M=v*.245,C=v*.225,E=v*.15;
3702x.clearRect(0,0,v,w),_s.forEach(N=>{z0(x,S,T,M,P,N.startAngle,N.endAngle,N.color,N.id===r,!0,N.inactiveColor)});const j=_s[r];hj(x,S,T,M,P,j.endAngle,j.color,!0,!0,j.inactiveColor),z0(x,S,T,M,P,j.startAngle,j.endAngle,j.color,!0,!0,j.inactiveColor),hj(x,S,T,M,P,j.endAngle,j.color,!0,!0,j.inactiveColor),wee(x,S,T,M,P,j.startAngle,j.endAngle),x.save(),x.beginPath(),x.arc(S,T,M-1,0,Math.PI*2),x.fillStyle="transparent",x.fill(),x.restore(),mj.forEach((N,L)=>{const O=L===r;z0(x,S,T,E,C,N.startAngle,N.endAngle,N.color,O,!1)}),mj.forEach((N,L)=>{const O=d[L]||N.label;kee(x,S,T,E,C,N.startAngle,N.endAngle,O,v*.018)}),x.save(),x.beginPath(),x.arc(S,T,E-1,0,Math.PI*2),x.fillStyle="transparent",x.fill(),x.restore(),x.save(),x.fillStyle="#94a3b8",x.font=`${v*.022}px sans-serif`,x.textAlign="center",x.textBaseline="middle",x.fillText(p.line1,S,T-v*.03),x.fillText(p.line2,S,T+v*.01),x.restore(),_s.forEach((N,L)=>{var G;const O=(N.startAngle+N.endAngle)/2,R=((G=u[L])==null?void 0:G.label)||N.label;See(x,S,T,P,O,R,N.id===r)})},[r,d,u,p]);k.useEffect(()=>{h()},[h]);const g=y=>{const x=i.current;if(!x)return;const v=x.getBoundingClientRect(),w=x.width/v.width,S=x.height/v.height,T=(y.clientX-v.left)*w,P=(y.clientY-v.top)*S,M=x.width/2,C=x.height/2,E=x.width,j=E*.34,N=E*.245,L=T-M,O=P-C,R=Math.sqrt(L*L+O*O);if(R<N||R>j)return;let G=Math.atan2(O,L)*180/Math.PI;G<0&&(G+=360),_s.forEach(ee=>{let ke=(ee.startAngle%360+360)%360,ae=(ee.endAngle%360+360)%360;(ke<ae?G>=ke&&G<=ae:G>=ke||G<=ae)&&m(ee.id)})};return s.jsxs("div",{className:"relative w-full max-w-7xl mx-auto py-8",children:[t&&s.jsx("div",{className:"text-center mb-8 max-w-4xl mx-auto",children:s.jsx("p",{className:"text-gray-100 text-lg leading-relaxed",children:n.introText})}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-5 gap-8 items-center",children:[s.jsxs("div",{className:"lg:col-span-3 relative w-full aspect-square mx-auto",children:[s.jsx("p",{className:"text-gray-300 text-sm text-center leading-relaxed -mb-20",children:"Ciclo de vida de calidad del software"}),s.jsx("canvas",{ref:i,width:900,height:900,className:"w-full h-full cursor-pointer",onClick:g})]}),s.jsx("div",{className:"lg:col-span-2 flex flex-col justify-center h-full",children:s.jsxs("div",{className:"space-y-5",children:[s.jsx(La,{mode:"wait",children:s.jsxs(_.div,{initial:{opacity:0,x:30},animate:{opacity:1,x:0},exit:{opacity:0,x:-30},transition:{duration:.3},className:"bg-white/5 backdrop-blur rounded-2xl p-7 border border-cyan-400/40 shadow-xl",children:[s.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[s.jsx("div",{className:"bg-gradient-to-br from-cyan-400 to-blue-600 text-white font-bold text-lg w-11 h-11 rounded-full flex items-center justify-center flex-shrink-0",children:String(r+1).padStart(2,"0")}),s.jsx("h3",{className:"text-lg font-bold text-white leading-tight",children:u[r].fullName})]}),s.jsx("p",{className:"text-gray-300 text-sm leading-relaxed mb-6",children:u[r].description}),(r===0||r===1)&&s.jsx("div",{className:"flex justify-center pt-4 border-t border-white/10",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost",className:"h-8 opacity-70"})}),r===2&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/hakapath_logo.png",alt:"Hakapath",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/haka_mobile_recorder_logo.png",alt:"Haka Mobile Recorder",className:"h-16 sm:h-20 opacity-80"})]}),r===3&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/haka_mobile_recorder_logo.png",alt:"Haka Mobile Recorder",className:"h-16 sm:h-20 opacity-80"})]}
3702),r===4&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"})]}),r===5&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/cassini_logo.png",alt:"Cassini",className:"h-14 sm:h-16 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/haka_mobile_recorder_logo.png",alt:"Haka Mobile Recorder",className:"h-16 sm:h-20 opacity-80"})]})]},r)}),s.jsx("div",{className:"flex gap-2 items-center",children:_s.map(y=>s.jsx("button",{onClick:()=>m(y.id),className:`h-2 rounded-full transition-all duration-300 ${r===y.id?"bg-cyan-400 w-8":"bg-gray-600 hover:bg-gray-400 w-3"}`},y.id))})]})})]})]})}function _ee(){const{t}=$(),e=t("servicios.continuos",{returnObjects:!0}),a=t("servicios.services",{returnObjects:!0}),n=k.useRef(null),{scrollYProgress:i}=zU({target:n,offset:["start end","end start"]}),r=IR(i,[.2,.8],["0%","100%"]);return s.jsxs("section",{ref:n,className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-x-clip",children:[s.jsx("div",{className:"relative py-16 sm:py-20 md:py-24 mt-10",children:s.jsxs("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full text-center",children:[s.jsx("h1",{id:"servicios-continuos-title",className:"mt-1 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:e.title}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mx-auto"}),s.jsx("p",{className:"mt-6 text-center text-md sm:text-base lg:text-xl text-gray-200 mb-2 sm:mb-2 leading-relaxed font-light",children:e.subt
3702itle}),s.jsx("div",{className:"mb-16 sm:mb-20",children:s.jsx(Og,{})}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 text-left",children:[s.jsx("div",{className:"lg:col-span-7 space-y-8",children:a.map((o,l)=>s.jsxs(_.div,{id:`servicios-continuos-card-${l+1}`,initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},viewport:{once:!0,margin:"-100px"},transition:{duration:.6,delay:l*.2},className:"p-6 sm:p-8 rounded-lg bg-primary/10 border border-primary/20 hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-primary/25",children:[s.jsx("h3",{className:"text-xl sm:text-2xl mb-3 text-primary leading-snug",children:o.title}),s.jsx("p",{className:"text-gray-200 text-sm sm:text-base mb-6 leading-relaxed",children:o.description}),l===0?s.jsxs("a",{href:"/salesforce-testing",className:"inline-flex items-center gap-2 px-6 py-3 bg-cyan-400 hover:bg-cyan-500 text-dark font-semibold rounded-lg transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50",children:["Conocer más del servicio",s.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M17 8l4 4m0 0l-4 4m4-4H3"})})]}):o.features&&s.jsx("div",{className:"space-y-3",children:o.features.map((c,d)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:d*.1},className:"flex items-start gap-3",children:[s.jsx("svg",{className:"w-5 h-5 text-primary flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-sm text-gray-200 leading-relaxed",children:c})]},d))})]},o.id))}),s.jsx("div",{className:"hidden lg:block lg:col-span-5 relative",children:s.jsxs("div",{className:"sticky top-24 h-fit",children:[s.jsx("div",{className:"absolute left-8 top-0 w-1 h-full bg-primary/20 rounded-full"}),s.jsx(_.div,{className:"absolute left-8 top-0 w-1 bg-primary rounded-full origin-top",style:{height:r}}),s.jsx("div",{className:"space-y-32 pl-20",children:a.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:20},whileInView:{opacity:1,x:0},viewport:{once:!0,margin:"-150px"},transition:{duration:.6,delay:.3},className:"relative",children:[s.jsx(_.div,{initial:{scale:0},whileInView:{scale:1},viewport:{once:!0,margin:"-150px"},transition:{duration:.4,delay:.2},className:"absolute -left-[52px] top-2 w-6 h-6 rounded-full bg-primary border-4 border-dark shadow-lg shadow-primary/50"}),s.jsxs("div",{className:"bg-gradient-to-br from-primary/20 to-primary/5 border border-primary/30 rounded-lg p-6 backdrop-blur-sm",children:[s.jsxs("div",{className:"flex items-start gap-3 mb-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0 mt-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),s.jsx("h4",{className:"text-lg font-semibold text-primary",children:"Beneficio Clave"})]}),s.jsx("p",{className:"text-gray-200 text-sm leading-relaxed",children:o.benefit})]})]},o.id))})]})})]})]})}),s.jsx(ie,{color:"#0a0d29f5",variant:2})]})}function Aee(){const{t}=$(),e=t("servicios.data",{returnObjects:!0});return s.jsxs("section",{id:"home",className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-x-clip",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsx("div",{className:"relative py-16 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden",children:s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsx("div",{className:"flex justify-center items-center mt-8 lg:mt-0 lg:text-left",children:s.jsx("img",{src:"/imagenes/datatesting.png",alt:"Equipo HakaLab - Soluciones tecnológicas innovadoras",className:"w-1/2 sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})}),s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h2",{id:"servicios-data-title",className:"mt-1 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"text-sm sm:text-base lg:text-lg text-gray-200 mb-6 sm:mb-8 leading-relaxed font-light mt-5",itemProp:"description",children:e.subt
3702itle}),s.jsx("div",{className:"mb-8 sm:mb-10 space-y-4",children:e.features.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:n*.1},className:"flex items-start gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-sm sm:text-base text-gray-200 leading-relaxed text-left",children:a})]},n))})]})]})})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function Eee(){const{t}=$(),[e,a]=k.useState(null),n=t("faqServicios",{returnObjects:!0}),i=n.items||[],r=l=>{a(e===l?null:l)},o={"@context":"https://schema.org","@type":"FAQPage",mainEntity:i.map(l=>{var c;return{"@type":"Question",name:l.question,acceptedAnswer:{"@type":"Answer",text:`${l.answer} ${(c=l.details)==null?void 0:c.join(" ")}`}}})};return s.jsxs("section",{className:"bg-dark py-20 sm:py-24 md:py-28 px-4",children:[s.jsx(gP,{children:s.jsx("script",{type:"application/ld+json",children:JSON.stringify(o)})}),s.jsxs("div",{className:"max-w-4xl mx-auto",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-white mb-5",children:n.titulo}),s.jsx("p",{className:"text-gray-400 text-lg max-w-2xl mx-auto leading-relaxed",children:n.subtitulo})]}),s.jsx("div",{className:"space-y-4",children:i.map((l,c)=>s.jsxs(_.div,{initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.4,delay:c*.05},className:"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden hover:border-slate-600 transition-colors",children:[s.jsxs("button",{onClick:()=>r(c),className:"w-full flex items-center justify-between p-6 text-left hover:bg-slate-700/20 transition-colors","aria-expanded":e===c,children:[s.jsx("span",{className:"text-white font-semibold text-base sm:text-lg pr-4 leading-snug",children:l.question}),s.jsx(_.span,{animate:{rotate:e===c?180:0},transition:{duration:.3},className:"text-primary flex-shrink-0",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})})]}),s.jsx(La,{children:e===c&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsxs("div",{className:"px-6 pb-6 pt-2 space-y-4 border-t border-slate-700/50",children:[s.jsx("p",{className:"text-gray-200 text-base leading-relaxed font-medium",children:l.answer}),l.details&&l.details.length>0&&s.jsx("ul",{className:"space-y-3 pl-1",children:l.details.map((d,u)=>s.jsxs("li",{className:"flex items-start gap-3",children:[s.jsx("span",{className:"text-primary mt-1.5 flex-shrink-0",children:s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",clipRule:"evenodd"})})}),s.jsx("span",{className:"text-gray-300 text-sm leading-relaxed",children:d})]},u))}),l.highlight&&s.jsx("div",{className:"pt-2",children:s.jsxs("span",{className:"inline-flex items-center gap-2 px-4 py-2 bg-primary/10 border border-primary/30 rounded-full text-primary text-sm font-semibold",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z",clipRule:"evenodd"})}),l.highlight]})})]})})})]},c))})]})]})}function Cee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Servicios de Testing Automatizado y QA en Chile",description:"Empresa lÃder en Quality Assurance (QA) en Chile. Testing automatizado, performance testing, certificación Salesforce y SAP, consultorÃa QA. Más de 10 años de experiencia con empresas Fortune 500.",path:"/servicios"}),s.jsx(vee,{}),s.jsx(_ee,{}),s.jsx(bee,{}),s.jsx(Aee,{}),s.jsx(Eee,{})]})}function jee(){const{t}=$(),e=t("nosotros.hero",{returnObjects:!0}),{isOpen:a,modalTitle:n,openModal:i,closeModal:r}=oa();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{id:"home",className:"relative bg-dark",
3702itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[400px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow-head"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h1",{className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"mt-10 text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light",itemProp:"description",children:e.subtitle}),s.jsx("div",{className:"flex justify-center lg:justify-start",children:s.jsx("button",{onClick:()=>i(t("contactModal.title")),className:"border-2 border-primary text-primary px-6 sm:px-8 md:px-8 py-2 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all","aria-label":t("nav.contacto"),children:e.cta})})]}),s.jsx("div",{className:"flex justify-center items-center mt-2 lg:mt-0",children:s.jsx("img",{src:"/imagenes/animado.gif",alt:t("common.altEquipoHakalab"),className:"w-1/2 sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})})]})})]}),s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-10 md:py-10",children:[s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.identidad.intro")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.koru.descripcion")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.kai.descripcion")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.haka.conclusion")})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsx(Yr,{isOpen:a,onClose:r,title:n})]})}function Tee(){const{t}=$(),e={image:"/imagenes/nosotros_caracteristicas.png",left:[{id:"esencia",title:t("nosotros.caracteristicas.esencia.title"),description:t("nosotros.caracteristicas.esencia.description"),icon:"/imagenes/nosotros_esencia.png"},{id:"vision",title:t("nosotros.caracteristicas.vision.title"),description:t("nosotros.caracteristicas.vision.description"),icon:"/imagenes/nosotros_vision.png"}],right:[{id:"mision",title:t("nosotros.caracteristicas.mision.title"),description:t("nosotros.caracteristicas.mision.description"),icon:"/imagenes/nosotros_mision.png"},{id:"compromiso",title:t("nosotros.caracteristicas.compromiso.title"),description:t("nosotros.caracteristicas.compromiso.description"),icon:"/imagenes/nosotros_compromiso.png"}]};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark py-16 sm:py-20 md:py-24",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-9",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-10 items-center",children:[s.jsx("div",{className:"lg:col-span-4 space-y-8 sm:space-y-12 mt-5",children:e.left.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:n*.2},className:"text-left lg:text-right",children:[s.jsx("div",{className:"flex lg:justify-end mb-4",children:s.jsx("img",{src:a.icon,alt:a.title,className:"w-12 h-12 sm:w-16 sm:h-16",loading:"lazy"})}),s.jsx("h3",{className:"text-xl sm:text-2xl font-semibold text-primary mb-3",children:a.title}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:a.description})]},a.id))}),s.jsx("div",{className:"lg:col-span-4 flex justify-center items-center my-6 lg:my-0 w-full",children:s.jsx(_.div,{className:"flex justify-center w-full",initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.8,delay:.3},children:s.jsx("img",{src:e.image,alt:"Personajes HakaLab",className:"w-2/3 sm:max-w-lg lg:max-w-lg h-auto drop-shadow-2xl object-contain mx-auto",loading:"lazy"})})}),s.jsx("div",{className:"lg:col-span-4 space-y-6 sm:space-y-10 lg:mt-5 sm:mt-0",children:e.right.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:n*.2},className:"text-left",children:[s.jsx("div",{className:"flex justify-start mb-4",children:s.jsx("img",{src:a.icon,alt:a.title,className:"w-12 h-12 sm:w-16 sm:h-16",loading:"lazy"})}),s.jsx("h3",{className:"text-xl sm:text-2xl font-semibold text-primary mb-3",children:a.title}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:a.description})]},a.id))})]})}),s.jsx(ie,{variant:1})]})}function Nee(t="haka_lab",e=10){const[a,n]=k.useState([]),[i,r]=k.useState(!0),[o,l]=k.useState(null);return k.useEffect(()=>{(async()=>{try{r(!0);const d=await fetch(`https://us-central1-web-haka-2026.cloudfunctions.net/getTweetsHttp?username=${t}&maxResults=${e}`);if(!d.ok)throw new Error(`Error HTTP: ${d.status}`);const u=await d.json();if(!u.success)throw new Error(u.error||"Error desconocido");n(u.tweets||[]),l(null)}catch(d){console.error("Error al obtener tweets:",d),l(d.message),n([])}finally{r(!1)}})()},[t,e]),{tweets:a,loading:i,error:o}}function Iee(){const{t}=$(),{tweets:e,loading:a}=Nee("haka_lab",9),[n,i]=k.useState(9),r=[{id:1,title:"Haka RTC captura y organiza tráfico de API REST",description:"Con Haka RTC captura y organiza tráfico de API REST desde el navegador y Postman o CSV para obtener pruebas de integración y regresión.",image:"/imagenes/personajes_home.png",date:"2024-01-14",link:"https://twitter.com/haka_lab"},{id:2,title:"Cada hora caÃda en un cyber puede costar hasta 25%",description:"En fechas crÃticas, una caÃda impacta significativamente en ventas y reputación.",image:"/imagenes/performance.png",date:"2024-01-09",link:"https://twitter.com/haka_lab"},{id:3,title:"Certificación más rápida, mismo nivel de calida
3702d",description:"Optimiza tus procesos de testing con nuestras soluciones.",image:"/imagenes/personajes_home.png",date:"2024-01-04",link:"https://twitter.com/haka_lab"}],o=()=>{i(d=>d+3)},l=e.length>0?e.slice(0,n):r.slice(0,n),c=n<(e.length>0?e.length:r.length);return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark py-16 sm:py-20 md:py-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-12 sm:mb-16 mt-8 sm:mt-12 md:mt-16",children:[s.jsx("h2",{className:"mt-1 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:t("nosotros.redes.titulo")}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mx-auto"}),s.jsx("p",{className:"text-base sm:text-lg text-gray-200 font-light mb-8 mt-8",children:t("nosotros.redes.subtitulo")}),s.jsxs("div",{className:"flex justify-center gap-6",children:[s.jsx(_.a,{href:"https://www.youtube.com/@HakaLab_latam",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:bg-red-600 transition-all duration-300 shadow-lg group",children:s.jsx("svg",{className:"w-6 h-6 text-white group-hover:text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M23.498 6.186a2.96 2.96 0 00-2.083-2.09C19.505 3.5 12 3.5 12 3.5s-7.505 0-9.415.596a2.96 2.96 0 00-2.083 2.09C0 8.1 0 12 0 12s0 3.9.502 5.814a2.96 2.96 0 002.083 2.09C4.495 20.5 12 20.5 12 20.5s7.505 0 9.415-.596a2.96 2.96 0 002.083-2.09C24 15.9 24 12 24 12s0-3.9-.502-5.814zM9.75 15.5v-7l6.5 3.5-6.5 3.5z"})})}),s.jsx(_.a,{href:"https://www.linkedin.com/company/33261585",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:bg-blue-600 transition-all duration-300 shadow-lg group",children:s.jsx("svg",{className:"w-6 h-6 text-white",viewBox:"0 0 24 24",fill:"currentColor",children:s.jsx("path",{d:"M4.98 3.5C4.98 4.88 3.87 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1 4.98 2.12 4.98 3.5zM.5 8h4v16h-4V8zm7 0h3.75v2.16h.05c.52-.99 1.8-2.03 3.7-2.03 3.96 0 4.68 2.6 4.68 5.97V24h-4v-7.5c0-1.79-.03-4.1-2.5-4.1-2.5 0-2.88 1.95-2.88 3.97V24h-4V8z"})})}),s.jsx(_.a,{href:"https://x.com/haka_lab",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:bg-black transition-all duration-300 shadow-lg",children:s.jsx("svg",{className:"w-5 h-5 text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"})})}),s.jsxs(_.a,{href:"https://www.instagram.com/hakalab.latam",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:shadow-lg transition-all duration-300 relative overflow-hidden group",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-tr from-[#feda75] via-[#d62976] to-[#4f5bd5] opacity-0 group-hover:opacity-100 transition-opacity duration-300"}),s.jsxs("svg",{className:"w-6 h-6 text-white relative z-10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"2",y:"2",width:"20",height:"20",rx:"5",ry:"5"}),s.jsx("path",{d:"M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"}),s.jsx("line",{x1:"17.5",y1:"6.5",x2:"17.51",y2:"6.5"})]})]})]})]}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 lg:gap-8",children:a?s.jsx("div",{className:"col-span-full text-center py-12",children:s.jsx("p",{className:"text-gray-300",children:t("common.cargandoTweets")})}):e.length>0?l.map((d,u)=>s.jsxs(_.a,{href:d.url,target:"_blank",rel:"noopener noreferrer",initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:u*.1},className:"group bg-slate-800/30 rounded-lg overflow-hidden border border-primary/20 hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-
3702primary/20 p-6 flex flex-col",children:[s.jsx("div",{className:"flex-1",children:s.jsx("h3",{className:"text-lg sm:text-xl font-semibold text-primary mb-3 group-hover:text-cyan-300 transition-colors line-clamp-3",children:d.text})}),s.jsxs("div",{className:"flex items-center justify-between text-xs text-gray-400 mt-4 pt-4 border-t border-primary/10",children:[s.jsxs("div",{className:"flex gap-4",children:[s.jsxs("span",{children:["â¤ï¸ ",d.likes]}),s.jsxs("span",{children:["ð ",d.retweets]}),s.jsxs("span",{children:["ð¬ ",d.replies]})]}),s.jsx("span",{className:"text-primary group-hover:underline",children:t("common.verEnX")})]}),s.jsx("div",{className:"text-xs text-gray-500 mt-3",children:new Date(d.created_at).toLocaleDateString("es-ES",{year:"numeric",month:"long",day:"numeric"})})]},d.id)):l.map((d,u)=>s.jsxs(_.a,{href:d.link,target:"_blank",rel:"noopener noreferrer",initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:u*.1},className:"group bg-slate-800/30 rounded-lg overflow-hidden border border-primary/20 hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-primary/20",children:[s.jsxs("div",{className:"relative h-48 bg-slate-700/50 overflow-hidden",children:[s.jsx("img",{src:d.image,alt:d.title,className:"w-full h-full object-cover group-hover:scale-110 transition-transform duration-300",loading:"lazy"}),s.jsx("div",{className:"absolute top-4 right-4 w-10 h-10 bg-black/70 rounded-full flex items-center justify-center",children:s.jsx("svg",{className:"w-5 h-5 text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"})})})]}),s.jsxs("div",{className:"p-6",children:[s.jsx("h3",{className:"text-lg sm:text-xl font-semibold text-primary mb-2 group-hover:text-cyan-300 transition-colors",children:d.title}),s.jsx("p",{className:"text-sm text-gray-300 mb-4 line-clamp-3",children:d.description}),s.jsxs("div",{className:"flex items-center justify-between text-xs text-gray-400",children:[s.jsx("span",{children:new Date(d.date).toLocaleDateString("es-ES",{year:"numeric",month:"long",day:"numeric"})}),s.jsx("span",{className:"text-primary group-hover:underline",children:t("common.verEnX")})]})]})]},d.id))}),s.jsx(_.div,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.4},className:"flex flex-col sm:flex-row gap-4 justify-center mt-12",children:c&&s.jsx("button",{onClick:o,className:"border-2 border-primary/50 text-primary px-8 py-3 rounded text-base sm:text-lg font-semibold hover:bg-primary/10 transition-all duration-300",children:t("nosotros.redes.verMasNoticias")})})]}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function Pee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Nosotros - Expertos en QA y Testing",description:"Conoce al equipo de HakaLab. Mas de 10 años de experiencia en testing automatizado y calidad de software en Chile.",path:"/nosotros"}),s.jsx(jee,{}),s.jsx(Tee,{}),s.jsx(Iee,{})]})}function Ree(){const{t}=$(),e=t("casosExito.hero",{returnObjects:!0}),{isOpen:a,modalTitle:n,openModal:i,closeModal:r}=oa();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{id:"home",className:"relative bg-dark",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[400px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow-head"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-1 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-right order-1 lg:order-2",children:[s.jsx("h1",{id:"casos-hero-title",className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-auto lg:mr-0"}),s.jsx("p",{id:"casos-hero-subtitle",className:"mt-6 text-md sm:text-base lg:text-lg text-gray-100 mb-8 leading-relaxed font-light",itemProp:"description",children:e.subt
3702itle}),s.jsx("div",{className:"flex justify-center lg:justify-end",children:s.jsx("button",{id:"casos-hero-button",onClick:()=>i(t("contactModal.title")),className:"border-2 border-primary text-primary px-6 py-2 sm:py-3 rounded-2xl text-base font-semibold hover:bg-primary hover:text-dark transition-all",children:e.btn})})]}),s.jsx("div",{className:"flex justify-center items-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/casos_exito.png",alt:"Casos de Ãxito HakaLab",id:"casos-hero-image",className:"w-full max-w-[250px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl",loading:"eager",width:"512",height:"512"})})]})})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsx(Yr,{isOpen:a,onClose:r,title:n})]})}function Lee({className:t="w-5 h-5"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M21 21H4.6c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C3 20.2401 3 19.9601 3 19.4V3m18 4-5.4343 5.4343c-.198.198-.297.297-.4112.3341a.5.5 0 0 1-.309 0c-.1142-.0371-.2132-.1361-.4112-.3341l-1.8686-1.8686c-.198-.198-.297-.297-.4112-.3341a.5.5 0 0 0-.309 0c-.1142.0371-.2132.1361-.4112.3341L7 15m14-8h-4m4 0v4"})})}function Oee({className:t="w-5 h-5"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M11 4.5h7.3c1.1201 0 1.6802 0 2.108.218.3763.1917.6823.4977.874.874.218.4278.218.9879.218 2.108V9c0 .9319 0 1.3978-.1522 1.7654-.203.49-.5924.8794-1.0824 1.0824C19.8978 12 19.4319 12 18.5 12M13 19.5H5.7c-1.1201 0-1.6802 0-2.108-.218a2 2 0 0 1-.874-.874C2.5 17.9802 2.5 17.4201 2.5 16.3V15c0-.9319 0-1.3978.1522-1.7654.203-.49.5924-.8794 1.0824-1.0824C4.1022 12 4.5681 12 5.5 12m4.8 2.5h3.4c.28 0 .42 0 .527-.0545a.5.5 0 0 0 .2185-.2185c.0545-.107.0545-.247.0545-.527v-3.4c0-.28 0-.42-.0545-.527a.5.5 0 0 0-.2185-.2185C14.12 9.5 13.98 9.5 13.7 9.5h-3.4c-.28 0-.42 0-.527.0545a.5.5 0 0 0-.2185.2185C9.5 9.88 9.5 10.02 9.5 10.3v3.4c0 .28 0 .42.0545.527a.5.5 0 0 0 .2185.2185c.107.0545.247.0545.527.0545m7.5 7.5h3.4c.28 0 .42 0 .527-.0545a.5.5 0 0 0 .2185-.2185C22 21.62 22 21.48 22 21.2v-3.4c0-.28 0-.42-.0545-.527a.5.5 0 0 0-.2185-.2185C21.62 17 21.48 17 21.2 17h-3.4c-.28 0-.42 0-.527.0545a.5.5 0 0 0-.2185.2185C17 17.38 17 17.52 17 17.8v3.4c0 .28 0 .42.0545.527a.5.5 0 0 0 .2185.2185C17.38 22 17.52 22 17.8 22M2.8 7h3.4c.28 0 .42 0 .527-.0545a.5.5 0 0 0 .2185-.2185C7 6.62 7 6.48 7 6.2V2.8c0-.28 0-.42-.0545-.527a.5.5 0 0 0-.2185-.2185C6.62 2 6.48 2 6.2 2H2.8c-.28 0-.42 0-.527.0545a.5.5 0 0 0-.2185.2185C2 2.38 2 2.52 2 2.8v3.4c0 .28 0 .42.0545.527a.5.5 0 0 0 .2185.2185C2.38 7 2.52 7 2.8 7"})})}function Mee({className:t="w-5 h-5"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M22 9H2m12 8.5 2.5-2.5-2.5-2.5m-4 0L7.5 15l2.5 2.5M2 7.8v8.4c0 1.6802 0 2.5202.327 3.162a3 3 0 0 0 1.311 1.311C4.2798 21 5.1198 21 6.8 21h10.4c1.6802 0 2.5202 0 3.162-.327a3 3 0 0 0 1.311-1.311C22 18.7202 22 17.8802 22 16.2V7.8c0-1.6802 0-2.5202-.327-3.162a3 3 0 0 0-1.311-1.311C19.7202 3 18.8802 3 17.2 3H6.8c-1.6802 0-2.5202 0-3.162.327a3 3 0 0 0-1.311 1.311C2 5.2798 2 6.1198 2 7.8"})})}function Dee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 12L7.5 7.5M12 12l4.5-4.5M12 12l-4.5 4.5M12 12l4.5 4.5M6 3h12M6 21h12M8.4 3v2.4c0 .5601 0 .8402.109 1.054a1 1 0 0 0 .437.437C9.1598 7 9.4399 7 10 7h4c.5601 0 .8402 0 1.054-.109a1 1 0 0 0 .437-.437C15.6 6.2402 15.6 5.9601 15.6 5.4V3M8.4 21v-2.4c0-.5601 0-.8402.109-1.054a1 1 0 0 1 .437-.437C9.1598 17 9.4399 17 10 17h4c.5601 0 .8402 0 1.054.109a1 1 0 0 1 .437.437c.109.2138.109.4939.109 1.054V21"})})}function qee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M22 12h-4m-6-6V2m0 20v-4m-6-6H2m20 0c0 5.5228-4.4772 10-10 10S2 17.5228 2 12 6.4772 2 12 2s10 4.4772 10 10m-4 0c0 3.3137-2.6863 6-6 6s-6-2.6863-6-6 2.6863-6 6-6 6 2.6863 6 6m-4 0a2 2 0 1 1-4 0 2 2
37020 0 1 4 0"})})}function zee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"m14.7279 10.1213 7.0711 7.0711c.3905.3905.5858.5858.5858.8284 0 .2427-.1953.4379-.5858.8284l-1.4142 1.4142c-.3905.3905-.5857.5858-.8284.5858s-.4379-.1953-.8284-.5858l-7.0711-7.0711m3.5355-3.5355A5.0001 5.0001 0 0 0 12 4c-.5523 0-1 .4477-1 1v.3431c0 .3183 0 .4774-.0586.6131a1 1 0 0 1-.2652.3652c-.1357.0586-.2948.0586-.6131.0586H9.5c-.2761 0-.4142 0-.5176.0384a1 1 0 0 0-.6963.6963C8.25 7.1858 8.25 7.3239 8.25 7.6v.65c0 .3183 0 .4774-.0586.6131a1 1 0 0 1-.3652.2652c-.1357.0586-.2948.0586-.6131.0586H7c-.5523 0-1 .4477-1 1a5.0001 5.0001 0 0 0 5.6569 4.9497m3.5355-3.5355-3.5355 3.5355"})})}function Vee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 15v3.5m0-3.5a6.9998 6.9998 0 0 1-4.2426-1.4571L6.5 12.5v-2l-3.2929-3.2929C2.7803 6.7803 2.5732 6.5732 2.4619 6.3271A1.5 1.5 0 0 1 2.25 5.5v-.3c0-.4714 0-.7071.0732-.8536a.5.5 0 0 1 .2732-.2732C2.7929 4 3.0286 4 3.5 4h.8c.2357 0 .4714 0 .6857.0381.1929.0343.3771.0933.5514.1762.1935.092.3664.2197.7122.4751L9.5 7.5h2l1.5429-1.2574A6.9998 6.9998 0 0 1 15 4.5V2m-3 13a6.9998 6.9998 0 0 0 4.2426-1.4571L17.5 12.5v-2l3.2929-3.2929c.4268-.4268.6402-.6402.7515-.8863A1.5 1.5 0 0 0 21.75 5.5v-.3c0-.4714 0-.7071-.0732-.8536a.5.5 0 0 0-.2732-.2732C21.2571 4 21.0214 4 20.5 4h-.8c-.2357 0-.4714 0-.6857.0381a2 2 0 0 0-.5514.1762c-.1935.092-.3664.2197-.7122.4751L14.5 7.5h-2l-1.5429-1.2574A6.9998 6.9998 0 0 0 9 4.5V2m3 13c0 1.8638 0 2.7956-.1522 3.5307-.203.9802-.7476 1.8744-1.5449 2.5375C9.5577 22 8.6935 22 6.9651 22c-.5523 0-.8284 0-1.0214-.0815a1.4 1.4 0 0 1-.8622-.8622C5 20.9463 5 20.6702 5 20.1179v-1.6358c0-.3183 0-.4774.0586-.6131a1 1 0 0 1 .2652-.3652c.1357-.0586.2948-.0586.6131-.0586h.8262c.3183 0 .4774 0 .6131.0586a1 1 0 0 1 .3652.2652c.0586.1357.0586.2948.0586.6131v1.6358c0 .5523 0 .8284.0815 1.0214a1.4 1.4 0 0 0 .8622.8622C8.8821 22 9.1582 22 9.7105 22h.3244c1.7284 0 2.5926 0 3.3378-.3932.7973-.4631 1.3418-1.3573 1.5449-2.5375C15.0676 18.3304 15.0676 17.3986 15.0676 15.5m0 0c0-1.8638 0-2.7956.1522-3.5307.203-.9802.7476-1.8744 1.5449-2.5375C17.5099 9 18.3741 9 20.1025 9c.5523 0 .8284 0 1.0214.0815a1.4 1.4 0 0 1 .8622.8622C22 10.1537 22 10.4298 22 10.9821v1.6358c0 .3183 0 .4774-.0586.6131a1 1 0 0 1-.2652.3652c-.1357.0586-.2948.0586-.6131.0586h-.8262c-.3183 0-.4774 0-.6131-.0586a1 1 0 0 1-.3652-.2652c-.0586-.1357-.0586-.2948-.0586-.6131v-1.6358c0-.5523 0-.8284-.0815-1.0214a1.4 1.4 0 0 0-.8622-.8622C18.1179 9 17.8418 9 17.2895 9h-.3244c-1.7284 0-2.5926 0-3.3378.3932-.7973.4631-1.3418 1.3573-1.5449 2.5375C12.0324 12.6696 12.0324 13.6014 12.0324 15.5M15 9a3 3 0 1 1-6 0 3 3 0 0 1 6 0"})})}function Hee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 16v2m0 0v2m0-2h-2m2 0h2M6.8 20h10.4c1.6802 0 2.5202 0 3.162-.327a3 3 0 0 0 1.311-1.311C22 17.7202 22 16.8802 22 15.2V8.8c0-1.6802 0-2.5202-.327-3.162a3 3 0 0 0-1.311-1.311C19.7202 4 18.8802 4 17.2 4H6.8c-1.6802 0-2.5202 0-3.162.327a3 3 0 0 0-1.311 1.311C2 6.2798 2 7.1198 2 8.8v6.4c0 1.6802 0 2.5202.327 3.162a3 3 0 0 0 1.311 1.311C4.2798 20 5.1198 20 6.8 20"})})}function Fee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 20V10m6 10V4m6 16v-7"})})}function Bee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"m9 12 2 2 4-4m7-1.3418V7.2c0-.6402 0-.9603-.0545-1.2162a2 2 0 0 0-.2185-.5274c-.1357-.2118-.3339-.3801-.7303-.7166l-4.8-4.08c-.3753-.3189-.5629-.4783-.7763-.5384a1 1 0 0 0-.5408 0c-.2134.0601-.401.2195-.7763.5384l-4.8 4.08c-.39
370264.3365-.5946.5048-.7303.7166a2 2 0 0 0-.2185.5274C2 6.2397 2 6.5598 2 7.2v1.4582c0 4.5714 2.5 8.7714 7.5 11.2714 5-2.5 7.5-6.7 7.5-11.2714"})})}function Uee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M7 22V11M2 13v6c0 .9319 0 1.3978.1522 1.7654.203.49.5924.8794 1.0824 1.0824C3.6022 22 4.0681 22 5 22h1.3431c.2357 0 .4714 0 .6857-.0381a2 2 0 0 0 .5514-.1762c.1935-.092.3664-.2197.7122-.4751L11 19m0 0 .5858-.5858c.3905-.3905.5858-.5858.7071-.8284.1214-.2427.1214-.5142.1214-1.0572V13c0-.4714 0-.7071.0732-.8536a.5.5 0 0 1 .2185-.2185C12.7929 11.85 13.0286 11.85 13.5 11.85h4.8c1.1201 0 1.6802 0 2.108-.218a2 2 0 0 0 .874-.874c.218-.4278.218-.9879.218-2.108V8.5c0-.4714 0-.7071-.0732-.8536a.5.5 0 0 0-.2185-.2185C21.0571 7.35 20.8214 7.35 20.35 7.35h-4.8c-.4714 0-.7071 0-.8536-.0732a.5.5 0 0 1-.2185-.2185C14.4 6.9071 14.4 6.6714 14.4 6.2V3.7c0-.5601 0-.8402-.109-1.054a1 1 0 0 0-.437-.437C13.6402 2.1 13.3601 2.1 12.8 2.1h-.3c-.2357 0-.4714 0-.6857.0381a2 2 0 0 0-.5514.1762c-.1935.092-.3664.2197-.7122.4751L7 6.5"})})}function $ee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 6h.01M6 18h.01M6 12h.01M22 8.2v-.4c0-1.6802 0-2.5202-.327-3.162a3 3 0 0 0-1.311-1.311C19.7202 3 18.8802 3 17.2 3H6.8c-1.6802 0-2.5202 0-3.162.327a3 3 0 0 0-1.311 1.311C2 5.2798 2 6.1198 2 7.8v.4c0 1.6802 0 2.5202.327 3.162a3 3 0 0 0 1.311 1.311C4.2798 13 5.1198 13 6.8 13h10.4c1.6802 0 2.5202 0 3.162-.327a3 3 0 0 0 1.311-1.311C22 10.7202 22 9.8802 22 8.2m0 7.6v.4c0 1.6802 0 2.5202-.327 3.162a3 3 0 0 1-1.311 1.311C19.7202 21 18.8802 21 17.2 21H6.8c-1.6802 0-2.5202 0-3.162-.327a3 3 0 0 1-1.311-1.311C2 18.7202 2 17.8802 2 16.2v-.4c0-1.6802 0-2.5202.327-3.162a3 3 0 0 1 1.311-1.311C4.2798 11 5.1198 11 6.8 11h10.4c1.6802 0 2.5202 0 3.162.327a3 3 0 0 1 1.311 1.311C22 13.2798 22 14.1198 22 15.8"})})}function Wee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M21 7.35294V16.6471C21 17.1686 21 17.4294 20.9447 17.6543C20.7672 18.3841 20.2128 18.9385 19.483 19.116C19.2581 19.1713 18.9973 19.1713 18.4758 19.1713C17.9543 19.1713 17.6935 19.1713 17.4686 19.116C16.7388 18.9385 16.
37021844 18.3841 16.0069 17.6543C15.9516 17.4294 15.9516 17.1686 15.9516 16.6471V7.35294C15.9516 6.83143 15.9516 6.57068 16.0069 6.34575C16.1844 5.61595 16.7388 5.06154 17.4686 4.88403C17.6935 4.82874 17.9543 4.82874 18.4758 4.82874C18.9973 4.82874 19.2581 4.82874 19.483 4.88403C20.2128 5.06154 20.7672 5.61595 20.9447 6.34575C21 6.57068 21 6.83143 21 7.35294ZM15.9516 7.35294V16.6471C15.9516 17.1686 15.9516 17.4294 15.8963 17.6543C15.7188 18.3841 15.1644 18.9385 14.4346 19.116C14.2097 19.1713 13.9489 19.1713 13.4274 19.1713H6.8C5.11984 19.1713 3.73433 17.7858 3.73433 16.1056V7.89437C3.73433 6.21421 5.11984 4.82874 6.8 4.82874H13.4274C13.9489 4.82874 14.2097 4.82874 14.4346 4.88403C15.1644 5.06154 15.7188 5.61595 15.8963 6.34575C15.9516 6.57068 15.9516 6.83143 15.9516 7.35294ZM9.86667 19.1713V20.2374C9.86667 21.2119 9.08114 22 8.10667 22C7.13219 22 6.34667 21.2119 6.34667 20.2374V19.1713H9.86667Z"})})}function Gee({className:t="w-8 h-8"}){return s.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:[s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M9.3951 19.3711L9.97955 20.6856C10.1533 21.0768 10.4368 21.4093 10.7958 21.6426C11.1547 21.8759 11.5737 22.0001 12.0018 22C12.4299 22.0001 12.8488 21.8759 13.2078 21.6426C13.5667 21.4093 13.8503 21.0768 14.024 20.6856L14.6084 19.3711C14.8165 18.9047 15.1664 18.5159 15.6084 18.26C16.0532 18.0034 16.5678 17.8941 17.0784 17.9478L18.5084 18.1C18.9341 18.145 19.3637 18.0656 19.7451 17.8713C20.1265 17.6771 20.4434 17.3763 20.6573 17.0056C20.8715 16.635 20.9735 16.2103 20.9511 15.7829C20.9286 15.3555 20.7825 14.9438 20.5307 14.5978L19.684 13.4344C19.3825 13.0171 19.2214 12.5148 19.224 12C19.2239 11.4866 19.3865 10.9864 19.6884 10.5711L20.5351 9.40778C20.787 9.06175 20.933 8.65007 20.9555 8.22267C20.978 7.79528 20.8759 7.37054 20.6618 7C20.4479 6.62923 20.131 6.32849 19.7496 6.13423C19.3681 5.93997 18.9386 5.86053 18.5129 5.90556L17.0829 6.05778C16.5722 6.11141 16.0577 6.00212 15.6129 5.74556C15.17 5.48825 14.82 5.09736 14.6129 4.62889L14.024 3.31444C13.8503 2.92317 13.5667 2.59072 13.2078 2.3574C12.8488 2.12408 12.4299 1.99993 12.0018 2C11.5737 1.99993 11.1547 2.12408 10.7958 2.3574C10.4368 2.59072 10.1533 2.92317 9.97955 3.31444L9.3951 4.62889C9.18803 5.09736 8.83798 5.48825 8.3951 5.74556C7.95032 6.00212 7.43577 6.11141 6.9251 6.05778L5.49066 5.90556C5.06499 5.86053 4.6354 5.93997 4.25397 6.13423C3.87255 6.32849 3.55567 6.62923 3.34177 7C3.12759 7.37054 3.02555 7.79528 3.04804 8.22267C3.07052 8.65007 3.21656 9.06175 3.46844 9.40778L4.3151 10.5711C4.61704 10.9864 4.77964 11.4866 4.7795
37025 12C4.77964 12.5134 4.61704 13.0137 4.3151 13.4289L3.46844 14.5922C3.21656 14.9382 3.07052 15.3499 3.04804 15.7773C3.02555 16.2047 3.12759 16.6295 3.34177 17C3.55589 17.3706 3.8728 17.6712 4.25417 17.8654C4.63554 18.0596 5.06502 18.1392 5.49066 18.0944L6.92066 17.9422C7.43133 17.8886 7.94587 17.9979 8.39066 18.2544C8.83519 18.511 9.18687 18.902 9.3951 19.3711Z"}),s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M15 12C15 13.6569 13.6569 15 12 15C10.3431 15 9 13.6569 9 12C9 10.3431 10.3431 9 12 9C13.6569 9 15 10.3431 15 12Z"})]})}function Kee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M22 11.0857V12.0057C21.9988 14.1621 21.3005 16.2604 20.0093 17.9875C18.7182 19.7147 16.9033 20.9782 14.8354 21.5896C12.7674 22.201 10.5573 22.1276 8.53447 21.3803C6.51168 20.633 4.78465 19.2518 3.61096 17.4428C2.43727 15.6338 1.87979 13.4938 2.02168 11.342C2.16356 9.19029 2.99721 7.14205 4.39828 5.5028C5.79935 3.86354 7.69279 2.72111 9.79619 2.24587C11.8996 1.77063 14.1003 1.98806 16.07 2.86572M22 4L12 14.01L9 11.01"})})}function Jee(){const{t}=$(),e={tabs:[{id:"performance",iconComponent:"line-chart",label:"Performance",cases:[{company:"Walmart",image:"/imagenes/casos_walmart.png"},{company:"Melt Pizzas",image:"/imagenes/casos_melt.png"}]},{id:"continuous",iconComponent:"dataflow",label:"Continuous Testing",cases:[{company:"Consorcio",image:"/imagenes/casos_consorcio.png"},{company:"Casa Ideas",image:"/imagenes/casos_casaideas.png"},{company:"Sodimac Homecenter",image:"/imagenes/casos_sodimac.png"},{company:"Scotiabank",image:"/imagenes/casos_scotiabank.png"}]},{id:"data",iconComponent:"code-browser",label:"Data Testing",cases:[{company:"Parque Arauco",image:"/imagenes/casos_parquearauco.png"}]}]},[a,n]=k.useState(0),i=e.tabs[a],r=Array.isArray(i.cases)?i.cases:[i],o={Walmart:"walmart","Melt Pizzas":"melt",Consorcio:"consorcio","Casa Ideas":"casaideas","Sodimac Homecenter":"sodimac",Scotiabank:"scotiabank","Parque Arauco":"parquearauco"},l=u=>{const p=o[u];return p?t(`casosExito.cases.${p}`,{returnObjects:!0}):null},c={"line-chart":Lee,dataflow:Oee,"code-browser":Mee,hourglass:Dee,target:qee,wrench:zee,rocket:Vee,monitor:Hee,chart:Fee,"check-shield":Bee,"thumbs-up":Uee,server:$ee,megaphone:Wee,gear:Gee,"circle-check":Kee},d=u=>{if(u.iconComponent&&c[u.iconComponent]){const p=c[u.iconComponent];return s.jsx(p,{className:"w-5 h-5 sm:w-6 sm:h-6"})}return u.iconImage?s.jsx("img",{src:u.iconImage,alt:u.label,className:"w-5 h-5 sm:w-6 sm:h-6 object-contain"}):s.jsx("span",{className:"text-lg sm:text-xl",children:u.icon})};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark py-16 sm:py-20 md:py-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx("div",{className:"flex flex-wrap justify-center gap-3 sm:gap-4 mb-12 sm:mb-16 mt-9",children:e.tabs.map((u,p)=>s.jsxs(_.button,{id:`casos-interactivos-tab-${u.id}`,onClick:()=>n(p),whileHover:{scale:1.05},whileTap:{scale:.95},className:` 3703 flex items-center gap-2 px-4 sm:px-6 py-2 sm:py-3 rounded-lg text-sm sm:text-base font-semibold 3704 transition-all duration-300 border-2 3705 ${a===p?"bg-primary text-dark border-primary shadow-lg shadow-primary/50":"bg-slate-800/50 text-gray-300 border-primary/30 hover:border-primary/60 hover:text-primary"} 3706 `,children:[d(u),s.jsx("span",{children:u.label})]},u.id))}),s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:-20},transition:{duration:.5},className:"space-y-16 sm:space-y-20",children:r.map((u,p)=>{const h=l(u.company)||u;return s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center",children:[s.jsxs("div",{className:`space-y-6 ${p%2===1?"lg:order-2":"lg:order-1"}`,children:[s.jsxs("div",{children:[s.jsx(_.h3,{initial:{opacity:0,x:-20}
3706,animate:{opacity:1,x:0},transition:{delay:.2},className:"text-2xl sm:text-3xl font-bold text-primary mb-2",children:h.company}),s.jsx(_.p,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.3},className:"text-xl sm:text-2xl text-gray-200",children:h.title})]}),h.problem&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.4},className:"bg-slate-800/30 p-4 sm:p-6 rounded-lg border border-red-500/30",children:[s.jsx("p",{className:"text-sm font-semibold text-red-400 mb-2",children:t("casosExito.desafioLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:h.problem})]}),h.solution&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.5},className:"bg-slate-800/30 p-4 sm:p-6 rounded-lg border border-primary/30",children:[s.jsx("p",{className:"text-sm font-semibold text-primary mb-2",children:t("casosExito.solucionLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:h.solution})]}),h.results&&s.jsx(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.6},className:"space-y-4",children:h.results.map((g,y)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.7+y*.1},className:"flex items-start gap-4",children:[g.iconComponent&&c[g.iconComponent]&&s.jsx("div",{className:"flex-shrink-0 text-primary",children:(()=>{const x=c[g.iconComponent];return s.jsx(x,{className:"w-8 h-8 sm:w-10 sm:h-10"})})()}),g.iconImage&&!g.iconComponent&&s.jsx("div",{className:"flex-shrink-0",children:s.jsx("img",{src:g.iconImage,alt:"",className:"w-8 h-8 sm:w-10 sm:h-10 object-contain"})}),g.icon&&!g.iconImage&&!g.iconComponent&&s.jsx("div",{className:"flex-shrink-0 text-3xl",children:g.icon}),g.metric&&!g.icon&&!g.iconImage&&!g.iconComponent&&s.jsx("div",{className:"flex-shrink-0",children:s.jsx("div",{className:"text-3xl sm:text-4xl font-bold text-primary",children:g.metric})}),s.jsx("div",{className:"flex-1",children:s.jsx("p",{className:"text-sm sm:text-base text-gray-200",children:g.description})})]},y))}),h.testimonial&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.9},className:"bg-slate-800/30 p-4 sm:p-6 rounded-lg border border-primary/30",children:[s.jsx("p",{className:"text-sm font-semibold text-primary mb-2",children:t("casosExito.testimonioLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 italic mb-4",children:h.testimonial.text}),s.jsxs("div",{className:"text-sm text-gray-300",children:[s.jsx("p",{className:"font-semibold",children:h.testimonial.author}),s.jsx("p",{children:h.testimonial.position}),s.jsx("p",{className:"text-primary",children:h.testimonial.company})]})]}),h.qa&&!h.testimonial&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.9},className:"bg-primary/10 p-4 sm:p-6 rounded-lg border border-primary/50",children:[s.jsx("p",{className:"text-sm sm:text-base font-semibold text-primary",children:t("casosExito.qaLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 mt-2",children:h.qa})]})]}),s.jsx(_.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},transition:{delay:.3,duration:.6},className:`flex justify-center items-center w-full ${p%2===1?"lg:order-1":"lg:order-2"}`,children:s.jsx("div",{className:"relative w-full max-w-lg flex justify-center",children:s.jsx("img",{src:u.image,alt:`Caso de éxito ${u.company}`,className:"w-1/2 sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"lazy"})})})]},p)})},a)})]}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function Qee(){const{isOpen:t,modalTitle:e,openModal:a,closeModal:n}=oa(),{t:i}=$();return s.jsxs(s.Fragment,{children:[s.jsx("section",{className:"relative bg-dark py-19 sm:py-20 mt-10",children:s.jsx("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs("div",{className:"flex flex-col lg:flex-row items-center justify-between gap-8 sm:pt-10 pt-5",children:[s.jsxs("div",{className:"flex-1 text-center lg:text-left mt-10",children:[s.jsx(_.h2,{id:"casos-cta-diagnostico-title",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white",children:i("casosExito.cta.titulo")}),s.jsx(_.p,{id:"casos-cta-diagnostico-description",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"text-base sm:text-lg text-gray-300 max-w-xl mt-6",children:i("casosExito.cta.descripcion")})]}),s.jsx(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.4},className:"flex-shrink-0",children:s.jsx("button",{id:"casos-cta-diagnostico-button",onClick:()=>a(i("casosExito.cta.boton")),className:"inline-block px-8 py-3 bg-transparent border-2 border-primary text-primary rounded-2xl font-semibold hover:bg-primary hover:text-dark transition-all duration-300 transform hover:scale-105 whitespace-nowrap",children:i("casosExito.cta.boton")})})]})})}),s.jsx(Yr,{isOpen:t,onClose:n,title:e})]})}function Kk({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 15V17M12 17V19.5M12 17H9.5M12 17H14.5M6 3H18C18 3 18 5.5 18 7C18 9.5 15.5 12 12 12C8.5 12 6 9.5 6 7C6 5.5 6 3 6 3ZM6 3H4C3.5 3 3 3.5 3 4V6C3 7.5 4 9 5.5 9H6M18 3H20C20.5 3 21 3.5 21 4V6C21 7.5 20 9 18.5 9H18M8.5 19.5H15.5C16.0523 19.5 16.5 19.9477 16.5 20.5C16.5 21.0523 16.0523 21.5 15.5 21.5H8.5C7.94772 21.5 7.5 21.0523 7.5 20.5C7.5 19.9477 7.94772 19.5 8.5 19.5Z"})})}function Xee(){const[t,e]=k.useState(""),[a,n]=k.useState(!1),[i,r]=k.useState(""),{t:o}=$(),l=async c=>{c.preventDefault(),n(!0),r("");try{const d=document.createElement("a");d.href="/descargas/Casos-de-exitos-Haka-lab.pdf",d.download="Casos-de-exitos-Haka-lab.pdf",document.body.appendChild(d),d.click(),document.body.removeChild(d),r(o("ctaNewsletter.mensaje")),e(""),setTimeout(()=>{r("")},5e3)}catch(d){console.error("Error:",d),r("Hubo un error. Por favor intenta de nuevo.")}finally{n(!1)}};return s.jsxs("section",{className:"relative bg-dark py-16 sm:py-20 xs:mt-7",children:[s.jsx("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"relative bg-slate-900/50 backdrop-blur-sm border border-primary/30 rounded-2xl p-8 sm:p-12 shadow-2xl",style:{boxShadow:"0 0 40px rgba(0, 255, 255, 0.1)"},children:[s.jsx("div",{className:"absolute top-0 left-0 w-32 h-32 bg-primary/5 rounded-full blur-3xl -z-10"}),s.jsx("div",{className:"absolute bottom-0 right-0 w-32 h-32 bg-primary/5 rounded-full blur-3xl -z-10"}),s.jsx(_.div,{className:"absolute -top-6 -right-6 text-primary",animate:{rotate:360,scale:[1,1.1,1]},transition:{rotate:{duration:8,repeat:1/0,ease:"linear"},scale:{duration:2,repeat:1/0,ease:"easeInOut"}},children:s.jsx("div",{className:"bg-slate-800 rounded-full p-4 border-2 border-primary shadow-lg shadow-primary/50",children:s.jsx(Kk,{className:"w-8 h-8 sm:w-10 sm:h-10"})})}),s.jsx(_.h2,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.1},className:"text-3xl sm:text-4xl md:text-3xl font-bold text-primary mb-8 text-center",children:o("ctaNewsletter.titulo")}),s.jsxs(_.form,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},onSubmit:l,className:"flex flex-col sm:flex-row gap-4 justify-center items-center",children:[s.jsx("input",{id:"input-email",type:"email",value:t,onChange:c=>e(c.target.value),placeholder:o("ctaNewsletter.placeholder"),required:!0,disabled:a,className:"w-full sm:flex-1 px-6 py-3 bg-slate-800/80 border border-gray-700 rounded-lg text-gray-200 placeholder-gray-500 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all disabled:opacity-50"}),s.jsx("button",{id:"btn-input-email",type:"submit",disabled:a,className:"w-full sm:w-auto px-4 sm:px-8 py-3 bg-transparent border-2 border-primary text-primary rounded-2xl font-semibold hover:bg-primary hover:text-dark transition-all duration-300 transform hover:scale-105 shadow-lg hover:shadow-
3706primary/50 text-sm sm:text-base leading-tight disabled:opacity-50 disabled:cursor-not-allowed",children:a?"Descargando...":o("ctaNewsletter.boton")})]}),i&&s.jsx(_.p,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:"text-center text-primary text-sm mt-4",children:i})]})}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function Yee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Casos de Exito - Resultados Comprobados",description:"Walmart, Sodimac, Scotiabank y mas. Conoce como HakaLab ha ayudado a empresas Fortune 500 a mejorar su calidad de software.",path:"/casosdeexito"}),s.jsx(Ree,{}),s.jsx(Jee,{}),s.jsx(Qee,{}),s.jsx(Xee,{})]})}function Zee(){const{t}=$(),e=t("productos.hero",{returnObjects:!0});return s.jsxs("section",{id:"home",className:"relative bg-dark",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsx("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[500px]",children:s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h1",{id:"productos-hero-title",className:"text-5xl md:text-5xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("h1",{className:"text-5xl md:text-5xl font-extrabold tracking-tight text-primary italic",itemProp:"headline",children:e.title2}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"mt-7 text-md sm:text-base lg:text-lg text-white mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light",itemProp:"description",children:e.subt
3706itle})]}),s.jsx("div",{className:"flex justify-center items-center mt-8 lg:mt-0",children:s.jsx("video",{id:"productos-hero-video",src:"/video/video_productos.webm",className:"w-full max-w-xs sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl rounded-lg",autoPlay:!0,loop:!0,muted:!0,playsInline:!0,itemProp:"video",children:t("common.videoNoSoportado")})})]})})}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function ete(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx("section",{ref:t,className:"relative bg-dark py-16 sm:py-20 md:py-24 overflow-x-clip",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 text-center",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white pt-6",children:a("cicloTesting.titulo")}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto"}),s.jsx("p",{className:"pt-8 text-center text-md sm:text-base lg:text-lg text-gray-200 mb-4 leading-relaxed max-w-4xl mx-auto",children:a("cicloTesting.descripcion")}),s.jsx(Og,{showIntro:!1})]})})}function tte(){const{t}=$(),e=t("productos.hero",{returnObjects:!0});return s.jsx("section",{className:"relative bg-dark pt-20",children:s.jsxs("div",{className:"max-w-6xl mx-auto px-4 py-12 sm:py-16 md:py-20 text-center",children:[s.jsx("h2",{id:"productos-resumen-title",className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white",itemProp:"headline",children:t("productos.titulo2")}),s.jsx("h2",{className:"text-4xl md:text-5xl font-extrabold tracking-tight text-primary",itemProp:"headline",children:e.title2})]})})}function ate(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),a=Qa(),{t:n}=$(),i=[{id:0,nombre:"HakaEngine",nombreCompleto:"Haka Automation Engine",imagen:"/imagenes/productos/card Automation Engine.png",descripcion:"Framework para pruebas Web, Mobile, Api e IA con mas de 1.800 steps preconstruidos e impulsado por IA",color:"from-emerald-600 to-cyan-500",borderColor:"border-emerald-400",ruta:"/haka-engine",aiPowered:!0},{id:1,nombre:"HakaAIStudio",nombreCompleto:"Haka AI Studio",imagen:"/imagenes/productos/Haka-AI-Studio.webp",descripcion:n("productos.hakaaistudio.descripcion"),color:"from-violet-600 to-blue-500",borderColor:"border-violet-400",ruta:"/haka-ai-studio",aiPowered:!0},{id:2,nombre:"Hakabuddy",nombreCompleto:"Haka Buddy",imagen:"/imagenes/productos/hakabuddy.webp",descripcion:n("productos.hakabuddy.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"/hakabuddy",aiPowered:!0},{id:3,nombre:"Hakaboost",nombreCompleto:"Haka Boost",imagen:"/imagenes/productos/hakaboost_new.png",descripcion:n("productos.hakaboost.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakaboost",aiPowered:!0},{id:4,nombre:"Hakapath",nombreCompleto:"Haka Path",imagen:"/imagenes/productos/hakapath.webp",descripcion:n("productos.hakapath.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakapath",aiPowered:!0},{id:5,nombre:"Hakartc",nombreCompleto:"HakaRTC",imagen:"/imagenes/productos/hakartc.webp",descripcion:n("productos.hakartc.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakartc",aiPowered:!0},{id:6,nombre:"Hakatools",nombreCompleto:"Haka Tools",imagen:"/imagenes/productos/hakatools.webp",descripcion:n("productos.hakatools.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"https://hakatools.hakalab.com/hakatools",external:!0,aiPowered:!1}];return s.jsxs("section",{ref:t,className:"relative bg-[#0a0e27] py-10 sm:py-10 md:py-1 mb-2",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8 pb-10",children:i.map((r,o)=>s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:o*.1},className:"group cursor-pointer relative",onClick:()=>r.external?window.open(r.ruta,"_blank"):a(r.ruta),children:s.jsxs("div",{id:`productos-card-${r.nombre.toLowerCase()}`,className:` 3707 relative bg-gradient-to-br ${r.color} 3708 rounded-3xl overflow-hidden 3709 border-4 ${r.borderColor} 3710 transition-all duration-300 3711 hover:scale-105 hover:shadow-2xl hover:shadow-cyan-500/20 3712 h-full flex flex-col 3713 `,children:[s.jsx("div",{className:"relative h-56 sm:h-56 bg-gradient-to-b from-transparent to-black/20",children:s.jsx("img",{id:`productos-image-${r.nombre.toLowerCase()}`,src:r.imagen,alt:r.nombreCompleto,className:"w-full h-full object-cover drop-shadow-2xl"})}),s.jsxs("div",{className:"bg-[#0a0e27] p-6 flex flex-col flex-1",children:[s.jsx("p",{className:"text-gray-300 text-sm sm:text-base mb-6 leading-relaxed",children:r.descripcion}),s.jsx("div",{className:"flex-1"}),s.jsx("button",{id:`productos-button-${r.nombre.toLowerCase()}`,className:` 3714 w-full bg-cyan-400 hover:bg-cyan-500 3715 text-[#0a0e27] font-bold 3716 py-3 px-6 rounded-2xl 3717 transition-all duration-300 3718 hover:shadow-lg hover:shadow-cyan-400/50 3719 transform hover:-translate-y-1 3720 `,children:n("relatedProducts.saberMas")})]})]})},r.id))})}),s.jsx(ie,{variant:1})]})}function nte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Productos - Herramientas de IA para Testing",description:"HakaBoost, HakaBuddy, HakaPath, HakaLens y mas. Herramientas de inteligencia artificial para acelerar tu QA hasta un 70%.",path:"/productos"}),s.jsx(Zee,{}),s.jsx(tte,{}),s.jsx(ate,{}),s.jsx(ete,{})]})}function ite(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{isOpen:a,modalTitle:n,closeModal:i}=oa(),{t:r}=$();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{ref:t,className:"relative bg-dark pt-20 pb-16 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakaboostgif.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-3",children:r("hakaboost.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mt-3",children:r("hakaboost.hero.gratis")})]})]}
3720),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsx(Yr,{isOpen:a,onClose:i,title:n})]})}function rte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:" bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-3xl font-bold text-white",children:a("hakaboost.presentacion.titulo")}),s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakaboost-ai-for-quality/gcpcibcgheckokkooihbkgjpdbnolfcg",target:"_blank",rel:"noopener noreferrer",className:` 3721 inline-block w-48 bg-cyan-400 hover:bg-cyan-500 3722 text-[#0a0e27] font-bold text-center 3723 py-3 rounded-full 3724 transition-all duration-300 3725 hover:shadow-lg hover:shadow-cyan-400/50 3726 transform hover:-translate-y-1 3727 mt-5 3728 `,children:a("hakaboost.descargar")})]}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_presentacion.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function ote(){const{t}=$();return s.jsx(s.Fragment,{children:s.jsxs("section",{className:"relative bg-dark pt-5",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-10",children:[s.jsx("h2",{className:"text-center text-3xl sm:text-3xl lg:text-4xl mb-4 sm:mb-6 md:mb-7 text-primary leading-tight sm:leading-snug",itemProp:"headline",children:t("hakaboost.potencia.titulo")}),s.jsx("p",{className:"text-center text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("hakaboost.potencia.descripcion")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakaboost-ai-for-quality/gcpcibcgheckokkooihbkgjpdbnolfcg",target:"_blank",rel:"noopener noreferrer",className:` 3729 inline-block w-48 bg-cyan-400 hover:bg-cyan-500 3730 text-[#0a0e27] font-bold text-center 3731 py-3 rounded-full 3732 transition-all duration-300 3733 hover:shadow-lg hover:shadow-cyan-400/50 3734 transform hover:-translate-y-1 3735 mt-1 3736 `,children:t("hakaboost.descargar")})})]}),s.jsx(ie,{color:"#0a0d29f5",variant:1})]})})}function ste(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakaboost.queHace.features",{returnObjects:!0}),i=a("hakaboost.caracteristicas.items",{returnObjects:!0}),r=a("hakaboost.beneficios.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-24 pb-0",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakaboost.queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakaboost.queHace.descripcion1")}),s.jsx("p",{className:"text-gray-200 mb-8 leading-relaxed",children:a("hakaboost.queHace.descripcion2")}),s.jsx("div",{className:"space-y-4",children:n.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakaboosk_quehace.gif",alt:a("hakaboost.queHace.titulo"),className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_caracteristica.png",alt:a("hakaboost.caracteristicas.titulo"),className:"sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakaboost.caracteristicas.titulo")}),i.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:o})]},l))]})]})}),s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakaboost.beneficios.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakaboost.beneficios.descripcion")}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_beneficios.png",alt:a("hakaboost.beneficios.titulo"),className:"w-full max-w-md h-auto"})})]})]})]}),s.jsx(ie,{variant:1})]})}function lte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),{t:i}=$(),r=i("faq.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark py-10 sm:py-20 md:py-20",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:i("faq.titulo")}),s.jsx("p",{className:"text-gray-300 text-lg",children:i("faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.05},className:"border border-primary/20 rounded-lg overflow-hidden hover:border-primary/50 transition-colors",children:[s.jsxs("button",{onClick:()=>n(a===l?-1:l),className:"w-full px-6 py-4 flex items-center justify-between bg-slate-800/30 hover:bg-slate-800/50 transition-colors",children:[s.jsx("h3",{className:"text-lg font-semibold text-white text-left",children:o.question}),s.jsx(_.div,{animate:{rotate:a===l?180:0},transition:{duration:.3},className:"flex-shrink-0 ml-4",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})})]}),s.jsx(_.div,{initial:{height:0,opacity:0}
3736,animate:{height:a===l?"auto":0,opacity:a===l?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"px-6 py-4 bg-slate-900/50 border-t border-primary/10",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:o.answer})})})]},l))})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function Zr({title:t,productIds:e=[2,3,4,5],showWaveDivider:a=!0}){const n=k.useRef(null),i=we(n,{once:!0,margin:"-100px"}),r=Qa(),{t:o}=$(),l=t||o("relatedProducts.title"),c={1:{id:1,nombre:"Hakaboost",nombreCompleto:"Haka Boost",imagen:"/imagenes/productos/hakaboost_new.png",descripcion:o("productos.hakaboost.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakaboost"},2:{id:2,nombre:"Hakabuddy",nombreCompleto:"Haka Buddy",imagen:"/imagenes/productos/hakabuddy.webp",descripcion:o("productos.hakabuddy.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"/hakabuddy"},3:{id:3,nombre:"Hakapath",nombreCompleto:"Haka Path",imagen:"/imagenes/productos/hakapath.webp",descripcion:o("productos.hakapath.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakapath"}
3736,4:{id:4,nombre:"Hakatools",nombreCompleto:"Haka Tools",imagen:"/imagenes/productos/hakatools.webp",descripcion:o("productos.hakatools.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"https://hakatools.hakalab.com/hakatools",external:!0},5:{id:5,nombre:"Hakartc",nombreCompleto:"HakaRTC",imagen:"/imagenes/productos/hakartc.webp",descripcion:o("productos.hakartc.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakartc"},6:{id:6,nombre:"HakaEngine",nombreCompleto:"Haka Automation Engine",imagen:"/imagenes/productos/card Automation Engine.png",descripcion:"",color:"from-emerald-600 to-cyan-500",borderColor:"border-emerald-400",ruta:"/haka-engine"}},d=e.map(u=>c[u]).filter(Boolean);return s.jsxs("section",{ref:n,className:"relative bg-[#0a0e27] py-16 sm:py-20 md:py-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsx(_.div,{initial:{opacity:0,y:-20},animate:i?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12 sm:mb-16",children:s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-primary",children:l})}),s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8",children:d.map((u,p)=>s.jsx(_.div,{initial:{opacity:0,y:30},animate:i?{opacity:1,y:0}:{},transition:{duration:.5,delay:p*.1},className:"group cursor-pointer",onClick:()=>{u.external?window.open(u.ruta,"_blank"):r(u.ruta)},children:s.jsxs("div",{className:` 3737 relative bg-gradient-to-br ${u.color} 3738 rounded-3xl overflow-hidden 3739 border-4 ${u.borderColor} 3740 transition-all duration-300 3741 hover:scale-105 hover:shadow-2xl hover:shadow-cyan-500/20 3742 flex flex-col 3743 `,children:[s.jsx("div",{className:"relative aspect-[4/3] bg-gradient-to-b from-transparent to-black/20",children:s.jsx("img",{src:u.imagen,alt:u.nombreCompleto,className:"w-full h-full object-cover drop-shadow-2xl"})}),s.jsxs("div",{className:"bg-[#0a0e27] p-6 flex flex-col flex-grow",children:[s.jsxs("h3",{className:"text-2xl sm:text-3xl font-bold mb-3",children:[s.jsx("span",{className:"text-cyan-400",children:"Haka"}),s.jsx("span",{className:"text-white",children:u.nombre.replace("Haka","")})]}),s.jsx("p",{className:"text-gray-300 text-sm sm:text-base mb-6 leading-relaxed flex-grow",children:u.descripcion}),s.jsx("button",{className:` 3744 w-full bg-cyan-400 hover:bg-cyan-500 3745 text-[#0a0e27] font-bold 3746 py-3 px-6 rounded-2xl 3747 transition-all duration-300 3748 hover:shadow-lg hover:shadow-cyan-400/50 3749 transform hover:-translate-y-1 3750 `,children:o("relatedProducts.saberMas")})]})]})},u.id))})]}),a&&s.jsx(ie,{color:"#0a0e27",variant:1})]})}function cte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaBoost - Copiloto de Calidad con IA para Jira y Azure DevOps",description:"Extension de Chrome que acelera la creacion de tests hasta un 70% con IA. Genera escenarios Gherkin, mejora descripciones y crea tests automaticamente.",path:"/hakaboost"}),s.jsx(ite,{}),s.jsx(rte,{}),s.jsx(ote,{}),s.jsx(ste,{}),s.jsx(lte,{}),s.jsx(Zr,{productIds:[2,3,4,5,6]})]})}function dte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsxs("section",{ref:t,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/HakaBuddy v3.gif",alt:"HakaBuddy Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakabuddy_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full",children:a("hakabuddy.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:a("hakabuddy.hero.gratis")})]})]}
3750),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function ute(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto",children:s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-3xl font-bold text-white",children:a("hakabuddy.presentacion.titulo")})}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakabuddygif2.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function pte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakabuddy_queHace.features",{returnObjects:!0}),i=a("hakabuddy_queHace.caracteristicasItems",{returnObjects:!0}),r=a("hakabuddy_queHace.beneficiosItems",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-10 pb-0",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white",children:a("hakabuddy_queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakabuddy_queHace.descripcion")}),s.jsx("div",{className:"space-y-4",children:n.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/quehacehakabuddy.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakabuddy_quehace.gif",alt:"CaracterÃsticas",className:"w-full max-w-md h-auto"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakabuddy_queHace.caracteristicas")}),i.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:o})]},l))]})]})}),s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakabuddy_queHace.beneficios")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakabuddy_queHace.beneficiosDescripcion")}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakabuddy2.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]})]}),s.jsx(ie,{variant:1})]})}function mte({isOpen:t,onClose:e}){const{t:a}=$();return s.jsx(La,{children:t&&s.jsx(s.Fragment,{children:s.jsx(_.div,{initial:{opacity:0}
3750,animate:{opacity:1},exit:{opacity:0},onClick:e,className:"fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-4",children:s.jsxs(_.div,{initial:{opacity:0,scale:.95,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:20},onClick:n=>n.stopPropagation(),className:"bg-[#1a1d3a] rounded-3xl shadow-2xl max-w-md w-full relative overflow-hidden",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-green-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative p-8 sm:p-10 text-center",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring",stiffness:200},className:"mb-6 flex justify-center",children:s.jsx("div",{className:"w-16 h-16 bg-gradient-to-br from-green-400 to-green-500 rounded-full flex items-center justify-center",children:s.jsx("svg",{className:"w-8 h-8 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M5 13l4 4L19 7"})})})}),s.jsx(_.h2,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.3},className:"text-2xl sm:text-3xl font-bold text-white mb-4",children:a("descargaExitoModal.titulo")}),s.jsx(_.p,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.4},className:"text-gray-300 mb-6 leading-relaxed",children:a("descargaExitoModal.mensaje")}),s.jsx(_.p,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.5},className:"text-sm text-gray-400 mb-8",children:a("descargaExitoModal.submensaje")}),s.jsx(_.div,{initial:{opacity:0}
3750,animate:{opacity:1},transition:{delay:.6},className:"flex justify-center gap-2 mb-8",children:[0,1,2].map(n=>s.jsx(_.div,{animate:{y:[0,-8,0]},transition:{duration:.6,delay:n*.1,repeat:1/0},className:"w-2 h-2 bg-cyan-400 rounded-full"},n))}),s.jsx(_.button,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.7},onClick:e,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-3 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 border-2 border-cyan-400",children:a("descargaExitoModal.boton")})]})]})})})})}function hte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState({nombre:"",email:"",cargo:"",empresa:"",sistemaOperativo:"",aceptaTerminos:!1}),[r,o]=k.useState(!1),[l,c]=k.useState(null),[d,u]=k.useState(!1),p=h=>{const{name:g,value:y,type:x,checked:v}=h.target;console.log(`Campo: ${g}, Tipo: ${x}, Valor: ${v||y}`),i({...n,[g]:x==="checkbox"?v:y}),g==="aceptaTerminos"&&v&&c(null)},m=async h=>{if(h.preventDefault(),!n.aceptaTerminos){c("error");return}o(!0),c(null);try{await Tl(ga(St,"mail"),{to:["[email protected]"],message:{subject:"Nueva descarga de HakaBuddy",html:` 3751 <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;"> 3752 <h2 style="color: #06b6d4;">Nueva descarga de HakaBuddy</h2> 3753 <div style="background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0;"> 3754 <p><strong>Nombre:</strong> ${n.nombre}</p> 3755 <p><strong>Email:</strong> ${n.email}</p> 3756 <p><strong>Cargo:</strong> ${n.cargo}</p> 3757 <p><strong>Empresa:</strong> ${n.empresa}</p> 3758 <p><strong>Sistema Operativo:</strong> ${n.sistemaOperativo}</p> 3759 </div> 3760 <p style="color: #6b7280; font-size: 12px;">Registro desde el formulario de descarga de hakalab.com</p> 3761 </div> 3762 `},timestamp:new Date}),u(!0),setTimeout(async()=>{const g={windows:"/descargas/version3.2.0.2/Hakabuddy-3.2.0.2-Windows.zip",mac:"/descargas/version3.2.0.2/Hakabuddy-3.2.0.2-OSX.zip",linux:"/descargas/version3.2.0.2/Hakabuddy-3.2.0.2-Linux.zip"},y=g[n.sistemaOperativo]||g.windows;try{const x=await fetch(y);if(!x.ok)throw new Error(`HTTP error! status: ${x.status}`);const v=await x.blob(),w=document.createElement("a");w.href=URL.createObjectURL(v),w.download=y.split("/").pop(),document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL(w.href)}catch(x){console.error("Error descargando archivo:",x)}},1e3),c("success"),i({nombre:"",email:"",cargo:"",empresa:"",sistemaOperativo:"",aceptaTerminos:!1}),setTimeout(()=>{c(null)},3e3)}catch(g){console.error("Error al enviar:",g),c("error")}finally{o(!1)}};return s.jsxs("section",{ref:t,className:"relative bg-dark py-16 sm:py-20 md:py-24",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs("div",{className:"relative rounded-3xl overflow-hidden",children:[s.jsx("div",{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/10 rounded-full blur-3xl -z-10"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl -z-10"}),s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-slate-800/40 to-slate-900/40 backdrop-blur-xl border border-white/10 rounded-3xl shadow-2xl shadow-cyan-500/20"}),s.jsx("div",{className:"relative p-8 sm:p-12 md:p-16",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx("h2",{className:"text-4xl sm:text-5xl font-bold text-white mb-6",children:a("hakabuddy.title")}),s.jsx("p",{className:"text-lg text-gray-300 leading-relaxed",children:a("hakabuddy.subtitle")}),s.jsx("img",{src:"/imagenes/productos/hakaboost_caracteristica.png",alt:"¿Qué hace Hakaboost?",className:"sm:w-full max-w-[150px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"bg-gradient-to-br from-slate-700/30 to-slate-800/30 rounded-2xl p-8 border border-cyan-400/20 backdrop-blur-md shadow-2xl shadow-cyan-500/10",children:s.jsxs("form",{onSubmit:m,className:"space-y-5",children:[s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"nombre",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("hakabuddy.nombre")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"nombre",name:"nombre",value:n.nombre,onChange:p,required:!0,placeholder:a("hakabuddy.nombrePlaceholder"),className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"email",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("contactModal.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"email",id:"email",name:"email",value:n.email,onChange:p,required:!0,placeholder:"[email protected]",className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"cargo",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("hakabuddy.cargo")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"cargo",name:"cargo",value:n.cargo,onChange:p,required:!0,placeholder:a("hakabuddy.cargoPlaceholder"),className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"empresa",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("contactModal.empresa")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"empresa",name:"empresa",value:n.empresa,onChange:p,required:!0,placeholder:a("hakabuddy.empresaPlaceholder"),className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"sistemaOperativo",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("hakabuddy.sistemaOperativo")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("select",{id:"sistemaOperativo",name:"sistemaOperativo",value:n.sistemaOperativo,onChange:p,required:!0,className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all text-sm backdrop-blur-sm hover:border-cyan-400/40",children:[s.jsx("option",{value:"",children:a("hakabuddy.sistemaOperativoPlaceholder")}),s.jsx("option",{value:"windows",children:"Windows"}),s.jsx("option",{value:"mac",children:"macOS"}),s.jsx("option",{value:"linux",children:"Linux"})]})]}),s.jsxs("div",{className:"flex items-start gap-3 pt-2",children:[s.jsx("input",{type:"checkbox",id:"aceptaTerminos",name:"aceptaTerminos",checked:n.aceptaTerminos,onChange:p,className:"mt-1 w-4 h-4 accent-cyan-400 cursor-pointer"}),s.jsxs("label",{htmlFor:"aceptaTerminos",className:"text-gray-300 text-sm cursor-pointer",children:[a("hakabuddy.aceptaTerminos")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]})]}),l==="success"&&s.jsx(_.div,{initial:{opacity:0,y:-10}
3762,animate:{opacity:1,y:0},className:"bg-green-500/20 border border-green-500 text-green-400 px-4 py-3 rounded-lg text-sm backdrop-blur-sm",children:a("hakabuddy.exitoDescarga")}),l==="error"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-red-500/20 border border-red-500 text-red-400 px-4 py-3 rounded-lg text-sm backdrop-blur-sm",children:a("hakabuddy.errorDescarga")}),s.jsx("button",{type:"submit",disabled:r,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-3 px-6 rounded-lg transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed border-2 border-cyan-400 mt-6 transform hover:-translate-y-0.5",children:r?s.jsxs("span",{className:"flex items-center justify-center gap-2",children:[s.jsxs("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[s.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),s.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),a("hakabuddy.descargando")]}):a("hakabuddy.descargar")})]})})]})})]})}),s.jsx(ie,{color:"#0a0e27",variant:1}),s.jsx(mte,{isOpen:d,onClose:()=>u(!1)})]})}function fte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),{t:i}=$(),r=i("hakabuddy_faq.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark py-10 sm:py-20 md:py-20 mt-10",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:i("hakabuddy_faq.titulo")}),s.jsx("p",{className:"text-gray-300 text-lg",children:i("hakabuddy_faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.05},className:"border border-primary/20 rounded-lg overflow-hidden hover:border-primary/50 transition-colors",children:[s.jsxs("button",{onClick:()=>n(a===l?-1:l),className:"w-full px-6 py-4 flex items-center justify-between bg-slate-800/30 hover:bg-slate-800/50 transition-colors",children:[s.jsx("h3",{className:"text-lg font-semibold text-white text-left",children:o.question}),s.jsx(_.div,{animate:{rotate:a===l?180:0},transition:{duration:.3},className:"flex-shrink-0 ml-4",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})})]}),s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:a===l?"auto":0,opacity:a===l?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"px-6 py-4 bg-slate-900/50 border-t border-primary/10",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:o.answer})})})]},l))})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function gte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaBuddy - Reportes de Testing con IA",description:"Herramienta de escritorio para generacion de reportes de testing con IA. Crea reportes manuales de forma inteligente en Windows y Mac.",path:"/hakabuddy"}),s.jsx(dte,{}),s.jsx(ute,{}),s.jsx(pte,{}),s.jsx(hte,{}),s.jsx(fte,{}),s.jsx(Zr,{title:"También te podrÃa interesar",productIds:[1,3,4,5,6]})]})}function yte(){const{t}=$(),e=k.useRef(null),a=we(e,{once:!0,margin:"-100px"});return s.jsx(s.Fragment,{children:s.jsxs("section",{ref:e,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:a?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakapathgif.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:a?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakapath_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-2",children:t("hakapath.titulo1")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:t("hakapath.gratis1")})]})]}
3762),s.jsx(ie,{color:"#0a0e27",variant:1})]})})}function xte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto mt-5",children:[s.jsx(_.h3,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-2xl font-bold text-white mt-5",children:a("hakapath.ayuda")}),s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakapath/jooljogmncojjfjoomhaamdbgjolnpkp",target:"_blank",rel:"noopener noreferrer",className:` 3763 w-48 bg-cyan-400 hover:bg-cyan-500 3764 text-[#0a0e27] font-bold 3765 py-3 rounded-full 3766 transition-all duration-300 3767 hover:shadow-lg hover:shadow-cyan-400/50 3768 transform hover:-translate-y-1 3769 mt-10 inline-block text-center 3770 `,children:a("hakapath.descargar")})]}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakapathgif2.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function vte(){const{t}=$();return s.jsx(s.Fragment,{children:s.jsxs("section",{className:"relative bg-dark pt-5",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-10",children:[s.jsx("h2",{className:"text-center text-3xl sm:text-3xl lg:text-4xl mb-4 sm:mb-6 md:mb-7 text-primary leading-tight sm:leading-snug",itemProp:"headline",children:t("potencia_hakapath.titulo")}),s.jsx("p",{className:"text-center text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakapath.descripcion1")}),s.jsx("p",{className:"text-center text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakapath.descripcion2")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakapath/jooljogmncojjfjoomhaamdbgjolnpkp",target:"_blank",rel:"noopener noreferrer",className:` 3771 w-48 bg-cyan-400 hover:bg-cyan-500 3772 text-[#0a0e27] font-bold 3773 py-3 rounded-full 3774 transition-all duration-300 3775 hover:shadow-lg hover:shadow-cyan-400/50 3776 transform hover:-translate-y-1 3777 mt-1 inline-block text-center 3778 `,children:t("hakapath.descargar")})})]}),s.jsx(ie,{color:"#0a0d29f5",variant:1})]})})}function bte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakapath_queHace.features",{returnObjects:!0}),i=a("hakapath_queHace.caracteristicasItems",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-24 pb-0",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakapath_queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakapath_queHace.descripcion1")}),s.jsx("p",{className:"text-gray-200 mb-8 leading-relaxed",children:a("hakapath_queHace.descripcion2")}),s.jsx("div",{className:"space-y-4",children:n.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-200 text-md",children:r})]},o))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakapath_quehace.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakapath_caracteristica.png",alt:"CaracterÃsticas",className:"w-full max-w-md h-auto"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakapath_queHace.caracteristicas")}),i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:r})]},o))]})]})})]}),s.jsx(ie,{variant:1})]})}function wte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),{t:i}=$(),r=i("hakapath_faq.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark py-10 sm:py-20 md:py-20",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:i("hakapath_faq.titulo")}),s.jsx("p",{className:"text-gray-300 text-lg",children:i("hakapath_faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.05},className:"border border-primary/20 rounded-lg overflow-hidden hover:border-primary/50 transition-colors",children:[s.jsxs("button",{onClick:()=>n(a===l?-1:l),className:"w-full px-6 py-4 flex items-center justify-between bg-slate-800/30 hover:bg-slate-800/50 transition-colors",children:[s.jsx("h3",{className:"text-lg font-semibold text-white text-left",children:o.question}),s.jsx(_.div,{animate:{rotate:a===l?180:0},transition:{duration:.3},className:"flex-shrink-0 ml-4",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})})]}),s.jsx(_.div,{initial:{height:0,opacity:0}
3778,animate:{height:a===l?"auto":0,opacity:a===l?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"px-6 py-4 bg-slate-900/50 border-t border-primary/10",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:o.answer})})})]},l))})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function kte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaPath - Planificacion y Ejecucion de Testing con IA",description:"Plataforma de ejecucion automatizada de pruebas con planificacion inteligente de testing impulsada por inteligencia artificial.",path:"/hakapath"}),s.jsx(yte,{}),s.jsx(xte,{}),s.jsx(vte,{}),s.jsx(bte,{}),s.jsx(wte,{}),s.jsx(Zr,{productIds:[1,2,4,5,6]})]})}function Ste(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsxs("section",{ref:t,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakartcgif.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakartc_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-3",children:a("hakartc.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:a("hakartc.hero.gratis")})]})]}),s.jsx(ie,{variant:1})]})}function _te(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto mt-5",children:[s.jsx(_.h3,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-2xl font-bold text-white mt-5",children:a("hakartc.presentacion.titulo")}),s.jsx("a",{href:"https://chromewebstore.google.com/detail/haka-rtc/jnmppgpcnckmiifheplcgcmapicdomkn",target:"_blank",rel:"noopener noreferrer",className:` 3779 w-48 bg-cyan-400 hover:bg-cyan-500 3780 text-[#0a0e27] font-bold 3781 py-3 rounded-full 3782 transition-all duration-300 3783 hover:shadow-lg hover:shadow-cyan-400/50 3784 transform hover:-translate-y-1 3785 mt-10 inline-block text-center 3786 `,children:a("hakartc.descargar")})]}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakartcgif2.gif",alt:"Hakartc Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function Ate(){const{t}=$();return s.jsx(s.Fragment,{children:s.jsxs("section",{className:"relative bg-dark pt-5",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-10",children:[s.jsx("h2",{className:"text-center text-3xl sm:text-3xl lg:text-4xl mb-4 sm:mb-6 md:mb-7 text-primary leading-tight sm:leading-snug",itemProp:"headline",children:t("potencia_hakartc.titulo")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakartc.descripcion1")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakartc.descripcion2")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("a",{href:"https://chromewebstore.google.com/detail/haka-rtc/jnmppgpcnckmiifheplcgcmapicdomkn",target:"_blank",rel:"noopener noreferrer",className:` 3787 w-48 bg-cyan-400 hover:bg-cyan-500 3788 text-[#0a0e27] font-bold 3789 py-3 rounded-full 3790 transition-all duration-300 3791 hover:shadow-lg hover:shadow-cyan-400/50 3792 transform hover:-translate-y-1 3793 mt-1 inline-block text-center 3794 `,children:t("hakartc.descargar")})})]}
3794),s.jsx(ie,{color:"#0a0d29f5",variant:1})]})})}function Ete(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakartc_queHace.features",{returnObjects:!0}),i=a("hakartc_queHace.caracteristicasItems",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-24 pb-0",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakartc_queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:s.jsx("div",{className:"space-y-4",children:n.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-200 text-md",children:r})]},o))})}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakartc_quehace.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakartc_caracteristicas.png",alt:"CaracterÃsticas",className:"w-full max-w-md h-auto"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakartc_queHace.caracteristicas")}),i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"â"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:r})]},o))]})]})})]}),s.jsx(ie,{variant:1})]})}function Cte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaRTC - Diseno de Casos de Prueba con IA",description:"Herramienta de diseno de casos de prueba asistida por inteligencia artificial para equipos de QA.",path:"/hakartc"}),s.jsx(Ste,{}),s.jsx(_te,{}),s.jsx(Ate,{}),s.jsx(Ete,{}),s.jsx(Zr,{productIds:[1,2,3,4,6]})]})}function jte(){const{t}=$(),e=k.useRef(null),a=we(e,{once:!0,margin:"-100px"});return s.jsx(s.Fragment,{children:s.jsxs("section",{ref:e,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow -mt-24"}),s.jsx("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-24 mb-14",children:s.jsxs(_.div,{initial:{opacity:0,y:30},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:a?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/Haka Insight_logo.png",alt:"Haka Insight Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-2 text-gray-300",children:"Analiza tu código y crea explicaciones simples con diagramas interactivos automáticamente"}),s.jsxs(_.h1,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:["Extensión gratuita para ",s.jsx("span",{className:"text-cyan-400",children:"VS Code"})]})]})}
3794),s.jsx(ie,{color:"#0a0e27",variant:1})]})})}function Tte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(!1);return s.jsxs(s.Fragment,{children:[s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 mt-10",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-24 md:pt-12 md:pb-14",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"text-3xl font-bold text-white mb-6",children:"¿Qué es Haka Insight?"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-lg text-gray-300 mb-8 leading-relaxed",children:"Una extensión de Visual Studio Code impulsada por inteligencia artificial que transforma la forma en que los desarrolladores comprenden y analizan código. Utilizando Google Gemini AI, convierte automáticamente tu código en diagramas interactivos mientras identifica vulnerabilidades de seguridad y evalúa la calidad del código, todo sin salir de tu IDE."}),s.jsx(_.h3,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-xl font-bold text-white mb-6",children:"Instala Haka Insight desde VS Code Marketplace"}),s.jsx("a",{href:"https://marketplace.visualstudio.com/items?itemName=hakalab.haka-insight",target:"_blank",rel:"noopener noreferrer",className:` 3795 inline-block w-64 bg-cyan-400 hover:bg-cyan-500 3796 text-[#0a0e27] font-bold 3797 py-3 px-8 rounded-full text-center 3798 transition-all duration-300 3799 hover:shadow-lg hover:shadow-cyan-400/50 3800 transform hover:-translate-y-1 3801 `,children:"Descargar Extensión"})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.4},className:"flex justify-center",children:s.jsxs("div",{className:"relative group cursor-pointer",onClick:()=>n(!0),children:[s.jsx("img",{src:"/video/haka-insight.gif",alt:"Haka Insight Demo",className:"w-full max-w-2xl h-auto drop-shadow-2xl rounded-lg transition-all duration-300 group-hover:scale-105"}),s.jsx("div",{className:"absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-lg flex items-center justify-center",children:s.jsx("svg",{className:"w-16 h-16 text-white",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"})})})]})})]})})}),s.jsx(La,{children:a&&s.jsxs(_.div,{initial:{opacity:0}
3801,animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/90",onClick:()=>n(!1),children:[s.jsx("button",{onClick:()=>n(!1),className:"absolute top-4 right-4 text-white hover:text-cyan-400 transition-colors duration-300 z-10",children:s.jsx("svg",{className:"w-10 h-10",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),s.jsx(_.div,{initial:{scale:.8,opacity:0},animate:{scale:1,opacity:1},exit:{scale:.8,opacity:0},transition:{duration:.3},className:"relative max-w-6xl w-full",onClick:i=>i.stopPropagation(),children:s.jsx("img",{src:"/video/haka-insight.gif",alt:"Haka Insight Demo",className:"w-full h-auto rounded-lg shadow-2xl"})})]})})]})}function Nte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),i=[{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"})}),title:"Diagramas Interactivos",description:"Genera automáticamente diagramas visuales de tu código mostrando archivos, clases, funciones y sus relaciones. Navega directamente al código haciendo clic en nodos."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"})}),title:"Análisis de Seguridad con IA",description:"Detecta vulnerabilidades de seguridad y las categoriza por severidad (Critical, High, Medium, Low) con scoring de riesgo automático."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"})}),title:"Métricas de Calidad",description:"Proporciona un score de calidad 0-100 con problemas categorizados (Bugs, Improvements, Performance, Best Practices) y recomendaciones accionables."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"})}),title:"Caché Inteligente",description:"Guarda automáticamente todos los análisis localmente para acceso instantáneo sin llamadas a la API. Ahorra ~70% en costos de API."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"Soporte Multi-Lenguaje",description:"Analiza código en JavaScript, TypeScript, Python, Java, C#, PHP, Ruby, Go y más. Interfaz bilingüe (Inglés/Español)."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),title:"Reportes Profesionales",description:"Crea reportes HTML profesionales de seguridad y calidad para compartir con tu equipo. Incluye resumen ejecutivo, hallazgos detallados y gráficos."}];return k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%i.length)},3e3);return()=>clearInterval(r)},[i.length]),s.jsx("section",{ref:t,className:"relative bg-dark py-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"CaracterÃsticas Principales"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Todo lo que necesitas para entender y mejorar tu código"})]}),s.jsxs("div",{className:"relative mb-20",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-cyan-400",initial:{width:"0%"},animate:{width:`${a/(i.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 z-20",animate:{left:`${a/(i.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 pt-20",children:i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:o*.1},className:"flex flex-col items-center text-center",children:[s.jsxs(_.div,{animate:{scale:a===o?1.2:1},transition:{duration:.6},className:"mb-4 relative",children:[s.jsx("div",{className:`absolute inset-0 rounded-full blur-lg transition-opacity duration-500 ${a>=o?"opacity-100":"opacity-0"}`,style:{background:"radial-gradient(circle, #06b6d4 0%, transparent 70%)",width:"100%",height:"100%"}}),s.jsx("div",{className:`transition-all duration-500 relative z-10 ${a>=o?"text-cyan-400":"text-gray-600"}`,style:{filter:a>=o?"drop-shadow(0 0 8px #06b6d4) drop-shadow(0 0 16px rgba(6, 182, 212, 0.5))":"none"},children:r.icon})]}
3801),s.jsxs(_.div,{animate:{opacity:a>=o?1:.5,scale:a===o?1.05:1},transition:{duration:.3},className:`p-4 rounded-lg border transition-all ${a>=o?"border-cyan-400/30 bg-cyan-400/5":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-2 text-sm lg:text-base ${a>=o?"text-cyan-400":"text-gray-400"}`,children:r.title}),s.jsx("p",{className:"text-xs lg:text-sm text-gray-200",children:r.description})]})]},o))})]}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.8},className:"mt-16 bg-gradient-to-r from-cyan-500/10 to-blue-500/10 p-8 rounded-2xl border border-cyan-400/30 relative",children:[s.jsxs(_.div,{initial:{scale:0,rotate:-180},animate:e?{scale:1,rotate:0}:{},transition:{duration:.8,delay:1},className:"absolute -top-6 -right-6 w-16 h-16 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-400/50 text-dark z-10",children:[s.jsx(Kk,{className:"w-8 h-8"}),s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-30"})]}),s.jsx("h3",{className:"text-2xl font-bold text-white mb-6 text-center",children:"¿Por qué elegir Haka Insight?"}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6",children:[s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"60-80%"}),s.jsx("div",{className:"text-gray-300",children:"Reducción en tiempo de comprensión de código"})]}),s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"~70%"}),s.jsx("div",{className:"text-gray-300",children:"Ahorro en costos de API con caché"})]}),s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"2 min"}),s.jsx("div",{className:"text-gray-300",children:"Setup completo y listo para usar"})]}),s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"Gratis"}),s.jsx("div",{className:"text-gray-300",children:"Con tu propia API key de Gemini"})]})]})]})]})})}function Ite(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),i=[{title:"Onboarding de Desarrolladores",problem:"Nuevo desarrollador necesita entender codebase complejo",solution:"Analiza archivos clave, genera diagramas, comprende arquitectura en minutos",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"})})},{title:"Code Review",problem:"Revisar PRs manualmente toma mucho tiempo",solution:"Análisis automático de seguridad y calidad antes de merge",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})})},{title:"AuditorÃa de Seguridad",problem:"Identificar vulnerabilidades en aplicación legacy",solution:"Escaneo completo con categorización por severidad y reportes",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})})},{title:"Refactoring",problem:"Necesitas mejorar calidad sin romper funcionalidad",solution:"Identifica áreas problemáticas con métricas objetivas",icon:s.jsxs("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]})},{title:"Documentación",problem:"Documentación de arquitectura desactualizada",solution:"Diagramas automáticos siempre actualizados con el código",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"})})},{title:"Due Diligence Técnico",problem:"Evaluar calidad de código antes de adquisición",solution:"Análisis completo con reportes profesionales para decisión",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})}];return k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%i.length)},5e3);return()=>clearInterval(r)},[i.length]),s.jsxs("section",{ref:t,className:"relative bg-[#0a0e27] py-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Casos de Uso Reales"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Cómo Haka Insight resuelve problemas del dÃa a dÃa"})]}),s.jsxs("div",{className:"relative max-w-5xl mx-auto mb-16",children:[s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0,x:100}
3801,animate:{opacity:1,x:0},exit:{opacity:0,x:-100},transition:{duration:.5},className:"bg-gradient-to-br from-slate-800/80 to-slate-900/80 p-10 rounded-2xl border-2 border-cyan-400/30 backdrop-blur-sm",children:s.jsxs("div",{className:"flex flex-col md:flex-row items-center gap-8",children:[s.jsx("div",{className:"flex-shrink-0",children:s.jsx("div",{className:"w-32 h-32 bg-gradient-to-br from-cyan-400/20 to-blue-500/20 rounded-2xl flex items-center justify-center border border-cyan-400/30 text-cyan-400",children:i[a].icon})}),s.jsxs("div",{className:"flex-1 text-center md:text-left",children:[s.jsx("h3",{className:"text-3xl font-bold text-white mb-4",children:i[a].title}),s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"bg-red-500/10 border border-red-400/30 rounded-lg p-4",children:[s.jsx("span",{className:"text-red-400 font-semibold text-lg",children:"Problema: "}),s.jsx("span",{className:"text-gray-300 text-lg",children:i[a].problem})]}),s.jsxs("div",{className:"bg-green-500/10 border border-green-400/30 rounded-lg p-4",children:[s.jsx("span",{className:"text-green-400 font-semibold text-lg",children:"Solución: "}),s.jsx("span",{className:"text-gray-300 text-lg",children:i[a].solution})]})]})]})]})},a)}),s.jsxs("div",{className:"flex items-center justify-center gap-4 mt-8",children:[s.jsx("button",{onClick:()=>n(r=>(r-1+i.length)%i.length),className:"w-10 h-10 rounded-full bg-slate-800 border border-cyan-400/30 hover:bg-cyan-400/20 transition-colors flex items-center justify-center text-cyan-400",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),s.jsx("div",{className:"flex gap-2",children:i.map((r,o)=>s.jsx("button",{onClick:()=>n(o),className:`transition-all duration-300 rounded-full ${o===a?"w-8 h-3 bg-cyan-400":"w-3 h-3 bg-gray-600 hover:bg-gray-500"}`},o))}),s.jsx("button",{onClick:()=>n(r=>(r+1)%i.length),className:"w-10 h-10 rounded-full bg-slate-800 border border-cyan-400/30 hover:bg-cyan-400/20 transition-colors flex items-center justify-center text-cyan-400",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]}),s.jsx("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 mt-8",children:i.map((r,o)=>s.jsxs(_.button,{onClick:()=>n(o),whileHover:{scale:1.05},className:`p-4 rounded-xl border transition-all ${o===a?"bg-cyan-400/20 border-cyan-400":"bg-slate-800/50 border-slate-700 hover:border-cyan-400/50"}`,children:[s.jsx("div",{className:`text-3xl mb-2 ${o===a?"text-cyan-400":"text-gray-500"}`,children:r.icon}),s.jsx("p",{className:`text-xs font-semibold ${o===a?"text-white":"text-gray-400"}`,children:r.title})]},o))})]})]}),s.jsx(ie,{color:"#0a0e27",variant:3})]})}function Pte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(null),i=[{question:"¿Haka Insight es realmente gratis?",answer:"SÃ, la extensión es completamente gratuita. Solo necesitas tu propia API key de Google Gemini, que también tiene un tier gratuito generoso. No hay costos ocultos ni suscripciones."},{question:"¿Qué lenguajes de programación soporta?",answer:"Haka Insight soporta múltiples lenguajes incluyendo JavaScript, TypeScript, Python, Java, C#, PHP, Ruby, Go y más. La IA de Gemini puede analizar prácticamente cualquier lenguaje de programación moderno."},{question:"¿Mis datos están seguros?",answer:"Absolutamente. Tu API key se almacena de forma segura usando VS Code Secret Storage. El código se envÃa directamente a la API de Google Gemini sin pasar por nuestros servidores. Además, el sistema de caché guarda los análisis localmente en tu máquina."},{question:"¿Cómo funciona el sistema de caché?",answer:"Cada vez que analizas un archivo, los resultados se guardan automáticamente en tu máquina. La próxima vez que abras ese análisis, se carga instantáneamente desde el caché sin hacer llamadas a la API, ahorrando tiempo y costos."},{question:"¿Puedo compartir los análisis con mi equipo?",answer:"SÃ, puedes generar reportes HTML profesionales que incluyen todos los hallazgos, diagramas y métricas. Estos reportes son fáciles de compartir por email o sistemas de gestión de proyectos."},{question:"¿Qué tan preciso es el análisis de seguridad?",answer:"Haka Insight utiliza Google Gemini AI, uno de los modelos de IA más avanzados. El análisis identifica vulnerabilidades comunes y las categoriza por severi
3801dad. Sin embargo, recomendamos usarlo como complemento a otras herramientas de seguridad y revisiones manuales."},{question:"¿Funciona con proyectos grandes?",answer:"SÃ, aunque actualmente analiza archivos individuales. El sistema de caché y los diagramas interactivos con zoom facilitan trabajar con bases de código grandes. Próximamente agregaremos análisis de múltiples archivos simultáneos."},{question:"¿Necesito conocimientos técnicos avanzados?",answer:"No, Haka Insight está diseñado para ser intuitivo. Si sabes usar VS Code, puedes usar Haka Insight. La interfaz es clara y los resultados se presentan de forma fácil de entender."},{question:"¿Puedo personalizar los análisis?",answer:"Actualmente puedes elegir entre dos modelos de IA (Gemini Flash para rapidez o Gemini Pro para análisis detallado) y cambiar el idioma de la interfaz. Estamos trabajando en reglas de análisis personalizables para futuras versiones."}];return s.jsx("section",{ref:t,className:"relative bg-dark py-20",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Preguntas Frecuentes"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Todo lo que necesitas saber sobre Haka Insight"})]}),s.jsx("div",{className:"space-y-4",children:i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:o*.05},className:"bg-slate-800/50 rounded-xl border border-slate-700 overflow-hidden",children:[s.jsxs("button",{onClick:()=>n(a===o?null:o),className:"w-full px-6 py-4 text-left flex justify-between items-center hover:bg-slate-700/30 transition-colors",children:[s.jsx("span",{className:"text-lg font-semibold text-white pr-4",children:r.question}),s.jsx("svg",{className:`w-6 h-6 text-cyan-400 flex-shrink-0 transition-transform ${a===o?"transform rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a===o&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.3},className:"px-6 pb-4",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:r.answer})})]},o))})]})})}function Rte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Haka Insight - Analisis de Codigo con IA",description:"Analisis inteligente de codigo fuente con IA para identificar riesgos y oportunidades de testing en tu proyecto.",path:"/haka-insight"}),s.jsx(jte,{}),s.jsx(Tte,{}),s.jsx(Nte,{}),s.jsx(Ite,{}),s.jsx(Pte,{}),s.jsx(Zr,{productIds:[1,2,3,4,5]})]})}function Lte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),i=[{label:"Web",path:"M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"},{label:"Mobile",path:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"},{label:"API",path:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"},{label:"BBDD",path:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"},{label:"Desktop",path:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},{label:"IA",path:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"}];return k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%i.length)},1500);return()=>clearInterval(r)},[i.length]),s.jsx(s.Fragment,{children:s.jsxs("section",{ref:t,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow -mt-24"}),s.jsx("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-24 mb-14",children:s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/haka automation ide.png",alt:"Haka Playwright Engine Logo",className:"sm:w-full max-w-[390px] sm:max-w-lg lg:max-w-xl h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-2 mb-2 text-gray-300",children:"Acelera la construcción de pruebas automatizadas hasta en un 80%"}),s.jsxs(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-5 mt-16 ",children:["Framework BDD con ",s.jsx("span",{className:"text-cyan-400",children:"1800+"})," Steps Múlticapa"]}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.7},className:"mt-0 flex flex-wrap items-center justify-center gap-3",children:i.map((r,o)=>s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsxs("div",{className:"flex flex-col items-center gap-1",children:[s.jsx("div",{className:` 3802 w-12 h-12 rounded-lg bg-slate-800/80 flex items-center justify-center 3803 transition-all duration-500 ease-in-out 3804 ${a===o?"border-2 border-cyan-400 shadow-[0_0_15px_rgba(34,211,238,0.6)] text-cyan-300 scale-110":"border border-cyan-400/30 text-cyan-400/60"} 3805 `,children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:r.path})})}),s.jsx("span",{className:`text-[10px] transition-all duration-500 ${a===o?"text-cyan-300":"text-gray-400"}`,children:r.label})]}),o<i.length-1&&s.jsx("span",{className:"text-cyan-400/40 font-bold text-lg",children:"+"})]},o))})]})}
3805),s.jsx(ie,{color:"#0a0e27",variant:1})]})})}function Ote(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(!1),[i,r]=k.useState(!1),[o,l]=k.useState(0),c=[{title:"Construcción de Feature",desc:"Escenarios BDD en Gherkin con +1.800 steps predefinidos. Soporta Scenario Outline con tablas de datos, Background compartido, tags para filtrar ejecución y variables dinámicas.",detail:"Asistido por Haka AI Studio (complemento VS Code con IA), el catálogo visual de Haka UI, grabación de flujos con Haka Conector, o documentación oficial. Sin escribir código Python."},{title:"Runner",desc:"Ejecuta los escenarios seleccionados por tags, en modo serial o paralelo. Selección inteligente de features según la matriz de pruebas.",detail:"Compatible con ejecución local y en pipelines de CI/CD (GitHub Actions, Azure Pipelines, GitLab CI). Soporta reintentos automáticos de escenarios fallidos y modo headless."},{title:"Ejecución en tiempo real",desc:"Chromium, Firefox, WebKit y Chrome real. Interacción realista: clicks, formularios, drag & drop, iframes, modales, scroll, teclado, uploads y descargas.",detail:"Self-healing con IA: si un localizador se rompe, el framework lo corrige automáticamente. Evidencia automática: screenshot por paso, grabación de video y data snapshots."},{title:"Reportes y Dashboards",desc:"Reportes HTML portables con screenshots embebidos, request/response de API, evaluaciones de IA y métricas de performance. Se generan automáticamente.",detail:"Integración push & play con Jira (comentarios + adjuntos), Xray Cloud (Test Executions), Azure DevOps, Cassini (dashboard centralizado) y Haka Lens."}];k.useEffect(()=>{const u=setInterval(()=>{l(p=>(p+1)%c.length)},3e3);return()=>clearInterval(u)},[c.length]);const d=[{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"})}),title:"1.800+ Steps Listos",description:"Pasos predefinidos para aplicaciones web, API, mobile, desktop, base de datos, performance, geolocalización, Gen AI y más."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),title:"Agentes de IA especializados",description:"Nuestro IDE integra agentes de IA especializados en construcción, ejecución y análisis de pruebas, que asisten en cada etapa del ciclo de calidad."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"})}),title:"Integración CI/CD",description:"Integra tus pruebas en pipelines de CI/CD para validación continua y automatizada, garantizando el gobierno de datos y la trazabilidad en cada ejecución."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),title:"Integración Plug & Play",description:"Integración push and play con Jira, Azure, Xray y dashboards personalizados. Conecta tu gestión de pruebas en minutos."}];return s.jsxs(s.Fragment,{children:[s.jsxs("section",{ref:t,className:"relative bg-dark pt-24 pb-20 mt-10",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:"CaracterÃsticas Principales"}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mb-6 mx-auto"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Haka Automation + IDE provee todo lo necesario para la automatización de pruebas en todas las capas del desarrollo de forma sencilla y segura, utilizando Inteligencia Artificial de forma estratég
3805ica desde la construcción hasta la ejecución, resultados y observabilidad."})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"relative rounded-2xl overflow-hidden border border-cyan-400/20 shadow-xl shadow-cyan-500/10",children:[!a&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900/90 z-10",children:[s.jsx("div",{className:"w-12 h-12 border-4 border-cyan-400/30 border-t-cyan-400 rounded-full animate-spin mb-4"}),s.jsx("p",{className:"text-gray-400 text-sm",children:"Cargando demo..."})]}),s.jsx("video",{autoPlay:!0,muted:!0,loop:!0,playsInline:!0,preload:"auto",className:`w-full h-auto transition-opacity duration-500 ${a?"opacity-100":"opacity-0"}`,onCanPlayThrough:()=>n(!0),onLoadedData:()=>n(!0),onError:()=>n(!0),children:s.jsx("source",{src:"/video/haka-engine-demo.mp4",type:"video/mp4"})})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.4},className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:d.map((u,p)=>s.jsxs(_.div,{initial:{opacity:0,y:15},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:.5+p*.15},className:"flex gap-4 p-5 rounded-xl border border-gray-700/50 bg-gray-800/30 hover:border-cyan-400/40 hover:bg-cyan-400/5 transition-all duration-300",children:[s.jsx("div",{className:"flex-shrink-0 text-cyan-400 mt-1",children:u.icon}),s.jsxs("div",{children:[s.jsx("h3",{className:"font-bold text-white text-lg mb-1",children:u.title}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:u.description})]})]},p))})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start mt-24",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.3},className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),title:"Grabación de flujos",description:"Captura un flujo funcional directamente desde el navegador y genera la prueba automáticamente, sin escribir código."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"})}),title:"Sesiones 2FA/MFA",description:"Sesiones almacenadas para sistemas con doble factor de autenticación: login manual una vez, ejecución automática siempre."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),title:"Evidencia automática",description:"Screenshot por paso, grabación de video y data snapshots generados automáticamente en cada corrida, sin configuración adicional."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zm0 8a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zm12 0a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"})}),title:"Validación de Gen AI",description:"Steps dedicados para probar servicios de IA generativa: evalúa respuestas de modelos y valida la calidad de las salidas dentro de tus escenarios."}].map((u,p)=>s.jsxs(_.div,{initial:{opacity:0,y:15},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:.5+p*.15},className:"flex gap-4 p-5 rounded-xl border border-gray-700/50 bg-gray-800/30 hover:border-cyan-400/40 hover:bg-cyan-400/5 transition-all duration-300",children:[s.jsx("div",{className:"flex-shrink-0 w-12 h-12 rounded-lg bg-cyan-400/10 border border-cyan-400/30 flex items-center justify-center text-cyan-400",children:u.icon}),s.jsxs("div",{children:[s.jsx("h3",{className:"font-bold text-white text-lg mb-1",children:u.title}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:u.description})]})]},p))}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.4},className:"relative rounded-2xl overflow-hidden border border-cyan-400/20 shadow-xl shadow-cyan-500/10 sticky top-8",children:[!i&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900/90 z-10",children:[s.jsx("div",{className:"w-12 h-12 border-4 border-cyan-400/30 border-t-cyan-400 rounded-full animate-spin mb
3805-4"}),s.jsx("p",{className:"text-gray-400 text-sm",children:"Cargando demo..."})]}),s.jsx("video",{autoPlay:!0,muted:!0,loop:!0,playsInline:!0,preload:"auto",className:`w-full h-auto transition-opacity duration-500 ${i?"opacity-100":"opacity-0"}`,onCanPlayThrough:()=>r(!0),onLoadedData:()=>r(!0),onError:()=>r(!0),children:s.jsx("source",{src:"/video/haka-engine-tools-v2.mp4",type:"video/mp4"})})]})]})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsxs("section",{className:"relative bg-dark pt-32 pb-20",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.8},children:[s.jsx("h3",{className:"text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:"Flujo de acción"}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mb-12"}),s.jsx("div",{className:"space-y-6",children:c.map((u,p)=>s.jsxs("div",{className:` 3806 grid grid-cols-1 lg:grid-cols-[1fr_auto_1fr] gap-4 items-center 3807 transition-all duration-700 ease-in-out 3808 ${o===p?"scale-[1.02]":"scale-100 opacity-70"} 3809 `,style:{marginLeft:`${p*40}px`},children:[s.jsxs("div",{className:` 3810 p-5 rounded-xl border-l-4 transition-all duration-700 3811 ${o===p?"border-cyan-400 bg-cyan-400/10 shadow-lg shadow-cyan-400/20":"border-cyan-400/30 bg-slate-800/50"} 3812 `,children:[s.jsx("h4",{className:`font-bold text-lg mb-2 transition-colors duration-500 ${o===p?"text-cyan-300":"text-cyan-400/70"}`,children:u.title}),s.jsx("p",{className:`text-sm transition-colors duration-500 ${o===p?"text-gray-200":"text-gray-400"}`,children:u.desc})]}),s.jsxs("div",{className:"hidden lg:flex items-center gap-1 px-2",children:[s.jsx("div",{className:`w-8 border-t-2 border-dashed transition-colors duration-500 ${o===p?"border-cyan-400":"border-cyan-400/30"}`}),s.jsx("div",{className:`w-2 h-2 rounded-full transition-all duration-500 ${o===p?"bg-cyan-400 shadow-[0_0_8px_rgba(34,211,238,0.8)]":"bg-cyan-400/40"}`}),s.jsx("div",{className:`w-2 h-2 rounded-full transition-all duration-500 ${o===p?"bg-cyan-400/80":"bg-cyan-400/20"}`}),s.jsx("div",{className:`w-8 border-t-2 border-dashed transition-colors duration-500 ${o===p?"border-cyan-400":"border-cyan-400/30"}`})]}),s.jsx("div",{className:` 3813 p-4 rounded-xl border border-dashed transition-all duration-700 3814 ${o===p?"border-cyan-400/60 bg-cyan-400/5 shadow-md shadow-cyan-400/10":"border-gray-500/30 bg-gray-800/20"} 3815 `,children:s.jsx("p",{className:`text-sm transition-colors duration-500 ${o===p?"text-gray-300":"text-gray-500"}`,children:u.detail})})]},p))})]})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})]})}function Mte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(null),i=[{question:"¿Necesito saber programar para usar el framework?",answer:"El framework resuelve +95% de los casos sin necesidad de escribir código, y los asistentes de IA pueden aumentar aún más ese porcentaje. Sin embargo, se considera necesario tener nociones de Python y Playwright para construir pasos personalizados cuando el flujo requiera una casuÃstica o paso demasiado especializado o particular."},{question:"¿Qué tipos de pruebas puedo automatizar?",answer:"Pruebas web (cualquier navegador), API REST, mobile (Android/iOS con Appium), desktop (PyAutoGUI), base de datos, y combinaciones de todas ellas en un mismo escenario."},{question:"¿Cómo maneja los selectores que se rompen?",answer:"El JSON POM soporta fallbacks: si el selector principal falla, el framework prueba automáticamente los alternativos. Con IA activa, puede encontrar selectores nuevos sin intervención."},{question:"¿Funciona con sistemas que tienen MFA/2FA?",answer:"SÃ. Las sesiones guardadas permiten hacer login manualmente una vez (incluyendo MFA) y reutilizar el estado del navegador en todas las ejecuciones posteriores."},{question:"¿Se integra con Jira y herramientas de gestión?",answer:"SÃ. Se integra con Xray Cloud para reportar resultados, con Cassini para gestión de ejecuciones, y con Haka Lens para crear bugs automáticamente cuando un test falla."},{question:"¿Puedo ejecutar tests en paralelo?",answer:"SÃ. Configurando PARALLEL_WORKERS en el .env, el framework ejecuta múltiples features simultáneamente, cada uno con su propio navegador."},{question:"¿Es compatible con CI/CD?",answer:"Totalmente. Funciona en GitHub Actions, GitLab CI, Jenkins y cualquier pipeline. Solo necesita Python y el pip install. Genera reportes HTML y screenshots automáticos en fallos."}];return s.jsx("section",{ref:t,className:"relative bg-dark py-20",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Preguntas Frecuentes"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Lo que más nos preguntan sobre el framework"})]}),s.jsx("div",{className:"space-y-4",children:i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:o*.05},className:"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden",children:[s.jsxs("button",{onClick:()=>
3815n(a===o?null:o),className:"w-full px-6 py-5 flex items-center justify-between text-left hover:bg-slate-700/30 transition-colors",children:[s.jsx("span",{className:"font-semibold text-white text-lg pr-4",children:r.question}),s.jsx("svg",{className:`w-5 h-5 text-emerald-400 flex-shrink-0 transition-transform ${a===o?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a===o&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},transition:{duration:.3},className:"px-6 pb-5",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:r.answer})})]},o))})]})})}function Dte(){const{isOpen:t,modalTitle:e,openModal:a,closeModal:n}=oa();return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Haka Playwright Engine - Framework de Testing Automatizado",description:"Framework de testing automatizado basado en Playwright con soporte BDD, ejecucion en paralelo, reportes integrados y compatibilidad mobile.",path:"/haka-engine"}),s.jsx(Lte,{}),s.jsx(Ote,{}),s.jsx("section",{className:"relative bg-dark py-20 mt-16",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},children:[s.jsx("svg",{className:"w-10 h-10 text-cyan-400/40 mb-4",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z"})}),s.jsx("blockquote",{className:"text-xl md:text-2xl text-gray-200 font-light leading-relaxed italic mb-6",children:'"Con la generación de código con IA, se le está pidiendo a los equipos que validen un orden de magnitud más de código manteniendo la misma capacidad de QA. El resultado es un cuello de botella en las pruebas: los lanzamientos se frenan, las funciones de IA se acumulan en preproducción y los equipos de ingenierÃa reciben la presión por limitaciones que ellos no crearon. La respuesta no es ralentizar la innovación, sino hacer evolucionar la ingenierÃa de calidad al mismo ritmo que la generación de código."'}),s.jsx("a",{href:"https://kms-technology.com/blog/the-testing-bottleneck-how-ai-coding-broke-qa-and-how-to-fix-it/",target:"_blank",rel:"noopener noreferrer",className:"text-cyan-400 text-sm hover:underline",children:"KMS Technology â The Testing Bottleneck"})]}),s.jsx(_.div,{initial:{opacity:0,x:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"relative",children:s.jsxs("div",{className:"relative bg-gradient-to-br from-[#1a1d3a] to-[#0a0e27] rounded-2xl border border-gray-700/50 shadow-2xl overflow-hidden",children:[s.jsxs("div",{className:"bg-[#2a2d4a] px-4 py-3 flex items-center gap-2 border-b border-gray-700/50",children:[s.jsxs("div",{className:"flex gap-2",children:[s.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"})]}),s.jsx("span",{className:"text-gray-400 text-sm ml-4",children:"Haka Automation Engine"})]}),s.jsxs("div",{className:"p-8 sm:p-10 text-center",children:[s.jsxs("h2",{className:"text-lg md:text-xl font-normal text-white mb-4",children:["En ",s.jsxs("span",{className:"font-bold",children:[s.jsx("span",{className:"text-cyan-400",children:"Haka"})," Lab"]})," tenemos la tecnologÃa, la metodologÃa y las personas que pueden ayudar a tus equipos de desarrollo a alcanzar sus objetivos con calidad"]}),s.jsx("button",{onClick:()=>a("Solicitar demo de Haka Automation Engine"),className:"mt-6 inline-block px-8 py-3 bg-transparent border-2 border-cyan-400 text-cyan-400 rounded-2xl font-semibold hover:bg-cyan-400 hover:text-[#0a0e27] transition-all duration-300 transform hover:scale-105",children:"Solicitar una demo"})]})]})})]})})}),s.jsx(Mte,{}),s.jsx(Zr,{productIds:[0,1,3,5]}),s.jsx(Yr,{isOpen:t,onClose:n,title:e})]})}function qte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsxs("section",{ref:t,className:"relative bg-dark pt-20 pb-16 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakaistudio_hero.png",alt:"Haka AI Studio Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakaistudio_logo.png",alt:"Haka AI Studio Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-xl w-full mt-3 text-gray-300",children:a("hakaistudio.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mt-3",children:a("hakaistudio.hero.exclusivo")}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.6},className:"mt-6 flex flex-wrap justify-center gap-2",children:[["VS Code","Kiro","Antigravity","Cursor","Windsurf"].map(n=>s.jsx("span",{className:"px-3 py-1 bg-cyan-400/10 border border-cyan-400/40 text-cyan-300 text-sm font-medium rounded-full",children:n},n)),s.jsx("span",{className:"px-3 py-1 bg-violet-400/10 border border-violet-400/40 text-violet-300 text-sm font-medium rounded-full",children:"+ cualquier editor VSX"})]}),s.jsxs(_.a,{href:"https://open-vsx.org/extension/HakaLabChile/haka-ai-studio",target:"_blank",rel:"noopener noreferrer",initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.7},className:"mt-6 inline-flex items-center gap-3 bg-cyan-400 hover:bg-cyan-300 text-[#0a0e27] font-bold px-8 py-3 rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 transform hover:-translate-y-1",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"})}),"Descargar en Open VSX"]}),s.jsx(_.p,{initial:{opacity:0}
3815,animate:e?{opacity:1}:{},transition:{duration:.6,delay:.8},className:"mt-3 text-sm text-gray-500",children:"O búscalo directamente en el marketplace de tu editor favorito"})]})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function zte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState(0),r=[{icon:s.jsxs("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]}),title:a("hakaistudio.presentacion.etapas.automatizacion.titulo"),description:a("hakaistudio.presentacion.etapas.automatizacion.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"})}),title:a("hakaistudio.presentacion.etapas.seguridad.titulo"),description:a("hakaistudio.presentacion.etapas.seguridad.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),title:a("hakaistudio.presentacion.etapas.ia.titulo"),description:a("hakaistudio.presentacion.etapas.ia.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"})}),title:a("hakaistudio.presentacion.etapas.talento.titulo"),description:a("hakaistudio.presentacion.etapas.talento.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"})}),title:a("hakaistudio.presentacion.etapas.impacto.titulo"),description:a("hakaistudio.presentacion.etapas.impacto.descripcion")}];return k.useEffect(()=>{const o=setInterval(()=>{i(l=>(l+1)%r.length)},3e3);return()=>clearInterval(o)},[r.length]),s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-16 sm:pt-40 pb-20 text-center overflow-hidden",children:s.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"text-4xl md:text-5xl font-bold text-white mb-6",children:a("hakaistudio.presentacion.titulo")}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-xl text-gray-300 mb-8 max-w-4xl mx-auto",children:a("hakaistudio.presentacion.subtitulo")}),s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"inline-flex items-center gap-3 bg-gradient-to-r from-violet-500/20 to-cyan-500/20 border border-violet-400/30 rounded-full px-6 py-3 mb-16",children:[s.jsx("svg",{className:"w-5 h-5 text-violet-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"})}),s.jsxs("span",{className:"text-sm text-gray-300",children:["Extensión ",s.jsx("span",{className:"text-violet-300 font-semibold",children:"VSX"})," compatible con"," ",s.jsx("span",{className:"text-cyan-300 font-semibold",children:"VS Code · Kiro · Antigravity · Cursor · Windsurf"})]})]}),s.jsxs("div",{className:"relative mt-16",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-gradient-to-r from-blue-500 to-purple-500",initial:{width:"0%"},animate:{width:`${n/(r.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-gradient-to-r from-blue-500 to-purple-500 rounded-full shadow-lg shadow-blue-500/50 z-20",animate:{left:`${n/(r.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-blue-500 animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-5 ga
3815p-4 pt-20",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.5+l*.1},className:"flex flex-col items-center text-center",children:[s.jsx(_.div,{animate:{scale:n===l?1.2:n>=l?1.05:1,rotate:n>=l?360:0},transition:{duration:.6},className:"mb-4 relative",children:s.jsx("div",{className:`transition-all duration-500 relative z-10 ${n>=l?"text-blue-400":"text-gray-600"}`,style:{filter:n>=l?"drop-shadow(0 0 8px rgba(59, 130, 246, 0.8)) drop-shadow(0 0 16px rgba(59, 130, 246, 0.4))":"none"},children:o.icon})}),s.jsxs(_.div,{animate:{opacity:n>=l?1:.5,scale:n===l?1.05:1},transition:{duration:.3},className:`p-4 rounded-lg border transition-all ${n>=l?"border-blue-500/30 bg-blue-500/10":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-2 text-sm lg:text-base ${n>=l?"text-blue-400":"text-gray-500"}`,children:o.title}),s.jsx("p",{className:"text-xs lg:text-sm text-gray-300",children:o.description})]})]},l))})]})]})})}function Vte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakaistudio.queHace.beneficios",{returnObjects:!0});return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.queHace.titulo")}),s.jsx("p",{className:"text-xl text-gray-400",children:a("hakaistudio.queHace.subtitulo")})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},animate:e?{opacity:1,x:0}:{},transition:{duration:.8},className:"flex flex-col items-center lg:items-start text-center lg:text-left",children:[s.jsx(_.div,{initial:{scale:.5,opacity:0},animate:e?{scale:1,opacity:1}:{},transition:{duration:1,delay:.3},className:"relative",children:s.jsx(_.h3,{animate:{textShadow:["0 0 20px rgba(6, 182, 212, 0.5)","0 0 40px rgba(6, 182, 212, 0.8)","0 0 20px rgba(6, 182, 212, 0.5)"]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},className:"text-8xl md:text-9xl font-black text-cyan-400 relative z-10",style:{textShadow:"0 0 30px rgba(6, 182, 212, 0.6)"},children:"70~80%"})}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-xl md:text-2xl text-gray-300 mt-6 max-w-md",children:a("hakaistudio.queHace.reduccion")})]}),s.jsx(_.div,{initial:{opacity:0,x:50},animate:e?{opacity:1,x:0}:{},transition:{duration:.8,delay:.2},className:"space-y-6",children:n.map((i,r)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.4+r*.1},className:"flex items-start gap-4 group",children:[s.jsx(_.div,{whileHover:{scale:1.2,rotate:360},transition:{duration:.5},className:"flex-shrink-0 mt-1",children:s.jsx("svg",{className:"w-7 h-7 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",style:{filter:"drop-shadow(0 0 6px rgba(6, 182, 212, 0.6))"},children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2.5,d:"M5 13l4 4L19 7"})})}),s.jsx("p",{className:"text-lg text-gray-300 group-hover:text-white transition-colors duration-300",children:i})]},r))})]})]})})}function Hte({variant:t=1}){const e="#1e3a8a",a="#0a0e27",n={1:"M0,0L0,40L48,45.3C96,51,192,61,288,66.7C384,72,480,72,576,66.7C672,61,768,51,864,56C960,61,1056,83,1152,88C1248,93,1344,83,1392,77.3L1440,72L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",2:"M0,0L0,40L48,34.7C96,29,192,19,288,24C384,29,480,51,576,56C672,61,768,51,864,45.3C960,40,1056,40,1152,34.7C1248,29,1344,19,1392,13.3L1440,8L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",3:"M0,0L0,40L48,45.3C96,51,192,61,288,56C384,51,480,29,576,24C672,19,768,29,864,40C960,51,1056,61,1152,61.3C1248,61,1344,51,1392,45.3L1440,40L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"},i=`waveGradBlue-${t}`;return s.jsx("div",{className:"absolute bottom-0 left-0 w-full overflow-visible pointer-events-none",style:{height:"clamp(60px, 15vw, 120px)",transform:"translateY(100%)",zIndex:10},children:s.jsxs("svg",{className:"w-full h-full overflow-visible",viewBox:"0 0 1440 100",preserveAspectRatio:"xMidYMid slice",xmlns:"http://www.w3.org/2000/svg",style:{filter:"drop-shadow(0px 18px 10px rgba(0, 0, 0, 0.8))"},children:[s.jsx("defs",{children:s.jsxs("linearGradient",{id:i,x1:"0%",y1:"0%",x2:"0%",y2:"100%",children:[s.jsx("stop",{offset:"0%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"50%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"100%",stopColor:a,stopOpacity:"1"})]})}),s.jsx("path",{fill:`url(#${i})`,d:n[t]})]})})}function Fte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=[{aspecto:a("hakaistudio.comparativa.tabla.tiempo.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.tiempo.sin"),conHaka:a("hakaistudio.comparativa.tabla.tiempo.con")},{aspecto:a("hakaistudio.comparativa.tabla.seguridad.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.seguridad.sin"),conHaka:a("hakaistudio.comparativa.tabla.seguridad.con")},{aspecto:a("hakaistudio.comparativa.tabla.selectores.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.selectores.sin"),conHaka:a("hakaistudio.comparativa.tabla.selectores.con")},{aspecto:a("hakaistudio.comparativa.tabla.reutilizacion.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.reutilizacion.sin"),conHaka:a("hakaistudio.comparativa.tabla.reutilizacion.con")},{aspecto:a("hakaistudio.comparativa.tabla.formato.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.formato.sin"),conHaka:a("hakaistudio.comparativa.tabla.formato.con")},{aspecto:a("hakaistudio.comparativa.tabla.mantenimiento.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.mantenimiento.sin"),conHaka:a("hakaistudio.comparativa.tabla.mantenimiento.con")}];return s.jsxs("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 py-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.comparativa.titulo")}),s.jsx("p",{className:"text-xl text-gray-400",children:a("hakaistudio.comparativa.subtitulo")})]}),s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"overflow-hidden rounded-2xl border border-slate-700/50 bg-slate-900/50 backdrop-blur-sm",children:s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full",children:[s.jsx("thead",{children:s.jsxs("tr",{className:"bg-gradient-to-r from-slate-800 to-slate-900",children:[s.jsx("th",{className:"px-6 py-4 text-left text-sm font-bold text-white uppercase tracking-wider border-b border-slate-700/50",children:a("hakaistudio.comparativa.aspecto")}),s.jsx("th",{className:"px-6 py-4 text-left text-sm font-bold text-red-400 uppercase tracking-wider border-b border-slate-700/50",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),a("hakaistudio.comparativa.sinHaka")]})}),s.jsx("th",{className:"px-6 py-4 text-left text-sm font-bold text-green-400 uppercase tracking-wider border-b border-slate-700/50",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),a("hakaistudio.comparativa.conHaka")]})})]})}),s.jsx("tbody",{children:n.map((i,r)=>s.jsxs(_.tr,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.4,delay:.3+r*.05},className:"border-b border-slate-700/30 hover:bg-slate-800/30 transition-colors duration-200",children:[s.jsx("td",{className:"px-6 py-4 text-white font-semibold",children:i.aspecto}),s.jsx("td",{className:"px-6 py-4 text-gray-300",children:i.sinHaka}),s.jsx("td",{className:"px-6 py-4 text-gray-300 bg-green-900/5",children:i.conHaka})]},r))})]})})}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.8},className:"mt-12 relative overflow-hidden rounded-xl",children:[s.jsx("div",{className:"absolute inset-0 opacity-20",style:{background:"radial-gradient(circle at center, #06b6d4 0%, transparent 70%)"}}),s.jsx("div",{className:"relative bg-gradient-to-r from-cyan-500/20 via-blue-500/20 to-purple-500/20 border border-cyan-500/50 rounded-xl p-6 text-center backdrop-blur-sm",children:s.jsxs(_.div,{animate:{scale:[1,1.02,1]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},children:[s.jsx("p",{className:"text-2xl font-bold text-white mb-2",children:a("hakaistudio.comparativa.destacado.titulo")}),s.jsx("p",{className:"text-lg text-cyan-400 font-semibold",children:a("hakaistudio.comparativa.destacado.descripcion")})]})})]})]}),s.jsx(Hte,{variant:1})]})}function Bte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState(0);k.useEffect(()=>{if(!e)return;const o=setInterval(()=>{i(l=>(l+1)%5)},2e3);return()=>clearInterval(o)},[e]);const r=[{titulo:a("hakaistudio.casosUso.frontEnd.titulo"),descripcion:a("hakaistudio.casosUso.frontEnd.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})},{titulo:a("hakaistudio.casosUso.backend.titulo"),descripcion:a("hakaistudio.casosUso.backend.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"})})},{titulo:a("hakaistudio.casosUso.regresion.titulo"),descripcion:a("hakaistudio.casosUso.regresion.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})})},{titulo:a("hakaistudio.casosUso.ayudante.titulo"),descripcion:a("hakaistudio.casosUso.ayudante.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.25
38155-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})})}];return s.jsx("section",{ref:t,className:"relative bg-[#0a0e27] pt-20 pb-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16 mt-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.casosUso.titulo").toUpperCase()}),s.jsx("div",{className:"w-24 h-1 bg-cyan-400 mx-auto mb-6"}),s.jsx("p",{className:"text-lg text-gray-300 max-w-3xl mx-auto",children:a("hakaistudio.casosUso.subtitulo")})]}),s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 max-w-5xl mx-auto",children:r.map((o,l)=>s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.1},className:"group relative",children:s.jsxs("div",{className:`relative h-full bg-[#0f1629] border-2 rounded-lg p-6 transition-all duration-500 ${n===l?"border-cyan-400 shadow-lg shadow-cyan-500/50 scale-105":"border-cyan-500/30 hover:border-cyan-400 hover:shadow-lg hover:shadow-cyan-500/20"}`,children:[n===l&&s.jsx(_.div,{initial:{opacity:0}
3815,animate:{opacity:[0,.3,0]},transition:{duration:1.5,repeat:1/0},className:"absolute inset-0 bg-gradient-to-br from-cyan-400/20 via-transparent to-transparent rounded-lg"}),s.jsx("div",{className:`mb-6 transition-all duration-500 ${n===l?"text-cyan-300 scale-110":"text-cyan-400"}`,children:o.icon}),s.jsx("h3",{className:"text-xl font-bold text-white mb-4 relative z-10",children:o.titulo}),s.jsx("p",{className:"text-gray-300 leading-relaxed text-sm relative z-10",children:o.descripcion})]})},l))}),s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.4},className:"mt-6 group relative",children:s.jsxs("div",{className:`relative bg-[#0f1629] border-2 rounded-lg p-6 transition-all duration-500 ${n===4?"border-cyan-400 shadow-lg shadow-cyan-500/50 scale-[1.02]":"border-cyan-500/30 hover:border-cyan-400 hover:shadow-lg hover:shadow-cyan-500/20"}`,children:[n===4&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:[0,.3,0]},transition:{duration:1.5,repeat:1/0},className:"absolute inset-0 bg-gradient-to-br from-cyan-400/20 via-transparent to-transparent rounded-lg"}),s.jsxs("div",{className:"flex items-start gap-6",children:[s.jsx("div",{className:`flex-shrink-0 transition-all duration-500 ${n===4?"text-cyan-300 scale-110":"text-cyan-400"}`,children:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})})}),s.jsxs("div",{className:"flex-1 relative z-10",children:[s.jsx("h3",{className:"text-xl font-bold text-white mb-4",children:a("hakaistudio.casosUso.talento.titulo")}),s.jsx("p",{className:"text-gray-300 leading-relaxed",children:a("hakaistudio.casosUso.talento.descripcion")})]})]})]})})]})})}function Ute(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState(null),r=a("hakaistudio.faq.items",{returnObjects:!0}),o=l=>{i(n===l?null:l)};return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.faq.titulo")}),s.jsx("p",{className:"text-xl text-gray-400",children:a("hakaistudio.faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((l,c)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:c*.1},className:"bg-slate-800/50 backdrop-blur-sm rounded-xl border border-slate-700 overflow-hidden",children:[s.jsxs("button",{onClick:()=>o(c),className:"w-full p-6 text-left flex justify-between items-center hover:bg-slate-800/70 transition-colors",children:[s.jsx("span",{className:"text-lg font-semibold text-white pr-8",children:l.question}),s.jsx("span",{className:"text-2xl text-blue-400 flex-shrink-0",children:n===c?"â":"+"})]}),s.jsx(_.div,{initial:!1,animate:{height:n===c?"auto":0,opacity:n===c?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"p-6 pt-0 text-gray-300 leading-relaxed",children:l.answer})})]},c))})]})})}function $te(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Haka AI Studio - Automatizacion de Testing con IA en VS Code",description:"Extension de VS Code para automatizacion de pruebas end-to-end con inteligencia artificial y soporte BDD completo.",path:"/haka-ai-studio"}),s.jsx(qte,{}),s.jsx(zte,{}),s.jsx(Vte,{}),s.jsx(Fte,{}),s.jsx(Bte,{}),s.jsx(Ute,{}),s.jsx(Zr,{title:"También te podrÃa interesar",productIds:[1,2,3,4,5]})]})}function Wte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-20 pb-16 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex flex-col items-center mb-8",children:[s.jsxs("h1",{className:"text-5xl md:text-6xl font-black text-white mb-2",children:["Haka ",s.jsx("span",{className:"text-cyan-400",children:"Lens"})]}),s.jsx("span",{className:"text-sm text-gray-500 font-mono",children:"v9.0"})]}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"text-xl md:text-2xl text-gray-300 mb-6 max-w-3xl mx-auto",children:"Plataforma de gestión de QA nativa para Jira Cloud. Centraliza pruebas, planes, ejecuciones y cobertura sin salir de tu flujo de trabajo."}),s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"text-3xl font-bold text-white mb-8",children:"QA integrado donde tus equipos ya trabajan"}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"flex flex-wrap justify-center gap-2 mb-8",children:["Jira Cloud","Atlassian Forge","Bilingue (EN/ES)","CI/CD API"].map(a=>s.jsx("span",{className:"px-3 py-1 bg-cyan-400/10 border border-cyan-400/40 text-cyan-300 text-sm font-medium rounded-full",children:a},a))}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"flex flex-wrap justify-center gap-4 mb-6",children:[s.jsxs("a",{href:"https://marketplace.atlassian.com",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-3 bg-cyan-400 hover:bg-cyan-300 text-[#0a0e27] font-bold px-8 py-3 rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 transform hover:-translate-y-1",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"})}),"Instalar desde Atlassian Marketplace"]}),s.jsxs("a",{href:"/hakalens/docs",className:"inline-flex items-center gap-3 bg-transparent border-2 border-cyan-400/60 text-cyan-300 hover:bg-cyan-400/10 font-bold px-8 py-3 rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/20 transform hover:-translate-y-1",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"})}),"Documentacion"]})]}),s.jsxs(_.div,{initial:{opacity:0}
3815,animate:e?{opacity:1}:{},transition:{duration:.6,delay:.6},className:"flex flex-wrap justify-center gap-6 text-sm text-gray-500",children:[s.jsx("a",{href:"/hakalens/docs",className:"hover:text-cyan-400 transition-colors",children:"API de Automatizacion"}),s.jsx("a",{href:"/hakalens/docs",className:"hover:text-cyan-400 transition-colors",children:"Plugins CI/CD"}),s.jsx("a",{href:"/hakalens/docs",className:"hover:text-cyan-400 transition-colors",children:"Soporte"})]})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function Gte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"});return s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-16 sm:pt-24 pb-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl md:text-5xl font-bold text-white mb-6 text-center",children:"Que es Haka Lens?"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"text-xl text-gray-300 mb-12 max-w-4xl mx-auto text-center",children:"Haka Lens es una aplicacion de QA creada por Haka Lab que vive dentro de Jira (Atlassian Forge), disenada para centralizar la gestion, ejecucion y documentacion de pruebas de softw
3815are sin salir de tus proyectos. Convierte historias y tareas en casos de prueba, planes y ejecuciones nativos de Jira, con trazabilidad de cobertura de extremo a extremo."}),s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-12",children:[{name:"Pruebas",icon:"ð§ª",desc:"Casos de prueba manuales y automatizados"},{name:"Planes",icon:"ð",desc:"Agrupa pruebas en planes ejecutables"},{name:"Ejecuciones",icon:"â¶ï¸",desc:"Registra resultados por caso"},{name:"Cobertura",icon:"ð",desc:"Trazabilidad sobre historias"},{name:"Bugs QA",icon:"ð",desc:"Bugs con metadatos enriquecidos"}].map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.4+n*.1},className:"p-4 rounded-lg border border-cyan-500/30 bg-cyan-500/5 text-center hover:bg-cyan-500/10 transition-all",children:[s.jsx("div",{className:"text-3xl mb-2",children:a.icon}),s.jsx("h3",{className:"text-cyan-400 font-bold text-sm mb-1",children:a.name}),s.jsx("p",{className:"text-xs text-gray-400",children:a.desc})]},a.name))}),s.jsxs(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.6},className:"text-lg text-gray-300 max-w-4xl mx-auto text-center",children:["Ofrece gestion de Casos de Prueba, Planes y Ejecuciones, cobertura sobre historias, sugerencia y analisis de pruebas con ",s.jsx("span",{className:"text-cyan-400 font-semibold",children:"IA"})," (proveedores externos o Rovo de Atlassian), reportes automaticos en ",s.jsx("span",{className:"text-cyan-400 font-semibold",children:"DOCX y HTML"}
3815),", dashboards con metricas de calidad e integracion con ",s.jsx("span",{className:"text-cyan-400 font-semibold",children:"CI/CD"})," (GitHub, GitLab, Bitbucket, Jenkins, Azure) via API de automatizacion."]}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.7},className:"mt-10 text-center",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:"Apoya en"}),s.jsx("div",{className:"flex flex-wrap justify-center gap-2",children:["Gestion de Pruebas","Ejecucion","Cobertura","Reportes","IA","CI/CD","Dashboards","Jira"].map(a=>s.jsx("span",{className:"px-4 py-2 bg-slate-800 border border-cyan-400/30 text-cyan-300 text-sm font-medium rounded-full",children:a},a))})]})]})})}const Kte=[{categoria:"Gestion",titulo:"Casos de Prueba en Jira",descripcion:"Crea y documenta casos de prueba nativos con pasos manuales o escenarios Gherkin, precondiciones, ambiente, categoria, enfoque y tiempo estimado."},{categoria:"Gestion",titulo:"Planes y Ejecuciones",descripcion:"Agrupa pruebas en Planes, lanza Ejecuciones y registra resultados por caso (exitoso, fallido, por ejecutar), con soporte de iteraciones parametrizadas."},{categoria:"Cobertura",titulo:"Trazabilidad sobre Historias",descripcion:"Vincula pruebas, planes y ejecuciones a historias para ver la cobertura y resultados directamente en el issue."},{categoria:"Inteligencia Artificial",titulo:"Sugerencia y Analisis con IA",descripcion:"Genera casos de prueba y analiza issues (riesgos, ambiguedades, mejoras) con Gemini, OpenAI, Anthropic o Rovo de Atlassian."},{categoria:"Observabilidad",titulo:"Reportes Automaticos",descripcion:"Genera reportes profesionales en DOCX y HTML con plantillas personalizables, evidencias y datos de ejecucion."},{categoria:"Observabilidad",titulo:"Dashboards de QA",descripcion:"12 gadgets con metricas de calida
3815d: cobertura, resultados, distribucion por tipo, factibilidad, tiempos y documentacion."},{categoria:"Integracion",titulo:"CI/CD y API de Automatizacion",descripcion:"Actualiza resultados desde tus pipelines (GitHub, GitLab, Bitbucket, Jenkins, Azure) via API REST con emparejamiento por tag."},{categoria:"Gestion",titulo:"Importacion desde CSV",descripcion:"Importa pruebas masivamente a un plan desde CSV con mapeo de columnas, deteccion de duplicados y creacion por lotes."}],Jte={Gestion:"border-blue-500/30 bg-blue-500/5",Cobertura:"border-green-500/30 bg-green-500/5","Inteligencia Artificial":"border-purple-500/30 bg-purple-500/5",Observabilidad:"border-amber-500/30 bg-amber-500/5",Integracion:"border-cyan-500/30 bg-cyan-500/5"},Qte={Gestion:"text-blue-400",Cobertura:"text-green-400","Inteligencia Artificial":"text-purple-400",Observabilidad:"text-amber-400",Integracion:"text-cyan-400"};function Xte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"});return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Funcionalidades"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Todo lo que necesitas para gestionar QA dentro de Jira"})]}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6",children:Kte.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.2+n*.08},className:`p-6 rounded-xl border ${Jte[a.categoria]} hover:scale-105 transition-transform duration-300`,children:[s.jsx("span",{className:`text-xs font-semibold uppercase tracking-wider ${Qte[a.categoria]}`,children:a.categoria}),s.jsx("h3",{className:"text-lg font-bold text-white mt-2 mb-3",children:a.titulo}),s.jsx("p",{className:"text-sm text-gray-400 leading-relaxed",children:a.descripcion})]},n))})]})})}const Yte=[{pregunta:"Haka Lens reemplaza a Xray o Zephyr?",respuesta:"Si. Haka Lens cubre la gestion completa de pruebas (casos, planes, ejecuciones, cobertura, bugs QA) directamente en Jira Cloud, sin necesidad de herramientas externas. Ademas incluye IA, reportes automaticos y API de CI/CD."},{pregunta:"Necesito instalar algo en mi computador?",respuesta:"No. Haka Lens es una app Atlassian Forge que corre 100% en la nube de Jira. Se instala desde el Marketplace y se usa directamente en Jira. Solo necesitas un sitio Jira Cloud."},{pregunta:"Como funciona la integracion con CI/CD?",respuesta:"Haka Lens expone una API REST (Web Trigger) que tus pipelines pueden llamar para actualizar resultados de tests. Soporta GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins y Azure DevOps. Tambien incluye plugins descargables para Playwright y Selenium."},{pregunta:"Que proveedores de IA soporta?",respuesta:"Soporta Google Gemini, OpenAI (GPT-4), Anthropic (Claude) como proveedores externos, y Rovo (modelo de Atlassian) como fallback integrado sin configuracion adicional."},{pregunta:"Puedo importar mis pruebas desde un archivo?",respuesta:"Si. Desde cualquier Plan de Pruebas puedes importar hasta 50 tests desde un archivo CSV con mapeo de columnas automatico, deteccion de duplicados y creacion por lotes."},{pregunta:"En que idiomas esta disponible?",respuesta:"Haka Lens es bilingue: ingles (por defecto) y espanol. El idioma se configura por proyecto desde la seccion Diversos. Aplica a toda la interfaz, reportes DOCX y mensajes del backend."},{pregunta:"Cuantos gadgets de dashboard incluye?",respuesta:"12 gadgets de metricas de QA: tests creados, planes activos, distribucion por tipo, resultados de ejecucion, cobertura, tests por ambiente/categoria/enfoque, factibilidad de automatizacion, tiempos y documentacion."},{pregunta:"Como se cobra?",respuesta:"Haka Lens se cobra por usuario con acceso (user-based billing). Solo pagan los usuarios que operan la herramienta (equipo QA). Los demas pueden ver dashboards y reportes sin licencia."}];function Zte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(null),i=r=>{n(a===r?null:r)};return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Preguntas Frecuentes"}),s.jsx("p",{className:"text-lg text-gray-400",children:"Todo lo que necesitas saber sobre Haka Lens"})]}),s.jsx("div",{className:"space-y-3",children:Yte.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:.1+o*.05},className:"border border-gray-700 rounded-lg overflow-hidden",children:[s.jsxs("button",{onClick:()=>i(o),className:"w-full flex items-center justify-between p-5 text-left bg-slate-900 hover:bg-slate-800 transition-colors",children:[s.jsx("span",{className:"font-semibold text-white pr-4",children:r.pregunta}),s.jsx("svg",{className:`w-5 h-5 text-cyan-400 flex-shrink-0 transition-transform duration-300 ${a===o?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a===o&&s.jsx("div",{className:"p-5 bg-slate-900/50 border-t border-gray-700",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:r.respuesta})})]},o))})]})})}function eae(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaLens - Gestion de Testing en Jira",description:"Aplicacion Jira para gestion de repositorios de pruebas, planes de ejecucion, cobertura y analitica de testing integrada.",path:"/hakalens"}),s.jsx(Wte,{}),s.jsx(Gte,{}),s.jsx(Xte,{}),s.jsx(Zte,{}),s.jsx(Zr,{title:"Tambien te podria interesar",productIds:[1,2,3,5,7]})]})}const Mg=t=>{k.useEffect(()=>{if(t.title&&(document.title=t.title),t.description){const e=document.querySelector('meta[name="description"]');e&&e.setAttribute("content",t.description)}if(t.keywords){const e=document.querySelector('meta[name="keywords"]');
3815e&&e.setAttribute("content",t.keywords)}if(t.canonical){let e=document.querySelector('link[rel="canonical"]');e||(e=document.createElement("link"),e.rel="canonical",document.head.appendChild(e)),e.href=t.canonical}if(t.ogTitle){const e=document.querySelector('meta[property="og:title"]');e&&e.setAttribute("content",t.ogTitle)}if(t.ogDescription){const e=document.querySelector('meta[property="og:description"]');e&&e.setAttribute("content",t.ogDescription)}if(t.ogImage){const e=document.querySelector('meta[property="og:image"]');e&&e.setAttribute("content",t.ogImage)}if(t.ogUrl){const e=document.querySelector('meta[property="og:url"]');e&&e.setAttribute("content",t.ogUrl)}if(t.twitterTitle){const e=document.querySelector('meta[name="twitter:title"]');e&&e.setAttribute("content",t.twitterTitle)}if(t.twitterDescription){const e=document.querySelector('meta[name="twitter:description"]');e&&e.setAttribute("content",t.twitterDescription)}if(t.twitterImage){const e=document.querySelector('meta[name="twitter:image"]');e&&e.setAttribute("content",t.twitterImage)}if(t.schema){let e=document.querySelector('script[type="application/ld+json"]');e||(e=document.createElement("script"),e.type="application/ld+json",document.head.appendChild(e)),e.textContent=JSON.stringify(t.schema)}},[t])}
3815,tae=[{id:"technology",name:{es:"TecnologÃa",en:"Technology"}},{id:"finance",name:{es:"Finanzas",en:"Finance"}},{id:"retail",name:{es:"Retail/E-commerce",en:"Retail/E-commerce"}},{id:"health",name:{es:"Salud",en:"Healthcare"}},{id:"education",name:{es:"Educación",en:"Education"}},{id:"manufacturing",name:{es:"Manufactura",en:"Manufacturing"}},{id:"telecommunications",name:{es:"Telecomunicaciones",en:"Telecommunications"}},{id:"government",name:{es:"Gobierno",en:"Government"}},{id:"energy",name:{es:"EnergÃa",en:"Energy"}},{id:"logistics",name:{es:"Transporte/LogÃstica",en:"Transport/Logistics"}},{id:"entertainment",name:{es:"Entretenimiento/Media",en:"Entertainment/Media"}},{id:"insurance",name:{es:"Seguros",en:"Insurance"}},{id:"real_estate",name:{es:"Inmobiliaria",en:"Real Estate"}},{id:"agriculture",name:{es:"Agricultura",en:"Agriculture"}},{id:"hospitality",name:{es:"Turismo/Hospitalidad",en:"Tourism/Hospitality"}},{id:"other",name:{es:"Otro",en:"Other"}}],aae=[{id:"web_app",name:{es:"Web y App",en:"Web and App"}},{id:"ecommerce",name:{es:"E-commerce",en:"E-commerce"}},{id:"salesforce",name:{es:"Salesforce",en:"Salesforce"}},{id:"sap",name:{es:"SAP",en:"SAP"}},{id:"erp",name:{es:"ERP Personalizado",en:"Custom ERP"}},{id:"crm",name:{es:"CRM",en:"CRM"}},{id:"mobile",name:{es:"Aplicaciones Móviles Nativas",en:"Native Mobile Applications"}},{id:"api",name:{es:"APIs/Microservicios",en:"APIs/Microservices"}},{id:"data_analytics",name:{es:"Data Analytics/BI",en:"Data Analytics/BI"}},{id:"iot",name:{es:"IoT",en:"IoT"}},{id:"blockchain",name:{es:"Blockchain",en:"Blockchain"}},{id:"other",name:{es:"Otro",en:"Other"}}],nae=t=>t?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t):!1,Kp=t=>t!=null&&t.toString().trim()!=="",iae=t=>{const e={};return Kp(t.email)?nae(t.email)||(e.email={es:"El email no es válido",en:"Email is not valid"}):e.email={es:"El email es requerido",en:"Email is required"}
3815,Kp(t.company)||(e.company={es:"La empresa es requerida",en:"Company is required"}),Kp(t.industry)||(e.industry={es:"La industria es requerida",en:"Industry is required"}),Kp(t.developmentType)||(e.developmentType={es:"El tipo de desarrollo es requerido",en:"Development type is required"}),e},rae=(t,e)=>t.every(a=>{const n=e[a.id];return n!=null&&n>=1&&n<=5});function oae({onSubmit:t}){const{t:e,i18n:a}=$(),n=a.language,[i,r]=k.useState({email:"",company:"",industry:"",developmentType:""}),[o,l]=k.useState({}),[c,d]=k.useState({}),u=g=>{const{name:y,value:x}=g.target;r(v=>({...v,[y]:x})),o[y]&&l(v=>{const w={...v};return delete w[y],w})},p=g=>{d(y=>({...y,[g]:!0}))},m=g=>{g.preventDefault();const y=iae(i);if(Object.keys(y).length>0){l(y),d({email:!0,company:!0,industry:!0,developmentType:!0});return}t(i)},h=()=>i.email&&i.company&&i.industry&&i.developmentType&&Object.keys(o).length===0;return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},className:"max-w-2xl mx-auto",children:[s.jsx(_.div,{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl",animate:{scale:[1,1.2,1],opacity:[.2,.3,.2]},transition:{duration:4,repeat:1/0,ease:"easeInOut"}}),s.jsx(_.div,{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/20 rounded-full blur-3xl",animate:{scale:[1.2,1,1.2],opacity:[.3,.2,.3]},transition:{duration:4,repeat:1/0,ease:"easeInOut",delay:2}}),s.jsx(_.div,{className:"absolute top-1/2 left-1/2 w-64 h-64 bg-purple-500/10 rounded-full blur-3xl",animate:{x:[-100,100,-100],y:[-50,50,-50]},transition:{duration:8,repeat:1/0,ease:"easeInOut"}}),s.jsxs("div",{className:"relative bg-gradient-to-br from-[#1a1d3a]/90 via-[#1a1d3a]/95 to-[#0a0e27]/90 backdrop-blur-xl rounded-3xl p-8 sm:p-10 border-2 border-cyan-400/30 shadow-2xl shadow-cyan-500/20",children:[s.jsxs("div",{className:"text-center mb-8",children:[s.jsx(_.div,{initial:{scale:0,rotate:-180},animate:{scale:1,rotate:0},transition:{duration:.6,ease:"backOut"},className:"inline-block mb-6",children:s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-cyan-400 to-blue-500 rounded-2xl blur-xl opacity-50"}),s.jsx("div",{className:"relative bg-gradient-to-br from-cyan-400 to-blue-500 p-4 rounded-2xl",children:s.jsx("svg",{className:"w-12 h-12 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})})})]})}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.2,duration:.5},className:"text-3xl sm:text-4xl font-bold mb-4",children:s.jsx("span",{className:"bg-gradient-to-r from-cyan-400 via-blue-400 to-purple-400 bg-clip-text text-transparent",children:e("quickAnalysis.welcome.title")})}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3,duration:.5},className:"text-gray-300 text-lg max-w-xl mx-auto leading-relaxed",children:e("quickAnalysis.welcome.subtitle")}),s.jsx(_.div,{initial:{width:0},animate:{width:"100%"},transition:{delay:.5,duration:.8},className:"h-1 bg-gradient-to-r from-transparent via-cyan-400 to-transparent mx-auto mt-6 rounded-full",style:{maxWidth:"200px"}})]}),s.jsxs(_.form,{onSubmit:m,className:"space-y-6",initial:{opacity:0}
3815,animate:{opacity:1},transition:{delay:.6,duration:.5},children:[s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.7,duration:.5},children:[s.jsxs("label",{htmlFor:"email",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),e("quickAnalysis.welcome.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsx("input",{type:"email",id:"email",name:"email",value:i.email,onChange:u,onBlur:()=>p("email"),placeholder:e("quickAnalysis.welcome.emailPlaceholder"),className:` 3816 w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 3817 border-2 transition-all duration-300 placeholder-gray-500 3818 ${c.email&&o.email?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"} 3819 focus:outline-none focus:shadow-lg focus:shadow-cyan-400/20 3820 `}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.email&&o.email&&s.jsxs(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.email[n]||o.email.es]})]}),s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.8,duration:.5},children:[s.jsxs("label",{htmlFor:"company",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"})}),e("quickAnalysis.welcome.company")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsx("input",{type:"text",id:"company",name:"company",value:i.company,onChange:u,onBlur:()=>p("company"),placeholder:e("quickAnalysis.welcome.companyPlaceholder"),className:` 3821 w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 3822 border-2 transition-all duration-300 placeholder-gray-500 3823 ${c.company&&o.company?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"} 3824 focus:outline-none focus:shadow-lg focus:shadow-cyan-400/20 3825 `}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.company&&o.company&&s.jsxs(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.company[n]||o.company.es]})]}),s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.9,duration:.5},children:[s.jsxs("label",{htmlFor:"industry",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),e("quickAnalysis.welcome.industry")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsxs("select",{id:"industry",name:"industry",value:i.industry,onChange:u,onBlur:()=>p("industry"),className:` 3826 w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 3827 border-2 transition-all duration-300 3828 ${c.industry&&o.industry?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"} 3829 focus:outline-none cursor-pointer focus:shadow-lg focus:shadow-cyan-400/20 3830 `,children:[s.jsx("option",{value:"",className:"bg-[#2a2d4a]",children:e("quickAnalysis.welcome.industryPlaceholder")}),tae.map(g=>s.jsx("option",{value:g.id,className:"bg-[#2a2d4a]",children:g.name[n]||g.name.es},g.id))]}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.industry&&o.industry&&s.jsxs(_.p,{initial:{opacity:0,y:-10}
3830,animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.industry[n]||o.industry.es]})]}),s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:1,duration:.5},children:[s.jsxs("label",{htmlFor:"developmentType",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"})}),e("quickAnalysis.welcome.developmentType")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsxs("select",{id:"developmentType",name:"developmentType",value:i.developmentType,onChange:u,onBlur:()=>p("developmentType"),className:` 3831 w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 3832 border-2 transition-all duration-300 3833 ${c.developmentType&&o.developmentType?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"} 3834 focus:outline-none cursor-pointer focus:shadow-lg focus:shadow-cyan-400/20 3835 `,children:[s.jsx("option",{value:"",className:"bg-[#2a2d4a]",children:e("quickAnalysis.welcome.developmentTypePlaceholder")}),aae.map(g=>s.jsx("option",{value:g.id,className:"bg-[#2a2d4a]",children:g.name[n]||g.name.es},g.id))]}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.developmentType&&o.developmentType&&s.jsxs(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.developmentType[n]||o.developmentType.es]})]}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:1.1,duration:.5},className:"relative",children:[h()&&s.jsx(_.div,{className:"absolute inset-0 bg-gradient-to-r from-cyan-400 to-blue-500 rounded-xl blur-xl opacity-50",animate:{opacity:[.3,.6,.3]},transition:{duration:2,repeat:1/0,ease:"easeInOut"}}),s.jsxs(_.button,{type:"submit",disabled:!h(),whileHover:h()?{scale:1.03,y:-2}:{},whileTap:h()?{scale:.97}:{},className:` 3836 relative w-full py-4 px-6 rounded-xl font-bold text-lg 3837 transition-all duration-300 border-2 overflow-hidden 3838 ${h()?"bg-gradient-to-r from-cyan-400 via-blue-500 to-purple-500 hover:from-cyan-500 hover:via-blue-600 hover:to-purple-600 text-white border-cyan-400 shadow-2xl shadow-cyan-400/50":"bg-gray-600 text-gray-400 border-gray-600 cursor-not-allowed opacity-50"} 3839 `,children:[h()&&s.jsx(_.div,{className:"absolute inset-0 bg-gradient-to-r from-transparent via-white/30 to-transparent",animate:{x:["-100%","200%"]},transition:{duration:2,repeat:1/0,ease:"easeInOut",repeatDelay:1}}),s.jsxs("span",{className:"relative flex items-center justify-center gap-2",children:[s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7l5 5m0 0l-5 5m5-5H6"})}),e("quickAnalysis.welcome.startButton")]})]})]})]})]})]})}const sae=[{id:"q1",group:1,text:{es:"¿Aplican mediciones y gestiones sobre los issues productivos para determinar mejoras continuas en el ciclo de desarrollo?",en:"Do you apply measurements and management on production issues to determine continuous improvements in the development cycle?"},category:"process",weight:1},{id:"q2",group:1,text:{es:"¿Hay un representante del equipo de calida
3839d en el levantamiento de requerimientos y/o planificación?",en:"Is there a quality team representative in requirements gathering and/or planning?"},category:"integration",weight:1},{id:"q3",group:1,text:{es:"¿Existen DOR (Definition of Ready) y DOD (Definition of Done) claros para las tareas a realizar?",en:"Are there clear DOR (Definition of Ready) and DOD (Definition of Done) for tasks to be performed?"},category:"process",weight:1},{id:"q4",group:2,text:{es:"¿El software es testeado en ambientes similares a producción?",en:"Is the software tested in environments similar to production?"},category:"environment",weight:1},{id:"q5",group:2,text:{es:"¿Los desarrolladores aplican pruebas unitarias?",en:"Do developers apply unit tests?"},category:"testing",weight:1},{id:"q6",group:2,text:{es:"¿Se aplican pruebas humo para validar los criterios de aceptación antes de pasar a etapa de pruebas?",en:"Are smoke tests applied to validate acceptance criteria before moving to the testing stage?"},category:"testing",weight:1},{id:"q7",group:3,text:{es:"¿El equipo de calidad realiza pruebas automatizadas?",en:"Does the quality team perform automated tests?"},category:"automation",weight:1},{id:"q8",group:3,text:{es:"¿Se obtienen métricas relevantes para la mejora continua en base a los bugs identificados?",en:"Are relevant metrics obtained for continuous improvement based on identified bugs?"},category:"metrics",weight:1},{id:"q9",group:3,text:{es:"¿La información del proceso de calidad está disponible fácilmente para todo el equipo?",en:"Is quality process information easily available to the entire team?"},category:"transparency",weight:1},{id:"q10",group:4,text:{es:"¿Se realizan pruebas regresivas periódicamente?",en:"Are regression tests performed periodically?"},category:"testing",weight:1}],lae=t=>{const e={};return t.forEach(a=>{e[a.group]||(e[a.group]=[]),e[a.group].push(a)}),Object.values(e)},Jp={industry:{finance:[{id:"q_fin_1",group:4,text:{es:"¿Se realizan pruebas de seguridad y cumplimiento normativo (PCI-DSS, SOX, etc.) de forma regular?",en:"Are security and regulatory compliance tests (PCI-DSS, SOX, etc.) performed regularly?"},category:"security",weight:1}],retail:[{id:"q_retail_1",group:4,text:{es:"¿Se realizan pruebas de carga y performance durante eventos de alto tráfico (Black Friday, Cyber Monday)?",en:"Are load and performance tests conducted during high-traffic events (Black Friday, Cyber Monday)?"},category:"performance",weight:1}],health:[{id:"q_health_1",group:4,text:{es:"¿Se valida el cumplimiento de normativas de privacidad de datos médicos (HIPAA, GDPR)?",en:"Is compliance with medical data privacy regulations (HIPAA, GDPR) validated?"},category:"compliance",weight:1}],manufacturing:[{id:"q_manuf_1",group:4,text:{es:"¿Se realizan pruebas de integración con dispositivos IoT y sistemas embebidos?",en:"Are integration tests performed with IoT devices and embedded systems?"},category:"integration",weight:1}],government:[{id:"q_gov_1",group:4,text:{es:"¿Se realizan auditorÃas de seguridad y cumplimiento de estándares gubernamentales?",en:"Are security audits and compliance with government standards performed?"},category:"compliance",weight:1}],technology:[{id:"q_tech_1",group:4,text:{es:"¿Se realizan pruebas de escalabilidad y multi-tenancy?",en:"Are scalability and multi-tenancy tests performed?"},category:"scalability",weight:1}],insurance:[{id:"q_ins_1",group:4,text:{es:"¿Se validan los cálculos actuariales y procesos de suscripción en las pruebas?",en:"Are actuarial calculations and underwriting processes validated in testing?"},category:"business_logic",weight:1}]},developmentType:{ecommerce:[{id:"q_ecom_1",group:4,text:{es:"¿Se validan los flujos de pago y checkout en diferentes métodos de pago?",en:"Are payment and checkout flows validated across different payment methods?"},category:"payment",weight:1}],salesforce:[{id:"q_sf_1",group:4,text:{es:"¿Se realizan pruebas de integración con sistemas legacy y migraciones de datos?",en:"Are integration tests with legacy systems and data migrations performed?"}
3839,category:"integration",weight:1}],sap:[{id:"q_sap_1",group:4,text:{es:"¿Se realizan pruebas de integración con sistemas legacy y migraciones de datos?",en:"Are integration tests with legacy systems and data migrations performed?"},category:"integration",weight:1}],erp:[{id:"q_erp_1",group:4,text:{es:"¿Se validan los procesos de negocio end-to-end en las pruebas?",en:"Are end-to-end business processes validated in testing?"},category:"business_logic",weight:1}],api:[{id:"q_api_1",group:4,text:{es:"¿Se realizan pruebas de contrato y validación de APIs?",en:"Are contract tests and API validation performed?"},category:"api",weight:1}],mobile:[{id:"q_mobile_1",group:4,text:{es:"¿Se realizan pruebas en múltiples dispositivos y versiones de OS?",en:"Are tests performed on multiple devices and OS versions?"},category:"compatibility",weight:1}],data_analytics:[{id:"q_data_1",group:4,text:{es:"¿Se valida la calidad y precisión de los datos en los reportes?",en:"Is data quality and accuracy validated in reports?"},category:"data_quality",weight:1}],iot:[{id:"q_iot_1",group:4,text:{es:"¿Se realizan pruebas de conectividad y resiliencia de dispositivos IoT?",en:"Are connectivity and resilience tests performed on IoT devices?"},category:"iot",weight:1}]}},cae=t=>{const[e,a]=k.useState(0),[n,i]=k.useState({}),[r,o]=k.useState([]);k.useEffect(()=>{l()},[t]);const l=()=>{let w=[...sae];if(t!=null&&t.industry&&Jp.industry[t.industry]){const T=Jp.industry[t.industry];w=[...w,...T]}if(t!=null&&t.developmentType&&Jp.developmentType[t.developmentType]){const T=Jp.developmentType[t.developmentType];w=[...w,...T]}const S=lae(w);o(S)},c=(w,S)=>{i(T=>({...T,[w]:S}))},d=k.useMemo(()=>{if(r.length===0)return!1;const w=r[e];return rae(w,n)},[r,e,n]),u=()=>{e<r.length-1&&a(w=>w+1)},p=()=>{e>0&&a(w=>w-1)},m=k.useMemo(()=>e===r.length-1,[e,r]),h=k.useMemo(()=>e===0,[e]),g=k.useMemo(()=>r[e]||[],[r,e]),y=k.useMemo(()=>r.flat().length,[r]),x=k.useMemo(()=>Object.keys(n).length,[n]),v=()=>{a(0),i({})};return{currentGroupIndex:e,answers:n,questionGroups:r,currentQuestions:g,totalQuestions:y,answeredQuestions:x,totalGroups:r.length,isLastGroup:m,isFirstGroup:h,canContinue:d,handleAnswer:c,handleNext:u,handlePrevious:p,resetQuiz:v}};function dae({current:t,total:e}){const{t:a}=$(),n=e>0?Math.round(t/e*100):0;return s.jsxs("div",{className:"w-full mb-8",children:[s.jsxs("div",{className:"flex justify-between items-center mb-3",children:[s.jsx("span",{className:"text-gray-300 text-sm font-medium",children:a("quickAnalysis.quiz.progress")}),s.jsxs("span",{className:"text-cyan-400 text-sm font-bold",children:[n,"%"]})]}),s.jsx("div",{className:"w-full h-3 bg-[#2a2d4a] rounded-full overflow-hidden",children:s.jsx(_.div,{initial:{width:0},animate:{width:`${n}%`},transition:{duration:.5,ease:"easeOut"},className:"h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full relative",children:s.jsx("div",{className:"absolute inset-0 bg-white/20 animate-pulse"})})}),s.jsx("div",{className:"flex justify-between items-center mt-2",children:s.jsxs("span",{className:"text-gray-400 text-xs",children:[t," ",a("quickAnalysis.quiz.of")," ",e]})})]})}function uae({value:t,onChange:e}){const{t:a}=$(),n=[{value:1,label:a("quickAnalysis.rating.never")},{value:2,label:a("quickAnalysis.rating.rarely")},{value:3,label:a("quickAnalysis.rating.sometimes")},{value:4,label:a("quickAnalysis.rating.frequently")},{value:5,label:a("quickAnalysis.rating.always")}];return s.jsx("div",{className:"flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center items-stretch sm:items-center mt-6",children:n.map(i=>s.jsxs(_.button,{type:"button",onClick:()=>e(i.value),whileHover:{scale:1.1},whileTap:{scale:.95},className:` 3840 flex flex-col items-center justify-center gap-2 p-4 rounded-xl 3841 transition-all duration-300 min-w-[80px] sm:min-w-[100px] 3842 ${t===i.value?"bg-gradient-to-br from-cyan-400 to-blue-500 text-white shadow-lg shadow-cyan-400/50 border-2 border-cyan-300":"bg-[#2a2d4a] text-gray-300 hover:bg-[#3a3d5a] border-2 border-transparent hover:border-cyan-400/30"} 3843 `,children:[s.jsx("div",{className:` 3844 w-10 h-10 sm:w-12 sm:h-12 rounded-full flex items-center justify-center text-xl sm:text-2xl font-bold 3845 ${t===i.value?"bg-white/20":"bg-white/5"} 3846 `,children:i.value}),s.jsx("span",{className:"text-xs sm:text-sm font-medium text-center",children:i.label})]},i.value))})}function pae({id:t,text:e,value:a,onChange:n,index:i=0}){const{i18n:r}=$(),o=r.language;return s.jsxs(_.div,{initial:{opacity:0,y:20}
3846,animate:{opacity:1,y:0},transition:{duration:.4,delay:i*.1},className:"bg-[#1a1d3a]/50 backdrop-blur-sm rounded-2xl p-6 sm:p-8 border border-cyan-400/20 hover:border-cyan-400/40 transition-all duration-300",children:[s.jsx("h3",{className:"text-lg sm:text-xl text-white font-medium mb-4 leading-relaxed",children:e[o]||e.es}),s.jsx(uae,{value:a,onChange:n})]})}function mae({questions:t,answers:e,onAnswer:a}){return s.jsx(_.div,{initial:{opacity:0,x:50},animate:{opacity:1,x:0},exit:{opacity:0,x:-50},transition:{duration:.3},className:"space-y-6",children:t.map((n,i)=>s.jsx(pae,{id:n.id,text:n.text,value:e[n.id]||null,onChange:r=>a(n.id,r),index:i},n.id))})}function hae({userData:t,onComplete:e}){const{t:a}=$(),{currentGroupIndex:n,answers:i,currentQuestions:r,totalQuestions:o,answeredQuestions:l,totalGroups:c,isLastGroup:d,isFirstGroup:u,canContinue:p,handleAnswer:m,handleNext:h,handlePrevious:g}=cae(t),y=()=>{d?e(i):h()};return s.jsxs(_.div,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.5},className:"max-w-4xl mx-auto",children:[s.jsx("div",{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative",children:[s.jsx(dae,{current:l,total:o}),s.jsx(La,{mode:"wait",children:s.jsx(mae,{questions:r,answers:i,onAnswer:m},n)}),s.jsxs("div",{className:"flex flex-col sm:flex-row gap-4 mt-8",children:[!u&&s.jsx(_.button,{type:"button",onClick:g,whileHover:{scale:1.02},whileTap:{scale:.98},className:` 3847 flex-1 py-4 px-6 rounded-xl font-bold text-lg 3848 bg-[#2a2d4a] text-gray-300 border-2 border-cyan-400/30 3849 hover:bg-[#3a3d5a] hover:border-cyan-400/50 3850 transition-all duration-300 3851 `,children:a("quickAnalysis.quiz.previousButton")}),s.jsx(_.button,{type:"button",onClick:y,disabled:!p,whileHover:p?{scale:1.02}:{},whileTap:p?{scale:.98}:{},className:` 3852 flex-1 py-4 px-6 rounded-xl font-bold text-lg 3853 transition-all duration-300 border-2 3854 ${p?"bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white border-cyan-400 hover:shadow-lg hover:shadow-cyan-400/50":"bg-gray-600 text-gray-400 border-gray-600 cursor-not-allowed opacity-50"} 3855 `,children:a(d?"quickAnalysis.quiz.seeResultsButton":"quickAnalysis.quiz.continueButton")})]}),!p&&s.jsx(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-center text-amber-400 text-sm mt-4",children:a("quickAnalysis.quiz.allQuestionsRequired")}),s.jsx("div",{className:"text-center mt-6",children:s.jsxs("span",{className:"text-gray-400 text-sm",children:[a("quickAnalysis.quiz.question")," ",n+1," ",a("quickAnalysis.quiz.of")," ",c]})})]})]})}
3855const V0={reactive:{id:"reactive",range:[0,20],name:{es:"Calidad Reactiva",en:"Reactive Quality"},label:{es:"Nivel CrÃtico",en:"Critical Level"},color:"#EF4444",bgColor:"bg-red-500",textColor:"text-red-500",borderColor:"border-red-500",diagnosis:{es:"El equipo apaga incendios. QA es un cuello de botella al final del proceso y hay poca visibilidad de lo que pasa en producción.",en:"The team is firefighting. QA is a bottleneck at the end of the process with little visibility into production."},icon:"ð¨"},transition:{id:"transition",range:[21,40],name:{es:"Calidad en Transición",en:"Quality in Transition"},label:{es:"Nivel Medio",en:"Medium Level"},color:"#F59E0B",bgColor:"bg-amber-500",textColor:"text-amber-500",borderColor:"border-amber-500",diagnosis:{es:"Existen esfuerzos (quizás algunas pruebas unitarias o ambientes de QA), pero falta consistencia y métricas para mejorar.",en:"Efforts exist (perhaps some unit tests or QA environments), but consistency and metrics for improvement are lacking."},icon:"â ï¸"}
3855,advanced:{id:"advanced",range:[41,60],name:{es:"Calidad Avanzada",en:"Advanced Quality"},label:{es:"Nivel Pro",en:"Pro Level"},color:"#10B981",bgColor:"bg-green-500",textColor:"text-green-500",borderColor:"border-green-500",diagnosis:{es:"El equipo tiene cultura de calidad. QA está integrado y hay métricas.",en:"The team has a quality culture. QA is integrated and there are metrics."},icon:"â
"}},fae=t=>t<=20?V0.reactive:t<=40?V0.transition:V0.advanced,gae={silos:{id:"silos",name:{es:"Alerta de Silos",en:"Silos Alert"},condition:t=>(t.q2||0)<3&&(t.q9||0)<3,message:{es:"Tu equipo de QA está aislado; esto genera retrabajo y costos altos de corrección.",en:"Your QA team is isolated; this generates rework and high correction costs."},icon:"ð¨",color:"#EF4444",severity:"high"},production_risk:{id:"production_risk",name:{es:"Alerta de Riesgo en Producción",en:"Production Risk Alert"},condition:t=>(t.q1||0)<3&&(t.q8||0)<3,message:{es:"Estás volando a ciegas; no estás aprendiendo de tus errores en producción.",en:"You are flying blind; you are not learning from your production errors."},icon:"â ï¸",color:"#F59E0B",severity:"high"},technical_debt:{id:"technical_debt",name:{es:"Alerta de Deuda Técnica",en:"Technical Debt Alert"},condition:t=>(t.q5||0)<3&&(t.q7||0)<3&&(t.q10||0)<3,message:{es:"Tu regresión manual se volverá insostenible pronto. La automatización es tu siguiente paso.",en:"Your manual regression will become unsustainable soon. Automation is your next step."},icon:"ð§",color:"#F59E0B",severity:"medium"},environment_issues:{id:"environment_issues",name:{es:"Alerta de Ambientes",en:"Environment Alert"},condition:t=>(t.q4||0)<3,message:{es:"Tus ambientes de prueba no reflejan producción, lo que aumenta el riesgo de bugs en producción.",en:"Your test environments do not reflect production, increasing the risk of production bugs."},icon:"ð",color:"#F59E0B",severity:"medium"}},yae=t=>{const e=[];return Object.values(gae).forEach(a=>{a.condition(t)&&e.push(a)}),e},Qp={qa_assessment:{id:"qa_assessment",name:{es:"QA Assessment & Strategy",en:"QA Assessment & Strategy"},description:{es:"Definimos procesos desde cero, establecemos DOR/DOD y movemos QA hacia la izquierda (Shift Left).",en:"We define processes from scratch, establish DOR/DOD and shift QA left."},link:"/servicios#continuous-testing",icon:"ð",levels:["reactive"],categories:["foundation"],redFlags:["silos","production_risk"]},test_automation:{id:"test_automation",name:{es:"Test Automation",en:"Test Automation"},description:{es:"Automatizamos pruebas humo y regresiones para liberar tiempo y mejorar la confianza.",en:"We automate smoke and regression tests to free up time and improve confidence."},link:"/servicios#continuous-testing",icon:"ð¤",levels:["transition","advanced"],categories:["automation"],redFlags:["technical_debt"]},continuous_testing:{id:"continuous_testing",name:{es:"Continuous Testing",en:"Continuous Testing"},description:{es:"Integramos pruebas en tu pipeline CI/CD para detectar problemas temprano.",en:"We integrate tests into your CI/CD pipeline to detect problems early."},link:"/servicios#continuous-testing",icon:"ð",levels:["reactive","transition","advanced"],categories:["integration"],redFlags:["silos","technical_debt"]},performance_testing:{id:"performance_testing",name:{es:"Performance Testing",en:"Performance Testing"},description:{es:"Optimizamos la carga del sistema y aseguramos que tu aplicación escale.",en:"We optimize system load and ensure your application scales."},link:"/servicios#performance",icon:"â¡",levels:["transition","advanced"],categories:["optimization","advanced"],redFlags:["production_risk"]},data_testing:{id:"data_testing",name:{es:"Data Testing",en:"Data Testing"},description:{es:"Validamos la calidad y precisión de tus datos en pipelines y reportes.",en:"We validate the quality and accuracy of your data in pipelines and reports."},link:"/servicios#data",icon:"ð",levels:["advanced"],categories:["advanced"],redFlags:[]},resource_optimization:{id:"resource_optimization",name:{es:"Optimización de Recursos",en:"Resource Optimization"},description:{es:"Optimizamos tus procesos de QA existentes para maximizar eficiencia y reducir costos.",en:"We optimize your existing QA processes to maximize efficiency and reduce costs."},link:"/servicios#continuous-testing",icon:"ð",levels:["advanced"],categories:["optimization"],redFlags:[]}},xae=(t,e,a)=>{let n=[];
3855Object.values(Qp).forEach(l=>{l.levels.includes(t)&&n.push(l)});const i=e.map(l=>l.id);Object.values(Qp).forEach(l=>{l.redFlags.some(d=>i.includes(d))&&!n.find(d=>d.id===l.id)&&n.push(l)}),a>50&&(n=n.filter(l=>l.categories.includes("optimization")||l.categories.includes("advanced")),n.length<2&&(n.push(Qp.resource_optimization),n.push(Qp.data_testing)));const r=[],o=new Set;return n.forEach(l=>{o.has(l.id)||(o.add(l.id),r.push(l))}),r},vae=(t,e)=>t>50?{es:"¡Excelente trabajo! Tu equipo tiene un nivel de calidad sólido. Podemos ayudarte a optimizar aún más tus recursos y procesos para alcanzar la excelencia operacional.",en:"Excellent work! Your team has a solid quality level. We can help you further optimize your resources and processes to achieve operational excellence."}:e==="transition"?{es:"Estás en el camino correcto. Con las mejoras adecuadas, puedes llevar tu calidad al siguiente nivel y reducir significativamente los costos de corrección.",en:"You are on the right track. With the right improvements, you can take your quality to the next level and significantly reduce correction costs."}:{es:"Hay oportunidades importantes de mejora. Implementar las prácticas correctas ahora te ahorrará tiempo y dinero en el futuro.",en:"There are significant opportunities for improvement. Implementing the right practices now will save you time and money in the future."},bae=t=>Object.values(t).reduce((e,a)=>e+(a||0),0),wae=t=>fae(t),kae=t=>yae(t),Sae=(t,e,a)=>xae(t,e,a),DO=t=>{const e=bae(t),a=wae(e),n=kae(t),i=Sae(a.id,n,e),r=vae(e,a.id);return{totalScore:e,maxScore:60,maturityLevel:a,redFlags:n,recommendedServices:i,personalizedMessage:r,answersCount:Object.keys(t).length}},_ae=t=>{const e=k.useMemo(()=>!t||Object.keys(t).length===0?null:DO(t),[t]),a=(e==null?void 0:e.totalScore)||0,n=(e==null?void 0:e.maxScore)||60,i=(e==null?void 0:e.maturityLevel)||null,r=(e==null?void 0:e.redFlags)||[],o=(e==null?void 0:e.recommendedServices)||[],l=(e==null?void 0:e.personalizedMessage)||null,c=n>0?Math.round(a/n*100):0,d=k.useMemo(()=>r.length>0,[r]),u=k.useMemo(()=>i?i.color:"#6B7280",[i]),p=k.useMemo(()=>a>50,[a]),m=k.useMemo(()=>a<20,[a]),h=k.useMemo(()=>a>=20&&a<=40,[a]);return{results:e,totalScore:a,maxScore:n,scorePercentage:c,maturityLevel:i,redFlags:r,recommendedServices:o,personalizedMessage:l,hasCriticalFlags:d,levelColor:u,isHighScore:p,isLowScore:m,isMediumScore:h,isReady:e!==null}};function Aae({score:t,maxScore:e=60}){const{t:a}=$(),[n,i]=k.useState(0),r=Math.round(t/e*100);k.useEffect(()=>{let l=0;const d=t/(1500/16),u=setInterval(()=>{l+=d,l>=t?(i(t),clearInterval(u)):i(Math.floor(l))},16);return()=>clearInterval(u)},[t]);const o=()=>r>=70?"from-green-400 to-emerald-500":r>=40?"from-amber-400 to-orange-500":"from-red-400 to-rose-500";return s.jsxs(_.div,{initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},transition:{duration:.6,ease:"backOut"},className:"relative",children:[s.jsxs("div",{className:"relative w-64 h-64 mx-auto",children:[s.jsx("div",{className:"absolute inset-0 rounded-full bg-gradient-to-br from-cyan-400/20 to-blue-500/20 blur-xl"}),s.jsx("div",{className:"relative w-full h-full rounded-full bg-[#1a1d3a] border-8 border-[#2a2d4a] flex flex-col items-center justify-center",children:s.jsxs(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.3,duration:.5,ease:"backOut"},className:"text-center",children:[s.jsx("div",{className:`text-6xl font-bold bg-gradient-to-r ${o()} bg-clip-text text-transparent`,children:n}),s.jsxs("div",{className:"text-gray-400 text-sm mt-1",children:[a("quickAnalysis.results.outOf")," ",e]}),s.jsx("div",{className:"text-gray-300 text-xs mt-2",children:a("quickAnalysis.results.points")})]})}),s.jsxs("svg",{className:"absolute inset-0 w-full h-full -rotate-90",children:[s.jsx("circle",{cx:"50%",cy:"50%",r:"45%",fill:"none",stroke:"#2a2d4a",strokeWidth:"8"}),s.jsx(_.circle,{cx:"50%",cy:"50%",r:"45%",fill:"none",stroke:"url(#scoreGradient)",strokeWidth:"8",strokeLinecap:"round",strokeDasharray:`${2*Math.PI*120}`,initial:{strokeDashoffset:2*Math.PI*120},animate:{strokeDashoffset:2*Math.PI*120*(1-r/100)},transition:{duration:1.5,ease:"easeOut"}}),s.jsx("defs",{children:s.jsxs("linearGradient",{id:"scoreGradient",x1:"0%",y1:"0%",x2:"100%",y2:"100%",children:[s.jsx("stop",{offset:"0%",stopColor:"#06b6d4"}),s.jsx("stop",{offset:"100%",stopColor:"#3b82f6"})]})})]})]}),s.jsxs(_.div,{initial:{opacity:0,y:20}
3855,animate:{opacity:1,y:0},transition:{delay:.8,duration:.5},className:"text-center mt-6",children:[s.jsxs("span",{className:"text-2xl font-bold text-cyan-400",children:[r,"%"]}),s.jsx("span",{className:"text-gray-400 text-sm ml-2",children:a("quickAnalysis.results.yourScore")})]})]})}function Eae({level:t,score:e}){const{t:a,i18n:n}=$(),i=n.language;if(!t)return null;const r=()=>{switch(t.id){case"reactive":return"ð¨";case"transition":return"â¡";case"advanced":return"ð";default:return"ð"}};return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.2},className:"text-center",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.4,duration:.5,ease:"backOut"},className:"inline-block",children:s.jsxs("div",{className:"relative px-8 py-4 rounded-2xl border-2",style:{borderColor:t.color,background:`linear-gradient(135deg, ${t.color}20, ${t.color}10)`},children:[s.jsx("div",{className:"text-5xl mb-2",children:r()}),s.jsx("h3",{className:"text-2xl font-bold mb-1",style:{color:t.color},children:t.name[i]||t.name.es}),s.jsx("div",{className:"inline-block px-4 py-1 rounded-full text-sm font-semibold",style:{backgroundColor:`${t.color}30`,color:t.color},children:t.label[i]||t.label.es}),s.jsx("div",{className:"absolute inset-0 rounded-2xl opacity-20 blur-xl",style:{backgroundColor:t.color}})]})}),s.jsx(_.p,{initial:{opacity:0}
3855,animate:{opacity:1},transition:{delay:.6,duration:.5},className:"text-gray-300 text-lg mt-6 max-w-2xl mx-auto leading-relaxed",children:t.diagnosis[i]||t.diagnosis.es})]})}function Cae({redFlags:t}){const{t:e,i18n:a}=$();return a.language,!t||t.length===0?s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},className:"bg-green-500/10 border border-green-500/30 rounded-2xl p-6 text-center",children:[s.jsx("div",{className:"text-4xl mb-3",children:"â
"}),s.jsx("p",{className:"text-green-400 font-medium",children:e("quickAnalysis.results.noRedFlags")})]}):s.jsx("div",{className:"space-y-4",children:t.map((n,i)=>s.jsx(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{duration:.5,delay:i*.1},className:"bg-red-500/10 border border-red-500/30 rounded-2xl p-6 hover:border-red-500/50 transition-all duration-300",children:s.jsxs("div",{className:"flex items-start gap-4",children:[s.jsx("div",{className:"text-3xl flex-shrink-0",children:n.icon}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h4",{className:"text-red-400 font-bold text-lg mb-2",children:e(`quickAnalysis.redFlags.${n.id}.title`)}),s.jsx("p",{className:"text-gray-300 leading-relaxed",children:e(`quickAnalysis.redFlags.${n.id}.message`)})]})]})},n.id))})}function jae({maturityLevel:t,redFlags:e,personalizedMessage:a}){const{t:n,i18n:i}=$(),r=i.language;return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.3},className:"space-y-8",children:[s.jsxs("div",{className:"text-center",children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:n("quickAnalysis.results.analysis")}),s.jsx("div",{className:"w-24 h-1 bg-gradient-to-r from-cyan-400 to-blue-500 mx-auto rounded-full"})]}),a&&s.jsx(_.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},transition:{delay:.4,duration:.5},className:"bg-gradient-to-br from-cyan-500/10 to-blue-500/10 border border-cyan-400/30 rounded-2xl p-6",children:s.jsx("p",{className:"text-gray-200 text-lg leading-relaxed text-center",children:typeof a=="string"?a:a[r]||a.es})}),s.jsxs("div",{children:[s.jsx("h3",{className:"text-xl font-bold text-white mb-4",children:n("quickAnalysis.results.redFlags")}),s.jsx(Cae,{redFlags:e})]})]})}function Tae({service:t,index:e=0}){const{t:a,i18n:n}=$();return n.language,s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:e*.1},whileHover:{scale:1.02,y:-5},className:"h-full",children:s.jsxs(Te,{to:t.link,className:"block h-full bg-[#1a1d3a]/50 backdrop-blur-sm rounded-2xl p-6 border border-cyan-400/20 hover:border-cyan-400/50 transition-all duration-300 group",children:[s.jsx("div",{className:"text-4xl mb-4 group-hover:scale-110 transition-transform duration-300",children:t.icon}),s.jsx("h4",{className:"text-xl font-bold text-white mb-3 group-hover:text-cyan-400 transition-colors duration-300",children:a(`quickAnalysis.services.${t.id}.name`)}),s.jsx("p",{className:"text-gray-300 leading-relaxed mb-4",children:a(`quickAnalysis.services.${t.id}.description`)}),s.jsxs("div",{className:"flex items-center text-cyan-400 font-medium group-hover:text-cyan-300 transition-colors duration-300",children:[s.jsx("span",{children:a("quickAnalysis.results.learnMore")}),s.jsx("svg",{className:"w-5 h-5 ml-2 group-hover:translate-x-1 transition-transform duration-300",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),s.jsx("div",{className:"absolute inset-0 rounded-2xl bg-gradient-to-br from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 transition-all duration-300 pointer-events-none"})]})})}function Nae({services:t,score:e}){const{t:a}=$();return!t||t.length===0?null:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.4},className:"space-y-8",children:[s.jsxs("div",{className:"text-center",children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:a("quickAnalysis.results.recommendations")}),s.jsx("p",{className:"text-gray-300 text-lg",children:a("quickAnalysis.results.recommendationsSubtitle")}),s.jsx("div",{className:"w-24 h-1 bg-gradient-to-r from-cyan-400 to-blue-500 mx-auto rounded-full mt-4"})]}),e>50&&s.jsx(_.div,{initial:{opacity:0,scale:.95}
3855,animate:{opacity:1,scale:1},transition:{delay:.5,duration:.5},className:"bg-gradient-to-br from-green-500/10 to-emerald-500/10 border border-green-400/30 rounded-2xl p-6",children:s.jsxs("div",{className:"flex items-center gap-3 justify-center",children:[s.jsx("span",{className:"text-3xl",children:"ð"}),s.jsx("p",{className:"text-green-400 font-medium text-lg",children:a("quickAnalysis.results.highScoreMessage")})]})}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:t.map((n,i)=>s.jsx(Tae,{service:n,index:i},n.id))})]})}function Iae({userEmail:t,results:e}){const{t:a}=$(),{openModal:n}=oa(),i=()=>{n(a("contactModal.title"))};return s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.5},className:"text-center",children:s.jsxs("div",{className:"bg-gradient-to-br from-cyan-500/10 to-blue-500/10 border border-cyan-400/30 rounded-3xl p-8 sm:p-12",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-cyan-400/5 to-blue-500/5 rounded-3xl"}),s.jsxs("div",{className:"relative",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.6,duration:.5,ease:"backOut"},className:"text-6xl mb-6",children:"ð¬"}),s.jsx("h3",{className:"text-2xl sm:text-3xl font-bold text-white mb-4",children:"¿Listo para mejorar tu calidad?"}),s.jsx("p",{className:"text-gray-300 text-lg mb-8 max-w-2xl mx-auto",children:"Nuestro equipo de expertos está listo para ayudarte a implementar las mejoras que necesitas."}),s.jsxs(_.button,{onClick:i,whileHover:{scale:1.05},whileTap:{scale:.95},className:` 3856 inline-flex items-center gap-3 px-8 py-4 rounded-xl 3857 bg-gradient-to-r from-cyan-400 to-blue-500 3858 hover:from-cyan-500 hover:to-blue-600 3859 text-white font-bold text-lg 3860 border-2 border-cyan-400 3861 hover:shadow-lg hover:shadow-cyan-400/50 3862 transition-all duration-300 3863 `,children:[s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),a("quickAnalysis.results.contactButton")]}),s.jsx("p",{className:"text-gray-400 text-sm mt-6",children:"Te responderemos en menos de 24 horas"})]})]})})}function Pae({answers:t,userData:e}){const{t:a}=$(),{totalScore:n,maxScore:i,maturityLevel:r,redFlags:o,recommendedServices:l,personalizedMessage:c,isReady:d}=_ae(t);return d?s.jsxs(_.div,{initial:{opacity:0}
3863,animate:{opacity:1},transition:{duration:.5},className:"max-w-6xl mx-auto space-y-16 pb-16",children:[s.jsx("div",{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative",children:[s.jsxs(_.div,{initial:{opacity:0,y:-20},animate:{opacity:1,y:0},transition:{duration:.5},className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl sm:text-5xl font-bold text-white mb-4",children:a("quickAnalysis.results.title")}),s.jsx("div",{className:"w-32 h-1 bg-gradient-to-r from-cyan-400 to-blue-500 mx-auto rounded-full"})]}),s.jsx("div",{className:"mb-16",children:s.jsx(Aae,{score:n,maxScore:i})}),s.jsx("div",{className:"mb-16",children:s.jsx(Eae,{level:r,score:n})}),s.jsx("div",{className:"mb-16",children:s.jsx(jae,{maturityLevel:r,redFlags:o,personalizedMessage:c})}),s.jsx("div",{className:"mb-16",children:s.jsx(Nae,{services:l,score:n})}),s.jsx("div",{children:s.jsx(Iae,{userEmail:e==null?void 0:e.email,results:{totalScore:n,maturityLevel:r,redFlags:o}})})]})]}):s.jsx("div",{className:"flex items-center justify-center min-h-screen",children:s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-cyan-400 mx-auto mb-4"}),s.jsx("p",{className:"text-gray-300",children:a("quickAnalysis.results.savingResults")})]})})}function Rae(){const{t,i18n:e}=$(),[a,n]=k.useState("welcome"),[i,r]=k.useState(null),[o,l]=k.useState({}),[c,d]=k.useState(null),[u,p]=k.useState(!1);Mg({title:t("quickAnalysis.welcome.title"),description:t("quickAnalysis.welcome.subtitle"),keywords:"quality assessment, software testing, QA maturity, test automation, calidad de software",ogImage:"/imagenes/og-quick-analysis.png"});const m=y=>{r(y),n("quiz")},h=async y=>{l(y);const x=DO(y);d(x),n("results"),g(y,x)},g=async(y,x)=>{p(!0);try{const v={email:i.email,company:i.company,industry:i.industry,developmentType:i.developmentType,answers:y,totalScore:x.totalScore,maxScore:x.maxScore,maturityLevel:x.maturityLevel.id,maturityLevelName:x.maturityLevel.name[e.language]||x.maturityLevel.name.es,redFlags:x.redFlags.map(S=>S.id),timestamp:xt.now(),language:e.language,userAgent:navigator.userAgent,completed:!0,jiraIssueCreated:!1,jiraIssueKey:null},w=await Tl(ga(St,"quality_assessments"),v);console.log("Evaluación guardada en Firestore con ID:",w.id);try{const S=await fetch("https://us-central1-web-haka-2026.cloudfunctions.net/createJiraIssueFromAssessment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({assessmentId:w.id,...v})});if(S.ok){const T=await S.json();console.log("Issue creado en Jira:",T)}else console.warn("No se pudo crear el issue en Jira:",S.status)}catch(S){console.warn("Error al crear issue en Jira:",S)}}catch(v){console.error("Error al guardar evaluación:",v)}finally{p(!1)}};return s.jsxs("div",{className:"min-h-screen bg-dark pt-24 pb-16 px-4 sm:px-6 lg:px-8 relative overflow-hidden",children:[s.jsxs(La,{mode:"wait",children:[a==="welcome"&&s.jsx(_.div,{initial:{opacity:0}
3863,animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:s.jsx(oae,{onSubmit:m})},"welcome"),a==="quiz"&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:s.jsx(hae,{userData:i,onComplete:h})},"quiz"),a==="results"&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:s.jsx(Pae,{answers:o,userData:i})},"results")]}),u&&s.jsx(_.div,{initial:{opacity:0,y:50},animate:{opacity:1,y:0},exit:{opacity:0,y:50},className:"fixed bottom-8 right-8 bg-cyan-500/20 border border-cyan-400/50 rounded-xl px-6 py-3 backdrop-blur-sm",children:s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx("div",{className:"animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-cyan-400"}),s.jsx("span",{className:"text-cyan-400 font-medium",children:t("quickAnalysis.results.savingResults")})]})})]})}const Lae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function Oae(){const{t}=$(),{openModal:e}=oa(),a=()=>{window.open(Lae,"_blank","width=1000,height=700,noopener")};return s.jsxs("section",{className:"relative min-h-[600px] flex items-center justify-center bg-dark pt-20",children:[s.jsxs("div",{className:"container mx-auto px-4 py-12 text-center relative",children:[s.jsx(_.div,{initial:{opacity:0,y:-20},animate:{opacity:1,y:0},transition:{duration:.6},className:"inline-block mb-8",children:s.jsx("div",{className:"bg-cyan-500/10 border border-cyan-400/30 rounded-full px-6 py-2 backdrop-blur-sm",children:s.jsx("span",{className:"text-cyan-400 font-semibold text-sm tracking-wider uppercase",children:"Expertos en Calidad de Salesforce"})})}),s.jsxs(_.h1,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.2},className:"text-4xl sm:text-4xl md:text-5xl lg:text-6xl font-bold mb-6 leading-tight",children:[s.jsx("span",{className:"text-white",children:"Somos especialistas en aseguramiento de calida
3863d"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"de Salesforce"})]}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.4},className:"text-gray-300 text-lg md:text-xl max-w-3xl mx-auto mb-12 leading-relaxed",children:"Con nuestra metodologÃa especializada en Salesforce aceleramos los tiempos de certificación de tus desarrollos"}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.6},className:"flex flex-col sm:flex-row gap-4 justify-center items-center",children:[s.jsx("button",{id:"hero-salesforce-schedule-button",onClick:a,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:"Agendemos una Reunión"}),s.jsx(Te,{to:"/casosdeexito",children:s.jsx("button",{id:"hero-salesforce-cases-button",className:"border-2 border-primary/50 text-primary px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:"Ver Casos de Ãxito"})})]}),s.jsx(_.div,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},transition:{duration:.8,delay:.8},className:"animate-float-slow absolute bottom-8 right-4 md:right-10 lg:right-20 z-20",children:s.jsx("img",{src:"/imagenes/salesforce.png",alt:"Salesforce",className:"w-20 h-20 md:w-38 md:h-28 lg:w-38 lg:h-38 object-contain drop-shadow-[0_0_20px_rgba(6,182,212,0.5)]"})})]}),s.jsx(ie,{variant:1})]})}function Mae(){const{t}=$(),[e,a]=k.useState(0);k.useEffect(()=>{const i=setInterval(()=>{a(r=>(r+1)%3)},2e3);return()=>clearInterval(i)},[]);const n=[{id:1,icon:s.jsx("svg",{className:"w-12 h-12 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),title:"Velocidad de Entrega",description:"70% de reducción del tiempo de las certificaciones de calidad.",color:"from-yellow-400 to-orange-500"},{id:2,icon:s.jsx("svg",{className:"w-12 h-12 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"QA Especializado",description:"Servicio de QA Automation especializado en desarrollo de proyectos Salesforce",color:"from-cyan-400 to-blue-500"},{id:3,icon:s.jsx("svg",{className:"w-12 h-12 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"Time To Market",description:"Disminución del Time To Market gracias a nuestra metodologÃa de calidad continua.",color:"from-green-400 to-emerald-500"}];return s.jsxs("section",{className:"relative py-20 bg-dark mt-20",children:[s.jsx("div",{className:"container mx-auto px-4",children:s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-8 lg:gap-12",children:n.map((i,r)=>s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:r*.2},className:"group",children:s.jsxs("div",{className:`relative h-full bg-[#1a1d3a]/50 backdrop-blur-sm rounded-2xl p-8 border transition-all duration-500 ${e===r?"border-cyan-400/50 shadow-xl shadow-cyan-400/10":"border-gray-700/50"}`,children:[s.jsx("div",{className:"mb-6",children:i.icon}),s.jsx("h3",{className:`text-2xl font-bold mb-4 transition-colors duration-500 ${e===r?"text-cyan-400":"text-white"}`,children:i.title}),s.jsx("p",{className:"text-gray-400 leading-relaxed",children:i.description}),s.jsx("div",{className:`absolute inset-0 rounded-2xl bg-gradient-to-br ${i.color} transition-opacity duration-500 pointer-events-none ${e===r?"opacity-5":"opacity-0"}`})]})},i.id))})}),s.jsx(ie,{variant:2})]})}const Dae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function qae(){const{t}=$(),{openModal:e}=oa(),a=()=>{window.open(Dae,"_blank","width=1000,height=700,noopener")},n=["Evaluación de madurez digital","Implementación de mejoras para la calidad del producto","Testing continuo y regresiones","Métricas de valor para la mejora continua"];return s.jsxs("section",{className:"relative py-20 bg-dark",children:[s.jsx("div",{className:"container mx-auto px-4 mt-10",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},children:[s.jsxs("div",{className:"inline-flex items-center gap-2 bg-cyan-500/10 border border-cyan-400/30 rounded-full px-4 py-2 mb-6",children:[s.jsx("svg",{className:"w-4 h-4 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"})}),s.jsx("span",{className:"text-cyan-400 font-semibold text-sm tracking-wider up
3863percase",children:"Calidad y Reducción de Riesgos"})]}),s.jsxs("h2",{className:"text-4xl md:text-5xl font-bold mb-7 leading-tight",children:[s.jsx("span",{className:"text-white",children:"Acelera tu Time to Market"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"con"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"Testing Automatizado"})]}),s.jsx("p",{className:"text-gray-400 text-lg leading-relaxed mb-8",children:"Una implementación con pruebas deficientes es un riesgo latente. Nuestro servicio especializado detecta problemas antes de que afecten a tu negocio y asegura que cada flujo funcione correctamente."}),s.jsx("div",{className:"space-y-4 mb-8",children:n.map((i,r)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.4,delay:r*.1},className:"flex items-center gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-gray-300 text-lg",children:i})]},r))}),s.jsx("button",{id:"hero-salesforce-schedule-button",onClick:a,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:"Hablemos Sobre Calidad"})]}),s.jsxs(_.div,{initial:{opacity:0,x:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"relative",children:[s.jsxs("div",{className:"relative bg-gradient-to-br from-[#1a1d3a] to-[#0a0e27] rounded-2xl border border-gray-700/50 shadow-2xl overflow-hidden",children:[s.jsxs("div",{className:"bg-[#2a2d4a] px-4 py-3 flex items-center gap-2 border-b border-gray-700/50",children:[s.jsxs("div",{className:"flex gap-2",children:[s.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"})]}),s.jsx("span",{className:"text-gray-400 text-sm ml-4",children:"Haka_Analysis_Report"})]}),s.jsxs("div",{className:"p-8 space-y-6",children:[s.jsxs("div",{className:"mb-6",children:[s.jsx("h3",{className:"text-white font-bold text-lg mb-1",children:"Haka Lab - Testing Report"}),s.jsx("p",{className:"text-gray-500 text-xs",children:"Salesforce Quality Analysis"})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsxs(_.div,{initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.5,delay:.4},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-cyan-400/20",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[s.jsx("svg",{className:"w-4 h-4 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Tests"})]}),s.jsx(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.5,delay:.6},className:"text-3xl font-bold text-cyan-400",children:"1,247"}),s.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"Ejecutados"})]}),s.jsxs(_.div,{initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.5,delay:.5},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-red-400/20",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[s.jsx("svg",{className:"w-4 h-4 text-red-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Bugs"})]}),s.jsx(_.div,{initial:{opacity:0},whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.5,delay:.7},className:"text-3xl font-bold text-red-400",children:"23"}),s.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"Detectados"})]})]}),s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.6},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-green-400/20",children:[s.jsxs("div",{className:"flex items-center justify-between mb-3",children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("svg",{className:"w-4 h-4 text-green-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Cobertura"})]}),s.jsx(_.span,{initial:{scale:0},whileInView:{scale:1},viewport:{once:!0},transition:{duration:.5,delay:.8,type:"spring"},className:"text-2xl font-bold text-green-400",children:"92%"})]}),s.jsx("div",{className:"w-full bg-gray-700 rounded-full h-2",children:s.jsx(_.div,{initial:{width:0},whileInView:{width:"92%"},viewport:{once:!0},transition:{duration:1,delay:.9},className:"bg-gradient-to-r from-green-400 to-emerald-500 h-2 rounded-full"})})]}),s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.7},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-purple-400/20",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-4",children:[s.jsx("svg",{className:"w-4 h-4 text-purple-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Bugs por Criticidad"})]}),s.jsxs("div",{className:"flex items-end justify-between gap-3 h-24 mb-2",children:[s.jsx("div",{className:"flex-1 flex flex-col items-center justify-end h-full",children:s.jsx(_.div,{initial:{scaleY:0},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:.8,delay:.9},style:{originY:1},className:"w-full h-[50%] bg-gradient-to-t from-red-500 to-red-400 rounded-t-md"})}),s.jsx("div",{className:"flex-1 flex flex-col items-center justify-end h-full",children:s.jsx(_.div,{initial:{scaleY:0},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:.8,delay:1},style:{originY:1},className:"w-full h-[40%] bg-gradient-to-t from-yellow-500 to-yellow-400 rounded-t-md"})}),s.jsx("div",{className:"flex-1 flex flex-col items-center justify-end h-full",children:s.jsx(_.div,{initial:{scaleY:0},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:.8,delay:1.1},style:{originY:1},className:"w-full h-[80%] bg-gradient-to-t from-green-500 to-green-400 rounded-t-md"})})]}),s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsx("span",{className:"flex-1 text-center text-[10px] text-red-400 font-semibold",children:"Alta"}),s.jsx("span",{className:"flex-1 text-center text-[10px] text-yellow-400 font-semibold",children:"Media"}),s.jsx("span",{className:"flex-1 text-center text-[10px] text-green-400 font-semibold",children:"Baja"})]})]}),s.jsxs(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.5,delay:1.2},className:"flex items-center justify-center gap-2 pt-2",children:[s.jsx("div",{className:"w-2 h-2 rounded-full bg-green-400 animate-pulse"}),s.jsx("span",{className:"text-xs text-gray-400",children:"All Systems Operational"})]})]}),s.jsx("div",{className:"absolute inset-0 bg-gradient-to-tr from-cyan-500/5 to-purple-500/5 pointer-events-none"})]}),s.jsx(_.div,{animate:{y:[0,-10,0]},transition:{duration:3,repeat:1/0,ease:"easeInOut"},className:"absolute -top-4 -right-4 w-24 h-24 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full blur-2xl opacity-30"}),s.jsx(_.div,{animate:{y:[0,10,0]},transition:{duration:4,repeat:1/0,ease:"easeInOut",delay:1},className:"absolute -bottom-4 -left-4 w-32 h-32 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full blur-2xl opacity-30"})]})]})}),s.jsx(ie,{variant:1})]})}function zae(){const{t}=$(),e=[{id:1,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"})}),title:"Maximización del ROI",description:"Transformamos tu inversión de QA en ganancias tangibles al reducir el time to market, minimizar errores productivos y mejorar la experiencia del usuario final.",color:"from-cyan-400 to-blue-500"},{id:2,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})}),title:"Eficiencia en Costos Operativos",description:"Eliminamos los altos costos asociados a la manualidad de los procesos de certificación. Menos horas hombre dedicadas a tareas repetitivas se traducen en un menor costo de delivery para tu empresa.",color:"from-purple-400 to-pink-500"},{id:3,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),title:"Reducción de Time-to-Market",description:"Optimizamos tus ciclos de entrega con una reducción del 70% en el tiempo de certificaciones regresivas. Aceleramos el despliegue de nuevos releases para que tu negocio nunca se detenga.",color:"from-pink-400 to-red-500"},{id:4,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"Testing E2E e Integraciones",description:"Garantizamos la integridad de tus flujos de principio a fin, validando integraciones crÃticas con sistemas legados. Aseguramos que Salesforce se comunique perfectamente con todo tu ecosistema digital.",color:"from-blue-400 to-indigo-500"},{id:5,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"})}),title:"Automatización de Alta Cobertura",description:"Ampliamos radicalmente tu capacidad de prueba; hemos logrado pasar de 674 a más de 5,600 casos automatizados. Cubrimos múltiples combinatorias y escenarios con componentes altamente reutilizables.",color:"from-cyan-400 to-teal-500"},{id:6,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),title:"Mejora Continua",description:"No solo entregamos; iteramos. Utilizamos las métricas de QA para implementar mejoras continuas en los equipos de desarrollo.",color:"from-green-400 to-emerald-500"}];return s.jsxs("section",{className:"relative py-20 bg-dark",children:[s.jsxs("div",{className:"container mx-auto px-4 mt-10 pt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("p",{className:"text-cyan-400 font-semibold text-lg tracking-wider up
3863percase mb-4",children:"¿Por qué nosotros?"}),s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:"Beneficios Clave"}),s.jsx("p",{className:"text-gray-400 text-lg max-w-3xl mx-auto",children:"Hemos diseñado e implementado exitosamente en multiples clientes nuestro servicio especializado en testing eficiente de Salesforce."})]}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:e.map((a,n)=>s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:n*.1},className:"group",children:s.jsxs("div",{className:"relative h-full bg-[#1a1d3a]/30 backdrop-blur-sm rounded-2xl p-6 border border-gray-700/50 hover:border-cyan-400/50 transition-all duration-300 hover:shadow-xl hover:shadow-cyan-400/10",children:[s.jsx("div",{className:"mb-4",children:a.icon}),s.jsx("h3",{className:"text-xl font-bold text-cyan-400 mb-3 group-hover:text-cyan-400 transition-colors duration-300",children:a.title}),s.jsx("p",{className:"text-gray-200 leading-relaxed text-md",children:a.description}),s.jsx("div",{className:`absolute inset-0 rounded-2xl bg-gradient-to-br ${a.color} opacity-0 group-hover:opacity-5 transition-opacity duration-300 pointer-events-none`})]})},a.id))}),s.jsx(_.div,{initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.8,delay:.3},className:"flex justify-center my-16",children:s.jsx("div",{className:"animate-float-slow",children:s.jsx("img",{src:"/imagenes/salesforce.png",alt:"Salesforce",className:"w-24 h-24 md:w-32 md:h-32 lg:w-40 lg:h-40 object-contain drop-shadow-[0_0_25px_rgba(6,182,212,0.6)]"})})}),s.jsx(Vae,{}),s.jsx(Hae,{})]}),s.jsx(ie,{variant:2})]})}function Vae(){const[t,e]=k.useState(0),a=[{title:"Análisis",description:"Integramos la visión de calidad desde la etapa de planificación"},{title:"Diseño",description:"Creamos una estrategia de testing adaptada al negocio"},{title:"Implementación",description:"Desarrollamos y ejecutamos las pruebas automatizadas"},{title:"Optimización",description:"Mejoramos continuamente basados en métricas"}];return k.useEffect(()=>{const n=setInterval(()=>{e(i=>(i+1)%a.length)},3e3);return()=>clearInterval(n)},[a.length]),s.jsxs("div",{className:"mt-20 pt-0",children:[s.jsx(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-16",children:s.jsx("p",{className:"text-gray-100 text-lg mt-6 max-w-4xl mx-auto",children:"Un enfoque estructurado y probado para garantizar la calidad de tu implementación Salesforce desde las etapas iniciales del ciclo de vida de desarrollo"})}),s.jsxs("div",{className:"relative max-w-5xl mx-auto",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-primary",initial:{width:"0%"},animate:{width:`${t/(a.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-primary rounded-full shadow-lg shadow-primary/50 z-20",animate:{left:`${t/(a.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-primary animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-4 gap-3 sm:gap-4 pt-20",children:a.map((n,i)=>s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:i*.1},className:"flex flex-col items-center text-center",children:[s.jsxs(_.div,{animate:{rotate:t>=i?360:0,scale:t===i?1.2:1},transition:{duration:.6},className:"mb-3 sm:mb-4 relative",children:[s.jsx("div",{className:`absolute inset-0 rounded-full blur-lg transition-opacity duration-500 ${t>=i?"opacity-100":"opacity-0"}`,style:{background:"radial-gradient(circle, #06b6d4 0%, transparent 10%)",width:"100%",height:"100%"}}),s.jsx("svg",{className:`w-8 sm:w-10 md:w-12 h-8 sm:h-10 md:h-12 transition-all duration-500 relative z-10 ${t>=i?"text-cyan-400 drop-shadow-lg":"text-gray-600"}`,style:{filter:t>=i?"drop-shadow(0 0 8px #06b6d4) drop-shadow(0 0 16px rgba(6, 182, 212, 0.5))":"none",textShadow:t>=i?"0 0 10px #06b6d4":"none"},fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{d:"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"})})]}
3863),s.jsxs(_.div,{animate:{opacity:t>=i?1:.5,scale:t===i?1.05:1},transition:{duration:.3},className:`p-3 sm:p-4 rounded-lg border transition-all ${t>=i?"border-primary/30 bg-primary/5":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-1 sm:mb-2 text-xs sm:text-sm lg:text-base ${t>=i?"text-primary":"text-gray-400"}`,children:n.title}),s.jsx("p",{className:"text-[10px] sm:text-xs lg:text-sm text-gray-100",children:n.description})]})]},`step-${i}`))})]})]})}function Hae(){const t={logos:[{id:1,image:"/imagenes/home/logo_abastible.png",alt:"Abastible"},{id:4,image:"/imagenes/home/logo_falabella.png",alt:"Falabella"},{id:5,image:"/imagenes/home/logo_casaideas.png",alt:"Casa Ideas"},{id:7,image:"/imagenes/home/log_bupa.png",alt:"Bupa"},{id:9,image:"/imagenes/home/logo_colmena.png",alt:"Colmena"},{id:10,image:"/imagenes/home/logo_consorcio.png",alt:"Consorcio"},{id:11,image:"/imagenes/home/logo_continuum.png",alt:"Continuum"},{id:14,image:"/imagenes/home/logo_scotiabank.png",alt:"Scotiabank"},{id:15,image:"/imagenes/home/logo_security.png",alt:"Security"},{id:17,image:"/imagenes/home/logo_vida_security.png",alt:"Vida Security"},{id:18,image:"/imagenes/home/logo_sodimac.png",alt:"Sodimac"}]},[e,a]=k.useState(0),n=4;k.useEffect(()=>{const r=setInterval(()=>{a(o=>{const l=o+n;return l>=t.logos.length?0:l})},3e3);return()=>clearInterval(r)},[t.logos.length]);const i=t.logos.slice(e,e+n);return s.jsxs("div",{className:"mt-20 pt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.8},className:"text-center mb-12",children:[s.jsx("h3",{className:"text-3xl md:text-3xl font-bold text-white mb-2",children:"Clientes que ConfÃan su Calidad Salesforce en Nosotros"}),s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-4 mx-auto"})]}),s.jsxs("div",{className:"relative",children:[s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0}
3863,animate:{opacity:1},exit:{opacity:0},transition:{duration:1.2,ease:"easeInOut"},className:"grid grid-cols-2 md:grid-cols-4 gap-8 lg:gap-12",children:i.map((r,o)=>s.jsx(_.div,{initial:{opacity:0,y:20,scale:.96},animate:{opacity:1,y:0,scale:1},transition:{type:"spring",stiffness:120,damping:22,delay:o*.1},whileHover:{scale:1.03},className:"flex items-center justify-center p-6 rounded-xl bg-slate-800/30 border border-primary/10 hover:border-primary/30 group",children:s.jsx("div",{className:"relative w-full h-20 flex items-center justify-center",children:s.jsx("img",{src:r.image,alt:r.alt,loading:"lazy",decoding:"async",width:"250",height:"150",className:"max-w-full max-h-full object-contain transition-all duration-300 opacity-90 group-hover:opacity-100 group-hover:scale-110"})})},r.id))},e)}),s.jsx("div",{className:"flex justify-center gap-2 mt-8",children:Array.from({length:Math.ceil(t.logos.length/n)}).map((r,o)=>s.jsx("button",{onClick:()=>a(o*n),className:`h-2 rounded-full transition-all duration-300 ${Math.floor(e/n)===o?"w-8 bg-primary":"w-2 bg-gray-600 hover:bg-gray-500"}`,"aria-label":`Ir al grupo ${o+1}`},o))})]})]})}const Fae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function Bae(){const{t}=$(),{openModal:e}=oa(),a=()=>{window.open(Fae,"_blank","width=1000,height=700,noopener")};return s.jsxs("section",{className:"relative py-32 bg-dark",children:[s.jsxs("div",{className:"container mx-auto px-4 text-center pt-5",children:[s.jsxs(_.h2,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-4xl md:text-5xl lg:text-6xl font-bold mb-6 leading-tight",children:[s.jsx("span",{className:"text-white",children:"¿Listo para escalar tu"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"Estrategia de Calidad?"})]}),s.jsx(_.p,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"text-gray-300 text-lg md:text-xl max-w-3xl mx-auto mb-12 leading-relaxed",children:"Agenda una reunión y permitenos mostrate como llevar tu estrategia de calidad en Salesforce al siguiente nivel."}),s.jsx("button",{id:"hero-salesforce-schedule-button",onClick:a,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:"Hablemos Sobre Calidad"}),s.jsx(_.div,{animate:{y:[0,-20,0],opacity:[.3,.6,.3]},transition:{duration:4,repeat:1/0,ease:"easeInOut"},className:"absolute top-1/4 left-1/4 w-2 h-2 bg-cyan-400 rounded-full blur-sm"}),s.jsx(_.div,{animate:{y:[0,-30,0],opacity:[.3,.6,.3]},transition:{duration:5,repeat:1/0,ease:"easeInOut",delay:1},className:"absolute top-1/3 right-1/3 w-3 h-3 bg-purple-400 rounded-full blur-sm"}),s.jsx(_.div,{animate:{y:[0,-25,0],opacity:[.3,.6,.3]},transition:{duration:4.5,repeat:1/0,ease:"easeInOut",delay:2},className:"absolute bottom-1/4 right-1/4 w-2 h-2 bg-blue-400 rounded-full blur-sm"})]}),s.jsx(ie,{variant:1})]})}function Uae(){const{t}=$();return Mg({title:"Salesforce Testing - HakaLab",description:"Servicios especializados de testing para Salesforce. Transformamos tu CRM en un motor de crecimiento.",keywords:"salesforce, testing, qa, automation, crm, salesforce partners, salesforce experts"}),s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx(Oae,{}),s.jsx(Mae,{}),s.jsx(qae,{}),s.jsx(zae,{}),s.jsx(Bae,{})]})}function $ae(){const{t}=$(),e=t("hakaAutomationEngine.hero",{returnObjects:!0}),{openModal:a}=oa();return s.jsxs("section",{className:"relative bg-dark",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden min-h-[500px] sm:min-h-[600px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow"}),s.jsx("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"text-center",children:[s.jsx(Lg,{text:e.badge}),s.jsx("h1",{className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white mt-6",children:e.title}),s.jsx("h2",{className:"text-4xl md:text-5xl font-extrabold text-primary italic mt-4",children:e.titleHighlight}),s.jsx("p",{className:"text-xl text-gray-300 font-normal max-w-3xl mx-auto leading-relaxed mt-10",children:e.subt
3863itle}),s.jsx("div",{className:"flex flex-col sm:flex-row justify-center gap-4 mt-14",children:s.jsx("button",{onClick:()=>a(e.ctaContact),className:"bg-primary border-2 border-primary text-dark px-10 py-3 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:e.ctaContact})})]})})]}),s.jsx(ie,{variant:1})]})}function Wae(){const{t}=$(),e=t("hakaAutomationEngine.diagram",{returnObjects:!0}),[a,n]=k.useState(0);k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%5)},2e3);return()=>clearInterval(r)},[]);const i=[{id:1,title:e.layer1.title,description:e.layer1.description,icons:["/imagenes/framework/Selenium_Logo.png","/imagenes/framework/playwright.png","/imagenes/framework/cucumber.png"],color:"from-orange-500/20 to-orange-500/5"},{id:2,title:e.layer2.title,description:e.layer2.description,icons:["/imagenes/framework/front.png","/imagenes/framework/apirest.png","/imagenes/framework/bbdd.png"],color:"from-green-500/20 to-green-500/5"},{id:3,title:e.layer3.title,description:e.layer3.description,icons:["/imagenes/framework/jira-3.svg","/imagenes/framework/Logo-Xray.png","/imagenes/framework/Grafana_icon.svg.png"],color:"from-purple-500/20 to-purple-500/5"},{id:4,title:e.layer4.title,description:e.layer4.description,icons:["/imagenes/framework/html.png","/imagenes/framework/video.png"],color:"from-blue-500/20 to-blue-500/5"},{id:5,title:e.layer5.title,description:e.layer5.description,icons:["/imagenes/framework/Jenkins_logo.svg.png","/imagenes/framework/github.png","/imagenes/framework/docker.png"],color:"from-primary/20 to-primary/5"}];return s.jsxs("section",{className:"relative bg-dark py-20 pt-14 mt-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:e.title}),s.jsx("p",{className:"text-xl text-gray-400 max-w-3xl mx-auto",children:e.subt
3863itle})]}),s.jsxs("div",{className:"relative max-w-5xl mx-auto",children:[s.jsxs("div",{className:"absolute left-8 top-0 bottom-0 w-1 hidden md:block",children:[s.jsx("div",{className:"absolute inset-0 bg-gray-800/30"}),s.jsx(_.div,{initial:{height:0},whileInView:{height:"100%"},transition:{duration:i.length*.3,ease:"linear"},viewport:{once:!0},className:"absolute top-0 left-0 w-full bg-gradient-to-b from-primary via-primary to-primary"})]}),i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.5,delay:o*.3},viewport:{once:!0},className:"relative mb-8 md:ml-16",children:[s.jsx(_.div,{initial:{width:1},whileInView:{width:"2.4rem"},transition:{duration:.4,delay:o*.3+.2},viewport:{once:!0},className:`absolute top-16 h-0.5 ${o===a?"bg-gradient-to-r from-cyan-400 to-cyan-400/50 shadow-lg shadow-cyan-400/50":"bg-gradient-to-r from-primary to-transparent"} hidden md:block transition-all duration-500`,style:{left:"-2rem"}}),s.jsx("div",{className:`bg-gradient-to-r ${r.color} border ${o===a?"border-cyan-400 shadow-lg shadow-cyan-400/50":"border-gray-800"} rounded-2xl p-6 md:p-8 backdrop-blur-sm transition-all duration-500`,children:s.jsxs("div",{className:"flex flex-col md:flex-row items-center gap-6",children:[s.jsx("div",{className:`flex-shrink-0 w-16 h-16 rounded-full ${o===a?"bg-cyan-400 text-dark shadow-lg shadow-cyan-400/50":"bg-gray-800 text-primary"} flex items-center justify-center text-2xl font-bold transition-all duration-500`,children:r.id}),s.jsxs("div",{className:"flex-grow text-center md:text-left",children:[s.jsx("h3",{className:"text-2xl font-bold text-white mb-2",children:r.title}),s.jsx("p",{className:"text-gray-200",children:r.description})]}),s.jsx("div",{className:"flex gap-4 flex-shrink-0",children:r.icons.map((l,c)=>s.jsx(_.div,{initial:{scale:0,rotate:-180},whileInView:{scale:1,rotate:0},transition:{duration:.5,delay:o*.3+.4+c*.1},viewport:{once:!0},whileHover:{scale:1.1,rotate:5},className:"w-14 h-14 bg-dark/50 rounded-lg p-2 flex items-center justify-center",children:s.jsx("img",{src:l,alt:"",className:"w-full h-full object-contain"})},c))})]})})]},r.id))]}),s.jsxs(_.div,{initial:{opacity:0,scale:.9},whileInView:{opacity:1,scale:1},transition:{duration:.5},viewport:{once:!0},className:"mt-24 bg-gradient-to-r from-primary/10 to-transparent border border-primary/30 rounded-2xl p-8 relative",children:[s.jsxs(_.div,{initial:{scale:0,rotate:-180},whileInView:{scale:1,rotate:0},transition:{duration:.6,delay:.3},viewport:{once:!0},className:"absolute -top-6 -right-6 w-12 h-12 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-400/50",children:[s.jsx("svg",{className:"w-6 h-6",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:s.jsx("path",{d:"M13 2L3 14H12L11 22L21 10H12L13 2Z",fill:"#0a0a0a",stroke:"#0a0a0a",strokeWidth:"1",strokeLinecap:"round",strokeLinejoin:"round"})}),s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-30"})]}),s.jsxs("div",{className:"flex flex-wrap justify-center items-start gap-6 md:gap-8 mb-6",children:[s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.2},viewport:{once:!0},src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost",className:"h-9 object-contain object-top"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.3},viewport:{once:!0},src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-10 object-contain object-top"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.4},viewport:{once:!0},src:"/imagenes/productos/hakapath_logo.png",alt:"Hakapath",className:"h-10 object-contain object-top"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.5},viewport:{once:!0},src:"/imagenes/productos/hakartc_logo.png",alt:"Hakartc",className:"h-10 object-contain object-top"})]}),s.jsx("p",{className:"text-xl text-white text-center",children:e.note})]})]}),s.jsx(ie,{variant:2})]})}function Gae(){const{t}=$(),e=t("hakaAutomationEngine.aiTesting",{returnObjects:!0}),a=[{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"12",cy:"8",r:"3",fill:"#22d3ee",opacity:"0.2"}),s.jsx("circle",{cx:"12",cy:"8",r:"3",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M6 21C6 17.134 8.686 14 12 14C15.314 14 18 17.134 18 21",stroke:"#22d3ee",strokeWidth:"2",strokeLinecap:"round"}),s.jsx("path",{d:"M9 8L10 9L12 7",stroke:"#0a0a0a",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("circle",{cx:"18",cy:"6",r:"2",fill:"#22d3ee"}),s.jsx("circle",{cx:"6",cy:"6",r:"2",fill:"#22d3ee"})]}
3863),title:e.features.genAI.title,description:e.features.genAI.description},{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("path",{d:"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z",fill:"#22d3ee",opacity:"0.2"}),s.jsx("path",{d:"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z",stroke:"#22d3ee",strokeWidth:"2",strokeLinejoin:"round"}),s.jsx("circle",{cx:"12",cy:"12",r:"3",fill:"#22d3ee"})]}),title:e.features.semantic.title,description:e.features.semantic.description},{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"4",y:"4",width:"6",height:"6",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"4",width:"6",height:"6",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"14",y:"4",width:"6",height:"6",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"14",y:"4",width:"6",height:"6",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"4",y:"14",width:"6",height:"6",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"14",width:"6",height:"6",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"14",y:"14",width:"6",height:"6",rx:"1",fill:"#22d3ee"}),s.jsx("path",{d:"M16 17L17 18L19 16",stroke:"#0a0a0a",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),title:e.features.rag.title,description:e.features.rag.description},{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M8 12L11 15L16 9",stroke:"#22d3ee",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),title:e.features.validation.title,description:e.features.validation.description}];return s.jsxs("section",{className:"relative bg-dark py-12 mt-16",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"grid lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},children:[s.jsx("div",{className:"inline-block bg-primary/20 text-primary px-4 py-2 rounded-full text-sm font-semibold mb-6",children:e.badge}),s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-6",children:e.title}),s.jsx("p",{className:"text-xl text-gray-300 mb-8 leading-relaxed",children:e.subt
3863itle}),s.jsx("div",{className:"space-y-4",children:a.map((n,i)=>s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},transition:{duration:.5,delay:i*.1},viewport:{once:!0},className:"flex items-start gap-4 bg-gradient-to-r from-gray-800/50 to-transparent border border-gray-800 rounded-xl p-4 hover:border-primary/50 transition-all duration-300",children:[s.jsx("div",{className:"flex-shrink-0",children:n.icon}),s.jsxs("div",{children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-1",children:n.title}),s.jsx("p",{className:"text-gray-400 text-sm",children:n.description})]})]},i))})]}),s.jsx(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"relative mt-16",children:s.jsxs("div",{className:"relative bg-gradient-to-br from-primary/10 to-purple-500/10 border-2 border-primary/30 rounded-3xl p-8 backdrop-blur-sm mt-20",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-primary/20 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-purple-500/20 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative space-y-6",children:[s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.2},viewport:{once:!0},className:"bg-gradient-to-r from-blue-500/20 to-blue-500/5 border border-blue-500/30 rounded-xl p-4 text-center",children:[s.jsx("p",{className:"text-blue-400 font-semibold mb-2",children:e.diagram.input.title}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.diagram.input.description})]}),s.jsx(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},transition:{duration:.3,delay:.4},viewport:{once:!0},className:"flex justify-center",children:s.jsx("div",{className:"text-primary text-3xl",children:"â"})}),s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.5},viewport:{once:!0},className:"bg-gradient-to-r from-purple-500/20 to-purple-500/5 border border-purple-500/30 rounded-xl p-4 text-center",children:[s.jsxs("div",{className:"flex items-center justify-center gap-2 mb-2",children:[s.jsxs("svg",{className:"w-6 h-6",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"12",cy:"8",r:"3",fill:"#a855f7",opacity:"0.3"}),s.jsx("circle",{cx:"12",cy:"8",r:"3",stroke:"#a855f7",strokeWidth:"2"}),s.jsx("path",{d:"M6 21C6 17.134 8.686 14 12 14C15.314 14 18 17.134 18 21",stroke:"#a855f7",strokeWidth:"2",strokeLinecap:"round"}),s.jsx("circle",{cx:"18",cy:"6",r:"2",fill:"#a855f7"}),s.jsx("circle",{cx:"6",cy:"6",r:"2",fill:"#a855f7"})]}),s.jsx("p",{className:"text-purple-400 font-semibold",children:e.diagram.genAI.title})]}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.diagram.genAI.description})]}),s.jsx(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},transition:{duration:.3,delay:.7},viewport:{once:!0},className:"flex justify-center",children:s.jsx("div",{className:"text-primary text-3xl",children:"â"})}),s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.8},viewport:{once:!0},className:"bg-gradient-to-r from-green-500/20 to-green-500/5 border border-green-500/30 rounded-xl p-4 text-center",children:[s.jsx("p",{className:"text-green-400 font-semibold mb-2",children:e.diagram.output.title}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.diagram.output.description})]}),s.jsx(_.div,{initial:{opacity:0},whileInView:{opacity:1},transition:{duration:.3,delay:1},viewport:{once:!0},className:"flex justify-center",children:s.jsx("div",{className:"text-primary text-3xl",children:"â"})}),s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:1.1},viewport:{once:!0},className:"bg-gradient-to-r from-primary/30 to-primary/10 border-2 border-primary rounded-xl p-4 text-center",children:[s.jsxs("div",{className:"flex items-center justify-center gap-2 mb-2",children:[s.jsxs("svg",{className:"w-6 h-6",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",fill:"#22d3ee",opacity:"0.3"}),s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M8 12L11 15L16 9",stroke:"#22d3ee",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),s.jsx("p",{className:"text-primary font-bold",children:e.diagram.testing.title})]}),s.jsx("p",{className:"text-gray-300 text-sm font-semibold",children:e.diagram.testing.description})]})]}),s.jsx(_.div,{initial:{rotate:-10,scale:0},whileInView:{rotate:0,scale:1},transition:{duration:.5,delay:1.3},viewport:{once:!0},className:"absolute -top-4 -right-4 bg-primary text-dark px-4 py-2 rounded-full font-bold text-sm shadow-lg",children:e.innovationBadge})]})})]}),s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6,delay:.4},viewport:{once:!0},className:"mt-16 text-center",children:s.jsxs("div",{className:"inline-block bg-gradient-to-r from-primary/20 to-purple-500/20 border border-primary/30 rounded-2xl px-12 py-8",children:[s.jsx("p",{className:"text-gray-400 mb-2",children:e.stat.label}),s.jsx("p",{className:"text-4xl md:text-5xl font-bold text-primary mb-2",children:e.stat.value}),s.jsx("p",{className:"text-gray-300",children:e.stat.description})]})})]}),s.jsx(ie,{variant:1})]})}function Kae(){const{t}=$(),e=t("hakaAutomationEngine.comparison",{returnObjects:!0});return s.jsxs("section",{className:"relative bg-dark py-20 mt-16",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:e.title}),s.jsx("p",{className:"text-xl text-gray-400 max-w-3xl mx-auto",children:e.subt
3863itle})]}),s.jsxs("div",{className:"grid md:grid-cols-2 gap-8 max-w-5xl mx-auto",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"bg-gradient-to-br from-gray-800/50 to-gray-900/50 border border-gray-700 rounded-2xl p-8",children:[s.jsxs("div",{className:"text-center mb-6",children:[s.jsx("div",{className:"inline-block bg-red-500/20 text-red-400 px-4 py-2 rounded-full text-sm font-semibold mb-4",children:e.traditional.badge}),s.jsx("h3",{className:"text-2xl font-bold text-white mb-2",children:e.traditional.title}),s.jsx("p",{className:"text-gray-400",children:e.traditional.description})]}),s.jsx("div",{className:"relative h-16 bg-gray-900 rounded-xl overflow-hidden mb-4",children:s.jsx(_.div,{initial:{width:0},whileInView:{width:"100%"},transition:{duration:1.5,delay:.3},viewport:{once:!0},className:"h-full bg-gradient-to-r from-red-600 to-red-400 flex items-center justify-center",children:s.jsx("span",{className:"text-white font-bold text-xl",children:"100%"})})}),s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-gray-400",children:[s.jsx("span",{className:"text-red-400",children:"â"}),s.jsx("span",{children:e.traditional.point1})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-400",children:[s.jsx("span",{className:"text-red-400",children:"â"}),s.jsx("span",{children:e.traditional.point2})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-400",children:[s.jsx("span",{className:"text-red-400",children:"â"}),s.jsx("span",{children:e.traditional.point3})]})]})]}),s.jsxs(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"bg-gradient-to-br from-primary/20 to-primary/5 border-2 border-primary rounded-2xl p-8 relative",children:[s.jsxs(_.div,{initial:{scale:0,rotate:-180},whileInView:{scale:1,rotate:0},transition:{duration:.6,delay:.4},viewport:{once:!0},className:"absolute -top-5 -right-5 w-14 h-14 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-400/50 text-dark z-10",children:[s.jsx(Kk,{className:"w-7 h-7"}),s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-30"})]}),s.jsx("div",{className:"absolute top-0 right-0 w-32 h-32 bg-primary/20 rounded-full blur-3xl -z-10"}),s.jsxs("div",{className:"relative text-center mb-6",children:[s.jsx("div",{className:"inline-block bg-primary/20 text-primary px-4 py-2 rounded-full text-sm font-semibold mb-4",children:e.hakalab.badge}),s.jsx("h3",{className:"text-2xl font-bold text-white mb-2",children:e.hakalab.title}),s.jsx("p",{className:"text-gray-300",children:e.hakalab.description})]}),s.jsxs("div",{className:"relative h-16 bg-gray-900 rounded-xl overflow-hidden mb-4",children:[s.jsx(_.div,{initial:{width:0},whileInView:{width:"60%"},transition:{duration:1.5,delay:.3},viewport:{once:!0},className:"h-full bg-gradient-to-r from-primary to-green-400 flex items-center justify-center",children:s.jsx("span",{className:"text-dark font-bold text-xl",children:"60%"})}),s.jsx("div",{className:"absolute right-4 top-1/2 transform -translate-y-1/2 text-primary font-bold text-lg",children:"40% Ahorro"})]}),s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-gray-300",children:[s.jsx("span",{className:"text-primary",children:"â"}),s.jsx("span",{children:e.hakalab.point1})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-300",children:[s.jsx("span",{className:"text-primary",children:"â"}),s.jsx("span",{children:e.hakalab.point2})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-300",children:[s.jsx("span",{className:"text-primary",children:"â"}),s.jsx("span",{children:e.hakalab.point3})]})]})]})]})]}),s.jsx(ie,{variant:1})]})}const Jae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function Qae(){const{t}=$(),e=t("hakaAutomationEngine.cta",{returnObjects:!0}),{openModal:a}=oa(),[n,i]=k.useState(!1),[r,o]=k.useState(!1),l=()=>{window.open(Jae,"_blank","width=1000,height=700,noopener")},c=()=>{i(!0),o(!1)},d=()=>{o(!0),i(!0)};return s.jsxs("section",{className:"relative bg-dark py-20 mt-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"mb-16",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"text-center mb-8",children:[s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:e.demoTitle}),s.jsx("p",{className:"text-xl text-gray-400 max-w-3xl mx-auto",children:e.demoSubtitle})]}),s.jsx(_.div,{initial:{opacity:0,scale:.95},whileInView:{opacity:1,scale:1},transition:{duration:.6,delay:.2},viewport:{once:!0},className:"relative max-w-5xl mx-auto",children:s.jsxs("div",{className:" relative bg-gradient-to-br from-primary/10 to-purple-500/10 border-2 border-primary/30 rounded-2xl p-4 backdrop-blur-sm",children:[s.jsxs("div",{className:"relative aspect-video rounded-xl overflow-hidden bg-gray-900",children:[!n&&!r&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900 z-10",children:[s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"w-16 h-16 border-4 border-primary/30 border-t-primary rounded-full animate-spin"}),s.jsx("div",{className:"absolute inset-0 flex items-center justify-center",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{d:"M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z"})})})]}),s.jsx("p",{className:"text-primary font-semibold mt-6 text-lg",children:e.videoLoading||"Cargando video..."}),s.jsx("p",{className:"text-gray-400 text-sm mt-2",children:e.videoLoadingSubtitle||"Por favor espera unos segundos"})]}),r&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900 z-10",children:[s.jsx("svg",{className:"w-16 h-16 text-red-400 mb-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),s.jsx("p",{className:"text-red-400 font-semibold text-lg mb-2",children:"Error al cargar el video"}),s.jsx("p",{className:"text-gray-400 text-sm mb-4",children:"El video es muy grande o hay un problema de conexión"}),s.jsx("a",{href:"/video/demo.mp4",target:"_blank",rel:"noopener noreferrer",className:"bg-primary text-dark px-6 py-2 rounded-lg font-semibold hover:bg-primary/80 transition-colors",children:"Abrir video en nueva pestaña"})]}),s.jsxs("video",{className:`w-full h-full object-cover transition-opacity duration-500 ${n&&!r?"opacity-100":"opacity-0"}`,controls:!0,onLoadedData:c,onError:d,preload:"auto",children:[s.jsx("source",{src:"/video/demo.mp4",type:"video/mp4"}),"Tu navegador no soporta el elemento de video."]})]}),s.jsxs("div",{className:"absolute top-8 left-8 bg-red-500 text-white px-3 py-1 rounded-full text-xs font-bold flex items-center gap-2",children:[s.jsx("span",{className:"w-2 h-2 bg-white rounded-full animate-pulse"}),"DEMO"]})]})})]}),s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"relative bg-gradient-to-br from-primary/20 to-primary/5 border-2 border-primary rounded-3xl p-12 overflow-hidden max-w-5xl mx-auto",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-primary/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-primary/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative text-center",children:[s.jsx(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.2},viewport:{once:!0},className:"inline-block bg-primary/20 text-primary px-6 py-2 rounded-full text-sm font-semibold mb-6",children:e.badge}),s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-6",children:e.title}),s.jsx("p",{className:"text-xl text-gray-300 max-w-2xl mx-auto mb-10",children:e.description}),s.jsxs("div",{className:"flex flex-col sm:flex-row justify-center gap-4",children:[s.jsx(_.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:l,className:"bg-primary border-2 border-primary text-dark px-10 py-4 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:e.scheduleDemo}),s.jsx(_.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>a(e.contact),className:"border-2 border-primary/50 text-primary px-10 py-4 rounded-2xl text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:e.contact})]})]})]})]}),s.jsx(ie,{variant:1})]})}function Xae(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx($ae,{}),s.jsx(Wae,{}),s.jsx(Gae,{}),s.jsx(Kae,{}),s.jsx(Qae,{})]})}function Yae(){const{t}=$(),e=t("frameworkHakalab.hero",{returnObjects:!0}),{openModal:a}=oa();return s.jsxs("section",{className:"relative bg-dark",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[500px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"absolute top-0 left-1/2 transform -translate-x-1/2 w-[800px] h-[400px] bg-primary/20 rounded-full blur-[120px] opacity-30"}),s.jsx("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"text-center",children:[s.jsx(Lg,{text:e.badge}),s.jsxs("h1",{className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white mt-6",children:[s.jsx("span",{className:"text-primary",children:"Haka"}),"Lab Framework"]}),s.jsx("h2",{className:"text-3xl md:text-4xl font-bold text-primary mt-6",children:e.titleHighlight}),s.jsx("p",{className:"text-xl text-gray-300 font-normal max-w-3xl mx-auto leading-relaxed mt-8",children:e.subt
3863itle}),s.jsx("div",{className:"flex flex-col sm:flex-row justify-center gap-4 mt-10",children:s.jsx("button",{onClick:()=>a(e.ctaContact),className:"bg-primary border-2 border-primary text-dark px-10 py-3 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:e.ctaContact})})]})})]}),s.jsx(ie,{variant:1})]})}function Zae(){const{t}=$(),e=t("frameworkHakalab.pillars",{returnObjects:!0}),a=[{icon:s.jsxs("svg",{className:"w-8 h-8",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"12",cy:"8",r:"4",fill:"#22d3ee",opacity:"0.2"}),s.jsx("circle",{cx:"12",cy:"8",r:"4",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M5 21C5 16.582 8.134 13 12 13C15.866 13 19 16.582 19 21",stroke:"#22d3ee",strokeWidth:"2",strokeLinecap:"round"})]}),title:e.people.title,description:e.people.description},{icon:s.jsxs("svg",{className:"w-8 h-8",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M8 12L11 15L16 9",stroke:"#22d3ee",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("circle",{cx:"18",cy:"6",r:"2",fill:"#22d3ee"})]}),title:e.methodology.title,description:e.methodology.description},{icon:s.jsxs("svg",{className:"w-8 h-8",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"4",y:"4",width:"7",height:"7",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"4",width:"7",height:"7",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"13",y:"4",width:"7",height:"7",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"13",y:"4",width:"7",height:"7",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"4",y:"13",width:"7",height:"7",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"13",width:"7",height:"7",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"13",y:"13",width:"7",height:"7",rx:"1",fill:"#22d3ee"}),s.jsx("path",{d:"M15 16.5L16 17.5L18 15.5",stroke:"#0a0a0a",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),title:e.technology.title,description:e.technology.description}];return s.jsxs("section",{className:"relative bg-dark py-20",children:[s.jsx("div",{className:"relative text-center mb-12 mt-20",children:s.jsxs("p",{className:"text-xl text-gray-300 max-w-3xl mx-auto",children:["Nuestra solución se centra en tres pilares fundamentales que trabajan en",s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"sinergia, aprendizaje y mejora continua"})]})}),s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 overflow-hidden",children:s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"bg-gradient-to-br from-primary/10 to-purple-500/10 border-2 border-primary/30 rounded-3xl p-8 md:p-12 pt-16 backdrop-blur-sm relative overflow-visible shadow-2xl shadow-primary/20",children:[s.jsx(_.div,{animate:{opacity:[.3,.6,.3],scale:[1,1.02,1]},transition:{duration:3,repeat:1/0,ease:"easeInOut"},className:"absolute inset-0 rounded-3xl border-2 border-primary/50 blur-sm"}),s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-primary/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-purple-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"relative grid grid-cols-1 md:grid-cols-3 gap-8",children:a.map((n,i)=>s.jsxs("div",{className:"relative",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},whileHover:{scale:1.05,y:-5},transition:{duration:.3},viewport:{once:!0},className:"relative bg-gradient-to-br from-gray-800/50 to-gray-900/50 border border-gray-700 rounded-2xl p-6 pt-14 hover:border-primary hover:shadow-2xl hover:shadow-primary/50 transition-all duration-300 h-full flex flex-col group",children:[s.jsx("div",{className:"absolute inset-0 rounded-2xl bg-primary/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300"}),s.jsx("div",{className:"absolute -top-8 left-1/2 transform -translate-x-1/2 bg-gradient-to-br from-gray-800 to-gray-900 border-2 border-primary rounded-xl p-3 shadow-lg shadow-primary/30 group-hover:shadow-
3863primary/60 group-hover:scale-110 transition-all duration-300",children:n.icon}),s.jsx("h3",{className:"relative text-lg font-bold text-white text-center mb-4 z-10",children:n.title}),s.jsx("p",{className:"relative text-gray-300 text-center leading-relaxed flex-grow z-10",children:n.description})]}),i<a.length-1&&s.jsx(_.div,{initial:{opacity:0,scale:0},whileInView:{opacity:1,scale:1},transition:{duration:.5,delay:i*.2+.4},viewport:{once:!0},className:"hidden md:block absolute -right-10 top-1/2 transform -translate-y-1/2 z-10",children:s.jsx(_.div,{animate:{scale:[1,1.2,1],opacity:[.7,1,.7]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},className:"w-12 h-12 rounded-full bg-primary/20 border-2 border-primary flex items-center justify-center shadow-lg shadow-primary/50",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M12 4v16m8-8H4"})})})})]},i))})]})}),s.jsx(ie,{variant:2})]})}function ene(){const{t}=$(),e=t("frameworkHakalab.methodology",{returnObjects:!0});return s.jsxs("section",{className:"relative bg-dark py-20 mt-10",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"text-center mb-16",children:s.jsxs("h2",{className:"text-4xl md:text-5xl font-bold text-white -mb-10",children:[s.jsx("span",{className:"text-primary",children:"Framework"})," Metodológico"]})}),s.jsx(Og,{}),s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6,delay:.3},viewport:{once:!0},className:"max-w-4xl mx-auto mt-16",children:s.jsxs("div",{className:"bg-gradient-to-br from-primary/10 to-purple-500/10 border-l-4 border-primary rounded-r-2xl p-8 backdrop-blur-sm relative -mt-10",children:[s.jsx("svg",{className:"absolute top-4 left-4 w-8 h-8 text-primary/30",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"})}),s.jsxs("div",{className:"flex items-start gap-6 mt-4",children:[s.jsx("div",{className:"flex-shrink-0",children:s.jsx("div",{className:"w-16 h-16 rounded-full bg-gradient-to-br from-primary to-blue-500 flex items-center justify-center text-white text-2xl font-bold shadow-lg shadow-primary/30",children:"MC"})}),s.jsxs("div",{className:"flex-grow",children:[s.jsxs("p",{className:"text-lg text-gray-200 italic leading-relaxed mb-4",children:['"',e.quote,'"']}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("div",{className:"h-px w-12 bg-primary"}),s.jsx("p",{className:"text-primary font-semibold",children:e.author}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.authorRole})]})]})]})]})})]}),s.jsx(ie,{variant:1})]})}function tne(){const{t}=$(),e=t("frameworkHakalab.technology",{returnObjects:!0}),a=[{src:"/imagenes/framework/Selenium_Logo.png",name:"Selenium",desc:e.tools.selenium},{src:"/imagenes/framework/playwright.png",name:"Playwright",desc:e.tools.playwright},{src:"/imagenes/framework/cucumber.png",name:"Cucumber",desc:e.tools.cucumber},{src:"/imagenes/framework/python.png",name:"Python",desc:e.tools.python},{src:"/imagenes/framework/Jenkins_logo.svg.png",name:"Jenkins",desc:e.tools.jenkins},{src:"/imagenes/framework/docker.png",name:"Docker",desc:e.tools.docker},{src:"/imagenes/framework/github.png",name:"GitHub",desc:e.tools.github},{src:"/imagenes/framework/jira-3.svg",name:"Jira",desc:e.tools.jira},{src:"/imagenes/framework/Logo-Xray.png",name:"Xray",desc:e.tools.xray},{src:"/imagenes/framework/Grafana_icon.svg.png",name:"Grafana",desc:e.tools.grafana},{src:"/imagenes/framework/html.png",name:"HTML Reports",desc:e.tools.html},{src:"/imagenes/framework/apirest.png",name:"API REST",desc:e.tools.apirest},{src:"/imagenes/framework/bbdd.png",name:"Database",desc:e.tools.bbdd},{src:"/imagenes/framework/front.png",name:"Frontend",desc:e.tools.front},{src:"/imagenes/framework/chrome.png",name:"Chrome",desc:e.tools.chrome},{src:"/imagenes/framework/appium.png",name:"Appium",desc:e.tools.appium}],n=[{src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost"},{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy"},{src:"/imagenes/productos/hakapath_logo.png",alt:"Hakapath"},{src:"/imagenes/productos/hakartc_logo.png",alt:"Hakartc"}];return s.jsxs("section",{className:"relative bg-dark py-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"text-center mb-16",children:[s.jsxs("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4 mt-10",children:[s.jsx("span",{className:"text-primary",children:"Framework"})," Tecnológico"]}),s.jsx("p",{className:"text-xl text-gray-300 max-w-3xl mx-auto",children:e.subt
3863itle})]}),s.jsxs("div",{className:"grid lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"relative",children:[s.jsx("div",{className:"absolute -top-4 -left-4 z-10",children:s.jsxs("div",{className:"bg-gradient-to-r from-primary to-blue-500 text-dark px-4 py-2 rounded-full font-bold text-sm shadow-lg shadow-primary/50 flex items-center gap-2",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"})}),e.aiPowered]})}),s.jsxs("div",{className:"bg-gradient-to-br from-gray-800/50 to-gray-900/50 border-2 border-gray-700 rounded-2xl p-8 hover:border-primary/50 transition-all duration-300",children:[s.jsx("h3",{className:"text-2xl font-bold text-white mb-6 text-center",children:e.techTitle}),s.jsx("div",{className:"grid grid-cols-6 gap-3",children:a.map((i,r)=>s.jsxs(_.div,{initial:{opacity:0,scale:0},whileInView:{opacity:1,scale:1},transition:{duration:.3,delay:r*.05},viewport:{once:!0},whileHover:{scale:1.1,rotate:5},className:"bg-dark/50 rounded-lg p-2 flex items-center justify-center aspect-square border border-gray-700 hover:border-primary/50 transition-all duration-300 relative group cursor-pointer",title:i.desc,children:[s.jsx("img",{src:i.src,alt:i.name,className:"w-full h-full object-contain"}),s.jsxs("div",{className:"absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 text-white text-xs rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none whitespace-nowrap z-20 shadow-lg border border-primary/30",children:[s.jsx("div",{className:"font-bold mb-1",children:i.name}),s.jsx("div",{className:"text-gray-300",children:i.desc}),s.jsx("div",{className:"absolute top-full left-1/2 transform -translate-x-1/2 -mt-1",children:s.jsx("div",{className:"border-4 border-transparent border-t-gray-900"})})]})]},r))})]})]}),s.jsxs(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"space-y-8",children:[s.jsxs("div",{className:"bg-gradient-to-br from-primary/10 to-purple-500/10 border-l-4 border-primary rounded-r-2xl p-6",children:[s.jsx("h4",{className:"text-lg font-bold text-white mb-2",children:e.differentiator.title}),s.jsx("p",{className:"text-md text-gray-300 leading-relaxed",children:e.differentiator.description})]}),s.jsxs("div",{className:"bg-gradient-to-br from-gray-800/50 to-gray-900/50 border border-gray-700 rounded-2xl p-6",children:[s.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[s.jsx("div",{className:"w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})})}),s.jsx("h4",{className:"text-xl font-bold text-white",children:e.powerups.title})]}),s.jsx("p",{className:"text-gray-300 mb-6",children:e.powerups.description}),s.jsx("div",{className:"grid grid-cols-2 gap-4 mb-6",children:n.map((i,r)=>s.jsx(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.4,delay:r*.1},viewport:{once:!0},className:"bg-dark/50 rounded-xl p-4 flex items-center justify-center border border-gray-700 hover:border-primary/50 transition-all duration-300",children:s.jsx("img",{src:i.src,alt:i.alt,className:"h-8 object-contain"})},r))}),s.jsx(Te,{to:"/haka-automation-engine",className:"block w-full bg-primary hover:bg-primary/80 text-dark font-bold py-3 px-6 rounded-xl text-center transition-all duration-300 hover:shadow-lg hover:shadow-primary/50 transform hover:-translate-y-1",children:e.cta})]})]})]})]}),s.jsx(ie,{variant:2})]})}function ane(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Yae,{}),s.jsx(Zae,{}),s.jsx(ene,{}),s.jsx(tne,{})]})}const nne=[{id:"inicio",title:"Inicio",group:"Empezar",icon:"",topics:[{id:"estructura-proyecto",title:"Estructura del Proyecto",content:`## Estructura de Carpetas Estándar 3864 3865Un proyecto que usa Haka Framework sigue una estructura especÃfica donde Behave maneja las features y el framework provee los steps, helpers y configuración. El framework se instala como paquete. 3866 3867### Proyecto MÃnimo 3868 3869\`\`\` 3870mi_proyecto/ 3871âââ .env # Configuración (navegador, URLs, timeouts) 3872âââ behave.ini # Configuración de Behave 3873âââ features/ 3874â âââ environment.py # Ciclo de vida (template del framework) 3875â âââ login.feature # Feature de login 3876â âââ compras.feature # Feature de compras 3877â âââ steps/ 3878â âââ custom_steps.py # Pasos personalizados del proyecto 3879âââ json_poms/ 3880â âââ LOGIN.json # Localizadores de la página de login 3881â âââ DASHBOARD.json # Localizadores del dashboard 3882â âââ COMPRAS.json # Localizadores del módulo compras 3883âââ screenshots/ # Screenshots automáticos (generado) 3884âââ html-reports/ # Reportes HTML (generado) 3885âââ requirements.txt # Dependencias (haka-playwright-engine) 3886\`\`\` 3887 3888### Proyecto Completo con API y Datos 3889 3890\`\`\` 3891mi_proyecto/ 3892âââ .env 3893âââ behave.ini 3894âââ features/ 3895â âââ environment.py 3896â âââ web/ 3897â â âââ login.feature 3898â â âââ checkout.feature 3899â âââ api/ 3900â â âââ usuarios_api.feature 3901â â âââ pagos_api.feature 3902â âââ steps/ 3903â âââ custom_web_steps.py 3904â âââ custom_api_steps.py 3905âââ json_poms/ 3906â âââ LOGIN.json 3907â âââ CHECKOUT.json 3908âââ payloads/ # JSON bodies para peticiones API 3909âââ schemas/ # JSON Schema para validar respuestas 3910âââ expected/ # Respuestas esperadas para comparar 3911âââ screenshots/ 3912âââ html-reports/ 3913âââ requirements.txt 3914\`\`\` 3915 3916## Consideraciones 3917 3918- \`features/environment.py\` es OBLIGATORIO â configura el framework. 3919- El archivo \`.env\` es OBLIGATORIO â contiene toda la configuración.
3920- \`json_poms/\` es la ubicación por defecto pero es configurable con \`JSON_POMS_PATH\`. 3921- Puedes organizar los \`.feature\` en subcarpetas; Behave los busca recursivamente. 3922 3923## Ejecutar las Pruebas 3924 3925\`\`\`bash 3926# Ejecutar todo 3927behave 3928 3929# Ejecutar un feature especÃfico 3930behave features/login.feature 3931 3932# Ejecutar por tag 3933behave --tags=@smoke 3934behave --tags="@smoke and @login" 3935 3936# Un escenario especÃfico por nombre 3937behave --name="Validar login con credenciales válidas" 3938 3939# Ejecución paralela (CLI del framework) 3940haka-run --workers=4 --features=features/ 3941\`\`\` 3942 3943## Tags Especiales del Framework 3944 3945- \`@no_browser\`: No se levanta Playwright, ideal para pruebas de API pura. 3946- \`@soft_assertions\`: Los fallos en assertions no detienen el escenario. 3947- \`@PROJ-XXX\`: Integración con Jira (si está configurada). 3948- \`@TEST-XXX\`: Integración con Xray (si está configurada).`},{id:"requisitos-previos",title:"Requisitos Previos",content:`## Requisitos del Sistema 3949 3950Para utilizar Haka Framework necesitas tener instalado: 3951 3952| Requisito | Versión MÃnima | Notas | 3953|---|---|---| 3954| Python | 3.10+ | Disponible en el PATH del sistema | 3955| pip | (incluido con Python) | Gestor de paquetes | 3956| Node.js | 18+ | Necesario para Appium (pruebas mobile) | 3957| Git | Cualquiera | Para clonar el repositorio | 3958 3959> **Nota para macOS:** Los comandos \`python\` deben ejecutarse como \`python3\`. 3960 3961## Dependencias Opcionales 3962 3963Según el tipo de pruebas que necesites, puedes instalar dependencias adicionales: 3964 3965| Tipo de Prueba | Paquetes Adicionales | 3966|---|---| 3967| Validación semántica con IA | \`sentence-transformers torch transformers keybert scikit-learn\` | 3968| Evaluación con Gemini (GenAI) | \`google-generativeai\` | 3969| Pruebas mobile con Appium | \`Appium-Python-Client\` (incluido por defecto) | 3970| OCR | \`pytesseract easyocr Pillow opencv-python\` (incluidos por defecto) | 3971| Pruebas desktop | \`pyautogui pillow pyperclip pytesseract\` (incluido por defecto) | 3972| MySQL | \`mysql-connector-python\` | 3973| PostgreSQL | \`psycopg2-binary\` |`},{id:"instalacion",title:"Instalación desde repositorio",content:`## 1. Clonar el Repositorio 3974 3975\`\`\`bash 3976git clone https://github.com/HakaLab-2025/Engine-Playwright-Base.git 3977cd Engine-Playwright-Base 3978\`\`\` 3979 3980## 2. Crear Entorno Virtual (recomendado) 3981 3982\`\`\`bash 3983python -m venv venv 3984 3985# Windows 3986venv\\Scripts\\activate 3987 3988# macOS / Linux 3989source venv/bin/activate 3990\`\`\` 3991 3992## 3. Instalar Dependencias Base 3993 3994\`\`\`bash 3995pip install -r requirements.txt 3996\`\`\` 3997 3998Esto instala \`haka-playwright-engine\` junto con todas las dependencias necesarias para pruebas web, API y utilidades generales. 3999 4000## 4. Instalar Navegadores de Playwright 4001 4002\`\`\`bash 4003playwright install 4004\`\`\` 4005 4006Descarga los binarios de Chromium, Firefox y WebKit necesarios para ejecutar pruebas web. 4007 4008## 5. Configurar el Archivo .env 4009 4010\`\`\`bash 4011# Windows 4012copy ejemplo.env .env 4013 4014# macOS / Linux 4015cp ejemplo.env .env 4016\`\`\` 4017 4018Edita el archivo \`.env\` con la configuración de tu proyecto. 4019 4020## 6. Dependencias Opcionales 4021 4022\`\`\`bash 4023# Validación semántica con IA 4024pip install sentence-transformers torch transformers keybert scikit-learn 4025 4026# Evaluación con Gemini (GenAI) 4027pip install google-generativeai 4028 4029# Pruebas mobile con Appium 4030pip install Appium-Python-Client 4031 4032# OCR 4033pip install pytesseract easyocr Pillow opencv-python 4034 4035# Pruebas desktop 4036pip install pyautogui pillow pyperclip pytesseract 4037\`\`\` 4038 4039> La mayorÃa de estas dependencias ya están incluidas en el \`requirements.txt\` por defecto. Adicionalmente, para OCR se requiere instalar el binario de Tesseract.`},{id:"haka-init",title:"Instalación con haka-init",content:`## Crear un Proyecto Nuevo con haka-init 4040 4041\`haka-init\` genera la estructura completa de un proyecto de pruebas en segundos. Es la forma recomendada de empezar: crea los archivos de configuración, los features de ejemplo, los runners y la documentación, todo listo para ejecutar. 4042 4043## Pasos previos 4044 4045Antes de ejecutar \`haka-init\`, necesitás tener el framework instalado: 4046 4047### 1. Crear una carpeta para el proyecto 4048 4049\`\`\`bash 4050mkdir mi-proyecto-qa 4051cd mi-proyecto-qa 4052\`\`\` 4053 4054### 2. Crear un entorno virtual 4055 4056\`\`\`bash 4057python -m venv venv 4058 4059# Windows 4060venv\\Scripts\\activate 4061 4062# macOS / Linux 4063source venv/bin/activate 4064\`\`\` 4065 4066> En macOS usá \`python3\` en lugar de \`python\`. 4067 4068### 3. Instalar el framework 4069 4070\`\`\`bash 4071pip install haka-playwright-engine 4072\`\`\` 4073 4074Esto instala el framework y habilita los comandos \`haka-init\`, \`haka-run\`, \`haka-agent\`, \`haka-login\` y \`haka-ui\`. 4075 4076### 4. Ejecutar haka-init 4077 4078\`\`\`bash 4079haka-init 4080\`\`\` 4081 4082Esto genera la estructura base en el directorio actual (15 archivos). 4083 4084### 5. Instalar las dependencias del proyecto 4085 4086\`\`\`bash 4087pip install -r requirements.txt 4088\`\`\` 4089 4090El \`requirements.txt\` generado incluye todas las dependencias. Algunas están comentadas según el tipo de prueba: descomentá las que necesites (semántica, OCR, mobile). 4091 4092### 6. Instalar los navegadores de Playwright 4093 4094\`\`\`bash 4095playwright install 4096\`\`\` 4097 4098### 7. Configurar el .env 4099 4100Editá el archivo \`.env\` con la configuración de tu proyecto: \`BASE_URL\`, credenciales de IA, integraciones, etc. 4101 4102--- 4103 4104## Uso básico 4105 4106\`\`\`bash 4107# Genera la estructura en el directorio actual 4108haka-init 4109 4110# Genera en un subdirectorio nuevo 4111haka-init mi-suite 4112\`\`\` 4113 4114Si el directorio ya tiene archivos, \`haka-init\` los conserva sin tocar. Para reemplazarlos con los de la plantilla: 4115 4116\`\`\`bash 4117haka-init --force 4118\`\`\` 4119 4120--- 4121 4122## Módulos opcionales 4123 4124Los flags agregan archivos de configuración y ejemplos especÃficos. Se pueden combinar y se pueden ejecutar después sobre un proyecto existente para agregar lo que falta: 4125 4126\`\`\`bash 4127# Solo web (default) 4128haka-init 4129 4130# Web + integración Jira 4131haka-init --jira 4132 4133# Web + Jira + Xray 4134haka-init --jira --xray 4135 4136# Web + ejemplos de pruebas API 4137haka-init --api 4138 4139# Web + pruebas mobile (incluye APK de demo) 4140haka-init --mobile 4141 4142# Todo junto 4143haka-init --jira --xray --api --mobile 4144\`\`\` 4145 4146> \`--xray\` implica \`--jira\` automáticamente: no tiene sentido sin él. 4147 4148--- 4149 4150## Qué genera cada flag 4151 4152### Base (siempre) 4153 4154| Archivo | Descripción | 4155|---------|-------------| 4156| \`.env\` | Configuración completa del framework (292 variables) | 4157| \`behave.ini\` | Configuración de Behave | 4158| \`requirements.txt\` | Dependencias Python con opcionales comentados | 4159| \`.gitignore\` | Ignora reportes, videos, sesiones y virtualenvs | 4160| \`Runner.py\` | Ejecución serial con selección de features | 4161| \`Runner_parallel.py\` | Ejecución paralela (usa PARALLEL_WORKERS del .env) | 4162| \`report_config.json\` | TÃtulo, logos y colores del reporte HTML | 4163| \`json_poms/DEMO.json\` | POM de ejemplo con selectores reales (role=, XPath, id) | 4164| \`features/demo_formulario.feature\` | Scenario Outline ejecutable contra hakatools | 4165| \`features/environment.py\` | Carga del framework (no necesita modificación) | 4166| \`features/steps/custom_steps.py\` | Tus pasos personalizados | 4167| \`README.md\` | Documentación completa del proyecto | 4168| \`documentacion/README.md\` | GuÃa para documentación funcional | 4169 4170### --jira 4171 4172| Archivo | Descripción | 4173|---------|-------------| 4174| \`jira_config.json\` | Configuración de la integración con Jira: adjuntos, comentarios, creación de bugs, campos personalizados | 4175 4176### --xray 4177 4178| Archivo | Descripción | 4179|---------|-------------| 4180| \`xray_config.json\` | Configuración completa de Xray Cloud: matching por tags, evidencias, ciclo de vida de tests, manejo de errores | 4181 4182### --mobile 4183 4184| Archivo | Descripción | 4185|---------|-------------| 4186| \`apps/appDemo.apk\` | APK de la Sauce Labs Demo App para pruebas | 4187| \`json_poms/DEMOMOBILE.json\` | POM mobile con selectores Appium (xpath, content-desc) | 4188| \`features/demo_mobile.feature\` | Scenario Outline de flujo de carrito mobile | 4189 4190### --api 4191 4192| Archivo | Descripción | 4193|---------|-------------| 4194| \`features/demo_api.feature\` | 4 escenarios de pruebas API REST contra jsonplaceholder | 4195 4196--- 4197 4198## Estructura resultante (base + todos los módulos) 4199 4200\`\`\` 4201mi-proyecto-qa/ 4202|-- .env 4203|-- .gitignore 4204|-- behave.ini 4205|-- requirements.txt 4206|-- Runner.py 4207|-- Runner_parallel.py 4208|-- report_config.json 4209|-- jira_config.json (--jira) 4210|-- xray_config.json (--xray) 4211|-- README.md 4212|-- features/ 4213| |-- environment.py 4214| |-- demo_formulario.feature 4215| |-- demo_api.feature (--api) 4216| |-- demo_mobile.feature (--mobile) 4217| +-- steps/ 4218| |-- __init__.py 4219| +-- custom_steps.py 4220|-- json_poms/ 4221| |-- DEMO.json 4222| +-- DEMOMOBILE.json (--mobile) 4223|-- apps/ 4224| +-- appDemo.apk (--mobile) 4225|-- documentacion/ 4226| +-- README.md 4227+-- test_files/ 4228 +-- .gitkeep 4229\`\`\` 4230 4231--- 4232 4233## Archivos existentes 4234 4235\`haka-init\` nunca sobreescribe un archivo que ya existe. Si corrés el comando en un proyecto que ya tiene un \`.env\` propio, lo conserva: 4236 4237\`\`\`
4238ð¡ï¸ Conservados, ya existÃan (3): 4239 = .env 4240 = features/steps/custom_steps.py 4241 = Runner.py 4242 Usá --force si querés reemplazarlos por la plantilla. 4243\`\`\` 4244 4245Eso permite agregar módulos después sin riesgo: 4246 4247\`\`\`bash 4248# El proyecto ya existe, solo quiero agregar la config de Xray 4249haka-init --xray 4250\`\`\` 4251 4252--- 4253 4254## Ejemplo completo desde cero 4255 4256\`\`\`bash 4257# 1. Crear carpeta y entorno 4258mkdir mi-suite && cd mi-suite 4259python -m venv venv 4260source venv/bin/activate # Linux/Mac 4261# venv\\Scripts\\activate # Windows 4262 4263# 2. Instalar el framework 4264pip install haka-playwright-engine 4265 4266# 3. Generar el proyecto con API y Jira 4267haka-init --api --jira 4268 4269# 4. Instalar dependencias del proyecto 4270pip install -r requirements.txt 4271 4272# 5. Instalar navegadores 4273playwright install 4274 4275# 6. Ejecutar la demo 4276python Runner.py 4277\`\`\` 4278 4279El feature de demo corre contra \`hakatools.hakalab.com\` sin necesidad de configurar nada más.`},{id:"configuracion-env",title:"Configuración (.env)",content:'## Descripción General\n\nEl framework usa un archivo `.env` en la raÃz del proyecto para toda la configuración. Se carga automáticamente con `python-dotenv` con `override=True`, lo que significa que las variables del `.env` tienen prioridad sobre las del sistema.\n\n> **Importante:** No subas el `.env` con credenciales reales a Git. Usa variables de entorno del sistema o secretos de CI/CD para datos sensibles.\n\n---\n\n## Navegador y Pruebas Web\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `BROWSER` | string | `chromium` | Navegador: `chromium`, `firefox`, `webkit`, `chrome` |\n| `HEADLESS` | bool | `false` | Ejecutar sin interfaz gráfica |\n| `TIMEOUT` | int (ms) | `30000` | Timeout global para operaciones de Playwright |\n| `ASSERTION_TIMEOUT` | int (ms) | `30000` | Timeout especÃfico para assertions/verificaciones |\n| `VIEWPORT_WIDTH` | int | `1920` | Ancho del viewport en pÃxeles |\n| `VIEWPORT_HEIGHT` | int | `1080` | Alto del viewport en pÃxeles |\n| `DEVICE_SCALE_FACTOR` | float | `1` | Factor de escala del dispositivo (2 para retina) |\n| `SLOW_MO` | int (ms) | `0` | Milisegundos de pausa entre cada acción |\n| `BASE_URL` | string | `""` | URL base de la aplicación bajo prueba |\n| `IGNORE_HTTPS_ERRORS` | bool | `false` | Ignorar errores de certificados SSL |\n| `BROWSER_USER_AGENT` | string | `""` | User agent personalizado |\n| `NAVIGATION_TIMEOUT` | int (ms) | `10000` | Timeout para navegación |\n| `WAIT_UNTIL` | string | `load` | Evento de espera: `load`, `domcontentloaded`, `networkidle` |\n| `DISABLE_NETWORKIDLE_WAIT` | bool | `true` | Desactivar espera de networkidle |\n\n**Configuración avanzada del navegador:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `BROWSER_ARGS` | string | `""` | Argumentos adicionales separados por coma |\n| `BROWSER_CONFIG_PRESET` | string | `""` | Preset: `performance`, `mobile`, `cicd`, `security_disabled` |\n| `BROWSER_CONFIG_FILE` | string | `""` | Ruta a archivo JSON con argumentos |\n| `BROWSER_MEMORY_LIMIT` | int (MB) | `4096` | LÃmite de memoria para el navegador |\n| `BROWSER_PROXY` | string | `""` | URL del proxy (ej: `http://proxy:8080`) |\n| `BROWSER_DOWNLOADS_DIR` | string | `downloads` | Directorio para archivos descargados |\n\n**Chrome/Chromium:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `CHROME_DISABLE_SECURITY` | bool | `false` | Desactivar seguridad web |\n| `CHROME_ENABLE_LOGGING` | bool | `false` | Activar logging del navegador |\n| `CHROME_LOG_LEVEL` | string | `INFO` | Nivel de log del navegador |\n| `CHROME_DISABLE_EXTENSIONS` | bool | `true` | Desactivar extensiones |\n| `CHROME_DISABLE_PLUGINS` | bool | `true` | Desactivar plugins |\n| `CHROME_DISABLE_IMAGES` | bool | `false` | No cargar imágenes (acelera pruebas) |\n| `CHROME_DISABLE_JAVASCRIPT` | bool | `false` | Desactivar JavaScript |\n\n**Firefox:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `FIREFOX_PROFILE_PATH` | string | `""` | Ruta a perfil personalizado |\n| `FIREFOX_DISABLE_ADDONS` | bool | `true` | Desactivar addons |\n| `FIREFOX_PRIVATE_MODE` | bool | `false` | Abrir en modo privado |\n\n---\n\n## Screenshots y Video\n\n**Screenshots:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `SCREENSHOTS_DIR` | str
4279ing | `reports/screenshots` | Directorio de screenshots |\n| `SCREENSHOT_FULL_PAGE` | bool | `false` | Capturar página completa o solo viewport |\n| `AUTO_SCREENSHOT_ON_FAILURE` | bool | `true` | Screenshot automático al fallar |\n| `HTML_REPORT_CAPTURE_ALL_STEPS` | bool | `true` | Capturar screenshot en cada step |\n| `CAPTURE_FRAMEWORK_STEPS` | bool | `false` | Capturar steps internos del framework |\n\n**Video:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `RECORD_VIDEO` | bool | `false` | Activar grabación de video |\n| `VIDEO_DIR` | string | `reports/videos` | Directorio de videos |\n| `VIDEO_SIZE` | string | `1280x720` | Resolución del video |\n| `VIDEO_MODE` | string | `retain-on-failure` | Cuándo guardar: `on`, `off`, `retain-on-failure` |\n| `VIDEO_INTRO_ENABLED` | bool | `true` | Habilitar intro en el video |\n| `CLEANUP_OLD_VIDEOS` | bool | `true` | Limpiar videos antiguos |\n| `VIDEO_MAX_AGE_HOURS` | int | `48` | Edad máxima de videos en horas |\n\n---\n\n## Reportes\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `USE_HTML_REPORT` | bool | `true` | Generar reporte HTML |\n| `HTML_REPORTS_DIR` | string | `reports/html-reports` | Directorio para reportes HTML |\n| `CLEANUP_OLD_FILES` | bool | `true` | Limpieza automática de archivos |\n| `CLEANUP_MODE` | string | `all` | Modo de limpieza: `all` o `old` |\n| `CLEANUP_MAX_AGE_HOURS` | int | `24` | Edad máxima en horas para modo `old` |\n\n**Reportes de IA:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `GENERATE_AI_REPORT` | bool | `true` | Generar reporte de validaciones de IA |\n| `AI_REPORT_PATH` | string | `reports/html-reports/ai-reports` | Directorio para reportes de IA |\n| `AI_REPORT_ANALYSIS` | bool | `true` | Usar Gemini para análisis automático |\n\n---\n\n## API Testing\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `API_BASE_URL` | string | `""` | URL base para testing de APIs |\n| `API_TIMEOUT` | int (s) | `30` | Timeout para requests HTTP |\n| `API_KEY` | string | `""` | API Key para autenticación |\n| `BEARER_TOKEN` | string | `""` | Bearer token para autenticación |\n\n---\n\n## Base de Datos\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `DB_TYPE` | string | `sqlite` | Tipo: `sqlite`, `mysql`, `postgresql` |\n| `DB_SQLITE_PATH` | string | `test_data/test.db` | Ruta al archivo SQLite |\n| `DB_SQLITE_TIMEOUT` | int (s) | `30` | Timeout de conexión SQLite |\n| `DB_CONNECTION_TIMEOUT` | int (s) | `30` | Timeout de conexión general |\n| `DB_QUERY_TIMEOUT` | int (s) | `60` | Timeout de queries |\n| `DB_AUTO_COMMIT` | bool | `true` | Auto-commit en escritura |\n| `DB_DEBUG_QUERIES` | bool | `false` | Mostrar queries en el log |\n\n**MySQL:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `DB_MYSQL_HOST` | string | `localhost` | Host |\n| `DB_MYSQL_PORT` | int | `3306` | Puerto |\n| `DB_MYSQL_DATABASE` | string | `test_db` | Base de datos |\n| `DB_MYSQL_USERNAME` | string | `test_user` | Usuario |\n| `DB_MYSQL_PASSWORD` | str
4279ing | `test_password` | Contraseña |\n| `DB_MYSQL_CHARSET` | string | `utf8mb4` | Charset |\n\n**PostgreSQL:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `DB_POSTGRES_HOST` | string | `localhost` | Host |\n| `DB_POSTGRES_PORT` | int | `5432` | Puerto |\n| `DB_POSTGRES_DATABASE` | string | `test_db` | Base de datos |\n| `DB_POSTGRES_USERNAME` | string | `test_user` | Usuario |\n| `DB_POSTGRES_PASSWORD` | string | `test_password` | Contraseña |\n| `DB_POSTGRES_SCHEMA` | string | `public` | Schema |\n\n---\n\n## Gemini AI (Juez GenAI)\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `GEMINI_API_KEY` | string | â | API Key de Google Gemini |\n| `GEMINI_JUDGE_MODEL` | string | `gemini-3.1-flash-lite-preview` | Modelo de Gemini |\n| `GEMINI_DEFAULT_THRESHOLD` | float | `0.8` | Umbral por defecto (0.0-1.0) |\n| `GEMINI_CACHE_TTL_HOURS` | int | `1` | TTL del caché en horas |\n| `GEMINI_JUDGE_PROMPT_FILE` | string | `""` | Ruta a prompt personalizado |\n\n**Valores recomendados para el umbral:**\n- `0.90 - 1.00`: Excelencia (muy estricto)\n- `0.80 - 0.89`: Bueno (recomendado para producción)\n- `0.70 - 0.79`: Aceptable (más permisivo)\n- `0.60 - 0.69`: Básico (desarrollo/testing)\n\n**Vectorización (Supabase):**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `SUPABASE_URL` | string | `""` | URL de Supabase |\n| `SUPABASE_KEY` | string | `""` | Key de Supabase |\n\n---\n\n## Validación Semántica\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `SEMANTIC_MODEL` | string | `paraphrase-multilingual-MiniLM-L12-v2` | Modelo de Sentence Transformers |\n| `SEMANTIC_THRESHOLD` | float | `0.75` | Umbral de similitud (0.0-1.0) |\n| `HIDE_TRANSFORMERS_WARNINGS` | bool | `true` | Ocultar warnings de transformers |\n| `HIDE_HF_WARNINGS` | bool | `true` | Ocultar warnings de HuggingFace |\n| `HIDE_BEHAVE_WARNINGS` | bool | `true` | Ocultar warnings de Behave |\n\n**Modelos disponibles:**\n- `paraphrase-multilingual-MiniLM-L12-v2` â Multilingüe, balanceado (~420MB) â **Recomendado**\n- `paraphrase-multilingual-mpnet-base-v2` â Multilingüe, más preciso (~1GB)\n- `all-MiniLM-L6-v2` â Solo inglés, rápido (~80MB)\n\n---\n\n## OCR / Tesseract\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `OCR_ENGINE` | string | `auto` | Motor OCR: `auto`, `tesseract`, `easyocr` |\n| `OCR_LANGUAGES` | string | `en,es` | Idiomas para OCR |\n| `OCR_MIN_CONFIDENCE` | float | `70.0` | Confianza mÃnima para resultados |\n| `OCR_PREPROCESSING` | string | `default` | Preprocesamiento: `default`, `denoise`, `enhance`, `morphology` |\n| `TESSERACT_PATH` | string | `""` | Ruta al ejecutable de Tesseract |\n| `OCR_SAVE_PROCESSED_IMAGES` | bool | `false` | Guardar imágenes procesadas |\n| `OCR_DEBUG_MODE` | bool | `false` | Modo debug de OCR |\n\n---\n\n## Integraciones (Jira, Xray, Azure DevOps)\n\n**Jira:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `JIRA_ENABLED` | bool | `false` | Activar integración con Jira |\n| `JIRA_URL` | string | `""` | URL de la instancia Jira |\n| `JIRA_EMAIL` | string | `""` | Email de la cuenta Jira |\n| `JIRA_TOKEN` | string | `""` | API token de Jira |\n| `JIRA_PROJECT` | string | `""` | Clave del proyecto (ej: `PROJ`) |\n| `JIRA_COMMENT_MESSAGE` | string | `Reporte prueba de QA` | Mensaje para comentarios |\n\n**Xray:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `XRAY_ENABLED` | bool | `false` | Activar integración con Xray |\n| `XRAY_AUTHORIZATION_TOKEN` | string | `""` | Bearer token de Xray Cloud |\n| `XRAY_BASE_URL` | string | `https://xray.cloud.getxray.app` | URL base de Xray |\n\n**Azure DevOps:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `AZURE_DEVOPS_ENABLED` | bool | `false` | Activar integración |\n| `AZURE_DEVOPS_ORG` | string | `""` | Nombre de la organización |\n| `AZURE_DEVOPS_PROJECT` | string | `""` | Nombre del proyecto |\n| `AZURE_DEVOPS_PAT` | string | `""` | Personal Access Token |\n\n---\n\n## Paralelización\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `PARALLEL_WORKERS` | int | `1` | Número de workers paralelos |\n| `MAX_BROWSER_INSTANCES` | int | `1` | Máximo instancias de navegador |\n| `BROWSER_POOL_SIZE` | int | `5` | Tamaño del pool de navegadores |\n| `WORKER_TIMEOUT` | int (s) | `300` | Timeout por worker |\n| `SHARD_INDEX` | int | â | Ãndice del shard actual (CI/CD) |\n| `TOTAL_SHARDS` | int | â | Total de shards (CI/CD) |\n\n---\n\n## Modo Stealth\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `STEALTH_MODE` | bool | `false` | Activar modo anti-detección |\n\nOculta propiedades que delatan automatización. Ãt
4279il para evitar detección de bots. Requiere `playwright-stealth` (incluido en `requirements.txt`).\n\n---\n\n## Logging y Debug\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `LOG_LEVEL` | string | `INFO` | Nivel: `DEBUG`, `INFO`, `WARNING`, `ERROR` |\n| `HAKALAB_DEBUG` | bool | `true` | Mensajes de debug del framework |\n| `HAKALAB_SHOW_STEPS` | bool | `false` | Mostrar lista de steps cargados al iniciar |\n\n---\n\n## Datos de Prueba\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `TEST_EMAIL` | string | `""` | Email de prueba (`context.test_data[\'email\']`) |\n| `TEST_PASSWORD` | string | `""` | Contraseña de prueba |\n| `TEST_USER_NAME` | string | `""` | Nombre de usuario de prueba |\n\n---\n\n## Reintentos\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `RETRY_FAILED_STEPS` | int | `0` | Reintentos para steps fallidos |\n| `RETRY_FAILED_SCENARIOS` | bool | `false` | Reintentos automáticos de escenarios |\n| `MAX_SCENARIO_RETRIES` | int | `1` | Máximo reintentos por escenario |\n\n---\n\n## Notas Generales\n\n- No pongas comillas alrededor de los valores en el `.env`.\n- Las variables son CASE SENSITIVE.\n- Nunca commitees el `.env` con credenciales reales.\n- Las variables del `.env` tienen prioridad sobre las del sistema (`override=True`).'},{id:"environment-py",title:"Configurar environment.py",content:`## Environment.py Simple (Recomendado) 4280 4281El archivo \`features/environment.py\` es el punto de entrada del ciclo de vida de Behave. Inicializa el framework, maneja screenshots, reportes y limpieza de recursos. 4282 4283\`\`\`python 4284from hakalab_framework import setup_framework_context, setup_scenario_context 4285from hakalab_framework.core.screenshot_manager import take_screenshot_on_failure 4286from hakalab_framework.core.environment_config import auto_after_scenario, auto_after_all 4287from hakalab_framework.core.soft_assertion_hooks import ( 4288 before_scenario_soft_assertions, 4289 after_step_soft_assertions, 4290 after_scenario_soft_assertions 4291) 4292from hakalab_framework.steps import * 4293 4294 4295def before_all(context): 4296 from hakalab_framework.core.screenshot_manager import cleanup_directories 4297 cleanup_directories() 4298 setup_framework_context(context) 4299 4300def before_scenario(context, scenario): 4301 if 'no_browser' in [tag.lower() for tag in getattr(scenario, 'tags', [])]: 4302 context.browser_disabled = True 4303 setup_scenario_context(context, scenario) 4304 before_scenario_soft_assertions(context, scenario) 4305 4306def after_step(context, step): 4307 after_step_soft_assertions(context, step) 4308 4309def after_scenario(context, scenario): 4310 try: 4311 after_scenario_soft_assertions(context, scenario) 4312 except AssertionError: 4313 pass 4314 take_screenshot_on_failure(context, scenario) 4315 auto_after_scenario(context, scenario) 4316 4317def after_all(context): 4318 if hasattr(context, 'framework_config') and context.framework_config: 4319 context.framework_config.cleanup() 4320 auto_after_all(context) 4321\`\`\` 4322 4323## Consideraciones 4324 4325- \`from hakalab_framework.steps import *\` es OBLIGATORIO â importa todos los steps. 4326- \`setup_framework_context(context)\` inicializa Playwright, variables, localizadores e integraciones.
4327- \`setup_scenario_context(context, scenario)\` crea o reutiliza la página del navegador.`},{id:"ejecucion",title:"Ejecución de Pruebas",content:`## Ejecución Directa con Behave 4328 4329\`\`\`bash 4330# Ejecutar todos los features 4331python -m behave 4332 4333# Ejecutar un feature especÃfico 4334python -m behave features/demo.feature 4335 4336# Ejecutar con un tag especÃfico 4337python -m behave --tags=@mi_tag 4338 4339# Ejecutar excluyendo tags 4340python -m behave --tags="not @wip" 4341 4342# Sin captura de output (ver prints en consola) 4343python -m behave --no-capture --no-skipped 4344\`\`\` 4345 4346## Ejecución con Runner.py 4347 4348El proyecto incluye un \`Runner.py\` que permite ejecutar pruebas con tags: 4349 4350\`\`\`bash 4351python Runner.py 4352\`\`\` 4353 4354> Por defecto el \`Runner.py\` ejecuta con el tag configurado internamente. Modifica la variable \`tags\` en el archivo según tus necesidades. 4355 4356## Configuración de Behave (behave.ini) 4357 4358\`\`\`ini 4359[behave] 4360paths = features 4361show_timings = true 4362show_skipped = false 4363logging_level = INFO 4364\`\`\` 4365 4366## Ejecución por Tags 4367 4368\`\`\`bash 4369# Combinar tags 4370behave --tags="@smoke and @login" 4371 4372# Un escenario especÃfico por nombre 4373behave --name="Validar login con credenciales válidas" 4374 4375# Ejecución paralela (CLI del framework) 4376haka-run --workers=4 --features=features/ 4377\`\`\``},{id:"tags-especiales",title:"Tags Especiales",content:`## Tags del Framework 4378 4379Los tags de Behave controlan el comportamiento del framework durante la ejecución: 4380 4381| Tag | Descripción | 4382|---|---| 4383| \`@no_browser\` | Desactiva la inicialización del navegador. Esencial para pruebas de API, BD, semántica o desktop. | 4384| \`@desktop\` | Indica que el escenario es una prueba de escritorio. Usar junto con \`@no_browser\`. | 4385| \`@mobile\` | Configura viewport móvil automáticamente (375x667). | 4386| \`@soft_assertions\` | Activa soft assertions para el escenario. Los fallos no detienen la ejecución. | 4387| \`@retry\` | Marca el escenario para reintento automático si falla (requiere \`RETRY_FAILED_SCENARIOS=true\`). | 4388| \`@JIRA-123\` | Vincula el escenario a una issue de Jira. El reporte se adjunta automáticamente. | 4389| \`@TEST-XXX\` | Integración con Xray (si está configurada). | 4390| \`@security\` | Activa la auditorÃa de seguridad pasiva (también \`@seguridad\` / \`@pentest\`). Funciona a nivel de escenario o feature. | 4391| \`@wip\` | Work in progress. Behave lo salta por defecto. | 4392| \`@skip\` | Salta el escenario. | 4393 4394## AuditorÃa de seguridad (\`@security\`) 4395 4396El tag \`@security\` audita el tráfico de red de la prueba y genera un reporte en \`reports/security/\` (JSON determinista + HTML). Revisa cabeceras de seguridad, cookies, CORS, mixed content y exposición de tecnologÃa. No hace fallar el escenario salvo que uses los steps de aserción de seguridad. 4397 4398### Análisis con IA (opcional) 4399 4400El reporte HTML incluye un **análisis complementario con IA** solo si hay un proveedor de IA configurado en el \`.env\`. Usa las mismas variables que el resto del framework: 4401 4402\`\`\`env 4403AI_PROVIDER=gemini # gemini | openai | anthropic | ollama 4404AI_MODEL=gemini-2.5-flash # opcional (hay default por proveedor) 4405 4406# Credencial según el proveedor elegido: 4407GEMINI_API_KEY=... 4408OPENAI_API_KEY=... 4409ANTHROPIC_API_KEY=... 4410OLLAMA_BASE_URL=http://localhost:11434 # para Ollama local 4411\`\`\` 4412 4413Sin proveedor configurado, la auditorÃa igual genera el reporte determinista (JSON + HTML) y solo omite la sección "Análisis con IA". No existe una variable especÃfica de seguridad para la IA. 4414 4415También puedes cambiar la carpeta de salida con \`SECURITY_REPORTS_DIR\` o desactivar la auditorÃa por completo con \`SECURITY_AUDIT_ENABLED=false\`. 4416 4417## Ejemplo de Uso 4418 4419\`\`\`gherkin 4420@no_browser @JIRA-456 4421Feature: Pruebas de API 4422 4423 @soft_assertions @retry 4424 Scenario: Validar endpoint de usuarios 4425 Given configuro la API base en "\${ENV.API_BASE_URL}" 4426 When realizo GET a "/usuarios" 4427 Then la respuesta deberia tener codigo "200" 4428\`\`\` 4429 4430\`\`\`gherkin 4431@desktop @no_browser 4432Feature: Pruebas de escritorio 4433 4434 Scenario: Verificar calculadora 4435 Given lanzo y espero "2" segundos la aplicacion "calc.exe" 4436 When hago click en la imagen "calculadora/boton_1" 4437\`\`\``}]},{id:"localizadores",title:"Localizadores",group:"Fundamentos",icon:"",topics:[{id:"json-poms",title:"JSON POMs",content:`## Qué es un JSON POM 4438 4439Los JSON POMs (Page Object Models en formato JSON) almacenan los selectores de elementos por página o módulo. Se leen desde la carpeta \`json_poms/\` y se exponen con \`$.ARCHIVO.elemento\`. 4440 4441### Ejemplo: json_poms/LOGIN.json 4442 4443\`\`\`json 4444{ 4445 "input_usuario": "#username", 4446 "input_password": "#password", 4447 "btn_login": "button[type='submit']", 4448 "mensaje_error": ".alert-error", 4449 "link_recuperar": "a[href='/forgot-password']" 4450} 4451\`\`\` 4452 4453### Uso en el feature 4454 4455\`\`\`gherkin 4456When relleno el campo "usuario" con "admin" con identificador "$.LOGIN.input_usuario" 4457And relleno el campo "clave" con "1234" con identificador "$.LOGIN.input_password" 4458And hago click en el elemento "boton login" con identificador "$.LOGIN.btn_login" 4459\`\`\` 4460 4461## Tipos de Selectores Soportados 4462 4463\`\`\`json 4464{ 4465 "por_id": "#mi-elemento", 4466 "por_clase": ".mi-clase", 4467 "por_css": "button.primary[type='submit']", 4468 "por_xpath": "//button[contains(text(),'Guardar')]", 4469 "por_atributo": "[data-testid='submit-btn']", 4470 "por_name": "[name='fieldName:REGION']" 4471} 4472\`\`\` 4473 4474## Formato por Tipo/Valor (Inferencia Automática) 4475 4476\`\`\`json 4477{ 4478 "titulo": {"type": "text", "value": "Bienvenido"}, 4479 "campo_email": {"type": "placeholder", "value": "Ingrese su email"}, 4480 "contenedor": {"type": "id", "value": "main-container"}, 4481 "boton": {"type": "class", "value": "btn-primary"},
4482 "custom": {"type": "data-testid", "value": "login-form"} 4483} 4484\`\`\` 4485 4486## Formato por Role (Accesibilidad) 4487 4488\`\`\`json 4489{ 4490 "campo_nombre": {"role": "textbox", "type": "name", "value": "Ingresa tu nombre"}, 4491 "boton_login": {"role": "button", "type": "exact", "value": "Login"} 4492} 4493\`\`\` 4494 4495## Formato con Fallbacks Automáticos 4496 4497\`\`\`json 4498{ 4499 "btn_guardar": { 4500 "selector": "button.primary", 4501 "fallbacks": ["button[type='submit']", "//button[text()='Guardar']"] 4502 } 4503} 4504\`\`\` 4505 4506Si el selector principal no encuentra el elemento, el framework prueba cada fallback en orden. 4507 4508## Placeholders Dinámicos 4509 4510\`\`\`json 4511{ 4512 "resultado_por_texto": "//*[contains(text(), '<valor>')]", 4513 "checkbox_por_indice": "(//input[@type='checkbox'])[<valor_int>]" 4514} 4515\`\`\` 4516 4517\`\`\`gherkin 4518When hago click en el elemento "resultado" con identificador "$.SEARCH.resultado_por_texto=Hola Mundo" 4519\`\`\``},{id:"localizadores-dinamicos",title:"Localizadores Dinámicos",content:`## Placeholders en Selectores 4520 4521Cuando el selector incluye un valor variable se usan placeholders que se reemplazan en tiempo de ejecución. 4522 4523\`\`\`json 4524{ 4525 "fila_por_nombre": "//tr[td[contains(text(), '<valor>')]]", 4526 "opcion_select": "option[value='<valor>']" 4527} 4528\`\`\` 4529 4530\`\`\`gherkin 4531When hago click en el elemento "fila Juan" con identificador "$.TABLA.fila_por_nombre=Juan Pérez" 4532\`\`\` 4533 4534## Ãndices para N-ésimo Elemento 4535 4536Cuando un selector retorna múltiples elementos, selecciona uno con \`[n]\` (Ãndice desde 0). 4537 4538\`\`\`gherkin 4539When hago click en el elemento "primer resultado" con identificador "$.LISTA.item_lista[0]" 4540And hago click en el elemento "tercer resultado" con identificador "$.LISTA.item_lista[2]" 4541\`\`\` 4542 4543## Selectores Inline (sin JSON POM) 4544 4545Si el identificador NO comienza con \`$.\`, se trata como selector directo. 4546 4547\`\`\`gherkin 4548When hago click en el elemento "boton" con identificador "button.primary" 4549And relleno el campo "nombre" con "Ana" con identificador "#campo-nombre" 4550And hago click en el elemento "link" con identificador "//a[contains(text(),'Ver más')]" 4551\`\`\``},{id:"helpers-context",title:"Helpers de Contexto",content:'## Helpers para Custom Steps\n\nEl framework provee funciones helper en `context` para simplificar el uso de localizadores en pasos personalizados.\n\n```python\n@step(\'hago login rápido con "{user}" y "{password}"\')\ndef step_quick_login(context, user, password):\n context.fill("$.LOGIN.input_usuario", user)\n context.fill("$.LOGIN.input_password", password)\n context.click("$.LOGIN.btn_login")\n context.wait_for("$.DASHBOARD.panel_principal")\n```\n\n## Helpers Disponibles\n\n- `context.find()` â Retorna un Locator de Playwright\n- `context.find_all()` â Retorna lista de Locators\n- `context.click()` â Click en elemento\n- `context.fill()` â Rellenar campo (resuelve variables)\n- `context.get_text()` â Obtener text_content()\n- `context.is_visible()` â Verificar visibilidad\n- `context.wait_for()` â Esperar elemento visible\n- `context.hover()` â Hover sobre elemento\n- `context.select()` â Seleccionar opción\n- `context.check()` / `context.uncheck()` â Checkbox\n\n### Helpers Avanzados\n\n- `context.wait_and_click()`\n- `context.scroll_and_click()`\n- `context.retry_action()`\n- `context.conditional_action()`'}]},{id:"variables",title:"Variables",group:"Fundamentos",icon:"",topics:[{id:"variables-basico",title:"Crear y Usar Variables",content:`## Crear Variable con Valor Fijo 4552 4553\`\`\`gherkin 4554When creo la variable "nombre_usuario" con valor "Juan Pérez" 4555And relleno el campo "nombre" con "\${nombre_usuario}" con identificador "$.FORM.input_nombre" 4556\`\`\` 4557 4558## Variables Aleatorias 4559 4560\`\`\`gherkin 4561When genero una variable "codigo_otp" con número aleatorio entre 100000 y 999999 4562When genero una variable "usuario_temp" con texto aleatorio de 8 caracteres 4563\`\`\` 4564 4565## Variables de Fecha 4566 4567\`\`\`gherkin 4568When genero una variable "fecha_hoy" con fecha actual usando formato "%d/%m/%Y" 4569When genero una variable "fecha_vencimiento" con fecha actual en formato "%d/%m/%Y" sumando 5 dÃas hábiles 4570\`\`\` 4571 4572## Variables de Entorno (.env) 4573 4574\`\`\`gherkin 4575Given voy a la url "\${ENV.BASE_URL}/login" 4576When relleno el campo "usuario" con "\${ENV.TEST_USER}" con identificador "$.LOGIN.input_user" 4577\`\`\` 4578 4579## Extraer Texto de un Elemento 4580 4581\`\`\`gherkin 4582When guardo el texto del elemento "$.RESULT.codigo" en la variable "codigo_generado"
4583Then verifico que la variable "codigo_generado" contiene "TXN-" 4584\`\`\` 4585 4586## Concatenar Variables 4587 4588\`\`\`gherkin 4589When creo la variable "cuenta_clp" con valor "CL123456789" 4590And concateno "AC S " y "\${cuenta_clp}" y lo guardo en la variable "busqueda_clp" 4591Then verifico que la variable "busqueda_clp" contiene "AC S CL123456789" 4592\`\`\``},{id:"variables-sintaxis",title:"Sintaxis de Variables",content:'## Regla de Oro\n\n**Variables existentes se referencian con `${nombre_variable}`**\n\nCuando quieres usar el **valor** de una variable que ya existe, debes usar: `${nombre_variable}`\n\n## Tabla Rápida de Referencia\n\n| Necesito... | Sintaxis | Ejemplo |\n|---|---|---|\n| Usar el VALOR de una variable | `${nombre}` | `relleno el campo "email" con "${email_usuario}"` |\n| Pasar el NOMBRE como parámetro | `nombre` (sin `${}`) | `verifico que la variable "email_usuario" contiene "@"` |\n| Crear una variable nueva | `"nombre"` (sin `${}`) | `creo la variable "resultado" con valor "42"` |\n| Guardar resultado en variable | `"nombre"` (sin `${}`) | `guardo el texto en la variable "titulo"` |\n| Concatenar variable + texto | `"texto" y "${variable}"` | `concateno "AC S " y "${cuenta}"` |\n\n## Ejemplo Completo\n\n```gherkin\nScenario: Encadenamiento de Variables\n Given creo la variable "prefijo" con valor "USR"\n And creo la variable "dominio" con valor "@miapp.com"\n When concateno "${prefijo}" y "_admin" y lo guardo en la variable "username"\n And concateno "${username}" y "${dominio}" y lo guardo en la variable "email"\n And relleno el campo "email" con "${email}" con identificador "$.FORM.input_email"\n Then verifico que la variable "email" contiene "@miapp.com"\n```\n\n**Variables resultantes:**\n- `prefijo` = "USR"\n- `username` = "USR_admin"\n- `email` = "[email protected]"'}]},{id:"pruebas-web",title:"Pruebas Web",group:"Tipos de Prueba",icon:"",topics:[{id:"steps-navegacion",title:"Inventario: Navegación",content:`## Navegación 4593 4594step: voy a la url "{url}" 4595descripcion: Navega a una URL especÃfica y espera a que la página cargue completamente. Soporta variables y reintentos automáticos. 4596 4597step: voy hacia atrás 4598descripcion: Navega hacia atrás en el historial del navegador y espera a que la página cargue. 4599 4600step: voy hacia adelante 4601descripcion: Navega hacia adelante en el historial del navegador y espera a que la página cargue. 4602 4603step: recargo la página 4604descripcion: Recarga la página actual y espera a que cargue completamente. 4605 4606step: espero a que cargue la página 4607descripcion: Espera a que la página termine de cargar según la estrategia de espera configurada. 4608 4609step: abro una nueva pestaña 4610descripcion: Abre una nueva pestaña en el navegador con los timeouts configurados. 4611 4612step: cierro la pestaña actual 4613descripcion: Cierra la pestaña actualmente activa del navegador. 4614 4615step: cambio a la pestaña {tab_index:d} 4616descripcion: Cambia a una pestaña especÃfica por su Ãndice numérico. 4617 4618step: maximizo la ventana 4619descripcion: Maximiza la ventana del navegador estableciendo el viewport a 1920x1080. 4620 4621step: establezco el tamaño de ventana a {width:d}x{height:d} 4622descripcion: Establece el tamaño de la ventana del navegador a dimensiones especÃficas en pÃxeles.`},{id:"steps-interaccion",title:"Inventario: Interacción",content:`## Interacción con Elementos 4623 4624step: hago click en el elemento "{element_name}" con identificador "{identifier}" 4625descripcion: Hace click en un elemento web. Espera a que sea visible antes de hacer click y añade una pausa de estabilización. 4626 4627step: hago click en el select "{element_name}" con identificador "{identifier}" 4628descripcion: Hace click en un elemento select/combobox para abrirlo. 4629 4630step: hago doble click en el elemento "{element_name}" con identificador "{identifier}" 4631descripcion: Hace doble click en un elemento web especÃfico. 4632 4633step: hago click derecho en el elemento "{element_name}" con identificador "{identifier}" 4634descripcion: Hace click derecho (menú contextual) en un elemento web. 4635 4636step: paso el mouse sobre el elemento "{element_name}" con identificador "{identifier}" 4637descripcion: Pasa el mouse sobre un elemento (hover) para activar efectos o menús desplegables. 4638 4639step: relleno el campo "{field_name}" con "{text}" con identificador "{identifier}" 4640descripcion: Rellena un campo de texto con el valor especificado. Soporta resolución de variables. 4641 4642step: relleno el campo de fecha "{field_name}" con "{date_text}" con identificador "{identifier}" 4643descripcion: Rellena un campo de fecha (input type="date") y dispara eventos de Angular. Acepta formatos DD-MM-YYYY y YYYY-MM-DD. 4644 4645step: limpio el campo "{field_name}" con identificador "{identifier}" 4646descripcion: Limpia completamente el contenido de un campo de texto. 4647 4648step: escribo "{text}" en el campo "{field_name}" con identificador "{identifier}" 4649descripcion: Escribe texto en un campo sin limpiar el contenido previo (append). 4650 4651step: selecciono la opción "{option}" del dropdown "{dropdown_name}" con identificador "{identifier}" 4652descripcion: Selecciona una opción de un dropdown/select por su texto visible. 4653 4654step: marco el checkbox "{checkbox_name}" con identificador "{identifier}" 4655descripcion: Marca un checkbox que está desmarcado. 4656 4657step: desmarco el checkbox "{checkbox_name}" con identificador "{identifier}" 4658descripcion: Desmarca un checkbox que está marcado. 4659 4660step: subo el archivo "{file_path}" al campo "{field_name}" con identificador "{identifier}" 4661descripcion: Sube un archivo al campo de tipo file especificado. 4662 4663step: remuevo el atributo "{attribute_name}" del elemento "{element_name}" con identificador "{identifier}" 4664descripcion: Remueve un atributo HTML de un elemento usando JavaScript (ej: readonly, disabled). 4665 4666step: establezco el atributo "{attribute_name}" a "{attribute_value}" en el elemento "{element_name}" con identificador "{identifier}" 4667descripcion: Establece o modifica un atributo HTML de un elemento usando JavaScript. 4668 4669step: verifico que el elemento "{element_name}" con identificador "{identifier}" tiene el atributo "{attribute_name}" 4670descripcion: Verifica que un elemento tiene un atributo HTML especÃfico presente. 4671 4672step: verifico que el elemento "{element_name}" con identificador "{identifier}" no tiene el atributo "{attribute_name}" 4673descripcion: Verifica que un elemento NO tiene un atributo HTML especÃfico. 4674 4675step: obtengo el atributo "{attribute_name}" del elemento "{element_name}" con identificador "{identifier}" y lo guardo en la variable "{variable_name}" 4676descripcion: Obtiene el valor de un atributo HTML de un elemento y lo guarda en una variable del framework. 4677 4678step: selecciono la fecha "{date_text}" en el input de fecha "{identifier}" 4679descripcion: Selecciona una fecha en un input nativo de tipo date, disparando eventos de Angular para validación. 4680 4681step: abro el calendario y relleno el campo de fecha "{field_name}" con "{date_text}" con identificador "{identifier}" 4682descripcion: Abre el calendario nativo del navegador y rellena el campo de fecha, disparando todos los eventos necesarios. 4683 4684step: abro el calendario html desde el icono derecho con localizador "{identifier}" 4685descripcion: Abre un calendario HTML haciendo click en el icono del borde derecho del campo de fecha. 4686 4687step: presiono desde el teclado "{key}"
4688descripcion: Presiona una tecla especÃfica del teclado con mapeo de teclas especiales (Enter, Escape, flechas, etc.).`},{id:"steps-esperas",title:"Inventario: Esperas",content:`## Esperas 4689 4690step: espero a que el elemento "{element_name}" sea visible con identificador "{identifier}" 4691descripcion: Espera a que un elemento sea visible en la página antes de continuar. 4692 4693step: espero a que el elemento "{element_name}" esté oculto con identificador "{identifier}" 4694descripcion: Espera a que un elemento esté oculto o desaparezca de la vista. 4695 4696step: espero a que el elemento "{element_name}" esté habilitado con identificador "{identifier}" 4697descripcion: Espera a que un elemento esté habilitado (no disabled) para interactuar con él. 4698 4699step: espero a que el elemento "{element_name}" contenga el texto "{text}" con identificador "{identifier}" 4700descripcion: Espera a que un elemento contenga un texto especÃfico en su contenido. 4701 4702step: espero a que la url de la página contenga "{url_part}" 4703descripcion: Espera a que la URL actual del navegador contenga una parte especÃfica de texto. 4704 4705step: espero a que el tÃtulo de la página sea "{title}" 4706descripcion: Espera a que el tÃtulo de la página sea exactamente el texto especificado. 4707 4708step: espero a que la red esté inactiva 4709descripcion: Espera a que no haya peticiones de red activas (networkidle). 4710 4711step: espero a que el contenido del DOM esté cargado 4712descripcion: Espera a que el evento DOMContentLoaded se haya disparado. 4713 4714step: espero a que el elemento "{element_name}" sea clickeable con identificador "{identifier}" 4715descripcion: Espera a que un elemento sea visible, esté adjunto al DOM y no esté deshabilitado. 4716 4717step: espero a que el select "{element_name}" tenga opciones con identificador "{identifier}" 4718descripcion: Espera a que un select tenga opciones cargadas (al menos 2, asumiendo que la primera es placeholder). 4719 4720step: espero a que el select "{element_name}" tenga al menos {count:d} opciones con identificador "{identifier}" 4721descripcion: Espera a que un select tenga al menos N opciones cargadas. 4722 4723step: espero a que la tabla "{element_name}" tenga filas con identificador "{identifier}" 4724descripcion: Espera a que una tabla tenga al menos una fila de datos cargada en el tbody. 4725 4726step: espero a que la tabla "{element_name}" tenga al menos {count:d} filas con identificador "{identifier}" 4727descripcion: Espera a que una tabla tenga al menos N filas de datos. 4728 4729step: espero a que la lista "{element_name}" tenga elementos con identificador "{identifier}" 4730descripcion: Espera a que una lista (ul/ol) tenga al menos un elemento li cargado. 4731 4732step: espero a que el elemento "{element_name}" tenga elementos hijos con identificador "{identifier}" 4733descripcion: Espera a que un elemento tenga al menos un elemento hijo cargado. 4734 4735step: espero a que el elemento "{element_name}" tenga el atributo "{attribute}" en identificador "{identifier}" 4736descripcion: Espera a que un elemento tenga un atributo HTML especÃfico presente. 4737 4738step: espero a que el elemento "{element_name}" tenga el atributo "{attribute}" con valor "{value}" con identificador "{identifier}" 4739descripcion: Espera a que un atributo de un elemento tenga un valor especÃfico. 4740 4741step: espero a que el campo "{element_name}" tenga valor con identificador "{identifier}" 4742descripcion: Espera a que un campo de entrada tenga algún valor (no esté vacÃo). 4743 4744step: espero a que el campo "{element_name}" tenga el valor "{value}" con identificador "{identifier}" 4745descripcion: Espera a que un campo de entrada tenga un valor especÃfico. 4746 4747step: espero a que el elemento "{element_name}" tenga la clase "{css_class}" con identificador "{identifier}" 4748descripcion: Espera a que un elemento tenga una clase CSS especÃfica en su classList. 4749 4750step: espero a que el elemento "{element_name}" no tenga la clase "{css_class}" con identificador "{identifier}" 4751descripcion: Espera a que un elemento NO tenga una clase CSS especÃfica. Ãtil para esperar fin de loading. 4752 4753step: espero a que haya al menos {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}" 4754descripcion: Espera a que haya al menos N elementos que coincidan con el selector dado. 4755 4756step: espero a que haya exactamente {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}" 4757descripcion: Espera a que haya exactamente N elementos que coincidan con el selector. 4758 4759step: espero a que el elemento "{element_name}" no esté vacÃo con identificador "{identifier}" 4760descripcion: Espera a que un elemento tenga contenido de texto (textContent no vacÃo). 4761 4762step: espero a que el elemento "{element_name}" deje de cambiar con identificador "{identifier}" 4763descripcion: Espera a que el contenido de un elemento se estabilice (no cambie durante 500ms). Ãtil para contadores y loaders. 4764 4765step: espero a que el spinner de carga desaparezca con identificador "{identifier}" 4766descripcion: Espera a que un spinner/loader desaparezca de la vista. 4767 4768step: espero a que el elemento "{element_name}" sea removido del DOM con identificador "{identifier}" 4769descripcion: Espera a que un elemento sea completamente removido del DOM. 4770 4771step: espero {seconds:d} segundos 4772descripcion: Espera un número especÃfico de segundos. Usar solo cuando sea estrictamente necesario. 4773 4774step: espero {milliseconds:d} milisegundos 4775descripcion: Espera un número especÃfico de milisegundos.`}
4775,{id:"steps-esperas-avanzadas",title:"Inventario: Esperas Avanzadas y Tiempos",content:`## Esperas Avanzadas y Tiempos 4776 4777Esperas condicionales por selector, pausas, esperas aleatorias/progresivas y cronómetros. Prefiere estas esperas inteligentes por sobre \`espero N segundos\` fijo. 4778 4779### Pausas y esperas por tiempo 4780 4781step: pauso {seconds:d} segundos 4782descripcion: Pausa un número especÃfico de segundos (alternativa a espero). 4783 4784step: pauso {milliseconds:d} milisegundos 4785descripcion: Pausa un número especÃfico de milisegundos (alternativa a espero). 4786 4787step: espero aleatoriamente entre {min_seconds:d} y {max_seconds:d} segundos 4788descripcion: Espera un tiempo aleatorio entre dos valores (útil para simular comportamiento humano). 4789 4790step: espero progresivamente: {wait_pattern} 4791descripcion: Espera con un patrón progresivo de tiempos (ej: "1,2,3,5" segundos). 4792 4793step: establezco el timeout global en {timeout:d} segundos 4794descripcion: Establece el timeout global para las operaciones de espera. 4795 4796### Esperas condicionales por selector 4797 4798step: espero hasta que el elemento "{selector}" sea visible 4799descripcion: Espera hasta que un elemento sea visible. 4800 4801step: espero hasta que el elemento "{selector}" desaparezca 4802descripcion: Espera hasta que un elemento desaparezca del DOM o deje de ser visible. 4803 4804step: espero hasta que el elemento "{selector}" esté habilitado 4805descripcion: Espera hasta que un elemento esté habilitado (no disabled). 4806 4807step: espero hasta que el elemento "{selector}" contenga el texto "{expected_text}" 4808descripcion: Espera hasta que un elemento contenga un texto especÃfico. 4809 4810step: espero hasta que el elemento "{selector}" tenga el atributo "{attribute}" con valor "{expected_value}" 4811descripcion: Espera hasta que un elemento tenga un atributo con un valor especÃfico. 4812 4813step: espero hasta que el elemento "{selector}" no esté en estado de carga 4814descripcion: Espera hasta que un elemento salga de un estado de carga (spinner/busy). 4815 4816step: espero con timeout de {timeout:d} segundos hasta que "{selector}" sea visible 4817descripcion: Espera a que un elemento sea visible con un timeout personalizado. 4818 4819step: espero hasta que haya {count:d} elementos "{selector}" 4820descripcion: Espera hasta que haya un número especÃfico de elementos (con número literal). 4821 4822step: espero hasta que haya en total {count_text} elementos "{selector}" 4823descripcion: Espera hasta que haya un número especÃfico de elementos (soporta variables). 4824 4825### Esperas de página, red y URL 4826 4827step: espero hasta que la página termine de cargar 4828descripcion: Espera hasta que la página termine de cargar completamente. 4829 4830step: espero hasta que no haya requests de red pendientes 4831descripcion: Espera hasta que no haya actividad de red pendiente. 4832 4833step: espero hasta que la URL contenga "{url_part}" 4834descripcion: Espera hasta que la URL contenga una parte especÃfica. 4835 4836### Cronómetros 4837 4838step: marco el tiempo de inicio como "{timer_name}" 4839descripcion: Inicia un cronómetro con un nombre especÃfico. 4840 4841step: verifico que el cronómetro "{timer_name}" no exceda {max_seconds:d} segundos 4842descripcion: Verifica que un cronómetro no exceda un tiempo máximo. 4843 4844step: muestro el tiempo transcurrido del cronómetro "{timer_name}" 4845descripcion: Muestra el tiempo transcurrido de un cronómetro.`},{id:"steps-scroll",title:"Inventario: Scroll",content:`## Scroll 4846 4847step: hago scroll al elemento "{element_name}" con identificador "{identifier}" 4848descripcion: Hace scroll hasta que un elemento especÃfico sea visible en el viewport. 4849 4850step: hago scroll al inicio de la página 4851descripcion: Hace scroll hasta el inicio (top) de la página. 4852 4853step: hago scroll al final de la página 4854descripcion: Hace scroll hasta el final (bottom) de la página. 4855 4856step: hago scroll hacia abajo {pixels:d} pÃxeles 4857descripcion: Hace scroll hacia abajo un número especÃfico de pÃxeles. 4858 4859step: hago scroll hacia arriba {pixels:d} pÃxeles 4860descripcion: Hace scroll hacia arriba un número especÃfico de pÃxeles. 4861 4862step: hago scroll hacia la izquierda {pixels:d} pÃxeles 4863descripcion: Hace scroll horizontal hacia la izquierda un número especÃfico de pÃxeles. 4864 4865step: hago scroll hacia la derecha {pixels:d} pÃxeles 4866descripcion: Hace scroll horizontal hacia la derecha un número especÃfico de pÃxeles. 4867 4868step: hago scroll del elemento "{element_name}" hacia abajo {pixels:d} pÃxeles con identificador "{identifier}" 4869descripcion: Hace scroll hacia abajo dentro de un elemento con overflow (contenedor scrollable). 4870 4871step: hago scroll del elemento "{element_name}" hacia arriba {pixels:d} pÃxeles con identificador "{identifier}"
4872descripcion: Hace scroll hacia arriba dentro de un elemento con overflow (contenedor scrollable).`},{id:"steps-ventanas-frames",title:"Inventario: Ventanas y Frames",content:`## Ventanas y Frames 4873 4874step: cambio a la nueva ventana 4875descripcion: Cambia el contexto a la ventana/pestaña más reciente que se haya abierto. Espera hasta 30 segundos. 4876 4877step: cierro la ventana actual 4878descripcion: Cierra la ventana actual y cambia a la primera ventana disponible. 4879 4880step: cambio a la ventana con tÃtulo "{title}" 4881descripcion: Cambia a una ventana especÃfica buscando por tÃtulo (búsqueda parcial, case-insensitive). Espera hasta 30 segundos. 4882 4883step: cambio a la ventana con url que contiene "{url_part}" 4884descripcion: Cambia a una ventana cuya URL contenga el texto especificado. Espera hasta 30 segundos si no existe aún. 4885 4886step: acepto la alerta simple 4887descripcion: Acepta (OK) una alerta de JavaScript esperando a que aparezca. 4888 4889step: rechazo la alerta 4890descripcion: Rechaza (Cancel) una alerta de JavaScript esperando a que aparezca. 4891 4892step: acepto la alerta con texto "{text}" 4893descripcion: Acepta una alerta de tipo prompt enviando un texto especÃfico. 4894 4895step: obtengo el texto de la alerta y lo guardo en la variable "{variable_name}" 4896descripcion: Captura el mensaje de una alerta, lo guarda en una variable y acepta el diálogo. 4897 4898step: cambio al frame "{frame_name}" con identificador "{identifier}" 4899descripcion: Cambia el contexto de ejecución a un frame/iframe especÃfico. 4900 4901step: cambio al contenido principal 4902descripcion: Vuelve al contenido principal de la página, saliendo de cualquier iframe. 4903 4904step: salgo del frame 4905descripcion: Alias para volver al contenido principal, saliendo del iframe actual. 4906 4907step: tomo una captura de pantalla y la guardo como "{filename}" 4908descripcion: Toma una captura de pantalla de la página completa y la guarda con el nombre especificado. 4909 4910step: tomo una captura del elemento "{element_name}" y la guardo como "{filename}" con identificador "{identifier}" 4911descripcion: Toma una captura de pantalla de un elemento especÃfico. 4912 4913step: el mensaje de la alerta deberÃa ser "{expected_text}" 4914descripcion: Verifica que el mensaje de una alerta sea exactamente igual al texto esperado. 4915 4916step: el mensaje de la alerta deberÃa contener "{expected_text}" 4917descripcion: Verifica que el mensaje de una alerta contenga un texto parcial. 4918 4919step: guardo el mensaje de la alerta en la variable "{variable_name}" 4920descripcion: Guarda el mensaje de una alerta en una variable y acepta el diálogo. 4921 4922step: extraigo el texto del diálogo lo guardo en la variable "{variable_name}" y cierro el diálogo 4923descripcion: Captura el texto de un diálogo usando listener, lo guarda en variable y cierra el diálogo. Desactiva listeners anteriores.`},{id:"steps-iframes",title:"Inventario: iFrames",content:`## iFrames 4924 4925step: cambio al iframe "{iframe_name}" con identificador "{identifier}" 4926descripcion: Cambia el contexto al iframe especificado usando su identificador. Guarda referencia en el stack de frames. 4927 4928step: cambio al iframe por nombre "{name}" 4929descripcion: Cambia al iframe buscando por su atributo name. 4930 4931step: cambio al iframe por src que contiene "{src_part}" 4932descripcion: Cambia al iframe buscando por parte de su URL src. 4933 4934step: cambio al iframe por Ãndice "{index}" 4935descripcion: Cambia al iframe por su posición/Ãndice en la página (basado en 0). 4936 4937step: regreso al frame padre 4938descripcion: Regresa al frame padre en la jerarquÃa de iframes. 4939 4940step: hago click en el elemento "{element_name}" dentro del iframe con identificador "{identifier}" 4941descripcion: Hace click en un elemento dentro del iframe actualmente activo. 4942 4943step: relleno el campo "{field_name}" con "{text}" dentro del iframe con identificador "{identifier}" 4944descripcion: Rellena un campo de texto dentro del iframe actualmente activo. 4945 4946step: deberÃa ver texto "{text}" dentro del iframe 4947descripcion: Verifica que un texto sea visible dentro del iframe actual. 4948 4949step: deberÃa ver el elemento "{element_name}" dentro del iframe con identificador "{identifier}" 4950descripcion: Verifica que un elemento sea visible dentro del iframe actual. 4951 4952step: espero a que cargue el iframe "{iframe_name}" con identificador "{identifier}" 4953descripcion: Espera a que un iframe sea visible y termine de cargar. 4954 4955step: ejecuto javascript "{script}" dentro del iframe 4956descripcion: Ejecuta código JavaScript dentro del contexto del iframe actual. 4957 4958step: obtengo el número de iframes y lo guardo en la variable "{variable_name}" 4959descripcion: Cuenta el número total de iframes en la página y guarda el resultado en una variable. 4960 4961step: verifico que existe el iframe "{iframe_name}" con identificador "{identifier}" 4962descripcion: Verifica que un iframe existe y es visible en la página. 4963 4964step: verifico que el iframe "{iframe_name}" tiene src "{expected_src}" con identificador "{identifier}" 4965descripcion: Verifica que un iframe tiene una URL src especÃfica.`},{id:"steps-teclado-mouse",title:"Inventario: Teclado y Mouse",content:`## Teclado y Mouse 4966 4967step: pulso la tecla "{key}"
4968descripcion: Presiona una tecla especÃfica del teclado. 4969 4970step: presiono la combinación de teclas "{keys}" 4971descripcion: Presiona una combinación de teclas (ej: Ctrl+C, Alt+Tab) manteniendo los modificadores. 4972 4973step: escribo el texto "{text}" con retraso de "{delay}" ms entre caracteres 4974descripcion: Escribe texto carácter por carácter con un retraso especÃfico entre cada uno. 4975 4976step: mantengo presionada la tecla "{key}" por "{duration}" segundos 4977descripcion: Mantiene presionada una tecla por un tiempo especÃfico y luego la suelta. 4978 4979step: hago click en las coordenadas x="{x}" y="{y}" 4980descripcion: Hace click en coordenadas especÃficas de la página. 4981 4982step: hago doble click en las coordenadas x="{x}" y="{y}" 4983descripcion: Hace doble click en coordenadas especÃficas de la página. 4984 4985step: hago click derecho en las coordenadas x="{x}" y="{y}" 4986descripcion: Hace click derecho en coordenadas especÃficas de la página. 4987 4988step: muevo el mouse a las coordenadas x="{x}" y="{y}" 4989descripcion: Mueve el cursor del mouse a coordenadas especÃficas sin hacer click. 4990 4991step: hago scroll con la rueda del mouse "{direction}" por "{steps}" pasos 4992descripcion: Hace scroll usando la rueda del mouse en dirección up o down por N pasos. 4993 4994step: realizo gesto de mouse desde x="{start_x}" y="{start_y}" hasta x="{end_x}" y="{end_y}" 4995descripcion: Realiza un gesto de arrastre con el mouse desde un punto hasta otro (mousedown, move, mouseup). 4996 4997step: simulo el atajo de teclado "{shortcut}" en el elemento "{element_name}" con identificador "{identifier}" 4998descripcion: Simula un atajo de teclado en un elemento especÃfico, enfocándolo primero. 4999 5000step: selecciono todo el texto con Ctrl+A 5001descripcion: Selecciona todo el texto de la página o del elemento enfocado. 5002 5003step: copio el texto seleccionado con Ctrl+C 5004descripcion: Copia el texto actualmente seleccionado al portapapeles. 5005 5006step: pego el texto con Ctrl+V 5007descripcion: Pega el contenido del portapapeles en el elemento enfocado. 5008 5009step: corto el texto con Ctrl+X 5010descripcion: Corta el texto seleccionado (lo copia y elimina). 5011 5012step: deshago la acción con Ctrl+Z 5013descripcion: Deshace la última acción realizada. 5014 5015step: rehago la acción con Ctrl+Y 5016descripcion: Rehace la última acción deshecha. 5017 5018step: navego con la tecla Tab "{times}" veces 5019descripcion: Navega entre elementos usando la tecla Tab un número especÃfico de veces. 5020 5021step: navego con Shift+Tab "{times}" veces 5022descripcion: Navega hacia atrás entre elementos usando Shift+Tab. 5023 5024step: pulso la tecla Enter 5025descripcion: Presiona la tecla Enter. 5026 5027step: presiono la tecla Escape 5028descripcion: Presiona la tecla Escape. 5029 5030step: presiono la tecla Espacio 5031descripcion: Presiona la tecla Espacio. 5032 5033step: presiono la tecla de flecha "{direction}" 5034descripcion: Presiona una tecla de flecha especÃfica (up, down, left, right o arriba, abajo, izquierda, derecha). 5035 5036step: escribo el texto "{text}" y presiono Enter 5037descripcion: Escribe texto y presiona Enter inmediatamente después. 5038 5039step: limpio el campo actual con Ctrl+A y Delete 5040descripcion: Limpia el campo actualmente enfocado seleccionando todo y borrando. 5041 5042step: simulo escritura humana con el texto "{text}" y retrasos aleatorios 5043descripcion: Simula escritura humana con retrasos aleatorios entre 50-200ms entre caracteres. 5044 5045step: incremento el campo numérico "{field_name}" "{times}" veces con identificador "{identifier}" 5046descripcion: Incrementa el valor de un campo numérico presionando ArrowUp N veces. 5047 5048step: decremento el campo numérico "{field_name}" "{times}" veces con identificador "{identifier}" 5049descripcion: Decrementa el valor de un campo numérico presionando ArrowDown N veces.`},{id:"steps-drag-drop",title:"Inventario: Drag and Drop",content:`## Drag and Drop 5050 5051step: arrastro el elemento "{source_element}" al elemento "{target_element}" con identificadores "{source_id}" y "{target_id}" 5052descripcion: Arrastra un elemento y lo suelta en otro usando movimiento de mouse manual con pausas. 5053 5054step: arrastro el elemento "{element_name}" por desplazamiento x="{x}" y="{y}" con identificador "{identifier}" 5055descripcion: Arrastra un elemento por un desplazamiento relativo en pÃxeles desde su posición actual. 5056 5057step: arrastro el elemento "{element_name}" a las coordenadas x="{x}" y="{y}" con identificador "{identifier}" 5058descripcion: Arrastra un elemento a coordenadas absolutas especÃficas en la página. 5059 5060step: empiezo a arrastrar el elemento "{element_name}" con identificador "{identifier}" 5061descripcion: Inicia el arrastre de un elemento (mousedown) para operaciones de drag complejas en múltiples pasos. 5062 5063step: muevo el elemento arrastrado a las coordenadas x="{x}" y="{y}" 5064descripcion: Mueve un elemento que está siendo arrastrado a nuevas coordenadas. 5065 5066step: suelto el elemento arrastrado 5067descripcion: Suelta el elemento que está siendo arrastrado (mouseup). 5068 5069step: paso el mouse sobre el elemento antes de arrastrar "{element_name}" con identificador "{identifier}" 5070descripcion: Pasa el mouse sobre un elemento antes de arrastrarlo. Ãtil para elementos que requieren hover previo. 5071 5072step: arrastro lentamente el elemento "{element_name}" al elemento "{target_element}" con identificadores "{source_id}" y "{target_id}" 5073descripcion: Drag and drop con movimiento lento en 20 pasos intermedios. Ãtil para elementos sensibles al movimiento. 5074 5075step: verifico que el drag and drop fue exitoso comprobando la posición del elemento "{element_name}" con identificador "{identifier}" 5076descripcion: Verifica que un drag and drop fue exitoso comprobando que el elemento tiene una posición válida. 5077 5078step: verifico que el elemento "{element_name}" está en la posición x="{x}" y="{y}" con identificador "{identifier}" 5079descripcion: Verifica que un elemento está en una posición especÃfica con tolerancia de 10 pÃxeles. 5080 5081step: arrastro y suelto el archivo "{file_path}" al elemento "{element_name}" con identificador "{identifier}" 5082descripcion: Arrastra y suelta un archivo en un elemento para uploads (usa set_input_files). 5083 5084step: arrastro el elemento "{source_element}" al elemento "{target_element}" usando API nativa con identificadores "{source_id}" y "{target_id}" 5085descripcion: Arrastra un elemento usando la API nativa drag_to de Playwright con fallback a método manual. 5086 5087step: realizo drag and drop avanzado desde "{source_element}" hasta "{target_element}" con identificadores "{source_id}" y "{target_id}" 5088descripcion: Drag and drop avanzado con múltiples métodos de fallback (API nativa, manual, HTML5). 5089 5090step: simulo drag and drop con HTML5 desde "{source_element}" hasta "{target_element}" con identificadores "{source_id}" y "{target_id}" 5091descripcion: Simula drag and drop HTML5 usando JavaScript con soporte para CSS, XPath e identificadores del framework.`},{id:"steps-formularios",title:"Inventario: Formularios",content:`## Formularios 5092 5093step: envÃo el formulario "{form_name}" con identificador "{identifier}" 5094descripcion: EnvÃa un formulario ejecutando form.submit() vÃa JavaScript. 5095 5096step: reseteo el formulario "{form_name}" con identificador "{identifier}"
5097descripcion: Resetea un formulario a sus valores por defecto usando form.reset(). 5098 5099step: relleno el formulario con datos de la variable "{data_variable}" para formulario "{form_name}" con identificador "{identifier}" 5100descripcion: Rellena un formulario completo con datos de una variable JSON, detectando automáticamente el tipo de cada campo. 5101 5102step: obtengo los datos del formulario y los guardo en la variable "{variable_name}" para formulario "{form_name}" con identificador "{identifier}" 5103descripcion: Extrae todos los datos de un formulario usando FormData y los guarda como JSON en una variable. 5104 5105step: valido el formulario "{form_name}" con identificador "{identifier}" 5106descripcion: Valida un formulario usando la validación HTML5 nativa (checkValidity). 5107 5108step: verifico los campos requeridos en el formulario "{form_name}" con identificador "{identifier}" 5109descripcion: Verifica que todos los campos marcados como required estén completados. 5110 5111step: establezco el campo "{field_name}" como solo lectura en formulario "{form_name}" con identificador de formulario "{form_id}" y identificador de campo "{field_id}" 5112descripcion: Establece un campo como solo lectura (readOnly = true). 5113 5114step: habilito el campo "{field_name}" en formulario "{form_name}" con identificador de formulario "{form_id}" y identificador de campo "{field_id}" 5115descripcion: Habilita un campo de formulario removiendo disabled y readOnly. 5116 5117step: deshabilito el campo "{field_name}" en formulario "{form_name}" con identificador de formulario "{form_id}" y identificador de campo "{field_id}" 5118descripcion: Deshabilita un campo de formulario (disabled = true). 5119 5120step: auto-relleno el formulario "{form_name}" con datos de prueba usando identificador "{identifier}" 5121descripcion: Auto-rellena un formulario con datos de prueba comunes (email, nombre, teléfono, dirección, etc.). 5122 5123step: limpio todos los campos del formulario "{form_name}" con identificador "{identifier}" 5124descripcion: Limpia todos los campos de un formulario (inputs, selects, textareas, checkboxes, radios).`},{id:"steps-navegador",title:"Inventario: Control del Navegador",content:`## Control del Navegador 5125 5126step: establezco la cookie "{name}" con valor "{value}" 5127descripcion: Establece una cookie especÃfica en el contexto del navegador. 5128 5129step: obtengo la cookie "{name}" y la guardo en la variable "{variable_name}" 5130descripcion: Obtiene el valor de una cookie y lo guarda en una variable. 5131 5132step: elimino la cookie "{name}" 5133descripcion: Elimina una cookie especÃfica del navegador. 5134 5135step: limpio todas las cookies 5136descripcion: Elimina todas las cookies del contexto del navegador. 5137 5138step: establezco el item de localStorage "{key}" con valor "{value}" 5139descripcion: Establece un item en el localStorage del navegador. 5140 5141step: obtengo el item de localStorage "{key}" y lo guardo en la variable "{variable_name}" 5142descripcion: Obtiene un item del localStorage y lo guarda en una variable. 5143 5144step: elimino el item de localStorage "{key}" 5145descripcion: Elimina un item especÃfico del localStorage. 5146 5147step: limpio el localStorage 5148descripcion: Limpia completamente el localStorage del navegador. 5149 5150step: establezco el item de sessionStorage "{key}" con valor "{value}" 5151descripcion: Establece un item en el sessionStorage del navegador. 5152 5153step: obtengo el item de sessionStorage "{key}" y lo guardo en la variable "{variable_name}" 5154descripcion: Obtiene un item del sessionStorage y lo guarda en una variable. 5155 5156step: limpio el sessionStorage 5157descripcion: Limpia completamente el sessionStorage del navegador. 5158 5159step: ejecuto JavaScript "{script}" y guardo el resultado en la variable "{variable_name}" 5160descripcion: Ejecuta JavaScript personalizado en la página y guarda el resultado en una variable. 5161 5162step: ejecuto el siguiente JavaScript y guardo el resultado en la variable "{variable_name}" 5163descripcion: Ejecuta JavaScript multilÃnea (desde context.text) y guarda el resultado. Envuelve automáticamente en función si contiene return. 5164 5165step: establezco el viewport del navegador a "{width}x{height}" 5166descripcion: Establece el tamaño del viewport del navegador a dimensiones especÃficas. 5167 5168step: habilito JavaScript 5169descripcion: Paso informativo que indica que JavaScript está habilitado (por defecto en Playwright). 5170 5171step: deshabilito JavaScript 5172descripcion: Paso informativo sobre deshabilitar JavaScript (requiere reiniciar contexto). 5173 5174step: establezco el user agent a "{user_agent}" 5175descripcion: Establece un user agent personalizado para las peticiones HTTP. 5176 5177step: obtengo el user agent actual y lo guardo en la variable "{variable_name}" 5178descripcion: Obtiene el user agent actual del navegador y lo guarda en una variable. 5179 5180step: simulo la condición de red "{condition}" 5181descripcion: Simula condiciones de red como slow_3g, fast_3g u offline. 5182 5183step: limpio la caché del navegador 5184descripcion: Limpia la caché del navegador usando la API de caches. 5185 5186step: bloqueo el tipo de recurso "{resource_type}" 5187descripcion: Bloquea un tipo especÃfico de recurso (images, scripts, stylesheets, etc.) interceptando las peticiones. 5188 5189step: desbloqueo todos los recursos 5190descripcion: Desbloquea todos los recursos previamente bloqueados. 5191 5192step: desactivo el navegador para esta prueba 5193descripcion: Desactiva el navegador para pruebas que no lo necesitan (API, validación semántica). Evita screenshots innecesarios. 5194 5195step: no necesito navegador para esta prueba 5196descripcion: Alias para desactivar el navegador en pruebas que no requieren UI. 5197 5198step: reactivo el navegador 5199descripcion: Reactiva el navegador después de haberlo desactivado. 5200 5201step: necesito el navegador ahora 5202descripcion: Alias para reactivar el navegador cuando se necesita nuevamente.`},{id:"steps-modales",title:"Inventario: Modales",content:`## Modales 5203 5204step: espero a que aparezca el modal "{modal_name}" con identificador "{identifier}" 5205descripcion: Espera hasta 10 segundos a que un modal sea visible en la página. 5206 5207step: espero a que desaparezca el modal "{modal_name}" con identificador "{identifier}" 5208descripcion: Espera hasta 10 segundos a que un modal desaparezca de la vista. 5209 5210step: cierro el modal "{modal_name}" haciendo click en el botón cerrar con identificador "{identifier}" 5211descripcion: Cierra un modal haciendo click en su botón de cerrar. 5212 5213step: cierro el modal presionando la tecla Escape 5214descripcion: Cierra un modal presionando la tecla Escape. 5215 5216step: cierro el modal haciendo click fuera 5217descripcion: Cierra un modal haciendo click fuera del contenido (en la esquina superior izquierda). 5218 5219step: verifico que el modal "{modal_name}" es visible con identificador "{identifier}" 5220descripcion: Verifica que un modal es actualmente visible en la página. 5221 5222step: verifico que el modal "{modal_name}" no es visible con identificador "{identifier}" 5223descripcion: Verifica que un modal no es visible en la página. 5224 5225step: verifico que el modal "{modal_name}" tiene el tÃtulo "{expected_title}" con identificador "{identifier}" 5226descripcion: Verifica que un modal tiene un tÃtulo especÃfico buscando en selectores comunes de tÃtulo. 5227 5228step: hago click en el botón "{button_text}" del modal "{modal_name}" con identificador de modal "{modal_id}" 5229descripcion: Hace click en un botón especÃfico dentro de un modal buscando por texto. 5230 5231step: relleno el campo "{field_name}" con "{text}" en el modal "{modal_name}" con identificadores modal="{modal_id}" campo="{field_id}" 5232descripcion: Rellena un campo de texto dentro de un modal especÃfico. 5233 5234step: verifico que el modal "{modal_name}" contiene el texto "{text}" con identificador "{identifier}" 5235descripcion: Verifica que un modal contiene un texto especÃfico visible. 5236 5237step: manejo la alerta del navegador con acción "{action}" 5238descripcion: Step deprecado. Usar 'acepto la alerta' o 'rechazo la alerta' en su lugar. 5239 5240step: manejo la confirmación del navegador con acción "{action}" 5241descripcion: Step deprecado. Usar 'acepto la alerta' o 'rechazo la alerta' en su lugar. 5242 5243step: manejo el prompt del navegador con texto "{text}" y acción "{action}" 5244descripcion: Step deprecado. Usar 'obtengo el texto de la alerta' en su lugar. 5245 5246step: espero a que aparezca cualquier modal 5247descripcion: Espera a que aparezca cualquier modal en la página buscando selectores comunes (.modal, .dialog, [role="dialog"], etc.). 5248 5249step: verifico que no hay modales visibles 5250descripcion: Verifica que no hay ningún modal visible en la página. 5251 5252step: tomo captura del modal "{modal_name}" con identificador "{identifier}" 5253descripcion: Toma una captura de pantalla especÃfica del modal y la guarda con timestamp. 5254 5255step: desactivo el manejo automático de diálogos 5256descripcion: Desactiva el manejo automático de diálogos/alertas removiendo todos los listeners. 5257 5258step: evito que se cierren automáticamente los diálogos 5259descripcion: Configura un listener que captura el mensaje del diálogo y lo acepta automáticamente. Debe ejecutarse ANTES de la acción que dispara el diálogo. 5260 5261step: obtengo el mensaje del diálogo guardado 5262descripcion: Obtiene el mensaje del diálogo que fue capturado por el listener previo. 5263 5264step: el mensaje del diálogo capturado deberÃa contener "{expected_text}" 5265descripcion: Verifica que el mensaje capturado del diálogo contiene un texto parcial. 5266 5267step: el mensaje del diálogo capturado deberÃa ser "{expected_text}" 5268descripcion: Verifica que el mensaje capturado del diálogo es exactamente igual al texto esperado. 5269 5270step: guardo el mensaje del diálogo capturado en la variable "{variable_name}" 5271descripcion: Guarda el mensaje capturado del diálogo en una variable del framework.`},{id:"steps-combobox",title:"Inventario: Combobox",content:`## Combobox 5272 5273step: selecciono la opción "{option}
5273" del combobox "{element_name}" con identificador "{identifier}" 5274descripcion: Selecciona una opción de un combobox simulando interacción humana completa con todos los eventos (focus, click, change, blur, Angular events). 5275 5276step: selecciono la opción "{option}" del select "{element_name}" con identificador "{identifier}" 5277descripcion: Selecciona una opción de un elemento select HTML nativo con eventos completos para compatibilidad con Angular y otros frameworks SPA. 5278 5279step: selecciono la opción por valor "{value}" del combobox "{element_name}" con identificador "{identifier}" 5280descripcion: Selecciona una opción de un combobox/select por su atributo value. 5281 5282step: selecciono la opción por Ãndice "{index}" del combobox "{element_name}" con identificador "{identifier}" 5283descripcion: Selecciona una opción de un combobox/select por su posición numérica. 5284 5285step: abro el dropdown "{element_name}" con identificador "{identifier}" 5286descripcion: Abre un dropdown personalizado haciendo click y esperando que aparezcan las opciones. 5287 5288step: selecciono la opción "{option}" del dropdown abierto 5289descripcion: Selecciona una opción de un dropdown que ya está abierto, buscando por diferentes selectores. 5290 5291step: escribo y selecciono "{text}" en el combobox buscable "{element_name}" con identificador "{identifier}" 5292descripcion: Escribe en un combobox buscable/autocomplete y selecciona la opción que coincida. 5293 5294step: limpio la selección del combobox "{element_name}" con identificador "{identifier}" 5295descripcion: Limpia la selección actual de un combobox usando múltiples métodos de fallback. 5296 5297step: verifico que el combobox "{element_name}" tiene seleccionada la opción "{option}" con identificador "{identifier}" 5298descripcion: Verifica que un combobox tiene una opción especÃfica actualmente seleccionada. 5299 5300step: verifico que el combobox "{element_name}" contiene las opciones "{options}" con identificador "{identifier}" 5301descripcion: Verifica que un combobox contiene todas las opciones especificadas (separadas por coma). 5302 5303step: selecciono múltiples opciones "{options}" del multiselect "{element_name}" con identificador "{identifier}" 5304descripcion: Selecciona múltiples opciones de un select múltiple (opciones separadas por coma). 5305 5306step: navego las opciones del combobox con flechas y selecciono la opción "{option}" de "{element_name}" con identificador "{identifier}" 5307descripcion: Navega por las opciones de un combobox usando teclas de flecha hasta encontrar y seleccionar la opción deseada. 5308 5309step: verifico que el combobox "{element_name}" tiene la opción "{option}" con identificador "{identifier}" 5310descripcion: Verifica que una opción especÃfica existe en el DOM del combobox sin abrirlo. Soporta variables en el identificador. 5311 5312## Validaciones de Combobox 5313 5314step: verifico que el combobox "{element_name}" contiene exactamente "{expected_options}" opciones con identificador "{identifier}" 5315descripcion: Verifica que un combobox contiene exactamente las opciones especificadas (separadas por coma), sin más ni menos. 5316 5317step: verifico que el combobox "{element_name}" tiene "{expected_count}" opciones con identificador "{identifier}" 5318descripcion: Verifica que un combobox tiene un número especÃfico de opciones no vacÃas. 5319 5320step: verifico que la primera opción del combobox "{element_name}" es "{expected_option}" con identificador "{identifier}" 5321descripcion: Verifica que la primera opción de un combobox es un texto especÃfico. 5322 5323step: verifico que la última opción del combobox "{element_name}" es "{expected_option}" con identificador "{identifier}" 5324descripcion: Verifica que la última opción de un combobox es un texto especÃfico. 5325 5326step: verifico que las opciones del combobox "{element_name}" están ordenadas alfabéticamente con identificador "{identifier}" 5327descripcion: Verifica que las opciones de un combobox están en orden alfabético. 5328 5329step: verifico que el combobox "{element_name}" no tiene opciones duplicadas con identificador "{identifier}" 5330descripcion: Verifica que un combobox no tiene opciones repetidas. 5331 5332step: verifico que el combobox "{element_name}" contiene la opción "{expected_option}" con identificador "{identifier}" 5333descripcion: Verifica que un combobox contiene una opción especÃfica entre sus opciones dis
5333ponibles. 5334 5335step: verifico que el combobox "{element_name}" no contiene la opción "{unexpected_option}" con identificador "{identifier}" 5336descripcion: Verifica que un combobox NO contiene una opción especÃfica. 5337 5338step: verifico que la selección por defecto del combobox "{element_name}" es "{expected_selection}" con identificador "{identifier}" 5339descripcion: Verifica que la selección por defecto (opción marcada como selected) es un texto especÃfico. 5340 5341step: verifico que el combobox "{element_name}" permite selección múltiple con identificador "{identifier}" 5342descripcion: Verifica que un combobox tiene el atributo multiple habilitado. 5343 5344step: verifico que el combobox "{element_name}" no permite selección múltiple con identificador "{identifier}" 5345descripcion: Verifica que un combobox NO tiene el atributo multiple. 5346 5347step: verifico que el combobox "{element_name}" es campo requerido con identificador "{identifier}" 5348descripcion: Verifica que un combobox tiene el atributo required. 5349 5350step: verifico que el placeholder del combobox "{element_name}" es "{expected_placeholder}" con identificador "{identifier}" 5351descripcion: Verifica que un combobox tiene un placeholder especÃfico (atributo o primera opción vacÃa). 5352 5353step: verifico que las opciones del combobox "{element_name}" contienen los valores "{expected_values}" con identificador "{identifier}" 5354descripcion: Verifica que las opciones de un combobox tienen atributos value especÃficos (separados por coma). 5355 5356step: verifico que el combobox "{element_name}" se puede filtrar escribiendo "{filter_text}" con identificador "{identifier}" 5357descripcion: Verifica que un combobox se puede filtrar escribiendo texto y que reduce el número de opciones visibles.`},{id:"steps-inputs-avanzados",title:"Inventario: Inputs Avanzados",content:`## Inputs Avanzados 5358 5359step: escribo gradualmente "{text}" en "{selector}" con {delay:d}ms entre caracteres 5360descripcion: Escribe texto gradualmente, carácter por carácter, con un delay especÃfico en milisegundos. 5361 5362step: escribo naturalmente "{text}" en "{selector}" 5363descripcion: Escribe texto simulando escritura humana con delays aleatorios entre 50-200ms. 5364 5365step: limpio completamente el campo "{selector}" 5366descripcion: Limpia completamente un campo usando múltiples métodos (clear, Ctrl+A+Delete, Backspace). 5367 5368step: selecciono todo el texto en "{selector}" y lo borro 5369descripcion: Selecciona todo el texto de un campo y lo borra con Delete. 5370 5371step: borro {num_chars:d} caracteres del final en "{selector}" 5372descripcion: Borra un número especÃfico de caracteres del final de un campo usando Backspace. 5373 5374step: reemplazo el texto en "{selector}" con "{new_text}" 5375descripcion: Reemplaza completamente el texto de un campo seleccionando todo y escribiendo el nuevo texto. 5376 5377step: agrego "{additional_text}" al final del texto en "{selector}" 5378descripcion: Agrega texto al final del contenido existente de un campo sin borrar lo anterior. 5379 5380step: inserto "{text}" al inicio del campo "{selector}" 5381descripcion: Inserta texto al inicio del contenido existente de un campo. 5382 5383step: tecleo "{key}" en el campo "{selector}" 5384descripcion: Presiona una tecla especÃfica en un elemento después de enfocarlo. 5385 5386step: tecleo combinación "{key_combination}" en el campo "{selector}" 5387descripcion: Presiona una combinación de teclas en un elemento especÃfico. 5388 5389step: enfoco el campo "{selector}" 5390descripcion: Enfoca un campo especÃfico usando focus(). 5391 5392step: desenfocar el campo actual 5393descripcion: Quita el foco del campo actual presionando Tab. 5394 5395step: copio el contenido del campo "{selector}" al portapapeles 5396descripcion: Selecciona todo el contenido de un campo y lo copia al portapapeles con Ctrl+C. 5397 5398step: pego el contenido del portapapeles en "{selector}" 5399descripcion: Pega el contenido del portapapeles en un campo con Ctrl+V. 5400 5401step: escribo avanzado "{text}" y presiono Enter en "{selector}" 5402descripcion: Escribe texto en un campo usando fill() y presiona Enter inmediatamente. 5403 5404step: selecciono el texto desde la posición {start:d} hasta {end:d} en "{selector}" 5405descripcion: Selecciona un rango especÃfico de texto en un campo usando setSelectionRange. 5406 5407step: escribo con velocidad "{speed_type}" el texto "{text}" en "{selector}" 5408descripcion: Escribe texto con velocidades predefinidas (muy_lenta, lenta, normal, ra
5408pida, muy_rapida). 5409 5410step: simulo errores de escritura con texto "{text}" en "{selector}" 5411descripcion: Simula errores de escritura humanos con 15% de probabilidad de error, corrección automática y delays variables. 5412 5413step: verifico que puedo escribir en el campo "{selector}" 5414descripcion: Verifica que un campo está habilitado y es editable (acepta entrada de texto). 5415 5416step: limpio el campo "{selector}" usando {method} 5417descripcion: Limpia un campo usando un método especÃfico (clear, select_all, backspace, delete). 5418 5419step: escribo texto multilÃnea en "{selector}" 5420descripcion: Escribe texto multilÃnea desde context.text (bloque de texto del feature) en un campo.`},{id:"steps-responsive",title:"Inventario: Responsive",content:`## Responsive 5421 5422step: establezco el viewport a tamaño móvil "{width}x{height}" 5423descripcion: Establece el viewport a un tamaño móvil especÃfico en pÃxeles. 5424 5425step: establezco el viewport a tamaño tablet "{width}x{height}" 5426descripcion: Establece el viewport a un tamaño tablet especÃfico en pÃxeles. 5427 5428step: establezco el viewport a tamaño desktop "{width}x{height}" 5429descripcion: Establece el viewport a un tamaño desktop especÃfico en pÃxeles. 5430 5431step: verifico que el elemento "{element_name}" es visible en móvil con identificador "{identifier}" 5432descripcion: Verifica que un elemento es visible en viewport móvil (375x667 - iPhone SE). 5433 5434step: verifico que el elemento "{element_name}" está oculto en móvil con identificador "{identifier}" 5435descripcion: Verifica que un elemento está oculto en viewport móvil (375x667). 5436 5437step: verifico que el elemento "{element_name}" se adapta a cambios de viewport con identificador "{identifier}" 5438descripcion: Verifica que un elemento cambia de tamaño o posición entre diferentes viewports (móvil, tablet, desktop). 5439 5440step: verifico que el menú de navegación se colapsa en móvil 5441descripcion: Verifica que el menú de navegación se colapsa en dispositivos móviles buscando elementos hamburger/toggle. 5442 5443step: verifico que el texto es legible en tamaño móvil 5444descripcion: Verifica que los textos tienen un tamaño de fuente mÃnimo de 14px en viewport móvil. 5445 5446step: verifico que los botones son amigables al tacto en móvil 5447descripcion: Verifica que los elementos clickeables tienen un tamaño mÃnimo de 44px para dispositivos táctiles. 5448 5449step: verifico que no hay scroll horizontal 5450descripcion: Verifica que el ancho de la página no excede el ancho del viewport (sin scroll horizontal). 5451 5452step: verifico que las imágenes se escalan apropiadamente en móvil 5453descripcion: Verifica que las imágenes no son más anchas que el viewport en dispositivos móviles. 5454 5455step: verifico que el elemento "{element_name}" se apila verticalmente en móvil con identificador "{identifier}" 5456descripcion: Verifica que elementos que están en fila en desktop se apilan verticalmente en móvil. 5457 5458step: verifico el comportamiento del breakpoint en "{width}" pÃxeles 5459descripcion: Verifica que hay cambios de layout al cruzar un breakpoint especÃfico. 5460 5461step: verifico que el elemento "{element_name}" tiene tamaño de fuente responsive con identificador "{identifier}" 5462descripcion: Verifica que un elemento tiene tamaño de fuente que se adapta entre viewport móvil y desktop.`},{id:"steps-tablas",title:"Inventario: Tablas",content:`## Tablas 5463 5464step: verifico que la tabla "{table_name}" tiene "{expected_rows}" filas con identificador "{identifier}" 5465descripcion: Verifica que una tabla tiene un número especÃfico de filas en el tbody. Soporta variables con \${variable_name}. 5466 5467step: verifico que la tabla "{table_name}" tiene "{expected_columns}" columnas con identificador "{identifier}" 5468descripcion: Verifica que una tabla tiene un número especÃfico de columnas en el header. 5469 5470step: hago click en la celda de la fila "{row}" columna "{column}" de la tabla "{table_name}" con identificador "{identifier}" 5471descripcion: Hace click en una celda especÃfica de la tabla por Ãndice de fila y columna (basados en 1). 5472 5473step: verifico que la celda de la fila "{row}" columna "{column}" contiene "{expected_text}" en la tabla "{table_name}" con identificador "{identifier}" 5474descripcion: Verifica que una celda especÃfica contiene un texto esperado. 5475 5476step: ordeno la tabla "{table_name}" por la columna "{column_name}" con identificador "{identifier}" 5477descripcion: Ordena una tabla haciendo click en el header de una columna especÃfica. 5478 5479step: filtro la tabla "{table_name}" por la columna "{column_name}" con valor "{filter_value}" con identificador "{identifier}" 5480descripcion: Filtra una tabla escribiendo un valor en el campo de filtro de una columna. 5481 5482step: selecciono la fila "{row_number}" en la tabla "{table_name}" con identificador "{identifier}" 5483descripcion: Selecciona una fila de la tabla haciendo click en su checkbox, radio o la fila completa. 5484 5485step: verifico que la fila "{row_number}" de la tabla "{table_name}
5485" está seleccionada con identificador "{identifier}" 5486descripcion: Verifica que una fila especÃfica está seleccionada (checkbox checked, clase selected/active). 5487 5488step: obtengo el valor de la celda fila "{row}" columna "{column}" y lo guardo en la variable "{variable_name}" de la tabla "{table_name}" con identificador "{identifier}" 5489descripcion: Obtiene el texto de una celda especÃfica y lo guarda en una variable. 5490 5491step: verifico que la fila "{row_number}" de la tabla "{table_name}" tiene los siguientes datos con identificador "{identifier}" 5492descripcion: Verifica que una fila completa tiene los datos esperados usando una tabla Gherkin con columna "datos". 5493 5494step: verifico que el header de la tabla "{table_name}" tiene las siguientes columnas con identificador "{identifier}" 5495descripcion: Verifica que el header de la tabla tiene los nombres de columnas esperados usando una tabla Gherkin con columna "columnas". 5496 5497step: verifico que la fila "{row_number}" de la tabla "{table_name}" tiene datos con formato con identificador "{identifier}" 5498descripcion: Verifica que una fila tiene datos que coinciden con formatos especÃficos (numero, string, fecha, email, url, button, a, vacio, no_vacio, cualquiera). Soporta múltiples formatos con separador /. 5499 5500step: guardo en la variable "{variable_name}" el valor de la columna "{column}" de la fila "{row}" en la tabla con identificador "{identifier}" 5501descripcion: Guarda el valor de una celda en una variable. Soporta XPath y CSS para el identificador. 5502 5503step: edito la celda de la fila "{row}" columna "{column}" con valor "{new_value}" en la tabla "{table_name}" con identificador "{identifier}" 5504descripcion: Edita el valor de una celda haciendo doble click y escribiendo en el campo de edición. 5505 5506step: exporto los datos de la tabla "{table_name}" y los guardo en la variable "{variable_name}" con identificador "{identifier}" 5507descripcion: Exporta todos los datos de la tabla como lista de diccionarios (headers como keys) y los guarda en una variable.`},{id:"steps-elementos-web",title:"Inventario: Elementos Web",content:`## Elementos Web 5508 5509step: establezco el atributo "{attribute}" con valor "{value}" en el elemento "{element_name}" con identificador "{identifier}" 5510descripcion: Establece un atributo especÃfico en un elemento usando JavaScript setAttribute. 5511 5512step: elimino el atributo "{attribute}" del elemento "{element_name}" con identificador "{identifier}" 5513descripcion: Elimina un atributo especÃfico de un elemento usando JavaScript removeAttribute. 5514 5515step: establezco el estilo CSS "{property}" con valor "{value}" en el elemento "{element_name}" con identificador "{identifier}" 5516descripcion: Establece una propiedad CSS inline en un elemento. 5517 5518step: disparo el evento "{event}" en el elemento "{element_name}" con identificador "{identifier}" 5519descripcion: Dispara un evento especÃfico (input, change, blur, etc.) en un elemento con bubbling. 5520 5521step: enfoco el elemento "{element_name}" con identificador "{identifier}" 5522descripcion: Enfoca un elemento especÃfico usando focus(). 5523 5524step: desenfocar el elemento "{element_name}" con identificador "{identifier}" 5525descripcion: Desenfoca un elemento especÃfico usando blur(). 5526 5527step: selecciono el texto del elemento "{element_name}" con identificador "{identifier}" 5528descripcion: Selecciona todo el texto dentro de un elemento usando selectText(). 5529 5530step: limpio la selección en la página 5531descripcion: Limpia cualquier selección de texto activa en la página. 5532 5533step: simulo mouse enter en el elemento "{element_name}" con identificador "{identifier}" 5534descripcion: Simula el evento mouseenter en un elemento usando hover(). 5535 5536step: simulo mouse leave en el elemento "{element_name}" con identificador "{identifier}" 5537descripcion: Simula el evento mouseleave moviendo el mouse fuera del elemento. 5538 5539step: obtengo las dimensiones del elemento y las guardo en variables ancho="{width_var}" alto="{height_var}" para elemento "{element_name}" con identificador "{identifier}" 5540descripcion: Obtiene el ancho y alto de un elemento y los guarda en variables separadas. 5541 5542step: obtengo la posición del elemento y la guardo en variables x="{x_var}" y="{y_var}" para elemento "{element_name}" con identificador "{identifier}" 5543descripcion: Obtiene las coordenadas x,y de un elemento y las guarda en variables separadas. 5544 5545step: clono el elemento "{source_element}" y lo añado a "{target_element}" con identificadores "{source_id}" y "{target_id}" 5546descripcion: Clona un elemento del DOM y lo añade como hijo de otro elemento. 5547 5548step: elimino el elemento "{element_name}" con identificador "{identifier}" 5549descripcion: Elimina un elemento completamente del DOM usando JavaScript remove().`},{id:"steps-validaciones",title:"Inventario: Validaciones",content:`## Aserciones de Elementos 5550 5551step: deberÃa ver el texto "{text}" 5552descripcion: Verifica que un texto exacto sea visible en la página actual. Soporta resolución de variables. 5553 5554step: deberÃa ver el texto que contiene "{text}" 5555descripcion: Verifica que un texto parcial sea visible en la página. Usa búsqueda XPath con contains. 5556 5557step: deberÃa ver en la página el texto {text_with_variable} 5558descripcion: Verifica que un texto sea visible en la página, soportando variables sin comillas (ej: \${variable}). 5559 5560step: no deberÃa ver el texto "{text}" 5561descripcion: Verifica que un texto especÃfico no sea visible en la página actual. 5562 5563step: el tÃtulo de la página deberÃa ser "{title}" 5564descripcion: Verifica que el tÃtulo de la página sea exactamente igual al texto proporcionado. 5565 5566step: el tÃtulo de la página deberÃa contener "{text}" 5567descripcion: Verifica que el tÃtulo de la página contenga un texto parcial especÃfico. 5568 5569step: el elemento "{element_name}" deberÃa existir con identificador "{identifier}" y valor "{value}" 5570descripcion: Verifica que un elemento existe en el DOM usando un localizador dinámico con placeholder reemplazado por el valor. 5571 5572step: el elemento "{element_name}" deberÃa existir en identificador "{identifier}" 5573descripcion: Verifica que un elemento existe en el DOM sin importar si es visible. Soporta localizadores dinámicos. 5574 5575step: el elemento "{element_name}" no deberÃa existir con identificador "{identifier}" y valor "{value}" 5576descripcion: Verifica que un elemento NO existe en el DOM usando un localizador dinámico con valor. 5577 5578step: el elemento "{element_name}" no deberÃa existir en identificador "{identifier}" 5579descripcion: Verifica que un elemento NO existe en el DOM. Soporta localizadores con placeholders. 5580 5581step: deberÃa ver el elemento "{element_name}" con identificador "{identifier}" 5582descripcion: Verifica que un elemento sea visible en la página. Soporta variables en el identificador con \${variable}. 5583 5584step: no deberÃa ver el elemento "{element_name}" con identificador "{identifier}" 5585descripcion: Verifica que un elemento no sea visible en la página. Soporta variables en el identificador. 5586 5587step: el elemento "{element_name}" deberÃa contener el texto "{text}" con identificador "{identifier}" 5588descripcion: Verifica que un elemento contenga un texto especÃfico (búsqueda parcial dentro del elemento). 5589 5590step: el elemento "{element_name}" deberÃa tener el texto exacto "{text}" con identificador "{identifier}" 5591descripcion: Verifica que un elemento tenga exactamente el texto proporcionado, sin contenido adicional. 5592 5593step: el campo "{field_name}" deberÃa tener el valor "{value}" con identificador "{identifier}" 5594descripcion: Verifica que un campo de formulario tenga un valor especÃfico. 5595 5596step: el campo "{field_name}" no deberÃa tener el valor "{value}" con identificador "{identifier}" 5597descripcion: Verifica que un campo de formulario NO tenga un valor especÃfico. 5598 5599step: el campo "{field_name}" deberÃa estar vacÃo con identificador "{identifier}" 5600descripcion: Verifica que un campo de formulario esté vacÃo, sin ningún valor ingresado. 5601 5602step: el campo "{field_name}" no deberÃa estar vacÃo con identificador "{identifier}" 5603descripcion: Verifica que un campo de formulario tenga algún valor (no esté vacÃo). 5604 5605step: el elemento "{element_name}" deberÃa estar habilitado con identificador "{identifier}" 5606descripcion: Verifica que un elemento esté habilitado para interacción del usuario. 5607 5608step: el elemento "{element_name}" deberÃa estar deshabilitado con identificador "{identifier}" 5609descripcion: Verifica que un elemento esté deshabilitado y no permita interacción. 5610 5611step: el checkbox "{checkbox_name}" deberÃa estar marcado con identificador "{identifier}" 5612descripcion: Verifica que un checkbox esté en estado marcado/checked. 5613 5614step: el checkbox "{checkbox_name}" no deberÃa estar marcado con identificador "{identifier}" 5615descripcion: Verifica que un checkbox no esté marcado. 5616 5617step: la url actual deberÃa ser "{url}" 5618descripcion: Verifica que la URL actual del navegador sea exactamente la proporcionada. 5619 5620step: la url actual deberÃa contener "{url_part}" 5621descripcion: Verifica que la URL actual del navegador contenga una parte especÃfica del texto. 5622 5623step: deberÃa haberse abierto una nueva ventana con url que contiene "{url_part}" 5624descripcion: Verifica que se abrió una nueva ventana o pestaña cuya URL contiene el texto especificado. 5625 5626step: deberÃa haberse abierto una nueva ventana con tÃtulo que contiene "{title}" 5627descripcion: Verifica que se abrió una nueva ventana o pestaña cuyo tÃtulo contiene el texto especificado. 5628 5629step: deberÃa haber {count:d} ventanas abiertas 5630descripcion: Verifica que hay un número especÃfico de ventanas/pestañas abiertas en el navegador. 5631 5632step: el elemento "{element_name}" deberÃa tener la clase "{css_class}" con identificador "{identifier}" 5633descripcion: Verifica que un elemento tenga una clase CSS especÃfica en su atributo class. 5634 5635step: el elemento "{element_name}" no deberÃa tener la clase "{css_class}" con identificador "{identifier}" 5636descripcion: Verifica que un elemento NO tenga una clase CSS especÃfica. 5637 5638step: el elemento "{element_name}" deberÃa tener el atributo "{attribute}" en identificador "{identifier}" 5639descripcion: Verifica que un elemento tenga un atributo HTML especÃfico, sin importar su valor. 5640 5641step: el elemento "{element_name}" no deberÃa tener el atributo "{attribute}" con identificador "{identifier}" 5642descripcion: Verifica que un elemento NO tenga un atributo HTML especÃfico. 5643 5644step: el elemento "{element_name}" deberÃa tener el atributo "{attribute}" con valor "{value}" con identificador "{identifier}" 5645descripcion: Verifica que un atributo HTML de un elemento tenga un valor exacto especÃfico. 5646 5647step: el elemento "{element_name}" deberÃa tener el atributo "{attribute}" que contiene "{value}" con identificador "{identifier}" 5648descripcion: Verifica que un atributo HTML de un elemento contenga un valor parcial especÃfico. 5649 5650step: el elemento "{element_name}" deberÃa ser de solo lectura con identificador "{identifier}" 5651descripcion: Verifica que un elemento tenga el atributo readonly (solo lectura). 5652 5653step: el elemento "{element_name}" no deberÃa ser de solo lectura con identificador "{identifier}" 5654descripcion: Verifica que un elemento NO sea de solo lectura. 5655 5656step: el elemento "{element_name}" deberÃa ser requerido con identificador "{identifier}" 5657descripcion: Verifica que un elemento tenga el atributo required (campo obligatorio). 5658 5659step: el elemento "{element_name}" no deberÃa ser requerido con identificador "{identifier}" 5660descripcion: Verifica que un elemento NO sea requerido. 5661 5662step: el elemento "{element_name}" deberÃa estar oculto con identificador "{identifier}" 5663descripcion: Verifica que un elemento esté oculto (hidden o display:none). 5664 5665step: el elemento "{element_name}" deberÃa estar adjunto al DOM con identificador "{identifier}" 5666descripcion: Verifica que un elemento esté adjunto/presente en el DOM del documento. 5667 5668step: el elemento "{element_name}" deberÃa ser editable con identificador "{identifier}" 5669descripcion: Verifica que un elemento sea editable por el usuario. 5670 5671step: el input "{element_name}" deberÃa tener valor mÃnimo "{min_value}" con identificador "{identifier}" 5672descripcion: Verifica que un input numérico tenga un atributo min con el valor especificado. 5673 5674step: el input "{element_name}" deberÃa tener valor máximo "{max_value}" con identificador "{identifier}" 5675descripcion: Verifica que un input numérico tenga un atributo max con el valor especificado. 5676 5677step: el input "{element_name}" deberÃa tener longitud máxima "{maxlength}" con identificador "{identifier}" 5678descripcion: Verifica que un input tenga un atributo maxlength con el valor especificado. 5679 5680step: el input "{element_name}" deberÃa tener patrón "{pattern}" con identificador "{identifier}" 5681descripcion: Verifica que un input tenga un atributo pattern de validación especÃfico. 5682 5683step: el input "{element_name}" deberÃa tener placeholder "{placeholder}" con identificador "{identifier}" 5684descripcion: Verifica que un input tenga un texto placeholder especÃfico. 5685 5686step: el input "{element_name}" deberÃa tener tipo "{input_type}" con identificador "{identifier}" 5687descripcion: Verifica que un input tenga un tipo especÃfico (text, email, number, etc.). 5688 5689step: deberÃa haber exactamente {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}" 5690descripcion: Verifica que haya un número exacto de elementos que coincidan con el selector. 5691 5692step: deberÃa haber al menos {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}" 5693descripcion: Verifica que haya al menos un número mÃnimo de elementos que coincidan con el selector. 5694 5695step: deberÃa haber como máximo {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}" 5696descripcion: Verifica que haya como máximo un número de elementos que coincidan con el selector. 5697 5698step: el elemento "{element_name}" deberÃa tener aria-label "{aria_label}" con identificador "{identifier}" 5699descripcion: Verifica que un elemento tenga un atributo aria-label con el valor especificado. 5700 5701step: el elemento "{element_name}" deberÃa tener rol "{role}" con identificador "{identifier}" 5702descripcion: Verifica que un elemento tenga un rol ARIA especÃfico (button, dialog, etc.). 5703 5704step: el elemento "{element_name}" deberÃa tener aria-expanded "{state}" con identificador "{identifier}" 5705descripcion: Verifica que un elemento tenga aria-expanded con un estado especÃfico (true/false). 5706 5707step: el elemento "{element_name}" deberÃa tener atributo data "{data_attr}" con valor "{value}" con identificador "{identifier}" 5708descripcion: Verifica que un elemento tenga un data-attribute especÃfico con un valor determinado. 5709 5710step: el enlace "{element_name}" deberÃa tener href "{href}" con identificador "{identifier}" 5711descripcion: Verifica que un enlace tenga un atributo href con la URL exacta especificada. 5712 5713step: el enlace "{element_name}" deberÃa tener href que contiene "{href_part}" con identificador "{identifier}" 5714descripcion: Verifica que un enlace tenga un href que contenga una parte especÃfica de la URL. 5715 5716step: la imagen "{element_name}" deberÃa tener src "{src}" con identificador "{identifier}" 5717descripcion: Verifica que una imagen tenga un atributo src con la ruta exacta especificada. 5718 5719step: la imagen "{element_name}" deberÃa tener alt "{alt}" con identificador "{identifier}" 5720descripcion: Verifica que una imagen tenga un texto alternativo (alt) especÃfico. 5721 5722step: el elemento "{element_name}" deberÃa tener tÃtulo "{title}" con identificador "{identifier}" 5723descripcion: Verifica que un elemento tenga un atributo title con el texto especificado. 5724 5725step: el elemento "{element_name}" deberÃa tener nombre "{name}" con identificador "{identifier}" 5726descripcion: Verifica que un elemento tenga un atributo name con el valor especificado. 5727 5728step: el elemento "{element_name}" deberÃa tener id "{element_id}" con identificador "{identifier}" 5729descripcion: Verifica que un elemento tenga un atributo id con el valor especificado. 5730 5731step: el select "{element_name}
5731" deberÃa tener la opción seleccionada "{option_text}" con identificador "{identifier}" 5732descripcion: Verifica que un select tenga una opción especÃfica actualmente seleccionada. 5733 5734step: el select "{element_name}" deberÃa tener {count:d} opciones con identificador "{identifier}" 5735descripcion: Verifica que un select tenga un número especÃfico de opciones disponibles. 5736 5737step: lanzo un error con el mensaje "{mensaje}" 5738descripcion: Fuerza un fallo inmediato del escenario con un mensaje personalizado. Ãtil para marcar caminos que no deberÃan alcanzarse. 5739 5740## Validaciones de Página 5741 5742step: deberia ver el elemento "{element_name}" con identificador "{identifier}" 5743descripcion: Verifica que un elemento es visible en la página (sin tilde en "deberÃa"). 5744 5745step: no deberia ver el elemento "{element_name}" con identificador "{identifier}" 5746descripcion: Verifica que un elemento NO es visible en la página (sin tilde en "deberÃa"). 5747 5748step: deberia ver que el elemento "{element_name}" existe con identificador "{identifier}" 5749descripcion: Verifica que un elemento existe en el DOM, aunque puede estar oculto visualmente. 5750 5751step: no deberia ver que el elemento "{element_name}" existe con identificador "{identifier}" 5752descripcion: Verifica que un elemento NO existe en el DOM de la página. 5753 5754step: verifico que el elemento "{element_name}" tiene la clase CSS "{css_class}" con identificador "{identifier}" 5755descripcion: Verifica que un elemento tiene una clase CSS especÃfica en su lista de clases. 5756 5757step: verifico que el elemento "{element_name}" no tiene la clase CSS "{css_class}" con identificador "{identifier}" 5758descripcion: Verifica que un elemento NO tiene una clase CSS especÃfica. 5759 5760step: verifico que el elemento "{element_name}" tiene el atributo "{attribute}" con valor "{expected_value}" con identificador "{identifier}" 5761descripcion: Verifica que un elemento tiene un atributo HTML con un valor exacto especÃfico. 5762 5763step: verifico que el atributo "{attribute}" del elemento "{element_name}" coincide con el patrón "{pattern}" con identificador "{identifier}" 5764descripcion: Verifica que un atributo de un elemento coincide con un patrón de expresión regular. 5765 5766step: verifico que el texto del elemento "{element_name}" coincide con el patrón "{pattern}" con identificador "{identifier}" 5767descripcion: Verifica que el texto de un elemento coincide con un patrón regex especÃfico. 5768 5769step: verifico que el texto del elemento "{element_name}" tiene formato de email válido con identificador "{identifier}" 5770descripcion: Verifica que el texto de un elemento tiene formato de correo electrónico válido. 5771 5772step: verifico que el texto del elemento "{element_name}" tiene formato de teléfono válido con identificador "{identifier}" 5773descripcion: Verifica que el texto de un elemento tiene formato de número telefónico válido. 5774 5775step: verifico que el texto del elemento "{element_name}" tiene formato de fecha válido "{date_format}" con identificador "{identifier}" 5776descripcion: Verifica que el texto de un elemento tiene un formato de fecha válido según el patrón proporcionado (ej: %Y-%m-%d). 5777 5778step: verifico que el texto del elemento "{element_name}" es numérico con identificador "{identifier}" 5779descripcion: Verifica que el texto de un elemento es un valor numérico válido. 5780 5781step: verifico que la longitud del texto del elemento "{element_name}" es "{expected_length}" con identificador "{identifier}" 5782descripcion: Verifica que el texto de un elemento tiene una longitud exacta en caracteres. 5783 5784step: verifico que la longitud del texto del elemento "{element_name}" está entre "{min_length}" y "{max_length}" con identificador "{identifier}" 5785descripcion: Verifica que la longitud del texto de un elemento está dentro de un rango especÃfico. 5786 5787step: verifico que el elemento "{element_name}" está dentro del viewport con identificador "{identifier}" 5788descripcion: Verifica que un elemento está visible dentro del área visible del navegador (viewport). 5789 5790step: verifico que el elemento "{element_name}" tiene el foco con identificador "{identifier}" 5791descripcion: Verifica que un elemento tiene actualmente el foco del te
5791clado. 5792 5793step: verifico que el color de fondo del elemento "{element_name}" es "{expected_color}" con identificador "{identifier}" 5794descripcion: Verifica que un elemento tiene un color de fondo especÃfico (soporta hex y rgb). 5795 5796step: verifico que el color del texto del elemento "{element_name}" es "{expected_color}" con identificador "{identifier}" 5797descripcion: Verifica que un elemento tiene un color de texto especÃfico. 5798 5799step: verifico que el tamaño de fuente del elemento "{element_name}" es "{expected_size}" con identificador "{identifier}" 5800descripcion: Verifica que un elemento tiene un tamaño de fuente especÃfico (ej: 16px). 5801 5802step: verifico que el ancho del elemento "{element_name}" es "{expected_width}" pÃxeles con identificador "{identifier}" 5803descripcion: Verifica que un elemento tiene un ancho especÃfico en pÃxeles. 5804 5805step: verifico que la altura del elemento "{element_name}" es "{expected_height}" pÃxeles con identificador "{identifier}" 5806descripcion: Verifica que un elemento tiene una altura especÃfica en pÃxeles. 5807 5808step: verifico que el elemento "{element_name}" está posicionado en x="{expected_x}" y="{expected_y}" con identificador "{identifier}" 5809descripcion: Verifica que un elemento está en una posición especÃfica en la página (con tolerancia de 5px). 5810 5811step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" es "{expected_value}" con identificador "{identifier}" 5812descripcion: Verifica que una propiedad CSS computada de un elemento tiene un valor exacto. 5813 5814step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" contiene "{expected_value}" con identificador "{identifier}" 5815descripcion: Verifica que una propiedad CSS computada de un elemento contiene un valor parcial. 5816 5817step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" no existe con identificador "{identifier}" 5818descripcion: Verifica que un elemento NO tiene una propiedad CSS especÃfica en su estilo inline. 5819 5820step: guardo en la variable "{variable_name}" el valor de la propiedad CSS "{property}" del elemento "{element_name}" con identificador "{identifier}" 5821descripcion: Obtiene el valor de una propiedad CSS computada y lo guarda en una variable para uso posterior. 5822 5823step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" coincide con el patrón "{pattern}" con identificador "{identifier}" 5824descripcion: Verifica que una propiedad CSS de un elemento coincide con un patrón de expresión regular. 5825 5826step: verifico que el elemento "{element_name}" tiene la propiedad CSS "{property}" con identificador "{identifier}" 5827descripcion: Verifica que un elemento tiene una propiedad CSS especÃfica definida (sin importar el valor). 5828 5829step: verifico que el elemento "{element_name}" no tiene la propiedad CSS "{property}" con identificador "{identifier}" 5830descripcion: Verifica que un elemento NO tiene una propiedad CSS especÃfica en su estilo.`},{id:"steps-extraccion-datos",title:"Inventario: Extracción de Datos y Variables",content:`## Extracción de Datos 5831 5832step: guardo el texto del elemento "{selector}" en la variable "{variable_name}" 5833descripcion: Obtiene el texto visible de un elemento (usando identificador JSON POM o selector CSS/XPath) y lo almacena en una variable. El selector puede ser $.ARCHIVO.elemento o un selector directo. 5834 5835step: guardo el atributo "{attribute}" del elemento "{selector}" en la variable "{variable_name}" 5836descripcion: Obtiene el valor de un atributo HTML de un elemento y lo almacena en una variable. 5837 5838step: obtengo el tÃtulo de la página y lo guardo en la variable "{variable_name}" 5839descripcion: Obtiene el tÃtulo de la página actual y lo almacena en una variable. 5840 5841step: cuento los elementos con identificador "{identifier}" y guardo el conteo en la variable "{variable_name}" 5842descripcion: Cuenta la cantidad de elementos que coinciden con un localizador y guarda el número en una variable. 5843 5844step: verifico si el elemento "{element_name}" es visible y guardo el resultado en la variable "{variable_name}" con identificador "{identifier}" 5845descripcion: Verifica si un elemento es visible y guarda el resultado booleano (true/false) en una variable. 5846 5847step: verifico si el elemento "{element_name}" está habilitado y guardo el resultado en la variable "{variable_name}" con identificador "{identifier}" 5848descripcion: Verifica si un elemento está habilitado y guarda el resultado booleano en una variable. 5849 5850step: verifico si el checkbox "{checkbox_name}" está marcado y guardo el resultado en la variable "{variable_name}" con identificador "{identifier}" 5851descripcion: Verifica si un checkbox está marcado y guarda el resultado booleano en una variable. 5852 5853## Variables 5854 5855step: creo la variable "{variable_name}" con valor "{value}" 5856descripcion: Crea o actualiza una variable con un valor especÃfico. Resuelve variables existentes en el valor. 5857 5858step: establezco "{variable_name}" = "{value}" 5859descripcion: Establece el valor de una variable usando sintaxis abreviada de asignación. 5860 5861step: establezco la variable "{variable_name}" con el valor "{value}"
5862descripcion: Establece el valor de una variable con sintaxis descriptiva completa. 5863 5864step: genero una variable "{variable_name}" con texto aleatorio de {length:d} caracteres 5865descripcion: Genera una variable con texto aleatorio alfanumérico de la longitud especificada. 5866 5867step: genero una cadena aleatoria de longitud {length:d} y la guardo en la variable "{variable_name}" 5868descripcion: Genera una cadena aleatoria de longitud especÃfica y la almacena en una variable. 5869 5870step: genero una variable "{variable_name}" con número aleatorio entre {min_val:d} y {max_val:d} 5871descripcion: Genera un número aleatorio dentro de un rango y lo guarda en una variable. 5872 5873step: genero un número aleatorio entre {min_val:d} y {max_val:d} y lo guardo en la variable "{variable_name}" 5874descripcion: Genera un número aleatorio entre dos valores y lo almacena en una variable. 5875 5876step: genero una variable "{variable_name}" con timestamp actual 5877descripcion: Genera una variable con el timestamp actual en formato YYYYMMDD_HHMMSS. 5878 5879step: obtengo el timestamp actual y lo guardo en la variable "{variable_name}" 5880descripcion: Obtiene el timestamp actual y lo almacena en una variable. 5881 5882step: genero una variable "{variable_name}" con fecha actual usando formato "{date_format}" 5883descripcion: Genera una variable con la fecha actual formateada según el patrón proporcionado (ej: %Y-%m-%d, %d/%m/%Y). 5884 5885step: obtengo la fecha actual y la guardo en la variable "{variable_name}" 5886descripcion: Obtiene la fecha actual en formato por defecto (%Y-%m-%d) y la guarda en una variable. 5887 5888step: concateno "{var1}" y "{var2}" y lo guardo en la variable "{result_var}" 5889descripcion: Concatena dos valores (textos, literales o variables con sintaxis \${nombre}) y guarda el resultado en una nueva variable. 5890 5891step: incremento la variable numérica "{variable_name}" en {increment:d} 5892descripcion: Incrementa el valor numérico de una variable en la cantidad especificada. 5893 5894step: muestro el valor de la variable "{variable_name}" 5895descripcion: Muestra en consola el valor actual de una variable para depuración. 5896 5897step: muestro en consola el valor de la variable "{variable_name}" 5898descripcion: Imprime en la consola el valor de una variable especÃfica. 5899 5900step: imprimo la variable "{variable_name}" 5901descripcion: Imprime el valor de una variable en la salida estándar. 5902 5903step: verifico que la variable "{variable_name}" contiene "{expected_value}" 5904descripcion: Verifica que el valor de una variable contiene un texto especÃfico (búsqueda parcial). 5905 5906step: verifico que la variable "{variable_name}" es igual a "{expected_value}" 5907descripcion: Verifica que el valor de una variable es exactamente igual al valor esperado. Soporta comparación entre variables. 5908 5909step: muestro todas las variables actuales 5910descripcion: Muestra en consola un listado de todas las variables definidas con sus valores actuales. 5911 5912step: limpio todas las variables globales 5913descripcion: Elimina todas las variables globales definidas durante la ejecución. 5914 5915step: limpio todas las variables del escenario 5916descripcion: Limpia todas las variables del escenario actual, dejando el estado limpio. 5917 5918step: copio la variable "{source_var}" a "{target_var}" 5919descripcion: Copia el valor de una variable existente a una nueva variable. 5920 5921step: genero una variable "{variable_name}" con fecha actual en formato "{date_format}" sumando {days:d} dÃas hábiles 5922descripcion: Genera una fecha futura sumando dÃas hábiles (lunes a viernes) a la fecha actual y la guarda en una variable. 5923 5924step: genero una fecha con {days:d} dÃas hábiles y la guardo en la variable "{variable_name}" en formato "{date_format}" 5925descripcion: Calcula una fecha futura con dÃas hábiles y la almacena en una variable con el formato especificado.`},{id:"steps-performance",title:"Inventario: Performance",content:`## Performance 5926 5927step: verifico que la página carga en menos de "{max_seconds}" segundos 5928descripcion: Verifica que la página completa su carga (networkidle) dentro del tiempo máximo especificado. 5929 5930step: verifico que el elemento "{element_name}" aparece en menos de "{max_seconds}" segundos con identificador "{identifier}" 5931descripcion: Verifica que un elemento se vuelve visible dentro del tiempo máximo especificado. 5932 5933step: verifico que el tiempo de respuesta del click en elemento "{element_name}" es menor a "{max_seconds}" segundos con identificador "{identifier}" 5934descripcion: Mide el tiempo de respuesta después de hacer click en un elemento y verifica que sea menor al máximo. 5935 5936step: mido y guardo el tiempo de carga de página en la variable "{variable_name}" 5937descripcion: Mide el tiempo de carga de la página hasta networkidle y lo guarda en una variable en segundos. 5938 5939step: verifico que las peticiones de red se completan en menos de "{max_seconds}" segundos 5940descripcion: Verifica que todas las peticiones de red pendientes se completan dentro del tiempo especificado. 5941 5942step: verifico que el tiempo de respuesta del envÃo de formulario es menor a "{max_seconds}" segundos 5943descripcion: Verifica que el envÃo de un formulario y su respuesta se completan dentro del tiempo máximo. 5944 5945step: verifico que los resultados de búsqueda aparecen en menos de "{max_seconds}" segundos 5946descripcion: Verifica que los resultados de búsqueda se muestran dentro del tiempo máximo especificado. 5947 5948step: verifico que la imagen "{image_name}" carga en menos de "{max_seconds}" segundos con identificador "{identifier}" 5949descripcion: Verifica que una imagen se carga completamente dentro del tiempo máximo especificado. 5950 5951step: verifico que la animación se completa en menos de "{max_seconds}" segundos en elemento "{element_name}" con identificador "{identifier}" 5952descripcion: Verifica que una animación CSS/JS se completa dentro del tiempo máximo en un elemento especÃfico. 5953 5954step: verifico que el modal "{modal_name}" se abre en menos de "{max_seconds}" segundos con identificador "{identifier}" 5955descripcion: Verifica que un modal se vuelve visible dentro del tiempo máximo especificado. 5956 5957step: verifico que el dropdown "{dropdown_name}" se expande en menos de "{max_seconds}" segundos con identificador "{identifier}" 5958descripcion: Verifica que un dropdown se expande y muestra sus opciones dentro del tiempo máximo. 5959 5960step: verifico que el rendimiento del scroll de página es suave 5961descripcion: Verifica que el scroll completo de la página (arriba y abajo) se ejecuta en menos de 1 segundo. 5962 5963step: verifico que el uso de memoria es aceptable después de "{actions_count}" acciones 5964descripcion: Verifica que el uso de memoria del navegador no supera el 80% después de realizar múltiples acciones.`}
5964,{id:"steps-performance-frontend",title:"Inventario: Performance Frontend",content:`## Performance Frontend (Web Vitals) 5965 5966Métricas de rendimiento del front end medidas en el navegador real (Navigation Timing API + PerformanceObserver). Las verificaciones de tiempo usan **milisegundos**. 5967 5968### Medición y reportes 5969 5970step: mido las metricas de carga de la pagina y las guardo en la variable "{variable_name}" 5971descripcion: Obtiene métricas de carga con Navigation Timing API y guarda un JSON con: dns, tcp, ttfb, download, dom_interactive, dom_complete, total. 5972 5973step: genero un reporte de performance de la pagina y lo guardo en la variable "{variable_name}" 5974descripcion: Genera un reporte completo de performance con todas las métricas disponibles: timing, vitals, recursos, DOM y errores. 5975 5976step: mido los recursos de la pagina por tipo y los guardo en la variable "{variable_name}" 5977descripcion: Cuenta y pesa los recursos agrupados por tipo (script, css, img, font, etc.). 5978 5979### Core Web Vitals 5980 5981step: verifico que el First Contentful Paint es menor a "{max_ms}" milisegundos 5982descripcion: Verifica el First Contentful Paint (FCP): cuándo se renderiza el primer contenido visible. Referencia Google: Bueno < 1800ms, Aceptable < 3000ms. 5983 5984step: verifico que el Largest Contentful Paint es menor a "{max_ms}" milisegundos 5985descripcion: Verifica el Largest Contentful Paint (LCP): cuándo termina de renderizar el elemento más grande del viewport. Referencia Google: Bueno < 2500ms, Necesita mejora < 4000ms. 5986 5987step: verifico que el Cumulative Layout Shift es menor a "{max_cls}" 5988descripcion: Verifica el Cumulative Layout Shift (CLS): estabilidad visual (cuánto se mueven los elementos al cargar). Referencia Google: Bueno < 0.1, Necesita mejora < 0.25. 5989 5990step: verifico que el TTFB es menor a "{max_ms}" milisegundos 5991descripcion: Verifica el Time To First Byte (TTFB): cuánto tarda el servidor en enviar el primer byte. Referencia: Bueno < 800ms, Aceptable < 1800ms. 5992 5993### DOM e interactividad 5994 5995step: verifico que el DOM esta interactivo en menos de "{max_ms}" milisegundos 5996descripcion: Verifica que el DOM alcanza el estado interactivo dentro del umbral. Referencia: Bueno < 3000ms, Aceptable < 5000ms. 5997 5998step: verifico que la pagina es interactiva en menos de "{max_seconds}" segundos 5999descripcion: Verifica que la página es interactiva (DOMContentLoaded + sin JS bloqueante) dentro del umbral en segundos. 6000 6001step: verifico que el DOM tiene menos de "{max_nodes}" nodos 6002descripcion: Verifica que el DOM no es excesivamente grande. Referencia: Bueno < 1500 nodos, Aceptable < 3000, Problemático > 5000. 6003 6004step: verifico que la profundidad maxima del DOM es menor a "{max_depth}" niveles 6005descripcion: Verifica que el DOM no tiene anidamiento excesivo. Referencia: Bueno < 15 niveles, Aceptable < 25, Problemático > 32. 6006 6007### Red, peso y errores 6008 6009step: verifico que la pagina carga menos de "{max_requests}" peticiones de red 6010descripcion: Verifica que la página no genera demasiadas peticiones HTTP durante su carga. 6011 6012step: verifico que el peso total de la pagina es menor a "{max_kb}" KB 6013descripcion: Verifica que el peso total de los recursos cargados no excede el lÃmite en KB. 6014 6015step: verifico que no hay errores de JavaScript en la consola 6016descripcion: Verifica que no hubo errores JavaScript durante la carga de la página.`},{id:"steps-accesibilidad",title:"Inventario: Accesibilidad",content:`## Accesibilidad 6017 6018step: verifico que el elemento "{element_name}" tiene etiqueta ARIA "{expected_label}" con identificador "{identifier}" 6019descripcion: Verifica que un elemento tiene un atributo aria-label con el valor exacto especificado. 6020 6021step: verifico que el elemento "{element_name}" tiene rol ARIA "{expected_role}" con identificador "{identifier}" 6022descripcion: Verifica que un elemento tiene un atributo role ARIA con el valor especificado. 6023 6024step: verifico que el elemento "{element_name}" es accesible por teclado con identificador "{identifier}" 6025descripcion: Verifica que un elemento puede recibir foco y tiene tabindex no negativo para navegación por teclado. 6026 6027step: verifico que el elemento "{element_name}" tiene texto alt "{expected_alt}" con identificador "{identifier}" 6028descripcion: Verifica que una imagen tiene un texto alternativo (alt) con el valor exacto especificado. 6029 6030step: verifico que el elemento "{element_name}" tiene jerarquÃa de encabezados correcta con identificador "{identifier}" 6031descripcion: Verifica que los encabezados de la página siguen una jerarquÃa correcta sin saltar niveles. 6032 6033step: verifico que el formulario tiene etiquetas apropiadas para todos los campos 6034descripcion: Verifica que todos los campos de formulario tienen etiquetas asociadas (label, aria-label o aria-labelledby). 6035 6036step: verifico que el elemento "{element_name}
6036" tiene contraste de color suficiente con identificador "{identifier}" 6037descripcion: Verifica que un elemento cumple con el ratio de contraste mÃnimo WCAG AA de 4.5:1. 6038 6039step: verifico que la página tiene estructura de documento apropiada 6040descripcion: Verifica que la página tiene tÃtulo, un solo h1, y elementos de navegación y contenido principal. 6041 6042step: verifico que el elemento "{element_name}" es anunciado por lector de pantalla con identificador "{identifier}" 6043descripcion: Verifica que un elemento será anunciado por lectores de pantalla (no tiene aria-hidden=true y tiene contenido accesible). 6044 6045step: verifico que los elementos interactivos tienen indicadores de foco 6046descripcion: Verifica que botones, enlaces e inputs tienen indicadores visuales de foco (outline, box-shadow). 6047 6048step: verifico que el elemento "{element_name}" tiene texto de enlace descriptivo con identificador "{identifier}" 6049descripcion: Verifica que un enlace tiene texto descriptivo y no genérico como "click aquÃ" o "más". 6050 6051step: verifico que las imágenes tienen texto alternativo apropiado 6052descripcion: Verifica que todas las imágenes de la página tienen atributo alt y que no es solo el nombre del archivo.`},{id:"steps-tooltips",title:"Inventario: Tooltips y Puntero",content:`## Tooltips y Puntero 6053 6054Pasos para validar tooltips y controlar el puntero del mouse. Resuelven el tooltip en cascada sin que el QA necesite saber qué librerÃa usa la aplicación: 6055 6056- \`aria-describedby\` del elemento 6057- \`role="tooltip"\` (estándar ARIA) 6058- Selectores de 11 librerÃas: Bootstrap, Material UI, Tippy, Ant Design, Vuetify, PrimeNG, Radix, jQuery UI 6059- Atributo \`title\` (tooltip nativo del navegador) 6060 6061> Los tooltips nativos (atributo \`title\`) los dibuja el navegador y no existen en el DOM. Solo es observable el atributo. 6062 6063## Validar el texto del tooltip 6064 6065step: el tooltip del elemento "{element_name}" deberÃa contener el texto "{expected_text}" con identificador "{identifier}" 6066descripcion: Pasa el mouse sobre un elemento y valida que su tooltip contenga el texto indicado. Resuelve en cascada. 6067 6068step: el tooltip del elemento "{element_name}" deberÃa ser "{expected_text}" con identificador "{identifier}" 6069descripcion: Igual que el anterior pero exige coincidencia exacta del texto completo. 6070 6071step: el tooltip visible deberÃa contener el texto "{expected_text}" 6072descripcion: Valida el tooltip que ya está visible, sin volver a hacer hover. Para cuando lo dispara otra acción como el foco. 6073 6074## Controlar el puntero 6075 6076step: paso el mouse sobre el elemento "{element_name}" y espero el tooltip con identificador "{identifier}" 6077descripcion: Pasa el mouse sobre un elemento y espera a que aparezca su tooltip, dejándolo abierto para validarlo en pasos siguientes. 6078 6079step: mantengo el mouse sobre el elemento "{element_name}" por "{seconds}" segundos con identificador "{identifier}" 6080descripcion: Mantiene el puntero sobre un elemento durante un tiempo. Para tooltips con delay largo o menús que requieren permanencia. 6081 6082step: quito el mouse del elemento 6083descripcion: Aleja el puntero para que se cierren los tooltips y menús por hover. Mueve el mouse a una esquina. 6084 6085## Validar ausencia del tooltip 6086 6087step: no deberÃa verse ningún tooltip 6088descripcion: Valida que no haya ningún tooltip visible, recorriendo todas las estrategias de la cascada. 6089 6090step: el elemento "{element_name}" no deberÃa mostrar tooltip con identificador "{identifier}" 6091descripcion: Valida que un elemento NO muestre tooltip al pasarle el mouse. 6092 6093## Accesibilidad del tooltip 6094 6095step: pongo el foco en el elemento "{element_name}" y espero el tooltip con identificador "{identifier}" 6096descripcion: Enfoca un elemento con el teclado y espera su tooltip. Un tooltip accesible debe aparecer también al tabular. 6097 6098step: el elemento "{element_name}" deberÃa describirse con el texto "{expected_text}" con identificador "{identifier}" 6099descripcion: Valida la descripción accesible (aria-describedby) sin hacer hover. Es lo que lee un screen reader. 6100 6101## Capturar texto del tooltip 6102 6103step: obtengo el texto del tooltip del elemento "{element_name}" y lo guardo en la variable "{variable_name}" con identificador "{identifier}" 6104descripcion: Guarda el texto del tooltip en una variable del framework para reutilizarlo en pasos siguientes.`},{id:"steps-geolocalizacion",title:"Inventario: Geolocalización",content:`## Geolocalización 6105 6106Documento generado a partir del código fuente real del framework. 6107Cada paso fue verificado directamente en el archivo \`geolocation_steps.py\`. 6108 6109**Requisitos:** Ninguno adicional (usa Playwright nativo). 6110 6111**Configuración .env:** 6112\`\`\` 6113GEOLOCATION_ENABLED=true 6114GEOLOCATION_LATITUDE=-33.4489 6115GEOLOCATION_LONGITUDE=-70.6693 6116GEOLOCATION_ACCURACY=100 6117\`\`\` 6118 6119**Nota importante:** Cuando \`GEOLOCATION_ENABLED=true\`, el framework otorga automáticamente el permiso de geolocalización al crear el contexto del navegador. Esto resuelve el problema de páginas que usan \`navigator.geolocation.getCurrentPosition()\` sin mostrar un popup de permiso explÃcito. 6120 6121--- 6122
6123## Configurar Geolocalización 6124 6125step: configuro la geolocalización en latitud "{lat}" y longitud "{lon}" 6126descripcion: Configura la geolocalización del navegador con las coordenadas indicadas. Otorga permisos automáticamente. 6127 6128step: configuro la geolocalización en latitud "{lat}" longitud "{lon}" con precisión "{acc}" 6129descripcion: Configura la geolocalización con una precisión personalizada en metros. 6130 6131step: configuro la geolocalización para "{ciudad}" 6132descripcion: Configura la geolocalización usando una ciudad predefinida. Ciudades disponibles: Santiago, Buenos Aires, Lima, Bogotá, México, Madrid, New York, London, Paris, Berlin, Tokyo, Sydney, São Paulo, ValparaÃso, Concepción. 6133 6134--- 6135 6136## Permisos 6137 6138step: otorgo permisos de geolocalización al navegador 6139descripcion: Otorga permisos de geolocalización al contexto del navegador sin cambiar las coordenadas. 6140 6141step: otorgo permisos de geolocalización para la url "{url}" 6142descripcion: Otorga permisos de geolocalización para un origen/URL especÃfico. 6143 6144--- 6145 6146## Desactivar 6147 6148step: desactivo la geolocalización del navegador 6149descripcion: Limpia la geolocalización y los permisos del navegador, volviendo al comportamiento por defecto (sin ubicación simulada). 6150 6151--- 6152 6153## Verificación 6154 6155step: verifico que la geolocalización del navegador es latitud "{lat}" y longitud "{lon}" 6156descripcion: Ejecuta navigator.geolocation.getCurrentPosition() en la página y verifica que las coordenadas coincidan (tolerancia de ~111 metros). 6157 6158step: verifico que la geolocalización del navegador es "{ciudad}" 6159descripcion: Verifica que la geolocalización actual corresponde a las coordenadas de una ciudad predefinida. 6160 6161--- 6162 6163## Ejemplos de Uso 6164 6165### Configurar desde .env (se aplica al crear el contexto) 6166 6167\`\`\` 6168# .env 6169GEOLOCATION_ENABLED=true 6170GEOLOCATION_LATITUDE=-33.4489 6171GEOLOCATION_LONGITUDE=-70.6693 6172\`\`\` 6173 6174### Cambiar dinámicamente durante un test 6175 6176\`\`\`gherkin 6177Feature: Geolocalización 6178 6179 Scenario: Verificar comportamiento con ubicación en Santiago 6180 When configuro la geolocalización para "santiago" 6181 And voy a la url "https://example.com/stores" 6182 Then verifico que la geolocalización del navegador es "santiago" 6183 6184 Scenario: Cambiar ubicación durante el flujo 6185 When configuro la geolocalización en latitud "-33.4489" y longitud "-70.6693" 6186 And voy a la url "https://maps.google.com" 6187 Then deberÃa ver el elemento "Indicador de ubicación" con identificador "#location-indicator" 6188 When configuro la geolocalización para "buenos aires" 6189 And recargo la página 6190 Then verifico que la geolocalización del navegador es latitud "-34.6037" y longitud "-58.3816" 6191 6192 Scenario: Permisos para un origen especÃfico 6193 When otorgo permisos de geolocalización para la url "https://example.com" 6194 And configuro la geolocalización en latitud "40.7128" longitud "-74.0060" con precisión "50" 6195 And voy a la url "https://example.com/location" 6196 Then verifico que la geolocalización del navegador es latitud "40.7128" y longitud "-74.0060" 6197\`\`\` 6198 6199### Ciudades predefinidas 6200 6201| Ciudad | Latitud | Longitud | 6202|--------|---------|----------| 6203| Santiago | -33.4489 | -70.6693 | 6204| Buenos Aires | -34.6037 | -58.3816 | 6205| Lima | -12.0464 | -77.0428 | 6206| Bogotá | 4.7110 | -74.0721 | 6207| México | 19.4326 | -99.1332 | 6208| Madrid | 40.4168 | -3.7038 | 6209| New York | 40.7128 | -74.0060 | 6210| London | 51.5074 | -0.1278 | 6211| Paris | 48.8566 | 2.3522 | 6212| Berlin | 52.5200 | 13.4050 | 6213| Tokyo | 35.6762 | 139.6503 | 6214| Sydney | -33.8688 | 151.2093 | 6215| São Paulo | -23.5505 | -46.6333 | 6216| ValparaÃso | -33.0472 | -71.6127 | 6217| Concepción | -36.8270 | -73.0503 |`},{id:"steps-condicionales",title:"Inventario: Condicionales",content:`## Pasos Condicionales 6218 6219Ejecutan acciones basadas en el estado actual de la página. Si la condición **no se cumple**, el step pasa sin error (no falla el escenario). 6220 6221**Timeout por defecto:** 3 segundos para verificación de condiciones. 6222 6223--- 6224 6225## Condicionales por Visibilidad â Click 6226 6227step: si el elemento "{element_name}" es visible hago click con identificador "{identifier}" 6228descripcion: Hace click en un elemento SOLO si es visible. Si no es visible, pasa sin error. 6229 6230step: si el elemento "{element_name}" es visible con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6231descripcion: Si un elemento es visible, hace click en OTRO elemento diferente. 6232 6233step: si el elemento "{element_name}" no es visible con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6234descripcion: Si un elemento NO es visible, hace click en otro elemento. 6235 6236--- 6237
6238## Condicionales por Existencia â Click 6239 6240step: si existe el elemento "{element_name}" hago click con identificador "{identifier}" 6241descripcion: Hace click en un elemento SOLO si existe en el DOM. Si no existe, pasa sin error. 6242 6243step: si existe el elemento "{element_name}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6244descripcion: Si un elemento existe en el DOM, hace click en OTRO elemento. 6245 6246step: si no existe el elemento "{element_name}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6247descripcion: Si un elemento NO existe en el DOM, hace click en otro elemento. 6248 6249--- 6250 6251## Condicionales por Visibilidad â Rellenar 6252 6253step: si el elemento "{element_name}" es visible relleno con "{text}" con identificador "{identifier}" 6254descripcion: Rellena un campo SOLO si es visible. Si no es visible, pasa sin error. 6255 6256step: si el elemento "{element_name}" es visible con identificador "{check_id}" relleno "{target}" con "{text}" con identificador "{target_id}" 6257descripcion: Si un elemento es visible, rellena OTRO campo con el texto indicado. 6258 6259--- 6260 6261## Condicionales por Texto â Click 6262 6263step: si el elemento "{element_name}" contiene "{text}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6264descripcion: Si un elemento contiene un texto parcial (case-insensitive), hace click en otro. 6265 6266step: si el elemento "{element_name}" no contiene "{text}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6267descripcion: Si un elemento NO contiene un texto, hace click en otro. 6268 6269--- 6270 6271## Condicionales por URL â Acciones 6272 6273step: si la url contiene "{url_part}" hago click en "{element_name}" con identificador "{identifier}" 6274descripcion: Si la URL actual contiene un texto, hace click en un elemento. 6275 6276step: si la url no contiene "{url_part}" hago click en "{element_name}" con identificador "{identifier}" 6277descripcion: Si la URL actual NO contiene un texto, hace click en un elemento. 6278 6279step: si la url contiene "{url_part}" navego a "{url}" 6280descripcion: Si la URL actual contiene un texto, navega a otra URL. 6281 6282step: si la url no contiene "{url_part}" navego a "{url}" 6283descripcion: Si la URL actual NO contiene un texto, navega a otra URL. 6284 6285--- 6286 6287## Condicionales por Visibilidad â Navegar 6288 6289step: si el elemento "{element_name}" es visible con identificador "{identifier}" navego a "{url}" 6290descripcion: Si un elemento es visible, navega a una URL. 6291 6292step: si el elemento "{element_name}" no es visible con identificador "{identifier}" navego a "{url}" 6293descripcion: Si un elemento NO es visible, navega a una URL. 6294 6295--- 6296 6297## Condicionales con Timeout Personalizado 6298 6299step: si el elemento "{element_name}" aparece en "{seconds}" segundos hago click con identificador "{identifier}" 6300descripcion: Espera N segundos a que aparezca un elemento. Si aparece, hace click. Si no, pasa sin error. 6301 6302step: si el elemento "{element_name}" aparece en "{seconds}" segundos con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}" 6303descripcion: Espera N segundos a que aparezca un elemento. Si aparece, hace click en otro. 6304 6305step: si el elemento "{element_name}" no aparece en "{seconds}" segundos con identificador "{identifier}" hago click en "{target}" con identificador "{target_id}" 6306descripcion: Espera N segundos. Si el elemento NO aparece, hace click en otro. 6307 6308--- 6309 6310## Condicionales por Variable â Acciones 6311 6312step: si la variable "{var_name}" es "{expected_value}" hago click en "{element_name}" con identificador "{identifier}" 6313descripcion: Si una variable tiene un valor exacto, hace click en un elemento. 6314 6315step: si la variable "{var_name}" no es "{expected_value}" hago click en "{element_name}" con identificador "{identifier}" 6316descripcion: Si una variable NO tiene un valor especÃfico, hace click en un elemento. 6317 6318step: si la variable "{var_name}" contiene "{expected_text}" hago click en "{element_name}" con identificador "{identifier}" 6319descripcion: Si una variable contiene un texto parcial (case-insensitive), hace click en un elemento. 6320 6321step: si la variable "{var_name}" es "{expected_value}" navego a "{url}" 6322descripcion: Si una variable tiene un valor especÃfico, navega a una URL. 6323 6324step: si la variable "{var_name}" es "{expected_value}" relleno "{element_name}" con "{text}" con identificador "{identifier}" 6325descripcion: Si una variable tiene un valor especÃfico, rellena un campo. 6326 6327--- 6328
6329## Condicionales por Estado del Elemento 6330 6331step: si el elemento "{element_name}" está habilitado hago click con identificador "{identifier}" 6332descripcion: Hace click en un elemento SOLO si está habilitado (no disabled). 6333 6334step: si el checkbox "{element_name}" no está marcado con identificador "{check_id}" lo marco 6335descripcion: Si un checkbox NO está marcado, lo marca. Si ya está marcado, pasa sin error. 6336 6337--- 6338 6339## Evaluar y Guardar Resultado 6340 6341step: evalúo si el elemento "{element_name}" es visible con identificador "{identifier}" y guardo en "{variable_name}" 6342descripcion: Evalúa si un elemento es visible y guarda "true" o "false" en una variable. 6343 6344step: evalúo si existe el elemento "{element_name}" con identificador "{identifier}" y guardo en "{variable_name}" 6345descripcion: Evalúa si un elemento existe en el DOM y guarda "true" o "false" en una variable. 6346 6347step: evalúo si el elemento "{element_name}" contiene "{text}" con identificador "{identifier}" y guardo en "{variable_name}" 6348descripcion: Evalúa si un elemento contiene un texto y guarda "true" o "false" en una variable. 6349 6350--- 6351 6352## Esperas con Timeout Personalizado 6353 6354step: espero a que el elemento "{element_name}" sea visible en máximo "{seconds}" segundos con identificador "{identifier}" 6355descripcion: Espera a que un elemento sea visible con un timeout personalizado en segundos. 6356 6357step: espero a que el elemento "{element_name}" desaparezca en máximo "{seconds}" segundos con identificador "{identifier}" 6358descripcion: Espera a que un elemento desaparezca con un timeout personalizado en segundos. 6359 6360step: espero a que el elemento "{element_name}" esté oculto en máximo "{seconds}" segundos con identificador "{identifier}" 6361descripcion: Espera a que un elemento esté oculto con un timeout personalizado en segundos. 6362 6363--- 6364 6365## Ejemplos de Uso 6366 6367### Cerrar popup si aparece 6368 6369\`\`\`gherkin 6370When si el elemento "cookie banner" es visible hago click con identificador "$.COOKIES.btn_aceptar" 6371\`\`\` 6372 6373### Flujo alternativo según estado 6374 6375\`\`\`gherkin 6376When si el elemento "error" es visible con identificador "$.LOGIN.msg_error" hago click en "reintentar" con identificador "$.LOGIN.btn_retry" 6377When si el elemento "error" no es visible con identificador "$.LOGIN.msg_error" hago click en "continuar" con identificador "$.LOGIN.btn_next" 6378\`\`\` 6379 6380### Esperar popup con timeout 6381 6382\`\`\`gherkin 6383When si el elemento "alerta" aparece en "5" segundos hago click con identificador "$.PAGE.btn_cerrar_alerta" 6384\`\`\` 6385 6386### Condicional por URL 6387 6388\`\`\`gherkin 6389When si la url contiene "login" navego a "\${ENV.BASE_URL}/dashboard" 6390\`\`\` 6391 6392### Condicional por variable 6393 6394\`\`\`gherkin 6395When evalúo si el elemento "descuento" es visible con identificador "$.CART.badge" y guardo en "hay_descuento" 6396And si la variable "hay_descuento" es "true" hago click en "aplicar" con identificador "$.CART.btn_aplicar" 6397\`\`\` 6398 6399### Marcar checkbox solo si no está marcado 6400 6401\`\`\`gherkin 6402When si el checkbox "términos" no está marcado con identificador "$.FORM.chk_terminos" lo marco 6403\`\`\` 6404 6405--- 6406 6407## Notas Importantes 6408 6409- **No fallan:** Si la condición no se cumple, el step pasa exitosamente sin ejecutar la acción. 6410- **Timeout corto (3s):** Por defecto se espera 3 segundos para verificar la condición. 6411- **Timeout personalizado:** Los steps con \`aparece en "{seconds}" segundos\` permiten definir cuánto esperar. 6412- **Variables:** Todos los textos y URLs se resuelven con \`\${variable}\` antes de usarse. 6413- **Case-insensitive:** Las comparaciones de texto (\`contiene\`) no distinguen mayúsculas/minúsculas.`},{id:"steps-playwright-moderno",title:"Inventario: Capacidades Modernas (Playwright 2026)",content:`## Capacidades Modernas de Playwright (2026) 6414 6415Pasos que aprovechan APIs recientes de Playwright para IA/agentes, accesibilidad 6416y control fino de interacciones. Las capacidades base requieren **Playwright 64171.61+**; el click sin desplazamiento requiere **Playwright 1.62+** (el paso 6418detecta la versión y avisa si es menor, sin romper el framework). 6419 6420### ARIA snapshot (IA / agentes / validación estructural) 6421 6422step: capturo el aria snapshot de la página en la variable "{variable_name}" 6423descripcion: Captura el árbol de accesibilidad (ARIA snapshot) de la página en una variable. Ãtil para depurar, aserciones estructurales o alimentar un agente/LLM. 6424 6425step: capturo el aria snapshot con coordenadas de la página en la variable "{variable_name}" 6426descripcion: Igual que el anterior pero anexa coordenadas [box=x,y,w,h] a cada nodo, para que agentes visuales/LLMs ubiquen espacialmente los elementos. 6427 6428step: capturo el aria snapshot del elemento "{element_name}" en la variable "{variable_name}" con identificador "{identifier}" 6429descripcion: Captura el ARIA snapshot acotado a un elemento (subárbol) en una variable. 6430 6431step: la estructura de la página deberÃa coincidir con el aria snapshot 6432descripcion: Valida la estructura de la página completa contra un ARIA snapshot esperado (formato YAML de Playwright) provisto como bloque de texto (docstring) debajo del paso. 6433 6434### Espera por función JavaScript 6435 6436step: espero hasta que se cumpla la función JavaScript "{expression}" 6437descripcion: Detiene la ejecución hasta que una función/expresión JavaScript evaluada en el navegador devuelva un valor verdadero. 6438 6439### CSS en pseudo-elementos (::before / ::after) 6440 6441step: verifico que el pseudo-elemento "{pseudo}" del elemento "{element_name}" tiene el CSS "{prop}" igual a "{value}" con identificador "{identifier}" 6442descripcion: Verifica una propiedad CSS aplicada en un pseudo-elemento (::before o ::after). El pseudo debe ser "before" o "after". 6443 6444### Drop nativo HTML5 6445 6446step: suelto el archivo "{file_path}" en el elemento "{element_name}" con identificador "{identifier}" 6447descripcion: Suelta (drag & drop nativo HTML5) un archivo sobre un elemento, simulando dragenter/dragover/drop que esperan las zonas de carga modernas. 6448 6449step: suelto el texto "{text}" en el elemento "{element_name}" con identificador "{identifier}" 6450descripcion: Suelta (drag & drop nativo HTML5) texto plano sobre un elemento. 6451
6452### Accesibilidad y control de scroll 6453 6454step: hago click en el elemento con rol "{role}" y descripción "{description}" 6455descripcion: Hace click en un elemento localizado por su rol ARIA y su descripción accesible (get_by_role con filtro description). 6456 6457step: hago click en el elemento "{element_name}" sin desplazamiento con identificador "{identifier}" 6458descripcion: Hace click en un elemento SIN el auto-scroll por defecto de Playwright (scroll="none"). Ãtil con headers/footers sticky o listas virtualizadas. Requiere Playwright 1.62+. 6459 6460## Ejemplo 6461 6462\`\`\`gherkin 6463@PlaywrightModerno 6464Scenario: Estructura accesible + espera por estado de la app 6465 Given voy a la url "\${ENV.BASE_URL}/dashboard" 6466 When capturo el aria snapshot con coordenadas de la página en la variable "mapa_espacial" 6467 And espero hasta que se cumpla la función JavaScript "() => window.appReady === true" 6468 Then la estructura de la página deberÃa coincidir con el aria snapshot 6469 """ 6470 - heading "Panel de control" [level=1] 6471 - button "Ingresar" 6472 """ 6473\`\`\``}]},{id:"pruebas-api",title:"Pruebas API",group:"Tipos de Prueba",icon:"",topics:[{id:"api-configuracion",title:"Configuración API",content:`## Configurar una Sesión API 6474 6475Antes de enviar peticiones, puedes configurar headers persistentes, autenticación y URL base que se aplican a todas las peticiones del escenario. 6476 6477\`\`\`gherkin 6478Given configuro la API base en "\${ENV.API_BASE_URL}" 6479And configuro el header "Accept" con valor "application/json" 6480And configuro el header "Content-Type" con valor "application/json" 6481And configuro el token Bearer "\${ENV.API_TOKEN}" 6482\`\`\` 6483 6484## Tipos de Autenticación 6485 6486\`\`\`gherkin 6487# Bearer Token 6488Given configuro el token Bearer "mi_token_secreto" 6489 6490# Basic Auth 6491Given configuro autenticacion basica usuario "admin" contrasena "password123" 6492 6493# API Key en header personalizado 6494Given configuro API key en el header "X-API-Key" con valor "\${ENV.API_KEY}" 6495\`\`\` 6496 6497## Consideraciones 6498 6499- Los headers configurados persisten durante todo el escenario. 6500- \`limpio los headers de sesion API\` resetea todos los headers. 6501- Para pruebas sin navegador, usa el tag \`@no_browser\` en el Feature. 6502- Las variables \`\${ENV.X}\` se resuelven desde el \`.env\`.`},{id:"api-peticiones",title:"Peticiones HTTP",content:`## Peticiones GET 6503 6504\`\`\`gherkin 6505When realizo GET a "https://api.miapp.com/users/1" 6506Then la respuesta deberia tener codigo "200" 6507And el campo "name" de la respuesta deberia ser "Juan" 6508\`\`\` 6509 6510## GET con Query Parameters 6511 6512\`\`\`gherkin 6513When realizo GET con parametros '{"page":"1","limit":"10"}' a "\${ENV.API_BASE_URL}/users" 6514Then la respuesta deberia tener codigo "200" 6515\`\`\` 6516 6517## POST Inline 6518 6519\`\`\`gherkin 6520When realizo POST a "\${ENV.API_BASE_URL}/users" con body '{"name": "Ana", "email": "[email protected]"}' 6521Then la respuesta deberia tener codigo "201" 6522And el campo "id" de la respuesta no deberia estar vacio 6523\`\`\` 6524 6525## POST con DocString (JSON multilÃnea) 6526 6527\`\`\`gherkin 6528When envio JSON body a "\${ENV.API_BASE_URL}/users" via POST 6529 """ 6530 { 6531 "name": "Ana GarcÃa", 6532 "email": "[email protected]", 6533 "role": "admin", 6534 "permissions": ["read", "write", "delete"] 6535 } 6536 """ 6537Then la respuesta deberia tener codigo "201" 6538\`\`\` 6539 6540## POST desde archivo externo 6541 6542\`\`\`gherkin 6543When cargo y envio POST a "\${ENV.API_BASE_URL}/users" con body del archivo "payloads/crear_usuario.json" 6544Then la respuesta deberia tener codigo "201" 6545\`\`\` 6546 6547## PUT, PATCH, DELETE 6548 6549\`\`\`gherkin 6550When realizo PUT a "\${ENV.API_BASE_URL}/users/1" con body '{"name": "Ana Actualizada"}' 6551When realizo PATCH a "\${ENV.API_BASE_URL}/users/1" con body '{"status": "active"}' 6552When realizo DELETE a "\${ENV.API_BASE_URL}/users/1" 6553\`\`\` 6554 6555## Ejecutar cURL 6556 6557\`\`\`gherkin 6558When ejecuto la peticion curl y guardo respuesta en "resultado" 6559 """ 6560 curl -X POST https://api.ejemplo.com/auth/login \\ 6561 -H "Content-Type: application/json" \\ 6562 -d '{"email": "[email protected]", "password": "123456"}' 6563 """ 6564\`\`\``},{id:"api-validaciones",title:"Validaciones API",content:`## Validar Código de Estado 6565 6566\`\`\`gherkin 6567Then la respuesta deberia tener codigo "200" 6568Then verifico que el estado de respuesta API está en el rango "200" a "299" 6569\`\`\` 6570 6571## Validar Campos JSON 6572 6573\`\`\`gherkin
6574Then el campo "data.user.name" de la respuesta deberia ser "Juan" 6575Then el campo "data.user.email" de la respuesta deberia contener "@empresa" 6576Then el campo "data.token" de la respuesta no deberia estar vacio 6577Then el campo "data.deletedAt" de la respuesta deberia ser nulo 6578\`\`\` 6579 6580## Validar Arrays 6581 6582\`\`\`gherkin 6583Then la respuesta deberia ser un array JSON 6584Then el array "data.items" de la respuesta deberia tener "5" elementos 6585Then el arreglo "$.data.users" deberia tener al menos "1" elementos 6586\`\`\` 6587 6588## Validar con JSONPath 6589 6590\`\`\`gherkin 6591Then existe el campo "$.data.user.id" en la respuesta 6592Then el campo "$.data.user.id" en la respuesta es de tipo "integer" 6593Then verifico que el campo "$.data.price" en la respuesta vale "99.99" 6594Then el campo "$.data.email" en la respuesta coincide con el patron "^[\\w.]+@[\\w]+\\.[a-z]{2,}$" 6595\`\`\` 6596 6597## Validar contra Schema JSON 6598 6599\`\`\`gherkin 6600Then verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/usuario_schema.json" 6601\`\`\` 6602 6603## Validar contra Respuesta Esperada 6604 6605\`\`\`gherkin 6606Then verifico que el JSON de respuesta API coincide exactamente con el archivo "expected/usuario_esperado.json" 6607Then verifico que el JSON de respuesta API coincide con el archivo "expected/lista.json" ignorando orden 6608Then verifico que el JSON de respuesta API coincide con el archivo "expected/user.json" ignorando campos "id,createdAt,updatedAt" 6609\`\`\` 6610 6611## Validar Performance 6612 6613\`\`\`gherkin 6614Then verifico que el tiempo de respuesta de la API es menor a "3" segundos 6615Then el tiempo de respuesta deberia ser menor a "500" milisegundos 6616\`\`\``},{id:"api-custom-steps",title:"Custom Steps API",content:`## Crear Custom Steps de API 6617 6618Puedes crear pasos personalizados que combinan múltiples operaciones API. 6619 6620\`\`\`python 6621from behave import step 6622 6623@step('obtengo el token de autenticación para "{user}" con clave "{password}"') 6624def step_get_auth_token(context, user, password): 6625 context.api_session.set_header("Content-Type", "application/json") 6626 response = context.api_session.post( 6627 f"{context.env.get('API_BASE_URL')}/auth/login", 6628 json={"email": user, "password": password} 6629 ) 6630 assert response.status_code == 200, f"Login falló: {response.status_code}" 6631 token = response.json()["data"]["token"] 6632 context.variable_manager.set_variable("auth_token", token) 6633 context.api_session.set_header("Authorization", f"Bearer {token}") 6634\`\`\` 6635 6636## Ejemplo: CRUD completo 6637 6638\`\`\`python 6639@step('creo un usuario con datos de prueba y guardo su ID') 6640def step_create_test_user(context): 6641 import random, string 6642 random_suffix = ''.join(random.choices(string.ascii_lowercase, k=5)) 6643 payload = { 6644 "name": f"Test User {random_suffix}", 6645 "email": f"test_{random_suffix}@qa.com", 6646 "role": "tester" 6647 } 6648 response = context.api_session.post( 6649 f"{context.env.get('API_BASE_URL')}/users", 6650 json=payload 6651 ) 6652 assert response.status_code == 201 6653 user_id = response.json()["data"]["id"] 6654 context.variable_manager.set_variable("created_user_id", str(user_id)) 6655\`\`\` 6656 6657## Consideraciones 6658 6659- Los custom steps API tienen acceso a \`context.api_session\` para realizar peticiones. 6660- Usa \`context.variable_manager.set_variable()\` para guardar datos entre steps. 6661- \`context.env.get('KEY')\` accede a las variables del \`.env\`. 6662- Puedes combinar steps web y API en un mismo escenario (flujo E2E).`},{id:"steps-api-config",title:"Inventario: Configuración",content:`## Inventario: Configuración de API 6663 6664step: configuro la API base en "{base_url}" 6665descripcion: Establece la URL base para todas las peticiones API del escenario. Las peticiones posteriores usarán esta URL como prefijo. 6666 6667step: configuro el header "{name}" con valor "{value}" 6668descripcion: Agrega o actualiza un header persistente que se enviará en todas las peticiones API del escenario. Ãtil para Content-Type, Accept, etc. 6669 6670step: configuro el token Bearer "{token}" 6671descripcion: Configura autenticación Bearer Token para todas las peticiones del escenario. Agrega automáticamente el header Authorization con el prefijo "Bearer". 6672 6673step: configuro autenticacion basica usuario "{username}" contrasena "{password}" 6674descripcion: Configura autenticación Basic Auth codificando usuario y contraseña en Base64. Se aplica a todas las peticiones del escenario. 6675 6676step: configuro API key en el header "{header_name}" con valor "{api_key}" 6677descripcion: Configura autenticación mediante API Key en un header personalizado. Permite especificar el nombre del header donde se enviará la clave. 6678 6679step: configuro headers de API 6680descripcion: Configura múltiples headers de una vez usando un DocString JSON en el feature. Permite definir varios headers en un solo paso sin repetir el paso por cada uno. 6681 6682step: limpio los headers de sesion API 6683descripcion: Elimina todos los headers configurados para la sesión actual. Ãtil para resetear la configuración entre escenarios o cuando se necesita cambiar de contexto de autenticación. 6684 6685step: establezco la URL base de API a "{base_url}" 6686descripcion: Establece una URL base para las peticiones API. Las peticiones a endpoints relativos se
6686concatenarán con esta URL base. 6687 6688step: establezco el header de API "{header_name}" a "{header_value}" 6689descripcion: Establece un header individual para las próximas peticiones API. El valor puede contener variables del framework que se resolverán al momento de enviar. 6690 6691step: establezco el timeout de API a "{timeout}" segundos 6692descripcion: Establece el tiempo máximo de espera para las peticiones API en segundos. Si una petición excede este tiempo, se lanzará un error de timeout. 6693 6694step: limpio todos los datos de sesión API 6695descripcion: Limpia completamente la sesión API incluyendo headers, URL base, timeout y última respuesta. Resetea todo el estado de la sesión API.`},{id:"steps-api-peticiones",title:"Inventario: Peticiones",content:`## Inventario: Peticiones GET 6696 6697step: realizo GET a "{url}" 6698descripcion: EnvÃa una petición GET usando los headers de sesión configurados previamente. La URL puede ser absoluta o relativa a la URL base configurada. 6699 6700step: realizo GET con parametros "{params}" a "{url}" 6701descripcion: EnvÃa una petición GET con query parameters. Los parámetros se pasan como JSON (ej: {"page":"1","limit":"10"}) y se agregan a la URL automáticamente. 6702 6703step: envÃo petición GET a "{url}" y guardo la respuesta en la variable "{variable_name}" 6704descripcion: EnvÃa una petición GET y guarda la respuesta completa (status, headers, body, json) en una variable del framework para uso posterior. 6705 6706step: envÃo petición GET al endpoint "{endpoint}" y guardo la respuesta en la variable "{variable_name}" 6707descripcion: EnvÃa una petición GET concatenando la URL base configurada con el endpoint relativo. Guarda la respuesta en una variable. 6708 6709step: envÃo petición GET autenticada a "{url}" con token "{token}" y guardo la respuesta en la variable "{variable_name}" 6710descripcion: EnvÃa una petición GET con autenticación Bearer Token. El token se incluye en el header Authorization y la respuesta se guarda en una variable. 6711 6712## Inventario: Peticiones POST/PUT/PATCH/DELETE 6713 6714step: realizo POST a "{url}" con body "{body}" 6715descripcion: EnvÃa una petición POST con body inline. Si el body es JSON válido se envÃa como application/json, de lo contrario como texto plano. 6716 6717step: realizo PUT a "{url}" con body "{body}" 6718descripcion: EnvÃa una petición PUT con body inline. Detecta automáticamente si el body es JSON para establecer el Content-Type adecuado. 6719 6720step: realizo PATCH a "{url}" con body "{body}" 6721descripcion: EnvÃa una petición PATCH con body inline. Ãtil para actualizaciones parciales de recursos REST. 6722 6723step: realizo DELETE a "{url}" 6724descripcion: EnvÃa una petición DELETE usando los headers de sesión configurados. No requiere body. 6725 6726step: envÃo petición POST a "{url}" con cuerpo "{body}" y guardo la respuesta en la variable "{variable_name}" 6727descripcion: EnvÃa una petición POST con cuerpo y guarda la respuesta completa en una variable. Detecta automáticamente si el body es JSON. 6728 6729step: envÃo petición PUT a "{url}" con cuerpo "{body}" y guardo la respuesta en la variable "{variable_name}" 6730descripcion: EnvÃa una petición PUT con cuerpo y guarda la respuesta completa en una variable del framework. 6731 6732step: envÃo petición PATCH a "{url}" con cuerpo "{body}" y guardo la respuesta en la variable "{variable_name}" 6733descripcion: EnvÃa una petición PATCH con cuerpo y guarda la respuesta completa en una variable del framework. 6734 6735step: envÃo petición DELETE a "{url}" y guardo la respuesta en la variable "{variable_name}" 6736descripcion: EnvÃa una petición DELETE y guarda la respuesta completa en una variable del framework. 6737 6738step: envÃo petición HEAD a "{url}" y guardo la respuesta en la variable "{variable_name}" 6739descripcion: EnvÃa una petición HEAD (solo obtiene headers, sin body) y guarda la respuesta en una variable. 6740 6741step: envÃo petición OPTIONS a "{url}" y guardo la respuesta en la variable "{variable_name}" 6742descripcion: EnvÃa una petición OPTIONS para consultar los métodos HTTP permitidos y configuración CORS del endpoint. 6743 6744step: envÃo petición multipart form a "{url}" con campos "{fields}" y guardo la respuesta en la variable "{variable_name}" 6745descripcion: EnvÃa una petición multipart/form-data con campos especificados como JSON. Ãtil para enviar formularios con múltiples campos. 6746 6747step: subo archivo "{file_path}" al endpoint API "{url}" con nombre de campo "{field_name}" y guardo la respuesta en la variable "{variable_name}" 6748descripcion: Sube un archivo a un endpoint API usando multipart/form-data. Permite especificar el nombre del campo del formulario para el archivo. 6749 6750step: subo archivo "{file_path}" a "{url}" en campo "{field_name}" 6751descripcion: Versión simplificada para subir un archivo via POST multipart/form-data. Usa los headers de sesión configurados (excepto Content-Type). 6752 6753step: envio form data "{form_data}" a "{url}" 6754descripcion: EnvÃa un POST con application/x-www-form-urlencoded. Los datos se pasan como JSON que se convierte a form-data. 6755 6756## Inventario: Peticiones con DocString 6757 6758step: envio JSON body a "{url}" via POST 6759descripcion: EnvÃa un POST con body JSON escrito como DocString multilÃnea en el feature. 6760 6761step: envio JSON body a "{url}" via PUT 6762descripcion: EnvÃa un PUT con body JSON como DocString multilÃnea. 6763 6764step: envio JSON body a "{url}" via PATCH 6765descripcion: EnvÃa un PATCH con body JSON como DocString multilÃnea. 6766 6767step: envio POST a "{url}" y guardo respuesta en "{variable_name}" 6768descripcion: EnvÃa un POST con body como DocString y guarda la respuesta completa en una variable. 6769 6770step: envio PUT a "{url}" y guardo respuesta en "{variable_name}" 6771descripcion: EnvÃa un PUT con body como DocString y guarda la respuesta en una variable del framework. 6772 6773step: envio PATCH a "{url}" y guardo respuesta en "{variable_name}" 6774descripcion: EnvÃa un PATCH con body como DocString y guarda la respuesta en una variable del framework. 6775 6776step: envio DELETE a "{url}" y guardo respuesta en "{variable_name}"
6777descripcion: EnvÃa un DELETE y guarda la respuesta en una variable. Opcionalmente acepta body como DocString. 6778 6779## Inventario: Peticiones desde archivo 6780 6781step: cargo y envio POST a "{url}" con body del archivo "{file_path}" 6782descripcion: Carga el body desde un archivo JSON externo y envÃa un POST. Ãtil para payloads grandes. 6783 6784step: cargo y envio PUT a "{url}" con body del archivo "{file_path}" 6785descripcion: Carga el body desde un archivo JSON externo y envÃa un PUT. Las variables del framework dentro del archivo se resuelven automáticamente. 6786 6787step: cargo y envio PATCH a "{url}" con body del archivo "{file_path}" 6788descripcion: Carga el body desde un archivo JSON externo y envÃa un PATCH. Soporta resolución de variables dentro del contenido del archivo. 6789 6790step: envio POST desde archivo "{file_path}" a "{url}" y guardo respuesta en "{variable_name}" 6791descripcion: Carga el body desde un archivo, envÃa POST y guarda la respuesta en una variable. 6792 6793step: envio PUT desde archivo "{file_path}" a "{url}" y guardo respuesta en "{variable_name}" 6794descripcion: Carga el body desde un archivo, envÃa PUT y guarda la respuesta en una variable del framework. 6795 6796step: envio PATCH desde archivo "{file_path}" a "{url}" y guardo respuesta en "{variable_name}" 6797descripcion: Carga el body desde un archivo, envÃa PATCH y guarda la respuesta en una variable del framework. 6798 6799step: cargo el cuerpo de petición API del archivo "{file_path}" y envÃo POST a "{url}" guardando respuesta en variable "{variable_name}" 6800descripcion: Carga el cuerpo de petición desde un archivo (JSON o texto plano) y envÃa POST. Detecta automáticamente el formato del contenido. 6801 6802step: cargo JSON del archivo "{file_path}" y envÃo POST a "{url}" guardando respuesta en variable "{variable_name}" 6803descripcion: Carga un archivo JSON y envÃa POST al endpoint especificado. Guarda la respuesta completa incluyendo status, headers y body en una variable. 6804 6805step: envÃo peticiones API en lote desde archivo "{requests_file}" y guardo resultados en variable "{variable_name}" 6806descripcion: EnvÃa múltiples peticiones API definidas en un archivo JSON de configuración. Los resultados se guardan como array. 6807 6808## Inventario: Peticiones cURL 6809 6810step: ejecuto la peticion curl y guardo respuesta en "{variable_name}" 6811descripcion: Ejecuta una petición parseando un comando cURL desde DocString. Soporta -X (método), -H (headers), -d (body), URLs y continuación de lÃnea con barra invertida. 6812 6813step: ejecuto la peticion curl del archivo "{file_path}" y guardo respuesta en "{variable_name}" 6814descripcion: Lee un comando cURL desde un archivo de texto y lo ejecuta. Ãtil para reutilizar comandos cURL exportados desde Postman o el navegador. 6815 6816## Inventario: Interceptación de llamadas API del navegador 6817 6818step: inicio la escucha de llamadas a API 6819descripcion: Activa listeners en el navegador para capturar todas las llamadas API (requests y responses) en background. 6820 6821step: detengo la escucha de llamadas a API 6822descripcion: Desactiva los listeners de captura de llamadas API del navegador. 6823 6824step: detengo la interceptación de llamadas a API 6825descripcion: Detiene la interceptación de rutas del navegador (unroute). Libera el control sobre las peticiones del navegador. 6826 6827step: verifico que se realizó una llamada a la API en "{api_url}" 6828descripcion: Verifica que se capturó una llamada a una URL especÃfica (búsqueda parcial). 6829 6830step: verifico que se realizó una llamada a la API "{api_url}" usando método "{method}" 6831descripcion: Verifica que se realizó una llamada a una API con un método HTTP especÃfico. 6832 6833step: verifico que la llamada a API contiene el parámetro "{parameter}" con valor "{value}" 6834descripcion: Verifica que la última llamada interceptada contiene un parámetro especÃfico con el valor esperado en el body JSON. 6835 6836step: verifico que la llamada a API contiene el header "{header_name}" con valor "{header_value}" 6837descripcion: Verifica que la última llamada interceptada contiene un header especÃfico con el valor esperado. 6838 6839step: verifico que el número de llamadas a la API "{api_url}" es "{expected_count}" 6840descripcion: Verifica que se realizó un número exacto de llamadas a una URL especÃfica. 6841 6842step: verifico que NO se realizó una llamada a la API "{api_url}" 6843descripcion: Verifica que NO se capturó ninguna llamada a una URL especÃfica. 6844 6845step: guardo los datos de la llamada a API en la variable "{variable_name}" 6846descripcion: Guarda los datos completos de la última llamada interceptada (URL, método, headers, body) en una variable del framework. 6847 6848step: limpio las llamadas a API interceptadas 6849descripcion: Limpia el registro de llamadas interceptadas.`},{id:"steps-api-validaciones",title:"Inventario: Validaciones",content:`## Inventario: Validaciones de código de estado 6850 6851step: la respuesta deberia tener codigo "{expected_status}" 6852descripcion: Verifica que el código de estado HTTP de la última respuesta coincide exactamente con el valor esperado. 6853 6854step: verifico que el código de estado de la respuesta API es "{expected_status}" 6855descripcion: Verifica el código de estado de la última respuesta API. Muestra el código actual vs esperado en caso de fallo. 6856 6857step: verifico que el estado de respuesta API está en el rango "{min_status}" a "{max_status}" 6858descripcion: Verifica que el código de estado está dentro de un rango numérico (ej: 200-299 para éxito). 6859 6860step: verifico que la respuesta API sigue las convenciones REST para el método "{http_method}" 6861descripcion: Verifica que el código de estado sigue las convenciones REST según el método HTTP (GETâ200, POSTâ201, PUT/DELETEâ200/204). 6862 6863## Inventario: Validaciones de headers 6864 6865step: verifico que el header de respuesta API "{header_name}" es igual a "{expected_value}" 6866descripcion: Verifica que un header de respuesta tiene exactamente el valor esperado. 6867 6868step: verifico que el header de respuesta API "{header_name}" contiene "{expected_text}" 6869descripcion: Verifica que un header de respuesta contiene un texto parcial. 6870 6871step: verifico que el tipo de contenido de respuesta API es "{expected_content_type}" 6872descripcion: Verifica que el Content-Type de la respuesta contiene el tipo esperado. 6873 6874step: verifico que los headers de rate limit están presentes en la respuesta API 6875descripcion: Verifica la presencia de headers de rate limiting (X-RateLimit-Limit, X-RateLimit-Remaining, etc.). 6876 6877step: verifico que la respuesta API tiene headers de seguridad 6878descripcion: Verifica la presencia de headers de seguridad importantes (X-Content-Type-Options, X-Frame-Options, HSTS, CSP, etc.). 6879 6880## Inventario: Validaciones de body y contenido 6881 6882step: verifico que la respuesta API es JSON válido 6883descripcion: Verifica que el cuerpo de la respuesta puede parsearse como JSON válido. 6884 6885step: verifico que la respuesta API contiene "{key}" con valor "{expected_value}" 6886descripcion: Verifica que la respuesta JSON contiene una clave con un valor especÃfico. Soporta notación de punto para claves anidadas. 6887 6888step: verifico que el cuerpo de respuesta API contiene el texto "{expected_text}" 6889descripcion: Verifica que el body de la respuesta (como texto plano) contiene un texto especÃfico. 6890 6891step: verifico que el array JSON de respuesta API tiene "{expected_length}" elementos 6892descripcion: Verifica que la respuesta es un array JSON con exactamente la cantidad de elementos indicada. 6893 6894step: verifico que el elemento "{index}" del array JSON tiene "{key}" con valor "{expected_value}" 6895descripcion: Verifica que un elemento especÃfico de un array JSON (por Ãndice) tiene un campo con el valor esperado. 6896 6897step: la respuesta deberia ser un array JSON 6898descripcion: Verifica que la respuesta completa es un array JSON (lista). Informa la cantidad de elementos. 6899 6900step: la respuesta deberia ser un objeto JSON 6901descripcion: Verifica que la respuesta completa es un objeto JSON (diccionario). Informa la cantidad de campos. 6902 6903step: el body de la respuesta deberia estar vacio 6904descripcion: Verifica que el cuerpo de la respuesta está vacÃo. Ãtil para validar respuestas 204 No Content. 6905 6906step: verifico que la respuesta API tiene paginación con total "{expected_total}" y página "{expected_page}" 6907descripcion: Verifica información de paginación buscando campos comunes (total, totalCount, page, currentPage) en la respuesta JSON. 6908 6909## Inventario: Validaciones de campos (notación de punto) 6910 6911step: el campo "{field_path}" de la respuesta deberia ser "{expected_value}" 6912descripcion: Verifica que un campo del JSON tiene el valor exacto esperado. Soporta notación de punto para campos anidados. 6913 6914step: el campo "{field_path}" de la respuesta deberia contener "{expected_value}" 6915descripcion: Verifica que un campo del JSON contiene un valor parcial (búsqueda de substring). 6916 6917step: el campo "{field_path}
6917" de la respuesta no deberia estar vacio 6918descripcion: Verifica que un campo no está vacÃo (no es None, string vacÃo ni lista vacÃa). 6919 6920step: el campo "{field_path}" de la respuesta deberia ser nulo 6921descripcion: Verifica que un campo es null/None en la respuesta JSON. 6922 6923step: el campo "{field_path}" deberia existir en la respuesta 6924descripcion: Verifica que un campo existe en el JSON de respuesta, sin importar su valor. 6925 6926step: el array "{field_path}" de la respuesta deberia tener "{count}" elementos 6927descripcion: Verifica que un array dentro de la respuesta tiene exactamente N elementos. 6928 6929step: el array "{field_path}" de la respuesta deberia tener al menos "{count}" elementos 6930descripcion: Verifica que un array dentro de la respuesta tiene al menos N elementos. 6931 6932## Inventario: Validaciones JSONPath 6933 6934step: existe el campo "{jsonpath}" en la respuesta 6935descripcion: Verifica que un campo existe en la respuesta usando notación JSONPath (ej: "$.data.user.id"). 6936 6937step: no existe el campo "{jsonpath}" en la respuesta 6938descripcion: Verifica que un campo NO existe en la respuesta usando notación JSONPath. 6939 6940step: el campo "{jsonpath}" en la respuesta es de tipo "{expected_type}" 6941descripcion: Verifica el tipo de un campo usando JSONPath. Tipos soportados: string, number, integer, boolean, array, object, null. 6942 6943step: verifico que el campo "{jsonpath}" en la respuesta vale "{expected_value}" 6944descripcion: Verifica que un campo JSONPath tiene el valor exacto esperado. 6945 6946step: verifico que el campo "{jsonpath}" en la respuesta contiene "{expected_value}" 6947descripcion: Verifica que un campo JSONPath contiene un valor parcial. 6948 6949step: el campo "{jsonpath}" en la respuesta es nulo 6950descripcion: Verifica que un campo JSONPath es null/None. 6951 6952step: el campo "{jsonpath}" en la respuesta no es nulo 6953descripcion: Verifica que un campo JSONPath no es null. 6954 6955step: el campo "{jsonpath}" en la respuesta esta vacio 6956descripcion: Verifica que un campo JSONPath está vacÃo (None, string vacÃo, lista vacÃa o diccionario vacÃo). 6957 6958step: el campo "{jsonpath}" en la respuesta no esta vacio 6959descripcion: Verifica que un campo JSONPath no está vacÃo. 6960 6961step: el campo "{jsonpath}" en la respuesta es mayor que "{expected_value}" 6962descripcion: Verifica que un campo numérico JSONPath es estrictamente mayor que el valor esperado. 6963 6964step: el campo "{jsonpath}" en la respuesta es menor que "{expected_value}" 6965descripcion: Verifica que un campo numérico JSONPath es estrictamente menor que el valor esperado. 6966 6967step: el campo "{jsonpath}" en la respuesta esta entre "{min_value}" y "{max_value}" 6968descripcion: Verifica que un campo numérico JSONPath está dentro del rango [min, max] inclusive. 6969 6970step: el campo "{jsonpath}" en la respuesta coincide con el patron "{pattern}" 6971descripcion: Verifica que un campo JSONPath coincide con una expresión regular. 6972 6973## Inventario: Validaciones de arrays JSONPath 6974 6975step: el arreglo "{jsonpath}" deberia tener "{count}" elementos 6976descripcion: Verifica que un array JSONPath tiene exactamente N elementos. 6977 6978step: el arreglo "{jsonpath}" deberia tener al menos "{count}" elementos 6979descripcion: Verifica que un array JSONPath tiene al menos N elementos. 6980 6981step: en el arreglo "{jsonpath}" en la posicion "{index}" encuentro "{field_path}" con valor "{expected_value}" 6982descripcion: Verifica el valor de un campo en un elemento especÃfico de un array JSONPath. 6983 6984step: en el arreglo "{jsonpath}" en la posicion "{index}" encuentro el campo "{field_path}" 6985descripcion: Verifica que un campo existe en un elemento especÃfico de un array JSONPath. 6986 6987step: el arreglo "{jsonpath}" deberia contener un elemento con "{field_path}" igual a "{expected_value}" 6988descripcion: Busca en todo el array si al menos un elemento tiene un campo con el valor esperado. 6989 6990step: todos los elementos del arreglo "{jsonpath}" deberian tener el campo "{field_path}" 6991descripcion: Verifica que todos los elementos de un array JSONPath tienen un campo especÃfico. 6992 6993step: guardo el campo JSONPath "{jsonpath}" de la respuesta en la variable "{variable_name}" 6994descripcion: Extrae un valor usando JSONPath y lo guarda en una variable del framework. 6995 6996## Inventario: Validaciones avanzadas de JSON 6997 6998step: verifico que el JSON de respuesta API coincide con el esquema del archivo "{schema_file}" 6999descripcion: Valida la respuesta JSON contra un JSON Schema (Draft 7) cargado desde archivo. 7000 7001step: verifico que el JSON de respuesta API coincide exactamente con el archivo "{expected_file}" 7002descripcion: Compara la respuesta JSON byte a byte con el contenido de un archivo. 7003 7004step: verifico que el JSON de respuesta API coincide con el archivo "{expected_file}" ignorando orden 7005descripcion: Compara la respuesta JSON con un archivo ignorando el orden de los elementos en arrays. 7006 7007step: verifico que el JSON de respuesta API coincide con el archivo "{expected_file}" ignorando campos "{ignored_fields}" 7008descripcion: Compara la respuesta JSON con un archivo excluyendo campos especÃficos (separados por coma). 7009 7010step: verifico que el JSON de respuesta API tiene el campo "{field_path}" con tipo "{expected_type}" 7011descripcion: Verifica que un campo especÃfico tiene el tipo de dato esperado. 7012 7013step: verifico que el campo "{field_path}" del JSON de respuesta API coincide con el patrón "{pattern}" 7014descripcion: Verifica que un campo de la respuesta coincide con una expresión regular. 7015 7016step: verifico que el campo "{field_path}" del JSON de respuesta API está en el rango {min_value} a {max_value} 7017descripcion: Verifica que un campo numérico está dentro de un rango especÃfico [min, max]. 7018 7019step: verifico que el array "{array_path}" del JSON de respuesta API contiene un elemento con "{field}" igual a "{value}" 7020descripcion: Busca en un array JSON si existe al menos un elemento cuyo campo especificado tiene el valor indicado. 7021 7022step: verifico que todos los elementos del array "{array_path}" del JSON de respuesta API tienen el campo "{field}" 7023descripcion: Verifica que cada elemento del array tiene un campo especÃfico. 7024 7025step: verifico que el JSON de respuesta API no tiene valores nulos 7026descripcion: Recorre recursivamente toda la respuesta JSON buscando valores null. 7027 7028step: verifico que el esquema JSON de respuesta API coincide con el archivo "{schema_file}" 7029descripcion: Validación básica de esquema JSON verificando tipos y propiedades. 7030 7031step: verifico que la respuesta API coincide con la respuesta esperada del ar
7031chivo "{expected_file}" 7032descripcion: Compara la respuesta JSON completa con un archivo de respuesta esperada. 7033 7034## Inventario: Extracción y almacenamiento de datos 7035 7036step: extraigo el valor de la respuesta API "{key}" y lo guardo en la variable "{variable_name}" 7037descripcion: Extrae un valor de la respuesta JSON usando notación de punto y lo guarda en una variable. 7038 7039step: guardo el campo "{field_path}" de la respuesta en la variable "{variable_name}" 7040descripcion: Extrae un campo del JSON de respuesta y lo guarda en una variable. 7041 7042step: guardo el body completo de la respuesta en la variable "{variable_name}" 7043descripcion: Guarda el body completo de la respuesta como string en una variable. 7044 7045step: guardo el status code de la respuesta en la variable "{variable_name}" 7046descripcion: Guarda el código de estado HTTP de la última respuesta en una variable. 7047 7048step: guardo el header "{header_name}" de la respuesta en la variable "{variable_name}" 7049descripcion: Guarda el valor de un header especÃfico de la respuesta en una variable. 7050 7051step: guardo el JSON de respuesta API en el archivo "{file_path}" 7052descripcion: Guarda la respuesta JSON formateada (con indentación) en un archivo. 7053 7054step: guardo el cuerpo de respuesta API en el archivo "{file_path}" 7055descripcion: Guarda el body de la respuesta (como texto) en un archivo. 7056 7057step: obtengo el valor de la respuesta API capturada "{api_url}" en la ruta "{json_path}" y lo guardo en la variable "{variable_name}" 7058descripcion: Extrae un valor de una respuesta API capturada en background por el listener. 7059 7060## Inventario: Rendimiento y carga 7061 7062step: verifico que el tiempo de respuesta de la API es menor a "{max_seconds}" segundos 7063descripcion: Verifica que el tiempo de respuesta de la última petición API no excede el lÃmite en segundos. 7064 7065step: el tiempo de respuesta deberia ser menor a "{max_ms}" milisegundos 7066descripcion: Verifica que el tiempo de respuesta es menor al lÃmite especificado en milisegundos. 7067 7068step: envÃo peticiones API concurrentes "{count}" veces a "{url}" y verifico que todas tengan éxito 7069descripcion: EnvÃa múltiples peticiones GET concurrentes usando threads para testing de carga. 7070 7071step: mido el rendimiento de API para "{iterations}" peticiones a "{url}" y guardo métricas en variable "{variable_name}" 7072descripcion: Ejecuta N peticiones secuenciales midiendo tiempos. Calcula métricas (min, max, promedio, mediana, tasa de error). 7073 7074## Inventario: CORS y seguridad 7075 7076step: verifico que el endpoint API "{endpoint}" soporta CORS 7077descripcion: EnvÃa una petición OPTIONS al endpoint y verifica la presencia de headers CORS. 7078 7079## Inventario: Datos de prueba 7080 7081step: creo datos de prueba API con plantilla "{template}" y valores "{values}" guardando en variable "{variable_name}" 7082descripcion: Crea datos de prueba reemplazando placeholders {{key}} en una plantilla JSON con valores proporcionados.`}]},{id:"pruebas-mobile",title:"Pruebas Mobile",group:"Tipos de Prueba",icon:"",topics:[{id:"mobile-setup",title:"GuÃa de Setup Mobile (Appium)",content:`## Requisitos 7083 7084- Servidor Appium corriendo (\`appium --port 4723\`) 7085- Dispositivo/emulador conectado y visible con \`adb devices\` 7086- App instalada o ruta al APK/IPA disponible 7087 7088## Configuración .env 7089 7090\`\`\`env 7091APPIUM_SERVER_URL=http://localhost:4723 7092APPIUM_PLATFORM_NAME=Android 7093APPIUM_DEVICE_NAME=emulator-5554 7094APPIUM_APP_PACKAGE=com.miapp.android 7095APPIUM_APP_ACTIVITY=.MainActivity 7096APPIUM_AUTOMATION_NAME=UiAutomator2 7097APPIUM_APP_PATH=./app/mi-app.apk 7098APPIUM_TIMEOUT=30000 7099APPIUM_RESET_STRATEGY=noReset 7100\`\`\` 7101 7102## Estrategias de Reset 7103 7104- \`noReset\`: No resetea la app entre tests (mantiene estado). 7105- \`fullReset\`: Desinstala y reinstala la app (estado limpio). 7106- \`fastReset\`: Limpia los datos de la app sin reinstalar. 7107 7108## Ejemplo de Feature 7109 7110\`\`\`gherkin 7111@mobile 7112Feature: Testing de la app mobile 7113 7114 Scenario: Login en la app 7115 Given uso el modo mobile 7116 When escribo texto "[email protected]" en el campo móvil "id:email_input" 7117 And escribo texto "password123" en el campo móvil "id:password_input" 7118 And hago tap simple en el elemento móvil "id:login_button" 7119 Then verifico que el elemento móvil "id:home_screen" es visible 7120\`\`\` 7121 7122## Consideraciones 7123 7124- \`uso el modo mobile\` verifica si la app está instalada y aplica la estrategia de reset configurada. 7125- La sesión se cierra automáticamente al finalizar el escenario. 7126- Puedes combinar pruebas mobile y web en un mismo feature usando \`activo el modo web en el contexto\`.`},{id:"mobile-configuracion",title:"Configuración Mobile",content:`## Tipos de Localizadores Mobile 7127 7128\`\`\` 7129id:mi_elemento â resource-id (Android) / accessibilityIdentifier (iOS) 7130xpath://android.widget.Button[@text='OK'] â XPath 7131accessibility_id:submit â accessibility id 7132class:android.widget.EditText â class name 7133\`\`\` 7134 7135## Variables de Entorno Mobile 7136 7137| Variable | Descripción | Ejemplo | 7138|----------|-------------|---------| 7139| APPIUM_SERVER_URL | URL del servidor Appium | http://localhost:4723 | 7140| APPIUM_PLATFORM_NAME | Plataforma | Android / iOS | 7141| APPIUM_DEVICE_NAME | Nombre del dispositivo | emulator-5554 | 7142| APPIUM_APP_PACKAGE | Package de la app (Android) | com.miapp.android | 7143| APPIUM_APP_ACTIVITY | Activity principal (Android) | .MainActivity | 7144| APPIUM_AUTOMATION_NAME | Motor de automatización | UiAutomator2 / XCUITest |
7145| APPIUM_APP_PATH | Ruta al APK/IPA | ./app/mi-app.apk | 7146| APPIUM_TIMEOUT | Timeout por defecto (ms) | 30000 | 7147| APPIUM_RESET_STRATEGY | Estrategia de reset | noReset / fullReset / fastReset | 7148 7149## Consideraciones 7150 7151- Los localizadores \`id:\` buscan por resource-id en Android y accessibilityIdentifier en iOS. 7152- XPath funciona pero es más lento; preferir id o accessibility_id. 7153- El timeout por defecto se usa en todas las esperas implÃcitas de elementos.`},{id:"mobile-interacciones",title:"Interacciones Mobile",content:`## Taps Básicos 7154 7155\`\`\`gherkin 7156When hago tap simple en el elemento móvil "id:btn_continuar" 7157And hago doble tap en el elemento móvil "id:item_favorito" 7158And hago tap largo simple en el elemento móvil "id:item_lista" 7159And hago tap largo en el elemento móvil "id:item_lista" por "2000" milisegundos 7160\`\`\` 7161 7162## Taps por Texto y Coordenadas 7163 7164\`\`\`gherkin 7165When hago tap en el texto móvil "Aceptar" 7166And hago tap en las coordenadas móvil "200" y "500" 7167And hago tap en el accessibility id "submit_button" 7168\`\`\` 7169 7170## Entrada de Texto 7171 7172\`\`\`gherkin 7173When escribo texto "Juan Pérez" en el campo móvil "id:name_input" 7174And limpio el campo móvil "id:email_input" 7175And agrego texto " Apellido" al campo móvil "id:name_input" 7176And escribo "password" en el campo móvil "id:pass" ocultando teclado 7177\`\`\` 7178 7179## Scroll y Swipe 7180 7181\`\`\`gherkin 7182When hago scroll hacia abajo en el dispositivo 7183And hago scroll hasta el elemento móvil "id:footer" 7184And hago swipe del elemento móvil "id:card" hacia la izquierda 7185And hago swipe desde "100" "500" hasta "100" "200" en el dispositivo 7186\`\`\` 7187 7188## Verificaciones 7189 7190\`\`\`gherkin 7191Then verifico que el elemento móvil "id:welcome" es visible 7192And verifico que el texto del elemento móvil "id:title" es "Bienvenido" 7193And verifico que el elemento móvil "id:btn_submit" está habilitado 7194\`\`\``},{id:"mobile-custom-steps",title:"Custom Steps Mobile",content:`## Crear Custom Steps Mobile 7195 7196\`\`\`python 7197from behave import step 7198 7199@step('hago login mobile con "{user}" y "{password}"') 7200def step_mobile_login(context, user, password): 7201 driver = context.appium_driver 7202 # Limpiar y escribir email 7203 context.mobile_fill("id:email_input", user) 7204 # Limpiar y escribir password 7205 context.mobile_fill("id:password_input", password) 7206 # Tap en botón login 7207 context.mobile_tap("id:login_button") 7208 # Esperar pantalla principal 7209 context.mobile_wait_visible("id:home_screen", timeout=10) 7210\`\`\` 7211 7212## Ejemplo: Navegación con Scroll 7213 7214\`\`\`python 7215@step('busco y selecciono el producto "{product_name}" en la lista') 7216def step_find_product(context, product_name): 7217 max_scrolls = 10 7218 for i in range(max_scrolls): 7219 try: 7220 element = context.mobile_find(f"xpath://*[contains(@text, '{product_name}')]") 7221 if element.is_displayed(): 7222 element.click() 7223 return 7224 except: 7225 context.mobile_scroll_down() 7226 raise AssertionError(f"Producto '{product_name}' no encontrado después de {max_scrolls} scrolls") 7227\`\`\` 7228 7229## Helpers Disponibles 7230 7231- \`context.mobile_tap(locator)\` â Tap en elemento 7232- \`context.mobile_fill(locator, text)\` â Escribir en campo (limpia primero) 7233- \`context.mobile_find(locator)\` â Buscar elemento 7234- \`context.mobile_find_all(locator)\` â Buscar todos los elementos 7235- \`context.mobile_wait_visible(locator, timeout)\` â Esperar elemento visible 7236- \`context.mobile_scroll_down()\` â Scroll hacia abajo 7237- \`context.mobile_scroll_up()\` â Scroll hacia arriba 7238- \`context.mobile_swipe(x1, y1, x2, y2)\` â Swipe entre coordenadas 7239- \`context.appium_driver\` â Acceso directo al driver de Appium`},{id:"mobile-inventario-sesion",title:"Inventario: Sesión",content:`## Conexión y Sesión 7240 7241step: uso el modo mobile 7242descripcion: Inicia el modo mobile leyendo la configuración del .env (APPIUM_*), conecta al dispositivo, verifica si la app está instalada y aplica la estrategia de reset configurada. 7243 7244step: desconecto del dispositivo móvil 7245descripcion: Cierra la sesión Appium activa con el dispositivo. 7246 7247step: reinicio la aplicación móvil 7248descripcion: Reinicia la aplicación sin cerrar la sesión Appium. 7249 7250step: lanzo la aplicación móvil 7251descripcion: Lanza la aplicación configurada en las capacidades de Appium. 7252 7253step: cierro la aplicación móvil 7254descripcion: Cierra la aplicación sin cerrar la sesión Appium. 7255
7256step: instalo la aplicación desde la ruta "{app_path}" 7257descripcion: Instala una aplicación en el dispositivo desde la ruta especificada. 7258 7259step: desinstalo la aplicación móvil 7260descripcion: Desinstala la aplicación actual del dispositivo. 7261 7262step: activo la aplicación móvil en primer plano 7263descripcion: Trae la aplicación actual al primer plano del dispositivo. 7264 7265step: termino la aplicación móvil en segundo plano 7266descripcion: Termina la aplicación actual enviándola a segundo plano. 7267 7268step: abro la aplicación móvil con paquete "{app_id}" 7269descripcion: Abre (activa o lanza) una app por su package en Android (ej: com.android.calculator2) o bundleId en iOS (ej: com.apple.Preferences). La app pasa a ser la "actual" para los pasos siguientes. 7270 7271step: abro la aplicación móvil con bundle "{app_id}" 7272descripcion: Alias del paso anterior; abre una app por su identificador (bundleId de iOS o package de Android). 7273 7274step: abro la aplicación "{name}" desde el dispositivo 7275descripcion: Android â abre una app tocando su Ãcono en el launcher por su nombre visible (ej: "Calculadora", "Ajustes"). Depende del launcher del dispositivo; para máxima fiabilidad usa la apertura por package/bundle id. 7276 7277step: lanzo la actividad "{activity}" del paquete "{package}" 7278descripcion: Android â lanza una actividad especÃfica de un paquete (ej: actividad ".Settings" del paquete "com.android.settings"). 7279 7280step: termino la aplicación móvil con paquete "{app_id}" 7281descripcion: Termina en segundo plano una app especÃfica indicada por su package/bundle id. 7282 7283step: verifico que la aplicación con paquete "{app_id}" está instalada 7284descripcion: Verifica que una app esté instalada en el dispositivo, identificada por su package/bundle id. 7285 7286## Navegación del Dispositivo 7287 7288step: presiono atrás en el dispositivo 7289descripcion: Presiona el botón Atrás del dispositivo. 7290 7291step: presiono el botón home del dispositivo 7292descripcion: Presiona el botón Home del dispositivo. 7293 7294step: abro el panel de notificaciones del dispositivo 7295descripcion: Abre el panel de notificaciones del dispositivo (Android). 7296 7297step: cambio la orientación del dispositivo a "{orientation}" 7298descripcion: Cambia la orientación del dispositivo al valor indicado (PORTRAIT o LANDSCAPE). 7299 7300step: cambio la orientación del dispositivo a horizontal 7301descripcion: Cambia la orientación del dispositivo a modo horizontal (LANDSCAPE). 7302 7303step: cambio la orientación del dispositivo a vertical 7304descripcion: Cambia la orientación del dispositivo a modo vertical (PORTRAIT). 7305 7306step: presiono el botón atrás del dispositivo repetidamente "{n}" veces 7307descripcion: Presiona el botón Atrás del dispositivo N veces consecutivas con una pausa entre cada pulsación. 7308 7309step: activo el modo web en el contexto 7310descripcion: Vuelve al modo web en el framework para pruebas mixtas mobile/web. 7311 7312step: abro la url "{url}" en el navegador del dispositivo 7313descripcion: Abre una URL especÃfica en el navegador del dispositivo móvil. 7314 7315## Contextos y Modo Mixto 7316 7317step: cambio al contexto webview del dispositivo 7318descripcion: Cambia al primer contexto WebView disponible para interactuar con contenido web dentro de la app. 7319 7320step: cambio al contexto webview número "{index}" del dispositivo 7321descripcion: Cambia a un contexto WebView especÃfico por su Ãndice cuando hay múltiples WebViews. 7322 7323step: cambio al contexto nativo del dispositivo 7324descripcion: Cambia al contexto nativo (NATIVE_APP) para interactuar con elementos nativos de la app. 7325 7326step: verifico que el contexto actual del dispositivo es "{expected}" 7327descripcion: Verifica que el contexto actual del dispositivo coincida con el valor esperado. 7328 7329step: verifico que hay contextos webview disponibles en el dispositivo 7330descripcion: Verifica que haya al menos un contexto WebView disponible en la aplicación. 7331 7332step: verifico que el contexto actual del dispositivo es nativo 7333descripcion: Verifica que el contexto actual sea NATIVE_APP (modo nativo). 7334 7335## Alertas y Diálogos 7336 7337step: acepto la alerta nativa del dispositivo 7338descripcion: Acepta (presiona OK/Aceptar) una alerta nativa del dispositivo. 7339 7340step: rechazo la alerta del dispositivo 7341descripcion: Rechaza o descarta una alerta nativa del dispositivo. 7342 7343step: obtengo el texto de la alerta del dispositivo y lo guardo en la variable "{var}" 7344descripcion: Obtiene el texto de una alerta nativa y lo almacena en una variable. 7345 7346step: escribo el texto "{text}" en la alerta del dispositivo 7347descripcion: Escribe texto en el campo de entrada de una alerta nativa. 7348 7349step: escribo "{text}" en la alerta del dispositivo y la acepto 7350descripcion: Escribe texto en una alerta nativa y luego la acepta automáticamente. 7351 7352step: verifico que el texto de la alerta del dispositivo es "{expected}" 7353descripcion: Verifica que el texto de la alerta sea exactamente igual al valor esperado. 7354 7355step: verifico que el texto de la alerta del dispositivo contiene "{expected}" 7356descripcion: Verifica que el texto de la alerta contenga el substring esperado. 7357 7358step: acepto la alerta del dispositivo solo si existe 7359descripcion: Acepta una alerta si existe en pantalla, sin fallar si no hay ninguna alerta presente. 7360 7361## Esperas 7362 7363step: espero "{seconds}" segundos en el dispositivo 7364descripcion: Pausa la ejecución durante el número de segundos indicado. 7365 7366step: espero que el elemento móvil "{locator}" sea visible 7367descripcion: Espera hasta que un elemento sea visible en pantalla usando el timeout por defecto. 7368 7369step: espero a que el elemento móvil "{locator}" sea visible en máximo "{seconds}" segundos 7370descripcion: Espera hasta que un elemento sea visible con un timeout especÃfico en segundos. 7371 7372step: espero que el elemento móvil "{locator}" desaparezca 7373descripcion: Espera hasta que un elemento desaparezca de la pantalla. 7374 7375step: espero a que el elemento móvil "{locator}" desaparezca en máximo "{seconds}" segundos 7376descripcion: Espera hasta que un elemento desaparezca con un timeout especÃfico en segundos. 7377 7378step: espero que el texto móvil "{text}" sea visible 7379descripcion: Espera hasta que un texto especÃfico sea visible en la pantalla del dispositivo. 7380 7381step: espero a que el texto móvil "{text}" sea visible en máximo "{seconds}" segundos 7382descripcion: Espera hasta que un texto sea visible con un timeout especÃfico en segundos. 7383 7384step: espero que el elemento móvil "{locator}" exista 7385descripcion: Espera hasta que un elemento exista en el DOM de la aplicación. 7386 7387step: espero a que el elemento móvil "{locator}" exista en máximo "{seconds}" segundos 7388descripcion: Espera hasta que un elemento exista en el DOM con un timeout especÃfico en segundos. 7389 7390step: espero a que la pantalla del dispositivo esté estable durante "{seconds}" segundos
7391descripcion: Espera a que la pantalla no cambie durante N segundos, útil para verificar que animaciones o cargas hayan terminado. 7392 7393## Screenshots y Reportes 7394 7395step: tomo screenshot del dispositivo 7396descripcion: Toma un screenshot del dispositivo y lo agrega automáticamente al reporte HTML. 7397 7398step: tomo un screenshot nombrado "{name}" del dispositivo 7399descripcion: Toma un screenshot con un nombre descriptivo especÃfico y lo agrega al reporte. 7400 7401step: tomo un screenshot del elemento móvil "{locator}" 7402descripcion: Toma un screenshot de un elemento especÃfico de la pantalla. 7403 7404step: tomo un screenshot nombrado "{name}" del elemento móvil "{locator}" 7405descripcion: Toma un screenshot de un elemento especÃfico con un nombre descriptivo. 7406 7407step: tomo un screenshot del dispositivo guardándolo en la variable "{var}" 7408descripcion: Toma un screenshot y guarda la ruta del archivo en una variable para uso posterior. 7409 7410step: tomo un screenshot del dispositivo por fallo del paso anterior 7411descripcion: Toma un screenshot solo si el escenario tiene errores, útil para diagnóstico de fallos. 7412 7413## Ejecución de Scripts y Comandos 7414 7415step: ejecuto el script "{script}" solo en el dispositivo 7416descripcion: Ejecuta un script JavaScript en el contexto WebView del dispositivo. 7417 7418step: ejecuto el script "{script}" en el dispositivo guardando resultado en la variable "{var}" 7419descripcion: Ejecuta un script JavaScript y guarda el resultado en una variable del framework. 7420 7421step: ejecuto el comando mobile "{command}" solo en el dispositivo 7422descripcion: Ejecuta un comando mobile especÃfico de Appium en el dispositivo. 7423 7424step: ejecuto el comando mobile "{command}" con argumentos en el dispositivo 7425descripcion: Ejecuta un comando mobile de Appium con argumentos definidos en una tabla Gherkin (columnas key/value). 7426 7427step: ejecuto el comando mobile "{command}" en el dispositivo guardando resultado en la variable "{var}" 7428descripcion: Ejecuta un comando mobile de Appium y guarda el resultado en una variable.`},{id:"mobile-inventario-taps",title:"Inventario: Taps",content:`## Taps y Clicks 7429 7430step: hago tap simple en el elemento móvil "{locator}" 7431descripcion: Realiza un tap simple en el elemento identificado por el locator. 7432 7433step: hago doble tap en el elemento móvil "{locator}" 7434descripcion: Realiza un doble tap en el elemento identificado por el locator. 7435 7436step: hago tap largo simple en el elemento móvil "{locator}" 7437descripcion: Realiza un long press con duración por defecto (1 segundo) en el elemento. 7438 7439step: hago tap largo en el elemento móvil "{locator}" por "{ms}" milisegundos 7440descripcion: Realiza un long press con una duración especÃfica en milisegundos sobre el elemento. 7441 7442step: hago tap en las coordenadas móvil "{x}" y "{y}" 7443descripcion: Realiza un tap en coordenadas absolutas de pantalla (x, y). 7444 7445step: hago tap en el texto móvil "{text}" 7446descripcion: Realiza un tap en el primer elemento que contiene el texto exacto indicado. 7447 7448step: hago tap en el accessibility id "{acc_id}" 7449descripcion: Realiza un tap usando el accessibility ID del elemento. 7450 7451step: hago tap en el elemento móvil "{locator}" con timeout de "{seconds}" segundos 7452descripcion: Realiza un tap en un elemento con un timeout personalizado de espera. 7453 7454step: hago tap en el primer elemento de la lista "{locator}" 7455descripcion: Realiza un tap en el primer elemento de una lista de coincidencias del locator. 7456 7457step: hago tap en el último elemento de la lista "{locator}" 7458descripcion: Realiza un tap en el último elemento de una lista de coincidencias del locator. 7459 7460step: hago tap en el elemento número "{index}" de la lista "{locator}" 7461descripcion: Realiza un tap en un elemento especÃfico por su Ãndice (base 0) dentro de una lista. 7462 7463step: hago tap en el elemento móvil "{locator}" tras hacer scroll 7464descripcion: Hace scroll hasta encontrar el elemento y luego realiza un tap sobre él. 7465 7466step: hago tap múltiple "{times}" veces en el elemento móvil "{locator}" 7467descripcion: Realiza múltiples taps consecutivos en un elemento la cantidad de veces indicada. 7468 7469step: hago tap en el elemento móvil "{locator}" esperando "{seconds}" segundos 7470descripcion: Realiza un tap en un elemento y luego espera el tiempo indicado en segundos. 7471 7472step: hago tap en el elemento móvil "{locator}" solo si existe 7473descripcion: Realiza un tap en un elemento solo si existe en pantalla, sin fallar si no está presente.`},{id:"mobile-inventario-texto",title:"Inventario: Texto y Teclado",content:`## Entrada de Texto y Teclado 7474 7475step: escribo texto "{text}" en el campo móvil "{locator}" 7476descripcion: Escribe texto en un campo, limpiando primero el contenido existente. 7477 7478step: escribo "{text}" en el campo móvil "{locator}" manteniendo contenido 7479descripcion: Escribe texto en un campo sin limpiar el contenido previo. 7480 7481step: limpio el campo móvil "{locator}" 7482descripcion: Limpia todo el contenido de un campo de texto. 7483 7484step: agrego texto "{text}" al campo móvil "{locator}" 7485descripcion: Agrega texto al final del campo sin borrar el contenido existente. 7486 7487step: limpio y escribo "{text}" en el campo móvil "{locator}" 7488descripcion: Limpia explÃcitamente el campo y luego escribe el texto indicado. 7489 7490step: escribo "{text}" en el campo móvil "{locator}" ocultando teclado 7491descripcion: Escribe texto en un campo y luego oculta el teclado virtual automáticamente. 7492 7493step: escribo "{text}" en el campo móvil "{locator}" presionando enter 7494descripcion: Escribe texto en un campo y presiona la tecla Enter al finalizar. 7495 7496step: escribo "{text}" en el campo móvil "{locator}" presionando buscar 7497descripcion: Escribe texto en un campo y presiona la tecla Search al finalizar. 7498 7499step: escribo "{text}" en el campo móvil "{locator}" letra por letra 7500descripcion: Escribe texto carácter por carácter, útil para campos con autocompletado que requieren entrada gradual. 7501 7502step: oculto el teclado del dispositivo 7503descripcion: Oculta el teclado virtual del dispositivo. 7504 7505step: presiono la tecla con código "{key_code}" en el dispositivo 7506descripcion: Presiona una tecla especÃfica usando su código Android KeyEvent. 7507 7508step: presiono la tecla Enter en el dispositivo 7509descripcion: Presiona la tecla Enter en el dispositivo. 7510 7511step: presiono la tecla Back en el dispositivo 7512descripcion: Presiona la tecla Back del dispositivo (código 4). 7513 7514step: presiono la tecla Tab en el dispositivo 7515descripcion: Presiona la tecla Tab en el dispositivo.`},{id:"mobile-inventario-scroll",title:"Inventario: Scroll y Swipe",content:`## Scroll y Swipe 7516 7517step: hago scroll hacia abajo en el dispositivo 7518descripcion: Realiza un scroll hacia abajo una vez en la pantalla del dispositivo. 7519 7520step: hago scroll abajo en el dispositivo "{n}" veces 7521descripcion: Realiza scroll hacia abajo N veces consecutivas. 7522 7523step: hago scroll hacia arriba en el dispositivo 7524descripcion: Realiza un scroll hacia arriba una vez en la pantalla del dispositivo. 7525 7526step: hago scroll arriba en el dispositivo "{n}" veces 7527descripcion: Realiza scroll hacia arriba N veces consecutivas. 7528 7529step: hago scroll hacia la izquierda en el dispositivo 7530descripcion: Realiza un scroll hacia la izquierda una vez en la pantalla del dispositivo. 7531 7532step: hago scroll izquierda en el dispositivo "{n}" veces 7533descripcion: Realiza scroll hacia la izquierda N veces consecutivas. 7534 7535step: hago scroll hacia la derecha en el dispositivo 7536descripcion: Realiza un scroll hacia la derecha una vez en la pantalla del dispositivo. 7537 7538step: hago scroll derecha en el dispositivo "{n}" veces 7539descripcion: Realiza scroll hacia la derecha N veces consecutivas. 7540 7541step: hago scroll hasta el elemento móvil "{locator}" 7542descripcion: Realiza scroll hasta que el elemento indicado sea visible en pantalla. 7543 7544step: hago scroll hasta encontrar el elemento móvil "{locator}" limitando a "{max_sw}" intentos 7545descripcion: Realiza scroll hasta encontrar el elemento con un lÃmite máximo de intentos de swipe. 7546 7547step: hago scroll hasta encontrar el texto móvil "{text}" 7548descripcion: Realiza scroll hasta que el texto indicado sea visible en pantalla. 7549 7550step: hago swipe del elemento móvil "{locator}" hacia la izquierda 7551descripcion: Realiza un swipe hacia la izquierda sobre un elemento especÃfico (útil para eliminar o revelar acciones). 7552 7553step: hago swipe del elemento móvil "{locator}" hacia la derecha 7554descripcion: Realiza un swipe hacia la derecha sobre un elemento especÃfico. 7555
7556step: hago swipe desde "{x1}" "{y1}" hasta "{x2}" "{y2}" en el dispositivo 7557descripcion: Realiza un swipe entre dos coordenadas absolutas de pantalla. 7558 7559step: hago swipe desde "{x1}" "{y1}" hasta "{x2}" "{y2}" con duración "{ms}" ms 7560descripcion: Realiza un swipe entre dos coordenadas con una duración especÃfica en milisegundos. 7561 7562step: hago pinch en el elemento móvil "{locator}" 7563descripcion: Realiza un gesto de pinch (zoom out) sobre un elemento. 7564 7565step: hago zoom en el elemento móvil "{locator}" 7566descripcion: Realiza un gesto de zoom (zoom in) sobre un elemento. 7567 7568step: hago scroll hasta el final de la pantalla del dispositivo 7569descripcion: Realiza scroll hasta el final de la pantalla con un máximo de 20 swipes.`},{id:"mobile-inventario-verificaciones",title:"Inventario: Verificaciones",content:`## Verificación de Elementos 7570 7571step: verifico que el elemento móvil "{locator}" es visible 7572descripcion: Verifica que un elemento sea visible en la pantalla del dispositivo. 7573 7574step: verifico que el elemento móvil "{locator}" no es visible 7575descripcion: Verifica que un elemento NO sea visible en la pantalla del dispositivo. 7576 7577step: verifico que el elemento móvil "{locator}" existe 7578descripcion: Verifica que un elemento exista en el DOM de la aplicación. 7579 7580step: verifico que el elemento móvil "{locator}" no existe 7581descripcion: Verifica que un elemento NO exista en el DOM de la aplicación. 7582 7583step: verifico que el elemento móvil "{locator}" está habilitado 7584descripcion: Verifica que un elemento esté habilitado para interacción. 7585 7586step: verifico que el elemento móvil "{locator}" está deshabilitado 7587descripcion: Verifica que un elemento esté deshabilitado y no permita interacción. 7588 7589step: verifico que el elemento móvil "{locator}" está seleccionado 7590descripcion: Verifica que un elemento esté seleccionado (checkbox, radio button). 7591 7592step: verifico que el elemento móvil "{locator}" no está seleccionado 7593descripcion: Verifica que un elemento NO esté seleccionado. 7594 7595step: verifico que el texto del elemento móvil "{locator}" es "{expected}" 7596descripcion: Verifica que el texto de un elemento sea exactamente igual al valor esperado. 7597 7598step: verifico que el texto del elemento móvil "{locator}" contiene "{expected}" 7599descripcion: Verifica que el texto de un elemento contenga el substring esperado. 7600 7601step: verifico que el texto del elemento móvil "{locator}" no contiene "{unexpected}" 7602descripcion: Verifica que el texto de un elemento NO contenga el substring indicado. 7603 7604step: verifico que el texto del elemento móvil "{locator}" no está vacÃo 7605descripcion: Verifica que el texto de un elemento no esté vacÃo ni contenga solo espacios. 7606 7607step: verifico que el atributo "{attr}" del elemento móvil "{locator}" es "{expected}" 7608descripcion: Verifica que el valor de un atributo del elemento sea exactamente el esperado. 7609 7610step: verifico que el atributo "{attr}" del elemento móvil "{locator}" contiene "{expected}" 7611descripcion: Verifica que el valor de un atributo del elemento contenga el substring esperado. 7612 7613step: verifico que hay "{count}" elementos móviles "{locator}" 7614descripcion: Verifica que la cantidad exacta de elementos coincida con el número esperado. 7615 7616step: verifico que hay al menos "{count}" elementos móviles "{locator}" 7617descripcion: Verifica que haya al menos N elementos que coincidan con el locator. 7618 7619step: verifico que la orientación del dispositivo es "{orientation}" 7620descripcion: Verifica que la orientación actual del dispositivo sea la esperada (PORTRAIT o LANDSCAPE). 7621 7622## Obtención de Datos y Variables 7623 7624step: obtengo el texto del elemento móvil "{locator}" y lo guardo en la variable "{var}" 7625descripcion: Obtiene el texto de un elemento y lo almacena en una variable del framework para uso posterior. 7626 7627step: obtengo el atributo "{attr}" del elemento móvil "{locator}" y lo guardo en la variable "{var}" 7628descripcion: Obtiene el valor de un atributo de un elemento y lo almacena en una variable. 7629 7630step: obtengo la cantidad de elementos móviles "{locator}" y la guardo en la variable "{var}" 7631descripcion: Cuenta los elementos que coinciden con el locator y guarda el resultado en una variable. 7632 7633step: obtengo la orientación del dispositivo y la guardo en la variable "{var}" 7634descripcion: Obtiene la orientación actual del dispositivo y la almacena en una variable. 7635 7636step: obtengo el tamaño de la pantalla del dispositivo y lo guardo en las variables "{w_var}" y "{h_var}" 7637descripcion: Obtiene el ancho y alto de la pantalla del dispositivo y los guarda en dos variables separadas. 7638 7639step: obtengo la información del dispositivo y la guardo en la variable "{var}" 7640descripcion: Obtiene información completa del dispositivo y la guarda como JSON en una variable. 7641 7642step: obtengo el contexto actual del dispositivo y lo guardo en la variable "{var}" 7643descripcion: Obtiene el contexto actual (NATIVE_APP o WEBVIEW) y lo almacena en una variable. 7644 7645step: obtengo los contextos disponibles del dispositivo y los guardo en la variable "{var}" 7646descripcion: Obtiene la lista de todos los contextos disponibles y la guarda como JSON en una variable. 7647 7648step: obtengo el código fuente de la pantalla del dispositivo y lo guardo en la variable "{var}" 7649descripcion: Obtiene el XML/HTML de la pantalla actual y lo almacena en una variable. 7650 7651step: imprimo la información del dispositivo 7652descripcion: Imprime en el log la información completa del dispositivo conectado. 7653 7654step: imprimo los contextos disponibles del dispositivo 7655descripcion: Imprime en el log la lista de contextos disponibles (NATIVE_APP, WEBVIEW, etc.). 7656 7657step: imprimo el código fuente de la pantalla del dispositivo 7658descripcion: Imprime en el log el XML/HTML de la pantalla actual del dispositivo (primeros 2000 caracteres).`}]},{id:"pruebas-desktop",title:"Pruebas Desktop",group:"Tipos de Prueba",icon:"",topics:[{id:"desktop-setup",title:"GuÃa de Setup Desktop (PyAutoGUI)",content:`## Requisitos 7659 7660- Python con PyAutoGUI instalado (\`pip install pyautogui\`) 7661- Tesseract OCR instalado (para funciones de lectura de texto) 7662- Imágenes de referencia en carpeta configurada 7663- Pantalla con resolución conocida (las coordenadas son absolutas) 7664 7665## Configuración .env 7666 7667\`\`\`env 7668DESKTOP_IMAGES_PATH=./desktop_images 7669DESKTOP_CONFIDENCE=0.8 7670DESKTOP_TIMEOUT=10 7671DESKTOP_PAUSE=0.5 7672\`\`\` 7673 7674## Ejemplo de Feature 7675 7676\`\`\`gherkin 7677@desktop 7678Feature: Automatización de aplicación de escritorio 7679 7680 Scenario: Abrir calculadora y sumar 7681 Given uso el modo desktop
7682 When abro la aplicacion "calc.exe" 7683 And hago click en la imagen "boton_5" 7684 And hago click en la imagen "boton_suma" 7685 And hago click en la imagen "boton_3" 7686 And hago click en la imagen "boton_igual" 7687 Then deberia ver la imagen "resultado_8" en pantalla 7688\`\`\` 7689 7690## Consideraciones 7691 7692- PyAutoGUI trabaja con coordenadas absolutas de pantalla. 7693- La búsqueda por imagen requiere imágenes de referencia (screenshots recortados). 7694- El nivel de confianza por defecto (0.8) puede ajustarse según la necesidad. 7695- \`uso el modo desktop\` activa el modo escritorio y las capturas del reporte usarán PyAutoGUI. 7696- Puedes combinar pruebas desktop y web usando \`uso el modo web\` para volver al navegador.`},{id:"desktop-automatizacion",title:"Automatización Desktop",content:`## Clicks por Coordenadas 7697 7698\`\`\`gherkin 7699When hago click en las coordenadas "500" "300" 7700And hago doble click en las coordenadas "500" "300" 7701And hago click derecho en las coordenadas "500" "300" 7702And muevo el mouse a las coordenadas "200" "400" 7703\`\`\` 7704 7705## Clicks por Imagen 7706 7707\`\`\`gherkin 7708When hago click en la imagen "boton_aceptar" 7709And hago doble click en la imagen "icono_archivo" 7710And hago click con confianza "0.9" en la imagen "boton_submit" 7711And hago click con desplazamiento "10" "5" en la imagen "campo_texto" 7712\`\`\` 7713 7714## Teclado y Texto 7715 7716\`\`\`gherkin 7717When escribo el texto "Hola mundo" 7718And pego el texto "Texto con ñ y tildes" usando el portapapeles 7719And presiono en escritorio la tecla "enter" 7720And presiono en escritorio las teclas "ctrl" y "s" 7721And presiono en escritorio las teclas "ctrl" mas "shift" mas "s" 7722\`\`\` 7723 7724## Drag and Drop 7725 7726\`\`\`gherkin 7727When arrastro desde las coordenadas "100" "200" hasta las coordenadas "400" "500" 7728And arrastro la imagen "archivo_origen" hacia la imagen "carpeta_destino" 7729And arrastro la imagen "icono" hacia las coordenadas "600" "400" 7730\`\`\` 7731 7732## Modo Mixto Web + Desktop 7733 7734\`\`\`gherkin 7735Given uso el modo web 7736When voy a la url "https://app.ejemplo.com/descargar" 7737And hago click en el elemento "btn_descargar" con identificador "$.DESCARGAS.btn_download" 7738Then uso el modo desktop 7739And espero a que aparezca la imagen "dialogo_guardar" 7740And hago click en la imagen "boton_guardar" 7741Then uso el modo web 7742And deberÃa ver el texto "Descarga completada" 7743\`\`\``},{id:"desktop-custom-steps",title:"Custom Steps Desktop",content:`## Crear Custom Steps Desktop 7744 7745\`\`\`python 7746from behave import step 7747import pyautogui 7748import time 7749 7750@step('abro el archivo "{filename}" en Notepad') 7751def step_open_in_notepad(context, filename): 7752 import subprocess 7753 subprocess.Popen(['notepad.exe', filename]) 7754 time.sleep(2) 7755 # Verificar que se abrió 7756 context.desktop_manager.wait_for_image("notepad_title", timeout=5) 7757 7758@step('guardo el documento activo con nombre "{name}"') 7759def step_save_as(context, name): 7760 pyautogui.hotkey('ctrl', 'shift', 's') 7761 time.sleep(1) 7762 pyautogui.typewrite(name, interval=0.05) 7763 pyautogui.press('enter') 7764 time.sleep(1) 7765\`\`\` 7766 7767## Helpers Disponibles 7768 7769- \`context.desktop_manager.click_image(name)\` â Click en imagen 7770- \`context.desktop_manager.find_image(name)\` â Buscar imagen 7771- \`context.desktop_manager.wait_for_image(name, timeout)\` â Esperar imagen 7772- \`context.desktop_manager.type_text(text)\` â Escribir texto 7773- \`context.desktop_manager.paste_text(text)\` â Pegar texto con portapapeles 7774- \`context.desktop_manager.take_screenshot(name)\` â Captura de pantalla 7775- \`context.desktop_manager.read_screen_text()\` â OCR de pantalla completa 7776- \`pyautogui\` â Acceso directo a PyAutoGUI para operaciones avanzadas`},{id:"desktop-inventario-apps",title:"Inventario: Aplicaciones",content:`## Gestión de Aplicaciones 7777 7778step: abro la aplicacion "{app_path}" 7779descripcion: Lanza una aplicación de escritorio y espera 2 segundos antes de continuar con el siguiente paso. 7780 7781step: lanzo y espero "{seconds}" segundos la aplicacion "{app_path}" 7782descripcion: Lanza una aplicación de escritorio y espera el tiempo indicado en segundos antes de continuar. 7783 7784step: lanzo con argumentos "{args}" la aplicacion "{app_path}" 7785descripcion: Lanza una aplicación de escritorio pasándole argumentos de lÃnea de comandos separados por espacios. 7786 7787step: cierro la aplicacion "{process_name}" 7788descripcion: Cierra una aplicación en ejecución buscándola por su nombre de proceso. 7789 7790step: traigo la ventana "{window_title}" al frente 7791descripcion: Trae una ventana al frente del escritorio buscándola por su tÃtulo. 7792 7793## Modo Mixto (Web + Escritorio) 7794 7795step: uso el modo desktop 7796descripcion: Activa el modo escritorio guardando el estado del navegador. Las capturas del reporte usarán PyAutoGUI. 7797 7798step: uso el modo web 7799descripcion: Vuelve al modo web restaurando la página del navegador. Las capturas del reporte vuelven a usar Playwright. 7800 7801step: uso el modo api 7802descripcion: Activa el modo API donde el reporte mostrará request/response en lugar de screenshots. 7803 7804step: cambio a la aplicacion de escritorio "{app_path}" desde la prueba web 7805descripcion: Lanza una aplicación de escritorio y activa modo desktop sin cerrar el navegador web activo. 7806 7807step: vuelvo al navegador web despues de la interaccion con escritorio 7808descripcion: Vuelve al modo web y trae la ventana del navegador al frente del escritorio. 7809 7810step: capturo el escritorio y vuelvo al navegador con nombre "{name}" 7811descripcion: Toma una captura del escritorio con nombre personalizado y devuelve el foco al navegador web. 7812 7813## Esperas 7814 7815step: espero "{seconds}" segundos en escritorio 7816descripcion: Pausa la ejecución la cantidad de segundos indicada antes de continuar. 7817 7818step: espero a que aparezca la imagen "{image_name}" 7819descripcion: Espera hasta que una imagen aparezca en pantalla usando el timeout por defecto. 7820 7821step: espero con timeout "{timeout}" segundos a que aparezca la imagen "{image_name}" 7822descripcion: Espera hasta que una imagen aparezca en pantalla con un timeout personalizado en segundos. 7823 7824step: espero a que desaparezca la imagen "{image_name}" 7825descripcion: Espera hasta que una imagen deje de estar visible en pantalla usando el timeout por defecto. 7826 7827step: espero con timeout "{timeout}" segundos a que desaparezca la imagen "{image_name}" 7828descripcion: Espera hasta que una imagen desaparezca de pantalla con un timeout personalizado en segundos. 7829 7830## Configuración y Utilidades 7831 7832step: guardo la posicion del mouse en la variable "{variable_name}" 7833descripcion: Obtiene las coordenadas actuales del cursor del mouse y las guarda en una variable. 7834 7835step: guardo el tamano de pantalla en la variable "{variable_name}" 7836descripcion: Obtiene la resolución actual de la pantalla (ancho, alto) y la guarda en una variable. 7837 7838step: establezco la pausa entre acciones en "{seconds}" segundos 7839descripcion: Configura el tiempo de espera automático entre cada acción de PyAutoGUI. 7840 7841step: establezco la confianza de busqueda de imagenes en "{confidence}" 7842descripcion: Configura el nivel de confianza global para la búsqueda de imágenes en pantalla (0.0 a 1.0). 7843 7844step: establezco el timeout de busqueda de imagenes en "{seconds}" segundos 7845descripcion: Configura el tiempo máximo de espera global para encontrar imágenes en pantalla.`},{id:"desktop-inventario-clicks",title:"Inventario: Clicks",content:`## Clicks por Coordenadas 7846 7847step: hago click en las coordenadas "{x}" "{y}" 7848descripcion: Realiza un click izquierdo en las coordenadas absolutas de pantalla indicadas. 7849 7850step: hago doble click en las coordenadas "{x}" "{y}" 7851descripcion: Realiza un doble click en las coordenadas absolutas de pantalla indicadas. 7852 7853step: hago click derecho en las coordenadas "{x}" "{y}" 7854descripcion: Realiza un click derecho en las coordenadas absolutas de pantalla indicadas. 7855 7856step: muevo el mouse a las coordenadas "{x}" "{y}" 7857descripcion: Mueve el cursor del mouse a las coordenadas indicadas sin realizar ningún click. 7858 7859step: escribo en las coordenadas "{x}" "{y}" el texto "{text}" 7860descripcion: Hace click en las coordenadas indicadas, limpia el campo y escribe el texto especificado. 7861 7862step: arrastro desde las coordenadas "{x1}" "{y1}" hasta las coordenadas "{x2}" "{y2}"
7863descripcion: Arrastra el mouse desde unas coordenadas de origen hasta unas coordenadas de destino (drag and drop). 7864 7865## Clicks por Imagen 7866 7867step: hago click en la imagen "{image_name}" 7868descripcion: Busca un elemento en pantalla por imagen de referencia y realiza un click izquierdo sobre él. 7869 7870step: hago doble click en la imagen "{image_name}" 7871descripcion: Busca un elemento en pantalla por imagen de referencia y realiza un doble click sobre él. 7872 7873step: hago click derecho en la imagen "{image_name}" 7874descripcion: Busca un elemento en pantalla por imagen de referencia y realiza un click derecho sobre él. 7875 7876step: paso el mouse sobre la imagen "{image_name}" 7877descripcion: Mueve el cursor sobre un elemento encontrado por imagen sin hacer click (hover). 7878 7879step: hago click con confianza "{confidence}" en la imagen "{image_name}" 7880descripcion: Hace click en un elemento por imagen usando un nivel de confianza personalizado (valor entre 0.0 y 1.0). 7881 7882step: hago click con desplazamiento "{offset_x}" "{offset_y}" en la imagen "{image_name}" 7883descripcion: Hace click en un elemento por imagen aplicando un desplazamiento en pÃxeles desde el centro de la imagen encontrada. 7884 7885step: escribo en la imagen "{image_name}" el texto "{text}" 7886descripcion: Hace click en un campo encontrado por imagen, limpia su contenido y escribe el texto indicado. 7887 7888step: agrego en la imagen "{image_name}" el texto "{text}" 7889descripcion: Hace click en un campo encontrado por imagen y agrega texto sin borrar el contenido existente. 7890 7891step: arrastro la imagen "{source_image}" hacia la imagen "{target_image}" 7892descripcion: Arrastra un elemento encontrado por imagen origen hacia otro elemento encontrado por imagen destino. 7893 7894step: arrastro la imagen "{source_image}" hacia las coordenadas "{x}" "{y}" 7895descripcion: Arrastra un elemento encontrado por imagen hacia unas coordenadas especÃficas de pantalla. 7896 7897## Scroll 7898 7899step: hago scroll hacia arriba "{clicks}" veces 7900descripcion: Realiza scroll hacia arriba en la posición actual del mouse la cantidad de clicks indicada. 7901 7902step: hago scroll hacia abajo "{clicks}" veces 7903descripcion: Realiza scroll hacia abajo en la posición actual del mouse la cantidad de clicks indicada. 7904 7905step: hago scroll arriba "{clicks}" veces en la posicion "{x}" "{y}" 7906descripcion: Realiza scroll hacia arriba en unas coordenadas especÃficas de pantalla. 7907 7908step: hago scroll abajo "{clicks}" veces en la posicion "{x}" "{y}" 7909descripcion: Realiza scroll hacia abajo en unas coordenadas especÃficas de pantalla. 7910 7911step: hago scroll arriba "{clicks}" veces sobre la imagen "{image_name}" 7912descripcion: Realiza scroll hacia arriba sobre un elemento encontrado por imagen. 7913 7914step: hago scroll abajo "{clicks}" veces sobre la imagen "{image_name}" 7915descripcion: Realiza scroll hacia abajo sobre un elemento encontrado por imagen.`},{id:"desktop-inventario-teclado",title:"Inventario: Teclado",content:`## Teclado y Texto 7916 7917step: escribo el texto "{text}" 7918descripcion: Escribe texto carácter a carácter en el elemento que tiene el foco actualmente. 7919 7920step: pego el texto "{text}" usando el portapapeles 7921descripcion: Escribe texto usando el portapapeles del sistema, soportando tildes, eñes y caracteres especiales. 7922 7923step: limpio el campo y escribo "{text}" 7924descripcion: Selecciona todo el contenido del campo activo, lo borra y escribe el texto nuevo. 7925 7926step: presiono en escritorio la tecla "{key}" 7927descripcion: Presiona una tecla especial en el escritorio (enter, tab, escape, f5, delete, etc.). 7928 7929step: presiono en escritorio las teclas "{key1}" y "{key2}" 7930descripcion: Presiona una combinación de dos teclas simultáneamente (ctrl+c, alt+f4, etc.). 7931 7932step: presiono en escritorio las teclas "{key1}" mas "{key2}" mas "{key3}" 7933descripcion: Presiona una combinación de tres teclas simultáneamente (ctrl+shift+s, etc.). 7934 7935step: mantengo presionada en escritorio la tecla "{key}" 7936descripcion: Mantiene una tecla presionada sin soltarla, útil para combinaciones con arrastre. 7937 7938step: suelto en escritorio la tecla "{key}" 7939descripcion: Suelta una tecla que fue previamente mantenida presionada. 7940 7941step: presiono Enter en escritorio 7942descripcion: Presiona la tecla Enter en el escritorio como atajo rápido. 7943 7944step: presiono Tab en escritorio 7945descripcion: Presiona la tecla Tab en el escritorio como atajo rápido. 7946 7947step: presiono Escape en escritorio 7948descripcion: Presiona la tecla Escape en el escritorio como atajo rápido. 7949 7950step: presiono el atajo de escritorio copiar 7951descripcion: Ejecuta el atajo de teclado Ctrl+C para copiar el contenido seleccionado. 7952 7953step: presiono el atajo de escritorio pegar 7954descripcion: Ejecuta el atajo de teclado Ctrl+V para pegar el contenido del portapapeles. 7955 7956step: presiono el atajo de escritorio seleccionar todo 7957descripcion: Ejecuta el atajo de teclado Ctrl+A para seleccionar todo el contenido. 7958 7959step: presiono el atajo de escritorio guardar 7960descripcion: Ejecuta el atajo de teclado Ctrl+S para guardar el documento activo. 7961 7962step: presiono el atajo de escritorio deshacer 7963descripcion: Ejecuta el atajo de teclado Ctrl+Z para deshacer la última acción. 7964 7965## Portapapeles 7966 7967step: copio el texto "{text}" al portapapeles 7968descripcion: Copia un texto especÃfico al portapapeles del sistema operativo. 7969 7970step: obtengo el contenido del portapapeles y lo guardo en la variable "{variable_name}" 7971descripcion: Lee el contenido actual del portapapeles del sistema y lo guarda en una variable. 7972 7973step: copio el texto seleccionado y lo guardo en la variable "{variable_name}" 7974descripcion: Ejecuta Ctrl+C sobre el texto seleccionado y guarda el resultado en una variable. 7975 7976step: deberia ver que el portapapeles contiene "{expected_text}" 7977descripcion: Verifica que el contenido actual del portapapeles contenga el texto esperado (comparación sin distinción de mayúsculas).`},{id:"desktop-inventario-verificaciones",title:"Inventario: Verificaciones",content:`## Verificaciones Visuales 7978 7979step: deberia ver la imagen "{image_name}" en pantalla 7980descripcion: Verifica que una imagen de referencia esté visible en la pantalla actual. Falla si no la encuentra. 7981
7982step: no deberia ver la imagen "{image_name}" en pantalla 7983descripcion: Verifica que una imagen de referencia NO esté visible en la pantalla actual. Falla si la encuentra. 7984 7985step: verifico con confianza "{confidence}" que la imagen "{image_name}" es visible 7986descripcion: Verifica que una imagen esté visible usando un nivel de confianza personalizado (0.0 a 1.0). 7987 7988step: guardo la ubicacion de la imagen "{image_name}" en la variable "{variable_name}" 7989descripcion: Busca una imagen en pantalla y guarda sus coordenadas (x, y) en una variable para uso posterior. 7990 7991step: cuento las ocurrencias de la imagen "{image_name}" y las guardo en la variable "{variable_name}" 7992descripcion: Busca todas las apariciones de una imagen en pantalla y guarda la cantidad encontrada en una variable. 7993 7994step: verifico que el tamano de pantalla es "{width}" por "{height}" 7995descripcion: Verifica que la resolución de pantalla coincida con el ancho y alto esperados en pÃxeles. 7996 7997## Capturas de Pantalla 7998 7999step: tomo una captura del escritorio 8000descripcion: Toma una captura de pantalla completa del escritorio y la registra en el reporte HTML. 8001 8002step: capturo el escritorio con nombre "{name}" 8003descripcion: Toma una captura de pantalla completa con un nombre personalizado y la registra en el reporte HTML. 8004 8005step: tomo una captura antes de la accion "{action_name}" 8006descripcion: Toma una captura de pantalla antes de ejecutar una acción, útil para documentar el estado previo. 8007 8008step: tomo una captura despues de la accion "{action_name}" 8009descripcion: Toma una captura de pantalla después de ejecutar una acción, útil para documentar el resultado. 8010
8011step: tomo una captura de la region "{x}" "{y}" "{width}" "{height}" con nombre "{name}" 8012descripcion: Toma una captura de una región especÃfica de la pantalla definida por coordenadas y dimensiones en pÃxeles. 8013 8014## OCR en Escritorio 8015 8016step: capturo el escritorio y extraigo texto en la variable "{variable_name}" 8017descripcion: Toma captura de pantalla completa, aplica OCR y guarda todo el texto detectado en una variable. 8018 8019step: deberia ver el texto "{expected_text}" en el escritorio usando OCR 8020descripcion: Toma captura del escritorio y verifica que el texto esperado esté presente usando reconocimiento óptico. 8021 8022step: no deberia ver el texto "{unexpected_text}" en el escritorio usando OCR 8023descripcion: Toma captura del escritorio y verifica que el texto NO esté presente usando reconocimiento óptico. 8024 8025step: capturo la region "{x}" "{y}" "{width}" "{height}" y extraigo texto en la variable "{variable_name}" 8026descripcion: Toma captura de una región especÃfica de pantalla y aplica OCR para extraer el texto en una variable. 8027 8028## Lectura y Extracción de Texto 8029 8030step: leo el texto de la pantalla y lo guardo en la variable "{variable_name}" 8031descripcion: Toma screenshot de toda la pantalla, aplica OCR y guarda el texto completo en una variable. 8032 8033step: leo el texto de la pantalla con confianza minima "{confidence}" y lo guardo en la variable "{variable_name}" 8034descripcion: Aplica OCR a la pantalla completa filtrando texto con confianza menor al umbral indicado. 8035
8036step: leo el texto de la region "{x}" "{y}" "{width}" "{height}" y lo guardo en la variable "{variable_name}" 8037descripcion: Toma screenshot de una región especÃfica en pÃxeles, aplica OCR y guarda el texto en una variable. 8038 8039step: copio y leo el texto seleccionado y lo guardo en la variable "{variable_name}" 8040descripcion: Copia el texto actualmente seleccionado en pantalla (Ctrl+C) y lo guarda en una variable. 8041 8042step: leo el campo imagen "{image_name}" y guardo el texto en la variable "{variable_name}" 8043descripcion: Hace click en un campo por imagen, selecciona todo su contenido, lo copia y guarda el texto en una variable. 8044 8045step: leo el campo en las coordenadas "{x}" "{y}" y guardo el texto en la variable "{variable_name}" 8046descripcion: Hace click en coordenadas, selecciona todo el contenido del campo, lo copia y guarda el texto en una variable. 8047 8048step: selecciono todo y leo el texto del campo activo y lo guardo en la variable "{variable_name}" 8049descripcion: En el campo con foco actual, selecciona todo (Ctrl+A), copia (Ctrl+C) y guarda el texto en una variable. 8050 8051## Verificaciones de Texto LeÃdo 8052 8053step: el texto leido en la variable "{variable_name}" deberia contener "{expected_text}" 8054descripcion: Verifica que el texto guardado en una variable contenga el texto esperado (sin distinción de mayúsculas). 8055 8056step: el texto leido en la variable "{variable_name}" deberia ser exactamente "{expected_text}" 8057descripcion: Verifica que el texto guardado en una variable sea exactamente igual al texto esperado.`}]},{id:"pruebas-bd",title:"Pruebas Base de Datos",group:"Tipos de Prueba",icon:"",topics:[{id:"bd-conexion",title:"Conexión y Consultas",content:`## Conexión a Base de Datos 8058 8059El framework soporta conexiones a SQLite y bases de datos configuradas por entorno (.env). 8060 8061### Configuración .env 8062 8063\`\`\`env 8064# PostgreSQL 8065DB_TYPE=postgresql 8066DB_POSTGRES_HOST=localhost 8067DB_POSTGRES_PORT=5432 8068DB_POSTGRES_DATABASE=mi_base_datos 8069DB_POSTGRES_USERNAME=usuario 8070DB_POSTGRES_PASSWORD=mi_password 8071DB_POSTGRES_SCHEMA=public 8072 8073# MySQL (alternativa) 8074# DB_TYPE=mysql 8075# DB_MYSQL_HOST=localhost 8076# DB_MYSQL_PORT=3306 8077# DB_MYSQL_DATABASE=mi_base_datos 8078# DB_MYSQL_USERNAME=usuario 8079# DB_MYSQL_PASSWORD=mi_password 8080# DB_MYSQL_CHARSET=utf8mb4 8081 8082# SQLite (alternativa) 8083# DB_TYPE=sqlite 8084# DB_SQLITE_PATH=test_data/test.db 8085\`\`\` 8086 8087### Ejemplo: Consulta y Validación 8088 8089\`\`\`gherkin 8090@no_browser 8091Feature: Validar datos en base de datos 8092 8093 Scenario: Verificar usuario creado 8094 Given me conecto a la base de datos usando configuración del entorno 8095 When ejecuto la consulta SQL "SELECT * FROM usuarios WHERE email = '[email protected]'" y guardo el resultado en la variable "resultado" 8096 Then verifico que el resultado de la consulta SQL tiene "1" filas 8097 And verifico que el resultado SQL contiene una fila con "email" igual a "[email protected]" 8098 And cierro la conexión a la base de datos 8099\`\`\` 8100 8101### Ejemplo: SQLite directo 8102 8103\`\`\`gherkin 8104 Scenario: Consultar SQLite local 8105 Given me conecto a la base de datos SQLite "./test_data/app.db" 8106 When ejecuto la consulta SQL "SELECT count(*) as total FROM productos" y guardo el resultado en la variable "conteo" 8107 Then obtengo el valor del resultado SQL de la columna "total" fila "0" y lo guardo en la variable "total_productos" 8108 And verifico que la variable "total_productos" es igual a "15" 8109\`\`\` 8110 8111### Ejemplo: Inserción y Backup 8112 8113\`\`\`gherkin 8114 Scenario: Insertar datos y hacer backup 8115 Given me conecto a la base de datos "mi_db" 8116 When inserto datos de prueba en la tabla "usuarios" con valores '{"nombre": "Ana", "email": "[email protected]", "rol": "admin"}' 8117 And ejecuto la actualización SQL "UPDATE usuarios SET activo = 1 WHERE email = '[email protected]'" 8118 Then hago backup de la base de datos al archivo "./backups/pre_test.sql" 8119 And cierro la conexión a la base de datos 8120\`\`\` 8121 8122## Consideraciones 8123 8124- Usa el tag \`@no_browser\` para pruebas de BD que no necesitan navegador. 8125- Los resultados de consultas se guardan como JSON en variables. 8126- \`obtengo el valor del resultado SQL\` permite extraer celdas especÃficas por columna y fila. 8127- Siempre cierra la conexión al finalizar con \`cierro la conexión a la base de datos\`.`}
8127,{id:"bd-inventario",title:"Inventario: Pasos BD",content:`## Conexión 8128 8129step: me conecto a la base de datos "{db_name}" 8130descripcion: Conecta a una base de datos usando la configuración del archivo .env o un nombre/ruta especÃfico. Soporta SQLite (por extensión .db/.sqlite) y conexiones configuradas por entorno. 8131 8132step: me conecto a la base de datos SQLite "{db_path}" 8133descripcion: Conecta directamente a una base de datos SQLite especificando la ruta del archivo. 8134 8135step: me conecto a la base de datos usando configuración del entorno 8136descripcion: Conecta a la base de datos utilizando las variables de configuración definidas en el archivo .env (DB_TYPE, DB_HOST, etc.). 8137 8138step: cierro la conexión a la base de datos 8139descripcion: Cierra la conexión activa a la base de datos. Si no hay conexión abierta, muestra una advertencia sin generar error. 8140 8141## Creación y Estructura 8142 8143step: creo base de datos de prueba con datos de ejemplo 8144descripcion: Crea una base de datos de prueba con tablas y datos de ejemplo precargados para facilitar las pruebas. 8145 8146step: creo la tabla "{table_name}" con columnas "{columns_definition}" 8147descripcion: Crea una tabla nueva con la definición de columnas especificada. Usa CREATE TABLE IF NOT EXISTS para evitar errores si ya existe. 8148 8149step: elimino la tabla "{table_name}" 8150descripcion: Elimina una tabla de la base de datos usando DROP TABLE IF EXISTS. 8151 8152## Consultas SELECT 8153 8154step: ejecuto la consulta SQL "{query}" y guardo el resultado en la variable "{variable_name}" 8155descripcion: Ejecuta una consulta SQL de lectura (SELECT) y guarda el resultado como JSON en una variable. También almacena el resultado en context.last_db_results para validaciones posteriores. 8156 8157step: obtengo el valor del resultado SQL de la columna "{column}" fila "{row_index}" y lo guardo en la variable "{variable_name}" 8158descripcion: Extrae un valor especÃfico del último resultado SQL indicando columna e Ãndice de fila, y lo guarda en una variable para uso posterior. 8159 8160## Operaciones de Escritura 8161 8162step: ejecuto la actualización SQL "{query}" 8163descripcion: Ejecuta una consulta SQL de modificación (INSERT, UPDATE, DELETE) e informa la cantidad de filas afectadas. 8164 8165step: inserto datos de prueba en la tabla "{table_name}" con valores "{values}" 8166descripcion: Inserta datos en una tabla a partir de valores en formato JSON. Soporta inserción de una fila o múltiples filas simultáneamente. 8167 8168## Verificaciones 8169 8170step: verifico que el resultado de la consulta SQL tiene "{expected_count}" filas 8171descripcion: Valida que el último resultado SQL obtenido contenga exactamente la cantidad de filas esperada. Falla si el conteo no coincide. 8172 8173step: verifico que el resultado SQL contiene una fila con "{column}" igual a "{expected_value}" 8174descripcion: Verifica que en el último resultado SQL exista al menos una fila donde la columna indicada tenga el valor esperado. 8175 8176## Backup 8177 8178step: hago backup de la base de datos al archivo "{backup_file}" 8179descripcion: Realiza un respaldo de la base de datos actual guardándolo en el archivo especificado.`},{id:"bd-email",title:"Inventario: Pasos Email",content:`## Email (SMTP/IMAP) 8180 8181Steps para enviar y leer emails. Permiten verificar flujos que dependen de correos: confirmaciones de registro, códigos de verificación (MFA por email), notificaciones, etc. 8182 8183> Estos pasos usan el tag \`@no_browser\` porque no requieren navegador. 8184 8185## EnvÃo de Email (SMTP) 8186 8187step: establezco las credenciales de email remitente="{sender}" contraseña="{password}" 8188descripcion: Establece las credenciales para envÃo de email. 8189 8190step: envÃo email a "{recipient}" con asunto "{subject}" y cuerpo "{body}" usando SMTP "{smtp_server}" puerto "{port}" 8191descripcion: EnvÃa un email usando SMTP con las credenciales previamente configuradas. 8192 8193## Lectura de Email (IMAP) 8194 8195step: me conecto al servidor IMAP "{imap_server}" puerto "{port}" con usuario "{username}" contraseña "{password}" 8196descripcion: Conecta a un servidor IMAP para leer emails. 8197 8198step: selecciono la carpeta de email "{folder}" 8199descripcion: Selecciona una carpeta de email (INBOX, SENT, etc.). 8200 8201step: busco emails con asunto que contiene "{subject_text}" y guardo el conteo en la variable "{variable_name}" 8202descripcion: Busca emails por asunto y guarda el conteo en una variable. 8203 8204step: obtengo el contenido del email más reciente y lo guardo en la variable "{variable_name}" 8205descripcion: Obtiene el contenido del email más reciente de la carpeta seleccionad
8205a. 8206 8207step: verifico que se recibió un email con asunto "{subject}" dentro de "{timeout}" segundos 8208descripcion: Espera y verifica que se recibió un email con un asunto especÃfico dentro del tiempo lÃmite. 8209 8210step: extraigo el código de verificación del cuerpo del email y lo guardo en la variable "{variable_name}" 8211descripcion: Extrae un código de verificación (numérico o alfanumérico) del último email recibido. 8212 8213step: elimino emails con asunto que contiene "{subject_text}" 8214descripcion: Elimina emails que contienen un texto especÃfico en el asunto. Ãtil para limpiar la bandeja después de las pruebas. 8215 8216step: cierro la conexión de email 8217descripcion: Cierra la conexión IMAP activa. 8218 8219## Ejemplo Completo 8220 8221\`\`\`gherkin 8222@no_browser 8223Feature: Verificación de email de registro 8224 8225 Scenario: El usuario recibe código de verificación por email 8226 Given establezco las credenciales de email remitente="[email protected]" contraseña="app_password_123" 8227 And me conecto al servidor IMAP "imap.gmail.com" puerto "993" con usuario "[email protected]" contraseña "app_password_123" 8228 And selecciono la carpeta de email "INBOX" 8229 And elimino emails con asunto que contiene "Código de verificación" 8230 When envÃo email a "[email protected]" con asunto "Bienvenido" y cuerpo "Tu cuenta fue creada" usando SMTP "smtp.gmail.com" puerto "587" 8231 Then verifico que se recibió un email con asunto "Código de verificación" dentro de "30" segundos 8232 And extraigo el código de verificación del cuerpo del email y lo guardo en la variable "codigo_mfa" 8233 And cierro la conexión de email 8234\`\`\` 8235 8236> Para Gmail, usa una contraseña de aplicación (App Password) en vez de tu contraseña normal.`}]},{id:"pruebas-genai",title:"Pruebas GenAI",group:"Tipos de Prueba",icon:"",topics:[{id:"genai-evaluacion",title:"Evaluación con Gemini",content:`## Evaluación de IA con Gemini como Juez 8237 8238El framework permite evaluar respuestas de sistemas de IA usando Gemini como juez imparcial en 7 dimensiones: precisión, cumplimiento, tono, coherencia, context relevance, faithfulness y answer relevance. 8239 8240### Configuración .env 8241 8242\`\`\`env 8243GEMINI_API_KEY=tu_api_key 8244GEMINI_DEFAULT_THRESHOLD=0.80 8245GEMINI_JUDGE_MODEL=gemini-3.1-flash-lite 8246\`\`\` 8247 8248### Flujo Básico 8249 8250\`\`\`gherkin 8251@no_browser 8252Feature: Evaluar chatbot de soporte 8253 8254 Scenario: Validar respuesta sobre polÃticas de devolución 8255 Given el contexto de reglas de negocio "soporte" está cargado desde el archivo "contextos/politicas_devolucion.txt" 8256 When interactúo con la IA con el prompt "¿Cuál es la polÃtica de devolución?" 8257 Then el Juez Gemini debe validar la respuesta con un umbral mÃnimo de 0.85 8258\`\`\` 8259 8260### Validación Directa (un solo paso) 8261 8262\`\`\`gherkin 8263 Scenario: Validar par pregunta-respuesta 8264 Given el contexto de reglas de negocio "FAQ" está cargado desde el archivo "contextos/faq.txt" 8265 Then valido con Gemini que según el contexto para la pregunta "¿Horario de atención?" la respuesta "Lunes a viernes de 9 a 18 hrs" es válida con umbral 0.80 8266\`\`\` 8267 8268### Criterios Personalizados 8269 8270\`\`\`gherkin 8271 Scenario: Validar con criterios especÃficos 8272 Given el contexto de reglas de negocio "legal" está cargado desde el archivo "contextos/terminos.txt" 8273 When establezco la respuesta del SUT como "El plazo es de 30 dÃas hábiles según la ley." 8274 Then el Juez Gemini debe validar la respuesta con criterios personalizados "precisión legal,citas normativas,lenguaje formal" y umbral 0.90 8275\`\`\` 8276 8277### Consideraciones 8278 8279- El Juez evalúa en 7 dimensiones por defecto, devolviendo un score promedio. 8280- Context Caching se usa automáticamente para contextos mayores a 32k tokens. 8281- Puedes guardar evaluaciones con \`guardo la evaluación del Juez en el archivo\`. 8282- El tag \`@no_browser\` es recomendado para pruebas puramente de GenAI.`},{id:"genai-semantica",title:"Validación Semántica",content:`## Validación Semántica con Embeddings 8283 8284Usa modelos de Sentence Transformers para comparar textos por significado (no por texto exacto). 8285 8286### Configuración 8287 8288\`\`\`gherkin 8289Given configuro el modelo semántico como "paraphrase-multilingual-MiniLM-L12-v2" 8290And establezco el umbral de similitud semántica en 0.80 8291\`\`\` 8292 8293### Comparación de Textos 8294 8295\`\`\`gherkin 8296Then el texto "El auto es rojo" debe ser semánticamente similar a "El vehÃculo tiene color rojo" 8297And el texto de la variable "respuesta_chatbot" debe ser semánticamente similar a "Nuestro horario es de 9 a 18" 8298\`\`\` 8299 8300### Análisis de Sentimiento 8301 8302\`\`\`gherkin 8303Then el sentimiento del texto "¡Excelente servicio, muy satisfecho!" debe ser "positivo" 8304And el sentimiento de la variable "feedback_cliente" debe ser "negativo" 8305\`\`\` 8306 8307### Clasificación de Texto 8308 8309\`\`\`gherkin 8310Then el texto "Quiero devolver mi producto" debe pertenecer a la categorÃa "devolución" de "consulta,reclamo,devolución,soporte" 8311\`\`\` 8312 8313### NLP Avanzado 8314 8315\`\`\`gherkin 8316When extraigo las entidades del texto "Juan visitó ParÃs el 15 de marzo" y las guardo en "entidades" 8317And genero un resumen del texto "..." y lo guardo en "resumen" 8318And analizo la toxicidad del texto "mensaje del usuario" y guardo el resultado en "es_toxico" 8319Then verifico que el texto "mensaje del usuario" no es tóxico 8320\`\`\` 8321 8322### Supabase Vector (RAG) 8323 8324\`\`\`gherkin 8325Given me conecto a Supabase usando variables de entorno 8326When busco en la tabla "knowledge_base" el contexto más similar a "polÃtica de reembolso" y lo guardo en "contexto" 8327Then el Juez Gemini debe validar la respuesta con un umbral mÃnimo de 0.85 8328\`\`\``}
8328,{id:"genai-inventario",title:"Inventario: Pasos GenAI",content:`## Evaluación con Gemini 8329 8330step: el contexto de reglas de negocio "{context_name}" está cargado desde el archivo "{file_path}" 8331descripcion: Carga el contexto de reglas de negocio desde un archivo. Si supera 32k tokens usa Context Caching de Gemini, si es menor lo almacena como system_instruction. 8332 8333step: cambio al contexto de reglas de negocio "{context_name}" 8334descripcion: Cambia al contexto de reglas de negocio especificado cuando hay múltiples contextos cargados. 8335 8336step: limpio todos los cachés de contexto 8337descripcion: Elimina todos los cachés de contexto creados en Gemini para liberar recursos. 8338 8339step: interactúo con la IA con el prompt "{user_query}" 8340descripcion: EnvÃa un prompt al Sistema Bajo Prueba (SUT) y guarda la respuesta para evaluación posterior. 8341 8342step: envÃo el prompt "{user_query}" a la IA 8343descripcion: Alias para interactuar con el SUT enviando un prompt y guardando la respuesta. 8344 8345step: establezco la respuesta del SUT como "{response_text}" 8346descripcion: Establece manualmente la respuesta del Sistema Bajo Prueba, útil para simular respuestas en testing. 8347 8348step: la respuesta del SUT es "{response_text}" 8349descripcion: Alias para establecer manualmente la respuesta del SUT. 8350 8351step: cargo la respuesta del SUT desde el archivo "{file_path}" 8352descripcion: Carga la respuesta del Sistema Bajo Prueba desde un archivo de texto. 8353 8354step: Gemini genera la respuesta para el prompt "{user_query}" 8355descripcion: Genera una respuesta usando Gemini basándose en el contexto de negocio cargado. Ãtil para crear golden answers o comparar con tu IA. 8356 8357step: genero la respuesta con Gemini para el prompt "{user_query}" 8358descripcion: Alias para generar una respuesta con Gemini usando el contexto de negocio activo. 8359 8360step: el Juez Gemini debe validar la respuesta con un umbral mÃnimo de {threshold} 8361descripcion: Evalúa la respuesta del SUT usando Gemini como Juez en 7 dimensiones (precisión, cumplimiento, tono, coherencia, context relevance, faithfulness, answer relevance). 8362 8363step: el Juez Gemini valida la respuesta con umbral {threshold} 8364descripcion: Alias para la validación del Juez Gemini con umbral especificado. 8365 8366step: el Juez Gemini debe validar la respuesta 8367descripcion: Evalúa la respuesta del SUT usando Gemini como Juez con el umbral configurado en .env o el valor por defecto (0.80
8367). 8368 8369step: el Juez Gemini debe validar la respuesta con criterios personalizados "{criteria}" y umbral {threshold} 8370descripcion: Evalúa la respuesta del SUT con criterios personalizados separados por comas y un umbral especÃfico. 8371 8372step: valido con Gemini que según el contexto para la pregunta "{pregunta}" la respuesta "{respuesta}" es válida con umbral {threshold} 8373descripcion: Valida un par pregunta-respuesta directamente en un solo paso, combinando establecer pregunta, respuesta y validar. 8374 8375step: el Juez Gemini valida que para la pregunta "{pregunta}" la respuesta "{respuesta}" es correcta con umbral {threshold} 8376descripcion: Alias para validar un par pregunta-respuesta en un solo paso con el Juez Gemini. 8377 8378step: guardo la evaluación del Juez en el archivo "{file_path}" 8379descripcion: Guarda la última evaluación del Juez Gemini en un archivo JSON para análisis posterior. 8380 8381step: el score de la última evaluación debe ser mayor o igual a {min_score} 8382descripcion: Verifica que el score de la última evaluación del Juez cumple con un mÃnimo requerido. 8383 8384## Steps Avanzados de GenAI 8385 8386step: valido que la respuesta del SUT está en idioma "{language}" 8387descripcion: Valida que la respuesta del Sistema Bajo Prueba está escrita en el idioma especificado usando Gemini para la detección. 8388 8389step: verifico que la respuesta está en "{language}" 8390descripcion: Alias para validar el idioma de la respuesta del SUT. 8391 8392step: valido que la respuesta del SUT es un JSON válido 8393descripcion: Verifica que la respuesta del SUT sea un JSON válido y lo parsea para uso posterior. 8394 8395step: verifico que la respuesta es JSON válido 8396descripcion: Alias para validar que la respuesta del SUT es JSON válido. 8397 8398step: valido que el JSON de respuesta tiene la estructura "{schema_file}" 8399descripcion: Valida que el JSON de respuesta cumple con un esquema JSON especÃfico cargado desde un archivo. 8400 8401step: verifico que el JSON cumple con el esquema "{schema_file}" 8402descripcion: Alias para validar la estructura JSON contra un esquema. 8403 8404step: valido que la intención de la respuesta es "{expected_intent}" 8405descripcion: Detecta y valida que la intención de la respuesta del SUT coincide con la esperada (informativa, persuasiva, etc.). 8406 8407step: verifico que la intención detectada es "{expected_intent}" 8408descripcion: Alias para validar la intencionalidad de la respuesta. 8409 8410step: valido que la respuesta rechaza el prompt adversarial 8411descripcion: Verifica que la IA rechaza correctamente un intento de manipulación o jailbreaking sin proporcionar información sensible. 8412 8413step: verifico que la IA rechaza el intento de jailbreaking 8414descripcion: Alias para validar el rechazo de prompts adversariales. 8415 8416step: valido que la respuesta no contiene alucinaciones según el contexto 8417descripcion: Detecta si la respuesta contiene información inventada (alucinaciones) que no está en el contexto de negocio. 8418 8419step: verifico que no hay hallucinations en la respuesta 8420descripcion: Alias para la detección de alucinaciones en la respuesta del SUT. 8421 8422step: valido que la respuesta no contiene sesgos de "{bias_type}" 8423descripcion: Detecta si la respuesta contiene sesgos especÃficos (género, edad, raza, etc.) como estereotipos o generalizaciones injustas. 8424 8425step: verifico que no hay sesgo de "{bias_type}" en la respuesta 8426descripcion: Alias para la detección de sesgos en la respuesta. 8427 8428step: valido que la respuesta no contiene lenguaje tóxico 8429descripcion: Detecta si la respuesta contiene lenguaje tóxico, ofensivo o inapropiado para un contexto profesional. 8430 8431step: verifico que la respuesta es profesional y respetuosa 8432descripcion: Alias para validar que la respuesta no contiene toxicidad. 8433 8434step: valido que las respuestas "{var1}" y "{var2}" son consistentes 8435descripcion: Valida que dos respuestas almacenadas en variables son consistentes entre sÃ, sin contradicciones ni inconsistencias lógicas. 8436 8437step: verifico consistencia entre "{var1}" y "{var2}" 8438descripcion: Alias para validar la consistencia entre dos respuestas. 8439 8440step: valido que la respuesta cita fuentes correctamente 8441descripcion: Verifica que la respuesta cita fuentes de forma especÃfica y verificable, evaluando la calidad de la citación. 8442 8443step: verifico que hay citación de fuentes en la respuesta 8444descripcion: Alias para validar la citación de fuentes en la respuesta. 8445 8446## Validación Semántica 8447 8448step: configuro el modelo semántico como "{model_name}" 8449descripcion: Configura el modelo de Sentence Transformers a utilizar para las validaciones semánticas. 8450 8451step: establezco el umbral de similitud semántica en {threshold} 8452descripcion: Establece el umbral de similitud (0.0 a 1.0) para las validaciones semánticas. 8453 8454step: uso la configuración semántica por defecto 8455descripcion: Configura modelo y umbral por defecto leyendo desde variables de entorno SEMANTIC_MODEL y SEMANTIC_THRESHOLD. 8456 8457step: el texto "{actual_text}" debe ser semánticamente similar a "{expected_text}"
8458descripcion: Verifica que dos textos sean semánticamente similares según el umbral configurado, usando embeddings y similitud de coseno. 8459 8460step: el texto de la variable "{var_name}" debe ser semánticamente similar a "{expected_text}" 8461descripcion: Verifica que el texto almacenado en una variable sea semánticamente similar al texto esperado. 8462 8463step: calculo la similitud semántica entre "{text1}" y "{text2}" y la guardo en "{var_name}" 8464descripcion: Calcula la similitud semántica entre dos textos y almacena el resultado numérico en una variable. 8465 8466step: el texto del elemento "{element_name}" con identificador "{locator}" debe ser semánticamente similar a "{expected_text}" 8467descripcion: Verifica que el texto de un elemento web sea semánticamente similar al texto esperado. 8468 8469## Semántica Avanzada 8470 8471step: el sentimiento del texto "{text}" debe ser "{expected_sentiment}" 8472descripcion: Analiza el sentimiento de un texto y verifica que coincida con el esperado (positivo, negativo o neutral). 8473 8474step: el sentimiento de la variable "{var_name}" debe ser "{expected_sentiment}" 8475descripcion: Analiza el sentimiento del texto almacenado en una variable y verifica que sea el esperado. 8476 8477step: clasifico el texto "{text}" en las categorÃas "{categories}" y guardo el resultado en "{var_name}" 8478descripcion: Clasifica un texto en una de las categorÃas proporcionadas (separadas por comas) usando similitud semántica. 8479 8480step: el texto "{text}" debe pertenecer a la categorÃa "{expected_category}" de "{categories}" 8481descripcion: Verifica que un texto pertenezca a una categorÃa especÃfica dentro de un conjunto de categorÃas posibles. 8482 8483step: detecto el idioma del texto "{text}" y lo guardo en "{var_name}" 8484descripcion: Detecta el idioma de un texto usando similitud semántica con textos de referencia y guarda el resultado. 8485 8486step: el idioma del texto "{text}" debe ser "{expected_language}" 8487descripcion: Verifica que un texto esté escrito en el idioma esperado. 8488 8489step: busco el texto más similar a "{query}" en la lista "{text_list}" y lo guardo en "{var_name}" 8490descripcion: Busca el texto más similar a una consulta dentro de una lista de textos separados por comas. 8491 8492step: comparo el texto "{text}" con múltiples referencias "{references}" y muestro las similitudes 8493descripcion: Compara un texto con múltiples referencias y muestra todas las similitudes calculadas. 8494 8495## NLP Avanzado 8496 8497step: extraigo las entidades del texto "{text}" y las guardo en "{var_name}" 8498descripcion: Extrae entidades nombradas (personas, lugares, organizaciones, fechas) de un texto usando un modelo NER multilingüe. 8499 8500step: verifico que el texto "{text}" contiene una entidad de tipo "{entity_type}" 8501descripcion: Verifica que un texto contenga al menos una entidad del tipo especificado (PER, LOC, ORG, DATE). 8502 8503step: genero un resumen del texto "{text}" y lo guardo en "{var_name}" 8504descripcion: Genera un resumen automático de un texto largo usando el modelo BART. 8505 8506step: genero un resumen de la variable "{var_name}" con máximo {max_words} palabras y lo guardo en "{output_var}" 8507descripcion: Genera un resumen con longitud controlada del texto almacenado en una variable. 8508 8509step: traduzco el texto "{text}" de "{source_lang}" a "{target_lang}" y lo guardo en "{var_name}" 8510descripcion: Traduce un texto entre idiomas soportados (es, en, fr, de, pt) usando modelos Helsinki-NLP. 8511 8512step: genero una respuesta para "{prompt}" y la guardo en "{var_name}" 8513descripcion: Genera texto automáticamente basado en un prompt usando GPT-2. 8514 8515step: analizo la toxicidad del texto "{text}" y guardo el resultado en "{var_name}" 8516descripcion: Analiza si un texto contiene contenido tóxico u ofensivo usando toxic-bert y guarda true/false. 8517 8518step: verifico que el texto "{text}" no es tóxico 8519descripcion: Verifica que un texto NO contenga contenido tóxico. 8520 8521step: extraigo las palabras clave del texto "{text}" y las guardo en "{var_name}" 8522descripcion: Extrae las 5 palabras clave más importantes de un texto usando KeyBERT. 8523 8524step: agrupo los textos "{text_list}" en {num_clusters} clusters y guardo los resultados en "{var_name}" 8525descripcion: Agrupa textos similares en clusters usando K-Means sobre embeddings semánticos. 8526 8527step: respondo la pregunta "{question}" basándome en el contexto "{context_text}" y guardo la respuesta en "{var_name}"
8528descripcion: Responde una pregunta basándose en un contexto proporcionado usando Question Answering con RoBERTa. 8529 8530## Supabase Vector / RAG 8531 8532step: me conecto a Supabase con URL "{supabase_url}" y key "{supabase_key}" 8533descripcion: Establece conexión a Supabase usando URL y API key proporcionados directamente o desde variables. 8534 8535step: me conecto a Supabase usando variables de entorno 8536descripcion: Conecta a Supabase usando las variables de entorno SUPABASE_URL y SUPABASE_KEY definidas en .env. 8537 8538step: busco en la tabla "{table_name}" el contexto más similar a "{query}" y lo guardo en "{variable_name}" 8539descripcion: Busca contexto similar usando búsqueda vectorial con embeddings de Gemini en Supabase. 8540 8541step: busco en la tabla "{table_name}" los {count} contextos más similares a "{query}" y los guardo en "{variable_name}" 8542descripcion: Busca múltiples contextos similares usando búsqueda vectorial. 8543 8544step: cargo el contexto de Supabase tabla "{table_name}" para la query "{query}" en el contexto de Gemini "{context_name}" 8545descripcion: Busca contexto en Supabase y lo carga directamente en Gemini como contexto de negocio nombrado. 8546 8547step: consulto la tabla "{table_name}" en Supabase y guardo el resultado en "{variable_name}" 8548descripcion: Consulta todos los registros de una tabla de Supabase y guarda el resultado en una variable. 8549 8550step: consulto la tabla "{table_name}" filtrando por "{column}" igual a "{value}" y guardo en "{variable_name}" 8551descripcion: Consulta una tabla de Supabase aplicando un filtro de igualdad en una columna especÃfica.`}]},{id:"patrones-avanzados",title:"Patrones Avanzados",group:"Técnicas Avanzadas",icon:"",topics:[{id:"scenario-outline",title:"Scenario Outline",content:`## Probar con Múltiples Datos 8552 8553\`Scenario Outline\` ejecuta el mismo escenario con múltiples combinaciones de datos. Cada fila de la tabla \`Examples\` genera una ejecución independiente. 8554 8555\`\`\`gherkin 8556Esquema del Escenario: Verificar que cada rol accede a su pantalla 8557 Dado voy a la url "\${ENV.BASE_URL}/login" 8558 Cuando relleno el campo "usuario" con "<email>" con identificador "$.LOGIN.input_user" 8559 Y relleno el campo "clave" con "<password>" con identificador "$.LOGIN.input_pass" 8560 Y hago click en el elemento "ingresar" con identificador "$.LOGIN.btn_login" 8561 Entonces la url actual deberÃa contener "<url_esperada>" 8562 8563 Ejemplos: 8564 | email | password | url_esperada | 8565 | [email protected] | admin123 | /dashboard | 8566 | [email protected] | user123 | /home | 8567 | [email protected] | viewer123 | /reports | 8568\`\`\` 8569 8570## Background (Antecedentes) 8571 8572Pasos que se ejecutan antes de CADA escenario del feature. 8573 8574\`\`\`gherkin 8575Antecedentes: 8576 Dado voy a la url "\${ENV.BASE_URL}/login" 8577 Y relleno el campo "usuario" con "\${ENV.TEST_USER}" con identificador "$.LOGIN.input_user" 8578 Y relleno el campo "clave" con "\${ENV.TEST_PASS}" con identificador "$.LOGIN.input_pass" 8579 Y hago click en el elemento "ingresar" con identificador "$.LOGIN.btn_login" 8580 8581Escenario: Crear un producto nuevo 8582 Cuando hago click en el elemento "nuevo" con identificador "$.PRODUCTS.btn_new" 8583\`\`\``},{id:"pasos-personalizados",title:"Pasos Personalizados",content:`## Crear un Paso Personalizado 8584 8585\`\`\`python 8586# features/steps/custom_steps.py 8587from behave import step 8588 8589@step('hago login con usuario "{user}" y clave "{password}"') 8590def step_login(context, user, password): 8591 user = context.variable_manager.resolve_variables(user) 8592 password = context.variable_manager.resolve_variables(password) 8593 context.fill("$.LOGIN.input_usuario", user) 8594 context.fill("$.LOGIN.input_password", password) 8595 context.click("$.LOGIN.btn_login") 8596 context.page.wait_for_load_state("domcontentloaded") 8597\`\`\` 8598 8599## Agrupar Pasos del Framework 8600 8601\`\`\`python 8602@step('completo el flujo de login para el ambiente "{env}"') 8603def step_full_login_flow(context, env): 8604 base_urls = {"dev": "http://localhost:3000", "staging": "https://staging.miapp.com"} 8605 url = base_urls.get(env, "http://localhost:3000") 8606 user = context.variable_manager.resolve_variables("\${ENV.TEST_USER}") 8607 password = context.variable_manager.resolve_variables("\${ENV.TEST_PASS}") 8608 context.execute_steps(f''' 8609 When voy a la url "{url}/login" 8610 And relleno el campo "usuario" con "{user}" con identificador "$.LOGIN.input_usuario" 8611 And relleno el campo "clave" con "{password}" con identificador "$.LOGIN.input_clave" 8612 And hago click en el elemento "login" con identificador "$.LOGIN.btn_login" 8613 ''') 8614\`\`\` 8615 8616## Paso con Tabla Gherkin 8617 8618\`\`\`python 8619@step('completo el formulario con los siguientes datos') 8620def step_fill_form(context): 8621 for row in context.table: 8622 campo = row['campo'] 8623 valor = context.variable_manager.resolve_variables(row['valor']) 8624 context.fill(f"$.REGISTRO.input_{campo}", valor) 8625\`\`\` 8626 8627\`\`\`gherkin 8628When completo el formulario con los siguientes datos 8629 | campo | valor | 8630 | nombre | Ana GarcÃa | 8631 | email | [email protected] | 8632 | telefono | +56912345678 | 8633\`\`\``},{id:"soft-assertions",title:"Soft Assertions",content:`## Qué son las Soft Assertions 8634 8635Por defecto, cuando una verificación falla, Behave detiene el escenario. Con Soft Assertions, las verificaciones fallidas se capturan pero la ejecución continúa. 8636 8637## Activar Soft Assertions 8638 8639\`\`\`gherkin 8640@soft_assertions 8641Scenario: Validar todos los campos del formulario 8642 Given voy a la url "\${ENV.BASE_URL}/perfil" 8643 Then el campo "nombre" deberÃa tener el valor "Ana" con identificador "$.PERFIL.nombre" 8644 And el campo "email" deberÃa tener el valor "[email protected]" con identificador "$.PERFIL.email" 8645 And el campo "rol" deberÃa tener el valor "Administrador" con identificador "$.PERFIL.rol" 8646\`\`\` 8647 8648## Comportamiento 8649 8650- Se activa con el tag \`@soft_assertions\` en el escenario.
8651- Solo captura \`AssertionError\` (pasos de verificación). 8652- Errores de otro tipo (TimeoutError, ElementNotFound) siguen deteniendo la ejecución. 8653- El reporte HTML muestra el estado real de cada step. 8654- Al final del escenario se imprime un resumen con todos los errores.`},{id:"reintentos",title:"Reintentos Automáticos",content:`## Configuración 8655 8656\`\`\`env 8657RETRY_FAILED_SCENARIOS=true 8658MAX_SCENARIO_RETRIES=2 8659\`\`\` 8660 8661## Cómo Funciona 8662 86631. Behave ejecuta todos los escenarios normalmente 86642. Cuando un escenario falla, se registra internamente 86653. Después de terminar todos los escenarios, se reintentan los fallidos 86664. Cada reintento crea una página limpia (navega a \`about:blank\`) 86675. Si pasa en el reintento, se reporta como passed 8668 8669## Recomendaciones 8670 8671- Usar para manejar flakiness, no para ocultar bugs reales 8672- Máximo 2-3 reintentos 8673- Si un escenario necesita reintentos consistentemente, investigar la causa raÃz 8674- En CI/CD, habilitar reintentos reduce falsos negativos`},{id:"variables-dinamicas-localizadores",title:"Variables en Identificadores",content:`## Variables Dinámicas en Identificadores 8675 8676Puedes usar variables del framework dentro de los identificadores para construir selectores dinámicamente. 8677 8678\`\`\`gherkin 8679When guardo el texto del elemento "$.RESULT.codigo" en la variable "id_registro" 8680And hago click en el elemento "editar" con identificador "$.TABLE.btn_editar=\${id_registro}" 8681\`\`\` 8682 8683Donde \`TABLE.json\` tiene: 8684\`\`\`json 8685{ 8686 "btn_editar": "[data-id='<valor>']" 8687} 8688\`\`\` 8689 8690## Texto Dinámico en XPath 8691 8692\`\`\`gherkin 8693When creo la variable "nombre_producto" con valor "Laptop Pro 15" 8694And deberÃa ver el elemento "producto" con identificador "$.CATALOG.item_por_nombre=\${nombre_producto}" 8695\`\`\` 8696 8697\`\`\`json 8698{ 8699 "item_por_nombre": "//div[@class='product-card'][contains(., '<valor>')]" 8700} 8701\`\`\` 8702 8703- La sintaxis \`$.ARCHIVO.elemento=\${variable}\` resuelve la variable antes de buscar el elemento. 8704- Si la variable no existe, el placeholder queda sin reemplazar.`},{id:"context-avanzado",title:"Context en Custom Steps",content:`## Recursos Disponibles en Context 8705 8706\`\`\`python 8707@step('ejecuto mi paso complejo') 8708def step_complex(context): 8709 # Navegador Playwright 8710 context.page # La página actual 8711 context.browser # El browser (multi-tab) 8712 8713 # Localizadores 8714 context.element_locator # ElementLocator para JSON POMs 8715 context.find("$.MOD.elemento") # Shortcut: retorna Locator 8716 context.click("$.MOD.btn") # Shortcut: click 8717 context.fill("$.MOD.input", "texto") # Shortcut: fill 8718 context.get_text("$.MOD.label") # Shortcut: text_content() 8719 8720 # Variables 8721 context.variable_manager.get_variable("mi_var") 8722 context.variable_manager.set_variable("nueva_var", "valor") 8723 context.variable_manager.resolve_variables("Hola \${nombre}") 8724 8725 # Logger 8726 context.logger.info("Mensaje de info") 8727 8728 # Framework config 8729 timeout = context.framework_config.config['timeout'] 8730 browser_name = context.framework_config.config['browser'] 8731\`\`\` 8732 8733## Paso que Usa Playwright Directamente 8734 8735\`\`\`python 8736@step('capturo el valor del campo oculto "{field_id}"') 8737def step_capture_hidden_field(context, field_id): 8738 value = context.page.evaluate(f"document.getElementById('{field_id}').value") 8739 context.variable_manager.set_variable(f"hidden_{field_id}", str(value)) 8740 print(f"â Campo oculto '{field_id}' = '{value}'") 8741\`\`\` 8742 8743- \`context.page\` puede ser None si el navegador fue desactivado (\`@no_browser\`). 8744- Siempre chequea \`if hasattr(context, 'page') and context.page:\` antes de usarlo.`},{id:"pasos-alias-condicionales",title:"Alias y Pasos Condicionales",content:`## Múltiples Alias para un Paso 8745 8746Un mismo paso puede tener múltiples formas de invocarlo: 8747 8748\`\`\`python 8749@step('ingreso al sistema como "{role}"') 8750@step('que ingreso al sistema como "{role}"') 8751@step('me logueo como "{role}"') 8752def step_login_as_role(context, role): 8753 credentials = { 8754 "admin": ("[email protected]", "admin123"), 8755 "usuario": ("[email protected]", "user123"), 8756 } 8757 email, password = credentials.get(role, ("[email protected]", "guest")) 8758 context.fill("$.LOGIN.input_email", email) 8759 context.fill("$.LOGIN.input_pass", password) 8760 context.click("$.LOGIN.btn_ingresar") 8761\`\`\` 8762 8763## Paso Condicional 8764 8765\`\`\`python 8766@step('cierro el modal de bienvenida si aparece') 8767def step_close_welcome_modal(context): 8768 try: 8769 btn_cerrar = context.page.locator("$.MODAL.btn_cerrar") 8770 if btn_cerrar.is_visible(timeout=3000): 8771 btn_cerrar.click() 8772 print("â Modal de bienvenida cerrado") 8773 else: 8774 print("â¹ï¸ Modal no apareció, continuando") 8775 except Exception: 8776 print("â¹ï¸ Modal no encontrado, continuando") 8777\`\`\` 8778 8779## Retry con Lógica Personalizada 8780 8781\`\`\`python 8782@step('espero a que el proceso termine con timeout de "{seconds}" segundos') 8783def step_wait_for_process(context, seconds): 8784 import time 8785 max_time = int(seconds) 8786 start = time.time() 8787 while time.time() - start < max_time: 8788 status = context.get_text("$.PROCESS.status_label") 8789 if status in ("Completado", "Error"): 8790 break 8791 context.page.wait_for_timeout(1000) 8792 else: 8793 raise AssertionError(f"El proceso no terminó en {seconds} segundos") 8794 assert status == "Completado", f"Terminó con estado: {status}" 8795\`\`\` 8796 8797- Usa \`context.conditional_action("selector", action_fn, else_fn)\` para condicionales simples. 8798- Usa \`context.retry_action(lambda: ..., max_retries=3, delay=1000)\` para reintentos automáticos.`},{id:"docstrings-tablas",title:"DocStrings y Tablas",content:`## Paso con DocString (Texto MultilÃnea) 8799 8800\`\`\`python 8801@step('envÃo la configuración al endpoint "{endpoint}"') 8802def step_send_config(context, endpoint): 8803 import requests, json 8804 payload = json.loads(context.text) 8805 response = requests.post(endpoint, json=payload, timeout=30) 8806 context.variable_manager.set_variable("last_status", str(response.status_code)) 8807\`\`\` 8808 8809\`\`\`gherkin 8810When envÃo la configuración al endpoint "https://api.miapp.com/config" 8811 """ 8812 { 8813 "modo": "produccion", 8814 "timeout": 5000, 8815 "retries": 3 8816 } 8817 """ 8818\`\`\` 8819 8820## Paso con Tabla Gherkin (DataTable) 8821 8822\`\`\`python 8823@step('verifico los datos del usuario en la tabla') 8824def step_verify_user_data(context): 8825 for row in context.table: 8826 columna = row['columna'] 8827 esperado = row['valor esperado'] 8828 actual = context.page.locator(f"td[data-col='{columna}']").text_content() 8829 assert esperado in actual, f"'{columna}': esperado '{esperado}', actual '{actual}'" 8830\`\`\` 8831 8832\`\`\`gherkin 8833Then verifico los datos del usuario en la tabla 8834 | columna | valor esperado | 8835 | nombre | Ana GarcÃa | 8836 | email | [email protected] | 8837 | estado | Activo | 8838\`\`\` 8839 8840- \`context.text\` es el DocString (sin las triples comillas). 8841- \`context.table\` es iterable con acceso por nombre de columna.`},{id:"tablas-html",title:"Manejo de Tablas HTML",content:`## Esperar y Verificar Tabla 8842 8843\`\`\`gherkin 8844When hago click en el elemento "buscar" con identificador "$.SEARCH.btn" 8845And espero a que la tabla "resultados" tenga filas con identificador "$.RESULT.tabla" 8846And espero a que la tabla "resultados" tenga al menos 5 filas con identificador "$.RESULT.tabla" 8847Then deberÃa haber exactamente 10 elementos que coinciden con "fila" con identificador "$.RESULT.tabla tbody tr" 8848\`\`\` 8849 8850## Paso Personalizado para Iterar Tabla 8851 8852\`\`\`python 8853@step('verifico que ninguna fila tiene estado "Pendiente"') 8854def step_verify_no_pending(context): 8855 rows = context.find_all("$.TABLA.filas_estado") 8856 for i, row in enumerate(rows): 8857 status = row.text_content().strip() 8858 assert status != "Pendiente", f"Fila {i} tiene estado 'Pendiente'" 8859 print(f"â Ninguna de las {len(rows)} filas tiene estado 'Pendiente'") 8860\`\`\` 8861 8862- Para tablas con paginación, navega página por página.
8863- Combina con \`guardo el texto del elemento "$.TABLA.fila[0]" en la variable "primera_fila"\` para extraer valores.`},{id:"ciclo-vida",title:"Ciclo de Vida",content:`## Orden de Ejecución 8864 8865\`\`\` 8866before_all â Una vez al inicio de toda la ejecución 8867 before_feature â Una vez por cada archivo .feature 8868 before_scenario â Una vez por cada escenario 8869 [Antecedentes] 8870 before_step â Antes de cada step 8871 after_step â Después de cada step 8872 after_scenario â Después de cada escenario 8873 after_feature â Al terminar el feature 8874after_all â Una vez al final de toda la ejecución 8875\`\`\` 8876 8877## Qué Hace el Framework en Cada Hook 8878 8879**before_all:** 8880- Carga el .env 8881- Inicia Playwright 8882- Crea ElementLocator y VariableManager 8883- Inicializa integraciones (Jira, Cassini) 8884 8885**before_scenario:** 8886- Crea o reutiliza la página del navegador 8887- Limpia variables de escenario anterior 8888- Inicializa soft assertions si aplica 8889 8890**after_step:** 8891- Captura screenshot si está configurado 8892- Procesa soft assertions 8893 8894**after_scenario:** 8895- Captura screenshot si el escenario falló 8896- Procesa reintentos si aplica 8897- Reporta resultado a Cassini/Jira 8898 8899**after_all:** 8900- Genera reporte HTML 8901- Cierra Playwright 8902- Finaliza integraciones`},{id:"variables-alcance-global",title:"Variables Globales",content:`## Alcance de Variables 8903 8904Por defecto las variables son de **escenario** (se limpian al terminar). Para compartir entre escenarios del mismo feature, usa variables globales. 8905 8906\`\`\`python 8907@step('guardo globalmente la variable "{name}" con valor "{value}"') 8908def step_set_global_var(context, name, value): 8909 context.variable_manager.set_variable(name, value, scope='global') 8910\`\`\` 8911 8912\`\`\`gherkin 8913# Escenario 1 8914When guardo globalmente la variable "token_sesion" con valor "abc123" 8915 8916# Escenario 2 (mismo feature) 8917Then verifico que la variable "token_sesion" contiene "abc" 8918\`\`\` 8919 8920## Variables en Custom Steps 8921 8922\`\`\`python 8923@step('creo un ticket con asunto "{subject}" y obtengo su número') 8924def step_create_ticket(context, subject): 8925 import requests 8926 response = requests.post( 8927 f"{context.variable_manager.get_variable('API_URL')}/tickets", 8928 json={"subject": subject}, timeout=30 8929 ) 8930 assert response.status_code == 201 8931 ticket_number = response.json()["number"] 8932 context.variable_manager.set_variable("numero_ticket", str(ticket_number)) 8933 print(f"â Ticket creado: #{ticket_number}") 8934\`\`\` 8935 8936\`\`\`gherkin 8937When creo un ticket con asunto "Error en formulario" y obtengo su número 8938Then verifico que la variable "numero_ticket" contiene "TKT-" 8939\`\`\` 8940 8941## Consideraciones 8942 8943- \`get_variable(name)\` busca en: variables de escenario â globales â entorno (.env). 8944- Si la variable no existe, lanza \`KeyError\`. Maneja la excepción si es opcional. 8945- \`resolve_variables(text)\` resuelve interpolaciones \`\${var}\` en un string completo. 8946- Las variables globales persisten durante toda la ejecución. 8947- Evita depender de variables globales para pruebas paralelas (condiciones de carrera).`},{id:"paralelizacion",title:"Ejecución Paralela",content:`## Configuración de Paralelismo 8948 8949El framework soporta ejecución paralela por features, usando múltiples instancias de Playwright simultáneamente. 8950 8951### Configuración en .env 8952 8953\`\`\`env 8954PARALLEL_WORKERS=4 # Número de workers paralelos (1 = serial) 8955\`\`\` 8956 8957### Ejecución desde CLI 8958 8959\`\`\`bash 8960# Ejecución serial (por defecto) 8961haka-run 8962 8963# Ejecución paralela con 4 workers 8964haka-run --parallel --workers 4 8965 8966# Ejecución paralela por tag 8967haka-run --parallel --workers 4 --tags @regression 8968\`\`\` 8969 8970### Ejecución desde Python 8971 8972\`\`\`python 8973from hakalab_framework.runner import run_tests 8974import sys 8975 8976# Serial 8977sys.exit(run_tests(tags='@smoke')) 8978 8979# Paralelo: usa PARALLEL_WORKERS del .env automáticamente 8980sys.exit(run_tests(tags='@regression')) 8981\`\`\` 8982 8983## Cómo Funciona 8984 89851. El framework detecta \`PARALLEL_WORKERS\` del \`.env\` 89862. Si es > 1 y hay más de un feature, ejecuta en paralelo 89873. Cada feature se ejecuta en un subprocess independiente 89884. Cada worker tiene su propia instancia de Playwright 89895. Al finalizar, se unifican los reportes HTML 8990
8991## Consideraciones 8992 8993- La paralelización es a nivel de **feature** (no de escenario) 8994- Cada worker tiene su propia sesión de navegador 8995- Variables globales no se comparten entre workers 8996- Los reportes se consolidan al final automáticamente 8997- Compatible con integraciones (Cassini crea una sola ejecución compartida)`},{id:"cicd",title:"CI/CD",content:`## Configuración para CI/CD 8998 8999### Variables de Entorno para Pipelines 9000 9001\`\`\`env 9002HEADLESS=true # Sin ventana visible 9003BROWSER=chromium # Más liviano que chrome 9004AUTO_SCREENSHOT_ON_FAILURE=true 9005RETRY_FAILED_SCENARIOS=true 9006MAX_SCENARIO_RETRIES=2 9007\`\`\` 9008 9009### CLI Optimizado para Docker 9010 9011\`\`\`bash 9012haka-run --headless --docker --tags @smoke 9013\`\`\` 9014 9015El flag \`--docker\` fuerza headless, activa screenshots en fallos y ajusta el logging. 9016 9017## Sharding en CI/CD (GitHub Actions) 9018 9019Para distribuir tests entre múltiples jobs paralelos, usa sharding por variables de entorno: 9020 9021\`\`\`env 9022SHARD_INDEX=1 # Ãndice del shard actual (1-based) 9023TOTAL_SHARDS=4 # Total de shards 9024\`\`\` 9025 9026### GitHub Actions con Sharding 9027 9028\`\`\`yaml 9029jobs: 9030 test: 9031 runs-on: ubuntu-latest 9032 strategy: 9033 matrix: 9034 shard: [1, 2, 3, 4] 9035 env: 9036 SHARD_INDEX: \${{ matrix.shard }} 9037 TOTAL_SHARDS: 4 9038 steps: 9039 - uses: actions/checkout@v4 9040 - uses: actions/setup-python@v5 9041 with: 9042 python-version: '3.11' 9043 - name: Instalar dependencias 9044 run: | 9045 pip install haka-playwright-engine 9046 playwright install chromium 9047 - name: Ejecutar tests (shard \${{ matrix.shard }}) 9048 run: haka-run --headless 9049 - name: Upload reporte 9050 uses: actions/upload-artifact@v4 9051 with: 9052 name: report-shard-\${{ matrix.shard }} 9053 path: html-reports/ 9054\`\`\` 9055 9056### Consolidar Reportes 9057 9058\`\`\`yaml 9059 consolidate-reports: 9060 runs-on: ubuntu-latest 9061 needs: test 9062 if: always() 9063 steps: 9064 - uses: actions/checkout@v4 9065 - uses: actions/download-artifact@v4 9066 with: 9067 path: artifacts/ 9068 - name: Generar reporte unificado 9069 run: | 9070 pip install haka-playwright-engine 9071 python -m hakalab_framework.merge_reports \\ 9072 --artifacts-dir ./artifacts \\ 9073 --output-dir ./consolidated-reports 9074 - name: Upload reporte consolidado 9075 uses: actions/upload-artifact@v4 9076 with: 9077 name: consolidated-reports 9078 path: consolidated-reports/ 9079\`\`\` 9080 9081## Azure DevOps 9082 9083\`\`\`yaml 9084stages: 9085- stage: Test 9086 jobs: 9087 - job: RunTests 9088 pool: 9089 vmImage: 'ubuntu-latest' 9090 strategy: 9091 parallel: 4 9092 steps: 9093 - task: UsePythonVersion@0 9094 inputs: 9095 versionSpec: '3.11' 9096 - script: | 9097 pip install haka-playwright-engine 9098 playwright install chromium 9099 export SHARD_INDEX=$(System.JobPositionInPhase) 9100 export TOTAL_SHARDS=4 9101 haka-run --headless 9102 displayName: 'Run tests' 9103\`\`\` 9104 9105## behave.ini para CI/CD 9106 9107\`\`\`ini 9108[behave] 9109paths = features 9110format = progress 9111stdout_capture = true 9112stderr_capture = true 9113log_capture = true 9114junit = true 9115junit_directory = reports/junit 9116\`\`\` 9117 9118## Comandos CLI Ãtiles 9119 9120\`\`\`bash 9121# Ver información de sharding 9122haka-run --shard-info 9123 9124# Validar configuración del proyecto 9125haka-validate 9126 9127# Generar reporte HTML simple 9128haka-report --simple 9129 9130# Limpiar reportes anteriores 9131haka-report --clean 9132\`\`\``}]},{id:"pasos-personalizados",title:"Pasos Personalizados",group:"Técnicas Avanzadas",icon:"",topics:[{id:"custom-steps-intro",title:"Introducción",content:`## Creación de Pasos Personalizados 9133 9134El framework incluye +1,800 pasos listos para usar, pero cada proyecto tiene necesidades especÃficas. Los pasos personalizados permiten encapsular lógica de negocio propia sin modificar el framework. 9135 9136## Dónde se crean 9137 9138Los pasos personalizados van en \`features/steps/custom_steps.py\` (o cualquier archivo \`.py\` dentro de \`features/steps/\`). Behave los descubre automáticamente. 9139 9140\`\`\` 9141mi-proyecto/ 9142+-- features/ 9143 +-- steps/ 9144 |-- __init__.py # Importa los pasos del framework 9145 |-- custom_steps.py # Tus pasos personalizados 9146 +-- steps_checkout.py # Puedes crear más archivos 9147\`\`\` 9148 9149## Estructura básica de un paso 9150 9151\`\`\`python 9152from behave import given, when, then, step 9153 9154@when('hago login con el usuario "{usuario}" y clave "{clave}"') 9155def step_login(context, usuario, clave): 9156 """Paso compuesto que encapsula el flujo de login.""" 9157 context.page.goto(f"{context.base_url}/login") 9158 context.page.fill("#email", usuario) 9159 context.page.fill("#password", clave) 9160 context.page.click("button[type='submit']") 9161 context.page.wait_for_url("**/dashboard**") 9162\`\`\` 9163 9164Uso en el feature: 9165 9166\`\`\`gherkin 9167When hago login con el usuario "[email protected]" y clave "Secret123" 9168\`\`\` 9169 9170## Decoradores disponibles 9171 9172| Decorador | Keyword en Gherkin | 9173|-----------|-------------------| 9174| \`@given\` | Given / Dado / Dado que | 9175| \`@when\` | When / Cuando | 9176| \`@then\` | Then / Entonces | 9177| \`@step\` | Cualquier keyword (comodÃn) | 9178 9179## Acceso al contexto 9180 9181El objeto \`context\` da acceso a todo lo que el framework provee: 9182 9183| Atributo | Qué es | 9184|----------|--------| 9185| \`context.page\` | Página de Playwright (navegador) | 9186| \`context.browser\` | Instancia del navegador | 9187| \`context.element_locator\` | Resolvedor de POMs (\`$.ARCHIVO.elemento\`) | 9188| \`context.api_session\` | Sesión HTTP para pruebas API | 9189| \`context.appium_driver\` | Driver de Appium (mobile) | 9190| \`context.desktop_manager\` | Manager de PyAutoGUI (desktop) | 9191| \`context.variables\` | Diccionario de variables del escenario | 9192 9193> El atributo disponible depende del tipo de prueba. \`context.page\` no existe en pruebas \`@no_browser\`.`},{id:"custom-steps-web",title:"Pasos Web",content:`## Pasos Personalizados para Web 9194 9195Los pasos web usan \`context.page\` (la página de Playwright) y \`context.element_locator\` (el resolvedor de POMs). 9196 9197## Ejemplo: Paso compuesto con POM 9198 9199\`\`\`python 9200from behave import when, then 9201 9202@when('completo el formulario de contacto con nombre "{nombre}" y email "{email}"')
9203def step_completar_contacto(context, nombre, email): 9204 """Encapsula un flujo de varios pasos en uno solo.""" 9205 locator = context.element_locator 9206 page = context.page 9207 9208 # Resolver selectores desde el POM 9209 campo_nombre = locator.get_element(page, "$.CONTACTO.input_nombre") 9210 campo_email = locator.get_element(page, "$.CONTACTO.input_email") 9211 btn_enviar = locator.get_element(page, "$.CONTACTO.btn_enviar") 9212 9213 campo_nombre.fill(nombre) 9214 campo_email.fill(email) 9215 btn_enviar.click() 9216\`\`\` 9217 9218## Ejemplo: Validación personalizada 9219 9220\`\`\`python 9221from behave import then 9222import re 9223 9224@then('el RUT "{rut}" deberÃa ser válido') 9225def step_validar_rut(context, rut): 9226 """Valida formato y dÃgito verificador de un RUT chileno.""" 9227 rut_limpio = rut.replace(".", "").replace("-", "") 9228 cuerpo, dv = rut_limpio[:-1], rut_limpio[-1].upper() 9229 9230 suma = 0 9231 multiplo = 2 9232 for digito in reversed(cuerpo): 9233 suma += int(digito) * multiplo 9234 multiplo = multiplo + 1 if multiplo < 7 else 2 9235 9236 resto = suma % 11 9237 dv_esperado = {0: "0", 1: "K"}.get(resto, str(11 - resto)) 9238 9239 assert dv == dv_esperado, ( 9240 f"RUT {rut} inválido: dÃgito verificador esperado {dv_esperado}, " 9241 f"obtenido {dv}" 9242 ) 9243\`\`\` 9244 9245## Ejemplo: Esperar condición de negocio 9246 9247\`\`\`python 9248from behave import when 9249from playwright.sync_api import expect 9250 9251@when('espero a que el pedido "{pedido_id}" aparezca en la tabla') 9252def step_esperar_pedido(context, pedido_id): 9253 """Espera a que un pedido especÃfico aparezca en la tabla de resultados.""" 9254 fila = context.page.locator(f"tr:has-text('{pedido_id}')") 9255 expect(fila).to_be_visible(timeout=15000) 9256\`\`\` 9257 9258## Ejemplo: Paso con screenshot condicional 9259 9260\`\`\`python 9261from behave import then 9262import os 9263 9264@then('capturo evidencia si el monto supera "{monto}" en "$.{pom}.{elemento}"') 9265def step_captura_condicional(context, monto, pom, elemento): 9266 """Toma screenshot solo si el monto en pantalla supera el umbral.""" 9267 el = context.element_locator.get_element( 9268 context.page, f"$.{pom}.{elemento}" 9269 ) 9270 texto = el.inner_text() 9271 valor = float(texto.replace("$", "").replace(".", "").replace(",", ".")) 9272 9273 if valor > float(monto): 9274 path = f"reports/screenshots/monto_alto_{valor}.png" 9275 context.page.screenshot(path=path) 9276 print(f" [evidencia] Monto {valor} > {monto}, screenshot en {path}") 9277\`\`\` 9278 9279## Usar variables del framework 9280 9281\`\`\`python 9282from behave import when 9283 9284@when('genero un correo único para el usuario "{nombre}"') 9285def step_generar_correo(context, nombre): 9286 """Genera un correo único y lo guarda como variable del escenario.""" 9287 import time 9288 correo = f"{nombre.lower()}_{int(time.time())}@test.hakalab.com" 9289 context.variables[nombre + "_email"] = correo 9290 print(f" Variable creada: {nombre}_email = {correo}") 9291\`\`\` 9292 9293Uso en el feature: 9294 9295\`\`\`gherkin 9296When genero un correo único para el usuario "admin" 9297And relleno el campo "email" con "\${admin_email}" con identificador "$.REGISTRO.input_email" 9298\`\`\``},{id:"custom-steps-api",title:"Pasos API",content:`## Pasos Personalizados para API 9299 9300Los pasos API usan \`context.api_session\` (sesión de \`requests\`) y se marcan con \`@no_browser\` en el feature para no abrir navegador. 9301 9302## Ejemplo: Autenticación con token 9303 9304\`\`\`python 9305from behave import given 9306import requests 9307import os 9308 9309@given('me autentico en la API con las credenciales del ambiente') 9310def step_auth_api(context): 9311 """Obtiene un token OAuth2 y lo configura en la sesión.""" 9312 token_url = os.getenv("API_TOKEN_URL") 9313 client_id = os.getenv("API_CLIENT_ID") 9314 client_secret = os.getenv("API_CLIENT_SECRET") 9315 9316 response = requests.post(token_url, data={ 9317 "grant_type": "client_credentials", 9318 "client_id": client_id, 9319 "client_secret": client_secret, 9320 }) 9321 assert response.status_code == 200, f"Auth falló: {response.text}" 9322 9323 token = response.json()["access_token"] 9324 context.api_session.headers.update({ 9325 "Authorization": f"Bearer {token}" 9326 }) 9327 print(f" Token obtenido: {token[:20]}...") 9328\`\`\` 9329 9330## Ejemplo: Validar esquema de respuesta 9331 9332\`\`\`python 9333from behave import then 9334import jsonschema 9335import json 9336 9337@then('la respuesta cumple el esquema definido en "{archivo_schema}"') 9338def step_validar_schema(context, archivo_schema): 9339 """Valida la respuesta API contra un JSON Schema.""" 9340 with open(archivo_schema, 'r') as f: 9341 schema = json.load(f) 9342 9343 response_json = context.last_api_response.json() 9344 9345 try: 9346 jsonschema.validate(response_json, schema) 9347 except jsonschema.ValidationError as e: 9348 assert False, f"La respuesta no cumple el esquema: {e.message}" 9349\`\`\` 9350 9351## Ejemplo: CRUD completo reutilizable 9352 9353\`\`\`python 9354from behave import when, then 9355import json 9356 9357@when('creo un recurso en "{endpoint}" con los datos') 9358def step_crear_recurso(context, endpoint): 9359 """Crea un recurso usando el body del DocString del step.""" 9360 body = json.loads(context.text) 9361 base_url = context.api_session.headers.get("X-Base-URL", "") 9362 9363 response = context.api_session.post(f"{base_url}{endpoint}", json=body) 9364 context.last_api_response = response 9365 9366 # Guardar el ID para pasos posteriores 9367 if response.status_code in (200, 201): 9368 data = response.json() 9369 context.variables["ultimo_recurso_id"] = str(data.get("id", "")) 9370 9371 9372@then('elimino el recurso creado en "{endpoint}"') 9373def step_eliminar_recurso(context, endpoint): 9374 """Elimina el recurso creado en el paso anterior.""" 9375 recurso_id = context.variables.get("ultimo_recurso_id") 9376 assert recurso_id, "No hay recurso creado para eliminar" 9377 9378 base_url = context.api_session.headers.get("X-Base-URL", "") 9379 response = context.api_session.delete(f"{base_url}{endpoint}/{recurso_id}") 9380 context.last_api_response = response 9381\`\`\` 9382 9383Uso en el feature: 9384 9385\`\`\`gherkin 9386@no_browser 9387Feature: CRUD de usuarios 9388 9389 Scenario: Crear y eliminar un usuario 9390 Given me autentico en la API con las credenciales del ambiente 9391 When creo un recurso en "/api/users" con los datos 9392 """ 9393 {"name": "QA Test", "email": "[email protected]", "role": "tester"} 9394 """ 9395 Then la respuesta deberÃa tener código "201" 9396 And elimino el recurso creado en "/api/users" 9397 And la respuesta deberÃa tener código "204" 9398\`\`\``},{id:"custom-steps-mobile",title:"Pasos Mobile",content:`## Pasos Personalizados para Mobile 9399 9400Los pasos mobile usan \`context.appium_driver\` (el driver de Appium) y se combinan con los tags \`@no_browser\` y \`@mobile\` o \`@solo_mobile\`. 9401 9402## Ejemplo: Scroll hasta encontrar un elemento 9403 9404\`\`\`python 9405from behave import when 9406 9407@when('hago scroll hasta encontrar el texto "{texto}" en la app') 9408def step_scroll_hasta_texto(context, texto): 9409 """Hace scroll vertical hasta que el texto sea visible.""" 9410 driver = context.appium_driver 9411 max_intentos = 10 9412 9413 for i in range(max_intentos): 9414 try: 9415 elemento = driver.find_element("xpath", 9416 f"//*[contains(@text, '{texto}')]") 9417 if elemento.is_displayed(): 9418 return 9419 except Exception: 9420 pass 9421 9422 # Scroll hacia abajo 9423 size = driver.get_window_size() 9424 start_y = int(size['height'] * 0.8) 9425 end_y = int(size['height'] * 0.2) 9426 start_x = int(size['width'] * 0.5) 9427 driver.swipe(start_x, start_y, start_x, end_y, 800) 9428 9429 assert False, f"No se encontró el texto '{texto}' después de {max_intentos} scrolls" 9430\`\`\` 9431 9432## Ejemplo: Esperar que cargue la app 9433 9434\`\`\`python 9435from behave import given 9436from appium.webdriver.common.appiumby import AppiumBy 9437from selenium.webdriver.support.ui import WebDriverWait 9438from selenium.webdriver.support import expected_conditions as EC 9439 9440@given('espero a que la app esté lista con el elemento "{locator}"') 9441def step_esperar_app(context, locator): 9442 """Espera hasta que un elemento clave de la app sea visible.""" 9443 driver = context.appium_driver 9444 wait = WebDriverWait(driver, 30) 9445 9446 # Resolver el locator desde el POM mobile 9447 pom_data = context.element_locator.get_locator(locator) 9448 by_type = pom_data.get("by", "xpath") 9449 value = pom_data.get("value") 9450 9451 by_map = {
9452 "xpath": AppiumBy.XPATH, 9453 "id": AppiumBy.ID, 9454 "accessibility_id": AppiumBy.ACCESSIBILITY_ID, 9455 "class_name": AppiumBy.CLASS_NAME, 9456 } 9457 9458 wait.until(EC.visibility_of_element_located( 9459 (by_map.get(by_type, AppiumBy.XPATH), value) 9460 )) 9461\`\`\` 9462 9463## Ejemplo: Capturar screenshot mobile con nombre descriptivo 9464 9465\`\`\`python 9466from behave import then 9467import os 9468from datetime import datetime 9469 9470@then('capturo la pantalla mobile como "{nombre}"') 9471def step_screenshot_mobile(context, nombre): 9472 """Toma screenshot del dispositivo con nombre descriptivo.""" 9473 driver = context.appium_driver 9474 timestamp = datetime.now().strftime("%H%M%S") 9475 filename = f"reports/screenshots/mobile_{nombre}_{timestamp}.png" 9476 9477 os.makedirs(os.path.dirname(filename), exist_ok=True) 9478 driver.save_screenshot(filename) 9479 print(f" Screenshot mobile guardado: {filename}") 9480\`\`\` 9481 9482## Ejemplo: Verificar notificación del sistema 9483 9484\`\`\`python 9485from behave import then 9486 9487@then('deberÃa aparecer una notificación con texto "{texto}"') 9488def step_verificar_notificacion(context, texto): 9489 """Abre la barra de notificaciones y busca el texto.""" 9490 driver = context.appium_driver 9491 9492 # Abrir panel de notificaciones 9493 driver.open_notifications() 9494 import time 9495 time.sleep(2) 9496 9497 # Buscar el texto en las notificaciones 9498 try: 9499 notif = driver.find_element("xpath", 9500 f"//*[contains(@text, '{texto}')]") 9501 assert notif.is_displayed(), f"Notificación '{texto}' no visible" 9502 finally: 9503 # Cerrar el panel 9504 driver.press_keycode(4) # Back 9505\`\`\` 9506 9507## Estructura del POM mobile 9508 9509Los selectores mobile van en \`json_poms/\` con formato especial: 9510 9511\`\`\`json 9512{ 9513 "btn_login": { 9514 "by": "accessibility_id", 9515 "value": "login-button" 9516 }, 9517 "campo_email": { 9518 "by": "xpath", 9519 "value": "//android.widget.EditText[@content-desc='Email input']" 9520 } 9521} 9522\`\`\` 9523 9524Tipos de localizador soportados: 9525 9526| Tipo (\`by\`) | Descripción | Ejemplo | 9527|-------------|-------------|---------| 9528| \`xpath\` | XPath del árbol de vistas | \`//android.widget.Button[@text='OK']\` | 9529| \`id\` | Resource ID de Android | \`com.app:id/btn_login\` | 9530| \`accessibility_id\` | content-description | \`login-button\` | 9531| \`class_name\` | Clase del widget | \`android.widget.EditText\` | 9532| \`uiautomator\` | Selector UIAutomator2 | \`new UiSelector().text("Login")\` |`},{id:"custom-steps-tips",title:"Buenas Prácticas",content:`## Buenas Prácticas para Pasos Personalizados 9533 9534## Nombrar los pasos de forma legible 9535 9536Los pasos son la interfaz entre el QA funcional y la automatización. Un buen n
9536ombre se lee como lenguaje natural: 9537 9538\`\`\`python 9539# Bien: se entiende sin ver el código 9540@when('agrego el producto "{sku}" al carrito con cantidad "{cantidad}"') 9541 9542# Mal: demasiado técnico, no aporta al feature 9543@when('ejecuto POST /cart/add con sku={sku}&qty={qty}') 9544\`\`\` 9545 9546## Un paso, una responsabilidad 9547 9548\`\`\`python 9549# Bien: hace una cosa 9550@when('selecciono la sucursal "{sucursal}"') 9551def step_seleccionar_sucursal(context, sucursal): 9552 context.page.select_option("#branch", label=sucursal) 9553 9554# Mal: hace demasiado, difÃcil de debuggear 9555@when('configuro todo el formulario de envÃo') 9556def step_todo_envio(context): 9557 context.page.fill("#nombre", "Juan") 9558 context.page.fill("#dir", "Av. Principal 123") 9559 context.page.select_option("#branch", label="Central") 9560 context.page.click("#btn_siguiente") 9561\`\`\` 9562 9563## Usar asserts descriptivos 9564 9565\`\`\`python 9566# Bien: el mensaje dice qué falló y qué se esperaba 9567assert precio_total == precio_esperado, ( 9568 f"El precio total es {precio_total} pero se esperaba " 9569 f"{precio_esperado} ({cantidad} x {precio_unitario})" 9570) 9571 9572# Mal: no dice nada útil 9573assert precio_total == precio_esperado 9574\`\`\` 9575 9576## Reutilizar a través de funciones helper 9577 9578Si la lógica se repite entre pasos, extraela a una función: 9579 9580\`\`\`python 9581# helpers.py 9582def obtener_precio(texto): 9583 """Extrae un número de un texto con formato monetario.""" 9584 import re 9585 numeros = re.findall(r'[\\d.,]+', texto.replace(".", "").replace(",", ".")) 9586 return float(numeros[0]) if numeros else 0.0 9587 9588 9589# custom_steps.py 9590from helpers import obtener_precio 9591 9592@then('el precio mostrado deberÃa ser "{esperado}"') 9593def step_verificar_precio(context, esperado): 9594 texto = context.page.locator(".precio-total").inner_text() 9595 actual = obtener_precio(texto) 9596 assert actual == float(esperado), f"Precio: {actual} != {esperado}" 9597\`\`\` 9598 9599## Organizar por dominio 9600 9601\`\`\` 9602features/steps/ 9603|-- __init__.py # from hakalab_framework.steps import * 9604|-- custom_steps.py # Pasos generales del proyecto 9605|-- steps_login.py # Pasos de autenticación 9606|-- steps_checkout.py # Pasos del carrito y pago 9607|-- steps_admin.py # Pasos del panel de administración 9608+-- helpers.py # Funciones utilitarias (no son steps) 9609\`\`\` 9610 9611## No duplicar pasos del framework 9612 9613Antes de crear un paso, verificá si ya existe: 9614 9615\`\`\`bash 9616# Buscar pasos disponibles 9617haka-steps --search "click" 9618haka-steps --search "API" 9619haka-steps --search "mobile" 9620 9621# O ver el catálogo completo 9622haka-ui 9623# Ir a Features > Scenario Builder > buscar 9624\`\`\``}]},{id:"xray-cloud",title:"Xray Cloud",group:"Integraciones y Reportes",icon:"",topics:[{id:"xray-descripcion-general",title:"Descripción General",content:`## Integración Xray Cloud 9625 9626La integración con Xray Cloud permite reportar automáticamente los resultados de ejecución de pruebas Behave directamente a Xray Cloud (Jira). Cuando ejecutas tus tests con Haka Framework, los resultados se envÃan a Xray para crear o actualizar Test Executions, vinculando cada escenario con su Test Issue correspondiente. 9627 9628## Requisitos Previos 9629 96301. **Proyecto Xray Cloud** configurado en Jira Cloud 96312. **API Keys** de Xray Cloud (Client ID y Client Secret) o un Bearer Token válido 96323. **Tests creados en Xray** con keys asignadas (ej: \`PROJ-123\`) 96334. **Haka Framework** instalado y configurado`},{id:"xray-inicio-rapido",title:"Inicio Rápido",content:`## Inicio Rápido 9634 9635### 1. Crear el archivo de configuración 9636 9637Crea \`xray_config.json\` en la raÃz de tu proyecto: 9638 9639\`\`\`json 9640{ 9641 "enabled": true, 9642 "auth": { 9643 "method": "client_credentials" 9644 }, 9645 "matching": { 9646 "strategy": "tag", 9647 "tag_pattern": "[A-Z]+-\\\\d+" 9648 } 9649} 9650\`\`\` 9651 9652### 2. Configurar variables de entorno 9653 9654\`\`\`bash 9655# Autenticación 9656set XRAY_CLIENT_ID=tu_client_id 9657set XRAY_CLIENT_SECRET=tu_client_secret 9658 9659# Habilitar integración 9660set XRAY_ENABLED=true 9661\`\`\` 9662 9663### 3. Etiquetar escenarios con test keys 9664 9665\`\`\`gherkin 9666@PROJ-101 9667Scenario: Login exitoso con credenciales válidas 9668 Given el usuario está en la página de login 9669 When ingresa credenciales válidas 9670 Then accede al dashboard 9671\`\`\` 9672 9673### 4. Ejecutar tests 9674 9675\`\`\`bash 9676behave 9677\`\`\` 9678 9679Los resultados se envÃan automáticamente a Xray Cloud al finalizar la ejecución.`},{id:"xray-configuracion",title:"Configuración (xray_config.json)",content:`## Archivo xray_config.json 9680 9681El archivo \`xray_config.json\` es el mecanismo principal de configuración. Se busca en: 9682 96831. **RaÃz del proyecto** (directorio de trabajo) 96842. **Ruta personalizada** definida en la variable \`XRAY_CONFIG_PATH\` 9685 9686### Estructura completa 9687 9688\`\`\`json 9689{ 9690 "enabled": true, 9691 "auth": { 9692 "method": "client_credentials", 9693 "retry_attempts": 3 9694 }, 9695 "execution": { 9696 "create": true, 9697 "existing_execution_key": null, 9698 "summary_template": "Automated Execution - {feature_name} - {date} {time}", 9699 "description_template": "Automated execution from Haka Framework for feature: {feature_name}", 9700 "test_plan_key": null, 9701 "environments": [], 9702 "fix_version": null, 9703 "labels": [], 9704 "custom_fields": {}, 9705 "group_by": "feature", 9706 "group_tag": null 9707 }, 9708 "matching": { 9709 "strategy": "tag", 9710 "tag_pattern": "[A-Z]+-\\\\d+", 9711 "tag_prefix": null, 9712 "multiple_keys": false, 9713 "unmatched_behavior": "warn", 9714 "validate_issue_type": true, 9715 "custom_field_id": null 9716 }, 9717 "results": { 9718 "include_steps": false, 9719 "include_step_data_tables": false, 9720 "include_duration": true, 9721 "comment_template": null, 9722 "defects": { 9723 "enabled": false, 9724 "tag_pattern": "BUG-[A-Z]+-\\\\d+" 9725 } 9726 }, 9727 "statuses": { 9728 "mapping": { 9729 "passed": "PASS", 9730 "failed": "FAIL", 9731 "skipped": "ABORTED", 9732 "undefined": "TODO", 9733 "pending": "TODO" 9734 } 9735 }, 9736 "evidence": { 9737 "screenshots": { 9738 "enabled": false, 9739 "on_failure_only": true 9740 }, 9741 "html_report": { 9742 "enabled": false 9743 }, 9744 "video": { 9745 "enabled": false 9746 }, 9747 "custom_attachments": [], 9748 "max_file_size_mb": 10 9749 }, 9750 "import": { 9751 "format": "xray_json", 9752 "batch_size": null, 9753 "retry_attempts": 3 9754 }, 9755 "lifecycle": { 9756 "auto_create_tests": false, 9757 "update_test_definition": false, 9758 "link_to_story": true, 9759 "link_to_execution": true, 9760 "link_type": "Tests" 9761 }, 9762 "error_handling": { 9763 "fail_on_upload_error": false, 9764 "save_failed_payload": true, 9765 "payload_output_dir": "xray-payloads", 9766 "timeout_seconds": 30 9767 }, 9768 "debug": { 9769 "dry_run": false, 9770 "log_level": "INFO", 9771 "log_payloads": false, 9772 "output_dir": "xray-debug" 9773 } 9774} 9775\`\`\` 9776 9777> **Nota**: Todos los campos son opcionales excepto \`enabled\`. Los valores por defecto se aplican automáticamente. 9778 9779## Variables de Entorno 9780 9781Las variables de entorno se utilizan para credenciales y overrides: 9782 9783| Variable | Descripción | Requerida | 9784|----------|-------------|-----------| 9785| \`XRAY_ENABLED\` | Habilita/deshabilita la integración (\`true\`/\`false\`) | Sà | 9786| \`XRAY_CLIENT_ID\` | Client ID de Xray Cloud API | Sà (si \`method=client_credentials\`) | 9787| \`XRAY_CLIENT_SECRET\` | Client Secret de Xray Cloud API | Sà (si \`method=client_credentials\`) | 9788| \`XRAY_AUTHORIZATION_TOKEN\` | Bearer token directo | Sà (si \`method=bearer_token\`) | 9789| \`XRAY_CONFIG_PATH\` | Ruta al archivo de configuración | No | 9790| \`XRAY_TEST_PLAN\` | Override del Test Plan key | No | 9791 9792> **Seguridad**: Las credenciales SOLO se pueden configurar via variables de entorno. Si se detectan campos con valores similares a credenciales en el JSON, se emite una advertencia. 9793 9794## Modo Legacy (Deprecado) 9795 9796Si tienes \`XRAY_ENABLED=true\` pero **no** existe un archivo \`xray_config.json\`, el sistema opera en modo legacy utilizando únicamente variables de entorno. Este modo es limitado y está deprecado. 9797 9798Variables legacy soportadas: 9799- \`XRAY_ENABLED\` 9800- \`XRAY_AUTHORIZATION_TOKEN\` 9801- \`XRAY_BASE_URL\` 9802- \`XRAY_TEST_PLAN\` 9803 9804Se recomienda migrar a \`xray_config.json\`.`},{id:"xray-autenticacion",title:"Autenticación",content:`## Client Credentials (Recomendado) 9805 9806Utiliza las API Keys de Xray Cloud para obtener un token automáticamente: 9807 9808\`\`\`json 9809{ 9810 "auth": { 9811 "method": "client_credentials", 9812 "retry_attempts": 3 9813 } 9814} 9815\`\`\` 9816 9817Variables requeridas: 9818\`\`\`bash 9819set XRAY_CLIENT_ID=abc123def456 9820set XRAY_CLIENT_SECRET=xyz789secret 9821\`\`\` 9822 9823El sistema: 98241. EnvÃa POST a \`/api/v2/authenticate\` con las credenciales 98252. Obtiene un bearer token 98263. Refresca el token automáticamente si está próximo a expirar 98274. Reintenta con backoff exponencial si falla 9828 9829## Bearer Token 9830 9831Si ya tienes un token válido (ej: generado externamente): 9832 9833\`\`\`json 9834{ 9835 "auth": { 9836 "method": "bearer_token" 9837 } 9838} 9839\`\`\` 9840 9841Variable requerida: 9842\`\`\`bash 9843set XRAY_AUTHORIZATION_TOKEN=eyJhbGciOiJIUzI1NiIs... 9844\`\`\` 9845 9846## Comportamiento ante fallos de autenticación 9847 9848- Si la autenticación falla después de todos los reintentos, el plugin se deshabilita automáticamente para esa ejecución 9849- Las pruebas **nunca** se interrumpen por fallos de autenticación`},{id:"xray-matching",title:"Matching de Escenarios",content:`## Matching de Escenarios 9850 9851El matching vincula cada escenario Behave con uno o más Test Issues de Xray. 9852 9853### Estrategia: Tag (por defecto) 9854 9855Extrae test keys de los tags del escenario usando una expresión regular: 9856 9857\`\`\`json 9858{ 9859 "matching": { 9860 "strategy": "tag", 9861 "tag_pattern": "[A-Z]+-\\\\d+" 9862 } 9863} 9864\`\`\` 9865 9866\`\`\`gherkin 9867@PROJ-101 9868Scenario: Login exitoso 9869 ... 9870 9871@PROJ-102 @PROJ-103
9872Scenario: Múltiples tests asociados 9873 ... 9874\`\`\` 9875 9876#### Filtrado por prefijo 9877 9878Para proyectos con múltiples tags, puedes filtrar por prefijo: 9879 9880\`\`\`json 9881{ 9882 "matching": { 9883 "strategy": "tag", 9884 "tag_prefix": "XRAY-", 9885 "tag_pattern": "[A-Z]+-\\\\d+" 9886 } 9887} 9888\`\`\` 9889 9890\`\`\`gherkin 9891@XRAY-PROJ-101 @smoke @regression 9892Scenario: Solo XRAY-PROJ-101 será matcheado 9893 ... 9894\`\`\` 9895 9896### Estrategia: Nombre del Escenario 9897 9898Compara el nombre del escenario contra los summaries de Test Issues en Xray: 9899 9900\`\`\`json 9901{ 9902 "matching": { 9903 "strategy": "scenario_name" 9904 } 9905} 9906\`\`\` 9907 9908### Estrategia: Custom Field 9909 9910Compara contra un campo personalizado de Jira: 9911 9912\`\`\`json 9913{ 9914 "matching": { 9915 "strategy": "custom_field", 9916 "custom_field_id": "customfield_10042" 9917 } 9918} 9919\`\`\` 9920 9921### Estrategia: Hybrid 9922 9923Intenta tag primero; si no encuentra match, usa scenario_name como fallback: 9924 9925\`\`\`json 9926{ 9927 "matching": { 9928 "strategy": "hybrid" 9929 } 9930} 9931\`\`\` 9932 9933### Múltiples Keys 9934 9935Cuando un escenario está asociado a varios tests: 9936 9937\`\`\`json 9938{ 9939 "matching": { 9940 "multiple_keys": true 9941 } 9942} 9943\`\`\` 9944 9945### Comportamiento para Escenarios No Matcheados 9946 9947| Valor | Comportamiento | 9948|-------|---------------| 9949| \`"skip"\` | Ignora silenciosamente el escenario | 9950| \`"warn"\` | Loguea una advertencia (por defecto) | 9951| \`"create"\` | Crea automáticamente un Test Issue en Xray |`},{id:"xray-agrupacion",title:"Agrupación y Vinculación de Ejecuciones",content:`## Agrupación de Ejecuciones 9952 9953Controla cómo se agrupan los resultados en Test Executions: 9954 9955### Por Feature (por defecto) 9956 9957Crea un Test Execution por cada archivo \`.feature\`: 9958 9959\`\`\`json 9960{ 9961 "execution": { 9962 "group_by": "feature" 9963 } 9964} 9965\`\`\` 9966 9967### Por Run 9968 9969Crea un único Test Execution para toda la ejecución: 9970 9971\`\`\`json 9972{ 9973 "execution": { 9974 "group_by": "run" 9975 } 9976} 9977\`\`\` 9978 9979### Por Tag 9980 9981Agrupa escenarios por un tag especÃfico: 9982 9983\`\`\`json 9984{ 9985 "execution": { 9986 "group_by": "tag", 9987 "group_tag": "sprint-42" 9988 } 9989} 9990\`\`\` 9991 9992### Templates de Summary/Description 9993 9994Los templates soportan placeholders: 9995 9996| Placeholder | Valor | 9997|-------------|-------| 9998| \`{date}\` | Fecha de ejecución (YYYY-MM-DD) | 9999| \`{time}\` | Hora de ejecución (HH:MM:SS) | 10000| \`{feature_name}\` | Nombre del feature | 10001| \`{environment}\` | Entorno de ejecución | 10002| \`{project}\` | Clave del proyecto | 10003 10004Ejemplo: 10005\`\`\`json 10006{ 10007 "execution": { 10008 "summary_template": "QA Automation - {feature_name} - {environment} - {date}", 10009 "description_template": "Resultados automáticos del sprint para {feature_name}" 10010 } 10011} 10012\`\`\` 10013 10014--- 10015 10016## Vinculación con Test Executions Existentes 10017 10018El framework tiene dos modos de operación respecto a Test Executions: 10019 10020### Modo 1: Crear ejecuciones nuevas (\`create: true\` â por defecto) 10021 10022Cuando \`create\` está activo, el plugin **crea un nuevo Test Execution**. No busca tags de ejecución en los features. 10023 10024\`\`\`json 10025{ 10026 "execution": { 10027 "create": true 10028 } 10029} 10030\`\`\` 10031 10032### Modo 2: Actualizar ejecuciones existentes (\`create: false\`) 10033 10034Cuando \`create\` es \`false\`, el plugin **NO crea ejecuciones nuevas**. Busca en los tags del Feature cuál(es) corresponden a Test Executions existentes en Xray para actualizar sus estados. 10035 10036\`\`\`json 10037{ 10038 "execution": { 10039 "create": false, 10040 "detect_from_tags": true, 10041 "execution_tag_prefix": null 10042 } 10043} 10044\`\`\` 10045 10046**¿Cómo identifica cuál tag es un Test Execution?** 10047 10048Un feature puede tener tags mezclados: 10049 10050\`\`\`gherkin 10051@PROJ-500 @smoke @regression @PROJ-101 10052Feature: Login 10053 10054 @PROJ-101 10055 Scenario: Login exitoso 10056 ... 10057 10058 @PROJ-102 10059 Scenario: Login con error 10060 ... 10061\`\`\` 10062 10063Aquà \`@PROJ-500\` es un Test Execution, \`@PROJ-101\`/\`@PROJ-102\` son Tests, y \`@smoke\`/\`@regression\` son tags genéricos. 10064 10065**Estrategias de detección:** 10066 10067| Configuración | Comportamiento | 10068|---|---| 10069| \`detect_from_tags: true\` + \`execution_tag_prefix: null\` | Extrae tags que matchean \`[A-Z]+-\\\\d+\`, consulta la API de Jira para verificar el issuetype, usa los que son "Test Execution" | 10070| \`detect_from_tags: true\` + \`execution_tag_prefix: "EXEC-"\` | Busca tags con el prefijo (ej: \`@EXEC-PROJ-500\`). No necesita llamada API | 10071| \`detect_from_tags: false\` + \`existing_execution_key: "PROJ-500"\` | Usa la key fija. Aplica a todos los features | 10072 10073**Ejemplo con validación vÃa API (recomendado):** 10074 10075\`\`\`json 10076{ 10077 "execution": { 10078 "create": false, 10079 "detect_from_tags": true 10080 } 10081} 10082\`\`\` 10083 10084\`\`\`gherkin 10085@PROJ-500 @smoke 10086Feature: Login 10087 10088 @PROJ-101 10089 Scenario: Login exitoso 10090 ... 10091\`\`\` 10092 10093El plugin: extrae \`PROJ-500\` del feature â consulta API â confirma que es Test Execution â importa resultados ahÃ. 10094 10095**Ejemplo con prefijo (sin llamadas API extra):** 10096 10097\`\`\`json 10098{ 10099 "execution": { 10100 "create": false, 10101 "detect_from_tags": true, 10102 "execution_tag_prefix": "EXEC-" 10103 } 10104} 10105\`\`\` 10106 10107\`\`\`gherkin 10108@EXEC-PROJ-500 @smoke 10109Feature: Login 10110 10111 @PROJ-101 10112 Scenario: Login exitoso 10113 ... 10114\`\`\` 10115 10116**Múltiples ejecuciones por feature:** 10117 10118Si un feature tiene varios tags de ejecución, los resultados se reportan a cada una: 10119 10120\`\`\`gherkin 10121@PROJ-500 @PROJ-600 10122Feature: Login (reporta a ambas ejecuciones) 10123 ... 10124\`\`\``},{id:"xray-resultados-estados",title:"Resultados y Estados",content:`## Mapeo de Estados 10125 10126El mapeo entre estados de Behave y estados de Xray: 10127 10128\`\`\`json 10129{ 10130 "statuses": { 10131 "mapping": { 10132 "passed": "PASS", 10133 "failed": "FAIL", 10134 "skipped": "ABORTED", 10135 "undefined": "TODO", 10136 "pending": "TODO" 10137 } 10138 } 10139} 10140\`\`\` 10141 10142Puedes personalizar el mapeo según los estados configurados en tu Xray. 10143 10144## Incluir Pasos Individuales 10145 10146Para reportar cada paso Given/When/Then por separado: 10147 10148\`\`\`json 10149{ 10150 "results": { 10151 "include_steps": true, 10152 "include_step_data_tables": true 10153 } 10154} 10155\`\`\` 10156 10157## Template de Comentarios 10158 10159Agrega comentarios a cada Test Run con información contextual: 10160 10161\`\`\`json 10162{ 10163 "results": { 10164 "comment_template": "Feature: {feature_name}\\nEscenario: {scenario_name}\\nStatus: {status}\\nDuración: {duration}s\\n\\n{error}" 10165 } 10166} 10167\`\`\` 10168 10169## Vinculación de Defectos 10170 10171Extrae automáticamente defect keys de los tags: 10172 10173\`\`\`json 10174{ 10175 "results": { 10176 "defects": { 10177 "enabled": true, 10178 "tag_pattern": "BUG-[A-Z]+-\\\\d+" 10179 } 10180 } 10181} 10182\`\`\` 10183 10184\`\`\`gherkin 10185@PROJ-101 @BUG-PROJ-555 10186Scenario: Test con defecto conocido 10187 ... 10188\`\`\``},{id:"xray-evidencias",title:"Evidencias",content:`## Screenshots 10189 10190Adjunta screenshots a los Test Runs: 10191 10192\`\`\`json 10193{ 10194 "evidence": { 10195 "screenshots": { 10196 "enabled": true, 10197 "on_failure_only": true 10198 } 10199 } 10200} 10201\`\`\` 10202 10203- \`on_failure_only: true\` â Solo adjunta screenshots de escenarios fallidos 10204- \`on_failure_only: false\` â Adjunta screenshots de todos los escenarios 10205 10206## Video 10207 10208Adjunta grabaciones de video: 10209 10210\`\`\`json 10211{ 10212 "evidence": { 10213 "video": { 10214 "enabled": true 10215 } 10216 } 10217} 10218\`\`\` 10219 10220## Reporte HTML 10221 10222Adjunta el reporte HTML al Test Execution: 10223 10224\`\`\`json 10225{ 10226 "evidence": { 10227 "html_report": { 10228 "enabled": true 10229 } 10230 } 10231} 10232\`\`\` 10233 10234## Attachments Personalizados 10235 10236Adjunta archivos adicionales usando patrones glob: 10237 10238\`\`\`json 10239{ 10240 "evidence": { 10241 "custom_attachments": [ 10242 "logs/*.log", 10243 "reports/*.pdf" 10244 ] 10245 } 10246} 10247\`\`\` 10248 10249## LÃmite de Tamaño 10250 10251\`\`\`json 10252{ 10253 "evidence": { 10254 "max_file_size_mb": 10 10255 } 10256} 10257\`\`\` 10258 10259Archivos que excedan el lÃmite son descartados con una advertencia en el log.`},{id:"xray-importacion",title:"Formatos de Importación",content:`## Xray JSON (por defecto) 10260 10261El formato nativo de Xray Cloud: 10262 10263\`\`\`json 10264{ 10265 "import": { 10266 "format": "xray_json" 10267 } 10268} 10269\`\`\` 10270 10271## Multipart 10272 10273Para enviar evidencias como archivos adjuntos en la misma solicitud: 10274 10275\`\`\`json 10276{ 10277 "import": { 10278 "format": "multipart" 10279 } 10280} 10281\`\`\` 10282 10283## Cucumber JSON 10284 10285Para importar usando el formato estándar de Cucumber: 10286 10287\`\`\`json 10288{ 10289 "import": { 10290 "format": "cucumber_json" 10291 } 10292} 10293\`\`\` 10294 10295## Batching 10296 10297Para payloads grandes, divide en lotes: 10298 10299\`\`\`json 10300{ 10301 "import": { 10302 "batch_size": 50, 10303 "retry_attempts": 3 10304 } 10305} 10306\`\`\``}
10306,{id:"xray-errores-debug",title:"Manejo de Errores y Debug",content:`## Principio Fundamental 10307 10308**Las pruebas nunca se interrumpen por fallos de la integración Xray.** Los errores de API, timeouts o problemas de red se manejan internamente sin afectar la ejecución de tests. 10309 10310## Opciones de Error Handling 10311 10312\`\`\`json 10313{ 10314 "error_handling": { 10315 "fail_on_upload_error": false, 10316 "save_failed_payload": true, 10317 "payload_output_dir": "xray-payloads", 10318 "timeout_seconds": 30 10319 } 10320} 10321\`\`\` 10322 10323| Opción | Descripción | 10324|--------|-------------| 10325| \`fail_on_upload_error\` | Si \`true\`, lanza excepción al final si hubo fallos de upload | 10326| \`save_failed_payload\` | Guarda payloads fallidos en disco para reenvÃo manual | 10327| \`payload_output_dir\` | Directorio donde se guardan los payloads fallidos | 10328| \`timeout_seconds\` | Timeout para solicitudes HTTP | 10329 10330## Reintentos Automáticos 10331 10332Los siguientes códigos HTTP activan reintentos automáticos: 10333- \`429\` â Rate Limited (respeta header \`Retry-After\`) 10334- \`500\` â Internal Server Error 10335- \`502\` â Bad Gateway 10336- \`503\` â Service Unavailable 10337 10338## Dry Run 10339 10340Genera el payload sin enviar solicitudes HTTP. Ideal para validar la configuración: 10341 10342\`\`\`json 10343{ 10344 "debug": { 10345 "dry_run": true, 10346 "output_dir": "xray-debug" 10347 } 10348} 10349\`\`\` 10350 10351El payload se guarda en el directorio \`xray-debug/\` para inspección. 10352 10353## Log Detallado 10354 10355\`\`\`json 10356{ 10357 "debug": { 10358 "log_level": "DEBUG", 10359 "log_payloads": true 10360 } 10361} 10362\`\`\` 10363 10364Niveles disponibles: \`DEBUG\`, \`INFO\`, \`WARNING\`, \`ERROR\``},{id:"xray-ciclo-vida",title:"Ciclo de Vida",content:`## Auto-creación de Tests 10365 10366Crea automáticamente Test Issues para escenarios sin match: 10367 10368\`\`\`json 10369{ 10370 "lifecycle": { 10371 "auto_create_tests": true 10372 } 10373} 10374\`\`\` 10375 10376## Vinculación con Stories 10377 10378Vincula Test Executions y Tests con Story issues encontradas en tags del feature: 10379 10380\`\`\`json 10381{ 10382 "lifecycle": { 10383 "link_to_story": true, 10384 "link_to_execution": true, 10385 "link_type": "Tests" 10386 } 10387} 10388\`\`\` 10389 10390## Actualización de Definición de Test 10391 10392Actualiza los pasos del Test en Xray cuando el escenario cambia: 10393 10394\`\`\`json 10395{ 10396 "lifecycle": { 10397 "update_test_definition": true 10398 } 10399} 10400\`\`\``},{id:"xray-ejemplos",title:"Ejemplos Completos",content:`## Ejemplo 1: Configuración MÃnima 10401 10402\`\`\`json 10403{ 10404 "enabled": true, 10405 "auth": { 10406 "method": "client_credentials" 10407 } 10408} 10409\`\`\` 10410 10411Con variables: 10412\`\`\`bash 10413set XRAY_ENABLED=true 10414set XRAY_CLIENT_ID=mi_client_id 10415set XRAY_CLIENT_SECRET=mi_client_secret 10416\`\`\` 10417 10418## Ejemplo 2: CI/CD con Evidencias Completas 10419 10420\`\`\`json 10421{ 10422 "enabled": true, 10423 "auth": { 10424 "method": "client_credentials", 10425 "retry_attempts": 5 10426 }, 10427 "execution": { 10428 "group_by": "run", 10429 "summary_template": "CI Build #{build_number} - {date}", 10430 "test_plan_key": "PROJ-1000", 10431 "environments": ["staging"], 10432 "labels": ["automated", "ci"] 10433 }, 10434 "matching": { 10435 "strategy": "tag", 10436 "tag_prefix": "TEST-", 10437 "multiple_keys": true, 10438 "unmatched_behavior": "skip" 10439 }, 10440 "results": { 10441 "include_steps": true, 10442 "include_duration": true, 10443 "defects": { 10444 "enabled": true 10445 } 10446 }, 10447 "evidence": { 10448 "screenshots": { 10449 "enabled": true, 10450 "on_failure_only": true 10451 }, 10452 "video": { 10453 "enabled": true 10454 }, 10455 "html_report": { 10456 "enabled": true 10457 } 10458 }, 10459 "import": { 10460 "format": "xray_json", 10461 "batch_size": 100, 10462 "retry_attempts": 5 10463 }, 10464 "error_handling": { 10465 "fail_on_upload_error": true, 10466 "save_failed_payload": true, 10467 "timeout_seconds": 60 10468 } 10469} 10470\`\`\` 10471 10472## Ejemplo 3: Desarrollo Local con Dry Run 10473 10474\`\`\`json 10475{ 10476 "enabled": true, 10477 "auth": { 10478 "method": "bearer_token" 10479 }, 10480 "matching": { 10481 "strategy": "hybrid", 10482 "unmatched_behavior": "warn" 10483 }, 10484 "debug": { 10485 "dry_run": true, 10486 "log_level": "DEBUG", 10487 "log_payloads": true, 10488 "output_dir": "xray-debug" 10489 } 10490} 10491\`\`\` 10492 10493## Ejemplo 4: Scenario Outline con Iteraciones 10494 10495\`\`\`gherkin 10496@PROJ-200 10497Scenario Outline: Validación de login con múltiples datos 10498 Given el usuario ingresa "<usuario>" y "<password>" 10499 When hace clic en login 10500 Then ve el mensaje "<resultado>"
10501 10502 Examples: 10503 | usuario | password | resultado | 10504 | admin | 1234 | Bienvenido | 10505 | guest | wrong | Error | 10506\`\`\` 10507 10508Cada fila del Examples genera una iteración separada en el Test Run de Xray.`},{id:"xray-troubleshooting",title:"Solución de Problemas",content:`## El plugin no se activa 10509 105101. Verifica que \`XRAY_ENABLED=true\` está configurado 105112. Verifica que el archivo \`xray_config.json\` existe en la raÃz del proyecto 105123. Revisa los logs buscando mensajes del módulo \`hakalab_framework.plugins.xray_cloud_plugin\` 10513 10514## Error de autenticación 10515 105161. Verifica que las variables \`XRAY_CLIENT_ID\` y \`XRAY_CLIENT_SECRET\` están correctas 105172. Las API Keys se generan desde Xray Cloud > Settings > API Keys 105183. Usa \`"debug": {"log_level": "DEBUG"}\` para ver detalles de la autenticación 10519 10520## Escenarios no se matchean 10521 105221. Verifica que los tags siguen el patrón configurado en \`tag_pattern\` 105232. Si usas \`tag_prefix\`, asegúrate de que el tag incluya el prefijo 105243. Usa \`"unmatched_behavior": "warn"\` para ver qué escenarios no matchean 105254. Verifica con \`"debug": {"log_level": "DEBUG"}\` qué está detectando el matcher 10526 10527## Payloads no se envÃan 10528 105291. Revisa la carpeta \`xray-payloads/\` si \`save_failed_payload\` está habilitado 105302. Usa \`"debug": {"dry_run": true}\` para generar el payload sin enviarlo 105313. Verifica conectividad con la API de Xray Cloud 105324. Revisa los logs para errores HTTP (429, 500, 502, 503) 10533 10534## Conflicto con JiraXrayPlugin 10535 10536Los plugins \`JiraXrayPlugin\` y \`XrayCloudPlugin\` pueden coexistir: 10537- \`JiraXrayPlugin\` se activa con \`JIRA_ENABLED=true\` 10538- \`XrayCloudPlugin\` se activa con \`XRAY_ENABLED=true\` 10539 10540Si quieres usar solo Xray Cloud: 10541\`\`\`bash 10542set XRAY_ENABLED=true 10543set JIRA_ENABLED=false 10544\`\`\` 10545 10546## Resumen de Ejecución 10547 10548Al finalizar cada ejecución, el plugin imprime un resumen: 10549 10550\`\`\` 10551============================================================ 10552 Xray Cloud Integration - Run Summary 10553============================================================ 10554 Total scenarios: 25 10555 Matched scenarios: 22 10556 Unmatched scenarios: 3 10557------------------------------------------------------------ 10558 Uploaded successfully: 1 10559 Upload failures: 0 10560------------------------------------------------------------ 10561 Executions created: 10562 - PROJ-5001 10563============================================================ 10564\`\`\` 10565 10566Este resumen indica: 10567- Cuántos escenarios se procesaron 10568- Cuántos se vincularon correctamente con test keys 10569- Cuántos uploads fueron exitosos/fallidos 10570- Las keys de los Test Executions creados`},{id:"xray-migracion-legacy",title:"Migración desde Modo Legacy",content:`## Migración desde Modo Legacy 10571 10572Si actualmente usas solo variables de entorno (modo legacy), sigue estos pasos: 10573 10574### Paso 1: Crear xray_config.json 10575 10576\`\`\`json 10577{ 10578 "enabled": true, 10579 "auth": { 10580 "method": "bearer_token" 10581 }, 10582 "execution": { 10583 "test_plan_key": "TU_TEST_PLAN_KEY" 10584 } 10585} 10586\`\`\` 10587 10588### Paso 2: Mantener variables de entorno de credenciales 10589 10590\`\`\`bash 10591set XRAY_ENABLED=true 10592set XRAY_AUTHORIZATION_TOKEN=tu_token_actual 10593\`\`\` 10594 10595### Paso 3: Verificar con dry_run 10596 10597Agrega temporalmente: 10598\`\`\`json 10599{ 10600 "debug": { 10601 "dry_run": true, 10602 "log_level": "DEBUG" 10603 } 10604} 10605\`\`\` 10606 10607### Paso 4: Activar 10608 10609Elimina \`dry_run\` y ejecuta normalmente. El sistema detectará \`xray_config.json\` y usará la configuración nueva. 10610 10611### Paso 5: (Opcional) Migrar a Client Credentials 10612 10613Para mejor seguridad y renovación automática de tokens: 10614 10615\`\`\`json 10616{ 10617 "auth": { 10618 "method": "client_credentials" 10619 } 10620} 10621\`\`\` 10622 10623\`\`\`bash 10624set XRAY_CLIENT_ID=nuevo_client_id 10625set XRAY_CLIENT_SECRET=nuevo_client_secret 10626\`\`\``}]},{id:"haka-lens",title:"Haka Lens",group:"Herramientas Haka",icon:"",topics:[{id:"hakalens-descripcion",title:"Descripción General",content:`## Integración con Haka Lens (Cassini) 10627
10628Haka Lens es la plataforma de visibilidad y métricas de calidad de Haka Lab. La integración permite reportar automáticamente los resultados de las ejecuciones de pruebas a Haka Lens en tiempo real. 10629 10630### ¿Qué hace? 10631 10632- Crea una ejecución en Haka Lens al iniciar una suite de pruebas 10633- Reporta el resultado de cada escenario (passed/failed) en tiempo real 10634- Registra tiempos de ejecución por escenario 10635- Permite visualizar tendencias y métricas en el dashboard de Haka Lens 10636- Se integra automáticamente a través del environment.py del framework 10637 10638### ¿Cómo funciona? 10639 106401. Al iniciar \`behave\`, el framework detecta \`CASSINI_ENABLED=true\` en el .env 106412. Se crea una ejecución en Haka Lens con el tÃtulo de la suite 106423. Por cada escenario ejecutado, se reporta su estado y duración 106434. Al finalizar, la ejecución se cierra automáticamente 106445. Los resultados son visibles inmediatamente en el dashboard`},{id:"hakalens-configuracion",title:"Configuración",content:`## Configuración de Haka Lens 10645 10646### Variables de Entorno (.env) 10647 10648\`\`\`env 10649# Habilitar/deshabilitar la integración 10650CASSINI_ENABLED=true 10651 10652# URL de la API de Haka Lens 10653CASSINI_API_URL=https://us-central1-cassini-eae7e.cloudfunctions.net/api/v1 10654 10655# API Key (obtenida desde el dashboard de Haka Lens) 10656CASSINI_API_KEY=tu_api_key_aqui 10657 10658# ID del equipo (obtenido desde el dashboard) 10659CASSINI_TEAM_ID=tu_team_id_aqui 10660 10661# TÃtulo personalizado para la suite (opcional) 10662CASSINI_SUITE_TITLE=Mi Suite de Regresión 10663 10664# Entorno de ejecución (opcional) 10665CASSINI_ENVIRONMENT=staging 10666 10667# Total de pasos fijo (opcional, se calcula automáticamente si no se especifica) 10668# CASSINI_TOTAL_STEPS=10 10669\`\`\` 10670 10671### Variables Requeridas 10672 10673| Variable | Descripción | 10674|----------|-------------| 10675| CASSINI_ENABLED | Debe ser \`true\` para activar la integración | 10676| CASSINI_API_URL | URL base de la API | 10677| CASSINI_API_KEY | API Key de autenticación (Bearer token) | 10678| CASSINI_TEAM_ID | Identificador del equipo en Haka Lens | 10679 10680### Variables Opcionales 10681 10682| Variable | Descripción | 10683|----------|-------------| 10684| CASSINI_SUITE_TITLE | Nombre de la suite (si no se especifica, se auto-genera) | 10685| CASSINI_ENVIRONMENT | Nombre del ambiente (staging, production, etc.) | 10686| CASSINI_TOTAL_STEPS | Número total de escenarios (se calcula automáticamente) |`},{id:"hakalens-uso",title:"Uso y Flujo",content:`## Uso de Haka Lens 10687 10688### Activación Automática 10689 10690Una vez configurado en el .env, no necesitas hacer nada más. El framework se encarga automáticamente de: 10691 106921. Detectar que Cassini está habilitado 106932. Crear la ejecución al inicio 106943. Reportar cada escenario 106954. Cerrar la ejecución al finalizar 10696 10697### Flujo de Reporte 10698 10699\`\`\` 10700before_all: 10701 â Inicializa CassiniIntegration 10702 â Crea ejecución (POST /executions) 10703 â Obtiene executionId 10704 10705after_scenario: 10706 â Reporta paso (POST /executions/{id}/steps) 10707 â Status: 'passed' o 'failed' 10708 â Incluye tiempo de ejecución en ms 10709 10710after_all: 10711 â La ejecución se cierra automáticamente 10712 â Dashboard se actualiza en tiempo real 10713\`\`\` 10714 10715### Ejecución Paralela 10716 10717Cuando ejecutas en paralelo con múltiples workers: 10718- Se crea UNA sola ejecución compartida 10719- Todos los workers reportan a la misma ejecución 10720- El total de steps se calcula automáticamente entre todos los workers 10721 10722### Comportamiento ante Errores 10723 10724- Si Cassini no está disponible (red caÃda), los tests continúan normalmente 10725- Los errores de conexión se loguean pero no interrumpen la ejecución 10726- Si la API Key es inválida, se muestra un mensaje y se desactiva para el resto de la ejecución 10727 10728### Ejemplo de Feature 10729 10730\`\`\`gherkin 10731# No necesitas ningún tag especial ni step adicional 10732# Solo tener CASSINI_ENABLED=true en el .env 10733 10734Feature: Login de usuarios 10735 10736 Scenario: Login exitoso 10737 Given voy a la url "\${ENV.BASE_URL}/login" 10738 When relleno el campo "email" con "[email protected]" con identificador "$.LOGIN.email" 10739 Then deberÃa ver el elemento "dashboard" con identificador "$.DASHBOARD.panel" 10740 # â Se reporta automáticamente a Haka Lens como PASSED 10741 10742 Scenario: Login fallido 10743 Given voy a la url "\${ENV.BASE_URL}/login"
10744 When relleno el campo "email" con "invalido" con identificador "$.LOGIN.email" 10745 Then deberÃa ver el texto "Credenciales incorrectas" 10746 # â Se reporta automáticamente a Haka Lens como PASSED o FAILED según resultado 10747\`\`\``},{id:"hakalens-dashboard",title:"Dashboard y Métricas",content:`## Dashboard de Haka Lens 10748 10749### ¿Qué ves en el Dashboard? 10750 10751- **Ejecuciones en tiempo real**: progreso de la suite actual 10752- **Historial de ejecuciones**: tendencia de passed/failed a lo largo del tiempo 10753- **Métricas por equipo**: resultados agregados por CASSINI_TEAM_ID 10754- **Duración**: tiempos promedio por escenario y por suite 10755- **Ambientes**: filtrar por CASSINI_ENVIRONMENT (staging, production, etc.) 10756 10757### Cómo Obtener las Credenciales 10758 107591. Accede al dashboard de Haka Lens 107602. Ve a Configuración â API Keys 107613. Genera una nueva API Key 107624. Copia el Team ID de tu equipo 107635. Configura ambos en el .env 10764 10765### Troubleshooting 10766 10767| Problema | Solución | 10768|----------|----------| 10769| "Cassini no configurado" | Verificar que CASSINI_API_URL, CASSINI_API_KEY y CASSINI_TEAM_ID están definidos | 10770| "No se pudo conectar" | Verificar conectividad a *.cloudfunctions.net puerto 443 | 10771| "Error al crear ejecución" | Verificar que la API Key sea válida y no haya expirado | 10772| Los resultados no aparecen | Verificar CASSINI_ENABLED=true (minúsculas) | 10773| Errores en paralelo | La ejecución compartida se maneja automáticamente, no requiere configuración |`}]},{id:"sesiones-guardadas",title:"Sesiones Guardadas",group:"Fundamentos",icon:"",topics:[{id:"sesiones-concepto",title:"Concepto",content:`## Qué es una Sesión Guardada 10774 10775Una sesión guardada es una captura completa del estado del navegador (cookie
10775s, localStorage, sessionStorage) después de un login exitoso. Permite reutilizar ese estado en ejecuciones automáticas futuras sin repetir el flujo de autenticación, incluyendo MFA/2FA. 10776 10777## Problema que Resuelve 10778 10779Sistemas como Salesforce, SAP, Azure AD, Google Workspace y otros exigen autenticación multi-factor (MFA) que no se puede automatizar de forma confiable. Con sesiones guardadas: 10780 10781- Haces login UNA sola vez (manualmente, con MFA incluido) 10782- Guardas el estado del navegador en un archivo JSON 10783- Tus tests restauran ese estado y acceden al sistema ya logueados 10784 10785## Cómo Funciona Internamente 10786 107871. El framework abre un navegador visible 107882. Tú haces login manualmente (incluyendo código MFA, biometrÃa, SSO, etc.) 107893. Al terminar, el framework captura el storageState de Playwright: cookies (httpOnly, secure, sameSite), localStorage de cada origen, sessionStorage, IndexedDB y Service Workers registrados 107904. Se guarda todo en \`logins/nombre.json\` (encriptado si hay clave) 107915. En la ejecución automática, se inyectan cookies, localStorage, IndexedDB y sessionStorage, y se navega a la URL capturada 107926. El servidor reconoce la sesión como válida y no pide login 10793 10794## Tipos de Sesión 10795 10796| Tipo | Uso | Archivo | 10797|------|-----|---------| 10798| **Estándar** | Salesforce, SAP, Azure AD, Google, etc. | \`logins/nombre.json\` | 10799| **Persistente** | WhatsApp Web, Signal, Telegram | \`logins/.persistent_nombre/\` (directorio) | 10800 10801Las sesiones persistentes guardan el perfil completo del navegador (user_data_dir) y se usan para apps con claves criptográficas no exportables. 10802 10803## Compatibilidad 10804 10805Funciona con cualquier sistema que use cookies para sesión: Salesforce, SAP, Azure AD, Google Workspace, Jira, Confluence, ServiceNow, OAuth2, SSO, etc. 10806 10807## Expiración TÃpica 10808 10809| Sistema | Duración tÃpica | 10810|---------|-----------------| 10811| Salesforce | 2-12 horas | 10812| SAP | 1-8 horas | 10813| Azure AD | 1-24 horas | 10814| Google Workspace | 1-14 dÃas |`},{id:"sesiones-implementacion",title:"Implementación Paso a Paso",content:`## Implementación Completa (desde cero) 10815 10816GuÃa para configurar sesiones guardadas en un proyecto nuevo o existente. 10817 10818## Requisitos 10819 10820- Haka Playwright Engine instalado 10821- Playwright browsers instalados (\`playwright install\`) 10822- Acceso al sistema donde se hará login 10823- Terminal interactiva para la captura (no funciona en CI headless) 10824 10825## Paso 1: Generar la clave de encriptación 10826 10827La clave protege las cookies y tokens sensibles que se guardan en disco. Solo necesitas hacerlo **una vez por proyecto**. 10828 10829\`\`\`bash 10830haka-login --gen-key 10831\`\`\` 10832 10833Esto crea el archivo \`.haka_session_key\` en la raÃz del proyecto con una clave Fernet aleatoria. 10834 10835**Alternativa para CI/CD:** En vez de archivo, usa la variable de entorno: 10836\`\`\`bash 10837export HAKA_SESSION_KEY="tu-clave-aqui" 10838\`\`\` 10839 10840## Paso 2: Agregar a .gitignore 10841 10842\`\`\`bash 10843echo '.haka_session_key' >> .gitignore 10844echo 'logins/' >> .gitignore 10845\`\`\` 10846 10847Esto evita subir credenciales sensibles al repositorio. 10848 10849## Paso 3: Capturar una sesión 10850 10851\`\`\`bash 10852haka-login --save admin_salesforce --url https://login.salesforce.com 10853\`\`\` 10854 10855**Lo que ocurre:** 108561. Se abre un navegador visible en la URL indicada 108572. Haces login completo (usuario, password, código MFA, lo que sea) 108583. Una vez dentro del sistema, vuelves a la terminal y presionas ENTER 108594. El framework captura cookies + localStorage y los guarda **cifrados** en \`logins/admin_salesforce.json\` 10860 10861**Opciones adicionales:** 10862\`\`\`bash 10863# Usar Firefox en vez de Chromium 10864haka-login --save mi_sesion --url https://mi-app.com --browser firefox 10865 10866# Dar más tiempo para MFA complejos 10867haka-login --save mi_sesion --url https://mi-app.com --timeout 10 10868\`\`\` 10869 10870## Paso 4: Usar en tus tests 10871 10872\`\`\`gherkin 10873Feature: Pruebas en Salesforce 10874 10875 Scenario: Crear nueva cuenta 10876 Given inicio sesion guardada con el usuario "admin_salesforce" 10877 When voy a la url "https://miorg.lightning.force.com/lightning/o/Account/new" 10878 And relleno el campo "Nombre" con "Cliente Test" con identificador "$.ACCOUNT.nombre" 10879 Then deberia ver el texto "se creo correctamente" 10880\`\`\` 10881 10882El step \`inicio sesion guardada\` desencripta el archivo en memoria, inyecta las cookies y navega a la URL donde se capturó. Todo transparente. 10883 10884**Variante: navegar a una URL diferente a la capturada** 10885\`\`\`gherkin 10886Given cargo sesion guardada "admin_sf" y navego a "https://miorg.lightning.force.com/lightning/o/Account/list" 10887\`\`\` 10888 10889## Paso 5: Verificar y listar 10890 10891\`\`\`bash 10892# Ver todas las sesiones (cifrada / sin cifrar) 10893haka-login --list 10894 10895# Ver detalle de una sesión 10896haka-login --info admin_salesforce 10897\`\`\` 10898 10899## Paso 6: Renovar cuando expire 10900 10901Cuando una sesión expira (el test redirige a login), simplemente recaptura: 10902 10903\`\`\`bash 10904haka-login --save admin_salesforce --url https://login.salesforce.com 10905\`\`\` 10906 10907Se sobrescribe y re-encripta automáticamente. 10908 10909## Estructura Final del Proyecto 10910 10911\`\`\` 10912mi-proyecto/ 10913âââ .env # Configuración del framework 10914âââ .gitignore # Incluye: logins/ y .haka_session_key 10915âââ .haka_session_key # Clave de encriptación (NO commitear) 10916âââ logins/ # Sesiones cifradas (NO commitear) 10917â âââ admin_salesforce.json 10918â âââ viewer_sap.json 10919âââ features/ 10920â âââ environment.py 10921â âââ salesforce.feature 10922âââ json_poms/ 10923âââ requirements.txt 10924\`\`\` 10925 10926## Resumen Rápido 10927 10928| Paso | Comando | Frecuencia | 10929|------|---------|------------| 10930| Generar clave | \`haka-login --gen-key\` | Una vez por proyecto | 10931| Capturar sesión | \`haka-login --save X --url Y\` | Una vez por sesión (o cuando expire) | 10932| Usar en test | \`Given inicio sesion guardada con el usuario "X"\` | Cada ejecución |
10933| Verificar | \`haka-login --list\` | Cuando quieras |`},{id:"sesiones-cli",title:"Comandos CLI",content:`## Capturar Sesión 10934 10935\`\`\`bash 10936# Sintaxis básica 10937haka-login --save <nombre> --url <url_de_login> 10938 10939# Ejemplos reales 10940haka-login --save admin_salesforce --url https://login.salesforce.com 10941haka-login --save sap_qa --url https://sap.miempresa.com/sap/bc/gui/sap/its/webgui 10942haka-login --save azure_user --url https://login.microsoftonline.com 10943 10944# Con opciones adicionales 10945haka-login --save admin_sf --url https://login.salesforce.com --browser firefox --timeout 10 10946\`\`\` 10947 10948## Opciones Disponibles 10949 10950| Opción | Default | Descripción | 10951|--------|---------|-------------| 10952| --save | (requerido) | Nombre para la sesión | 10953| --url | (requerido) | URL de la página de login | 10954| --browser | chromium | Navegador: chromium, firefox, webkit | 10955| --timeout | 5 | Minutos máximos para completar el login | 10956| --persistent | false | Usar sesión persistente (perfil completo, para WhatsApp/Signal) | 10957 10958## Capturar Sesión Persistente 10959 10960Para aplicaciones como WhatsApp Web, Signal o Telegram que usan claves criptográficas internas: 10961 10962\`\`\`bash 10963haka-login --save whatsapp --url https://web.whatsapp.com --persistent 10964haka-login --save signal --url https://signal.link --persistent 10965\`\`\` 10966 10967Esto guarda el perfil completo del navegador en \`logins/.persistent_nombre/\` en vez de un archivo JSON. 10968 10969## Listar Sesiones 10970 10971\`\`\`bash 10972haka-login --list 10973\`\`\` 10974 10975Salida: 10976\`\`\` 10977ð Sesiones guardadas (3): 10978 10979 ⢠admin_salesforce 10980 URL: https://miorg.lightning.force.com/lightning/page/home 10981 Capturada: 2026-07-10T14:30:22 10982 Cookies: 28 10983 10984 ⢠sap_qa 10985 URL: https://sap.miempresa.com/sap/bc/gui/sap/its/webgui 10986 Capturada: 2026-07-09T09:15:00 10987 Cookies: 12 10988\`\`\` 10989 10990## Ver Información Detallada 10991 10992\`\`\`bash 10993haka-login --info admin_salesforce 10994\`\`\` 10995 10996## Eliminar Sesión 10997 10998\`\`\`bash 10999haka-login --delete sesion_vieja 11000\`\`\` 11001 11002## Renovar Sesión Expirada 11003 11004\`\`\`bash 11005# Simplemente recapturar con el mismo nombre (sobrescribe) 11006haka-login --save admin_salesforce --url https://login.salesforce.com 11007\`\`\``},{id:"sesiones-steps-bdd",title:"Steps BDD Disponibles",content:`## Uso en Features 11008 11009### Login básico (navega a la URL capturada) 11010 11011\`\`\`gherkin 11012Feature: Pruebas en Salesforce 11013 11014 Scenario: Crear nueva cuenta 11015 Given inicio sesion guardada con el usuario "admin_salesforce" 11016 When voy a la url "https://miorg.lightning.force.com/lightning/o/Account/new" 11017 And relleno el campo "Nombre" con "Cliente Test" con identificador "$.ACCOUNT.nombre" 11018 Then deberÃa ver el elemento "Toast" con identificador "$.ACCOUNT.toast_exito" 11019\`\`\` 11020 11021### Login con URL especÃfica (ir directo a una página interna) 11022 11023\`\`\`gherkin 11024Feature: Reportes SAP 11025 11026 Scenario: Descargar reporte mensual 11027 Given cargo sesion guardada "sap_qa" y navego a "https://sap.miempresa.com/reportes/mensuales" 11028 When hago click en el elemento "Generar" con identificador "$.REPORTES.btn_generar" 11029 Then espero a que el elemento "Descarga" sea visible con identificador "$.REPORTES.link_descarga" 11030\`\`\` 11031 11032### Con variables de entorno 11033 11034\`\`\`gherkin 11035Feature: Multi-ambiente 11036 11037 Scenario: Verificar dashboard 11038 Given inicio sesion guardada con el usuario "\${ENV.SESSION_NAME}" 11039 When voy a la url "\${ENV.BASE_URL}/dashboard" 11040 Then deberÃa ver el elemento "Titulo" con identificador "$.DASHBOARD.titulo" 11041\`\`\` 11042 11043### Verificar que la sesión existe antes de usarla 11044 11045\`\`\`gherkin 11046Feature: Validación previa 11047 11048 Scenario: Sesión debe existir 11049 Then verifico que la sesion guardada "admin_salesforce" existe 11050 Given inicio sesion guardada con el usuario "admin_salesforce" 11051\`\`\` 11052 11053### Uso recomendado en Background 11054 11055\`\`\`gherkin 11056Feature: Mi feature 11057 11058 Background: 11059 Given inicio sesion guardada con el usuario "mi_usuario" 11060 11061 Scenario: Test 1 11062 When ... 11063 11064 Scenario: Test 2 11065 When ... 11066\`\`\` 11067 11068Usar en Background asegura que cada escenario restaura la sesión limpia.`},{id:"sesiones-inventario",title:"Inventario de Pasos",content:`## Inventario Completo de Steps de Sesiones Guardadas 11069 11070step: inicio sesion guardada con el usuario "{session_name}"
11071descripcion: Restaura una sesión de login previamente capturada. Detecta automáticamente si la sesión es estándar (cookies + localStorage + IndexedDB) o persistente (perfil completo). Para sesiones estándar: carga cookies, localStorage, IndexedDB y sessionStorage, luego navega a la URL capturada. Para sesiones persistentes: cierra el navegador actual y reabre uno con el perfil guardado. 11072 11073step: cargo sesion guardada "{session_name}" y navego a "{url}" 11074descripcion: Restaura una sesión guardada pero navega a una URL diferente a la capturada. Soporta tanto sesiones estándar como persistentes. Ãtil para ir directamente a una página interna del sistema sin pasar por el home. 11075 11076step: verifico que la sesion guardada "{session_name}" existe 11077descripcion: Verifica que una sesión guardada existe en la carpeta logins/ antes de intentar restaurarla. Falla con un mensaje claro si no existe, indicando cómo crearla. 11078 11079step: elimino la sesion guardada "{session_name}" 11080descripcion: Elimina el archivo JSON de una sesión guardada de la carpeta logins/. Ãtil para limpieza de sesiones expiradas o como paso de teardown. 11081 11082## Notas Técnicas 11083 11084**Variables soportadas:** 11085Todos los pasos resuelven variables del framework en el nombre de sesión: 11086\`\`\`gherkin 11087Given inicio sesion guardada con el usuario "\${ENV.SESSION_NAME}" 11088\`\`\` 11089 11090**Qué se restaura (Sesión Estándar):** 11091- Cookies de todos los dominios (incluyendo httpOnly y secure) 11092- localStorage de cada origen visitado durante la captura 11093- sessionStorage de cada pestaña/origen 11094- IndexedDB (bases de datos completas con todos los stores) 11095- Navegación automática a la URL donde se estaba al momento de la captura 11096 11097**Qué se restaura (Sesión Persistente):** 11098- TODO el estado del navegador (perfil completo user_data_dir) 11099- Service Workers, Cache API, WebCrypto keys 11100- IndexedDB con claves criptográficas no exportables 11101- Estado completo de la app (como si nunca hubieras cerrado el navegador) 11102 11103**Qué NO se restaura (Estándar):** 11104- Claves criptográficas no exportables (usar sesión persistente) 11105- Estado de JavaScript en memoria (variables globales, websockets) 11106- Sesiones de WebSocket activas 11107 11108**Detección automática:** 11109El step \`inicio sesion guardada\` detecta automáticamente el tipo de sesión: 11110- Si existe \`logins/.persistent_nombre/\` â sesión persistente 11111- Si existe \`logins/nombre.json\` â sesión estándar`},{id:"sesiones-encriptacion",title:"Encriptación",content:`## Encriptación de Sesiones 11112 11113Las sesiones guardadas contienen cookies reales con tokens de autenticación. El framework soporta encriptación automática usando Fernet (AES-128-CBC + HMAC-SHA256). 11114 11115## Cómo Funciona 11116 11117- Los archivos \`.json\` en \`logins/\` se guardan encriptados (base64 de Fernet) 11118- Al leer, se detecta automáticamente si el archivo está cifrado o plano (backward compatible) 11119- El archivo cifrado tiene un header \`HAKA_ENC:\` seguido del ciphertext 11120- La clave se deriva de una passphrase usando SHA-256 11121 11122## Configuración de la Clave 11123 11124La clave se obtiene en este orden de prioridad: 11125 111261. **Variable de entorno** \`HAKA_SESSION_KEY\` 111272. **Archivo** \`.haka_session_key\` en la raÃz del proyecto 111283. **Generación automática** al capturar la primera sesión 11129 11130### Opción 1: Variable de entorno 11131 11132\`\`\`bash 11133export HAKA_SESSION_KEY=mi_clave_secreta_segura 11134\`\`\` 11135 11136### Opción 2: Archivo de clave 11137 11138\`\`\`bash 11139# Se genera automáticamente la primera vez, o créalo manualmente: 11140echo "mi_clave_secreta" > .haka_session_key 11141chmod 600 .haka_session_key 11142\`\`\` 11143 11144## Habilitar/Deshabilitar Encriptación 11145 11146\`\`\`env 11147# Habilitar (por defecto si hay clave disponible) 11148HAKA_SESSION_ENCRYPT=true 11149 11150# Deshabilitar explÃcitamente 11151HAKA_SESSION_ENCRYPT=false 11152\`\`\` 11153 11154## Seguridad 11155 11156- Agrega \`.haka_session_key\` al \`.gitignore\` 11157- Agrega \`logins/\` al \`.gitignore\` 11158- En CI/CD, pasa la clave como secreto: \`HAKA_SESSION_KEY\` en environment variables 11159- Los permisos del archivo de clave se restringen automáticamente a \`600\` (solo owner) 11160 11161## Formato del Archivo Encriptado 11162 11163\`\`\` 11164HAKA_ENC:gAAAAABl... (ciphertext en base64) 11165\`\`\` 11166 11167Al leer, el framework detecta el header \`HAKA_ENC:\` y desencripta automáticamente. Si el archivo no tiene el header, se lee como JSON plano (compatibilidad hacia atrás). 11168 11169## Troubleshooting 11170 11171| Problema | Solución | 11172|----------|----------| 11173| "No se encontró clave de encriptación" | Configura HAKA_SESSION_KEY o crea .haka_session_key | 11174| "No se pudo desencriptar la sesión" | La clave es incorrecta o el archivo está corrompido. Recaptura la sesión. | 11175| Sesiones antiguas sin encriptar | Funcionan normalmente (detección automática). Recaptúralas para encriptarlas. |`},{id:"sesiones-persistentes",title:"Sesiones Persistentes",content:`## Sesiones Persistentes (WhatsApp, Signal, Telegram) 11176 11177Las sesiones persistentes son un modo especial para aplicaciones que **no funcionan** con el enfoque clásico de cookies + localStorage. Esto incluye: 11178 11179- **WhatsApp Web** (Signal Protocol + IndexedDB con claves no exportables) 11180- **Signal Web** 11181- **Telegram Web** (MTProto keys) 11182- Cualquier app con WebCrypto keys no exportables o Service Workers con estado criptográfico 11183 11184## Diferencia con Sesiones Estándar 11185 11186| Aspecto | Sesión Estándar | Sesión Persistente | 11187|---------|----------------|-------------------| 11188| Qué guarda | Cookies + localStorage + IndexedDB (exportados) | Perfil COMPLETO del navegador (user_data_dir) | 11189| Cómo restaura | Inyecta datos en un contexto nuevo | Reabre el navegador con el perfil guardado | 11190| Archivo resultante | \`logins/nombre.json\` (cifrable) | \`logins/.persistent_nombre/\` (directorio) | 11191| Compatibilidad | Cualquier sitio con cookies | Apps con claves criptográficas internas | 11192| Tamaño | ~10-100 KB | ~50-500 MB | 11193 11194## Captura 11195 11196\`\`\`bash 11197haka-login --save whatsapp --url https://web.whatsapp.com --persistent 11198\`\`\` 11199 11200**Lo que ocurre:** 112011. Se abre un navegador con un perfil dedicado (user_data_dir) 112022. Escaneas el QR o completas el login 112033. Esperas a que la app cargue completamente 112044. Presionas ENTER 112055. El perfil completo queda guardado en \`logins/.persistent_whatsapp/\` 11206 11207## Uso en Tests 11208 11209Los steps son los mismos. El framework detecta automáticamente si la sesión es persistente: 11210 11211\`\`\`gherkin 11212Feature: Notificaciones WhatsApp 11213 11214 Scenario: Enviar mensaje 11215 Given inicio sesion guardada con el usuario "whatsapp" 11216 When hago click en el elemento "Buscar" con identificador "$.WA.search" 11217 And relleno el campo "Buscar" con "Equipo QA" con identificador "$.WA.search_input" 11218\`\`\` 11219 11220O con URL de navegación: 11221 11222\`\`\`gherkin 11223Given cargo sesion guardada "whatsapp" y navego a "https://web.whatsapp.com" 11224\`\`\` 11225 11226## Cómo Funciona Internamente 11227 112281. El framework detecta que la sesión tiene un directorio \`.persistent_*\` 112292. Cierra el navegador actual del framework
112303. Abre un nuevo navegador con \`launch_persistent_context(user_data_dir=...)\` 112314. El navegador reconoce la sesión válida y no pide re-escaneo de QR 112325. Todo el estado (Service Workers, IndexedDB, Cache API, WebCrypto keys) se mantiene 11233 11234## Renovación 11235 11236Para WhatsApp: la sesión dura ~14 dÃas. Si expira, simplemente recaptura: 11237 11238\`\`\`bash 11239haka-login --save whatsapp --url https://web.whatsapp.com --persistent 11240\`\`\` 11241 11242## Consideraciones 11243 11244- Las sesiones persistentes NO se encriptan (son directorios, no archivos JSON) 11245- Son más pesadas en disco (~50-500 MB) 11246- No se pueden compartir fácilmente entre máquinas 11247- Solo funcionan con el mismo tipo de navegador con que se capturaron 11248- Agregar \`logins/.persistent_*/\` al \`.gitignore\``},{id:"sesiones-captura-avanzada",title:"Captura Avanzada",content:`## Datos que se Capturan Automáticamente 11249 11250A partir de la v1.5, la captura de sesiones incluye mucho más que cookies: 11251 11252| Dato | Descripción | Cuándo es útil | 11253|------|-------------|----------------| 11254| **Cookies** | Todas (httpOnly, secure, sameSite) | Siempre â es la base de toda sesión | 11255| **localStorage** | Por cada origen visitado | Apps que guardan tokens JWT, preferencias | 11256| **sessionStorage** | Por cada pestaña/origen | SAP, apps bancarias (tokens CSRF, session IDs) | 11257| **IndexedDB** | Bases de datos completas | Firebase, Auth0, Salesforce Lightning, SAP Fiori | 11258| **Service Workers** | Registros detectados | Apps PWA con auth en Service Workers | 11259 11260## IndexedDB 11261 11262Muchas aplicaciones modernas almacenan tokens y estado crÃtico en IndexedDB: 11263 11264- **Firebase**: \`firebaseLocalStorageDb\` con tokens de autenticación 11265- **Auth0**: Tokens de refresh y access 11266- **Salesforce Lightning**: Cache de componentes y estado de sesión 11267- **SAP Fiori**: Estado de la UI y tokens 11268 11269El framework captura todas las bases de datos IndexedDB accesibles y las restaura automáticamente al inicio de la sesión. 11270 11271## sessionStorage 11272 11273A diferencia de localStorage, el sessionStorage se pierde al cerrar la pestaña. Sin embargo, durante la captura se preserva: 11274 11275- Tokens CSRF de aplicaciones bancarias 11276- IDs de sesión de SAP 11277- Estado de navegación de SPAs 11278 11279**Nota**: La restauración de sessionStorage requiere que la app no invalide estos valores al detectar una nueva pestaña. 11280 11281## Formato del Archivo de Sesión 11282 11283\`\`\`json 11284{ 11285 "_metadata": { 11286 "session_name": "admin_salesforce", 11287 "login_url": "https://login.salesforce.com", 11288 "captured_url": "https://miorg.lightning.force.com/home", 11289 "captured_at": "2026-07-10T14:30:22", 11290 "browser": "chromium", 11291 "framework_version": "1.5.0", 11292 "encrypted": true, 11293 "captured_data": ["sessionStorage", "indexedDB", "serviceWorkers"] 11294 }, 11295 "storageState": { "cookies": [...], "origins": [...] }, 11296 "sessionStorage": [{ "origin": "...", "sessionStorage": [...] }], 11297 "indexedDB": [{ "origin": "...", "name": "...", "stores": {...} }], 11298 "serviceWorkers": [{ "scope": "...", "active": true }] 11299} 11300\`\`\` 11301 11302El campo \`captured_data\` indica qué datos adicionales se incluyeron en la captura (varÃa según la app). 11303 11304## Restauración Inteligente 11305 11306Al restaurar, el framework: 11307 113081. Inyecta cookies en el browser context 113092. Navega a cada origen para restaurar localStorage 113103. Navega a cada origen de IndexedDB y recrea las bases/stores 113114. Navega a cada origen de sessionStorage y restaura items 113125. Finalmente navega a la URL objetivo 11313 11314Todo esto es transparente: el step \`inicio sesion guardada\` hace todo automáticamente. 11315 11316## Troubleshooting 11317 11318| Problema | Causa | Solución | 11319|----------|-------|----------| 11320| La app pide login de nuevo | Cookies expiradas | Recapturar la sesión | 11321| IndexedDB no se restaura | La app cambió el schema | Recapturar la sesión | 11322| sessionStorage se ignora | La app invalida en nueva pestaña | Usar sesión persistente | 11323| "Service Workers detectados" | Info â no es un error | Los SW se re-registran solos |`}]},{id:"haka-agent",title:"𧪠Haka Agent (Experimental)",group:"Herramientas Haka",icon:"ð¤",topics:[{id:"agent-concepto",title:"Concepto",content:`## Haka Agent â Discovery Automatizado 11324 11325>
11325 â ï¸ **EXPERIMENTAL**: Esta funcionalidad está en fase experimental. Su API, comportamiento y artefactos generados pueden cambiar entre versiones sin previo aviso. Ãsala para explorar y documentar, pero revisa siempre los resultados antes de incorporarlos a tu suite. 11326 11327Haka Agent (\`haka-agent\`) es un agente que recorre una aplicación web, entiende qué hace, y genera automáticamente tres cosas: 11328 113291. **Documentación funcional** â Un reporte markdown con reglas de negocio, validaciones y comportamientos observados 113302. **Localizadores verificados (JSON POM)** â Con fallbacks y puntaje de estabilidad 113313. **Escenarios BDD ejecutables** â En el formato estándar del framework, listos para correr con \`behave\` 11332 11333## Principio Fundamental 11334 11335A diferencia de un generador de tests basado en IA convencional, el agente **ejecuta primero y escribe el test después**. Cada acción se ejecuta en un navegador real, su efecto se observa comparando el estado antes y después, y solo entonces se sintetiza el escenario. Un escenario marcado como \`@verificado\` tiene la garantÃa de que sus pasos funcionaron y sus aserciones corresponden a algo que efectivamente ocurrió. 11336 11337## IA Opcional 11338 11339La IA es una capa opcional. Sin ella el agente sigue verificando selectores, construyendo la matriz de casos de formularios y observando efectos. Con IA activa se añade: análisis funcional, detección de reglas de negocio, planificación de flujos y nombres descriptivos de escenarios. 11340 11341## Ejemplo Rápido 11342 11343\`\`\`bash 11344cd /ruta/a/tu/proyecto-de-pruebas 11345haka-agent exhaustive --url https://miapp.com/formulario --dry-run 11346\`\`\` 11347 11348Esto analiza el formulario, genera selectores verificados, construye la matriz de casos, y produce un feature y un reporte â sin enviar ningún formulario.`},{id:"agent-instalacion",title:"Requisitos e Instalación",content:`## Requisitos 11349 11350> â ï¸ **EXPERIMENTAL**: Haka Agent requiere la última versión del framework. 11351 11352El agente necesita: 11353- Haka Playwright Engine instalado 11354- Playwright browsers instalados 11355- Opcionalmente: un proveedor de IA para análisis funcional 11356 11357\`\`\`bash 11358pip install haka-playwright-engine 11359playwright install chromium 11360\`\`\` 11361 11362## Configuración de IA (opcional) 11363 11364El agente reutiliza la misma configuración de IA del framework. Configura en tu \`.env\`: 11365 11366\`\`\`env 11367# Gemini (recomendado por costo y velocidad) 11368AI_PROVIDER=gemini 11369GEMINI_API_KEY=tu_api_key 11370AI_MODEL=gemini-2.5-flash 11371\`\`\` 11372 11373Otros proveedores soportados: OpenAI, Anthropic, Ollama local. 11374 11375## Sin IA 11376 11377Sin proveedor configurado el agente funciona en modo determinista: selectores verificados, matriz de casos y observación de efectos. Lo que se pierde es el análisis funcional, reglas de negocio y nombres descriptivos. 11378 11379## Importante 11380 11381- Ejecutar desde el directorio del proyecto (donde está el \`.env\`) 11382- Chromium es el navegador recomendado 11383- Un discovery completo puede consumir 20-100 llamadas al modelo de IA`},{id:"agent-modos",title:"Modos de Operación",content:`## Los Cuatro Modos 11384 11385> â ï¸ **EXPERIMENTAL**: Los modos y sus opciones pueden cambiar. 11386 11387### exhaustive â Agotar una vista 11388 11389\`\`\`bash 11390haka-agent exhaustive --url https://miapp.com/crear-pedido --dry-run 11391\`\`\` 11392 11393Prueba cada elemento interactivo y construye la matriz completa de casos de formularios: obligatorios faltantes, formatos inválidos, valores frontera, solo espacios, caracteres especiales y longitud máxima. Ideal para "quiero conocer todas las casuÃsticas de esta pantalla". 11394 11395### explore â Mapear la aplicación 11396 11397\`\`\`bash 11398haka-agent explore --url https://miapp.com --autonomous --budget 60 --max-states 25 11399\`\`\` 11400 11401Recorrido libre con frontera de exploración y backtracking. Prioriza contenido funcional sobre menús de navegación. Genera documentación general y el \`graph.json\` para regression. 11402 11403### flow â Completar un objetivo concreto 11404 11405\`\`\`bash 11406haka-agent flow --url https://miapp.com --goal "crear un pedido nuevo con dos productos" 11407\`\`\` 11408 11409La IA planifica los pasos, el executor confirma que cada uno funcionó. Si un paso falla, replanifica. **Requiere proveedor de IA**. 11410 11411### regression â Detectar cambios 11412 11413\`\`\`bash 11414# Generar lÃnea base 11415haka-agent explore --url https://miapp.com --autonomous --session baseline_v1 11416 11417# Comparar después de un release 11418haka-agent regression --url https://miapp.com --baseline discovery/graph.json 11419\`\`\` 11420 11421Compara el estado actual contra un grafo de referencia. Reporta vistas nuevas, vistas que ya no responden, y elementos que cambiaron. 11422 11423## Recomendación 11424
11425- Empezar siempre con \`exhaustive\` sobre una pantalla conocida 11426- \`explore\` con \`--read-only\` para mapear sin riesgo 11427- \`flow\` es el único modo que no funciona sin IA 11428- \`regression\` necesita un \`graph.json\` previo`},{id:"agent-opciones-cli",title:"Opciones CLI",content:`## Opciones Comunes 11429 11430> â ï¸ **EXPERIMENTAL**: Las opciones pueden cambiar entre versiones. 11431 11432| Opción | Valor | Descripción | 11433|---|---|---| 11434| \`--url\` | URL | Punto de partida (obligatoria salvo \`--cdp-url\`) | 11435| \`--cdp-url\` | \`http://localhost:9222\` | Adoptar un Chrome ya abierto | 11436| \`--browser\` | chromium/chrome/firefox/webkit | Navegador a usar | 11437| \`--budget\` | entero (default: 60) | Máximo de acciones a ejecutar | 11438| \`--max-states\` | entero (default: 25) | Máximo de vistas distintas | 11439| \`--output\` | ruta (default: .) | Directorio de salida | 11440| \`--session\` | nombre | Nombre del POM y feature | 11441| \`--login-session\` | nombre | Sesión guardada con haka-login | 11442| \`--locale\` | es-CL | Locale de los datos generados | 11443| \`--instructions\` | texto | Contexto de negocio para el agente | 11444| \`--autonomous\` | flag | Sin preguntar al QA | 11445| \`--dry-run\` | flag | Rellenar pero no enviar formularios | 11446| \`--read-only\` | flag | Solo navegar y leer | 11447| \`--headless\` | flag | Sin ventana visible | 11448 11449## Opciones EspecÃficas 11450 11451\`\`\`bash 11452# flow: requiere objetivo 11453haka-agent flow --url URL --goal "descripción del objetivo" 11454 11455# regression: ruta de lÃnea base 11456haka-agent regression --url URL --baseline discovery/graph.json 11457\`\`\` 11458 11459## Notas 11460 11461- \`--budget\` cuenta acciones (clicks, fills, selects), no páginas 11462- Un formulario de 6 campos consume ~7 acciones 11463- Sin \`--session\` el nombre se genera con timestamp 11464- \`--cdp-url\` ignora \`--browser\` y \`--headless\` 11465- \`--instructions\` y \`--goal\` requieren IA configurada 11466 11467## Ejemplos 11468 11469Todos los ejemplos se ejecutan **desde la raÃz de tu proyecto de pruebas**, donde está el \`.env\`. Ahà es donde el agente escribe \`features/generated/\`, \`json_poms/\` y \`discovery/\`. 11470 11471## 1. Primera vez: conocer una pantalla 11472 11473Si nunca usaste el agente, empezá por acá. Una sola pantalla, sin enviar nada: 11474 11475\`\`\`bash 11476haka-agent exhaustive --url https://miapp.com/contacto --dry-run 11477\`\`\` 11478 11479Qué pasa: abre una ventana de Chromium, verifica un selector para cada elemento de la pantalla, construye la matriz de casos del formulario (obligatorios faltantes, formatos inválidos, lÃmites de longitud) y rellena los campos **sin apretar Enviar**. 11480 11481Qué obtenés: 11482 11483\`\`\` 11484json_poms/06082026_2132.json # localizadores verificados 11485features/generated/06082026_2132.feature 11486discovery/06082026_2132.md # análisis funcional 11487discovery/screenshots/ 11488\`\`\` 11489 11490> ð¡ \`exhaustive\` fuerza \`--max-states\` a un máximo de **3** aunque pidas más. Es a propósito: el modo existe para agotar *una* vista, no para navegar. 11491 11492## 2. Mapear una aplicación completa sin tocar nada 11493 11494\`\`\`bash 11495haka-agent explore --url https://miapp.com --read-only --autonomous --budget 40 11496\`\`\` 11497 11498\`--read-only\` limita al agente a navegar y leer: no rellena ni envÃa. Es la forma segura de largarlo contra un ambiente que no conocés, o contra algo parecido a producción. 11499 11500\`--autonomous\` evita que te pregunte antes de cada acción de riesgo. Combinado con \`--read-only\` no hay riesgo que confirmar, asà que van bien juntos. 11501 11502## 3. Explorar en serio, creando datos 11503 11504\`\`\`bash 11505haka-agent explore --url https://qa.miapp.com --autonomous \\ 11506 --budget 80 --max-states 30 --session mapeo_qa_v1 11507\`\`\` 11508 11509Sin \`--dry-run\` ni \`--read-only\`, el agente **sÃ** envÃa formularios y crea registros. Usalo en QA, nunca en producción. 11510 11511\`--session mapeo_qa_v1\` fija el nombre: el POM queda en \`json_poms/MAPEO_QA_V1.json\` y el feature en \`features/generated/mapeo_qa_v1.feature\`. Volver a correr con la misma sesión **acumula** en esos archivos en vez de sobrescribirlos. 11512 11513## 4. Aplicación con login 11514 11515### Opción A â Guardar la sesión una vez (recomendado) 11516 11517Sirve incluso con MFA/2FA, porque el login lo hacés vos a mano una sola vez: 11518 11519\`\`\`bash 11520# 1. Login manual. Se abre el navegador y tenés 5 minutos para entrar. 11521haka-login --save qa_admin --url https://miapp.com/login 11522 11523# 2. Verificar que quedó guardada 11524haka-login --list 11525 11526# 3. El agente arranca ya autenticado 11527haka-agent explore --url https://miapp.com/dashboard \\ 11528 --login-session qa_admin --autonomous --budget 60 11529\`\`\` 11530
11531La sesión queda en \`logins/qa_admin.json\` (cookies + localStorage). Opciones útiles: 11532 11533\`\`\`bash 11534haka-login --save wpp --url https://web.whatsapp.com --persistent 11535haka-login --save admin --url https://miapp.com --timeout 10 11536haka-login --info qa_admin 11537haka-login --encrypt qa_admin 11538haka-login --delete qa_admin 11539\`\`\` 11540 11541> \`--persistent\` usa un perfil de Chrome completo en vez de solo cookies. Necesario para apps que atan la sesión al dispositivo, como WhatsApp o Signal. 11542 11543### Opción B â Adoptar un Chrome que ya tenés abierto 11544 11545\`\`\`bash 11546# 1. Abrir Chrome con el puerto de depuración 11547google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-haka 11548 11549# 2. Navegar a mano hasta donde quieras: login, filtros, pasos previos... 11550 11551# 3. Enganchar el agente a esa pestaña, sin --url 11552haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run 11553\`\`\` 11554 11555Cuando pasás \`--cdp-url\` **sin** \`--url\`, el agente arranca desde donde esté la pestaña. Es la vÃa más práctica para llegar a una pantalla enterrada detrás de varios pasos: llegás vos a mano y desde ahà toma el control. 11556 11557Si además pasás \`--url\`, navega a esa dirección dentro del navegador adoptado. 11558 11559## 5. Un objetivo concreto 11560 11561\`\`\`bash 11562haka-agent flow --url https://miapp.com \\ 11563 --goal "crear un pedido nuevo con dos productos y confirmarlo" 11564\`\`\` 11565 11566La IA planifica los pasos eligiendo entre elementos ya verificados, y el executor confirma que cada uno tuvo efecto. Si un paso falla, replanifica con lo que aprendió. 11567 11568Es el **único modo que no funciona sin IA**: sin un proveedor configurado no hay quién planifique. 11569 11570Un objetivo bien escrito hace toda la diferencia. Comparalo: 11571 11572\`\`\`bash 11573# Vago: el agente no sabe cuándo terminó 11574--goal "probar el checkout" 11575 11576# Concreto: hay un criterio de éxito observable 11577--goal "agregar el producto SKU-1234 al carro, aplicar el cupón QA10 y \\ 11578 llegar a la pantalla de confirmación de pago" 11579\`\`\` 11580 11581## 6. LÃnea base y regresión 11582 11583\`\`\`bash 11584# Antes del release: fotografiar la aplicación 11585haka-agent explore --url https://miapp.com --autonomous \\ 11586 --budget 80 --session baseline_v1 11587 11588# Guardar el grafo con un nombre estable 11589cp discovery/graph.json discovery/baseline_v1.json 11590 11591# Después del release: comparar 11592haka-agent regression --url https://miapp.com \\ 11593 --baseline discovery/baseline_v1.json 11594\`\`\` 11595 11596El reporte te dice qué vistas aparecieron, cuáles dejaron de responder y qué elementos cambiaron de comportamiento. 11597 11598Sin \`--baseline\` busca en \`discovery/graph.json\`, que es donde \`explore\` deja el último grafo. Sirve para una comparación rápida contra la corrida anterior, pero para regresión de verdad conviene copiarlo a un nombre fijo: si no, la próxima exploración lo pisa. 11599 11600## 7. Darle contexto de negocio 11601 11602El agente no sabe qué significa tu dominio hasta que se lo contás: 11603 11604\`\`\`bash 11605haka-agent exhaustive --url https://miapp.com/alta-cliente \\ 11606 --dry-run \\ 11607 --instructions "El RUT debe ser chileno y válido con dÃgito verificador. \\ 11608El campo Convenio solo acepta clientes de tipo Empresa. \\ 11609No uses correos con dominio @test.com, el sistema los rechaza." 11610\`\`\` 11611 11612Eso cambia los datos que genera y las validaciones que espera. Requiere IA configurada; sin ella se ignora. 11613 11614## 8. Datos en otro locale 11615 11616\`\`\`bash 11617haka-agent exhaustive --url https://app.com.br/cadastro --locale pt-BR --dry-run 11618haka-agent exhaustive --url https://app.com/signup --locale en-US --dry-run 11619\`\`\` 11620 11621\`--locale\` afecta dos cosas: el locale del navegador y el formato de los datos generados (nombres, teléfonos, direcciones, fechas). El default es \`es-CL\`. 11622 11623## 9. En CI, sin ventana 11624 11625\`\`\`bash 11626haka-agent explore --url https://qa.miapp.com \\ 11627 --headless --autonomous --read-only \\ 11628 --budget 50 --session ci_nightly --output ./artefactos 11629\`\`\` 11630 11631\`--headless\` va casi siempre acompañado de \`--autonomous\`: sin ventana no hay nadie para responder una confirmación. 11632 11633\`--output ./artefactos\` mueve todo lo generado a ese directorio, cómodo para publicarlo como artefacto del pipeline. 11634 11635## 10. Otro navegador 11636 11637\`\`\`bash 11638haka-agent exhaustive --url https://miapp.com --browser chrome --dry-run 11639haka-agent exhaustive --url https://miapp.com --browser firefox --dry-run 11640haka-agent exhaustive --url https://miapp.com --browser webkit --dry-run 11641\`\`\` 11642 11643\`chromium\` (default) es el recomendado y el más probado. \`chrome\` usa el Chrome instalado en el sistema en vez del que trae Playwright. Con \`--cdp-url\` esta opción se ignora. 11644 11645--- 11646 11647## Cómo dimensionar \`--budget\` 11648 11649\`--budget\` cuenta **acciones**, no páginas. Sirve de referencia: 11650 11651| Situación | Acciones aproximadas | 11652|---|---| 11653| Formulario de 6 campos + enviar | ~7 | 11654| Matriz de casos de ese formulario | ~25-40 | 11655| Recorrer un menú de 8 secciones | ~8 | 11656| Tabla con filtros y paginación | ~15 | 11657 11658Con \`--budget\` muy bajo el agente corta a mitad de camino y el feature queda incompleto. Muy alto y una corrida puede tardar bastante y consumir muchas llamadas al modelo. Para arrancar, 40-60 es un rango razonable. 11659 11660## Combinaciones que conviene conocer 11661 11662| Combinación | Qué pasa | 11663|---|---| 11664| \`--dry-run\` + \`--read-only\` | Gana el más restrictivo: solo lectura | 11665| \`--cdp-url\` + \`--browser\` | \`--browser\` se ignora, ya hay un navegador | 11666| \`--cdp-url\` + \`--headless\` | \`--headless\` se ignora por el mismo motivo | 11667| \`--cdp-url\` + \`--login-session\` | Gana \`--cdp-url\`: ya hay una sesión viva | 11668| \`--cdp-url\` sin \`--url\` | Arranca desde la pestaña actual | 11669| \`exhaustive\` + \`--max-states 25\` | Se recorta a 3 | 11670| \`flow\` sin IA | Falla: es el único modo que la exige | 11671| \`--headless\` sin \`--autonomous\` | Puede quedar esperando una confirmación que no ves | 11672 11673## Chuleta 11674 11675\`\`\`bash 11676# Conocer una pantalla, sin enviar nada 11677haka-agent exhaustive --url URL --dry-run 11678 11679# Mapear una app sin tocar nada 11680haka-agent explore --url URL --read-only --autonomous 11681 11682# Explorar creando datos, en QA 11683haka-agent explore --url URL --autonomous --budget 80 --session mi_mapeo 11684 11685# Detrás de login 11686haka-login --save usr --url URL/login 11687haka-agent explore --url URL --login-session usr --autonomous 11688 11689# Desde una pantalla a la que llegaste a mano 11690haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run 11691 11692# Un objetivo concreto (requiere IA) 11693haka-agent flow --url URL --goal "objetivo con criterio de éxito claro" 11694 11695# Regresión contra una lÃnea base 11696haka-agent regression --url URL --baseline discovery/baseline_v1.json 11697
11698# Ver la versión instalada 11699haka-agent --version 11700\`\`\``},{id:"agent-seguridad",title:"Modos de Seguridad",content:`## Niveles de Riesgo 11701 11702> â ï¸ **EXPERIMENTAL** 11703 11704El agente clasifica cada acción por nivel de riesgo antes de ejecutarla: 11705 11706| Nivel | Significado | 11707|---|---| 11708| \`safe\` | Sin efectos persistentes (navegar, leer) | 11709| \`caution\` | Crea o modifica datos (enviar formulario) | 11710| \`destructive\` | Borra datos o acciones irreversibles | 11711 11712## Los Tres Modos de Seguridad 11713 11714\`\`\`bash 11715# read_only: solo navegación y lectura 11716haka-agent explore --url https://miapp.com --read-only 11717 11718# dry_run: rellena formularios pero NO los envÃa 11719haka-agent exhaustive --url https://miapp.com/form --dry-run 11720 11721# normal (default): permite crear y modificar 11722haka-agent exhaustive --url https://miapp.com/form 11723\`\`\` 11724 11725## Recomendaciones 11726 11727- Acciones \`destructive\` se bloquean incluso en modo normal 11728- Usar \`--read-only\` la primera vez que apuntas a un ambiente desconocido 11729- **Nunca apuntar a producción sin \`--read-only\`** 11730- En \`--dry-run\` los escenarios quedan \`@derivado\` porque no se enviaron`},{id:"agent-artefactos",title:"Artefactos Generados",content:`## Estructura de Salida 11731 11732> â ï¸ **EXPERIMENTAL**: El formato de los artefactos puede cambiar. 11733 11734\`\`\` 11735tu-proyecto/ 11736âââ json_poms/ 11737â âââ MI_MODULO.json Localizadores verificados con fallbacks 11738âââ features/generated/ 11739â âââ mi_modulo.feature Escenarios BDD 11740âââ discovery/ 11741 âââ discovery_mi_modulo.md Documentación funcional 11742 âââ graph.json Grafo de estados (para regression) 11743 âââ screenshots/ 11744 âââ login_page_dfa9342c.png Captura por vista 11745\`\`\` 11746 11747## JSON POM Generado 11748 11749\`\`\`json 11750{ 11751 "input_username": { 11752 "selector": "#username", 11753 "fallbacks": [ 11754 "//label[normalize-space(text())='Username']/following::input[1]", 11755 "input[name=\\"username\\"]" 11756 ] 11757 }, 11758 "btn_login": { 11759 "selector": "//button[contains(normalize-space(.),'Login')]", 11760 "fallbacks": ["button.radius"] 11761 } 11762} 11763\`\`\` 11764 11765Los selectores se usan como: \`$.MI_MODULO.input_username\` 11766 11767## Tags de Escenarios 11768 11769| Tag | Significado | 11770|---|---| 11771| \`@verificado\` | Ejecutado en navegador real, pasos funcionaron | 11772| \`@derivado\` | Inferido del HTML pero no ejecutado | 11773| \`@happy_path\` | Flujo exitoso con datos válidos | 11774| \`@required_missing\` | Campo obligatorio vacÃo | 11775| \`@format_invalid\` | Formato incorrecto | 11776| \`@boundary_*\` | Valores en los lÃmites | 11777 11778## Ejecutar los Escenarios 11779 11780\`\`\`bash 11781# Solo lo verificado (confiable) 11782behave features/generated/ --tags=@verificado 11783 11784# Solo caminos felices 11785behave features/generated/ --tags=@happy_path 11786 11787# Excluir los derivados sin revisar 11788behave features/generated/ --tags=~@derivado 11789\`\`\` 11790 11791## Acumulación por Sesión 11792 11793Si corres con el mismo \`--session\` varias veces, los selectores nuevos se agregan sin borrar los existentes.`},{id:"agent-formularios",title:"Matriz de Casos",content:'## Matriz de Casos de Formularios\n\n> â ï¸ **EXPERIMENTAL**\n\nCuando el agente encuentra un formulario, extrae las restricciones del HTML (`required`, `type`, `pattern`, `minlength`, `maxlength`, `min`, `max`) y deriva una matriz de casos de forma **determinista** (no depende de la IA):\n\n| CategorÃa | Qué prueba |\n|---|---|\n| `happy_path` | Todos los campos válidos |\n| `required_missing` | Falta un campo obligatorio (uno por campo) |\n| `format_invalid` | Formato incorrecto según type o pattern |\n| `boundary_min` | Valor en el lÃmite inferior |\n| `boundary_below` | Justo por debajo del lÃmite |\n| `boundary_max` | Valor en el lÃmite superior |\n| `boundary_above` | Justo por encima del lÃmite |\n| `max_length_exact` | Exactamente el máximo permitido |\n| `whitespace_only` | Solo espacios en campo obligatorio |\n| `special_chars` | Apóstrofos, ampersands, ángulos |\n\n## Ejemplo de Escenario Generado\n\n```gherkin\n@formulario @happy_path @positivo @verificado\nScenario: Completar login con datos válidos\n Given voy a la url "https://miapp.com/login"\n When relleno el campo "Username" con "Valentina" con identificador "$.MI_MODULO.input_username"\n And relleno el campo "Password" con "ClaveSegura2026!" con identificador "$.MI_MODULO.input_password"\n And hago click en el elemento "Login" con identificador "$.MI_MODULO.btn_login"\n And espero 2 segundos\n Then deberÃa ver el texto "Your username is invali
11793d!"\n```\n\nEl `Then` no fue inventado: es el mensaje que la aplicación **realmente mostró** al ejecutar el caso.\n\n## Con y Sin IA\n\n- **Con IA**: genera datos plausibles según locale y contexto de negocio\n- **Sin IA**: datos derivados del nombre y tipo del campo (email â email válido, rut â RUT formateado)'},{id:"agent-cdp",title:"Pantallas Profundas (CDP)",content:`## Partir desde una Pantalla Profunda 11794 11795> â ï¸ **EXPERIMENTAL** 11796 11797Cuando la pantalla que quieres analizar está detrás de un login y varios pasos previos (wizard, carrito, formulario dependiente), puedes navegar manualmente y pasarle el control al agente: 11798 11799\`\`\`bash 11800# 1. Abrir Chrome con puerto de depuración 11801google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-haka 11802 11803# 2. En ese Chrome: login + navegar hasta la pantalla objetivo 11804 11805# 3. Sin cerrar el navegador, lanzar el agente 11806haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run 11807\`\`\` 11808 11809El agente adopta la pestaña actual y arranca desde ahÃ, reutilizando tu sesión y estado. 11810 11811## Cuándo Usar Cada Opción 11812 11813| Situación | Opción | 11814|---|---| 11815| Solo hay que pasar el login | \`--login-session\` | 11816| Login + pasos previos (wizard, carrito) | \`--cdp-url\` | 11817| App con claves criptográficas | \`--login-session\` con sesión persistente | 11818 11819## Consideraciones 11820 11821- Solo funciona con navegadores Chromium (Chrome, Edge) 11822- Usar un \`--user-data-dir\` separado 11823- El agente **no cierra tu navegador** al terminar 11824- El agente **sà navega en tu ventana** â duplica la pestaña si necesitas preservar el estado`},{id:"agent-flujo-trabajo",title:"Flujo de Trabajo",content:`## Flujo Recomendado 11825 11826> â ï¸ **EXPERIMENTAL**: Los artefactos generados son un punto de partida, no un reemplazo del criterio del QA. 11827 11828### De Cero a Suite 11829 11830\`\`\`bash 11831# 1. Mapear la aplicación sin tocar nada 11832haka-agent explore --url https://miapp.com --read-only --autonomous \\ 11833 --session mapa_general --budget 60 11834 11835# 2. Leer el discovery para entender qué hay 11836# discovery/discovery_mapa_general.md 11837 11838# 3. Profundizar en las pantallas crÃticas 11839haka-agent exhaustive --url https://miapp.com/crear-pedido \\ 11840 --session pedidos --dry-run 11841 11842# 4. Ejecutar de verdad en ambiente seguro para obtener @verificado 11843haka-agent exhaustive --url https://miapp.com/crear-pedido --session pedidos 11844 11845# 5. Validar un flujo completo 11846haka-agent flow --url https://miapp.com \\ 11847 --goal "crear un pedido y confirmarlo" --session flujo_pedido 11848\`\`\` 11849 11850### Uso Continuo (Regresión) 11851 11852\`\`\`bash 11853# Después de cada release 11854haka-agent regression --url https://miapp.com --baseline discovery/graph.json 11855\`\`\` 11856 11857### Organización por Módulo 11858 11859\`\`\`bash 11860haka-agent exhaustive --url https://miapp.com/clientes --session clientes 11861haka-agent exhaustive --url https://miapp.com/pedidos --session pedidos 11862haka-agent exhaustive --url https://miapp.com/facturas --session facturas 11863\`\`\` 11864 11865Cada \`--session\` genera un POM y feature separado. Correr con el mismo nombre acumula selectores. 11866 11867## Limitaciones Conocidas 11868 11869- No reemplaza el criterio del QA 11870- Solo detecta lo observable desde el frontend 11871- Aplicaciones con captcha bloquean la exploración 11872- Canvas y WebGL no son inspeccionables 11873- \`flow\` requiere IA configurada 11874- Nunca apuntar a producción sin \`--read-only\``},{id:"agent-referencia",title:"Referencia Rápida",content:`## Cheat Sheet 11875 11876> â ï¸ **EXPERIMENTAL** 11877 11878\`\`\`bash 11879# Explorar sin tocar nada 11880haka-agent explore --url URL --read-only --autonomous 11881 11882# Agotar una pantalla sin enviar formularios 11883haka-agent exhaustive --url URL --dry-run 11884 11885# Agotar una pantalla ejecutando de verdad 11886haka-agent exhaustive --url URL 11887 11888# Completar un objetivo dirigido 11889haka-agent flow --url URL --goal "descripción del objetivo" 11890 11891# Detectar cambios contra lÃnea base 11892haka-agent regression --url URL --baseline discovery/graph.json 11893 11894# Con autenticación 11895haka-agent explore --url URL --login-session NOMBRE 11896 11897# Adoptar Chrome abierto (pantallas profundas) 11898haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run 11899 11900# Pipeline: sin ventana, sin preguntas, solo lectura 11901haka-agent explore --url URL --headless --autonomous --read-only 11902 11903# Ayuda 11904haka-agent --help 11905haka-agent <modo> --help 11906\`\`\` 11907 11908## Troubleshooting 11909 11910| SÃntoma | Solución | 11911|---|---| 11912| "IA: no configurada" | Ejecutar desde el directorio del proyecto donde está el \`.env\` | 11913| POM con pocos selectores | Subir \`--budget\` o apuntar a la vista especÃfica | 11914| Todos los escenarios \`@derivado\` | Quitar \`--dry-run\` y correr en ambiente seguro | 11915| No pasa del login | Usar \`--login-session\` o \`--cdp-url\` | 11916| Se queda en la misma vista | Subir \`--max-states\` | 11917| "No se pudo conectar a 9222" | Levantar Chrome con \`--user-data-dir\` separado |`}]},{id:"browser-context",title:"Browser Context",group:"Fundamentos",icon:"",topics:[{id:"browser-context-personalizacion",title:"Personalización del Browser Context",content:`## Personalización del Browser Context 11918 11919El framework permite personalizar completamente el navegador que se abre para las pruebas mediante \`context.browser_context_options\` en tu archivo \`environment.py\`. Esto te da acceso a **todas las opciones de Playwright** sin necesidad de modificar el framework. 11920 11921--- 11922 11923## Uso Básico 11924 11925En tu \`features/environment.py\`: 11926 11927\`\`\`python 11928from hakalab_framework.core.environment_config import setup_framework_context, setup_sce
11928nario_context 11929 11930def before_all(context): 11931 setup_framework_context(context) 11932 11933 # Personalizar el browser context 11934 context.browser_context_options = { 11935 'locale': 'es-CL', 11936 'timezone_id': 'America/Santiago', 11937 'color_scheme': 'dark', 11938 } 11939 11940def before_scenario(context, scenario): 11941 setup_scenario_context(context, scenario) 11942\`\`\` 11943 11944Las opciones se aplican **automáticamente** al crear la primera página del navegador. 11945 11946--- 11947 11948## Prioridad de Configuración 11949 119501. **\`.env\`** â Configuración base (viewport, timeout, headless, etc.) 119512. **\`context.browser_context_options\`** â Sobrescribe o complementa el .env 119523. **Steps dinámicos** â Pueden cambiar valores en runtime (ej: geolocalización) 11953 11954El merge es **inteligente**: 11955- \`permissions\`: se **concatenan** (framework + usuario). Si el .env pone \`['geolocation']\` y tú pones \`['notifications']\`, el resultado es \`['geolocation', 'notifications']\`. 11956- \`extra_http_headers\`: se **mergean** (dict update, tus headers se agregan a los del framework). 11957- Todo lo demás: **tu valor gana** sobre el del .env.`},{id:"browser-context-opciones",title:"Opciones Disponibles",content:`## Opciones Disponibles 11958 11959Todas las opciones de \`browser.new_context()\` de Playwright están disponibles: 11960 11961### Localización y Zona Horaria 11962 11963\`\`\`python 11964context.browser_context_options = { 11965 'locale': 'es-CL', # Idioma del navegador 11966 'timezone_id': 'America/Santiago', # Zona horaria simulada 11967} 11968\`\`\` 11969 11970Ãtil para probar que las fechas, formatos numéricos y textos se muestran correctamente según la región. 11971 11972### Geolocalización 11973 11974\`\`\`python 11975context.browser_context_options = { 11976 'geolocation': { 11977 'latitude': -33.4489, 11978 'longitude': -70.6693, 11979 'accuracy': 50, # Precisión en metros (opcional) 11980 }, 11981 'permissions': ['geolocation'], # OBLIGATORIO para que funcione 11982} 11983\`\`\` 11984 11985**Nota:** También puedes configurar esto via \`.env\` con \`GEOLOCATION_ENABLED=true\`. 11986 11987### Apariencia 11988 11989\`\`\`python 11990context.browser_context_options = { 11991 'color_scheme': 'dark', # 'dark', 'light', 'no-preference' 11992 'forced_colors': 'active', # 'active', 'none' (alto contraste) 11993 'reduced_motion': 'reduce', # 'reduce', 'no-preference' 11994} 11995\`\`\` 11996 11997Ideal para probar dark mode, accesibilidad y preferencias de movimiento reducido. 11998 11999### Permisos del Navegador 12000 12001\`\`\`python 12002context.browser_context_options = { 12003 'permissions': [ 12004 'geolocation', 12005 'notifications', 12006 'clipboard-read', 12007 'clipboard-write', 12008 'camera', 12009 'microphone', 12010 ], 12011} 12012\`\`\` 12013 12014Los permisos se otorgan automáticamente sin popup. Esto resuelve el problema de pruebas bloqueadas por popups de permisos. 12015 12016### Headers HTTP Personalizados 12017 12018\`\`\`python 12019context.browser_context_options = { 12020 'extra_http_headers': { 12021 'X-Custom-Token': 'abc123', 12022 'Accept-Language': 'es-CL,es;q=0.9', 12023 'X-Test-Environment': 'staging', 12024 }, 12025} 12026\`\`\` 12027 12028Se envÃan con **cada request** del navegador. Ãtil para APIs que requieren headers de autenticación custom. 12029 12030### Autenticación HTTP (Basic Auth) 12031 12032\`\`\`python 12033context.browser_context_options = { 12034 'http_credentials': { 12035 'username': 'admin', 12036 'password': 'secret', 12037 }, 12038} 12039\`\`\` 12040 12041Para páginas protegidas con autenticación HTTP básica (el popup de login del browser). 12042 12043### Proxy 12044 12045\`\`\`python 12046context.browser_context_options = { 12047 'proxy': { 12048 'server': 'http://proxy.company.com:8080', 12049 'bypass': '*.internal.com', # Dominios que no pasan por proxy 12050 'username': 'proxy_user', # Opcional 12051 'password': 'proxy_pass', # Opcional 12052 }, 12053} 12054\`\`\` 12055 12056### Red y Conectividad 12057 12058\`\`\`python 12059context.browser_context_options = { 12060 'offline': True, # Simular sin conexión 12061 'ignore_https_errors': True, # Ignorar errores SSL 12062} 12063\`\`\` 12064 12065### Dispositivo Móvil 12066 12067\`\`\`python 12068context.browser_context_options = { 12069 'is_mobile': True, 12070 'has_touch': True, 12071 'viewport': {'width': 390, 'height': 844}, # iPhone 14 12072 'device_scale_factor': 3, 12073 'user_agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0...', 12074} 12075\`\`\` 12076 12077### Seguridad y JavaScript 12078 12079\`\`\`python 12080context.browser_context_options = { 12081 'bypass_csp': True, # Ignorar Content-Security-Policy 12082 'java_script_enabled': False, # Desactivar JavaScript 12083} 12084\`\`\` 12085 12086### Descargas 12087 12088\`\`\`python 12089context.browser_context_options = { 12090 'accept_downloads': True, # Permitir descargas automáticas 12091} 12092\`\`\` 12093 12094### Estado de Almacenamiento (Storage State) 12095 12096\`\`\`python 12097context.browser_context_options = { 12098 'storage_state': 'state.json', # Restaurar cookies/localStorage 12099} 12100\`\`\` 12101 12102Ãtil para saltar el login reutilizando una sesión previa (ver Sesiones Guardadas).`},{id:"browser-context-ejemplos",title:"Ejemplos Completos",content:`## Ejemplos Completos 12103 12104### E-commerce con ubicación en Santiago + dark mode 12105 12106\`\`\`python 12107def before_all(context): 12108 setup_framework_context(context) 12109 context.browser_context_options = { 12110 'locale': 'es-CL', 12111 'timezone_id': 'America/Santiago', 12112 'geolocation': {'latitude': -33.4489, 'longitude': -70.6693}, 12113 'permissions': ['geolocation'], 12114 'color_scheme': 'dark', 12115 } 12116\`\`\` 12117 12118### API interna con proxy + headers custom 12119 12120\`\`\`python 12121def before_all(context): 12122 setup_framework_context(context) 12123 context.browser_context_options = { 12124 'proxy': {'server': 'http://proxy:3128'}, 12125 'extra_http_headers': { 12126 'X-API-Key': os.getenv('API_KEY'), 12127 'X-Environment': 'qa', 12128 }, 12129 'ignore_https_errors': True, 12130 } 12131\`\`\` 12132 12133### Mobile responsive testing 12134 12135\`\`\`python 12136def before_all(context): 12137 setup_framework_context(context) 12138 context.browser_context_options = { 12139 'is_mobile': True, 12140 'has_touch': True, 12141 'viewport': {'width': 375, 'height': 812}, 12142 'device_scale_factor': 3, 12143 'user_agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)...', 12144 } 12145\`\`\` 12146 12147### Testing offline y sin JavaScript 12148 12149\`\`\`python 12150def before_all(context): 12151 setup_framework_context(context) 12152 context.browser_context_options = { 12153 'offline': True, 12154 'java_script_enabled': False, 12155 } 12156\`\`\` 12157 12158--- 12159
12160## Combinación con Steps Dinámicos 12161 12162Las opciones de \`browser_context_options\` se aplican al **crear** el contexto. Si necesitas cambiar valores **durante** la ejecución (ej: cambiar geolocalización entre scenarios), usa los steps dinámicos: 12163 12164\`\`\`gherkin 12165Scenario: Verificar tienda cercana en Santiago 12166 When configuro la geolocalización para "santiago" 12167 And voy a la url "https://tienda.cl/sucursales" 12168 Then deberÃa ver el texto "Providencia" 12169 12170Scenario: Verificar tienda cercana en ValparaÃso 12171 When configuro la geolocalización para "valparaiso" 12172 And voy a la url "https://tienda.cl/sucursales" 12173 Then deberÃa ver el texto "Viña del Mar" 12174\`\`\` 12175 12176--- 12177 12178## Notas Importantes 12179 12180- **\`browser_context_options\` se lee UNA VEZ** al crear el primer contexto del escenario. Si lo cambias después de \`before_all\`, no tendrá efecto en contextos ya creados. 12181- **No conflicta con el \`.env\`**: El .env sigue siendo la fuente principal para viewport, timeout, headless, browser type, etc. Las \`browser_context_options\` complementan esos valores. 12182- **Reutilización de páginas**: Si el framework reutiliza una página entre scenarios (comportamiento por defecto), las opciones del context ya están aplicadas. Solo si se necesita un **nuevo** contexto se vuelven a aplicar. 12183- **No es necesario importar nada extra**: Solo define el diccionario en \`context\` y el framework lo usa automáticamente.`},{id:"browser-context-geolocation-env",title:"Geolocalización via .env",content:`## Configuración de Geolocalización via .env 12184 12185La forma más simple de habilitar geolocalización es mediante variables de entorno en el archivo \`.env\`: 12186 12187\`\`\`env 12188# Habilitar geolocalización automática 12189GEOLOCATION_ENABLED=true 12190 12191# Coordenadas (obligatorias si GEOLOCATION_ENABLED=true) 12192GEOLOCATION_LATITUDE=-33.4489 12193GEOLOCATION_LONGITUDE=-70.6693 12194 12195# Precisión en metros (opcional, default: 100) 12196GEOLOCATION_ACCURACY=100 12197\`\`\` 12198 12199### Comportamiento 12200 12201Cuando \`GEOLOCATION_ENABLED=true\`: 122021. El framework otorga automáticamente el permiso \`geolocation\` al crear el contexto del navegador 122032. Configura las coordenadas especificadas como ubicación simulada 122043. Las páginas que llamen \`navigator.geolocation.getCurrentPosition()\` recibirán las coordenadas configuradas sin mostrar popup de permiso 12205 12206### Prioridad con browser_context_options 12207 12208Si además defines geolocalización en \`browser_context_options\`, el merge inteligente se aplica: 12209 12210\`\`\`python 12211# .env tiene: GEOLOCATION_ENABLED=true, lat=-33.4489, lon=-70.6693 12212 12213def before_all(context): 12214 setup_framework_context(context) 12215 context.browser_context_options = { 12216 'geolocation': {'latitude': -34.6037, 'longitude': -58.3816}, # Buenos Aires 12217 'permissions': ['notifications'], # Se concatena con ['geolocation'] del .env 12218 } 12219# Resultado: geolocation=Buenos Aires, permissions=['geolocation', 'notifications'] 12220\`\`\` 12221 12222### Combinación con Steps Dinámicos 12223 12224Puedes configurar la geolocalización base via .env y cambiarla durante la ejecución: 12225 12226\`\`\`gherkin 12227# El .env configura Santiago como ubicación inicial 12228# Durante el test, cambias dinámicamente: 12229 12230Scenario: Verificar cambio de ubicación 12231 Given voy a la url "https://mi-app.com/tiendas" 12232 # Usa la ubicación del .env (Santiago) 12233 Then deberÃa ver el texto "Tienda Santiago Centro" 12234 12235 When configuro la geolocalización para "valparaiso" 12236 And recargo la página 12237 # Ahora usa ValparaÃso 12238 Then deberÃa ver el texto "Tienda Viña del Mar" 12239\`\`\` 12240 12241### Ejemplo completo de environment.py con geolocalización 12242 12243\`\`\`python 12244from hakalab_framework.core.environment_config import setup_framework_context, setup_scenario_context 12245 12246def before_all(context): 12247 setup_framework_context(context) 12248 12249 # Complementar la geolocalización del .env con opciones adicionales 12250 context.browser_context_options = { 12251 'locale': 'es-CL', 12252 'timezone_id': 'America/Santiago', 12253 'permissions': ['notifications'], # Se suma al 'geolocation' del .env 12254 } 12255 12256def before_scenario(context, scenario): 12257 setup_scenario_context(context, scenario) 12258\`\`\``}]}
12258,{id:"problemas-comunes",title:"Problemas Comunes",group:"Empezar",icon:"",topics:[{id:"problemas-linux",title:"Problemas en Linux",content:`## Problemas en Linux 12259 12260### Error: dependencias del sistema no instaladas 12261 12262\`\`\` 12263playwright._impl._errors.Error: Host system is missing dependencies to run browsers. 12264\`\`\` 12265 12266**Solución:** 12267\`\`\`bash 12268sudo playwright install-deps 12269# O instalar manualmente las dependencias de Chromium: 12270sudo apt-get install -y libgbm1 libasound2 libatk1.0-0 libcups2 libdbus-1-3 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libpango-1.0-0 libcairo2 12271\`\`\` 12272 12273### Error: "No usable sandbox" en Docker/CI 12274 12275\`\`\` 12276Failed to launch chromium because of sandbox limitations 12277\`\`\` 12278 12279**Solución:** Agregar al .env: 12280\`\`\`env 12281CHROMIUM_SANDBOX=false 12282\`\`\` 12283 12284O ejecutar con la variable de entorno: 12285\`\`\`bash 12286PLAYWRIGHT_CHROMIUM_SANDBOX=0 behave 12287\`\`\` 12288 12289### Error: display not found (entornos sin GUI) 12290 12291\`\`\` 12292Error: Failed to launch browser: DISPLAY environment variable is not set 12293\`\`\` 12294 12295**Solución:** Usar modo headless obligatoriamente: 12296\`\`\`env 12297HEADLESS=true 12298\`\`\` 12299 12300O instalar Xvfb para un display virtual: 12301\`\`\`bash 12302sudo apt-get install -y xvfb 12303xvfb-run behave 12304\`\`\` 12305 12306### Error: permisos en la carpeta de screenshots 12307 12308\`\`\`bash 12309chmod -R 777 screenshots/ html-reports/ 12310\`\`\` 12311 12312### Playwright no encuentra los browsers tras instalación con pip 12313 12314\`\`\`bash 12315# Verificar que playwright está en el PATH correcto 12316which playwright 12317# Reinstalar browsers 12318python -m playwright install chromium 12319\`\`\` 12320 12321### Error con pyautogui (Desktop) en Linux sin display 12322 12323\`\`\` 12324Xlib.error.DisplayNameError: Bad display name "" 12325\`\`\` 12326 12327**Solución:** PyAutoGUI requiere un display X11. En servidores headless no funciona. Usa Xvfb o ejecuta desktop tests solo en máquinas con GUI. 12328 12329### Firewall corporativo bloquea la validación de licencia 12330 12331**Verificar conectividad:** 12332\`\`\`bash 12333curl -I https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia 12334# Debe retornar: HTTP 405 Method Not Allowed 12335\`\`\` 12336 12337**Si está bloqueado, pedir a IT que habilite:** 12338\`\`\` 12339Dominio: *.cloudfunctions.net 12340Protocolo: HTTPS 12341Puerto: 443 12342Dirección: Salida (Outbound) 12343\`\`\``},{id:"problemas-macos",title:"Problemas en macOS",content:`## Problemas en macOS 12344 12345### Error: "webkit" no se puede verificar (Gatekeeper) 12346 12347\`\`\` 12348"Playwright.app" can't be opened because Apple cannot check it for malicious software 12349\`\`\` 12350 12351**Solución:** 12352\`\`\`bash 12353# Remover la cuarentena del browser de Playwright 12354xattr -cr ~/Library/Caches/ms-playwright 12355# O usar chromium que no tiene este problema 12356\`\`\` 12357 12358En .env, preferir chromium: 12359\`\`\`env 12360BROWSER=chromium 12361\`\`\` 12362 12363### Error: "Operation not permitted" al tomar screenshots (Desktop) 12364 12365macOS requiere permisos de accesibilidad para PyAutoGUI: 12366 123671. Ir a **System Preferences â Security & Privacy â Privacy â Accessibility** 123682. Agregar la app de Terminal (o iTerm2) a la lista 123693. Si usas un IDE, agregar el IDE también 12370 12371### Error: Tesseract OCR no encontrado 12372 12373\`\`\`bash 12374# Instalar con Homebrew 12375brew install tesseract 12376brew install tesseract-lang # Para idiomas adicionales 12377 12378# Verificar instalación 12379tesseract --version 12380\`\`\` 12381 12382### Error con certificados SSL en macOS 12383 12384\`\`\` 12385ssl.SSLCertVerificationError: certificate verify failed 12386\`\`\` 12387 12388**Solución:** 12389\`\`\`bash 12390# Instalar certificados de Python 12391/Applications/Python\\ 3.11/Install\\ Certificates.command 12392# O con pip: 12393pip install certifi 12394\`\`\` 12395 12396### Playwright se cierra inesperadamente en macOS Sonoma+ 12397 12398\`\`\`bash 12399# Actualizar Playwright a la última versión 12400pip install --upgrade playwright 12401playwright install 12402\`\`\` 12403 12404### Appium + Android emulator en macOS con Apple Silicon (M1/M2/M3) 12405 12406\`\`\`bash 12407# Usar el emulador ARM64 (no x86) 12408# En Android Studio: crear AVD con imagen "arm64-v8a" 12409# Verificar: 12410adb devices 12411\`\`\` 12412 12413### Firewall corporativo bloquea la validación de licencia 12414 12415**Verificar conectividad:** 12416\`\`\`bash 12417curl -I https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia 12418\`\`\` 12419 12420Si hay proxy corporativo: 12421\`\`\`bash 12422export HTTPS_PROXY=http://proxy.empresa.com:8080 12423\`\`\``},{id:"problemas-windows",title:"Problemas en Windows",content:`## Problemas en Windows 12424 12425### Error: "execution policy" al ejecutar scripts 12426 12427\`\`\` 12428running scripts is disabled on this system 12429\`\`\` 12430 12431**Solución (PowerShell como administrador):** 12432\`\`\`powershell 12433Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 12434\`\`\` 12435 12436### Error: ruta demasiado larga (path > 260 caracteres) 12437 12438\`\`\` 12439FileNotFoundError: [WinError 3] The system cannot find the path specified 12440\`\`\` 12441 12442**Solución:** 124431. Mover el proyecto a una ruta más corta (ej: \`C:\\tests\\mi_proyecto\`) 124442. O habilitar rutas largas en Windows: 12445\`\`\`powershell 12446# PowerShell como administrador 12447New-ItemProperty -Path "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force 12448\`\`\` 12449 12450### Error: permisos al instalar Playwright browsers 12451 12452\`\`\` 12453PermissionError: [WinError 5] Access is denied 12454\`\`\` 12455 12456**Solución:** 12457\`\`\`bash
12458# Ejecutar como administrador o especificar directorio: 12459set PLAYWRIGHT_BROWSERS_PATH=C:\\playwright-browsers 12460playwright install chromium 12461\`\`\` 12462 12463### Error: pip no reconocido 12464 12465\`\`\`bash 12466# Usar py launcher de Windows: 12467py -m pip install haka-playwright-engine 12468py -m playwright install 12469\`\`\` 12470 12471### Error: encoding (tildes y caracteres especiales) 12472 12473\`\`\` 12474UnicodeDecodeError: 'charmap' codec can't decode byte 12475\`\`\` 12476 12477**Solución:** Establecer encoding UTF-8: 12478\`\`\`bash 12479# En el .env o variable de entorno: 12480set PYTHONIOENCODING=utf-8 12481# O en PowerShell: 12482$env:PYTHONIOENCODING = "utf-8" 12483\`\`\` 12484 12485También agregar al inicio del script: 12486\`\`\`bash 12487chcp 65001 12488\`\`\` 12489 12490### Error: antivirus bloquea Playwright/Chromium 12491 12492Algunos antivirus corporativos (CrowdStrike, SentinelOne, Symantec) bloquean el ejecutable de Chromium. 12493 12494**Solución:** 12495- Solicitar a IT que agregue exclusiones para la carpeta de browsers de Playwright 12496- Ruta tÃpica: \`%USERPROFILE%\\AppData\\Local\\ms-playwright\\chromium-*\` 12497 12498### PyAutoGUI no funciona con escalado de pantalla (DPI > 100%) 12499 12500\`\`\`python 12501# Las coordenadas no coinciden con lo visible 12502\`\`\` 12503 12504**Solución:** Deshabilitar el escalado DPI para Python: 125051. Click derecho en python.exe â Propiedades â Compatibilidad 125062. "Change high DPI settings" â "Override high DPI scaling" â Application 12507 12508O agregar al .env: 12509\`\`\`env 12510DESKTOP_DPI_AWARE=true 12511\`\`\` 12512 12513### Firewall corporativo bloquea la validación de licencia 12514 12515**Verificar conectividad (PowerShell):** 12516\`\`\`powershell 12517$url = "https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia" 12518Invoke-WebRequest -Uri $url -Method HEAD 12519# Debe retornar: 405 Method Not Allowed 12520\`\`\` 12521 12522**Configurar proxy:** 12523\`\`\`powershell 12524$env:HTTPS_PROXY = "http://proxy.empresa.com:8080" 12525\`\`\``},{id:"problemas-generales",title:"Problemas Generales (Todos los OS)",content:`## Problemas Generales (Todos los OS) 12526 12527### Error: "No module named hakalab_framework" 12528 12529\`\`\`bash 12530pip install haka-playwright-engine 12531# O si usas virtualenv, verificar que está activado: 12532source venv/bin/activate # Linux/macOS 12533venv\\Scripts\\activate # Windows 12534\`\`\` 12535 12536### Error: browsers no instalados 12537 12538\`\`\` 12539playwright._impl._errors.Error: Executable doesn't exist 12540\`\`\` 12541 12542\`\`\`bash 12543playwright install chromium 12544# O todos: 12545playwright install 12546\`\`\` 12547 12548### El elemento no se encuentra (timeout) 12549 12550**Causas comunes:** 12551- El localizador en el JSON POM está incorrecto 12552- El nombre del archivo JSON no está en MAYÃSCULAS 12553- El elemento aún no existe en el DOM (necesita espera) 12554- El elemento está dentro de un iframe 12555 12556**Soluciones:** 12557\`\`\`gherkin 12558# Aumentar timeout global en .env: 12559TIMEOUT=30000 12560 12561# O esperar explÃcitamente: 12562When espero a que el elemento "mi_elemento" sea visible con identificador "$.PAGE.elemento" 12563 12564# Si está en un iframe: 12565When cambio al iframe "frame_principal" con identificador "$.PAGE.iframe" 12566\`\`\` 12567 12568### Error: environment.py no encontrado 12569 12570\`\`\` 12571ConfigError: No steps directory 12572\`\`\` 12573 12574Verificar estructura: 12575\`\`\` 12576mi_proyecto/ 12577âââ features/ 12578â âââ environment.py â OBLIGATORIO 12579â âââ mi_test.feature 12580â âââ steps/ 12581â âââ custom_steps.py 12582\`\`\` 12583 12584### Error: "from hakalab_framework.steps import *" falla 12585 12586\`\`\`bash 12587# Verificar versión instalada: 12588pip show haka-playwright-engine 12589 12590# Actualizar a la última versión: 12591pip install --upgrade haka-playwright-engine 12592\`\`\` 12593 12594### Variables no se resuelven en los steps 12595 12596\`\`\`gherkin 12597# INCORRECTO: usar {variable} directamente 12598When voy a la url "{mi_url}" 12599 12600# CORRECTO: usar sintaxis del framework 12601When creo la variable "mi_url" con valor "https://ejemplo.com" 12602And voy a la url "\${mi_url}" 12603\`\`\` 12604 12605### Los tests pasan en local pero fallan en CI/CD 12606 12607**Checklist CI/CD:** 126081. HEADLESS=true en .env o variable de entorno 126092. playwright install-deps (Linux) 126103. playwright install chromium 126114. Timeouts suficientes (30000ms mÃnimo) 126125. Screenshots habilitados para debugging 126136. Verificar conectividad de red (API tests, licencia) 12614 12615\`\`\`env 12616# .env para CI: 12617HEADLESS=true 12618BROWSER=chromium 12619TIMEOUT=30000 12620AUTO_SCREENSHOT_ON_FAILURE=true 12621RETRY_FAILED_SCENARIOS=true 12622MAX_SCENARIO_RETRIES=2 12623\`\`\` 12624 12625### Error de licencia: "License validation failed" 12626 12627**Posibles causas:** 12628- Primera ejecución sin conexión a internet 12629- Firewall bloquea el endpoint de validación 12630- Clave de licencia expirada o incorrecta 12631 12632**Verificar conectividad:** 12633\`\`\`bash 12634# Linux/macOS: 12635curl -I https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia 12636 12637# Windows PowerShell: 12638Invoke-WebRequest -Uri "https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia" -Method HEAD 12639\`\`\` 12640 12641**Si el firewall bloquea, pedir a IT que habilite:** 12642- Dominio: *.cloudfunctions.net 12643- Puerto: 443 (HTTPS) 12644- Dirección: Salida (Outbound) 12645 12646**La validación ocurre solo 1 vez cada 10 dÃas.** Después usa caché local. 12647 12648### Sesión guardada no funciona (redirige a login) 12649 12650- La sesión expiró. Recapturar: \`haka-login --save nombre --url url\`
12651- El browser no coincide. Recapturar con el mismo browser que usas en tests. 12652- Las cookies fueron invalidadas por el servidor (cambio de password, revocación). 12653 12654### Ejecución paralela falla o tiene resultados inconsistentes 12655 12656- Cada worker debe usar datos de prueba independientes 12657- No compartir variables globales entre features paralelos 12658- Verificar que no hay dependencia de orden entre tests 12659- Usar \`--workers=1\` para diagnosticar si es un problema de concurrencia 12660 12661### Error al generar reporte HTML 12662 12663\`\`\`bash 12664# Verificar permisos de escritura: 12665mkdir -p html-reports screenshots 12666chmod 755 html-reports screenshots 12667 12668# Verificar que environment.py tiene la integración del reporte: 12669# setup_html_reporting(context) en before_all 12670# generate_html_report(context) en after_all 12671\`\`\` 12672 12673### PyAutoGUI (Desktop): "could not find image on screen" 12674 12675- Verificar que la imagen de referencia existe en DESKTOP_IMAGES_PATH 12676- Bajar la confianza: \`hago click con confianza "0.7" en la imagen "boton"\` 12677- La resolución de pantalla puede haber cambiado â recapturar las imágenes 12678- En modo headless no funciona (requiere display visible) 12679 12680### Appium (Mobile): "Could not create session" 12681 12682\`\`\`bash 12683# Verificar que Appium está corriendo: 12684appium --version 12685# Si no: npm install -g appium 12686 12687# Verificar dispositivo conectado: 12688adb devices 12689 12690# Verificar que la app está instalada: 12691adb shell pm list packages | grep mi.paquete 12692\`\`\` 12693 12694### Error: "Timeout exceeded" en steps de espera 12695 12696**Ajustar timeouts según el contexto:** 12697\`\`\`env 12698# Timeout general (ms) 12699TIMEOUT=30000 12700 12701# Para entornos lentos (VPN, staging remoto): 12702TIMEOUT=60000 12703\`\`\` 12704 12705**O usar esperas explÃcitas con timeout personalizado en el step:** 12706\`\`\`gherkin 12707When espero a que el elemento "resultado" sea visible con identificador "$.PAGE.resultado" 12708# Este step usa el TIMEOUT del .env 12709\`\`\``}]},{id:"salesforce",title:"Salesforce",group:"Aplicaciones Empresariales",icon:"",topics:[{id:"salesforce-descripcion",title:"Descripción General",content:`## Salesforce con frontdoor.jsp y Perfiles 12710 12711El framework incluye una integración nativa con Salesforce que permite autenticar usuarios de prueba mediante la API de Salesforce y abrir la sesión directamente en el navegador usando \`frontdoor.jsp\`. 12712 12713>
12713 **Cambio importante: Salesforce retira el login por contraseña.** La autenticación por usuario, contraseña y security token está siendo retirada. En **API 65.0 y posteriores ya no está disponible** y las organizaciones nuevas la traen deshabilitada; para versiones anteriores Salesforce anunció el retiro definitivo en la release **Summer '27**. La forma soportada es **OAuth JWT Bearer** (\`SF_API_AUTH_MODE=oauth_jwt_bearer\`), que no requiere contraseñas en el \`.env\`. **Los steps no cambian.** 12714 12715### CaracterÃsticas 12716 12717- **Autenticación sin contraseñas**: Un certificado firma el acceso de cada perfil. No se guardan passwords ni security tokens. 12718- **Frontdoor.jsp**: Abre la sesión autenticada directamente en Playwright sin pasar por el formulario de login web. 12719- **Perfiles nombrados**: Configura múltiples usuarios por ambiente (\`UAT1\`, \`SIT1\`, etc.) y selecciónalos desde Gherkin. 12720- **Identidad real por perfil**: Cada perfil entra como su propio usuario, conservando sus permisos y visibilidad de datos. 12721- **Reutilización de sesión**: Si el perfil ya está activo y Lightning sigue cargado, no vuelve a autenticar ni navegar. 12722- **Sin Login As**: No se requieren permisos administrativos para cambiar de identidad. 12723- **Aislamiento en paralelo**: Cada worker/proceso mantiene sus propias sesiones, sin compartir cookies ni tokens. 12724 12725### Modos de Autenticación 12726 12727| Modo | Con qué entra | Cuándo usarlo | 12728|---|---|---| 12729| \`oauth_jwt_bearer\` | Cada perfil entra como su propio usuario | **Recomendado.** Login en pantalla y también API | 12730| \`oauth_client_credentials\` | Todos los perfiles entran como un único usuario de integración | Solo pruebas de API sin navegador | 12731| \`legacy_soap\` | Usuario, contraseña y security token | En retirada por Salesforce. No usar en configuraciones nuevas | 12732 12733Con \`oauth_client_credentials\` el acceso obtenido sirve para consultar datos pero **no** para abrir la pantalla de Salesforce: el login por \`frontdoor\` falla. Para pruebas con navegador usa \`oauth_jwt_bearer\`. 12734 12735El modo \`legacy_soap\` sigue funcionando donde la organización aún lo permite, y al usarlo el framework escribe una advertencia en el log. 12736 12737### Requisitos 12738 12739- El usuario Salesforce debe tener **API Enabled** en su perfil/permiso. 12740- Configurar \`SF_LOGIN_MODE=frontdoor\`, \`SF_API_ENABLED=true\` y \`SF_API_AUTH_MODE=oauth_jwt_bearer\` en el \`.env\`. 12741- Una aplicación conectada en Salesforce con firma digital y el usuario autorizado. El procedimiento completo está en la guÃa de habilitación JWT. 12742 12743> **Importante:** frontdoor.jsp no evita MFA, SSO, restricciones de IP, Login Flows ni polÃticas de sesión. Si alguna de estas aplica al usuario de prueba, coordina con el administrador de Salesforce para que las desactive en el ambiente de prueba o usa IPs confiables.`},{id:"salesforce-jwt-login",title:"Login con JWT (Paso a Paso)",content:`## Habilitar el Login con JWT 12744 12745Procedimiento completo para que las pruebas entren a Salesforce como un usuario real, sin guardar contraseñas. Al terminar funciona este step: 12746 12747\`\`\`gherkin 12748Given inicio sesión con el usuario "UAT1" 12749\`\`\` 12750 12751**Necesitas:** permisos de administrador en Salesforce y el usuario con el que correrán las pruebas. Toma unos 20 minutos, porque Salesforce tarda algunos minutos en aplicar cada cambio. 12752 12753### Cómo funciona 12754 12755En lugar de una contraseña se usan dos archivos que funcionan como una llave y su candado: 12756 12757- El **candado** (\`.crt\`) se lo entregas a Salesforce. Es público. 12758- La **llave** (\`.key\`) se queda en tu equipo. Esta es secreta. 12759 12760Cuando las pruebas arrancan, firman su acceso con la llave. Salesforce verifica que calce con el candado y las deja entrar como el usuario que indiques. 12761 12762--- 12763 12764## Paso 1: Generar el certificado 12765 12766En una terminal, dentro de tu proyecto de pruebas: 12767 12768\`\`\`bash 12769mkdir -p sf_key 12770openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:2048 \\ 12771 -keyout sf_key/haka_sf.key -out sf_key/haka_sf.crt \\ 12772 -subj "/CN=haka-automation" 12773\`\`\` 12774 12775| Archivo | Qué es | Destino | 12776|---|---|---| 12777| \`haka_sf.crt\` | El candado | Se sube a Salesforce en el Paso 2 | 12778| \`haka_sf.key\` | La llave | Se queda en tu equipo. **Nunca** se sube | 12779 12780> **Antes de continuar**, agrega \`sf_key/\` al \`.gitignore\`. Con esa llave se puede entrar a Salesforce como tus usuarios de prueba, sin contraseña y sin verificación por correo. 12781 12782--- 12783 12784## Paso 2: Crear la aplicación conectada 12785 12786**Configuración â Gestor de aplicaciones â Nueva aplicación conectada.** 12787 12788Completa nombre y correo de contacto. Luego, en la sección **API (Habilitar configuración de OAuth)**: 12789 12790| Opción | Qué hacer | 12791|---|---| 12792| Habilitar configuración de OAuth | Marcar | 12793| URL de devolución de llamada | Pegar \`https://login.salesforce.com/services/oauth2/success\` | 12794| Usar firmas digitales | Marcar y subir \`haka_sf.crt\` | 12795 12796La URL de devolución de llamada es obligatoria aunque este flujo no la use. Si la dejas vacÃa, Salesforce responde *URL no válida*. 12797 12798> Si al subir el certificado dice **"El archivo cargado no es un certificado"**, estás subiendo el \`.key\`. Debe ser el \`.crt\`. 12799 12800### Ãmbitos de OAuth 12801 12802Pasa estos tres a la lista de seleccionados: 12803 12804\`\`\`text 12805Gestionar datos de usuario a través de las API (api) 12806Gestionar datos de usuario a través de navegadores (web) 12807Realizar solicitudes en cualquier momento (refresh_token, offline_access) 12808\`\`\` 12809 12810| Ãmbito | Para qué sirve | 12811|---|---| 12812| \`api\` | Consultas SOQL y validaciones por API | 12813| \`web\` | Convertir el acceso en una sesión de navegador. **Sin este, el login falla** | 12814| \`refresh_token\` | No se usa, pero Salesforce exige tenerlo habilitado para permitir el flujo | 12815 12816\`lightning\` y \`visualforce\` **no** sustituyen a \`web\`: dan acceso a esos contenedores, no a la conversión del acceso en sesión. 12817
12818### Casillas que deben quedar SIN marcar 12819 12820- **Emitir tokens de acceso basados en tokens web JSON (JWT) para usuarios nombrados.** El nombre engaña: controla el *formato* de los tokens, no este flujo. Marcarla rompe el login. 12821- **Requerir secreto para flujo e servidor web.** 12822- **Requerir mTLS.** 12823 12824Guarda. Salesforce tarda entre 2 y 10 minutos en activar una aplicación nueva. 12825 12826--- 12827 12828## Paso 3: Copiar la Clave de consumidor 12829 128301. **Configuración â Gestor de aplicaciones**, busca tu aplicación. 128312. Flecha del extremo derecho â **Ver**. 128323. Sección **API** â **Administrar detalles de consumidor**. 128334. Salesforce envÃa un código de verificación por correo. Ingrésalo. 128345. Copia la **Clave de consumidor**. Empieza con \`3MVG9\`. 12835 12836El **Secreto de consumidor** que aparece al lado **no se usa** en este flujo. Solo aplica al modo \`oauth_client_credentials\` para pruebas de API sin navegador. 12837 12838--- 12839 12840## Paso 4: Crear el conjunto de permisos 12841 12842Este conjunto es solo una etiqueta para identificar quién puede usar la aplicación. No le des permisos de datos. 12843 128441. **Configuración â Conjuntos de permisos â Nuevo**. 128452. Etiqueta: \`HAKA Automation JWT\`. 128463. **Guardar**. No marques nada más. 12847 12848> **Por qué uno nuevo y vacÃo:** en el Paso 6 se autoriza a *todos* los usuarios que tengan el conjunto que marques. Si reutilizas uno existente que tiene asignada mucha gente, le das ese acceso a toda esa gente. 12849 12850--- 12851 12852## Paso 5: Asignar el permiso al usuario 12853 128541. **Configuración â Usuarios**, abre el usuario de pruebas. 128552. Baja a **Asignaciones de conjuntos de permisos**. 128563. **Modificar asignaciones**. 128574. Pasa \`HAKA Automation JWT\` a la derecha y **Guardar**. 12858 12859Repite con cada usuario que vaya a representar un perfil. 12860 12861--- 12862 12863## Paso 6: Autorizar el usuario en la aplicación 12864 12865Son dos partes y **ninguna funciona sola**. Es donde más se traba la configuración. 12866 12867### Parte 1: la polÃtica 12868 128691. **Gestor de aplicaciones** â flecha de la derecha â **Administrar**. 128702. **Editar polÃticas**. 128713. **Usuarios permitidos** â **Los usuarios aprobados por el administrador se han autorizado previamente**. 128724. **Guardar**. 12873 12874### Parte 2: la asignación 12875 12876Esta no aparece en la pantalla anterior, hay que volver atrás: 12877 128785. Entra otra vez a **Administrar**, sin hacer clic en Editar polÃticas. 128796. Baja al final de la página. Verás los recuadros **Perfiles** y **Conjuntos de permisos**. 128807. En **Conjuntos de permisos** â **Gestionar conjuntos de permisos**. 128818. Marca \`HAKA Automation JWT\` y **Guardar**. 12882 12883Si haces solo la Parte 1, el error será \`user is not admin approved to access this app\`. Espera unos minutos de propagación antes de probar. 12884 12885### Revisa también Relajación de IP 12886 12887En la misma pantalla de polÃticas, **Relajación de IP** con *Activar restricciones de IP* hace que Salesforce valide la IP de ejecución contra los rangos del usuario. En local puede funcionar y en CI fallar, porque la IP del runner cambia. Si aparecen errores de sesión, cambia a *Relajar restricciones de IP*. 12888 12889--- 12890 12891## Paso 7: Configurar el .env 12892 12893\`\`\`env 12894SF_API_ENABLED=true 12895SF_LOGIN_MODE=frontdoor 12896SF_API_AUTH_MODE=oauth_jwt_bearer 12897SF_API_DOMAIN=test 12898 12899SF_JWT_PRIVATE_KEY_PATH=sf_key/haka_sf.key 12900 12901SF_PERFIL_UAT1_OAUTH_CLIENT_ID=3MVG9...clave_del_paso_3 12902SF_PERFIL_UAT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token 12903[email protected] 12904\`\`\` 12905 12906| Valor | De dónde sale | 12907|---|---| 12908| \`_OAUTH_CLIENT_ID\` | La Clave de consumidor del Paso 3 | 12909| \`_OAUTH_TOKEN_URL\` | La dirección con la que entras a Salesforce en el navegador, más \`/services/oauth2/token\` | 12910| \`_JWT_USERNAME\` | El usuario del Paso 5 | 12911| \`UAT1\` | El nombre que uses en el Gherkin. Si el step dice \`"QA2"\`, las variables son \`SF_PERFIL_QA2_...\` | 12912 12913El detalle completo de variables está en **Configuración (.env)** de esta misma sección. 12914 12915--- 12916 12917## Paso 8: Probar 12918 12919\`\`\`gherkin 12920@salesforce 12921Feature: Prueba de acceso 12922 12923 Scenario: Entrar a Salesforce 12924 Given inicio sesión con el usuario "UAT1" 12925 Then verifico que estoy autenticado en Salesforce 12926\`\`\` 12927 12928Si el step pasa, terminaste. Si falla, el mensaje indica el modo, el código HTTP y el error de Salesforce; búscalo en **Seguridad y Troubleshooting**. 12929 12930--- 12931 12932## Agregar otro ambiente 12933 12934Una aplicación conectada existe en **una sola organización**. Un perfil que apunte a otro sandbox necesita su propia aplicación: repite los pasos 2, 3, 4, 5 y 6 en esa organización. Puedes subir **el mismo** \`haka_sf.crt\`, asà sigues usando una sola llave. 12935 12936Luego agrega tres lÃneas al \`.env\`: 12937 12938\`\`\`env 12939SF_PERFIL_SIT1_OAUTH_CLIENT_ID=clave_del_otro_ambiente
12940SF_PERFIL_SIT1_OAUTH_TOKEN_URL=https://otra-org--sit1.sandbox.my.salesforce.com/services/oauth2/token 12941[email protected] 12942\`\`\` 12943 12944Y en el Gherkin eliges cuál usar: 12945 12946\`\`\`gherkin 12947Given inicio sesión con el usuario "UAT1" 12948Given inicio sesión con el usuario "SIT1" 12949\`\`\` 12950 12951Si el ambiente es **producción** y no un sandbox, agrégale también: 12952 12953\`\`\`env 12954SF_PERFIL_PROD_JWT_AUDIENCE=https://login.salesforce.com 12955\`\`\` 12956 12957--- 12958 12959## Checklist final 12960 12961| # | Paso | Dónde | 12962|---|---|---| 12963| 1 | Generar \`.crt\` y \`.key\`, y agregar \`sf_key/\` al \`.gitignore\` | Terminal | 12964| 2 | Crear la aplicación, subir el \`.crt\`, ámbitos \`api\` + \`web\` + \`refresh_token\` | Gestor de aplicaciones | 12965| 3 | Copiar la Clave de consumidor | Administrar detalles de consumidor | 12966| 4 | Crear el conjunto de permisos | Conjuntos de permisos | 12967| 5 | Asignarlo al usuario | Usuarios | 12968| 6 | PolÃtica de usuarios preautorizados **y** asignar el conjunto a la app | Administrar | 12969| 7 | Configurar el \`.env\` | Proyecto | 12970| 8 | Ejecutar el escenario de prueba | Proyecto |`},{id:"salesforce-configuracion",title:"Configuración (.env)",content:`## Variables de Entorno para Salesforce 12971 12972Agrega las siguientes variables a tu archivo \`.env\`: 12973 12974### Configuración Base 12975 12976\`\`\`env 12977# Habilitar la conexión API de Salesforce 12978SF_API_ENABLED=true 12979 12980# Modo de login: frontdoor usa API + frontdoor.jsp 12981SF_LOGIN_MODE=frontdoor 12982 12983# Dominio API: "test" para sandbox, "login" para producción 12984SF_API_DOMAIN=test 12985 12986# Autenticación: JWT Bearer, sin contraseñas 12987SF_API_AUTH_MODE=oauth_jwt_bearer 12988 12989# Ruta de destino después del login (donde aterriza el navegador) 12990SF_RET_URL=/lightning/page/home 12991 12992# Timeout de navegación frontdoor en segundos 12993SF_FRONTDOOR_TIMEOUT_SECONDS=60 12994\`\`\` 12995 12996### Certificado 12997 12998El acceso se firma con una llave privada. Genera el par de archivos una sola vez: 12999 13000\`\`\`bash 13001mkdir -p sf_key 13002openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:2048 \\ 13003 -keyout sf_key/haka_sf.key -out sf_key/haka_sf.crt \\ 13004 -subj "/CN=haka-automation" 13005\`\`\` 13006 13007El \`.crt\` se sube a la aplicación conectada de Salesforce. El \`.key\` se queda en tu equipo y **nunca** se versiona: agrega \`sf_key/\` al \`.gitignore\`. 13008 13009\`\`\`env 13010SF_JWT_PRIVATE_KEY_PATH=sf_key/haka_sf.key 13011\`\`\` 13012 13013### Perfiles de Usuario 13014 13015Define uno o más perfiles con el patrón \`SF_PERFIL_<NOMBRE>_*\`: 13016 13017\`\`\`env 13018# Perfil UAT1 13019SF_PERFIL_UAT1_OAUTH_CLIENT_ID=3MVG9...clave_de_consumidor 13020SF_PERFIL_UAT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token 13021[email protected] 13022 13023# Perfil SIT1 13024SF_PERFIL_SIT1_OAUTH_CLIENT_ID=3MVG9...clave_de_consumidor 13025SF_PERFIL_SIT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token 13026[email protected] 13027\`\`\` 13028 13029Si ambos perfiles viven en la misma organización comparten la Clave de consumidor y el endpoint; solo cambia el usuario. Perfiles en organizaciones distintas necesitan su propia aplicación conectada, porque una aplicación existe en una sola organización. 13030 13031### Detalle de las Variables por Perfil 13032 13033| Variable | Obligatoria | Descripción | 13034|---|---|---| 13035| \`SF_PERFIL_<NOMBRE>_JWT_USERNAME\` | Sà | Usuario con el que entra el perfil. Si ya existe \`_USER\`, se reutiliza ese valor | 13036| \`SF_PERFIL_<NOMBRE>_OAUTH_CLIENT_ID\` | Sà | Clave de consumidor de la aplicación conectada | 13037| \`SF_PERFIL_<NOMBRE>_OAUTH_TOKEN_URL\` | Sà | URL de la organización con \`/services/oauth2/token\` al final | 13038| \`SF_PERFIL_<NOMBRE>_JWT_PRIVATE_KEY_PATH\` | No | Llave propia del perfil. Si se omite usa \`SF_JWT_PRIVATE_KEY_PATH\` | 13039| \`SF_PERFIL_<NOMBRE>_JWT_AUDIENCE\` | No | Solo para perfiles de producción: \`https://login.salesforce.com\` | 13040| \`SF_PERFIL_<NOMBRE>_URL\` | No | URL de instancia. Si está vacÃa, usa la que devuelve la API | 13041 13042Las variables sin prefijo de perfil (\`SF_OAUTH_CLIENT_ID\`, \`SF_JWT_PRIVATE_KEY_PATH\`, \`SF_JWT_USERNAME\`) funcionan como valor por defecto para todos los perfiles. 13043 13044### Integración continua 13045 13046En CI, en lugar del archivo, entrega el contenido de la llave como secreto: 13047 13048\`\`\`env 13049SF_JWT_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY----- 13050SF_JWT_PRIVATE_KEY_PASSPHRASE=solo_si_la_llave_esta_cifrada 13051\`\`\` 13052 13053### Migración desde el modo anterior 13054
13055Si tu \`.env\` todavÃa tiene estas variables, elimÃnalas y cambia esas credenciales en Salesforce, porque siguen siendo válidas aunque el archivo ya no las use: 13056 13057\`\`\`env 13058SF_PERFIL_UAT1_PASS=... 13059SF_PERFIL_UAT1_TOKEN=... 13060SF_PERFIL_UAT1_OAUTH_CLIENT_SECRET=... 13061\`\`\` 13062 13063El \`_JWT_USERNAME\` puede omitirse si el perfil ya define \`SF_PERFIL_<NOMBRE>_USER\`: ese valor se reutiliza como usuario, asà que migrar no obliga a renombrar variables. 13064 13065### URL de Instancia 13066 13067La \`_URL\` debe ser la **URL base de la instancia** (el dominio de la API), **no** la URL de Lightning completa: 13068 13069\`\`\`env 13070# CORRECTO - URL base de la instancia 13071SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.my.salesforce.com 13072 13073# INCORRECTO - URL de Lightning (no usar) 13074# SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.lightning.force.com/lightning/n/Inicio 13075\`\`\` 13076 13077> Si dejas \`_URL\` vacÃa, \`simple-salesforce\` devuelve automáticamente la instancia correcta al autenticar. Solo necesitas configurarla si quieres forzar una instancia especÃfica. 13078 13079### Variables Opcionales Avanzadas 13080 13081\`\`\`env 13082# Versión API explÃcita (vacÃo = default de simple-salesforce) 13083SF_API_VERSION= 13084 13085# Timeout de llamadas API en segundos 13086SF_API_TIMEOUT_SECONDS=30 13087 13088# Reintentos para errores transitorios (429, 5xx) 13089SF_API_MAX_RETRIES=2 13090 13091# Path del endpoint frontdoor (rara vez necesitas cambiarlo) 13092SF_FRONTDOOR_PATH=/secur/frontdoor.jsp 13093\`\`\``},{id:"salesforce-steps",title:"Steps Disponibles",content:`## Steps de Login por Perfil 13094 13095El step principal para seleccionar un perfil: 13096 13097\`\`\`gherkin 13098# Login con perfil nombrado (el más usado) 13099Given inicio sesión con el usuario "UAT1" 13100Given inicio sesion con el usuario "SIT1" 13101 13102# También funcionan con mayúscula inicial 13103Given Inicio sesión con el usuario "UAT1" 13104Given Inicio sesion con el usuario "SIT1" 13105\`\`\` 13106 13107El nombre del perfil se normaliza automáticamente: \`uat1\`, \`UAT1\`, \` uat1 \` buscan todos \`SF_PERFIL_UAT1_*\`. 13108 13109## Steps Legacy (Compatibilidad) 13110 13111\`\`\`gherkin 13112# Login genérico (usa el perfil default o SF_USERNAME) 13113Given inicio sesión en Salesforce 13114 13115# Login con nombre de perfil (equivale al step principal) 13116Given inicio sesión en Salesforce como "UAT1" 13117\`\`\` 13118 13119## Step de Verificación 13120 13121\`\`\`gherkin 13122# Verifica que Lightning está cargado en la página actual 13123Then verifico que estoy autenticado en Salesforce 13124Then verifico que estoy autenticado en salesforce 13125\`\`\` 13126 13127## Step de Inicialización API (Opcional) 13128 13129Si necesitas el cliente API (\`context.ssf\`) sin abrir el navegador: 13130 13131\`\`\`gherkin 13132# Inicializar solo la conexión API de un perfil 13133Given Inicializa la conexión con Salesforce para el usuario "UAT1" 13134 13135# Inicializar conexión API del usuario base 13136Given Inicializa la conexión con Salesforce 13137\`\`\` 13138 13139Después de este step, \`context.ssf\` contiene el cliente \`simple-salesforce\` listo para ejecutar consultas SOQL, CRUD, etc. 13140 13141## Ejemplo Completo 13142 13143\`\`\`gherkin 13144@salesforce 13145Feature: Pruebas en Salesforce SIT 13146 13147 Background: 13148 Given inicio sesión con el usuario "UAT1" 13149 Then verifico que estoy autenticado en Salesforce 13150 13151 Scenario: Verificar página de inicio 13152 Then deberÃa ver el texto "Inicio" 13153 13154 Scenario: Navegar a Cuentas 13155 When navego al objeto de Salesforce "Account" 13156 Then deberÃa ver el texto "Cuentas" 13157\`\`\` 13158 13159## Ejemplo con Cambio de Perfil 13160 13161\`\`\`gherkin 13162@salesforce 13163Feature: Pruebas con múltiples usuarios 13164 13165 Scenario: Operar como UAT1 13166 Given inicio sesión con el usuario "UAT1" 13167 Then verifico que estoy autenticado en Salesforce 13168 # ... acciones como UAT1 13169 13170 Scenario: Operar como SIT1 13171 Given inicio sesión con el usuario "SIT1" 13172 Then verifico que estoy autenticado en Salesforce 13173 # ... acciones como SIT1 13174 13175 Scenario: Volver a UAT1 sin re-autenticar 13176 Given inicio sesión con el usuario "UAT1" 13177 # Reutiliza el cliente API de UAT1, solo navega de nuevo 13178 Then verifico que estoy autenticado en Salesforce 13179\`\`\``},{id:"salesforce-ui-interaccion",title:"Interacción con la UI",content:`## Interacción con la UI de Salesforce (Lightning) 13180 13181Además del login, el framework incluye un catálogo de pasos para **interactuar con la interfaz de Salesforce Lightning**: navegar entre apps y objetos, crear/editar/eliminar registros, llenar campos, seleccionar picklists, resolver lookups, manejar mensajes toast y más. Todos resuelven variables (\`\${VARIABLE}\`) igual que el resto del framework. 13182 13183### Esperar la carga de Lightning 13184 13185\`\`\`gherkin 13186# Espera a que desaparezca el spinner de carga y el header quede visible 13187When espero a que cargue Salesforce Lightning 13188\`\`\` 13189 13190> Ãtil justo después de \`inicio sesión con el usuario "..."\` o después de navegar a una app/objeto, para asegurar que Lightning terminó de renderizar antes de interactuar. 13191 13192### Navegación 13193 13194\`\`\`gherkin
13195# Abrir una app desde el App Launcher (busca en "View All" si no está visible) 13196When navego a la aplicación de Salesforce "Ventas" 13197 13198# Ir al listado de un objeto (Account, Contact, Opportunity, objetos personalizados, etc.) 13199When navego al objeto de Salesforce "Account" 13200 13201# Abrir un registro especÃfico por Id 13202When abro el registro "001XXXXXXXXXXXX" de Salesforce para el objeto "Account" 13203 13204# Cambiar de pestaña dentro de un registro (Detalles, Relacionado, Chatter, etc.) 13205When hago click en la pestaña "Relacionado" de Salesforce 13206 13207# Cambiar entre Lightning y Classic 13208When cambio a la vista clásica de Salesforce 13209When cambio a la vista Lightning de Salesforce 13210\`\`\` 13211 13212> \`navego al objeto de Salesforce\` primero intenta hacer click en el menú de navegación; si no encuentra el objeto ahÃ, navega directo por URL (\`/lightning/o/{objeto}/list\`), asà que funciona incluso con objetos que no están fijados en la barra de navegación. 13213 13214### Crear, editar y eliminar registros 13215 13216\`\`\`gherkin 13217# Iniciar la creación de un registro nuevo (abre el modal/formulario) 13218When creo un nuevo registro de Salesforce para el objeto "Account" 13219 13220# Llenar un campo del formulario (detecta input, textarea, lightning-input, lightning-textarea) 13221When relleno el campo de Salesforce "Name" con "Acme Corp" 13222When relleno el campo de Salesforce "Phone" con "\${TELEFONO_CLIENTE}" 13223 13224# Seleccionar una opción de un picklist 13225When selecciono la opción "Technology" del picklist "Industry" de Salesforce 13226 13227# Resolver un campo lookup (escribe el término, espera resultados y selecciona el primero) 13228When busco y selecciono el lookup "AccountId" de Salesforce con "Acme" 13229 13230# Guardar el registro (espera a que el spinner de guardado desaparezca) 13231When guardo el registro de Salesforce 13232 13233# Editar un registro ya abierto 13234When edito el registro de Salesforce 13235 13236# Eliminar el registro actual (usa el menú de acciones y confirma el modal) 13237When elimino el registro de Salesforce 13238\`\`\` 13239 13240### Verificación de datos y mensajes 13241 13242\`\`\`gherkin 13243# Verificar el valor de un campo en la vista de detalle de un registro 13244Then verifico que el campo "Industry" del registro de Salesforce contiene "Technology" 13245 13246# Esperar un mensaje toast por tipo 13247Then espero el mensaje toast de Salesforce "success" 13248Then espero el mensaje toast de Salesforce "error" 13249 13250# Cerrar todos los toasts visibles (útil antes de continuar el flujo) 13251When cierro los mensajes toast de Salesforce 13252\`\`\` 13253 13254| Tipo de toast | Selector interno | 13255|---|---| 13256| \`success\` | \`.slds-notify--toast.slds-theme--success\` | 13257| \`error\` | \`.slds-notify--toast.slds-theme--error\` | 13258| \`warning\` | \`.slds-notify--toast.slds-theme--warning\` | 13259| \`info\` | \`.slds-notify--toast.slds-theme--info\` | 13260 13261### Búsqueda global 13262 13263\`\`\`gherkin 13264When busco en la búsqueda global de Salesforce con "Acme Corp" 13265\`\`\` 13266 13267### Ejemplo completo (crear y validar una cuenta) 13268 13269\`\`\`gherkin 13270@salesforce 13271Feature: Crear cuenta en Salesforce 13272 13273 Background: 13274 Given inicio sesión con el usuario "UAT1" 13275 Then verifico que estoy autenticado en Salesforce 13276 13277 Scenario: Crear una cuenta nueva y confirmar el guardado 13278 When navego al objeto de Salesforce "Account" 13279 And creo un nuevo registro de Salesforce para el objeto "Account" 13280 And relleno el campo de Salesforce "Name" con "Acme Corp" 13281 And selecciono la opción "Technology" del picklist "Industry" de Salesforce 13282 And guardo el registro de Salesforce 13283 Then espero el mensaje toast de Salesforce "success" 13284 And verifico que el campo "Industry" del registro de Salesforce contiene "Technology" 13285\`\`\` 13286 13287### Ejemplo con lookup y edición 13288 13289\`\`\`gherkin 13290@salesforce 13291Feature: Asociar un contacto a una cuenta existente 13292 13293 Scenario: Editar contacto y asociar su cuenta vÃa lookup 13294 Given inicio sesión con el usuario "UAT1" 13295 When navego al objeto de Salesforce "Contact" 13296 And busco en la búsqueda global de Salesforce con "Juan Pérez" 13297 And abro el registro "003XXXXXXXXXXXX" de Salesforce para el objeto "Contact" 13298 And edito el registro de Salesforce 13299 And busco y selecciono el lookup "AccountId" de Salesforce con "Acme Corp" 13300 And guardo el registro de Salesforce 13301 Then espero el mensaje toast de Salesforce "success" 13302\`\`\` 13303 13304> Estos pasos están pensados para Lightning Experience. Si tu org usa mucho Classic, recuerda que \`cambio a la vista clásica de Salesforce\` / \`cambio a la vista Lightning de Salesforce\` te permiten alternar cuando algún flujo lo requiera.`},{id:"salesforce-api-consultas",title:"Consultas e Integridad (API)",content:`## Consultas SOQL e Integridad de Objetos (API) 13305 13306Además de las pruebas de UI, el framework incluye pasos para **consultar y validar tus objetos de Salesforce directamente por API*
13306*, sin abrir el navegador. Sirven para comprobar la **integridad** de tu configuración: que un objeto tenga los campos correctos, que un picklist tenga los valores esperados, que un campo sea obligatorio, cuántos registros existen, etc. 13307 13308Son ideales para pruebas rápidas con los tags \`@api @no_browser\`. 13309 13310### ¿Necesito configurar una API nueva o credenciales nuevas? â NO 13311 13312Esta es la parte importante y donde más gente se confunde: 13313 13314> **Si ya tienes Salesforce funcionando con perfiles (\`SF_PERFIL_...\`), NO tienes que agregar ninguna variable nueva, ninguna API key, ni ningún endpoint.** Estos pasos **reutilizan la misma conexión del perfil** que ya usas para iniciar sesión. 13315 13316Es decir, si tu \`.env\` ya tiene algo como esto (que es lo normal): 13317 13318\`\`\`env 13319SF_API_ENABLED=true 13320SF_LOGIN_MODE=frontdoor 13321SF_API_DOMAIN=test 13322 13323SF_API_AUTH_MODE=oauth_jwt_bearer 13324SF_JWT_PRIVATE_KEY_PATH=sf_key/haka_sf.key 13325 13326SF_PERFIL_UAT1_OAUTH_CLIENT_ID=3MVG9...clave_de_consumidor 13327SF_PERFIL_UAT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token 13328[email protected] 13329\`\`\` 13330 13331...entonces **ya está todo listo**. No agregues nada más. Los pasos de consulta usan la conexión de ese mismo perfil. 13332 13333### ¿Cómo se conecta entonces? â Con el perfil que indicas en el paso 13334 13335Tienes dos formas de dejar lista la conexión antes de consultar: 13336 13337**Opción A â Ya iniciaste sesión (prueba de UI + consultas):** 13338Si en tu escenario ya hiciste el login normal de Salesforce, los pasos de consulta **reutilizan automáticamente** esa sesión. No necesitas hacer nada extra: 13339 13340\`\`\`gherkin 13341Given inicio sesión con el usuario "UAT1" 13342When ejecuto la consulta SOQL "SELECT Id, Name FROM Account LIMIT 5" 13343Then la consulta devuelve al menos un registro 13344\`\`\` 13345 13346**Opción B â Solo API, sin navegador (recomendada para integridad):** 13347Usa el paso de inicialización indicando **el mismo perfil** de tu \`.env\`. Esto conecta por API con las credenciales de ese perfil, sin abrir Chrome: 13348 13349\`\`\`gherkin 13350Given inicializo la API de Salesforce para el usuario "UAT1" 13351\`\`\` 13352 13353El \`"UAT1"\` de aquà es exactamente el mismo nombre que usas en \`SF_PERFIL_UAT1_...\`. Cambia a \`"SIT1"\` para usar el otro perfil, etc. 13354 13355> **Ojo con el paso sin perfil:** existe también \`Given inicializo la API de Salesforce\` (sin nombre de usuario). Ese usa el "usuario base" (\`SF_USERNAME\` / \`SF_PASSWORD\` / \`SF_SECURITY_TOKEN\`), que normalmente **no** tienes configurado si trabajas con perfiles. Si usas perfiles, usa siempre la versión **"para el usuario"**. 13356 13357### Requisitos 13358 13359- Tu perfil ya funciona para login (ese mismo usuario sirve para las consultas). 13360- \`SF_API_ENABLED=true\` (ya lo tienes si usas \`frontdoor\`). 13361- Nada más. No hay API keys extra ni endpoints que configurar. 13362 13363### Variables en los pasos 13364 13365Todos los valores de estos pasos aceptan la misma sintaxis de variables que usas en el resto de tus features (por ejemplo variables guardadas con pasos previos o valores del entorno), asà no necesitas escribir IDs o valores fijos dentro del \`.feature\`. 13366 13367### Ejemplo completo (integridad de un picklist) 13368 13369\`\`\`gherkin 13370@api @no_browser @salesforce 13371Feature: Integridad de Account 13372 13373 Scenario: El picklist Industry mantiene sus valores 13374 Given inicializo la API de Salesforce para el usuario "UAT1" 13375 Then el objeto "Account" existe 13376 And el objeto "Account" tiene el campo "Industry" 13377 And el campo "Industry" del objeto "Account" es de tipo "picklist" 13378 And el campo "Name" del objeto "Account" es obligatorio 13379 And el picklist "Industry" del objeto "Account" contiene el valor "Technology" 13380 And el picklist "Industry" del objeto "Account" contiene los valores "Banking, Retail, Technology" 13381\`\`\` 13382 13383En el inventario siguiente están todos los pasos disponibles, agrupados por tipo.`},{id:"salesforce-api-inventario",title:"Inventario: Consultas e Integridad",content:`## Inventario de Pasos â Consultas e Integridad (API) 13384 13385Recuerda: primero conecta con \`Given inicializo la API de Salesforce para el usuario "UAT1"\` (o reutiliza tu login de Salesforce ya hecho). Después usa cualquiera de estos pasos. El Ãndice de registros \`{i}\` empieza en **1**. 13386 13387### Conexión 13388 13389\`\`\`gherkin 13390# Conectar por API usando un perfil del .env (recomendado, sin navegador) 13391Given inicializo la API de Salesforce para el usuario "UAT1" 13392Given inicializo la API de Salesforce para el perfil "UAT1" # alias, mismo comportamiento 13393 13394# Conectar con el usuario base (solo si usas SF_USERNAME/SF_PASSWORD/SF_SECURITY_TOKEN) 13395Given inicializo la API de Salesforce 13396Given inicializo la conexión API de Salesforce # alias, mismo comportamiento 13397\`\`\` 13398 13399### Consultas SOQL 13400 13401\`\`\`gherkin 13402When ejecuto la consulta SOQL "SELECT Id, Name FROM Account WHERE Name != null" 13403When ejecuto la consulta SOQL de Salesforce "SELECT Id, Name FROM Account WHERE Name != null" # alias 13404When ejecuto la consulta SOQL completa "SELECT Id FROM Contact" # trae TODAS las páginas 13405When guardo el resultado de la consulta SOQL "SELECT Id FROM Account LIMIT 3" en la variable "cuentas" 13406 13407Then la consulta devuelve 5 registros 13408Then la consulta devuelve al menos 1 registros 13409Then la consulta devuelve como máximo 10 registros 13410Then la consulta devuelve al menos un registro 13411Then la consulta no devuelve registros 13412 13413Then el registro 1 tiene el campo "Name" igual a "Acme" 13414Then el registro 1 tiene el campo "Name" que contiene "Acm"
13415Then el campo "Industry" del registro 1 no está vacÃo 13416Then el campo "Industry" del registro 1 está vacÃo 13417Then algún registro tiene el campo "Type" igual a "Customer" 13418Then todos los registros tienen el campo "IsActive" igual a "true" 13419Then ningún registro tiene el campo "Type" igual a "Prospect" 13420 13421When guardo el campo "Id" del registro 1 en la variable "primerId" 13422When cuento los registros de la consulta y los guardo en la variable "total" 13423\`\`\` 13424 13425> Los campos aceptan rutas con punto para relaciones, por ejemplo \`"Account.Name"\`. 13426 13427### Conteo por objeto 13428 13429\`\`\`gherkin 13430Then el objeto "Account" tiene 100 registros 13431Then el objeto "Account" tiene al menos 1 registros 13432Then el objeto "Account" tiene 3 registros donde "Industry = 'Technology'" 13433Then el objeto "Account" tiene registros donde "Name != null" 13434Then existe al menos un registro de "Contact" donde "Email != null" 13435Then el objeto "Lead" no tiene registros donde "Status = 'Junk'" 13436 13437When cuento los registros de "Account" donde "Industry = 'Banking'" y los guardo en la variable "bancos" 13438When cuento los registros de "Contact" y los guardo en la variable "totalContactos" 13439\`\`\` 13440 13441### Registro por Id 13442 13443\`\`\`gherkin 13444When obtengo el registro "001XXXXXXXXXXXX" del objeto "Account" 13445Then el último registro obtenido tiene el campo "Name" igual a "Acme" 13446When guardo el campo "OwnerId" del último registro obtenido en la variable "dueno" 13447\`\`\` 13448 13449### Integridad de objetos 13450 13451\`\`\`gherkin 13452Then el objeto "Account" existe 13453Then existe el objeto "Account" en Salesforce # alias, mismo comportamiento 13454Then el objeto "ObjetoInventado__c" no existe 13455Then el objeto "Account" tiene el campo "Industry" 13456Then el objeto "Account" no tiene el campo "CampoQueNoDebeExistir__c" 13457Then el objeto "Account" tiene los campos "Name, Industry, Phone" 13458Then el objeto "Account" tiene al menos 10 campos 13459Then el objeto "Account" tiene 45 campos 13460Then el objeto "MiObjeto__c" es personalizado 13461Then el objeto "Account" permite crear registros 13462When describo el objeto "Account" 13463\`\`\` 13464 13465### Integridad de campos 13466 13467\`\`\`gherkin 13468Then el campo "Industry" del objeto "Account" es de tipo "picklist" 13469Then el campo "Name" del objeto "Account" es obligatorio 13470Then el campo "Website" del objeto "Account" es opcional 13471Then el campo "Email" del objeto "Contact" es único 13472Then el campo "Name" del objeto "Account" es actualizable 13473Then el campo "CreatedDate" del objeto "Account" es de solo lectura 13474Then el campo "Name" del objeto "Account" tiene longitud 255 13475Then el campo "Name" del objeto "Account" tiene longitud máxima 255 13476Then la etiqueta del campo "Industry" del objeto "Account" es "Sector" 13477Then el campo "AccountId" del objeto "Contact" referencia al objeto "Account" 13478\`\`\` 13479 13480> Tipos comunes de Salesforce: \`string\`, \`textarea\`, \`picklist\`, \`multipicklist\`, \`reference\`, \`boolean\`, \`double\`, \`currency\`, \`date\`, \`datetime\`, \`email\`, \`phone\`, \`id\`. 13481 13482### Integridad de picklists 13483 13484\`\`\`gherkin 13485Then el picklist "Industry" del objeto "Account" contiene el valor "Technology" 13486Then el picklist "Industry" del objeto "Account" no contiene el valor "Obsoleto" 13487Then el picklist "Industry" del objeto "Account" contiene los valores "Banking, Retail, Technology" 13488Then el picklist "Industry" del objeto "Account" contiene exactamente los valores "Banking, Retail, Technology" 13489Then el picklist "Industry" del objeto "Account" tiene 35 valores 13490Then el picklist "Industry" del objeto "Account" tiene 30 valores activos 13491Then el valor por defecto del picklist "Estado__c" del objeto "MiObjeto__c" es "Nuevo" 13492Then el valor "Technology" del picklist "Industry" del objeto "Account" está activo 13493Then el valor "Obsoleto" del picklist "Industry" del objeto "Account" está inactivo 13494When guardo los valores del picklist "Industry" del objeto "Account" en la variable "sectores" 13495\`\`\` 13496 13497- **contiene los valores**: verifica que estén TODOS los indicados (pueden existir otros más). 13498- **contiene exactamente los valores**: el conjunto de valores **activos** debe ser idéntico al indicado (ni más ni menos). 13499 13500### Tipos de registro 13501 13502\`\`\`gherkin 13503Then el objeto "Opportunity" tiene el tipo de registro "Ventas" 13504Then el objeto "Opportunity" tiene 2 tipos de registro 13505\`\`\` 13506 13507### REST genérico (avanzado) 13508 13509\`\`\`gherkin 13510When ejecuto una petición REST de Salesforce a "limits" 13511Then la respuesta REST de Salesforce tiene el campo "DailyApiRequests.Max" igual a "15000" 13512\`\`\` 13513 13514Todos estos pasos quedan registrados en el reporte HTML con la consulta y su resultado, para que puedas revisarlos de
13514spués.`},{id:"salesforce-reutilizacion",title:"Reutilización y Paralelismo",content:`## Reutilización de Sesión 13515 13516El framework es inteligente con la reutilización: 13517 13518### Mismo Perfil, Misma Sesión 13519 13520Si llamas \`inicio sesión con el usuario "UAT1"\` dos veces seguidas: 135211. La primera vez: autentica por API + abre frontdoor.jsp + espera Lightning. 135222. La segunda vez: verifica que Lightning sigue cargado â **no hace nada** (no navega, no re-autentica). 13523 13524### Cambio de Perfil 13525 13526Si cambias de \`UAT1\` a \`SIT1\`: 135271. Obtiene o crea el cliente API de \`SIT1\`. 135282. Abre frontdoor.jsp con la sesión de \`SIT1\`. 135293. Ambos clientes quedan en cache. 13530 13531### Regreso a un Perfil Anterior 13532 13533Si vuelves a \`UAT1\` después de usar \`SIT1\`: 135341. Reutiliza el cliente API de \`UAT1\` (ya estaba conectado). 135352. Solo navega para restaurar la sesión de \`UAT1\` en el navegador. 13536 13537### Retención Entre Features 13538 13539La sesión se conserva entre features del mismo proceso. Si el \`Background\` de cada feature llama al mismo perfil, solo el primer feature navega; los siguientes reutilizan. 13540 13541## Ejecución Paralela 13542 13543### Aislamiento por Proceso 13544 13545Cada worker paralelo ejecuta un subprocess independiente con: 13546- Su propio browser Playwright. 13547- Su propio BrowserContext y cookies. 13548- Su propio cache de clientes API. 13549- Sus propias sesiones Salesforce. 13550 13551**No se comparte nada entre workers.** 13552 13553### Limitación con Mismo Usuario 13554 13555Si dos workers usan el mismo usuario Salesforce y ambos **modifican datos**, Salesforce puede producir conflictos (locks, errores de concurrencia). Recomendaciones: 13556 13557| Situación | Recomendación | 13558|---|---| 13559| Features de solo lectura | Pueden compartir usuario sin problemas | 13560| Features que modifican datos | Usar un usuario distinto por worker | 13561| Features mixtos | Separar por tags y asignar usuarios | 13562 13563### Configuración para Múltiples Workers 13564 13565\`\`\`env 13566# Worker 1 usa UAT1 13567[email protected] 13568 13569# Worker 2 usa UAT2 13570[email protected] 13571\`\`\` 13572 13573Ambos comparten la aplicación conectada y el certificado; solo cambia el usuario. 13574 13575\`\`\`gherkin 13576# Feature asignado a worker 1 13577@worker1 13578Feature: Operaciones en cuentas 13579 Given inicio sesión con el usuario "UAT1" 13580 13581# Feature asignado a worker 2 13582@worker2 13583Feature: Operaciones en contactos 13584 Given inicio sesión con el usuario "UAT2" 13585\`\`\``},{id:"salesforce-seguridad",title:"Seguridad y Troubleshooting",content:'## Seguridad\n### La Llave Privada\n- **Nunca versionar el `.key`.** Agrega `sf_key/` a `.gitignore`. Con ese archivo se puede entrar a Salesforce como los usuarios autorizados, sin contraseña y sin verificación por correo.\n- En CI, entrégala como secreto en `SF_JWT_PRIVATE_KEY` en lugar de subir el archivo.\n- El conjunto de permisos asignado a la aplicación conectada es el control real de quién puede autenticarse. RevÃsalo periódicamente y no reutilices uno que tenga asignada mucha gente.\n### Credenciales\n- **Nunca versionar el `.env`** en Git. Agrega `.env` a `.gitignore`.\n- En CI/CD, usa secretos del pipeline (GitHub Secrets, GitLab CI Variables, etc.).\n- El framework enmascara automáticamente passwords, tokens y `sid` en logs, errores y reportes.\n### Qué se Enmascara\n- `SF_PASSWORD`, `SF_SECURITY_TOKEN`\n- `SF_PERFIL_*_PASS`, `SF_PERFIL_*_TOKEN`\n- Llave privada, client secret y access tokens en mensajes de error\n- Parámetro `sid` en URLs de frontdoor\n- Cualquier valor que coincida con patterns de password/token en textos de error\n### Permisos del Usuario\nLas pruebas ven exactamente lo que ve el usuario del perfil. Si le faltan permisos sobre un objeto, las consultas SOQL **no dan error**: devuelven cero resultados, y el fallo parece un problema de datos cuando en realidad es de permisos.\n## Troubleshooting\nLos errores de autenticación informan el modo activo, el código HTTP y el mensaje de Salesforce. Por ejemplo: `modo=oauth_jwt_bearer; HTTP 400; error=invalid_app_access`.\n### Error: "user is not admin approved to access this app"\nFalta autorizar al usuario en la aplicación conectada. Son dos partes y ninguna funciona sola:\n1. **Administrar â Editar polÃticas â Usuarios permitidos** â *Los usuarios a
13585probados por el administrador se han autorizado previamente*.\n2. Volver a **Administrar** sin editar, bajar al recuadro **Conjuntos de permisos** y asignar ahà el conjunto que tiene el usuario.\nDespués de guardar, espera unos minutos de propagación.\n### Error: "invalid assertion" o "audience is invalid"\nLa llave privada no corresponde al certificado subido, o el `aud` es incorrecto. El `aud` es `https://test.salesforce.com` para sandbox y `https://login.salesforce.com` para producción, y **no** es la URL de tu organización: esa va en `_OAUTH_TOKEN_URL`.\n### Error: "invalid_client"\nLa Clave de consumidor está mal copiada, o la aplicación conectada todavÃa no se activó. Salesforce tarda entre 2 y 10 minutos en activar una aplicación nueva.\n### Error: "request not supported on this domain"\nLa dirección de `_OAUTH_TOKEN_URL` no corresponde. Usa la misma con la que entras a Salesforce por el navegador, agregando `/services/oauth2/token`.\n### Error: "Salesforce rechazó la sesión y mostró su pantalla de login"\nEl acceso se obtuvo pero no abrió la pantalla. Revisa:\n1. Que la aplicación conectada tenga el ámbito `web` (*Gestionar datos de usuario a través de navegadores*).\n2. Que el usuario no tenga el permiso **Solo API**, porque ese tipo de usuario no puede abrir sesión de navegador.\n3. Que no lo bloqueen MFA, SSO o restricciones de IP. En la aplicación, **Relajación de IP** suele necesitar *Relajar restricciones de IP* para CI, donde la IP cambia.\n4. Que `SF_API_AUTH_MODE` no sea `oauth_client_credentials`: ese modo no abre sesión de navegador.\n### Error: "Salesforce no alcanzó Lightning en la fase frontdoor"\n**Causas comunes:**\n1. **URL incorrecta en `_URL`**: Debe ser la URL base (`my.salesforce.com`), no la URL de Lightning (`lightning.force.com`).\n ```env\n # BIEN\n SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.my.salesforce.com\n # MAL\n SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.lightning.force.com/lightning/n/Inicio\n ```\n2. **Usuario sin API Enabled**: Revisa el perfil del usuario en Salesforce â System Permissions â API Enabled.\n3. **MFA/SSO activo**: frontdoor.jsp no puede saltarse MFA. Coordina con el admin para desactivarlo en el ambiente de prueba.\n4. **Timeout muy bajo**: Aumenta `SF_FRONTDOOR_TIMEOUT_SECONDS` si la org es lenta.\n### Error: "Faltan credenciales JWT del perfil \'X\'"\nEl nombre del perfil no coincide con las variables del `.env`. Verifica:\n- El nombre en el step se normaliza a mayúsculas: `"uat1"` busca `SF_PERFIL_UAT1_*`.\n- Espacios y guiones se convierten en `_`: `"uat 1"` busca `SF_PERFIL_UAT_1_*`.\n- Debe existir el usuario, la Clave de consumidor y la llave privada, ya sea por perfil o como valor global.\n### Error: "SF_LOGIN_MODE=frontdoor requiere SF_API_ENABLED=true"\nAgrega `SF_API_ENABLED=true` en tu `.env`.\n### Error: "simple-salesforce no está instalada"\nReinstala el framework:\n```bash\npip install --upgrade haka-playwright-engine\n```\n### Advertencia en el log: "Salesforce está retirando el login SOAP"\nTu `.env` está usando `SF_API_AUTH_MODE=legacy_soap`, con usuario, contraseña y security token. Ese método ya no está disponible en API 65.0 y posteriores. Migra a `oauth_jwt_bearer`.\n### ¿Dónde obtengo la Clave de consumidor?\nEn Salesforce: **Configuración â Gestor de aplicaciones**, flecha de la derecha de tu aplicación â **Ver** â sección **API** â **Administrar detalles de consumidor**. Salesforce envÃa un código de verificación por correo antes de mostrarla.\n> **Nota:** El **Secreto de consumidor** que aparece junto a la Clave no se usa con JWT Bearer. Solo aplica al modo `oauth_client_credentials` para pruebas de API sin navegador.'}]},{id:"sap",title:"SAP (UI5 / Fiori)",group:"Aplicaciones Empresariales",icon:"",topics:[{id:"sap-descripcion",title:"Descripción General",content:'## Automatización de SAP Web (SAPUI5 / Fiori)\n\nSAP Web (SAPUI5, OpenUI5, Fiori Launchpad, Fiori Elements) **no usa elementos HTML nativos**. Un "checkbox" no es un `<input type="checkbox">`, un "select" no es un `<select>` y una "tabla" no son `<table>` estándar. Todo se renderiza como `div`/`span`/`ul`/`li` con clases propias (`sapM*`, `sapUi*`, `sapF*`) y atributos ARIA.\n\nEsto rompe los pasos genéricos de cualquier framework. Por eso Haka incluye un catálogo dedicado de **101 pasos SAP** (202 patrones contando el al
13585ias con `que` inicial) que conocen estos patrones: controles UI5, roles ARIA, tablas responsive vs grid y los *busy indicators* de OData.\n\n### Regla de oro\n\nTodos los pasos SAP llevan la palabra **`SAP`** o **`Fiori`** en su nombre. Si un paso no la lleva, es un paso genérico del framework (que también puedes usar cuando aplique: navegación, ventanas, evidencias, aserciones de texto).\n\n### Qué cubre el catálogo SAP\n\n| CategorÃa | Pasos |\n|---|---|\n| Base (click por texto, combobox, tabla, botón) | 7 |\n| Estados de carga y espera (OData) | 4 |\n| Inputs y campos de texto | 10 |\n| CheckBox / RadioButton / Switch | 9 |\n| Mensajes (Toast / MessageBox / MessageStrip / MessagePopover) | 8 |\n| Tablas (responsive + grid) | 13 |\n| Select / MultiComboBox / Value Help (F4) | 6 |\n| Diálogos y popovers | 6 |\n| Navegación Fiori Launchpad | 9 |\n| Botones y acciones (avanzado) | 8 |\n| DatePicker / DateRange | 5 |\n| Tabs / IconTabBar / Wizard | 4 |\n| ObjectPage (Fiori Elements) | 4 |\n| Utilidades / Avanzado | 5 |\n| Elementos genéricos SAP por POM | 3 |\n| **Total** | **101** |\n\n> Todos los pasos SAP tienen nombres únicos, sin ambigüedad de Behave ni conflictos de prefijo con el resto del catálogo. Cada paso admite el prefijo opcional `que` (ej: `que hago click en el elemento SAP ...`) para encadenar en `And`/`Y`.'},{id:"sap-espera-carga",title:"Espera Inteligente (OData)",content:`## Espera inteligente: lo primero que debes saber 13586 13587SAP carga datos de forma asÃncrona vÃa **OData**. Entre una acción y la siguiente suele aparecer un *busy indicator* que bloquea la UI. Si interactúas antes de que desaparezca, el paso falla de forma intermitente (flaky). 13588 13589Casi todos los pasos SAP ya esperan internamente a que SAP esté listo, pero cuando necesites una espera explÃcita entre acciones: 13590 13591\`\`\`gherkin 13592When hago click en el elemento SAP "boton GO" con identificador "$.APP.btn_go" 13593And espero a que SAP termine de cargar 13594Then verifico que la tabla SAP "resultados" con identificador "$.APP.tabla" tiene 15 filas 13595\`\`\` 13596 13597### Consideraciones 13598 13599- \`espero a que SAP termine de cargar\` espera a que desaparezcan **todos** los busy indicators globales. 13600- \`espero a que la tabla SAP "X" cargue datos\` es más especÃfico: espera a que la tabla salga de busy y renderice filas. 13601- Evita \`espero N segundos\` (hardcoded). Usa las esperas SAP inteligentes.`},{id:"sap-inicio-rapido",title:"Inicio Rápido (Ejemplos)",content:`## Ejemplos reales de flujos SAP 13602 13603### Flujo S/4HANA â Manage Supplier Line + Monitor Grant 13604 13605\`\`\`gherkin 13606@sap 13607Scenario: Flujo S/4HANA - Manage Supplier Line + Monitor Grant 13608 Given voy a la url "\${ENV.URL_BASE}" 13609 And escribo "[email protected]" en el input SAP "Usuario" con identificador "$.DEMO_SAP.login_username" 13610 And hago click en el elemento SAP "boton login" con identificador "$.DEMO_SAP.btn_login" 13611 And escribo "\${ENV.PASS_SAP}" en el input SAP "Pass" con identificador "$.DEMO_SAP.login_password" 13612 * evidencia "Login completo" 13613 And hago click en el elemento SAP "boton login" con identificador "$.DEMO_SAP.btn_login" 13614 And hago click en el elemento SAP "Accounts Payable" con identificador "$.DEMO_SAP.seccion_accounts" 13615 When intento cambiar a la ventana con url que contiene "my300180.s4hana.ondemand.com" esperando hasta 60 segundos 13616 And espero a que SAP termine de cargar 13617 And si existe el elemento SAP "Cerrar Tour" con identificador "$.DEMO_SAP.leave_tour" hago click 13618 And hago click en el elemento SAP "Menú Home" con identificador "$.DEMO_SAP.Menu_Home" 13619 And hago click en el elemento SAP "Manage Supplier Line" con identificador "$.DEMO_SAP.Opcion_MSLI" 13620 When selecciono "All Items" del combobox SAP "Status" con identificador "$.DEMO_SAP.msli_status" 13621 And hago click en el elemento SAP "boton GO" con identificador "$.DEMO_SAP.msli_go" 13622 And hago click en el elemento SAP "Primer elemento del listado" con identificador "$.DEMO_SAP.primer_registro" 13623 * evidencia "Manage Supplier" 13624 Then verifico que el elemento SAP "Panel Billing Details" con identificador "$.DEMO_SAP.panel_grant_billig" está visible 13625 And deberÃa ver el texto "33,73K" 13626\`\`\` 13627 13628### Fiori Launchpad â abrir app, filtrar tabla y validar 13629 13630\`\`\`gherkin 13631@sap 13632Scenario: Fiori Launchpad - abrir app, filtrar tabla y validar 13633 Given voy a la url "\${ENV.FIORI_URL}" 13634 And verifico que estoy en el launchpad de Fiori 13635 When abro el tile de Fiori "Manage Purchase Orders" 13636 And espero a que SAP termine de cargar
13637 And selecciono "All Items" del combobox SAP "Status" con identificador "$.PO.status" 13638 And hago click en el elemento SAP "Go" con identificador "$.PO.btn_go" 13639 And espero a que la tabla SAP "resultados" cargue datos 13640 Then verifico que la tabla SAP "resultados" con identificador "$.PO.tabla" contiene el texto "ACME Corp" 13641 And verifico que la tabla SAP "resultados" con identificador "$.PO.tabla" tiene 15 filas 13642\`\`\` 13643 13644### Formulario SAP â inputs, selects, checkbox y validación 13645 13646\`\`\`gherkin 13647@sap 13648Scenario: Formulario SAP - inputs, selects, checkbox y validación 13649 Given voy a la url "\${ENV.FIORI_URL}" 13650 When abro del grupo de Fiori "Compras" el tile "Create Supplier Invoice" 13651 And escribo "ACME Corp" en el input SAP "Proveedor" con identificador "$.INV.proveedor" 13652 And selecciono "CLP" del select SAP "Moneda" con identificador "$.INV.moneda" 13653 And selecciono la fecha "15/03/2025" en el DatePicker SAP "Fecha" con identificador "$.INV.fecha" 13654 And marco el checkbox SAP "Pago inmediato" con identificador "$.INV.pago_inmediato" 13655 And presiono el botón de acción "Save" del footer SAP 13656 Then verifico el mensaje toast SAP "Factura creada correctamente" 13657\`\`\` 13658 13659> Los pasos SAP se combinan con los genéricos del framework: \`voy a la url\`, \`intento cambiar a la ventana ...\`, \`* evidencia\` y \`deberÃa ver el texto\` siguen siendo genéricos.`},{id:"sap-inv-base",title:"Inventario: Base, Cargas y Espera",content:`## SAP UI5 / Fiori (base) 13660 13661step: hago click en el texto "{text}" 13662descripcion: Hace click en cualquier elemento que contenga el texto visible especificado. 13663 13664step: selecciono "{option}" del combobox SAP "{element_name}" con identificador "{identifier}" 13665descripcion: Selecciona una opción de un combobox SAP UI5. 13666 13667step: selecciono "{option}" del combobox SAP que muestra "{current_value}" 13668descripcion: Selecciona una opción de un combobox SAP identificándolo por su valor actual visible. 13669 13670step: abro el combobox SAP "{element_name}" con identificador "{identifier}" 13671descripcion: Abre un combobox SAP sin seleccionar opción (para inspección o validación). 13672 13673step: escribo "{text}" en el campo SAP "{element_name}" con identificador "{identifier}" y selecciono "{option}" 13674descripcion: Escribe en un campo SAP (search/input) y selecciona una opción del autocomplete. 13675 13676step: selecciono la fila con texto "{text}" en la tabla SAP "{table_name}" con identificador "{identifier}" 13677descripcion: Selecciona una fila de una tabla SAP UI5 buscando por texto visible en cualquier celda. 13678 13679step: presiono el botón SAP "{button_text}" 13680descripcion: Presiona un botón SAP UI5 por su texto visible. 13681 13682## Estados de carga y espera 13683 13684step: espero a que SAP termine de cargar 13685descripcion: Espera a que desaparezcan todos los busy indicators globales de SAP. 13686 13687step: espero a que desaparezca el busy indicator SAP 13688descripcion: Espera a que desaparezca el busy indicator local de SAP. 13689 13690step: espero a que la tabla SAP "{table_name}" cargue datos 13691descripcion: Espera a que una tabla SAP salga de estado busy y tenga filas. 13692 13693step: espero a que el diálogo SAP "{title}" aparezca 13694descripcion: Espera a que un diálogo SAP con el tÃtulo dado se haga visible.`},{id:"sap-inv-inputs",title:"Inventario: Inputs y Campos de Texto",content:`## Inputs y campos de texto 13695 13696step: escribo "{text}" en el input SAP "{element_name}" con identificador "{identifier}" 13697descripcion: Escribe texto en un input UI5 identificado por POM o selector directo. 13698 13699step: escribo "{text}" en el input SAP con label "{label}" 13700descripcion: Escribe texto en un input UI5 localizado por su label asociad
13700o. 13701 13702step: limpio el input SAP "{element_name}" con identificador "{identifier}" 13703descripcion: VacÃa un input UI5. 13704 13705step: verifico que el input SAP "{element_name}" con identificador "{identifier}" contiene "{value}" 13706descripcion: Verifica el valor actual de un input UI5. 13707 13708step: verifico que el input SAP "{element_name}" con identificador "{identifier}" está vacÃo 13709descripcion: Verifica que un input UI5 esté vacÃo. 13710 13711step: escribo "{text}" en el textarea SAP "{element_name}" con identificador "{identifier}" 13712descripcion: Escribe texto en un TextArea UI5. 13713 13714step: escribo "{text}" en el campo de búsqueda SAP 13715descripcion: Escribe en un SearchField UI5 (search box con lupa) y presiona Enter. 13716 13717step: verifico que el input SAP "{element_name}" con identificador "{identifier}" tiene estado "{state}" 13718descripcion: Verifica el valueState de un input UI5 (Error/Warning/Success/Information/None). 13719 13720step: verifico el mensaje de validación "{text}" del input SAP "{element_name}" 13721descripcion: Verifica el valueStateText (mensaje bajo el campo) de un input SAP. 13722 13723step: escribo letra por letra "{text}" en el input SAP "{element_name}" con identificador "{identifier}" 13724descripcion: Escribe texto carácter por carácter en un input SAP (dispara autocomplete/suggestions).`},{id:"sap-inv-controles",title:"Inventario: CheckBox, Radio y Switch",content:`## CheckBox / RadioButton / Switch 13725 13726step: marco el checkbox SAP "{element_name}" con identificador "{identifier}" 13727descripcion: Marca un CheckBox UI5 (si no está ya marcado). 13728 13729step: desmarco el checkbox SAP "{element_name}" con identificador "{identifier}" 13730descripcion: Desmarca un CheckBox UI5 (si está marcado). 13731 13732step: verifico que el checkbox SAP "{element_name}" con identificador "{identifier}" está marcado 13733descripcion: Verifica que un CheckBox UI5 esté marcado. 13734 13735step: verifico que el checkbox SAP "{element_name}" con identificador "{identifier}" está desmarcado 13736descripcion: Verifica que un CheckBox UI5 esté desmarcado. 13737 13738step: selecciono el radio button SAP "{label}" 13739descripcion: Selecciona un RadioButton UI5 por su label visible. 13740 13741step: verifico que el radio button SAP "{label}" está seleccionado 13742descripcion: Verifica que un RadioButton UI5 esté seleccionado. 13743 13744step: activo el switch SAP "{element_name}" con identificador "{identifier}" 13745descripcion: Enciende un Switch UI5 (si está apagado). 13746 13747step: desactivo el switch SAP "{element_name}" con identificador "{identifier}" 13748descripcion: Apaga un Switch UI5 (si está encendido). 13749 13750step: verifico que el switch SAP "{element_name}" con identificador "{identifier}" está activado 13751descripcion: Verifica que un Switch UI5 esté encendido.`},{id:"sap-inv-mensajes",title:"Inventario: Mensajes",content:`## Mensajes (Toast / MessageBox / MessageStrip / MessagePopover) 13752 13753step: verifico el mensaje toast SAP "{text}" 13754descripcion: Verifica que aparezca un MessageToast SAP con el texto dado. 13755 13756step: espero el mensaje toast SAP 13757descripcion: Espera a que aparezca cualquier MessageToast SAP. 13758 13759step: verifico el MessageBox SAP de tipo "{msg_type}" 13760descripcion: Verifica que aparezca un MessageBox SAP del tipo dado (Error/Warning/Success/Information/Confirm). 13761 13762step: confirmo el MessageBox SAP 13763descripcion: Presiona OK/Yes/Aceptar en un MessageBox SAP. 13764 13765step: cancelo el MessageBox SAP 13766descripcion: Presiona Cancel/No/Cancelar en un MessageBox SAP. 13767 13768step: verifico el MessageStrip SAP "{text}" 13769descripcion: Verifica un MessageStrip SAP (barra de mensaje inline) con el texto dado. 13770 13771step: abro el MessagePopover SAP 13772descripcion: Abre el MessagePopover SAP (indicador de mensajes de validación). 13773 13774step: verifico que hay {count:d} mensajes de error SAP 13775descripcion: Verifica la cantidad de mensajes de error en el MessagePopover SAP.`},{id:"sap-inv-tablas",title:"Inventario: Tablas",content:`## Tablas (sap.m.Table responsive + sap.ui.table grid) 13776 13777Todos los pasos de tabla prueban automáticamente ambos tipos de tabla SAP. Las columnas se localizan por su nombre de header (parcial, case-insensitive). 13778 13779step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" tiene {count:d} filas 13780descripcion: Verifica la cantidad de filas de una tabla SAP. 13781 13782step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" contiene el texto "{text}" 13783descripcion: Verifica que una tabla SAP contenga el texto en alguna celda. 13784 13785step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" no contiene el texto "{text}" 13786descripcion: Verifica que una tabla SAP NO contenga el texto en ninguna celda. 13787 13788step: hago click en la celda de columna "{col}" de la fila con texto "{row_text}" en la tabla SAP "{table_name}" con identificador "{identifier}" 13789descripcion: Hace click en una celda especÃfica (columna + fila) de una tabla SAP. 13790 13791step: obtengo el valor de la columna "{col}" de la fila con texto "{row_text}" de la tabla SAP "{table_name}" con identificador "{identifier}" en la variable "{var}" 13792descripcion: Extrae el valor de una celda (columna+fila) de una tabla SAP a una variable. 13793 13794step: marco el checkbox de la fila con texto "{row_text}" en la tabla SAP "{table_name}" con identificador "{identifier}" 13795descripcion: Marca el checkbox de selección de una fila en una tabla SAP multiselect. 13796 13797step: selecciono todas las filas de la tabla SAP "{table_name}" con identificador "{identifier}" 13798descripcion: Marca el checkbox de selección de todas las filas (header select-all). 13799 13800step: presiono la acción "{action}" de la fila con texto "{row_text}" en la tabla SAP "{table_name}" con identificador "{identifier}" 13801descripcion: Presiona un botón de acción inline dentro de una fila de tabla SAP. 13802 13803step: ordeno la tabla SAP "{table_name}" con identificador "{identifier}" por la columna "{col}" 13804descripcion: Ordena una tabla SAP haciendo click en el header de la columna. 13805 13806step: expando la fila con texto "{row_text}" de la tabla SAP "{table_name}" con identificador "{identifier}" 13807descripcion: Expande una fila expandible en una TreeTable SAP. 13808 13809step: verifico que la fila con texto "{row_text}" de la tabla SAP "{table_name}" con identificador "{identifier}" tiene la columna "{col}" con valor "{value}" 13810descripcion: Verifica el valor de una celda (columna+fila) de una tabla SAP. 13811 13812step: voy a la página {page_num:d} de la tabla SAP "{table_name}" con identificador "{identifier}" 13813descripcion: Navega a una página especÃfica en la paginación de una tabla SAP. 13814 13815step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" está vacÃa 13816descripcion: Verifica que una tabla SAP esté vacÃa (estado No data).`},{id:"sap-inv-select",title:"Inventario: Select, MultiComboBox y Value Help",content:`## Select / MultiComboBox / Value Help (F4) 13817 13818step: selecciono "{option}" del select SAP "{element_name}" con identificador "{identifier}" 13819descripcion: Selecciona una opción de un sap.m.Select UI5 (distinto del ComboBox editable). 13820 13821step: agrego "{option}" al MultiComboBox SAP "{element_name}" con identificador "{identifier}" 13822descripcion: Agrega una opción (token) a un MultiComboBox SAP. 13823 13824step: elimino el token "{value}" del MultiComboBox SAP "{element_name}" con identificador "{identifier}" 13825descripcion: Elimina un token seleccionado de un MultiComboBox/MultiInput SAP. 13826 13827step: verifico que el combobox SAP "{element_name}" con identificador "{identifier}" muestra "{value}" 13828descripcion: Verifica el valor mostrado por un combobox/select SAP. 13829 13830step: abro el value help del campo SAP "{element_name}" con identificador "{identifier}" 13831descripcion: Abre el Value Help (F4) de un campo SAP. 13832 13833step: selecciono "{value}" del value help SAP 13834descripcion: Selecciona un valor del diálogo de Value Help (F4) SAP.`},{id:"sap-inv-dialogos",title:"Inventario: Diálogos y Popovers",content:`## Diálogos y popovers 13835 13836step: verifico que el diálogo SAP "{title}" está visible 13837descripcion: Verifica que un diálogo SAP con el tÃtulo dado esté visible. 13838 13839step: cierro el diálogo SAP 13840descripcion: Cierra el diálogo SAP activo (botón X, Cancel o Close). 13841 13842step: presiono "{button}" en el diálogo SAP 13843descripcion: Presiona un botón del footer de un diálogo SAP por su texto. 13844 13845step: verifico que el popover SAP está visible 13846descripcion: Verifica que un Popover SAP esté visible. 13847 13848step: cierro el popover SAP 13849descripcion: Cierra un Popover SAP presionando Escape. 13850 13851step: verifico el contenido "{text}" del diálogo SAP 13852descripcion: Verifica que el diálogo SAP activo contenga el texto dado.`},{id:"sap-inv-fiori",title:"Inventario: Fiori Launchpad",content:`## Navegación Fiori Launchpad 13853 13854Estos pasos operan sobre el **shell** de Fiori (home, tiles, buscador, menú de usuario), no sobre la app embebida. 13855 13856step: abro el tile de Fiori "{tile}" 13857descripcion: Hace click en un tile del Fiori Launchpad por su tÃtulo. 13858 13859step: abro del grupo de Fiori "{group}" el tile "{tile}" 13860descripcion: Hace click en un tile dentro de un grupo especÃfico del launchpad. Nota el orden: primero el grupo, luego el tile. 13861 13862step: busco "{text}" en la búsqueda de Fiori 13863descripcion: Usa el buscador global del shell de Fiori. 13864 13865step: vuelvo al inicio de Fiori 13866descripcion: Hace click en el botón Home del shell de Fiori. 13867 13868step: abro el menú de usuario de Fiori 13869descripcion: Despliega el menú de acciones de usuario del shell de Fiori. 13870 13871step: cierro sesión en Fiori 13872descripcion: Cierra sesión desde el menú de usuario de Fiori (confirma el logout automáticamente). 13873 13874step: abro el panel de notificaciones de Fiori 13875descripcion: Abre el popover de notificaciones del shell de Fiori. 13876 13877step: navego atrás en Fiori 13878descripcion: Presiona el botón back del shell de Fiori (no del navegador). 13879 13880step: verifico que estoy en el launchpad de Fiori 13881descripcion: Verifica que el shell home del Fiori Launchpad esté visible.`},{id:"sap-inv-botones",title:"Inventario: Botones y Acciones",content:`## Botones y acciones (avanzado) 13882 13883step: presiono el botón SAP con icono "{icon}" 13884descripcion: Presiona un botón SAP identificado por su icono (nombre sap-icon:// o sufijo). 13885 13886step: presiono el botón SAP con tooltip "{tooltip}" 13887descripcion: Presiona un botón SAP por su atributo title/tooltip. 13888 13889step: presiono dentro del contenedor SAP "{container}" el botón "{button_text}" 13890descripcion: Presiona un botón SAP por texto, acotado a un contenedor/diálogo especÃfico (evita ambigüedad si hay varios botones iguales). 13891 13892step: presiono el botón de acción "{button_text}" del footer SAP 13893descripcion: Presiona un botón del footer bar SAP (Save, Cancel, etc.). 13894 13895step: abro el menú de acciones SAP "{button_text}" 13896descripcion: Abre un MenuButton SAP que despliega opciones. 13897 13898step: selecciono "{option}" del menú de acciones SAP 13899descripcion: Selecciona una opción de un menú SAP desplegado. 13900 13901step: presiono el botón de segmento SAP "{text}"
13902descripcion: Presiona un botón de un SegmentedButton SAP (toggle de vistas tipo Lista/Tarjetas). 13903 13904step: presiono el botón de overflow de la toolbar SAP 13905descripcion: Presiona el botón de overflow ('...') de una OverflowToolbar SAP.`},{id:"sap-inv-fechas",title:"Inventario: Fechas (DatePicker)",content:`## DatePicker / DateTimePicker / DateRange 13906 13907step: selecciono la fecha "{date}" en el DatePicker SAP "{element_name}" con identificador "{identifier}" 13908descripcion: Escribe una fecha en un DatePicker SAP. 13909 13910step: abro el calendario del DatePicker SAP "{element_name}" con identificador "{identifier}" 13911descripcion: Abre el popup de calendario de un DatePicker SAP. 13912 13913step: selecciono el dÃa {day:d} del calendario SAP 13914descripcion: Hace click en un dÃa visible del calendario SAP abierto. 13915 13916step: selecciono el rango "{from_date}" a "{to_date}" en el DateRange SAP "{element_name}" con identificador "{identifier}" 13917descripcion: Escribe un rango de fechas en un DateRangeSelection SAP. 13918 13919step: verifico que el DatePicker SAP "{element_name}" con identificador "{identifier}" tiene la fecha "{date}" 13920descripcion: Verifica la fecha actual de un DatePicker SAP.`},{id:"sap-inv-tabs-objectpage",title:"Inventario: Tabs, Wizard y ObjectPage",content:`## Tabs / IconTabBar / Wizard 13921 13922step: selecciono la pestaña SAP "{tab}" 13923descripcion: Selecciona una pestaña de un IconTabBar/TabContainer SAP. 13924 13925step: verifico que la pestaña SAP "{tab}" está activa 13926descripcion: Verifica que una pestaña SAP esté seleccionada/activa. 13927 13928step: avanzo al siguiente paso del wizard SAP 13929descripcion: Avanza al siguiente paso de un Wizard SAP. 13930 13931step: verifico que el paso "{step_name}" del wizard SAP está activo 13932descripcion: Verifica que un paso especÃfico del wizard SAP esté activo. 13933 13934## ObjectPage / Detalle (Fiori Elements) 13935 13936step: navego a la sección "{section}" del ObjectPage SAP 13937descripcion: Navega a una sección del ObjectPage SAP vÃa el anchor bar. 13938 13939step: verifico el header del ObjectPage SAP "{title}" 13940descripcion: Verifica el tÃtulo del header de un ObjectPage SAP. 13941 13942step: entro en modo edición del ObjectPage SAP 13943descripcion: Presiona el botón Edit de un ObjectPage SAP. 13944 13945step: verifico el ObjectStatus SAP "{text}" con estado "{state}" 13946descripcion: Verifica un ObjectStatus SAP con su texto y estado (Success/Error/Warning/None).`},{id:"sap-inv-utilidades",title:"Inventario: Utilidades y Genéricos",content:`## Utilidades / Avanzado 13947 13948step: hago scroll hasta el elemento SAP con texto "{text}" 13949descripcion: Hace scroll hasta un elemento SAP por su texto (útil con virtualización). 13950 13951step: verifico que existe el control SAP con id "{control_id}" 13952descripcion: Verifica que exista un control SAP por su id estable de UI5. 13953 13954step: capturo el valor del control SAP "{element_name}" con identificador "{identifier}" en la variable "{var}" 13955descripcion: Captura el valor de un control SAP (input o texto) en una variable. 13956 13957step: verifico que el control SAP "{element_name}" con identificador "{identifier}" está habilitado 13958descripcion: Verifica que un control SAP esté habilitado. 13959 13960step: verifico que el control SAP "{element_name}" con identificador "{identifier}" está deshabilitado 13961descripcion: Verifica que un control SAP esté deshabilitado. 13962 13963## Elementos genéricos SAP por POM (click, visibilidad, condicional) 13964 13965Cuando el flujo es 100% SAP y quieres el wait de OData integrado en cada acción, usa estos pasos por identificador POM en vez de los genéricos del framework. 13966 13967step: hago click en el elemento SAP "{element_name}" con identificador "{identifier}" 13968descripcion: Hace click en un control SAP por POM/selector, esperando a que SAP esté listo antes y después. 13969 13970step: verifico que el elemento SAP "{element_name}" con identificador "{identifier}" está visible 13971descripcion: Verifica que un control SAP identificado por POM/selector esté visible. 13972 13973step: si existe el elemento SAP "{element_name}" con identificador "{identifier}" hago click 13974descripcion: Hace click en un control SAP solo si existe y es visible (no falla si no está). Ãtil para tours, cookies y avisos intermitentes.`},{id:"sap-buenas-practicas",title:"Buenas Prácticas",content:'## Buenas prácticas para SAP\n\n1. **Localizadores por id de UI5**: cuando el POM capture el id estable de UI5 (`__component0---view--controlId`), úsalo â es el selector más confiable. Los pasos SAP lo aceptan vÃa POM.\n2. **Espera antes de aserciones**: intercala `espero a que SAP termine de cargar` después de acciones que disparan OData.\n3. **Iframes de Fiori**: el Launchpad clásico embebe apps en iframes. Los pasos de app respetan el iframe activo; los pasos del shell (`... de Fiori`) operan sobre el shell. Usa `cambio al iframe ...` si tu app está embebida.\n4. **Condicionales para tours/avisos**: usa `si existe el elemento SAP ... hago click` para diálogos intermitentes (tours de bienvenida, cookies).\n5. **Combina con pasos genéricos**: navegación (`voy a la url`), ventanas (`intento cambiar a la ventana ...`), evidencias (`* evidencia`) y aserciones de texto (`deberÃa ver el texto`) siguen siendo genéricos â úsalos junto a los pasos SAP.\n\n### Distinción clave: pasos SAP vs genéricos\n\n| Situación | Usa |\n|---|---|\n| Click en control UI5 con wait de OData | `hago click en el elemento SAP "X" con identificador "Y"` |\n| Click en elemento HTML normal | `hago click en el elemento "X" con identificador "Y"` (genérico) |\n| Escribir en input UI5 | `escribo "X" en el input SAP "Y" con identificador "Z"` |\n| Navegar a una URL | `voy a la url "..."` (genérico) |\n| Cambiar de ventana/pestaña | `intento cambiar a la ventana ...` (genérico) |\n\n### Referencia completa\n\nEl catálogo SAP se genera desde las definiciones reales del framework (`sap_steps.py`).
13974Cada paso admite el prefijo opcional `que` para encadenar en `And`/`Y`.'}]},{id:"haka-ui",title:"Haka UI",group:"Herramientas Haka",icon:"",topics:[{id:"hakaui-descripcion",title:"Descripción General",content:`## Haka UI â Interfaz Gráfica Local 13975 13976Haka UI es una interfaz web local integrada al framework que permite gestionar visualmente tu proyecto de pruebas. Incluye 7 módulos: Dashboard, Features, Page Objects, Runner, Reportes, Configuración e Integraciones. 13977 13978### CaracterÃsticas Principales 13979 13980- **Sin instalación adicional**: viene empaquetada con el framework 13981- **Comando único**: se lanza con \`haka-ui\` desde cualquier proyecto (alias: \`hakalab-ui\`) 13982- **Dark theme**: interfaz oscura profesional con acentos cyan 13983- **Sidebar colapsable**: reduce a iconos para maximizar espacio de trabajo 13984- **Logo personalizable**: coloca tu logo en \`public/logo.png\` 13985- **SPA routing**: navega directamente por URL (ej: \`localhost:8787/features\`) 13986- **API documentada**: Swagger disponible en \`/api/docs\` 13987 13988### Arquitectura 13989 13990- **Backend**: FastAPI (Python) â lee/escribe archivos del proyecto 13991- **Frontend**: Vite + React â interfaz SPA empaquetada en \`dist/\` 13992- **Puerto**: 8787 por defecto 13993- **Sin base de datos**: todo se lee/escribe directamente en los archivos del proyecto`},{id:"hakaui-instalacion",title:"Instalación y Uso",content:"## Requisitos\n\n- Haka Playwright Engine instalado (`pip install haka-playwright-engine`)\n- `fastapi` y `uvicorn` (incluidos automáticamente con el framework desde v1.4.28)\n\n## Lanzamiento\n\n```bash\n# Desde el directorio de tu proyecto (con venv activado si aplica)\nhaka-ui\n```\n\n> El comando `hakalab-ui` sigue funcionando como alias por compatibilidad, pero `haka-ui` es el nombre recomendado (homologado con `haka-init`, `haka-run`, `haka-agent`, etc.).\n\nEl servidor se levanta en `http://localhost:8787` y abre el navegador automáticamente.\n\n## Opciones de LÃnea de Comandos\n\n| Opción | Descripción | Default |\n|--------|-------------|---------|\n| `--port` | Puerto del servidor | 8787 |\n| `--path` o `-p` | Ruta al directorio del proyecto | Directorio actual |\n| `--no-browser` | No abrir el navegador automáticamente | false |\n\n```bash\n# Ejemplos\nhaka-ui --port 9000\nhaka-ui --path /ruta/a/mi/proyecto\nhaka-ui --no-browser\n```"},{id:"hakaui-dashboard",title:"Módulo: Dashboard",content:`## Dashboard 13994 13995Vista general del proyecto con métricas de la última ejecución. 13996 13997### Contenido 13998 13999- **Cards de resumen**: cantidad de Features, Scenarios y JSON POMs del proyecto 14000- **Ãltima ejecución**: fecha, duración, navegador usado 14001- **Gráficos donut**: porcentaje de éxito para Scenarios y Steps 14002- **Barras de progreso**: distribución passed/failed/skipped 14003 14004### Fuente de Datos 14005 14006Los gráficos se generan desde el último archivo JSON en \`reports/html-reports/\`. Si no hay reportes, solo se muestran las cards de conteo.`},{id:"hakaui-features",title:"Módulo: Features",content:`## Features 14007 14008Gestión completa de archivos \`.feature\` con vista visual por escenarios. 14009 14010### Vista General 14011 14012- Features agrupados por **carpeta** del filesystem 14013- Carpetas colapsables con conteo de features 14014- **Filtro** por nombre de feature o tag 14015- Crear carpetas, mover features entre carpetas 14016- **Tag de grupo**: seleccionar múltiples features y aplicar un tag a nivel Feature 14017 14018### Vista por Escenarios 14019 14020Al seleccionar un feature, se parsea y muestra cada escenario como una **card individual** con: 14021 14022- Tags del scenario (badges) 14023- Tipo: Scenario o Scenario Outline 14024- Pasos con syntax highlighting (Given/When/Then en colores) 14025- Tabla de Examples (para Outlines) 14026- Botón **"Editar con Builder"** por escenario 14027- Botón **"Editar todo (código)"** para edición libre del feature completo 14028 14029### Crear Feature 14030 14031- Nombre + Tags + Carpeta destino (si hay carpetas) 14032- Se crea el archivo en el filesystem del proyecto 14033 14034### Scenario Builder 14035 14036Modal split-panel (60% editor / 40% catálogo): 14037 14038**Panel izquierdo (editor):** 14039- TÃtulo y tags del scenario 14040- Toggle tipo: Scenario / Scenario Outline 14041- Lista de pasos con controles (â editar, ââ mover, â eliminar) 14042- Tabla de Examples: crear tabla, agregar/eliminar columnas y filas, editar headers y celdas 14043 14044**Panel derecho (catálogo):**
14045- **Buscador** que filtra en tiempo real todo el catálogo 14046- +700 pasos organizados por categorÃa (Web, API REST, Base de Datos, Gen AI, Performance, Sesiones) 14047- Badge **"usado en tus features"** para pasos ya utilizados en el proyecto 14048- Al agregar un paso con parámetros, se abre un formulario inline 14049 14050**Selector de localizadores (POM):** 14051- Para parámetros de tipo \`identifier\`, aparece un botón **"POM"** 14052- Abre un modal dedicado con: 14053 - Buscador de localizadores 14054 - Lista de JSON POMs expandibles con sus localizadores 14055 - Botón **"+ Nuevo"** para crear un localizador inline (seleccionar POM, nombre, selector) 14056 - Click en un localizador para usarlo: se inserta como \`$.NOMBRE.localizador\``},{id:"hakaui-poms",title:"Módulo: Page Objects",content:`## Page Objects (JSON POMs) 14057 14058Visualización y edición de los archivos de localizadores. 14059 14060### Vista de Lista 14061 14062- Cards compactas por cada archivo JSON POM 14063- Nombre del archivo + cantidad de localizadores 14064- Click para abrir el editor 14065 14066### Editor 14067 14068- Lista de localizadores (nombre â selector) 14069- Editor JSON para edición directa 14070- Crear nuevos POMs 14071- Los cambios se guardan directamente en el filesystem`},{id:"hakaui-runner",title:"Módulo: Ejecutar",content:`## Runner (Ejecutar) 14072 14073Ejecución visual de pruebas con selección de tags. 14074 14075### Selección de Tags 14076 14077- Tags agrupados por nivel: **Feature** (cyan) y **Scenario** (naranja) 14078- **Buscador** que filtra por nombre de tag, nombre de scenario O nombre de feature 14079- Checkbox para seleccionar múltiples tags 14080- Hover muestra qué scenarios ejecutará cada tag 14081- Contador total de scenarios a ejecutar 14082 14083### Configuración de Ejecución 14084 14085- Selector de **navegador**: Chrome, Firefox, WebKit 14086- **Headless**: checkbox para ejecutar sin ventana 14087- Botón **Ejecutar** 14088 14089### Flujo de Ejecución (Modal) 14090 14091- Botón "Flujo de Ejecución" muestra un modal con el orden exacto en que behave ejecutará 14092- Expande Scenario Outlines en sus iteraciones reales 14093- Lazy rendering para soportar 5000+ escenarios 14094 14095### Salida en Tiempo Real 14096 14097- Cards por escenario con estado (â passed / â failed) 14098- Pasos individuales con estado 14099- Mensaje de error para pasos fallidos 14100- Detección automática de **virtualenv** del proyecto (\`venv/\`, \`.venv/\`, \`env/\`) 14101- Usa \`venv/bin/python -m behave\` para ejecutar con las dependencias correctas`},{id:"hakaui-reportes",title:"Módulo: Reportes",content:`## Reportes 14102 14103Visor de reportes HTML y JSON de ejecuciones pasadas. 14104 14105### Lista de Reportes 14106 14107- Reportes agrupados por **ejecución** (timestamp) 14108- Badges de tipo: JSON / HTML 14109- Tamaño del archivo 14110- Ordenados por fecha descendente 14111 14112### Vista Resumen (JSON) 14113 14114- Info de ejecución: duración, navegador, ambiente, hora inicio 14115- **3 cards** con porcentaje de éxito: Features, Scenarios, Steps 14116- Detalle expandible: Feature â Scenario â Step 14117- Iconos de estado (â â â) 14118- Botón ð· en pasos con screenshot â abre modal con la imagen 14119- Mensaje de error para pasos fallidos 14120 14121### Vista HTML 14122 14123- Iframe con el reporte HTML completo renderizado 14124- Altura 70vh, ancho completo`},{id:"hakaui-config",title:"Módulo: Configuración",content:`## Configuración 14125 14126Editor visual del archivo \`.env\` del proyecto. 14127 14128### Secciones 14129 14130Las ~120 variables se organizan en secciones colapsables: 14131- Navegador y Pruebas Web 14132- Rutas y Directorios 14133- Funcionalidades (screenshots, video, cleanup) 14134- Gemini AI 14135- Validación Semántica 14136- Jira / Xray 14137- Cassini (Haka Lens) 14138- Salesforce 14139- Variables de Prueba 14140- Integración con Test Managers 14141 14142### CaracterÃsticas 14143 14144- **Booleans** se muestran como combobox (select true/false) 14145- **Strings** se muestran como campos editables 14146- **Tooltip con ?** en cada variable explicando su función 14147- Botón **Guardar** actualiza directamente el \`.env\` del proyecto 14148- Indicadores visuales: "Sin guardar" (naranja), "Guardado" (verde)`},{id:"hakaui-integraciones",title:"Módulo: Integraciones",content:`## Integraciones 14149 14150Editores visuales para configuraciones de integraciones externas. Organizado en pestañas. 14151 14152### Jira 14153 14154- Campos booleanos: adjuntar HTML, video, screenshots, comentar resultado, crear issue on failure, vincular bug con tags 14155- Campos de texto: tipo de issue, tipo de vÃnculo 14156- Mapeo de tags con campos personalizados por tipo de issue 14157
14158### Cassini (Haka Lens) 14159 14160- Variables \`CASSINI_*\` del \`.env\` con detección automática de tipo (bool/string) 14161- Tooltips explicativos por variable 14162 14163### CI/CD 14164 14165- Lista de workflows de GitHub Actions encontrados en \`.github/workflows/\` (solo lectura) 14166 14167### Reportes (report_config.json) 14168 14169- **Información del Reporte**: tÃtulo, ingeniero, producto, empresa, versión, ambiente 14170- **Logos**: preview de imagen + upload (conversión a base64 client-side) + campos alt y width. Permite cargar PNG/JPG/SVG/WebP hasta 500KB. 14171- **Estilos**: color pickers nativos + input hex para cada color del reporte HTML (primario, secundario, accent, éxito, warning)`},{id:"hakaui-api",title:"API Backend",content:"## Endpoints de la API\n\nEl backend expone endpoints RESTful bajo `/api/`. Documentación Swagger disponible en `http://localhost:8787/api/docs`.\n\n| Prefijo | Descripción |\n|---------|-------------|\n| `/api/dashboard/summary` | Resumen del proyecto + última ejecución |\n| `/api/config/` | Lectura y escritura del .env |\n| `/api/poms/` | CRUD de JSON POMs |\n| `/api/features/` | Listado, lectura, creación, edición, tags, carpetas, used-steps |\n| `/api/runner/tags` | Tags disponibles con scenarios asociados |\n| `/api/runner/start` | Iniciar ejecución de behave |\n| `/api/runner/status/{id}` | Estado y output de ejecución en curso |\n| `/api/reports/` | Listado y lectura de reportes (JSON, HTML, screenshots) |\n| `/api/integrations/` | Lectura y escritura de configs de integraciones |\n| `/api/steps-catalog/` | Catálogo de pasos parseado desde documentación |\n\n### Notas Técnicas\n\n- El frontend se empaqueta pre-buildeado en `dist/`. No requiere Node.js en producción.\n- El catálogo de pasos se parsea en runtime desde `hakalab_framework/documentacion/INVENTARIO_PASOS_*.md`, siempre sincronizado con la versión instalada.\n- La ejecución usa el virtualenv detectado en el proyecto para ejecutar behave.\n- Las imágenes de logos se convierten a base64 client-side sin upload de archivos al servidor."}]},{id:"haka-cli",title:"CLI (Comandos)",group:"Empezar",icon:"",topics:[{id:"cli-resumen",title:"Resumen de Comandos",content:"## Los 12 comandos del framework\n\nAl instalar `haka-playwright-engine` se registran 12 comandos en tu entorno:\n\n| Comando | Para que sirve |\n|---|---|\n| `haka-init` | Crear la estructura de un proyecto nuevo |\n| `haka-run` | Ejecutar las pruebas |\n| `haka-report` | Regenerar o servir el reporte HTML |\n| `haka-steps` | Buscar en el catalogo de +1800 steps |\n| `haka-validate` | Validar estructura del proyecto y .env |\n| `haka-login` | Guardar sesiones de login (bypass 2FA/MFA) |\n| `haka-deps` | Instalar dependencias opcionales (OCR, etc.) |\n| `haka-agent` | Explorar una app con IA y generar POMs/features |\n| `haka-connector` | Servidor para grabar desde la extension de Chrome |\n| `haka-vault` | Boveda cifrada de datos de prueba (credenciales, tokens) |\n| `haka-ui` | Interfaz grafica local del proyecto |\n| `haka-mcp` | Servidor MCP para asistentes de IA |"},{id:"cli-haka-init",title:"haka-init",content:`## haka-init 14172 14173Crea la estructura de un proyecto de pruebas nuevo (o completa una existente). 14174 14175\`\`\`bash 14176haka-init # solo web, en el directorio actual 14177haka-init mi-suite # en un subdirectorio nuevo 14178haka-init --jira # web + configuracion de Jira 14179haka-init --jira --xray # web + Jira + Xray 14180haka-init --mobile # web + ejemplos de Mobile (Appium) 14181haka-init --api # web + ejemplos de API REST 14182\`\`\` 14183 14184### Opciones 14185 14186| Opcion | Descripcion | 14187|---|---| 14188| \`project_name\` | Subdirectorio destino. Por defecto el directorio actual | 14189| \`--template\` | Plantilla: basic (default) o advanced | 14190| \`--force\` | Sobrescribe archivos existentes | 14191| \`--jira\` | Agrega configuracion de Jira | 14192| \`--xray\` | Agrega configuracion de Xray (implica --jira) | 14193| \`--mobile\` | Agrega ejemplos y estructura para Mobile (Appium) | 14194| \`--api\` | Agrega ejemplos de pruebas API REST | 14195 14196Los modulos (--jira, --xray, --mobile, --api) se pueden correr despues sobre un proyecto ya existente para agregar lo que falta, sin tocar lo que ya esta.`},{id:"cli-haka-run",title:"haka-run",content:`## haka-run 14197 14198Ejecuta las pruebas del proyecto con Behave. 14199 14200\`\`\`bash 14201haka-run # todo features/ 14202haka-run --tags @smoke # solo un tag 14203haka-run --feature login # un feature puntual 14204haka-run --parallel --workers 8 # en paralelo 14205haka-run --browser firefox --headless 14206\`\`\` 14207 14208### Opciones 14209 14210| Opcion | Descripcion | 14211|---|---| 14212| \`--tags\` | Tag para filtrar | 14213| \`--feature\` | Nombre de un archivo .feature puntual | 14214| \`--parallel\` | Ejecuta con multiples workers | 14215| \`--workers\` | Cantidad de workers en paralelo (default: 4) | 14216| \`--list-features\` | Lista los .feature disponibles y termina | 14217| \`--browser\` | Sobrescribe BROWSER del .env | 14218| \`--headless\` | Fuerza modo headless | 14219| \`--docker\` | Preset para CI/Docker | 14220 14221### Reintentos 14222 14223Si \`RETRY_FAILED_SCENARIOS=true\` en el .env, reintenta automaticamente los escenarios fallidos hasta \`MAX_SCENARIO_RETRIES\` veces (default 1).`},{id:"cli-haka-steps",title:"haka-steps",content:`## haka-steps 14224 14225Explora el catalogo completo de steps del framework (mas de 1800 pasos disponibles). 14226 14227\`\`\`bash 14228haka-steps # resumen por categoria 14229haka-steps --search "doble click" # busqueda exacta (substring) 14230haka-steps --search "click" --category Web 14231haka-steps --suggest "clic doble" # busqueda flexible, tolera errores 14232haka-steps --category Salesforce # todos los steps de una categoria 14233haka-steps --generate-docs # genera steps_documentation.md 14234\`\`\` 14235 14236### Opciones 14237 14238| Opcion | Descripcion | 14239|---|---| 14240| \`--search\` | Busca por substring en el texto o la descripcion del step | 14241| \`--category\` | Filtra por categoria (Web, Validaciones, API REST, Mobile, Desktop, Base de Datos, Salesforce, Gen AI, Performance, Geolocalizacion, Condicionales, Sesiones) | 14242| \`--suggest\` | Sugiere steps por similitud (fuzzy match), tolera errores de tipeo |
14243| \`--generate-docs\` | Genera steps_documentation.md con el catalogo completo | 14244| \`--list-categories\` | Fuerza el resumen por categoria | 14245 14246Sin flags, muestra cuantos steps hay por categoria. Si --search no encuentra nada, sugiere probar con --suggest.`},{id:"cli-haka-validate",title:"haka-validate",content:`## haka-validate 14247 14248Valida la estructura del proyecto (features/, json_poms/, behave.ini) y las variables del .env contra el esquema del framework. 14249 14250\`\`\`bash 14251haka-validate # valida el proyecto actual 14252haka-validate --env-file .env.staging # valida un .env especifico 14253haka-validate --full # documentacion completa de TODAS las variables 14254haka-validate --generate-env # genera .env.example con todas las variables 14255\`\`\` 14256 14257### Opciones 14258 14259| Opcion | Descripcion | 14260|---|---| 14261| \`--env-file\` | Archivo .env especifico a validar | 14262| \`--full\` | Muestra la documentacion completa de cada variable | 14263| \`--generate-env\` | Genera .env.example con todas las variables |`},{id:"cli-haka-login",title:"haka-login",content:'## haka-login\n\nGestiona sesiones de login guardadas, para saltarse 2FA/MFA en las ejecuciones automatizadas.\n\n```bash\nhaka-login --save admin_prod --url https://login.salesforce.com\nhaka-login --save whatsapp --url https://web.whatsapp.com --persistent\nhaka-login --list\nhaka-login --info admin_prod\nhaka-login --delete admin_prod\nhaka-login --gen-key\nhaka-login --encrypt admin_prod\n```\n\n### Opciones\n\n| Opcion | Descripcion |\n|---|---|\n| `--save` | Nombre para guardar la sesion (requiere --url) |\n| `--url` | URL de login |\n| `--browser` | Navegador: chromium (default), firefox, webkit |\n| `--timeout` | Minutos para completar el login manual (default: 5) |\n| `--persistent` | Guarda el perfil completo del navegador (WhatsApp, Signal, Telegram) |\n| `--list` | Lista las sesiones guardadas |\n| `--info` | Muestra el detalle de una sesion |\n| `--delete` | Elimina una sesion guardada |\n| `--gen-key` | Genera la clave de encriptacion de sesiones |\n| `--encrypt` / `--encrypt-all` | Encripta sesiones |\n| `--decrypt` | Desencripta una sesion |\n\nUna vez guardada, se usa en los .feature con: `Given inicio sesion guardada con el usuario "admin_prod"`'},{id:"cli-haka-deps",title:"haka-deps",content:`## haka-deps 14264 14265Gestiona dependencias opcionales del framework (OCR, extraccion avanzada de datos, performance). 14266 14267\`\`\`bash 14268haka-deps --status # ver que esta instalado 14269haka-deps --check ocr # verificar dependencias de un grupo 14270haka-deps --install ocr # instalar un grupo 14271haka-deps --install all # instalar todos los grupos opcionales 14272\`\`\` 14273 14274### Opciones 14275 14276| Opcion | Descripcion | 14277|---|---| 14278| \`--status\` | Muestra el estado de todas las dependencias opcionales | 14279| \`--check\` | Verifica que falta de un grupo especifico | 14280| \`--install\` | Instala un grupo (ocr, advanced_data, performance, o all) |`},{id:"cli-haka-report",title:"haka-report",content:`## haka-report 14281 14282Regenera o sirve el reporte de la ultima ejecucion. 14283 14284> El reporte HTML principal se genera automaticamente al terminar cada ejecucion de haka-run, con screenshots embebidos y branding personalizable. Este comando es complementario para regenerar o servir un reporte existente. 14285 14286\`\`\`bash 14287haka-report # genera el reporte y abre el navegador 14288haka-report --no-browser # genera sin abrir el navegador 14289haka-report --simple # genera un reporte HTML simple 14290haka-report --serve --port 9000 # sirve el reporte ya generado 14291haka-report --clean # limpia reportes anteriores 14292\`\`\` 14293 14294### Opciones 14295 14296| Opcion | Descripcion | 14297|---|---| 14298| \`--serve\` | Sirve el reporte con un servidor integrado | 14299| \`--port\` | Puerto del servidor (default: 8080) | 14300| \`--simple\` | Genera un reporte HTML simple | 14301| \`--clean\` | Limpia reportes y resultados anteriores | 14302| \`--no-browser\` | No abre el navegador automaticamente |`},{id:"cli-haka-vault",title:"haka-vault",content:`## haka-vault 14303 14304Boveda cifrada de datos de prueba. Almacena credenciales, tokens, RUTs y cualquier dato sensible de forma segura en el repositorio. 14305 14306El archivo \`.haka_vault\` se cifra con AES-256 y va al repo sin riesgo. Sin la clave, es ilegible. La clave vive en \`.haka_session_key\` (fuera del repo) o en la variable de entorno \`HAKA_SESSION_KEY\` (para CI/CD). 14307 14308\`\`\`bash 14309# Inicializar el vault en el proyecto 14310haka-vault init 14311 14312# Agregar un dato (formato: seccion.clave valor) 14313haka-vault set login_admin.usuario [email protected] 14314haka-vault set login_admin.password MiClave123 14315 14316# Obtener un dato 14317haka-vault get login_admin.usuario 14318 14319# Ver secciones y sus claves 14320haka-vault list 14321 14322# Exportar el vault descifrado (solo debug) 14323haka-vault export 14324 14325# Eliminar un dato o seccion 14326haka-vault delete login_admin.password 14327haka-vault delete-section login_admin 14328\`\`\` 14329 14330### Uso en features 14331 14332\`\`\`gherkin 14333Scenario: Login con datos del vault 14334 Given cargo credenciales del vault "login_admin" 14335 And voy a la url "\${url}" 14336 When relleno el campo "Email" con "\${usuario}" con identificador "$.LOGIN.input_email" 14337 And relleno el campo "Password" con "\${password}" con identificador "$.LOGIN.input_password" 14338 Then deberÃa ver el elemento "Dashboard" con identificador "$.DASHBOARD.contenedor" 14339\`\`\` 14340 14341Tambien puedes cargar un campo especifico: 14342 14343\`\`\`gherkin 14344Given cargo el campo "usuario" del vault "login_admin" en la variable "mi_user" 14345\`\`\` 14346 14347### CI/CD 14348 14349En pipelines, la clave se pasa como un unico secret: 14350 14351\`\`\`yaml 14352# GitHub Actions 14353env: 14354 HAKA_SESSION_KEY: \${{ secrets.HAKA_SESSION_KEY }} 14355 14356# GitLab CI 14357variables: 14358 HAKA_SESSION_KEY: $HAKA_VAULT_KEY 14359\`\`\` 14360 14361### Opciones 14362 14363| Opcion | Descripcion | 14364|---|---| 14365| \`init\` | Inicializa el vault (genera clave + archivo cifrado) | 14366| \`set <seccion.clave> <valor>\` | Agrega o actualiza un dato | 14367| \`get <seccion.clave>\` | Obtiene un dato (muestra en terminal) | 14368| \`list\` | Lista todas las secciones y sus claves | 14369| \`delete <seccion.clave>\` | Elimina una clave | 14370| \`delete-section <seccion>\` | Elimina una seccion completa | 14371| \`export\` | Muestra el vault descifrado en JSON (solo debug) | 14372 14373### Seguridad 14374 14375- Cifrado AES-256-GCM en reposo 14376- La clave nunca va al repositorio (\`.haka_session_key\` esta en \`.gitignore\`) 14377- Cumple principios de la Ley 21.719: minimizacion, cifrado, accountability 14378- Compatible con \`:::ocultar\` para triple proteccion (repo + reporte + screenshot)`}]},{id:"haka-mcp",title:"Haka MCP",group:"Herramientas Haka",icon:"",topics:[{id:"mcp-descripcion",title:"Descripcion General",content:`## Haka MCP - El proyecto dentro de tu asistente de IA 14379 14380Haka MCP es un servidor Model Context Protocol (MCP) que expone un proyecto Haka Playwright Engine (features, catalogo de steps, POMs, reportes) a cualquier asistente de IA compatible: Kiro, Claude Desktop, Cursor, Windsurf, etc. 14381 14382En vez de describir manualmente que steps existen, copiar y pegar el contenido de un reporte, o salir del chat a correr \`haka-steps --search\`, el asistente puede invocar estas herramientas directamente durante la conversacion. 14383 14384### Requisitos 14385 14386- Haka Playwright Engine instalado (Python 3.10 o superior) 14387- El servidor MCP se instala automaticamente con el framework 14388 14389\`\`\`bash 14390pip install haka-playwright-engine 14391python -m playwright install chromium 14392\`\`\``},{id:"mcp-configuracion",title:"Configuracion",content:`## Configuracion del servidor MCP 14393 14394Registra el servidor en el mcp.json de tu asistente: 14395 14396\`\`\`json 14397{ 14398 "mcpServers": { 14399 "haka-engine": { 14400 "command": "/ruta/a/tu-proyecto/venv/bin/haka-mcp", 14401 "cwd": "/ruta/a/tu-proyecto" 14402 } 14403 } 14404} 14405\`\`\` 14406 14407>
14407 Usa la ruta absoluta al binario haka-mcp dentro del venv del proyecto. "command": "haka-mcp" sin ruta puede fallar porque el cliente MCP no hereda el PATH de tu terminal. 14408 14409### Verificacion manual 14410 14411\`\`\`bash 14412cd /ruta/a/tu-proyecto 14413haka-mcp 14414# Queda esperando en stdio. Ctrl+C para cerrar. 14415\`\`\``},{id:"mcp-tools-lectura",title:"Tools de Lectura",content:`## Tools de lectura del proyecto 14416 14417### Catalogo de steps 14418 14419**search_steps(query, category, limit)** 14420 14421Busca en el catalogo de +1800 steps por texto en el patron o la descripcion. Devuelve el patron, descripcion, parametros y keyword sugerido (Given/When/Then). 14422 14423**list_step_categories()** 14424 14425Lista las categorias disponibles (Web, API REST, Salesforce, Gen AI, Mobile, etc.). 14426 14427### Features 14428 14429**list_features()** 14430 14431Lista los archivos .feature del proyecto con su nombre, tags y cantidad de escenarios. 14432 14433**get_feature(path)** 14434 14435Lee un .feature puntual con contenido crudo y estructura parseada (tags, escenarios, steps, Examples). 14436 14437### Page Objects (POMs) 14438 14439**list_poms()** 14440 14441Lista los JSON POM del proyecto con sus localizadores. 14442 14443**get_pom(filename)** 14444 14445Lee un JSON POM puntual por nombre de archivo. 14446 14447### Reportes 14448 14449**list_reports()** 14450 14451Lista los archivos de reporte (JSON y HTML) disponibles, mas recientes primero. 14452 14453**get_last_report()** 14454 14455Devuelve el resumen del ultimo reporte: info de ejecucion, pass/fail/skipped, y detalle por feature, escenario y step con mensajes de error. 14456 14457### Validacion 14458 14459**validate_project()** 14460 14461Valida la estructura del proyecto (carpetas features/, json_poms/, behave.ini) y las variables del .env. 14462 14463### Ejecucion 14464 14465**run_tests(tags)** 14466 14467Ejecuta las pruebas con Behave, opcionalmente filtradas por tag (ej: "@smoke"). Requiere licencia configurada en el .env.`},{id:"mcp-browser-experimental",title:"Navegacion (Experimental)",content:`## Navegacion con estado - EXPERIMENTAL 14468 14469Un segundo grupo de tools que comparten un navegador vivo entre llamadas: abrir, navegar, ver la pagina, actuar sobre un elemento y cerrar. 14470 14471> Estas tools son experimentales. Los escenarios que se lleguen a escribir quedan marcados con @borrador y requieren revision humana antes de integrarse a la suite. 14472 14473### Tools de navegacion 14474 14475| Tool | Descripcion | 14476|---|---| 14477| \`browser_open(headless)\` | Abre el navegador y empieza la sesion | 14478| \`browser_navigate(url)\` | Navega a una URL | 14479| \`browser_snapshot(limit)\` | Captura los elementos interactivos con selectores verificados | 14480| \`browser_click(key)\` | Hace click en un elemento y observa el efecto | 14481| \`browser_fill(key, value)\` | Rellena un campo | 14482| \`browser_select_option(key, value, label)\` | Selecciona una opcion de un select | 14483| \`browser_check(key, checked)\` | Marca o desmarca un checkbox | 14484| \`browser_save_selectors(keys)\` | Persiste los selectores verificados al JSON POM | 14485| \`browser_draft_scenario(intent)\` | Escribe las acciones como escenario .feature @borrador | 14486| \`browser_close()\` | Cierra la sesion | 14487 14488### Ejemplo de flujo 14489 14490\`\`\` 14491browser_open(headless=True) 14492browser_navigate("https://miapp.test/contacto") 14493browser_snapshot() 14494browser_fill("input_nombre", "Ana") 14495browser_snapshot() 14496browser_fill("input_email", "[email protected]") 14497browser_snapshot() 14498browser_click("btn_enviar") 14499browser_save_selectors() 14500browser_draft_scenario("Enviar el formulario de contacto") 14501browser_close() 14502\`\`\` 14503 14504El .feature queda en features/generated/ con tag @borrador, y los selectores en json_poms/.`}]},{id:"privacidad-oculto",title:"Privacidad (:::oculto)",group:"Fundamentos",icon:"",topics:[{id:"priv-concepto",title:"Concepto",content:`## Privacidad en Screenshots y Reportes 14505 14506Los screenshots y el texto de los pasos en reportes HTML pueden contener datos personales visibles: RUTs, correos, tarjetas. Si el reporte se comparte, esos datos quedan expuestos. 14507 14508**Solucion:** Agregar \`:::oculto\` al final de cualquier localizador en el JSON POM. El framework aplica doble redactado: 14509 14510- **En screenshots**: pinta un rectangulo negro sobre el elemento antes de guardar el PNG. 14511- **En el texto del reporte**: reemplaza el valor por \`***\` en la linea del paso. 14512 14513**El dato nunca llega al disco ni al reporte.** El test sigue funcionando normalmente.`},{id:"priv-uso",title:"Uso",content:`## Como usar :::oculto 14514 14515En tu JSON POM, agrega \`:::oculto\` o \`:::ocultar\` al selector del campo sensible: 14516 14517\`\`\`json 14518{ 14519 "input_rut": "#rut-field:::oculto", 14520 "input_correo": "role=textbox[name='Correo']:::oculto", 14521 "input_tarjeta": "[data-testid='card-number']:::oculto", 14522 "btn_enviar": "#submit" 14523} 14524\`\`\` 14525 14526No hay variables de entorno que configurar ni codigo que tocar. Se aceptan ambas variantes. 14527 14528### Que pasa internamente 14529 145301. \`element_locator\` detecta \`:::oculto\` al final del selector 145312. Recorta el sufijo para Playwright (\`#rut-field\`) 145323. Registra el selector en la lista de elementos a redactar 145334. Al tomar screenshot: obtiene \`bounding_box()\` de cada selector registrado 145345. Dibuja rectangulos negros con Pillow sobre esas areas 145356. El PNG guardado en disco ya NO contiene el dato visible 145367. En el reporte: \`relleno el campo "RUT" con "19595225-6"\` se muestra como \`relleno el campo "RUT" con "***"\` 14537 14538### Requisitos 14539 14540- Pillow (incluido en extras \`[ocr]\` y \`[full]\`). Si no esta instalado, avisa una vez y guarda sin redactar. 14541- Funciona con CSS, XPath, role y text; con fallbacks; con screenshots de fallo, por step y manuales.`},{id:"priv-combinaciones",title:"Combinacion con Vault",content:`## Triple Proteccion 14542 14543Combinando \`:::oculto\` con el Haka Vault y Scenario Outline: 14544 14545| Capa | Protege | Mecanismo | 14546|------|---------|-----------| 14547| Haka Vault | El repositorio | Datos cifrados con AES-256, nunca en texto plano | 14548| \`:::oculto\` | El reporte HTML | Rectangulo negro sobre screenshots + texto \`***\` en pasos | 14549| Scenario Outline | El .feature | Datos en la tabla, no en los steps, facil de ofuscar | 14550 14551### Ejemplo completo 14552 14553\`\`\`gherkin 14554Feature: Login seguro 14555 14556 Scenario: Ingresar con credenciales del vault 14557 Given cargo credenciales del vault "login_prod" 14558 And voy a la url "\${url}" 14559 When relleno el campo "RUT" con "\${rut}" con identificador "$.LOGIN.input_rut" 14560 And relleno el campo "Password" con "\${password}" con identificador "$.LOGIN.input_pass" 14561 And hago click en el elemento "Ingresar" con identificador "$.LOGIN.btn_login" 14562 Then deberÃa ver el elemento "Dashboard" con identificador "$.DASHBOARD.contenedor" 14563\`\`\` 14564 14565Con el POM: 14566\`\`\`json 14567{ 14568 "input_rut": "#rut:::oculto", 14569 "input_pass": "#password:::oculto", 14570 "btn_login": "#btn-login" 14571} 14572\`\`\` 14573 14574Resultado: el RUT y password no aparecen ni en el repo (vault), ni en el screenshot (:::oculto), ni en el reporte (texto enmascarado).`}]},{id:"haka-connector",title:"Haka Connector",group:"Herramientas Haka",icon:"",topics:[{id:"connector-concepto",title:"Concepto",content:`## Haka Connector â Grabar desde el Navegador 14575 14576Extension de Chrome MV3 + servidor local que graba la interaccion del QA en **su propio navegador con su sesion activa** y genera el \`.feature\` + POM automaticamente. 14577 14578A diferencia de Haka Agent (que explora solo), el Connector graba lo que hace la persona. No necesitas repetir el login ni abrir un navegador limpio â se graba a mitad de un flujo largo. 14579 14580### Arquitectura 14581 14582- **Extension Chrome**: captura clicks, inputs, selects, checks. Verifica unicidad de selectores en el DOM real. 14583- **Servidor Python** (\`haka-connector\`): traduce acciones a steps Gherkin, genera POM con \`ElementIndex\`, acumula escenarios con \`ArtifactGenerator\`. 14584- **Compatibilidad**: se negocia por numero de protocolo entre extension y servidor.`},{id:"connector-instalacion",title:"Instalacion y Uso",content:`## Instalacion 14585 14586\`\`\`bash 14587pip install 'haka-playwright-engine[connector]' 14588\`\`\` 14589 14590Esto instala FastAPI + uvicorn para el servidor. La extension de Chrome se descarga por separado. 14591 14592## Uso 14593 14594\`\`\`bash 14595# 1. Iniciar el servidor 14596haka-connector 14597 14598# 2. Abrir Chrome y activar la extension (panel lateral derecho) 14599# 3. Navegar normalmente e interactuar con la app 14600# 4. La extension captura cada accion con selector verificado 14601# 5. Al terminar, el servidor genera el .feature + POM 14602\`\`\` 14603 14604### Que genera 14605 14606- \`features/generated/grabacion_TIMESTAMP.feature\` â Escenario Gherkin con steps reales 14607- \`json_poms/PAGINA.json\` â Selectores verificados contra el DOM 14608 14609### Soporte de iframes 14610 14611El content script corre en todos los frames. El traductor inserta \`cambio al iframe por src que contiene\` y \`regreso al frame padre\` donde hagan falta. 14612 14613### Verificacion 14614 14615Los features generados se ejecutan con \`haka-run\`: 0 undefined (porque los steps existen en el catalogo) y 0 failed (porque los selectores son reales).`}]},{id:"web-moderna",title:"Web Moderna (SPA)",group:"Tipos de Prueba",icon:"",topics:[{id:"wm-descripcion",title:"Descripcion",content:`## Steps para Componentes Web Modernos 14616 1461759 steps para elementos que las apps SPA (React, Angular, Vue, Material UI, Ant Design, Vuetify) usan masivamente y que NO son HTML nativo. 14618 14619Modulo: \`modern_web_steps.py\` 14620 14621Todos los steps respetan el iframe activo y usan la cascada de fallbacks del POM.`},{id:"wm-dropdowns",title:"Dropdowns y Autocomplete",content:'## Dropdowns personalizados\n\nPara dropdowns de Material UI, React Select, PrimeNG, etc. que NO son `<select>`:\n\n| Step | Descripcion |\n|---|---|\n| `las opciones del dropdown "{nombre}" deberian ser "{opciones}" con identificador "{id}"` | Verifica opciones exactas (separadas por coma) |\n| `las opciones del dropdown "{nombre}" deberian contener "{opciones}" con identificador "{id}"` | Verifica que contenga al menos las indicadas |\n| `las sugerencias del autocompletable "{nombre}" deberian contener "{esperadas}" con identificador "{id}"` | Verifica sugerencias visibles |\n\n```gherkin\nWhen relleno el campo "Ciudad" con "San" con identificador "$.FORM.ciudad"\nThen las sugerencias del autocompletable "Ciudad" deberian contener "Santiago,San Fernando" con identificador "$.FORM.ciudad"\n```'},{id:"wm-componentes",title:"Componentes UI",content:'## Multi-select, Chips, Sliders, Tabs, Acordeones\n\n| Step | Descripcion |\n|---|---|\n| `agrego la opcion "{opcion}" al multiselect "{nombre}" con identificador "{id}
14621"` | Selecciona opcion en multi-select |\n| `remuevo la opcion "{opcion}" del multiselect "{nombre}" con identificador "{id}"` | Quita chip/tag |\n| `las opciones seleccionadas del multiselect "{nombre}" deberian ser "{esperadas}"` | Verifica chips |\n| `muevo el slider "{nombre}" al valor "{valor}" con identificador "{id}"` | Ajusta slider |\n| `el valor del slider "{nombre}" deberia ser "{valor}"` | Verifica slider |\n| `selecciono la pestana "{nombre}" con identificador "{id}"` | Activa tab |\n| `la pestana activa deberia ser "{nombre}"` | Verifica tab activo |\n| `expando el acordeon "{nombre}" con identificador "{id}"` | Abre acordeon (idempotente) |\n| `el acordeon "{nombre}" deberia estar expandido` | Verifica estado |\n| `activo el toggle "{nombre}" con identificador "{id}"` | Enciende toggle switch |\n| `desactivo el toggle "{nombre}" con identificador "{id}"` | Apaga toggle switch |'},{id:"wm-notificaciones",title:"Notificaciones y Progreso",content:'## Toasts, Badges, Barras de Progreso\n\n| Step | Descripcion |\n|---|---|\n| `deberia aparecer un toast con el mensaje "{texto}"` | Verifica toast/notification |\n| `el toast deberia desaparecer en {N}
14621 segundos` | Espera desaparicion |\n| `no deberia haber toasts visibles` | Verifica ausencia |\n| `el badge "{nombre}" deberia mostrar "{valor}"` | Verifica contador de badge |\n| `espero a que la barra de progreso llegue al 100%` | Espera progress bar |\n\n## Datepicker, Color Picker, Rich Text\n\n| Step | Descripcion |\n|---|---|\n| `selecciono la fecha "{dd-mm-yyyy}" en el datepicker "{nombre}" con identificador "{id}"` | Para datepickers no nativos |\n| `selecciono el color "{#hex}" en el color picker "{nombre}"` | Seleccion de color |\n| `escribo "{texto}" en el editor de texto enriquecido "{nombre}" con identificador "{id}"` | Quill, TinyMCE, CKEditor, ProseMirror |\n| `el contenido del editor "{nombre}" deberia contener "{texto}"` | Verifica contenido |\n\n## Otros\n\n| Step | Descripcion |\n|---|---|\n| `la cantidad de elementos visibles "{nombre}" deberia ser {N}` | Conteo exacto |\n| `deberia haber al menos {N} elementos visibles "{nombre}"` | Conteo minimo |\n| `copio al portapapeles el contenido del elemento "{nombre}"` | Clipboard |\n| `el portapapeles deberia contener "{texto}"` | Verifica clipboard |\n| `hago scroll infinito hasta que haya {N} elementos "{nombre}"` | Infinite scroll |\n| `los elementos "{nombre}" deberian estar en el orden "{a,b,c}"` | Verifica secuencia |\n| `el breadcrumb deberia mostrar la ruta "{Home > Seccion > Pagina}"` | Verifica breadcrumbs |\n| `el campo "{nombre}" deberia mostrar el error "{mensaje}"` | Validacion inline |'}]},{id:"api-avanzada",title:"API Avanzada",group:"Tipos de Prueba",icon:"",topics:[{id:"api-adv-descripcion",title:"Descripción",content:"## Steps Avanzados de API\n\n27 steps (54 patrones contando el al
14621ias con `que` inicial) inspirados en Karate/Judo Framework. Cubren GraphQL, retry/polling, OAuth2, match parcial, JSON Schema, WebSocket, SOAP/XML, idempotencia, paginación, latencia (p95), cookies y comparación de versiones.\n\nMódulo: `api_advanced_steps.py`"},{id:"api-adv-graphql",title:"GraphQL",content:'## GraphQL\n\n| Step | Descripción |\n|---|---|\n| `envÃo query GraphQL a "{url}" con query "{query}" y guardo la respuesta en la variable "{variable}"` | Ejecuta una query GraphQL |\n| `envÃo mutation GraphQL a "{url}" con mutation "{mutation}" y guardo la respuesta en la variable "{variable}"` | Ejecuta una mutation GraphQL |\n| `configuro variables GraphQL "{variables_json}"` | Establece variables para la próxima query/mutation |\n| `la respuesta GraphQL no deberÃa tener errores` | Verifica que el campo `errors` esté vacÃo |\n| `el campo GraphQL "{path}" deberÃa ser "{expected}"` | Valida un campo de la respuesta |\n\n```gherkin\nGiven configuro variables GraphQL \'{"userId": 1}\'\nWhen envÃo query GraphQL a "/graphql" con query "query($userId: Int!) { user(id: $userId) { name } }" y guardo la respuesta en la variable "user"\nThen la respuesta GraphQL no deberÃa tener errores\nAnd el campo GraphQL "data.user.name" deberÃa ser "Felipe"\n```'},{id:"api-adv-retry",title:"Retry, OAuth2, Encadenamiento",content:`## Retry Until (polling asÃncrono) 14622 14623| Step | Descripción | 14624|---|---| 14625| \`reintento GET a "{url}" hasta que el campo "{field}" sea "{expected}" con máximo {max_retries} intentos cada {interval} segundos\` | Polling de estado por GET | 14626| \`reintento POST a "{url}" con body "{body}" hasta que el status sea {expected_status} con máximo {max_retries} intentos cada {interval} segundos\` | Polling con POST | 14627 14628## OAuth2 (client_credentials) 14629 14630| Step | Descripción | 14631|---|---| 14632| \`obtengo token OAuth2 de "{token_url}" con client_id "{client_id}" y client_secret "{client_secret}"\` | Obtiene el token y configura el Bearer automáticamente | 14633 14634## Encadenamiento de llamadas 14635 14636| Step | Descripción | 14637|---|---| 14638| \`extraigo el campo "{field}" de la última respuesta API y lo uso como "{param}" en la siguiente petición\` | Reutiliza un valor de la respuesta anterior en la siguiente request | 14639 14640\`\`\`gherkin 14641When envÃo petición POST a "/orders" con cuerpo '{"product":"laptop"}' y guardo la respuesta en la variable "orden" 14642And extraigo el campo "id" de la última respuesta API y lo uso como "order_id" en la siguiente petición 14643Then reintento GET a "/orders/\${order_id}" hasta que el campo "status" sea "shipped" con máximo 10 intentos cada 5 segundos 14644\`\`\``},{id:"api-adv-validaciones",title:"Match, Schema, WebSocket",content:'## Match parcial y Schema\n\n| Step | Descripción |\n|---|---|\n| `la respuesta API deberÃa contener parcialmente "{expected_json}"` | Match parcial estilo Karate (contains) |\n| `todos los elementos del array API "{path}" deberÃan contener "{expected_json}"` | Match aplicado a cada elemento del array |\n| `la respuesta API deberÃa cumplir el esquema "{schema_json}"` | Validación con JSON Schema inline |\n| `verifico idempotencia ejecutando {method} a "{url}" {times} veces y comparando respuestas` | Test de idempotencia (GET/DELETE/etc.) |\n\n## WebSocket\n\n| Step | Descripción |\n|---|---|\n| `abro conexión WebSocket a "{url}" y guardo la referencia como "{ws_name}"` | Abre y nombra la conexión |\n| `envÃo mensaje "{message}" por WebSocket "{ws_name}"` | EnvÃa un mensaje |\n| `recibo mensaje del WebSocket "{ws_name}" y lo guardo en la variable "{variable}"` | Recibe y guarda el mensaje |\n| `cierro la conexión WebSocket "{ws_name}"` | Cierra la conexión |\n\n## SOAP / XML, paginación, latencia y multipart\n\n| Step | Descripción |\n|---|---|\n| `recorro todas las páginas de "{url}" con parámetro "{page_param}" y acumulo resultados en "{variable}"` | Paginación automática |\n| `envÃo petición SOAP a "{url}" con body XML del archivo "{file_path}" y guardo la respuesta en la variable "{variable}"` | Petición SOAP desde archivo XML |\n| `la respuesta XML deberÃa contener el tag "{tag}" con valor "{expected}"` | Validación de XML |\n| `mido latencia de {count} peticiones GET a "{url}" y verifico que el p95 sea menor a {max_ms} ms` | Latencia p95 |\n| `envÃo petición multipart a "{url}" con archivo "{file_path}" campo "{field}" y datos adicionales "{extra_fields}" y guardo en "{variable}"` | Multipart con archivo + campos |\n\n## Cookies, comparación y versiones\n\n| Step | Descripción |\n|---|---|\n| `guardo las cookies de la respuesta API en la sesión` | Persiste cookies en la sesión API |\n| `verifico que la cookie "{cookie_name}
14644" existe en la sesión API` | Verifica una cookie de sesión |\n| `limpio las cookies de la sesión API` | Limpia las cookies de la sesión |\n| `comparo la respuesta API actual con la guardada en la variable "{variable}" ignorando los campos "{ignored_fields}"` | Comparación ignorando campos volátiles |\n| `verifico que el endpoint "{endpoint}" responde igual en versiones "{versions}"` | Compara la respuesta entre versiones de API |'}]},{id:"verificacion-archivos",title:"Verificacion de Archivos",group:"Tipos de Prueba",icon:"",topics:[{id:"va-descripcion",title:"Descripcion",content:`## Steps para Verificacion y Comparacion de Archivos 14645 1464632 steps para validar archivos descargados o generados por la app bajo test: exportaciones CSV, reportes PDF, descargas Excel, archivos XML, imagenes y verificacion de integridad por hash. 14647 14648Modulo: \`file_verification_steps.py\` 14649 14650Util para certificar que las exportaciones de una app generan archivos correctos (estructura, contenido, integridad).`},{id:"va-comparacion",title:"Comparacion de Archivos",content:`## Comparacion 14651 14652| Step | Descripcion | 14653|---|---| 14654| \`el archivo "{a}" deberia ser identico al archivo "{b}"\` | Byte a byte | 14655| \`el CSV "{a}" deberia coincidir con "{b}" ignorando las columnas "{cols}"\` | Ignora columnas dinamicas | 14656| \`el JSON "{a}" deberia coincidir con "{b}" ignorando los campos "{campos}"\` | Ignora campos dinamicos | 14657| \`el CSV "{a}" deberia tener la misma estructura que "{b}"\` | Solo verifica columnas | 14658 14659## PDF 14660 14661| Step | Descripcion | 14662|---|---| 14663| \`el PDF "{path}" deberia contener el texto "{texto}"\` | Busca en todas las paginas | 14664| \`el PDF "{path}
14664" no deberia contener el texto "{texto}"\` | Ausencia | 14665| \`el PDF "{path}" deberia tener {N} paginas\` | Conteo de paginas | 14666 14667## Excel 14668 14669| Step | Descripcion | 14670|---|---| 14671| \`en el archivo Excel "{path}" hoja "{hoja}" celda "{celda}" deberia contener "{valor}"\` | Valor de celda | 14672| \`el archivo Excel "{path}" hoja "{hoja}" deberia tener al menos {N} filas de datos\` | Minimo filas | 14673| \`la suma de la columna "{col}" del Excel "{path}" hoja "{hoja}" deberia ser "{total}"\` | Suma de columna |`},{id:"va-csv-xml-hash",title:"CSV, XML, Hash y Limpieza",content:`## CSV avanzado 14674 14675| Step | Descripcion | 14676|---|---| 14677| \`en el archivo CSV "{path}" la columna "{col}" deberia estar ordenada de forma "{orden}"\` | asc o desc | 14678| \`en el archivo CSV "{path}" no deberia haber filas duplicadas en la columna "{col}"\` | Unicidad | 14679| \`el archivo CSV "{path}" deberia tener exactamente las columnas "{a,b,c}"\` | Estructura | 14680| \`el promedio de la columna "{col}" en el archivo CSV "{path}" deberia ser mayor a "{N}"\` | Estadistica | 14681| \`el archivo CSV "{path}" deberia tener {N} filas de datos\` | Conteo | 14682 14683## XML 14684 14685| Step | Descripcion | 14686|---|---| 14687| \`en el archivo XML "{path}" el nodo "{xpath}" deberia contener "{valor}"\` | Valor de nodo | 14688| \`en el archivo XML "{path}" deberia haber {N} nodos "{xpath}"\` | Conteo de nodos | 14689 14690## Existencia, tamano y hash 14691 14692| Step | Descripcion | 14693|---|---| 14694| \`deberia existir el archivo "{path}"\` | Existe | 14695| \`no deberia existir el archivo "{path}"\` | No existe | 14696| \`el archivo "{path}" deberia pesar menos de {N} MB\` | Tamano maximo | 14697| \`el hash MD5 del archivo "{path}" deberia ser "{hash}"\` | Integridad MD5 | 14698| \`el hash SHA256 del archivo "{path}" deberia ser "{hash}"\` | Integridad SHA256 | 14699| \`guardo el hash SHA256 del archivo "{path}" en la variable "{var}"\` | Para comparar despues | 14700 14701## Limpieza 14702 14703| Step | Descripcion | 14704|---|---| 14705| \`elimino el archivo "{path}" si existe\` | Cleanup | 14706| \`limpio el directorio "{path}"\` | Borra contenido del directorio |`}]},{id:"screenshots-reportes",title:"Screenshots y Reportes",group:"Integraciones y Reportes",icon:"",topics:[{id:"configuracion-screenshots",title:"Configuracion de Screenshots",content:`## Captura de Screenshots 14707 14708El framework captura screenshots automaticamente durante la ejecucion de pruebas para generar evidencia visual en el reporte HTML. 14709 14710### Configuracion basica (.env) 14711 14712\`\`\` 14713# Capturar screenshot en CADA paso (genera mucha evidencia, util para debug) 14714HTML_REPORT_CAPTURE_ALL_STEPS=true 14715 14716# Solo capturar en pasos fallidos (default, menos peso) 14717HTML_REPORT_CAPTURE_ALL_STEPS=false 14718 14719# Screenshots de pagina completa o solo viewport 14720SCREENSHOT_FULL_PAGE=true 14721 14722# Directorio donde se guardan los screenshots 14723SCREENSHOTS_DIR=screenshots 14724\`\`\` 14725 14726### Comportamiento por defecto 14727 14728| Situacion | Comportamiento | 14729|---|---| 14730| Pasos fallidos | Siempre se captura screenshot automaticamente | 14731| Pasos exitosos | Solo se captura si \`HTML_REPORT_CAPTURE_ALL_STEPS=true\` | 14732| Modo API | No se capturan screenshots (se muestra request/response) | 14733| Modo Desktop | Se controla con \`DESKTOP_CAPTURE_ALL_STEPS=true\` (default: true) | 14734| Modo Mobile | Se controla con \`MOBILE_CAPTURE_ALL_STEPS=true\` (default: true) |`},{id:"screenshot-group",title:"Screenshot Group",content:`## Screenshot Group â Control de capturas en pasos compuestos 14735 14736Cuando creas un paso personalizado que agrupa varios sub-pasos con \`context.execute_steps(...)\`, por defecto el framework captura un screenshot por cada sub-paso (si la captura esta habilitada). Esto genera evidencia redundante. 14737 14738\`screenshot_group\` es un context manager que permite controlar que screenshots se conservan dentro de un paso compuesto. 14739 14740### Import 14741 14742\`\`\`python 14743from hakalab_framework import screenshot_group 14744\`\`\` 14745 14746### Politicas disponibles 14747 14748| Policy | Comportamiento | 14749|---|---| 14750| \`'all'\` | Captura todos los screenshots de cada sub-paso (por defecto) | 14751| \`'last'\` | Solo conserva el ultimo screenshot del grupo (estado final) | 14752| \`'first'\` | Solo conserva el primer screenshot del grupo (estado inicial) | 14753| \`'none'\` | No captura ningun screenshot en los sub-pasos | 14754 14755### Ejemplo: Solo el ultimo screenshot (policy='last') 14756 14757El caso mas comun. Te interesa ver como quedo la pantalla despues de completar todo el flujo. 14758 14759\`\`\`python 14760from behave import step 14761from hakalab_framework import screenshot_group 14762 14763@step('completo el formulario de login con "{usuario}" y "{clave}"') 14764def step_login(context, usuario, clave): 14765 with screenshot_group(context, policy='last'): 14766 context.execute_steps(f''' 14767 When relleno el campo "usuario" con "{usuario}" con identificador "$.LOGIN.input_user" 14768 And relleno el campo "password" con "{clave}" con identificador "$.LOGIN.input_pass" 14769 And hago click en el elemento "Login" con identificador "$.LOGIN.btn_login" 14770 ''') 14771\`\`\` 14772 14773Resultado en el reporte: se muestra 1 solo screenshot (el de despues del click en Login), no 3. 14774 14775### Ejemplo: Solo el primer screenshot (policy='first') 14776 14777Util cuando quieres capturar el estado inicial antes de que el flujo modifique la pantalla. 14778 14779\`\`\`python 14780@step('verifico y limpio el carrito de compras') 14781def step_limpiar_carrito(context): 14782 with screenshot_group(context, policy='first'): 14783 context.execute_steps(''' 14784 When hago click en el elemento "Carrito" con identificador "$.HEADER.btn_carrito" 14785 And hago click en el elemento "Vaciar" con identificador "$.CARRITO.btn_vaciar" 14786 And hago click en el elemento "Confirmar" con identificador "$.MODAL.btn_confirmar" 14787 ''') 14788\`\`\` 14789 14790Resultado en el reporte: se muestra 1 screenshot (despues de abrir el carrito, antes de vaciarlo). 14791 14792### Ejemplo: Sin screenshots (policy='none') 14793 14794Para pasos auxiliares que no aportan evidencia visual (setup de datos, limpieza, navegacion intermedia). 14795 14796\`\`\`python 14797@step('preparo los datos de prueba del usuario "{email}"') 14798def step_preparar_datos(context, email): 14799 with screenshot_group(context, policy='none'): 14800 context.execute_steps(f''' 14801 Given voy a la url "https://admin.test/users" 14802 When relleno el campo "buscar" con "{email}" con identificador "$.ADMIN.input_search" 14803 And hago click en el elemento "Buscar" con identificador "$.ADMIN.btn_search"
14804 And hago click en el elemento "Reset" con identificador "$.ADMIN.btn_reset" 14805 ''') 14806\`\`\` 14807 14808Resultado en el reporte: no se captura ningun screenshot de estos sub-pasos. 14809 14810### Ejemplo: Todos los screenshots (policy='all') 14811 14812Es el comportamiento por defecto. No necesitas usar \`screenshot_group\` para esto, pero puedes ser explicito. 14813 14814\`\`\`python 14815@step('realizo el flujo critico de pago') 14816def step_pago(context): 14817 with screenshot_group(context, policy='all'): 14818 context.execute_steps(''' 14819 When selecciono la opcion "Tarjeta" del campo "metodo_pago" con identificador "$.PAGO.select_metodo" 14820 And relleno el campo "numero" con "4111111111111111" con identificador "$.PAGO.input_numero" 14821 And hago click en el elemento "Pagar" con identificador "$.PAGO.btn_pagar" 14822 ''') 14823\`\`\` 14824 14825Resultado en el reporte: se captura un screenshot por cada sub-paso (3 en total). 14826 14827### Anidamiento 14828 14829\`screenshot_group\` soporta anidamiento. Si un paso compuesto llama a otro paso compuesto que tambien usa \`screenshot_group\`, cada uno respeta su propia policy de forma independiente. 14830 14831### Retrocompatibilidad 14832 14833Si no usas \`screenshot_group\`, el comportamiento es identico al anterior. Los proyectos existentes no necesitan cambios.`},{id:"reportes-html",title:"Reportes HTML",content:`## Reportes HTML 14834 14835### Campos personalizados en el header 14836 14837El reporte HTML muestra una barra con informacion del proyecto (Ingeniero, Fecha, Producto, Empresa, Version, Ambiente). Puedes agregar campos adicionales configurandolos en el \`report_config.json\`: 14838 14839\`\`\`json 14840{ 14841 "report_info": { 14842 "title": "Reporte de Pruebas", 14843 "engineer": "Felipe Farias", 14844 "execution_date": "auto", 14845 "product": "Mi App", 14846 "company": "Haka Lab", 14847 "version": "2.1.0", 14848 "environment": "QA" 14849 }, 14850 "custom_fields": [ 14851 { 14852 "enabled": true, 14853 "label": "Sprint", 14854 "value": "Sprint 24", 14855 "icon": "sprint-icon" 14856 }, 14857 { 14858 "enabled": true, 14859 "label": "Rama", 14860 "value": "feature/login-refactor", 14861 "icon": "branch-icon" 14862 }, 14863 { 14864 "enabled": true, 14865 "label": "Pipeline", 14866 "value": "CI #1482", 14867 "icon": "pipeline-icon" 14868 }, 14869 { 14870 "enabled": false, 14871 "label": "Ticket", 14872 "value": "JIRA-1234", 14873 "icon": "ticket-icon" 14874 } 14875 ] 14876} 14877\`\`\` 14878 14879Los campos con \`"enabled": true\` se muestran en la barra del header junto a los campos fijos. Los que tienen \`"enabled": false\` se ignoran. Si el JSON no tiene la seccion \`custom_fields\`, el reporte se genera igual que antes. 14880 14881### Buscador y filtro de escenarios 14882 14883El reporte HTML incluye una barra de busqueda arriba de la lista de features que permite: 14884 14885- Buscar por texto: filtra escenarios cuyo nombre o tags contengan lo que escribes. 14886- Filtrar por estado: muestra solo los escenarios Passed, Failed o Skipped. 14887 14888El filtro funciona en tiempo real (mientras escribes) y es completamente client-side (no requiere servidor ni conexion). Los features que quedan sin escenarios visibles se ocultan automaticamente. 14889 14890### Atajos de teclado del reporte 14891 14892| Atajo | Accion | 14893|---|---| 14894| \`Ctrl+E\` | Expandir/contraer todos los features | 14895| \`ESC\` | Cerrar el modal de screenshot ampliado | 14896 14897### Configuracion de colores 14898 14899Los colores del reporte se configuran en la seccion \`styling\` del \`report_config.json\`: 14900 14901\`\`\`json 14902{ 14903 "styling": { 14904 "primary_color": "#2c3e50", 14905 "secondary_color": "#3498db", 14906 "accent_color": "#e74c3c", 14907 "success_color": "#27ae60", 14908 "warning_color": "#f39c12" 14909 } 14910} 14911\`\`\` 14912 14913### Logos 14914 14915El reporte soporta dos logos (esquina superior izquierda y derecha): 14916 14917\`\`\`json 14918{ 14919 "logos": { 14920 "primary_logo": { 14921 "enabled": true, 14922 "path": "auto", 14923 "alt": "Haka Lab", 14924 "width": "150px" 14925 }, 14926 "secondary_logo": { 14927 "enabled": true, 14928 "path": "data:image/png;base64,...", 14929 "alt": "Mi Empresa", 14930 "width": "150px" 14931 } 14932 } 14933} 14934\`\`\` 14935 14936- \`"path": "auto"\` usa el logo de Haka Lab embebido. 14937- Para logos personalizados, usa una ruta de archivo o un data URI en base64.`}]}],fj=["Empezar","Fundamentos","Tipos de Prueba","Aplicaciones Empresariales","Técnicas Avanzadas","Herramientas Haka","Integraciones y Reportes"],ine="Otros";function rne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const h=new Set;
14937return nne.filter(g=>h.has(g.id)?!1:(h.add(g.id),!0))},[]);k.useEffect(()=>{document.title="Docs - Haka Playwright Engine | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const h=i.toLowerCase();return c.map(g=>({...g,topics:g.topics.filter(y=>y.title.toLowerCase().includes(h)||y.content.toLowerCase().includes(h))})).filter(g=>g.topics.length>0)},[i,c]),u=k.useMemo(()=>{const h=new Map;for(const x of d){const v=x.group||ine,w=h.get(v)||[];w.push(x),h.set(v,w)}const g=fj.filter(x=>h.has(x)),y=[...h.keys()].filter(x=>!fj.includes(x));return[...g,...y].map(x=>({name:x,sections:h.get(x)}))},[d]),p=k.useMemo(()=>{for(const h of c){const g=h.topics.find(y=>y.id===a);if(g)return g}return null},[a,c]),m=(h,g)=>{e(h),n(g),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"Haka Playwright Engine - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:` 14938 fixed lg:sticky top-0 left-0 z-50 lg:z-10 14939 w-80 h-screen overflow-y-auto 14940 bg-darkGray border-r border-gray-800 14941 transition-transform duration-300 14942 ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"} 14943 `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"Haka Playwright Engine"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Documentación del Framework"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:h=>r(h.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:u.map(h=>s.jsxs("div",{className:"mb-4",children:[s.jsx("p",{className:"px-3 pt-3 pb-1.5 text-[11px] font-bold uppercase tracking-wider text-gray-500",children:h.name}),h.sections.map(g=>{const y=i.trim()?!0:t===g.id;return s.jsxs("div",{className:"mb-1",children:[s.jsxs("button",{onClick:()=>e(t===g.id?null:g.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:g.icon}),s.jsx("span",{children:g.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${y?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),y&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:g.topics.map(x=>s.jsx("button",{onClick:()=>m(g.id,x.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===x.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:x.title},x.id))})]},g.id)})]},h.name))})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:p?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:p.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(one,{content:p.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function one({content:t}){return sne(t).map((a,n)=>s.jsx(lne,{block:a},n))}function sne(t){var i;const e=[],a=t.split(` 14944`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(` 14945`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("> ")||r===">"){const o=[];for(;n<a.length&&(a[n].startsWith("> ")||a[n]===">");)o.push(a[n].replace(/^>\s?/,"")),n++;e.push({type:"quote",text:o.join(" ").trim()});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function lne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(Fm,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
14945case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"quote":return s.jsx("blockquote",{className:"border-l-4 border-primary/60 bg-primary/5 px-4 py-3 my-4 rounded-r-lg text-gray-300 leading-relaxed",children:s.jsx(Fm,{text:t.text})});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(Fm,{text:e})},a))});case"table":return s.jsx(cne,{rows:t.rows});default:return null}}function cne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(Fm,{text:o})},l))},r))})]})})}function Fm({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const qO=k.createContext(),H0="hakalab.com",dne="https://us-central1-haka-licencias-productos.cloudfunctions.net/validarLicencia",F0=["Engine Playwright","Haka AI Studio","HakaBoost","Hakabuddy","HakaPath"];function At({children:t}){const[e,a]=k.useState(null),[n,i]=k.useState(!0);k.useEffect(()=>{const c=localStorage.getItem("docs_user");if(c)try{a(JSON.parse(c))}catch{}const d=Y3(xi,u=>{var p;if(u&&((p=u.email)!=null&&p.endsWith(`@${H0}`))){const m={email:u.email,name:u.displayName,photo:u.photoURL,method:"google",productos:F0};a(m),localStorage.setItem("docs_user",JSON.stringify(m))}i(!1)});return i(!1),()=>d()},[]);const r=async()=>{const c=new Kn;c.setCustomParameters({hd:H0});const d=await cO(xi,c),u=d.user.email;if(!(u!=null&&u.endsWith(`@${H0}`)))throw await yd(xi),new Error("Solo se permiten cuentas @hakalab.com");const p={email:u,name:d.user.displayName,photo:d.user.photoURL,method:"google",productos:F0};return a(p),localStorage.setItem("docs_user",JSON.stringify(p)),p},o=async(c,d)=>{const u=await fetch(dne,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:d,mail:c,producto:"todos",id_app:"na"})});if(!u.ok)throw new Error("Error de conexión con el servidor");const p=await u.json();if(p.estado!=="habilitado")throw new Error(p.mensaje||"Licencia no válida");const h=(Array.isArray(p.producto)?p.producto:[p.producto]).filter(y=>F0.includes(y));if(h.length===0)throw new Error("Tu licencia no incluye acceso a documentación disponible");const g={email:c,name:p.nombre||c,empresa:p.empresa,method:"license",productos:h};return a(g),localStorage.setItem("docs_user",JSON.stringify(g)),g},l=async()=>{try{await yd(xi)}catch{}a(null),localStorage.removeItem("docs_user")};return s.jsx(qO.Provider,{value:{user:e,loading:n,loginWithGoogle:r,loginWithLicense:o,logout:l},children:t})}const Zl=()=>k.useContext(qO),go={id:"haka-automation-engine",titulo:"Curso Haka Automation Engine",descripcion:"Seis sesiones en orden, desde qué es el framework hasta ejecutar pruebas en dispositivos móviles.",sesiones:[{numero:1,id:"que-es-haka-automation-engine",titulo:"¿
14945Qué es el Haka Automation Engine?",nivel:"Introducción",duracion:"18:51",youtubeId:"lMQLdlcsebU",descripcion:"Qué resuelve el framework, cómo se compone y en qué se diferencia de automatizar con Playwright a mano.",temas:["Visión general","Arquitectura","Casos de uso"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:2,id:"ambientacion-del-proyecto",titulo:"Ambientación del proyecto",nivel:"Básico",duracion:"18:45",youtubeId:"hre6R5sxTJo",descripcion:"Instalación, estructura de carpetas y configuración inicial del archivo .env para dejar el proyecto listo.",temas:["Instalación","Estructura","Configuración .env"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:3,id:"primera-prueba-web",titulo:"Primera Prueba Web",nivel:"Básico",duracion:"28:29",youtubeId:"kjeDr5sxtRk",descripcion:"Escribir un escenario en Gherkin, mapear localizadores en un Page Object y ejecutar la prueba en el navegador.",temas:["Gherkin","Localizadores","Ejecución"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:4,id:"pruebas-api-rest",titulo:"Pruebas de API Rest",nivel:"Intermedio",duracion:"24:44",youtubeId:"1h9J7OmNRDE",descripcion:"Peticiones HTTP, validación de respuestas y encadenamiento de datos entre pasos sin abrir el navegador.",temas:["Peticiones HTTP","Validaciones","Variables"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:5,id:"ambientacion-mobile",titulo:"Ambientación Mobile",nivel:"Intermedio",duracion:"21:15",youtubeId:"6u8f75G9nnI",descripcion:"Preparar el entorno de pruebas móviles: Appium, dependencias y configuración del dispositivo o emulador.",temas:["Appium","Dependencias","Emulador"],docsLink:"/docs/haka-playwright-engine/docs"}
14945,{numero:6,id:"ejecucion-en-mobile",titulo:"Ejecución en Mobile",nivel:"Intermedio",duracion:"30:59",youtubeId:"vSM4jtFhUlM",descripcion:"Escribir y correr un escenario móvil, con taps, scroll y verificaciones sobre la aplicación instalada.",temas:["Taps y scroll","Verificaciones","Reportes"],docsLink:"/docs/haka-playwright-engine/docs"}]};function une(t){if(!t)return 0;const e=String(t).split(":").map(Number);return e.some(Number.isNaN)?0:e.reduce((a,n)=>a*60+n,0)}function gj(t){const e=Math.round(t/60),a=Math.floor(e/60),n=e%60;return a===0?`${n}min`:n===0?`${a}h`:`${a}h ${n}min`}function pne(t=[],e=go){let a=0,n=0;for(const i of e.sesiones){const r=une(i.duracion);a+=r,t.includes(i.id)||(n+=r)}return{total:a,restante:n}}const zO="haka-video-progress";function mne(t){try{const e=window.localStorage.getItem(`${zO}:${t}`),a=e?JSON.parse(e):[];return Array.isArray(a)?a.filter(n=>typeof n=="string"):[]}catch{return[]}}function yj(t,e){try{window.localStorage.setItem(`${zO}:${t}`,JSON.stringify(e))}catch{}}function hne({completadas:t,total:e}){const n=2*Math.PI*34,i=e>0?t/e:0;return s.jsxs("div",{className:"relative w-24 h-24 shrink-0",children:[s.jsxs("svg",{className:"w-24 h-24 -rotate-90",viewBox:"0 0 80 80","aria-hidden":"true",children:[s.jsx("circle",{cx:"40",cy:"40",r:34,fill:"none",stroke:"currentColor",strokeWidth:"5",className:"text-gray-800"}),s.jsx("circle",{cx:"40",cy:"40",r:34,fill:"none",stroke:"currentColor",strokeWidth:"5",strokeLinecap:"round",className:"text-primary transition-[stroke-dashoffset] duration-700 ease-out",strokeDasharray:n,strokeDashoffset:n*(1-i)})]}),s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[s.jsx("span",{className:"text-white font-bold text-xl leading-none",children:t}),s.jsxs("span",{className:"text-gray-500 text-[11px] mt-0.5",children:["de ",e]})]})]})}function fne({sesion:t,siguiente:e,onCerrar:a,onCompletar:n,onIrSiguiente:i}){return k.useEffect(()=>{const r=l=>{l.key==="Escape"&&a()};window.addEventListener("keydown",r);const o=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{window.removeEventListener("keydown",r),document.body.style.overflow=o}},[a]),s.jsx("div",{className:"fixed inset-0 z-[60] flex items-center justify-center p-4 sm:p-6 bg-black/80 backdrop-blur-sm",role:"dialog","aria-modal":"true","aria-label":`Sesión ${t.numero}: ${t.titulo}`,onClick:a,children:s.jsxs(_.div,{initial:{opacity:0,scale:.97},animate:{opacity:1,scale:1},transition:{duration:.2},className:"w-full max-w-5xl bg-darkGray border border-gray-800 rounded-2xl overflow-hidden shadow-2xl",onClick:r=>r.stopPropagation(),children:[s.jsxs("div",{className:"flex items-start justify-between gap-4 px-5 py-4 border-b border-gray-800",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsxs("p",{className:"text-primary text-xs font-semibold tracking-wide",children:["SESIÃN ",t.numero]}),s.jsx("h2",{className:"text-white font-semibold text-base sm:text-lg truncate",children:t.titulo})]}),s.jsx("button",{onClick:a,"aria-label":"Cerrar reproductor",className:"text-gray-400 hover:text-white transition-colors p-1 shrink-0",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),s.jsx("div",{className:"aspect-video bg-black",children:s.jsx("iframe",{className:"w-full h-full",src:`https://www.youtube-nocookie.com/embed/${t.youtubeId}?autoplay=1&rel=0&modestbranding=1`,title:`Sesión ${t.numero}: ${t.titulo}`,allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})}),s.jsxs("div",{className:"px-5 py-4 flex flex-col sm:flex-row sm:items-center gap-3 sm:justify-between",children:[s.jsxs("button",{onClick:()=>n(t.id),className:"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg border border-primary/40 text-primary text-sm font-medium hover:bg-primary/10 transition-colors",children:[s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),"Marcar como completada"]}),e&&s.jsxs("button",{onClick:()=>i(e),className:"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-primary/90 hover:bg-primary text-dark text-sm font-semibold transition-colors",children:["Siguiente: ",e.titulo,s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})]})})}function gne(){const{user:t,logout:e}=Zl(),[a,n]=R8(),[i,r]=k.useState([]),[o,l]=k.useState(null),c=go.sesiones,d=k.useMemo(()=>c.filter(v=>v.youtubeId),[c]);k.useEffect(()=>{document.title="Video Tutoriales - Haka Automation Engine | Haka Lab",r(mne(go.id))},[]),k.useEffect(()=>{const v=a.get("v");if(!v){l(null);return}const w=c.find(S=>S.id===v&&S.youtubeId);l(w||null)},[a,c]);const u=k.useCallback(v=>{v.youtubeId&&n({v:v.id},{replace:!1})},[n]),p=k.useCallback(()=>{n({},{replace:!0})},[n]),m=k.useCallback(v=>{r(w=>{const S=w.includes(v)?w.filter(T=>T!==v):[...w,v];return yj(go.id,S),S})},[]),h=k.useCallback(v=>{r(w=>{if(w.includes(v))return w;const S=[...w,v];return yj(go.id,S),S})},[]),g=k.useCallback(v=>{const w=d.findIndex(S=>S.id===v.id);return w>=0&&d[w+1]||null},[d]),y=i.filter(v=>c.some(w=>w.id===v)).length,x=k.useMemo(()=>pne(i),[i]);return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[s.jsx(Te,{to:"/docs/haka-playwright-engine",className:"text-gray-400 hover:text-white transition-colors text-sm shrink-0",children:"â Volver"}),s.jsx("span",{className:"text-gray-600",children:"|"}),s.jsx("span",{className:"text-white font-semibold text-base sm:text-lg truncate",children:"Video Tutoriales"})]}),s.jsxs("div",{className:"flex items-center gap-4 shrink-0",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:t==null?void 0:t.email}),s.jsx("button",{onClick:e,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsxs("main",{className:"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-10 sm:py-14",children:[s.jsxs(_.div,{initial:{opacity:0,y:10}
14945,animate:{opacity:1,y:0},transition:{duration:.4},className:"flex flex-col sm:flex-row sm:items-center gap-6 mb-12",children:[s.jsxs("div",{className:"flex-1",children:[s.jsx("p",{className:"text-primary text-xs font-semibold tracking-wider mb-2",children:"RUTA DE APRENDIZAJE"}),s.jsx("h1",{className:"text-3xl sm:text-4xl font-bold text-white mb-3",children:go.titulo}),s.jsx("p",{className:"text-gray-400 leading-relaxed mb-4",children:go.descripcion}),s.jsxs("div",{className:"flex items-center gap-3 text-sm flex-wrap",children:[s.jsxs("span",{className:"text-gray-500",children:[c.length," sesiones · ",gj(x.total)," en total"]}),x.restante>0&&x.restante<x.total&&s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"text-gray-700","aria-hidden":"true",children:"â¢"}),s.jsxs("span",{className:"text-primary font-medium",children:[gj(x.restante)," restantes"]})]}),x.restante===0&&s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"text-gray-700","aria-hidden":"true",children:"â¢"}),s.jsx("span",{className:"text-primary font-medium",children:"Curso completado"})]})]})]}),s.jsx(hne,{completadas:y,total:c.length})]}),s.jsx("ol",{className:"relative",children:c.map((v,w)=>{const S=i.includes(v.id),T=!!v.youtubeId,P=w===c.length-1;return s.jsxs(_.li,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.35,delay:Math.min(w*.06,.4)},className:"relative pl-14 sm:pl-16 pb-6 last:pb-0",children:[!P&&s.jsx("span",{"aria-hidden":"true",className:`absolute left-[19px] sm:left-[23px] top-12 bottom-0 w-0.5 rounded-full transition-colors duration-500 ${S?"bg-primary/50":"bg-gray-800"}`}),s.jsx("span",{"aria-hidden":"true",className:`absolute left-0 top-1 w-10 h-10 sm:w-12 sm:h-12 rounded-full border-2 flex items-center justify-center font-bold text-sm transition-all duration-300 ${S?"bg-primary/15 border-primary text-primary shadow-[0_0_18px_-4px_rgba(0,212,255,0.6)]":T?"bg-darkGray border-gray-700 text-gray-300":"bg-darkGray border-gray-800 text-gray-600"}`,children:S?s.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M5 13l4 4L19 7"})}):v.numero}),s.jsx("div",{className:`group rounded-xl border bg-darkGray transition-all duration-300 overflow-hidden ${T?"border-gray-800 hover:border-primary/50 hover:bg-darkGray/80":"border-gray-800/70 opacity-70"}`,children:s.jsxs("div",{className:"flex flex-col sm:flex-row",children:[s.jsxs("div",{className:"sm:w-56 shrink-0 relative",children:[s.jsx("div",{className:"aspect-video bg-dark/60 overflow-hidden",children:T?s.jsx("img",{src:`https://i.ytimg.com/vi/${v.youtubeId}/hqdefault.jpg`,alt:"",loading:"lazy",className:"w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("span",{className:"text-gray-600 text-xs font-medium",children:"Próximamente"})})}),T&&s.jsx("button",{onClick:()=>u(v),"aria-label":`Reproducir sesión ${v.numero}: ${v.titulo}`,className:"absolute inset-0 flex items-center justify-center bg-dark/40 opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity outline-none",children:s.jsx("span",{className:"w-12 h-12 rounded-full bg-primary text-dark flex items-center justify-center shadow-lg",children:s.jsx("svg",{className:"w-5 h-5 ml-0.5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M8 5v14l11-7z"})})})}),v.duracion&&s.jsx("span",{className:"absolute bottom-2 right-2 px-1.5 py-0.5 rounded bg-black/80 text-white text-[11px] font-medium tabular-nums",children:v.duracion})]}),s.jsxs("div",{className:"flex-1 p-4 sm:p-5 min-w-0",children:[s.jsxs("div",{className:"flex items-start justify-between gap-3 mb-1.5",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[s.jsxs("span",{className:"text-[11px] font-semibold text-gray-500 tracking-wide",children:["SESIÃN ",v.numero]}),s.jsx("span",{className:"px-2 py-0.5 rounded-full bg-dark border border-gray-700 text-[10px] font-medium text-gray-400",children:v.nivel})]}),s.jsx("h3",{className:"text-white font-semibold text-base sm:text-lg leading-snug",children:v.titulo})]}),s.jsx("button",{onClick:()=>
14945m(v.id),"aria-pressed":S,"aria-label":S?`Marcar sesión ${v.numero} como no completada`:`Marcar sesión ${v.numero} como completada`,title:S?"Completada":"Marcar como completada",className:`shrink-0 w-7 h-7 rounded-full border flex items-center justify-center transition-colors ${S?"border-primary bg-primary/15 text-primary":"border-gray-700 text-transparent hover:border-gray-500 hover:text-gray-500"}`,children:s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M5 13l4 4L19 7"})})})]}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed mb-3",children:v.descripcion}),s.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:v.temas.map(M=>s.jsx("span",{className:"px-2 py-0.5 rounded-md bg-dark/70 border border-gray-800 text-[11px] text-gray-400",children:M},M))}),s.jsxs("div",{className:"mt-4 flex items-center gap-4",children:[T?s.jsxs("button",{onClick:()=>u(v),className:"inline-flex items-center gap-1.5 text-primary text-sm font-medium hover:gap-2.5 transition-all",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M8 5v14l11-7z"})}),"Ver sesión"]}):s.jsx("span",{className:"text-gray-600 text-sm",children:"Disponible pronto"}),v.docsLink&&s.jsx(Te,{to:v.docsLink,className:"text-gray-500 hover:text-gray-300 text-sm transition-colors",children:"Leer la documentación"})]})]})]})})]},v.id)})}),d.length===0&&s.jsx("p",{className:"mt-10 text-center text-gray-500 text-sm",children:"Las sesiones se publicarán próximamente."})]}),o&&s.jsx(fne,{sesion:o,siguiente:g(o),onCerrar:p,onCompletar:h,onIrSiguiente:v=>{h(o.id),n({v:v.id},{replace:!0})}})]})}const yne=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es Haka AI Studio?",content:`## ¿Qué es Haka AI Studio? 14946 14947Haka AI Studio es una extensión de Visual Studio Code que usa inteligencia artificial para generar pruebas automatizadas. Graba las interacciones del usuario en un navegador y genera automáticamente casos de prueba en formato Gherkin/BDD con implementaciones listas para ejecutar. 14948 14949En términos simples: abres tu aplicación web, interactúas con ella (clicks, formularios, navegación), y la extensión genera los tests por ti. 14950 14951**Compatible con Haka-Playwright-Engine v1.4.1** 14952 14953## ¿Para quién es? 14954 14955| Perfil | Beneficio principal | 14956|--------|-------------------| 14957| QA Manual que quiere automatizar | Genera tests sin escribir código. Graba y la IA escribe por ti. | 14958| QA Automation | Acelera la creación de tests. La IA genera el esqueleto, tú lo refinas. | 14959| Desarrollador | Crea tests de regresión rápidamente mientras desarrolla features. | 14960| Tech Lead / QA Lead | Estandariza el formato de tests (Gherkin + Page Objects) en el equipo. | 14961| Equipos sin experiencia en automation | Punto de entrada accesible. La curva de aprendizaje baja drásticamente. |`},{id:"funcionalidades",title:"Funcionalidades Principales",content:`## Funcionalidades Principales 14962 14963| Funcionalidad | Descripción | 14964|---------------|-------------|
14965| **Koru** | Graba interacciones en el navegador y genera pruebas Gherkin con IA | 14966| **Kai** | Chat asistente de IA especializado en automatización de pruebas | 14967| **@aistudio** | Asistente inteligente inline en archivos .feature (búsqueda + IA) | 14968| **Gherkin/Cucumber** | Syntax highlighting, icono, colores personalizables | 14969| **Rest** | Genera features de pruebas REST desde OpenAPI, Postman o cURL | 14970| **Mock Server** | Servidor HTTP local para simular APIs | 14971| **Autocompletado** | IntelliSense de steps del framework en archivos .feature | 14972| **Sesiones Guardadas** | Autologin con sesiones capturadas (MFA/2FA, Firebase, SAP, Salesforce) | 14973| **Multi-IA** | Soporta Google Gemini, OpenAI y Anthropic Claude | 14974| **Dual Engine** | Funciona con Playwright y Selenium | 14975| **i18n** | Interfaz completa en español e inglés | 14976| **Modo Invitado** | Uso sin licencia con conocimiento genérico de IA |`},{id:"instalacion",title:"Instalación",content:`## Instalación 14977 14978### Requisitos Previos 14979 14980- Visual Studio Code versión 1.85.0 o superior 14981- Node.js versión 20.x o superior 14982- Python versión 3.8 o superior (para ejecutar tests) 14983- Navegador: Chrome, Firefox, Edge o Safari 14984 14985### Pasos de Instalación 14986 149871. Abre VS Code 149882. Ve a Extensiones (Ctrl+Shift+X en Windows/Linux, Cmd+Shift+X en Mac) 149893. Busca "Haka AI Studio" o instala desde .vsix 149904. Haz clic en "Instalar" 149915. Recarga VS Code (Ctrl+Shift+P â "Developer: Reload Window") 14992 14993### Instalación desde .vsix 14994 14995\`\`\`bash 14996code --install-extension haka-ai-studio-1.5.9.vsix 14997\`\`\` 14998 14999### Verificación 15000 15001Después de instalar, deberÃas ver: 15002- Icono de Haka AI Studio en la barra lateral izquierda 15003- Panel "Haka AI Studio" en la vista lateral 15004- Comandos disponibles en la paleta de comandos (Ctrl+Shift+P â "Haka:") 15005- Archivos .feature con syntax highlighting automático`},{id:"inicio-rapido",title:"Inicio Rápido",content:`## Inicio Rápido 15006 150071. **Instalar** la extensión desde el Marketplace o archivo .vsix 150082. **Abrir** el panel de Haka AI Studio desde la barra de actividad 150093. **Aceptar** los Términos de Uso y PolÃtica de Privacidad 150104. **Iniciar sesión** con Google o tu licencia Hakalab 150115. **Configurar** tu proveedor de IA (Gemini recomendado) en la pestaña Config 150126. **Grabar** un test con Koru o preguntarle a Kai 15013 15014### Tipos de Cuenta 15015 15016| Tipo | Acceso | 15017|------|--------| 15018| **Haka Lab** (Google OAuth) | Acceso completo, steps vectorizados | 15019| **Clave de Licencia** | Acceso completo, validación por dispositivo | 15020| **Invitado** | Koru + Kai con IA genérica (sin vectores, sin REST) |`},{id:"flujo-trabajo",title:"Flujo de Trabajo",content:`## Flujo de Trabajo TÃpico 15021 15022\`\`\` 150231. Abrir VS Code en tu proyecto de tests 150242. Click en Haka AI Studio (barra lateral) 150253. Configurar IA si es la primera vez 150264. (Opcional) Seleccionar perfil de sesión guardada 150275. Click "Grabar" â interactuar con la app â "Detener" 150286. Click "Generar con IA" 150297. Revisar resultado â Guardar archivos 15030\`\`\` 15031 15032### Para escribir features manualmente 15033 15034\`\`\` 150351. Crear/abrir un archivo .feature 150362. Disfrutar del syntax highlighting automático 150373. Usar @aistudio para buscar steps existentes 150384. Usar @aistudio? para que la IA sugiera steps nuevos 150395. Personalizar colores en Config > Cucumber / Gherkin 15040\`\`\` 15041 15042## Comparación con Alternativas 15043 15044| CaracterÃstica | Haka AI Studio | Playwright Codegen | Selenium IDE | 15045|---------------|----------------|-------------------|--------------| 15046| Genera Gherkin | Si | No | No | 15047| Syntax Highlighting Gherkin | Si (integrado) | No | No | 15048| @aistudio (búsqueda + IA inline) | Si | No | No | 15049| Page Objects | Si (JSON) | No | No | 15050| IA integrada | Si (multi-proveedor) | No | No | 15051| Reutiliza steps existentes | Si (vectorial) | No | No | 15052| Chat asistente | Si (Kai) | No | No | 15053| Sesiones guardadas (MFA) | Si (con IndexedDB) | No | No | 15054| Mock Server | Si (integrado) | No | No | 15055| Autocompletado .feature | Si (IntelliSense + @aistudio) | No | No | 15056| Pruebas REST desde spec | Si (OpenAPI/cURL) | No | No | 15057| Colores Gherkin personalizables | Si (en tiempo real) | No | No |`}]},{id:"configuracion",title:"Configuración",icon:"",topics:[{id:"config-ia",title:"Configurar Proveedor de IA",content:`## Configurar Proveedor de IA 15058 15059Haka AI Studio soporta múltiples proveedores de IA. Gemini es el recomendado por su integración con el sistema de búsqueda vectorial. 15060 15061### Obtener API Key de Gemini 15062 150631. Ve a https://aistudio.google.com/apikey 150642. Haz clic en "Get API Key" o "Create API Key" 150653. Copia tu API Key 15066 15067### Configurar en Haka AI Studio 15068 150691. Abre Haka AI Studio (barra lateral de VS Code) 150702. Ve a la pestaña "Config" 150713. Pega tu API Key 150724. Selecciona el modelo 150735. Los cambios se aplican en tiempo real (sin reiniciar VS Code) 15074 15075### Proveedores Soportados 15076 15077| Proveedor | Modelo Recomendado | Costo aprox. por test | 15078|-----------|-------------------|----------------| 15079| **Gemini** (Google) | gemini-2.5-flash-lite | ~$0.003 | 15080| **OpenAI** | gpt-4o | ~$0.01 | 15081| **Claude** (Anthropic) | claude-3-5-sonnet | ~$0.008 | 15082 15083### Costos Estimados Mensuales 15084 15085| Uso mensual | Costo aproximado | 15086|-------------|-----------------| 15087| 50 tests/mes | ~$0.15-$0.50 USD | 15088| 200 tests/mes | ~$0.60-$2.00 USD | 15089| 500 tests + chat | ~$1.50-$5.00 USD | 15090 15091### Consumo de IA 15092 15093- **No consume al grabar** â la grabación es local 15094- **Consume al generar** â cuando presionas "Generar con IA" 15095- **Consume al chatear** â cada mensaje a Kai usa tokens 15096- **Consume al vectorizar** â al generar embeddings de tus custom steps 15097- **Consume @aistudio?** â al pedir sugerencias con IA generativa`},{id:"config-licencia",title:"Licencia y Autenticación",content:`## Licencia y Autenticación 15098 15099### Métodos de Login 15100
15101- **Google OAuth** â cuenta corporativa @hakalab.com o autorizada 15102- **Email + Clave de licencia** â licencia manual por dispositivo 15103- **Modo invitado** â sin licencia, acceso limitado 15104 15105### Un dispositivo a la vez 15106 15107La licencia se bloquea por dispositivo. Si necesitas usar la extensión en otro equipo, cierra sesión en el actual. El bloqueo se libera automáticamente. 15108 15109### Modo Invitado 15110 15111Permite usar funcionalidades básicas sin licencia: 15112- Koru (grabación + generación con IA genérica) 15113- Chat con Kai (sin vectores del framework) 15114- No tiene acceso a engines vectorizados ni pruebas REST 15115 15116### Validación de Licencia 15117 15118- Primera ejecución: valida inmediatamente 15119- Próximos 10 dÃas: usa caché local (sin llamadas) 15120- Cada 10 dÃas: revalida (1 sola llamada) 15121 15122### Si hay Firewall Corporativo 15123 15124Solicitar a IT que habilite: 15125- Dominio: *.cloudfunctions.net (puerto 443) 15126- Dominio: generativelanguage.googleapis.com (para Gemini) 15127- Dirección: Salida (Outbound)`},{id:"config-panel",title:"Panel de Configuración",content:`## Panel de Configuración 15128 15129La pestaña Config organiza todas las opciones en secciones colapsables (plegables) que comienzan minimizadas por defecto. 15130 15131| Sección | Contenido | 15132|---------|-----------| 15133| **Gemini AI** | API Key, selección de modelo | 15134| **Instrucción adicional** | Prompt personalizado que se añade a todas las generaciones | 15135| **Estado** | Indicador de configuración actual | 15136| **Vectorización de Steps** | Escanear y vectorizar steps custom del proyecto | 15137| **Cucumber / Gherkin** | Colores de sintaxis, formato, vista previa en vivo | 15138| **Idioma** | Español / English | 15139 15140### Secciones Colapsables 15141 15142- Todas las secciones tienen chevron (â¼/â¶) para expandir/colapsar 15143- Comienzan colapsadas por defecto para una vista limpia 15144- Animación suave de apertura/cierre 15145- El panel hace scroll correctamente cuando varias están abiertas`}]},{id:"koru",title:"Koru (Grabación)",icon:"",topics:[{id:"koru-como-grabar",title:"Cómo Grabar",content:`## Grabación con Koru 15146 15147Koru es el módulo de grabación inteligente de Haka AI Studio. Captura las interacciones en el navegador en tiempo real. 15148 15149### Cómo Grabar 15150 151511. Abre el panel de Haka AI Studio (clic en el icono en la barra lateral) 151522. Ingresa la URL de tu aplicación 151533. (Opcional) Selecciona un perfil de sesión guardada para autologin 151544. Haz clic en "Iniciar Grabación" 151555. Se abrirá un navegador controlado (Chromium) 151566. Navega e interactúa con tu aplicación como lo harÃa un usuario real 151577. Haz clic en "Detener Grabación" cuando termines 15158 15159### Lo que Captura 15160 15161- Clicks en elementos 15162- Escritura en campos de texto 15163- Navegación entre páginas 15164- Selección de opciones en dropdowns 15165- Checks y radios 15166- Scrolls 15167 15168### Dos Modos de Grabación 15169 15170| Modo | Selectores | Uso recomendado | 15171|------|-----------|-----------------| 15172| **Playwright** | Roles, labels, data-testid | Apps modernas con buen markup | 15173| **Selenium** | XPath optimizados con validación de unicidad | Apps legacy o con selectores complejos |`},{id:"koru-generacion",title:"Generación con IA",content:`## Generación de Tests con IA 15174 15175### Paso 1: Revisar Grabación 15176 15177Después de detener la grabación, verás: 15178- Lista de acciones capturadas 15179- Selectores detectados 15180- Opción de editar antes de generar 15181 15182### Paso 2: Generar con IA 15183 151841. Haz clic en "Generar con IA" (botón con icono de chispa) 151852. Espera a que el proveedor procese (tÃpicamente 5-30 segundos) 151863. Verás el test generado en formato Gherkin 15187 15188### Paso 3: Revisar Resultado 15189 15190El test generado incluye: 15191- **Feature**: Descripción del flujo 15192- **Scenario**: Caso de prueba especÃfico 15193- **Steps**: Pasos en formato Gherkin (Given, When, Then) 15194- **Page Objects**: Localizadores en JSON 15195- **Implementación**: Código Python listo para ejecutar 15196 15197### Ejemplo de Test Generado 15198 15199\`\`\`gherkin 15200Feature: Login de usuario 15201 15202 Scenario: Login exitoso con credenciales válidas 15203 Given voy a la url "https://app.ejemplo.com/login" 15204 When relleno el campo "Email" con "[email protected]" con identificador "$.LOGIN.input_email" 15205 And relleno el campo "Password" con "123456" con identificador "$.LOGIN.input_password" 15206 And hago click en el elemento "Botón Ingresar" con identificador "$.LOGIN.btn_submit" 15207 Then deberÃa ver el elemento "Dashboard" con identificador "$.DASHBOARD.titulo" 15208\`\`\` 15209 15210\`\`\`json 15211// LOGIN.json (Page Object generado) 15212{ 15213 "input_email": "#email", 15214 "input_password": "#password", 15215 "btn_submit": "button[type='submit']" 15216} 15217\`\`\``},{id:"koru-busqueda-vectorial",title:"Búsqueda Vectorial",content:`## Búsqueda Vectorial (
15217Reutilización) 15218 15219El sistema vectoriza los steps existentes del framework Hakalab y los compara semánticamente con las acciones grabadas. 15220 15221### ¿Qué logra? 15222 15223- Si ya existe un step que hace lo que grabaste â lo reutiliza 15224- Si no existe â genera uno nuevo 15225- Evita duplicación de código 15226- Sugiere mejores prácticas del framework 15227 15228### Vectores Disponibles 15229 15230| Tipo | Cantidad | 15231|------|----------| 15232| API | 130 | 15233| Base de Datos | 14 | 15234| Desktop | 87 | 15235| GenAI | 52 | 15236| GuÃas | 143 | 15237| Mobile | 129 | 15238| Validaciones | 151 | 15239| Web | 481 | 15240| **Total** | **1187** | 15241 15242### Vectorizar Steps Personalizados 15243 15244En la pestaña Config > Vectorización de Steps, puedes escanear y vectorizar los steps de tu propio proyecto para que la IA los reutilice al generar tests.`},{id:"koru-consejos",title:"Consejos de Grabación",content:`## Consejos para Mejores Grabaciones 15245 15246### Buenas Prácticas 15247 15248- Usa datos ficticios en ambientes de prueba 15249- Graba flujos completos (inicio a fin) 15250- Espera a que los elementos carguen antes de interactuar 15251- Valida resultados visibles en la página 15252- Graba un flujo por escenario (no mezcles múltiples flujos) 15253 15254### Evitar 15255 15256- No grabes en producción con datos reales 15257- No cambies de ventana durante la grabación 15258- No hagas acciones muy rápidas (la grabación podrÃa perder eventos) 15259- No grabes datos sensibles (contraseñas reales, números de tarjeta) 15260 15261### Grabación de Login 15262 15263\`\`\` 152641. Iniciar grabación 152652. Navegar a https://ejemplo.com/login 152663. Escribir usuario en el campo "Usuario" 152674. Escribir contraseña en el campo "Contraseña" 152685. Hacer clic en "Iniciar Sesión" 152696. Esperar a que cargue el dashboard 152707. Detener grabación 15271\`\`\``}]},{id:"aistudio",title:"@aistudio",icon:"",topics:[{id:"aistudio-descripcion",title:"¿Qué es @aistudio?",content:`## @aistudio â Asistente Inteligente en .feature 15272 15273El sistema \`@aistudio\` es un asistente inteligente que funciona directamente dentro de los archivos \`.feature\`. Escribe el trigger y obtén sugerencias de steps al instante. 15274 15275### Uso 15276 15277\`\`\`gherkin 15278# Buscar steps en todo el proyecto + búsqueda semántica 15279@aistudio click 15280 15281# Pedir a la IA que sugiera steps (con descripción de qué hace cada uno) 15282@aistudio? como valido que un modal se cierra 15283\`\`\` 15284 15285### Niveles de Inteligencia 15286 15287| Trigger | Nivel | Fuente | Velocidad | 15288|---------|-------|--------|-----------| 15289| \`@aistudio <texto>\` | Búsqueda local | Todos los .feature del proyecto (recursivo) | Instantáneo | 15290| \`@aistudio <texto>\` | Búsqueda semántica | 1187 vectores del framework Hakalab | Instantáneo | 15291| \`@aistudio? <texto>\` | IA generativa | Gemini AI con contexto del proyecto | 1-3 segundos | 15292 15293### Comportamiento 15294 15295- Al seleccionar una sugerencia, todo el \`@aistudio...\` se reemplaza con el step elegido 15296- Las sugerencias locales muestran el archivo fuente de cada step 15297- Las sugerencias semánticas muestran el % de similitud y la categorÃa 15298- Las sugerencias de IA incluyen una explicación de qué hace cada paso 15299- Un spinner en la barra de estado indica cuando la IA está procesando`},{id:"aistudio-niveles",title:"Niveles de Inteligencia",content:`## Niveles de Inteligencia de @aistudio 15300 15301### Nivel 1 â Búsqueda Local en el Proyecto 15302 15303- Escanea recursivamente TODOS los \`.feature\` del workspace 15304- Excluye automáticamente \`node_modules\`, \`.git\`, \`dist\`, etc. 15305- Filtra por coincidencia fuzzy de múltiples términos 15306- Muestra el archivo fuente de cada step encontrado 15307 15308### Nivel 2 â Búsqueda Semántica (Embeddings) 15309 15310- Usa los 1187 vectores pre-entrenados del framework Hakalab 15311- Encuentra steps semánticamente similares aunque no coincidan textualmente 15312- Muestra el % de similitud y la categorÃa (api, web, mobile, validaciones, etc.) 15313- Se activa automáticamente cuando el query tiene 3+ caracteres 15314 15315### Nivel 3 â Generación con IA (Gemini) 15316 15317- Se activa con \`@aistudio?\` (con signo de interrogación) 15318- EnvÃa a Gemini el contexto del proyecto (steps existentes, steps del archivo actual) 15319- Genera 3-5 sugerencias de steps compatibles con el proyecto 15320- Cada sugerencia incluye una descripción de qué hace el paso concretamente 15321- Muestra un spinner en la barra de estado mientras procesa 15322 15323### Comportamiento al Seleccionar 15324 15325- Todo el texto \`@aistudio...\` o \`@aistudio?...\` se reemplaza con el step elegido 15326- El step incluye su keyword (Given/When/Then/And/But)
15327- La indentación se mantiene`},{id:"aistudio-ejemplos",title:"Ejemplos de Uso",content:`## Ejemplos de @aistudio 15328 15329### Buscar steps existentes 15330 15331\`\`\`gherkin 15332# Buscar todos los steps que tienen "login" 15333@aistudio login 15334 15335# Buscar steps de validación 15336@aistudio verificar elemento visible 15337 15338# Buscar steps de API 15339@aistudio request POST 15340\`\`\` 15341 15342### Pedir sugerencias a la IA 15343 15344\`\`\`gherkin 15345# Pedir a la IA pasos para un flujo especÃfico 15346@aistudio? como hago logout y verifico que redirige al login 15347 15348# Pedir steps de API 15349@aistudio? validar respuesta JSON con status 201 15350 15351# Pedir steps de formulario 15352@aistudio? como verifico que un formulario se envió correctamente 15353\`\`\` 15354 15355### Requisitos 15356 15357- **Búsqueda local (nivel 1):** funciona sin API key 15358- **Búsqueda semántica (nivel 2):** requiere Gemini configurado 15359- **Generación IA (nivel 3):** requiere Gemini configurado`}]},{id:"gherkin",title:"Gherkin / Cucumber",icon:"",topics:[{id:"gherkin-syntax",title:"Syntax Highlighting",content:`## Soporte Gherkin / Cucumber 15360 15361Haka AI Studio convierte a VS Code en un editor completo para archivos Gherkin. 15362 15363### Reconocimiento de Lenguaje 15364 15365- Los archivos \`.feature\` se identifican automáticamente como lenguaje "Gherkin" 15366- Aliases: "Gherkin", "Feature", "Cucumber" 15367- Icono de Cucumber en las tabs del editor 15368 15369### Syntax Highlighting (Gramática TextMate) 15370 15371| Elemento | Color por defecto | 15372|----------|-------------------| 15373| Feature/Scenario/Background/Rule/Examples | Rosa (#FF79C6) | 15374| Given/When/Then/And/But | Verde (#50FA7B) | 15375| Tags (@smoke, @api) | Amarillo (#F1FA8C) | 15376| Comentarios (# ...) | Gris (#6272A4) | 15377| Strings ("valor") | Blanco (#F8F8F2) | 15378| Variables (<param>) | Rojo (#FF5555) | 15379| Tablas (|) | Cyan (#00D4FF) | 15380| Doc Strings (triple comillas) | Blanco | 15381 15382### Configuración de Lenguaje 15383 15384- Comentarios de lÃnea con \`#\` 15385- Auto-cierre de \`"\`, \`'\`, \`<>\` 15386- Folding por bloques Feature/Scenario/Background`},{id:"gherkin-idiomas",title:"Idiomas Soportados",content:`## Idiomas Soportados en la Gramática 15387 15388La gramática Gherkin reconoce keywords en 5 idiomas: 15389 15390| Idioma | Feature | Scenario | Given | When | Then | And | But | 15391|--------|---------|----------|-------|------|------|-----|-----| 15392| Inglés | Feature | Scenario | Given | When | Then | And | But | 15393| Español | CaracterÃstica | Escenario | Dado/Dada | Cuando | Entonces | Y | Pero | 15394| Francés | Fonctionnalité | Scénario | Ãtant donné | Quand | Alors | Et | Mais | 15395| Portugués | Funcionalidade | Cenário | Dado | Quando | Então | E | Mas | 15396| Alemán | Funktionalität | Szenario | Angenommen | Wenn | Dann | Und | Aber | 15397 15398Todos los keywords se reconocen y colorean correctamente independientemente del idioma utilizado.`},{id:"gherkin-colores",title:"Configuración de Colores",content:`## Configuración de Colores Gherkin 15399 15400Personaliza los colores directamente desde el panel de configuración de Haka AI Studio. 15401 15402### Cómo Configurar 15403 154041. Abre el panel â pestaña **Config** 154052. Expande la sección **Cucumber / Gherkin** 154063. Ajusta los colores con los color pickers 154074. Los cambios se aplican **en tiempo real** al editor 154085. La vista previa muestra cómo se verá 15409 15410### Opciones Disponibles 15411 15412- **Colores de palabras clave**: 7 color pickers para cada tipo de elemento 15413- **Formato**: Negrita para keywords, cursiva para tags y comentarios 15414- **Vista previa en vivo**: Muestra el resultado de los colores en tiempo real
15415- **Actualización instantánea**: Los colores se aplican al editor al cambiar, sin necesidad de guardar 15416- **Botón Restablecer**: Vuelve a los colores por defecto (esquema Dracula adaptado) 15417 15418Los colores se guardan en \`editor.tokenColorCustomizations\` de VS Code y persisten entre sesiones. 15419 15420### Icono Cucumber 15421 15422Los archivos \`.feature\` muestran un icono de Cucumber/Gherkin en: 15423- Las tabs del editor (siempre visible) 15424- El explorador de archivos (activando el tema "Haka Gherkin File Icons" en File > Preferences > File Icon Theme)`}]},{id:"kai",title:"Kai (Chat IA)",icon:"",topics:[{id:"kai-descripcion",title:"¿Qué es Kai?",content:`## Chat con Kai (Asistente IA) 15425 15426Kai es tu asistente de IA especializado en testing, integrado directamente en VS Code. 15427 15428### ¿Qué puedes hacer con Kai? 15429 15430- Preguntar cómo automatizar algo especÃfico 15431- Pedir que refine un test generado 15432- Consultar sobre el framework Hakalab 15433- Pedir explicaciones del código generado 15434- Obtener sugerencias de mejoras 15435 15436### Kai conoce 15437 15438- Todos los steps del framework Hakalab (Web, API, Mobile, Desktop, GenAI) 15439- Las reglas de buenas prácticas de Gherkin 15440- Los patrones de Page Object (JSON POMs) 15441- La estructura de proyectos del framework 15442- Configuración del .env y environment.py 15443 15444### UI del Chat 15445 15446- Fuente optimizada (12.5px) para mejor legibilidad 15447- Code blocks con fuente monospace (11px) 15448- Textarea con font-size cómodo para escritura`},{id:"kai-ejemplos",title:"Ejemplos de Uso",content:`## Ejemplos de Preguntas a Kai 15449 15450### Sobre Testing 15451 15452- "¿Cómo escribo un test para un modal?" 15453- "¿Cuál es la mejor forma de validar un formulario?" 15454- "¿Cómo manejo elementos dinámicos?" 15455 15456### Sobre el Framework 15457 15458- "¿Qué steps hay disponibles para tablas?" 15459- "¿Cómo configuro las sesiones guardadas?" 15460- "¿Cómo uso variables en los identificadores?" 15461 15462### Sobre Código Generado 15463 15464- "ExplÃcame este test que se generó" 15465- "¿Cómo puedo mejorar este escenario?" 15466- "¿Por qué usa ese selector y no otro?" 15467 15468### Sobre Buenas Prácticas 15469 15470- "¿Cómo organizo mis features por módulo?" 15471- "¿Cuándo usar Scenario Outline vs múltiples Scenarios?" 15472- "¿Cómo hago para no repetir el login en cada test?" 15473 15474### Consumo 15475 15476Cada mensaje a Kai usa tokens del proveedor de IA configurado. Las respuestas tÃpicas consumen entre 500-2000 tokens de salida.`}]},{id:"rest",title:"REST y Mock Server",icon:"",topics:[{id:"rest-generador",title:"Generador REST",content:`## Generador de Pruebas REST 15477 15478Genera features Gherkin para pruebas de API REST desde especificaciones. 15479 15480### Métodos de Entrada 15481 15482- **Archivo OpenAPI/Swagger** â carga el archivo JSON/YAML de tu API 15483- **Colección Postman** â importa colecciones exportadas 15484- **cURL** â pega comandos cURL directamente 15485 15486### Lo que Genera 15487 15488- Escenarios completos con Background 15489- Casos exitosos y de error 15490- Validaciones de status code y JSON response 15491- Headers y autenticación configurados 15492 15493### Ejemplo Generado 15494 15495\`\`\`gherkin 15496@no_browser 15497Feature: API de Usuarios 15498 15499 Scenario: Obtener lista de usuarios 15500 Given configuro la API base en "https://api.ejemplo.com/v1" 15501 And configuro el token Bearer "\${ENV.API_TOKEN}" 15502 When realizo GET a "/users?page=1&limit=10" 15503 Then la respuesta deberia tener codigo "200" 15504 And la respuesta deberia ser un array JSON 15505 And el array "" de la respuesta deberia tener al menos "1" elementos 15506\`\`\``},{id:"rest-mock-server",title:"Mock Server",content:`## Mock Server Local 15507 15508Servidor HTTP integrado para simular APIs dummy antes de que estén disponibles en el ambiente real. 15509 15510### CaracterÃsticas 15511 15512- Soporta endpoints GET, POST, PUT, DELETE y PATCH 15513- Status codes personalizados 15514- Response body en JSON configurables 15515- Headers custom por endpoint 15516- Simulación de latencia (delay en ms) para probar timeouts 15517- CORS automático para consumir desde cualquier frontend 15518- Path matching con parámetros dinámicos (\`:id\`, \`{id}\`) 15519- Log en vivo de todos los requests recibidos 15520 15521### Configuración 15522 15523- Guardar/cargar configuración desde \`mock-server.json\` del proyecto 15524- Agregar endpoints desde la UI del panel 15525- Iniciar/detener el servidor con un click 15526 15527### Uso TÃpico 15528 15529\`\`\` 155301. Abrir pestaña "Rest" en el panel 155312. Ir a la sección "Mock Server" 155323. Agregar endpoints con sus respuestas 155334. Iniciar el servidor (se asigna un puerto local) 155345. Consumir desde tu frontend o tests 155356. Ver el log de requests en tiempo real 15536\`\`\``}]},{id:"sesiones",title:"Sesiones Guardadas",icon:"",topics:[{id:"sesiones-descripcion",title:"¿Qué son las Sesiones?",content:`## Sesiones Guardadas (Autologin) 15537 15538Permite reutilizar sesiones de login previamente capturadas para evitar flujos de MFA/2FA en cada ejecución. 15539 15540### ¿Para qué sirve? 15541 15542Si tu aplicación tiene: 15543- Login con MFA/2FA (código SMS, authenticator) 15544- SSO corporativo (SAML, OAuth) 15545- Firebase Auth / Auth0 15546- SAP Fiori / Salesforce Lightning 15547 15548No necesitas hacer login manualmente en cada test. Capturas la sesión una vez y la reutilizas. 15549 15550### Cómo Funciona 15551 155521. Captura una sesión con \`haka-login --save nombre --url https://tu-app.com\` 155532. Haces login manualmente (incluyendo MFA/2FA) 155543. El framework guarda el estado completo 155554. En AI Studio, seleccionas el perfil de sesión antes de grabar 155565. El navegador se abre ya autenticado 15557 15558### Datos Capturados 15559 15560- Cookies de todos los dominios (httpOnly, secure, sameSite) 15561- localStorage y sessionStorage por origen 15562- IndexedDB completa (todas las bases y stores) 15563- Detección de Service Workers 15564 15565### Compatibilidad 15566 15567| Plataforma | Soporte | 15568|-----------|---------| 15569| Firebase Auth | Si (IndexedDB + localStorage) | 15570| Auth0 | Si (cookies + localStorage) | 15571| Salesforce Lightning | Si (IndexedDB completa) | 15572| SAP Fiori | Si (cookies + IndexedDB) | 15573| SSO Corporativo | Si (cookies de sesión) | 15574| MFA/2FA | Si (sesión post-autenticación) | 15575 15576### Seguridad 15577 15578- Cifrado con Fernet (AES-128-CBC + HMAC-SHA256) 15579- Usa variable de entorno \`HAKA_SESSION_KEY\` como clave 15580- Los perfiles se almacenan cifrados localmente`}
15580]},{id:"autocompletado",title:"Autocompletado",icon:"",topics:[{id:"autocompletado-clasico",title:"Autocompletado Clásico",content:`## Autocompletado de Steps 15581 15582Al editar archivos \`.feature\`, la extensión ofrece dos sistemas de autocompletado: 15583 15584### 1. Autocompletado Clásico (tras keyword) 15585 15586- Se activa al escribir \`Given \`, \`When \`, \`Then \`, \`And \` o \`But \` 15587- Escanea \`<proyecto>/docs/ejemplos/*.feature\` 15588- Muestra steps disponibles del framework con su keyword y archivo fuente 15589- Cache de 30 segundos para rendimiento óptimo 15590 15591### 2. @aistudio (búsqueda inteligente) 15592 15593- Se activa al escribir \`@aistudio\` en cualquier parte del archivo 15594- Busca en TODO el proyecto + embeddings + IA 15595- Ver sección @aistudio para más detalles 15596 15597### Diferencias 15598 15599| CaracterÃstica | Clásico | @aistudio | 15600|---------------|---------|-----------| 15601| Trigger | Tras keyword Gherkin | \`@aistudio\` en cualquier lugar | 15602| Alcance | Solo docs/ejemplos/ | Todo el proyecto + vectores + IA | 15603| Velocidad | Instantáneo | Instantáneo (local) / 1-3s (IA) | 15604| Requiere API Key | No | Solo nivel 2 y 3 |`}]},{id:"seguridad",title:"Seguridad y Privacidad",icon:"",topics:[{id:"seguridad-datos",title:"Manejo de Datos",content:`## Seguridad y Privacidad 15605 15606### Principios 15607 15608- Sin telemetrÃa, sin rastreo, sin envÃo de datos a Haka Lab 15609- Comunicación con IA exclusivamente por HTTPS 15610- API Keys en almacenamiento cifrado de VS Code (SecretStorage) 15611- Validación de licencia por dispositivo 15612- Sesiones de login cifradas con Fernet 15613 15614### ¿Qué datos se envÃan al proveedor de IA? 15615 15616- Las acciones grabadas (selectores, textos ingresados, URLs) 15617- El contexto de steps del framework para reutilización 15618- Las preguntas que haces a Kai 15619- Queries de @aistudio? (nivel 3) 15620 15621### ¿Qué datos NO se envÃan? 15622 15623- Contraseñas reales (se recomienda usar datos ficticios) 15624- Cookies o tokens de sesión 15625- Código fuente de tu aplicación bajo prueba 15626- Información del sistema operativo 15627 15628### Almacenamiento Local 15629 15630- La API Key se guarda en el almacenamiento seguro de VS Code 15631- Las grabaciones se almacenan temporalmente en memoria 15632- Los tests generados se guardan solo cuando tú los guardas explÃcitamente 15633- Los colores Gherkin se persisten en settings de VS Code 15634 15635### Recomendaciones 15636 15637- Usa ambientes de prueba (staging, QA) para grabar, nunca producción 15638- Usa datos ficticios en formularios durante la grabación 15639- Revisa el test generado antes de guardarlo 15640- No compartas tu API Key con otros usuarios`}]},{id:"uso-avanzado",title:"Uso Avanzado",icon:"",topics:[{id:"avanzado-vectorizacion",title:"Vectorización Custom",content:`## Vectorizar Steps Personalizados 15641 15642Si tu proyecto tiene custom steps, puedes vectorizarlos para que la IA los reutilice al generar tests. 15643 15644### Desde la UI 15645 156461. Panel de Haka AI Studio â pestaña Config 156472. Expandir sección "Vectorización de Steps" 156483. Click en "Escanear y Vectorizar" 15649 15650### ¿Qué hace? 15651 156521. Escanea los archivos de steps en tu proyecto 156532. Extrae las definiciones de cada step 156543. Genera embeddings semánticos de cada paso 156554. Los almacena en la base vectorial local 15656 15657### Resultado 15658 15659La próxima vez que grabes y generes, si una acción coincide con un custom step tuyo, la IA lo usará en vez de crear uno nuevo.`},{id:"avanzado-comandos",title:"Comandos Disponibles",content:`## Comandos de VS Code 15660 15661Todos los comandos están disponibles desde la paleta (Ctrl+Shift+P): 15662 15663| Comando | Descripción | 15664|---------|-------------| 15665| Haka: Start Recording | Iniciar grabación de interacciones | 15666| Haka: Stop Recording | Detener grabación | 15667| Haka: Generate Test | Generar test con IA a partir de la grabación | 15668| Haka: Configure AI Provider | Configurar proveedor y API Key | 15669| Haka: Switch AI Provider | Cambiar de proveedor rápidamente | 15670| Haka: Vectorize Custom Steps | Vectorizar steps personalizados del proyecto | 15671| Haka: Open Chat (Kai) | Abrir el chat con el asistente Kai | 15672| Haka: Show License Info | Ver información de licencia actual | 15673| Haka: Logout | Cerrar sesión de licencia |`},{id:"avanzado-tecnologias",title:"Stack Tecnológico",content:`## TecnologÃas 15674 15675| Componente | TecnologÃa |
15676|-----------|------------| 15677| Plataforma | VS Code Extension API | 15678| Lenguaje | TypeScript | 15679| Build | Webpack | 15680| Grabación | Playwright CDP | 15681| IA | Google Gemini / OpenAI / Anthropic Claude | 15682| Vectorización | Embeddings locales (dim=768) | 15683| Syntax Highlighting | TextMate Grammar (JSON) | 15684| UI | HTML + CSS custom (Webview) | 15685| Auth | Google OAuth + API REST Hakalab | 15686| Mock Server | Node.js http module | 15687| Cifrado | Fernet (AES-128-CBC + HMAC-SHA256) |`}]},{id:"faq",title:"FAQ",icon:"",topics:[{id:"preguntas-frecuentes",title:"Preguntas Frecuentes",content:`## Preguntas Frecuentes 15688 15689### ¿Necesito saber programar para usarlo? 15690 15691No para grabar y generar. Sà para ajustar y ejecutar los tests generados. 15692 15693### ¿Funciona con cualquier aplicación web? 15694 15695SÃ, cualquier aplicación accesible desde un navegador. 15696 15697### ¿Los tests generados se pueden ejecutar directamente? 15698 15699SÃ, si estás usando el Hakalab Framework. Los .feature generados son compatibles con Behave + Playwright o Behave + Selenium. 15700 15701### ¿Necesito mi propia API key? 15702 15703SÃ. Se configura en la pestaña Config. Cada usuario usa su propia key del proveedor que elija (Gemini, OpenAI o Claude). 15704 15705### ¿Consume créditos de IA al grabar? 15706 15707No. Solo consume al presionar "Generar con IA", al chatear con Kai, o al usar @aistudio? (nivel 3). 15708 15709### ¿Se pueden vectorizar mis propios steps? 15710 15711SÃ. En Config > Vectorización de Steps, escanea y vectoriza los steps de tu proyecto. 15712 15713### ¿Cómo uso @aistudio? 15714 15715En cualquier archivo \`.feature\`, escribe \`@aistudio\` seguido de lo que buscas. Para pedir a la IA, usa \`@aistudio?\` seguido de tu pregunta. 15716 15717### ¿@aistudio busca solo en docs/ejemplos? 15718 15719No. \`@aistudio\` busca en TODO el proyecto recursivamente. El autocompletado clásico (tras keyword) sà busca solo en \`docs/ejemplos/\`. 15720 15721### ¿Los colores de Gherkin se aplican automáticamente? 15722 15723SÃ. Al instalar la extensión, los archivos \`.feature\` obtienen highlighting automáticamente. Para personalizar colores, ve a Config > Cucumber / Gherkin. 15724 15725### ¿Puedo usar @aistudio sin API key? 15726 15727La búsqueda local (nivel 1) funciona sin API key. Los niveles 2 (semántico) y 3 (IA) requieren tener Gemini configurado. 15728 15729### ¿Qué frameworks de test soporta? 15730 15731Genera tests compatibles con Haka Playwright Engine (Behave + Playwright) y Haka Selenium Engine (Behave + Selenium). 15732 15733### ¿Funciona sin internet? 15734 15735La grabación funciona sin internet. La generación con IA, el chat y @aistudio (niveles 2 y 3) requieren conexión. 15736 15737### ¿Puedo usar la extensión en más de un equipo? 15738 15739La licencia permite un dispositivo a la vez. Si cambias de equipo, cierra sesión en el anterior.`},{id:"troubleshooting",title:"Solución de Problemas",content:`## Solución de Problemas 15740 15741### La extensión no aparece en VS Code 15742 15743- Verificar versión de VS Code >= 1.85.0 15744- Reinstalar: \`code --install-extension haka-ai-studio-1.5.9.vsix\` 15745- Recargar ventana: Ctrl+Shift+P â "Developer: Reload Window" 15746 15747### Error al configurar API Key 15748 15749- Verificar que la API Key es válida y no ha expirado 15750- Verificar conexión a internet 15751- Probar con otro proveedor para descartar problemas de red 15752 15753### La grabación no captura acciones 15754 15755- Verificar que el navegador de grabación está abierto
15756- No cambiar de ventana durante la grabación 15757- Esperar a que los elementos carguen antes de interactuar 15758- Reiniciar la grabación si se pierden eventos 15759 15760### Error al generar con IA 15761 15762- Verificar que hay una grabación activa (no vacÃa) 15763- Verificar que la API Key del proveedor es válida 15764- Si el error es de timeout, la grabación puede ser muy larga â dividir en partes 15765- Cambiar a otro proveedor si uno falla consistentemente 15766 15767### Error de licencia 15768 15769- Verificar email y clave de licencia 15770- Verificar conexión a internet (necesaria para validar) 15771- Si hay firewall, verificar acceso a *.cloudfunctions.net puerto 443 15772- Si cambió de equipo, cerrar sesión en el anterior 15773 15774### El test generado no funciona 15775 15776- Verificar que los selectores son válidos (puede haber cambiado la app) 15777- Verificar que el framework Hakalab está instalado y configurado 15778- Verificar que el .env tiene las variables necesarias (BASE_URL, etc.) 15779 15780### @aistudio no muestra sugerencias 15781 15782- Verificar que estás en un archivo .feature 15783- Verificar que escribiste \`@aistudio \` (con espacio) seguido de tu búsqueda 15784- Para nivel 2 y 3, verificar que Gemini está configurado con API key válida 15785 15786### Los colores de Gherkin no se ven 15787 15788- Verificar que el archivo tiene extensión .feature 15789- Recargar VS Code (Ctrl+Shift+P â "Developer: Reload Window") 15790- Verificar que no hay otra extensión Gherkin en conflicto`},{id:"changelog",title:"Changelog",content:`## Changelog 15791 15792### v1.5.9 (16 julio 2026) 15793 15794**Nuevas CaracterÃsticas:** 15795- **@aistudio**: Asistente inteligente en archivos .feature con búsqueda local, semántica y generación con IA 15796- **Soporte Gherkin/Cucumber**: Syntax highlighting completo, icono Cucumber, soporte multiidioma 15797- **Panel de Configuración Cucumber/Gherkin**: Colores personalizables, formato, vista previa en vivo 15798- **Secciones colapsables en Config**: Todas las secciones plegables con animación suave 15799 15800**Correcciones:** 15801- Login con Google: solucionada condición de carrera en OAuth 15802- Webview JavaScript: corregido ReferenceError en inicialización 15803- UI Config Panel: corregido overflow en secciones expandidas 15804 15805### v1.4.9 (15 julio 2026) 15806 15807**Nuevas CaracterÃsticas:** 15808- **Mock Server Local**: Servidor HTTP integrado para simular APIs 15809- **Autocompletado de Steps**: IntelliSense nativo para archivos .feature 15810- **Sesiones con IndexedDB**: Captura completa incluyendo IndexedDB y sessionStorage 15811 15812**Correcciones:** 15813- Configuración de IA en tiempo real (sin reiniciar) 15814- Checkbox de términos de uso corregido 15815- Autologin de sesiones estabilizado 15816 15817### v1.4.0 (15 mayo 2026) 15818 15819- Sesiones Guardadas (perfiles cifrados con Fernet) 15820- Generador de Pruebas REST (OpenAPI/Swagger, Postman, cURL) 15821- Modo Selenium (XPath inteligente + servidor de eventos HTTP) 15822 15823### v1.0.20 (18 mayo 2025) 15824 15825- Multi-Proveedor de IA (Gemini, OpenAI, Claude) 15826- Arquitectura con BaseProvider + Factory pattern 15827- Suite de pruebas completa (75+ casos, 82% cobertura) 15828 15829### v1.0.19 (10 mayo 2025) 15830 15831- Grabación mejorada 15832- Generación con Gemini AI 15833- Chat Kai 15834- Búsqueda vectorial 15835 15836### v1.0.18 (15 abril 2025) 15837 15838- Versión inicial de Haka AI Studio`}]}];function xne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return yne.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - Haka AI Studio | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"Haka AI Studio - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:` 15839 fixed lg:sticky top-0 left-0 z-50 lg:z-10 15840 w-80 h-screen overflow-y-auto 15841 bg-darkGray border-r border-gray-800 15842 transition-transform duration-300 15843 ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"} 15844 `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"Haka AI Studio"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Manual de Usuario v1.5.9"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(vne,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function vne({content:t}){return bne(t).map((a,n)=>s.jsx(wne,{block:a},n))}function bne(t){var i;const e=[],a=t.split(` 15845`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(` 15846`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function wne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(vb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
15846case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(vb,{text:e})},a))});case"table":return s.jsx(kne,{rows:t.rows});default:return null}}function kne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(vb,{text:o})},l))},r))})]})})}function vb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const Sne=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es HakaBoost?",content:`## ¿Qué es HakaBoost? 15847 15848HakaBoost es una extensión de Chrome (Manifest V3) que potencia los flujos de trabajo de QA y testing usando IA. Funciona directamente sobre Jira Cloud y Azure DevOps desde un side panel integrado. 15849 15850## ¿Para quién es? 15851 15852| Perfil | Beneficio principal | 15853|--------|-------------------| 15854| QA Manual | Genera tests Gherkin automáticamente desde requerimientos | 15855| QA Automation | Acelera la creación de escenarios con criterios de aceptación | 15856| Product Owner | Mejora la calidad de las historias de usuario con IA | 15857| Tech Lead | Estandariza el formato de requerimientos y tests en el equipo | 15858 15859## Plataformas Soportadas 15860 15861| Plataforma | Leer descripción | Mejorar con IA | Crear Tests | Vincular | Comentar | 15862|---|---|---|---|---|---| 15863| Jira Cloud | DOM + API | Si | Test/Task | Si | Si | 15864| Azure DevOps | DOM + API | Si | Test Case | Si | Si | 15865| Xray Cloud | â | â | Cucumber | Si | â |`},{id:"instalacion",title:"Instalación",content:`## Instalación 15866 15867### Requisitos 15868 15869- Google Chrome 120+ (Manifest V3) 15870- Una cuenta en Jira Cloud o Azure DevOps 15871- Al menos un proveedor de IA configurado 15872 15873### Pasos 15874 158751. Descarga el archivo de la extensión o clona el repositorio 158762. Abre \`chrome://extensions\` â activa **Modo desarrollador** 158773. Click en **Cargar descomprimida** â selecciona la carpeta del proyecto 158784. HakaBoost aparecerá en la barra de extensiones 15879 15880### Verificación 15881 15882- Verás el Ãcono de HakaBoost en la barra de extensiones de Chrome 15883- Atajo de teclado: \`Ctrl+Shift+Y\` (Windows/Linux) / \`Cmd+Shift+Y\` (macOS) 15884- Al abrir un work item en Jira o Azure DevOps, el side panel se activa`},{id:"uso-basico",title:"Uso Básico",content:`## Uso Básico 15885 15886### Flujo Principal 15887 158881. Navega a un work item en Jira o Azure DevOps 158892. Abre HakaBoost con el Ãcono o \`Ctrl+Shift+Y\` 158903. La extensión detecta automáticamente la plataforma 158914. **Leer descripción** â carga el contenido actual del work item 158925. **Mejorar Desc.** â genera versión mejorada con IA (criterios de aceptación + Gherkin) 158936. **Actualizar Jira/Azure** â reemplaza la descripción en la plataforma 158947. **Sugerir Tests** â parsea escenarios y permite crearlos como issues 15895 15896### Detección Automática 15897
15898HakaBoost detecta automáticamente si estás en Jira Cloud o Azure DevOps y adapta su comportamiento: 15899- Los botones se ajustan a la plataforma activa 15900- Los tipos de issue/work item se configuran por plataforma 15901- Los vÃnculos se crean según la convención de cada sistema`}]},{id:"configuracion",title:"Configuración",icon:"",topics:[{id:"config-ia",title:"Proveedores de IA",content:`## Configuración de IA 15902 15903Desde el side panel â pestaña **Configuraciones** â sección IA. 15904 15905### Chrome Built-in AI (Gemini Nano) 15906 15907- 100% local, sin costo, sin enviar datos a la nube 15908- No requiere API Key 15909- Requiere Chrome 120+ con soporte de Chrome AI habilitado 15910- Limitación: inputs largos se truncan a 4000 caracteres 15911 15912### Google Gemini (Cloud) 15913 15914- Modelos disponibles: gemini-2.5-flash, gemini-2.0-flash 15915- Requiere API Key de Google AI Studio 15916- Obtener en: https://aistudio.google.com/apikey 15917- Bajo costo, rápido 15918 15919### OpenAI (Cloud) 15920 15921- Modelos disponibles: gpt-4o-mini, gpt-4o, gpt-4-turbo 15922- Requiere API Key de OpenAI 15923- Obtener en: https://platform.openai.com/api-keys 15924 15925### Prompt Personalizable 15926 15927Puedes personalizar el prompt que se envÃa a la IA para ajustar el estilo de las mejoras de descripción según tus necesidades de equipo.`},{id:"config-jira",title:"Jira Cloud",content:`## Configuración de Jira Cloud 15928 15929Desde el side panel â pestaña **Configuraciones** â sección Jira. 15930 15931### Campos Requeridos 15932 15933| Campo | Descripción | Ejemplo | 15934|-------|-------------|---------| 15935| URL base | URL de tu instancia Jira | https://tu-sitio.atlassian.net | 15936| Email | Email de tu cuenta Atlassian | [email protected] | 15937| API Token | Token de API de Atlassian | Crear en id.atlassian.com | 15938 15939### Cómo Obtener el API Token 15940 159411. Ve a https://id.atlassian.com/manage-profile/security/api-tokens 159422. Click en "Create API token" 159433. Asigna un nombre descriptivo (ej: "HakaBoost") 159444. Copia el token generado 159455. Pégalo en la configuración de HakaBoost 15946 15947### Opciones Personalizables 15948 15949- **Tipo de issue para tests**: Test (Xray) o Task (estándar) 15950- **Tipo de vÃnculo**: "Tests", "Relates to", u otro personalizado 15951- **Proyecto por defecto**: se detecta automáticamente del work item actual`},{id:"config-azure",title:"Azure DevOps",content:`## Configuración de Azure DevOps 15952 15953Desde el side panel â pestaña **Configuraciones** â sección Azure DevOps. 15954 15955### Campos Requeridos 15956 15957| Campo | Descripción | Ejemplo | 15958|-------|-------------|---------| 15959| Organización | Nombre de la organización | mi-empresa | 15960| Proyecto | Nombre del proyecto | QA-Automation | 15961| PAT | Personal Access Token | Token con permisos de Work Items | 15962 15963### Cómo Obtener el PAT 15964 159651. En Azure DevOps, click en tu avatar â "Personal Access Tokens" 159662. Click en "New Token" 159673. Nombre: "HakaBoost" 159684. Scopes: Work Items (Read & Write) 159695. Click "Create" 159706. Copia el token generado 15971 15972### Opciones Personalizables 15973 15974- **Tipo de Work Item**: Test Case (predeterminado) 15975- **Tipo de vÃnculo**: "Tested By" (predeterminado)`},{id:"config-xray",title:"Xray Cloud",content:`## Configuración de Xray Cloud (Opcional) 15976 15977Para funcionalidades avanzadas de testing con Xray en Jira. 15978 15979### Campos Requeridos 15980 15981| Campo | Descripción | 15982|-------|-------------| 15983| Client ID | ID de cliente de Xray Cloud API | 15984| Client Secret | Secret de Xray Cloud API | 15985 15986### Cómo Obtener Credenciales 15987 159881. En Jira, ve a Xray â Settings â API Keys 159892. Genera un nuevo par Client ID / Client Secret 159903. Configura ambos en HakaBoost 15991 15992### Funcionalidades con Xray 15993 15994- Crear tests de tipo Cucumber (en vez de Generic) 15995- Export directo como archivo .feature 15996- Steps de Gherkin estructurados en el Test Issue de Xray`},{id:"config-ofuscacion",title:"Ofuscación de Datos",content:`## Ofuscación de Datos Sensibles 15997 15998HakaBoost ofusca automáticamente información sensible antes de enviarla a la IA cloud. 15999 16000### Datos que se Ofuscan 16001 16002- URLs completas 16003- Emails 16004- Direcciones IP 16005- Números de teléfono 16006- RUT (Chile) 16007- UUIDs 16008 16009### Configuración 16010 16011- Toggle para activar/desactivar la ofuscación 16012- Diccionario personalizado: define palabras â reemplazos especÃficos 16013 16014### Cómo Funciona 16015 160161. Antes de enviar a la IA, se detectan patrones sensibles 160172. Se reemplazan por placeholders genéricos 160183. La IA genera la respuesta con los placeholders 160194. Se des-ofusca automáticamente al mostrar el resultado 16020 16021### Nota 16022 16023La ofuscación no aplica a Chrome Built-in AI (Gemini Nano) ya que procesa todo localmente sin enviar datos a la nube.`}]},{id:"copiloto",title:"Copiloto de Descripción",icon:"",topics:[{id:"copiloto-mejorar",title:"Mejorar Descripción",content:`## Copiloto de Descripción 16024 16025### ¿Qué Hace? 16026 16027Lee la descripción actual de un work item (historia de usuario, bug, task) y genera una versión mejorada que incluye: 16028 16029- Descripción estructurada y clara 16030- Criterios de aceptación explÃcitos 16031- Escenarios Gherkin (Given/When/Then) 16032- Precondiciones identificadas 16033- Datos de ejemplo cuando aplica 16034 16035### Flujo 16036 160371. **Leer Descripción**: Extrae el texto del work item actual (DOM o API REST) 160382. **Mejorar Desc.**: EnvÃa a la IA con el prompt configurado 160393. **Vista previa**: Muestra el resultado mejorado para revisión
160404. **Actualizar**: Reemplaza la descripción en Jira o Azure DevOps vÃa API 16041 16042### Ejemplo 16043 16044**Antes (descripción original):** 16045\`\`\` 16046Como usuario quiero poder recuperar mi contraseña 16047\`\`\` 16048 16049**Después (mejorada por IA):** 16050\`\`\` 16051## Descripción 16052Como usuario registrado, quiero poder recuperar mi contraseña olvidada 16053para poder acceder nuevamente a mi cuenta sin contactar a soporte. 16054 16055## Criterios de Aceptación 16056- El usuario puede solicitar recuperación desde la pantalla de login 16057- Se envÃa un email con link de recuperación válido por 24 horas 16058- El link permite establecer una nueva contraseña 16059- La nueva contraseña debe cumplir las polÃticas de seguridad 16060 16061## Escenarios 16062 16063Scenario: Solicitar recuperación con email válido 16064 Given estoy en la pantalla de login 16065 When hago click en "Olvidé mi contraseña" 16066 And ingreso mi email registrado "[email protected]" 16067 And hago click en "Enviar" 16068 Then deberÃa ver el mensaje "Te enviamos un email de recuperación" 16069 And deberÃa recibir un email con el link de recuperación 16070\`\`\``},{id:"copiloto-crear-tests",title:"Crear Tests",content:`## Creación de Tests 16071 16072### ¿Qué Hace? 16073 16074Parsea los escenarios Gherkin de la descripción mejorada y crea issues/work items de tipo Test en la plataforma, vinculándolos automáticamente al work item principal. 16075 16076### Flujo 16077 160781. **Sugerir Tests**: Parsea los escenarios Gherkin de la descripción 160792. **Seleccionar**: Elige cuáles escenarios crear como tests 160803. **Crear**: Crea los issues en la plataforma con los steps Gherkin 160814. **Vincular**: Vincula automáticamente cada test al work item original 16082 16083### En Jira Cloud 16084 16085- Crea issues de tipo Test (si usas Xray) o Task 16086- Vincula con el tipo de link configurado (ej: "Tests", "Relates to") 16087- Si usa Xray: crea como Cucumber Test con steps estructurados 16088 16089### En Azure DevOps 16090 16091- Crea Work Items de tipo Test Case 16092- Vincula con "Tested By" al work item principal 16093- Los steps se agregan como Test Steps del Test Case 16094 16095### Exportación 16096 16097- Export como archivo \`.feature\` (Cucumber) 16098- Export como Excel con los escenarios tabulados`}]},{id:"funciones-pro",title:"Funciones Pro",icon:"",topics:[{id:"pro-analisis",title:"Análisis de IA",content:`## Análisis de IA (Pro) 16099 16100Genera un reporte de calidad del work item con recomendaciones, riesgos y precondiciones. 16101 16102### ¿Qué Incluye? 16103 16104- **Recomendaciones**: Mejoras sugeridas para el requerimiento 16105- **Riesgos identificados**: Posibles problemas de implementación o testing 16106- **Precondiciones**: Condiciones necesarias antes de ejecutar los tests 16107- **Puntos de atención**: Ãreas que requieren validación extra 16108 16109### Opciones 16110 16111- **Publicar como comentario**: Agrega el análisis como comentario en el work item 16112- **Exportar a PDF**: Descarga el reporte como documento PDF 16113 16114### Presentación 16115 16116El análisis se presenta en formato de cards verticales con categorización visual por tipo (recomendación, riesgo, precondición).`},{id:"pro-datos-prueba",title:"Datos de Prueba",content:`## Datos de Prueba (Pro) 16117 16118Sugiere datos concretos para cada escenario: valores válidos, inválidos, lÃmite y edge cases. 16119 16120### ¿Qué Genera? 16121 16122Para cada escenario Gherkin detectado, sugiere: 16123 16124- **Datos válidos**: valores correctos que deben funcionar 16125- **Datos inválidos**: valores que deben ser rechazados 16126- **Datos lÃmite**: valores en los extremos permitidos 16127- **Edge cases**: situaciones atÃpicas o combinaciones especiales 16128 16129### Presentación Visual 16130 16131- Cards por escenario con badges de clasificación 16132- Colores por tipo: verde (válido), rojo (inválido), amarillo (lÃmite), naranja (edge) 16133 16134### Scenario Outline 16135 16136Los datos sugeridos se pueden transformar automáticamente en: 16137- **Scenario Outline** con tabla de Examples 16138- Formato listo para copiar al .feature 16139 16140### Ejemplo 16141 16142\`\`\`gherkin 16143Scenario Outline: Validar campo email 16144 When ingreso "<email>" en el campo de email 16145 Then deberÃa ver "<resultado>" 16146 16147 Examples: 16148 | email | resultado | tipo | 16149 | [email protected] | Ãxito | válido | 16150 | [email protected] | Ãxito | lÃmite | 16151 | | Error: campo requerido | inválido | 16152 | usuario@@empresa.com | Error: formato inválido | inválido | 16153 | [email protected] | Ãxito | edge case | 16154\`\`\``},{id:"pro-cobertura",title:"Análisis de Cobertura",content:`## Análisis de Cobertura (Pro) 16155 16156Compara los escenarios generados contra la descripción original para
16156identificar brechas de cobertura. 16157 16158### ¿Qué Hace? 16159 161601. Toma la descripción original del work item 161612. Toma los escenarios Gherkin generados 161623. Compara usando IA para detectar gaps 161634. Sugiere escenarios faltantes 16164 16165### Resultado 16166 16167- **Cobertura actual**: Porcentaje estimado de cobertura de los requisitos 16168- **Gaps identificados**: Requisitos o criterios sin escenarios asociados 16169- **Sugerencias**: TÃtulos concretos de escenarios adicionales necesarios 16170 16171### Ejemplo de Gap 16172 16173\`\`\` 16174Gap detectado: "El criterio de expiración del link en 24 horas 16175no tiene escenario de validación" 16176 16177Sugerencia: "Scenario: Verificar que link de recuperación expira después de 24 horas" 16178\`\`\``}]},{id:"planes",title:"Planes y Cuenta",icon:"",topics:[{id:"planes-free-pro",title:"Free vs Pro",content:`## Planes 16179 16180### Plan Free 16181 16182- Registro sin contraseña (nombre, email, empresa) 16183- Acceso al Copiloto de Descripción (mejorar + crear tests) 16184- Proveedores de IA: Chrome Built-in AI, Gemini, OpenAI 16185- Sin lÃmite de uso del copiloto base 16186 16187### Plan Pro 16188 16189- Login con email/contraseña o Google 16190- Todo lo de Free + 16191- Análisis de IA (reporte de calidad) 16192- Datos de Prueba (sugerencias con clasificación) 16193- Análisis de Cobertura (detección de gaps) 16194- Exportación a PDF 16195- Publicación como comentario 16196 16197### Clientes de Haka Lab 16198 16199Los clientes de Haka Lab tienen acceso gratuito al plan Pro iniciando sesión con su cuenta de Google corporativa (dominio configurado).`},{id:"planes-autenticacion",title:"Autenticación",content:`## Autenticación 16200 16201### Registro Free 16202 162031. Click en "Registrarse" en el panel de HakaBoost 162042. Ingresa: nombre, email, empresa 162053. No requiere contraseña 162064. Acceso inmediato al copiloto base 16207 16208### Login Pro 16209 162101. Click en "Iniciar Sesión" 162112. Opciones: 16212 - Email + Contraseña 16213 - Google (para dominios configurados) 162143. Verificación server-side del plan 16215 16216### Recuperación de Contraseña 16217 162181. Click en "Olvidé mi contraseña" 162192. Ingresa tu email 162203. Recibirás un link para restablecer 16221 16222### Sesión Concurrente 16223 16224- Solo un dispositivo activo por cuenta 16225- Si se detecta sesión en otro dispositivo, se notifica al usuario 16226- Puedes cerrar la sesión remota y continuar en el dispositivo actual`}]},{id:"privacidad",title:"Privacidad",icon:"",topics:[{id:"privacidad-datos",title:"Manejo de Datos",content:`## Privacidad y Seguridad 16227 16228### Almacenamiento 16229 16230- Todos los datos de configuración se guardan localmente en \`chrome.storage.sync\` 16231- Los tokens y API keys nunca se envÃan a servidores propios de Haka Lab 16232- La autenticación usa Firebase Auth (REST API directa, sin SDK) 16233 16234### IA Cloud (OpenAI / Gemini) 16235 16236Cuando usas proveedores cloud: 16237- Las descripciones se envÃan a los proveedores según sus términos de servicio 16238- La ofuscación automática protege datos sensibles antes del envÃo 16239- Puedes usar Chrome Built-in AI (Gemini Nano) para procesamiento 100% local 16240 16241### Chrome Built-in AI 16242 16243- Procesamiento completamente local en tu dispositivo 16244- Ningún dato sale de tu computador 16245- No requiere internet para funcionar (después de la descarga inicial del modelo) 16246 16247### Firebase 16248 16249- Solo se usa para autenticación (login/registro) 16250- Se almacenan: email, nombre, empresa, plan 16251- No se almacenan descripciones, tests ni contenido de work items`}]}];function _ne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return Sne.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - HakaBoost | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"HakaBoost - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:` 16252 fixed lg:sticky top-0 left-0 z-50 lg:z-10 16253 w-80 h-screen overflow-y-auto 16254 bg-darkGray border-r border-gray-800 16255 transition-transform duration-300 16256 ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"} 16257 `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"HakaBoost"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Copiloto de Calidad v3.0"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(Ane,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function Ane({content:t}){return Ene(t).map((a,n)=>s.jsx(Cne,{block:a},n))}function Ene(t){var i;const e=[],a=t.split(` 16258`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(` 16259`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function Cne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(bb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
16259case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(bb,{text:e})},a))});case"table":return s.jsx(jne,{rows:t.rows});default:return null}}function jne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(bb,{text:o})},l))},r))})]})})}function bb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const Tne=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es HakaBuddy?",content:`## ¿Qué es HakaBuddy? 16260 16261HakaBuddy es una herramienta de escritorio para equipos de QA que centraliza la gestión, ejecución y documentación de pruebas de softw
16261are â tanto manuales como automatizadas con Playwright. 16262 16263Permite registrar pruebas paso a paso con evidencia visual, grabar y ejecutar scripts de automatización, generar reportes profesionales en PDF y HTML, y publicar suites de regresión en GitHub, GitLab o Bitbucket para ejecutarlas en CI/CD. 16264 16265## ¿Para quién es? 16266 16267| Perfil | Beneficio principal | 16268|--------|-------------------| 16269| QA Manual | Registro de pruebas con evidencia visual y reportes PDF profesionales | 16270| QA Automation | Grabación y ejecución de scripts Playwright sin escribir código | 16271| QA Lead | Gestión de suites de regresión y trazabilidad completa | 16272| Equipos ágiles | Integración con Jira, Xray, CI/CD y reportes exportables | 16273 16274## Plataformas 16275 16276- Windows (.exe) 16277- macOS (.app / .dmg) â Intel y Apple Silicon 16278- Linux (ejecutable) 16279 16280## TecnologÃas 16281 16282- Python 3.12+ con PyQt6 (interfaz gráfica) 16283- Playwright (automatización de navegador) 16284- SQLite (base de datos local) 16285- Multi-proveedor IA (Gemini, OpenAI, Claude, Ollama)`},{id:"instalacion",title:"Instalación",content:`## Instalación 16286 16287### Windows 16288 162891. Descarga \`Hakabuddy.exe\` 162902. Ejecuta el instalador 162913. La aplicación se instala y crea un acceso directo 16292 16293### macOS 16294 162951. Descarga \`Hakabuddy.dmg\` 162962. Abre el DMG y arrastra Hakabuddy a Aplicaciones 162973. La primera vez, macOS puede pedir permisos de: 16298 - Captura de pantalla (para evidencias) 16299 - Accesibilidad (para grabación) 16300 16301**Nota:** Compilar en el mismo tipo de arquitectura donde se va a usar (Intel â Intel, Apple Silicon â Apple Silicon). 16302 16303### Linux (Manjaro/Arch) 16304 16305\`\`\`bash 16306sudo pacman -S python python-pip qt6-base qt6-svg 16307./Hakabuddy 16308\`\`\` 16309 16310Si usas Wayland y hay problemas gráficos: \`export QT_QPA_PLATFORM=xcb\` 16311 16312### Datos del Usuario 16313 16314Los datos se guardan automáticamente en: 16315- **Windows**: \`C:\\Users\\{usuario}\\AppData\\Local\\Hakabuddy\\data\\\` 16316- **macOS**: \`~/Library/Application Support/Hakabuddy/data/\` 16317- **Linux**: \`~/.local/share/Hakabuddy/data/\` 16318 16319Incluye: base de datos SQLite, configuración, scripts grabados, capturas y reportes. Los datos persisten entre actualizaciones del ejecutable.`},{id:"login",title:"Login y Sesión",content:`## Login y Sesión 16320 16321### Opciones de Acceso 16322 16323| Método | Descripción | 16324|--------|-------------| 16325| Google OAuth2 | Login con cuenta de Google (recomendado para equipos) | 16326| Email/Contraseña | Login con Firebase Auth | 16327| Modo Invitado | Pruebas manuales sin cuenta (funcionalidad limitada) | 16328 16329### Sesión Persistente 16330 16331- La sesión se mantiene entre ejecuciones de la aplicación 16332- No necesitas hacer login cada vez que abres HakaBuddy 16333- El refresh token se almacena localmente de forma segura 16334- Si pierdes la sesión, simplemente vuelve a hacer login 16335 16336### Modo Invitado 16337 16338Permite usar las funcionalidades básicas de pruebas manuales sin necesidad de crear cuenta. No tiene acceso a: 16339- Integraciones (Jira, Git) 16340- Funcionalidades Pro 16341- Historial persistente`}]},{id:"configuracion",title:"Configuracion",icon:"",topics:[{id:"config-productos",title:"Productos y Ambientes",content:`## Productos y Ambientes 16342 16343### Productos 16344 16345Configura los productos que tu equipo testea. Cada prueba se asocia a un producto para organizar el historial. 16346 16347- Agregar/editar/eliminar productos 16348- Nombre del producto visible en reportes 16349- Filtrar historial por producto 16350 16351### Ambientes 16352 16353Define los ambientes disponibles para tus pruebas: 16354- Desarrollo 16355- QA 16356- Staging 16357- Producción 16358- Custom (cualquier nombre) 16359 16360### Células / Equipos 16361 16362Organiza las pruebas por células o equipos de trabajo. Ãtil para equipos grandes con múltiples QAs.`},{id:"config-ia",title:"Inteligencia Artificial",content:`## Configuración de IA 16363 16364### Proveedores Soportados 16365 16366| Proveedor | Tipo | Modelos | 16367|-----------|------|---------| 16368| Google Gemini | Cloud | gemini-2.0-flash, gemini-pro | 16369| OpenAI | Cloud | gpt-4o, gpt-4o-mini | 16370| Claude (Anthropic) | Cloud | claude-3-7-sonnet | 16371| Ollama | Local | llama3, mistral, codestral, cualquier modelo local | 16372 16373### Configurar Proveedor Cloud 16374 163751. Ir a Configuraciones â IA 163762. Seleccionar proveedor 163773. Ingresar API Key 163784. Seleccionar modelo 16379 16380### Configurar Ollama (Local) 16381 163821. Instalar Ollama (\`https://ollama.ai\`) 163832. Descargar modelo: \`ollama pull llama3\` 163843. En HakaBuddy: seleccionar "Ollama" como proveedor 163854. URL del servidor: \`http://localhost:11434\` (por defecto) 163865. Seleccionar modelo disponible 16387 16388**Ventaja de Ollama:** 100% local, sin costo de API, sin enviar datos a la nube, funciona sin internet.`},{id:"config-jira",title:"Jira y Xray",content:`## Configuración de Jira 16389 16390### Campos Requeridos 16391 16392| Campo | Ejemplo | 16393|-------|---------| 16394| URL base | https://tu-sitio.atlassian.net | 16395| Email | [email protected] | 16396| API Token | Token de Atlassian | 16397 16398### Cómo Obtener el API Token 16399 164001. Ve a https://id.atlassian.com/manage-profile/security/api-tokens 164012. "Create API token" â Nombre: "HakaBuddy" 164023. Copia el token y pégalo en HakaBuddy 16403 16404### Configuración de Xray (opcional) 16405 16406| Campo | Descripción | 16407|-------|-------------| 16408| Client ID | ID de Xray Cloud API | 16409| Client Secret | Secret de Xray Cloud API | 16410 16411Obtener en: Jira â Xray â Settings â API Keys`},{id:"config-reportes",title:"Reportes",content:`## Configuración de Reportes 16412 16413### PDF 16414 16415- **Logo**: Imagen PNG/JPG del equipo o empresa (aparece en portada) 16416- **Plantilla de portada**: Personalizable 16417- **Datos de pie de página**: Nombre de empresa, contacto 16418- **Formato de fecha**: Configurable 16419 16420### HTML 16421 16422- Logo embebido en base64 16423- TÃtulo del reporte personalizable 16424- Tema oscuro por defecto 16425 16426### Plantillas 16427 16428HakaBuddy incluye plantillas PDF profesionales por defecto. La portada, contraportada y formato de pasos se pueden personalizar.`},{id:"config-git",title:"Git / CI-CD",content:`## Configuración Git 16429 16430### Plataformas Soportadas 16431 16432| Plataforma | Token requerido | 16433|------------|----------------| 16434| GitHub | Personal Access Token (PAT) | 16435| GitLab | Personal Access Token | 16436| Bitbucket | App Password | 16437 16438### Configurar 16439 164401. Ir a Configuraciones â Git/CI-CD 164412. Seleccionar plataforma 164423. Ingresar token de acceso 164434. Seleccionar repositorio destino 164445. Configurar rama (por defecto: main)`}]},{id:"pruebas-manuales",title:"Pruebas Manuales",icon:"",topics:[{id:"manual-flujo",title:"Flujo Completo",content:`## Flujo de Pruebas Manuales 16445 16446### Paso 1: Iniciar Prueba 16447 164481. Selecciona producto y ambiente 164492. Ingresa el tÃtulo del caso de prueba 164503. (Opcional) Asocia una issue de Jira 164514. Click en "Iniciar Prueba" 16452 16453### Paso 2: Registrar Pasos 16454 16455Para cada paso de la prueba: 164561. Ingresa el tÃtulo/descripción de la acción 164572. Ejecuta la acción en la aplicación bajo prueba 164583. Captura evidencia (screenshot)
164594. Marca el estado: Exitoso o Fallido 164605. (Opcional) Agrega observaciones 16461 16462### Paso 3: Finalizar 16463 164641. Click en "Finalizar Prueba" 164652. Selecciona formato de reporte (PDF, HTML, o ambos) 164663. El reporte se genera automáticamente con toda la evidencia 164674. (Opcional) Exportar a Xray JSON 16468 16469### Funcionalidades Durante la Ejecución 16470 16471- Editar pasos previos sin perder el progreso 16472- Agregar observaciones a cualquier paso 16473- Adjuntar archivos adicionales (JSON, PDF) 16474- Activar/desactivar grabación de video 16475- Usar IA para generar descripciones de pasos`},{id:"manual-capturas",title:"Tipos de Captura",content:`## Tipos de Captura de Evidencia 16476 16477### Pantalla Completa 16478 16479Captura todo el contenido visible del monitor principal. Ideal para mostrar el contexto completo de la acción. 16480 16481### Ãrea Seleccionada 16482 16483Permite recortar una región especÃfica de la pantalla: 164841. Click en "Capturar Ãrea" 164852. Arrastra para seleccionar la zona 164863. Solo se guarda la región seleccionada 16487 16488Ideal para: campos especÃficos, mensajes de error, tooltips. 16489 16490### Con Temporizador 16491 16492Captura después de un delay configurable: 16493- 3 segundos 16494- 5 segundos 16495- 10 segundos 16496 16497Ãtil para: menús desplegables, tooltips que desaparecen, animaciones. 16498 16499### Editor de Imagen 16500 16501Después de capturar, puedes editar la imagen: 16502- Resaltar áreas (rectángulos de color) 16503- Agregar flechas indicativas 16504- Añadir texto/anotaciones 16505- Difuminar información sensible`},{id:"manual-video",title:"Grabación de Video",content:`## Grabación de Video 16506 16507### Activar Grabación 16508 165091. Al iniciar una prueba, activa el toggle de "Grabar Video" 165102. Se captura todo lo que ocurre en pantalla durante la prueba 165113. Al finalizar, el video se adjunta al reporte 16512 16513### Configuración 16514 16515- Formato: MP4 16516- FPS configurable 16517- Se almacena junto con las evidencias del test 16518 16519### Casos de Uso 16520 16521- Pruebas exploratorias donde necesitas mostrar el flujo completo 16522- Bugs difÃciles de reproducir (el video muestra exactamente qué pasó) 16523- Demostraciones para stakeholders o desarrolladores 16524- Evidencia de timing (animaciones, transiciones, cargas)`},{id:"manual-anexos",title:"Anexos y Adjuntos",content:`## Anexos y Adjuntos 16525 16526### Tipos de Anexos Soportados 16527 16528- **JSON**: Respuestas de API, configuraciones, payloads 16529- **PDF**: Documentos de referencia, especificaciones 16530- **Archivos de texto**: Logs, outputs de consola 16531 16532### Cómo Adjuntar 16533 165341. Durante la ejecución de la prueba, click en "Adjuntar" 165352. Selecciona el archivo desde tu sistema 165363. El anexo se incluye en el reporte final con portada separada 16537 16538### En el Reporte PDF 16539 16540Los anexos aparecen en una sección dedicada con: 16541- Portada de anexos separada 16542- Cada archivo con su nombre y tipo 16543- Contenido embebido o referenciado`}]},{id:"pruebas-automatizadas",title:"Pruebas Automatizadas",icon:"",topics:[{id:"auto-grabar",title:"Grabar Scripts",content:`## Grabación de Scripts Playwright 16544 16545### Cómo Grabar 16546 165471. Ve a la pestaña "Playwright" en HakaBuddy 165482. Click en "Nueva Grabación" 165493. Configura las opciones del navegador 165504. Ingresa la URL inicial 165515. Se abre el navegador â interactúa normalmente 165526. Al cerrar el navegador, el script se guarda automáticamente 16553 16554### Opciones del Navegador 16555 16556| Opción | Descripción | Ejemplo | 16557|--------|-------------|---------| 16558| Navegador | Motor del browser | Chromium, Chrome, Edge | 16559| Viewport | Resolución de pantalla | 1920x1080 | 16560| User-Agent | Agente personalizado | Mozilla/5.0... | 16561| Headers | Headers HTTP custom | Authorization, X-Custom | 16562| Locale | Idioma del navegador | es-CL, en-US | 16563| Timezone | Zona horaria | America/Santiago | 16564| Slow Motion | Delay entre acciones | 100ms | 16565 16566### Con Sesión Autenticada 16567 16568Si necesitas grabar en un sitio con login/2FA: 165691. Primero captura una sesión (ver sección Sesiones Autenticadas) 165702. Al grabar, selecciona la sesión guardada 165713. El navegador se abre ya autenticado 165724. Graba las acciones post-login 16573 16574### Resultado 16575 16576La grabación genera un script Python compatible con Playwright que se almacena en la base de datos local de HakaBuddy. Puedes editarlo, ejecutarlo o incluirlo en una suite.`},{id:"auto-ejecutar",title:"Ejecutar Scripts",content:`## Ejecución de Scripts 16577 16578### Script Individual 16579 165801. Selecciona un script grabado de la lista 165812. Click en "Ejecutar" 165823. El navegador se abre y ejecuta las acciones grabadas 165834. Cada paso se captura con screenshot automático 165845. Al finalizar se muestra el resultado (passed/failed) 16585 16586### Lo que Ocurre Durante la Ejecución 16587 16588- Se captura screenshot en cada paso 16589- Se registra el tiempo de cada acción 16590- Se detecta automáticamente si el paso fue exitoso o falló 16591- Si falla, se captura el error y el estado de la pantalla 16592- Al finalizar se genera un reporte con toda la evidencia 16593 16594### Modos de Ejecución 16595 16596| Modo | Descripción | Uso | 16597|------|-------------|-----| 16598| Visible (headed) | Ves el navegador ejecutar | Debugging, demos | 16599| Invisible (headless) | Sin interfaz gráfica | CI/CD, ejecución masiva | 16600 16601### Con Sesión Autenticada 16602 16603Selecciona una sesión guardada al ejecutar para que el navegador inicie ya logueado en el sistema bajo prueba.`},{id:"auto-outline",title:"Scenario Outline (Datos)",content:`## Scenario Outline â Ejecución con Múlt
16603iples Datos 16604 16605### ¿Qué es? 16606 16607Permite ejecutar un mismo script con diferentes conjuntos de datos automáticamente. HakaBuddy detecta los valores parametrizables del script y te permite definir una tabla de datos. 16608 16609### Cómo Funciona 16610 166111. Selecciona un script grabado 166122. HakaBuddy analiza el script y detecta valores que pueden ser variables (textos ingresados, URLs, etc.) 166133. Defines una tabla de datos con diferentes combinaciones 166144. El script se ejecuta N veces, una por cada fila de datos 166155. Se genera un reporte consolidado 16616 16617### Ejemplo 16618 16619Si tu script graba un login: 16620\`\`\` 16621Paso 1: Ir a https://app.com/login 16622Paso 2: Escribir "[email protected]" en campo email 16623Paso 3: Escribir "password123" en campo password 16624Paso 4: Click en "Ingresar" 16625\`\`\` 16626 16627Puedes parametrizar: 16628| email | password | resultado_esperado | 16629|-------|----------|-------------------| 16630| [email protected] | password123 | Dashboard | 16631| [email protected] | user456 | Home | 16632| [email protected] | wrong | Error de login | 16633 16634El script se ejecuta 3 veces con diferentes datos.`},{id:"auto-editar",title:"Editar Scripts",content:`## Edición de Scripts 16635 16636### Editor Integrado 16637 16638HakaBuddy permite editar los scripts grabados directamente desde la aplicación: 16639 16640- Ver y modificar cada paso del script 16641- Cambiar selectores si la app cambió 16642- Agregar o quitar pasos 16643- Modificar textos y valores 16644- Reordenar pasos 16645 16646### Análisis de Script con IA 16647 16648La IA puede analizar tu script y sugerir: 16649- Mejores selectores (más robustos) 16650- Pasos de validación faltantes 16651- Optimizaciones de flujo 16652- Esperas implÃcitas recomendadas`}]},{id:"suites",title:"Suites de Regresion",icon:"",topics:[{id:"suites-crear",title:"Crear Suites",content:`## Crear una Suite de Regresión 16653 16654### ¿Qué es una Suite? 16655 16656Una suite agrupa múltiples scripts de automatización para ejecutarlos en secuencia como una prueba de regresión completa. 16657 16658### Crear una Suite 16659 166601. Ve a la sección de Suites 166612. Click en "Nueva Suite" 166623. Asigna un nombre descriptivo 166634. Agrega scripts arrastrándolos o seleccionándolos de la lista 166645. Configura el orden de ejecución (drag & drop) 16665 16666### Organización 16667 16668- Cada suite tiene un nombre y descripción 16669- Los scripts se ejecutan en el orden configurado 16670- Puedes agregar/quitar scripts en cualquier momento 16671- Un script puede estar en múltiples suites`},{id:"suites-ejecutar",title:"Ejecutar Suites",content:`## Ejecución de Suites 16672 16673### Flujo 16674 166751. Selecciona la suite a ejecutar 166762. Click en "Ejecutar Suite" 166773. Los scripts se ejecutan en orden secuencial 166784. Progreso en tiempo real (barra de progreso por script) 166795. Al finalizar: reporte consolidado 16680 16681### Durante la Ejecución 16682 16683- Barra de progreso general (scripts completados / total) 16684- Estado de cada script (en espera, ejecutando, passed, failed) 16685- Tiempo transcurrido 16686- Opción de cancelar la ejecución 16687 16688### Resultado 16689 16690Al finalizar la suite se genera: 16691- Reporte HTML consolidado con todos los scripts 16692- Resumen: scripts passed / failed / total 16693- Duración total y por script 16694- Evidencias de cada paso de cada script 16695 16696### Historial 16697 16698Cada ejecución de suite se registra con: 16699- Fecha y hora 16700- Duración total 16701- Scripts passed / failed 16702- Reporte descargable`}]},{id:"cicd",title:"Integracion CI/CD",icon:"",topics:[{id:"cicd-push",title:"Push a Repositorio",content:`## Push de Suites a CI/CD 16703 16704### Plataformas Soportadas 16705 16706| Plataforma | Workflow generado | 16707|------------|-----------------| 16708| GitHub | GitHub Actions (.github/workflows/) | 16709| GitLab | GitLab CI (.gitlab-ci.yml) | 16710| Bitbucket | Bitbucket Pipelines (bitbucket-pipelines.yml) | 16711 16712### Flujo 16713 167141. Configura las credenciales Git (token de acceso) 167152. Selecciona la suite a publicar 167163. Click en "Push a CI/CD" 167174. HakaBuddy genera automáticamente: 16718 - Los scripts de la suite como archivos .py 16719 - El workflow de CI/CD según la plataforma 16720 - El runner que ejecuta los scripts en headless 16721 - El requirements.txt con las dependencias 16722 - Configuración de artefactos (reportes como descargables) 167235. Push al repositorio seleccionado 16724 16725### Lo que se Genera 16726 16727\`\`\` 16728repo/ 16729âââ .github/workflows/regression.yml # (o .gitlab-ci.yml) 16730âââ scripts/ 16731â âââ script_login.py 16732â âââ script_checkout.py 16733â âââ script_search.py 16734âââ runner.py # Ejecutor de la suite 16735âââ requirements.txt # playwright, etc. 16736âââ README.md # Instrucciones 16737\`\`\``},{id:"cicd-workflow",title:"Workflow Generado",content:`## Workflow Generado 16738 16739### GitHub Actions (ejemplo) 16740 16741\`\`\`yaml 16742name: Regression Suite 16743on: 16744 workflow_dispatch: 16745 schedule: 16746 - cron: '0 8 * * 1-5' # Lunes a viernes 8am 16747 16748jobs: 16749 test: 16750 runs-on: ubuntu-latest 16751 steps: 16752 - uses: actions/checkout@v4 16753 - uses: actions/setup-python@v5 16754 with: 16755 python-version: '3.11' 16756 - name: Install dependencies 16757 run: | 16758 pip install -r requirements.txt 16759 playwright install chromium 16760 playwright install-deps 16761 - name: Run regression 16762 run: python runner.py 16763 - name: Upload report 16764 if: always() 16765 uses: actions/upload-artifact@v4 16766 with: 16767 name: regression-report 16768 path: reports/ 16769\`\`\` 16770
16771### CaracterÃsticas del Workflow 16772 16773- Instalación automática de Python + Playwright 16774- Ejecución en modo headless 16775- Reporte HTML como artefacto descargable 16776- Configurable: schedule, trigger manual, o en cada push 16777- Notificación del resultado (passed/failed)`},{id:"cicd-runner",title:"Runner Template",content:`## Runner de CI/CD 16778 16779El runner es un script Python que HakaBuddy genera automáticamente. Ejecuta todos los scripts de la suite en orden y genera el reporte. 16780 16781### Qué Hace 16782 167831. Lee la configuración de la suite 167842. Ejecuta cada script en orden secuencial 167853. Captura screenshots en cada paso 167864. Detecta passed/failed por script 167875. Genera reporte HTML consolidado 167886. Retorna exit code 0 (todo passed) o 1 (alguno failed) 16789 16790### Personalización 16791 16792El runner se puede editar para: 16793- Cambiar el orden de ejecución 16794- Agregar setup/teardown global 16795- Configurar variables de entorno 16796- Ajustar timeouts 16797- Agregar notificaciones (Slack, email, etc.)`}]},{id:"reportes",title:"Reportes",icon:"",topics:[{id:"reportes-pdf",title:"Reporte PDF",content:`## Reporte PDF Profesional 16798 16799### Estructura del PDF 16800 168011. **Portada**: Logo, tÃtulo del test, fecha, tester, producto, ambiente 168022. **Contenido**: Cada paso con tÃtulo, estado (color verde/rojo), evidencia screenshot y observaciones 168033. **Portada de Anexos**: Separador visual si hay archivos adjuntos 168044. **Anexos**: Contenido de archivos JSON, PDFs adjuntados 168055. **Contraportada**: Logo y datos de la empresa/equipo 16806 16807### Personalización 16808 16809- Logo del equipo/empresa configurable 16810- Plantilla de portada personalizable 16811- Colores según estado (verde = exitoso, rojo = fallido) 16812- Formato de fecha y metadata configurables 16813- Fuente profesional (Calibri) incluida 16814 16815### Generación 16816 16817Al finalizar cualquier prueba (manual o automatizada): 168181. Click en "Generar PDF" 168192. Se genera automáticamente con toda la evidencia 168203. Se guarda en la carpeta de reportes del test 168214. Se puede abrir, compartir o enviar por email`},{id:"reportes-html",title:"Reporte HTML",content:`## Reporte HTML 16822 16823### CaracterÃsticas 16824 16825- **Autocontenido**: Un solo archivo .html con todo embebido 16826- **Tema oscuro**: Diseño profesional con tema dark 16827- **Logos en base64**: No requiere carpeta de imágenes externa 16828- **Pasos expandibles**: Click para expandir/colapsar cada paso 16829- **Evidencias embebidas**: Screenshots en base64 (no requiere archivos externos) 16830- **Portable**: Se puede enviar por email o compartir sin dependencias 16831 16832### Ideal Para 16833 16834- Compartir resultados por email (un solo archivo adjunto) 16835- Publicar como artefacto en CI/CD 16836- Archivar con todas las evidencias autocontenidas 16837- Visualizar en cualquier navegador sin configuración`},{id:"reportes-xray",title:"Exportación Xray",content:`## Exportación Xray JSON 16838 16839### ¿Qué es? 16840 16841Exporta los resultados de prueba en formato JSON compatible con Jira Xray para importarlos directamente como Test Executions. 16842 16843### Estructura del JSON 16844 16845- Test Key (issue asociada en Jira) 16846- Status (PASS/FAIL) 16847- Steps con detalle y evidencia 16848- Metadata (fecha, tester, ambiente, duración) 16849- Evidencias adjuntas (screenshots) 16850 16851### Flujo 16852 168531. Al configurar la prueba, asocia una issue de Jira 168542. Ejecuta la prueba normalmente 168553. Al finalizar, click en "Exportar Xray" 168564. Se genera el JSON listo para importar en Xray 168575. Opcionalmente, se sube automáticamente vÃa API de Xray`},{id:"reportes-playwright",title:"Reporte de Scripts",content:`## Reporte de Scripts Automatizados 16858 16859### Reporte Individual 16860 16861Cada ejecución de script genera: 16862- Estado: passed/failed 16863- Duración total 16864- Detalle paso a paso con screenshots 16865- Error (si falló) con stack trace 16866 16867### Reporte de Suite 16868 16869La ejecución de una suite genera un reporte consolidado: 16870- Resumen ejecutivo (passed/failed/total) 16871- Duración total 16872- Detalle de cada script con sus pasos 16873- Evidencias de cada paso 16874- EstadÃsticas de la regresión`}]},{id:"jira-xray",title:"Integracion Jira y Xray",icon:"",topics:[{id:"jira-conexion",title:"Conectar con Jira",content:`## Integración con Jira Cloud 16875 16876### Funcionalidades 16877 16878- Conectar a tu proyecto de Jira Cloud 16879- Listar issues del proyecto (historias, bugs, tasks) 16880- Asociar pruebas a issues especÃficas 16881- Ver detalles de la issue desde HakaBuddy 16882- Filtrar issues por sprint, estado o asignado 16883 16884### Cómo Conectar 16885 168861. Ve a Configuraciones â Jira 168872. Ingresa URL, email y API Token 168883. Click en "Probar Conexión" 168894. Si es exitoso, verás los proyectos disponibles 16890 16891### Asociar Prueba a Issue 16892 168931. Al iniciar una prueba, click en "Vincular con Jira" 168942. Selecciona la issue de la lista o busca por key 168953. La prueba queda asociada y aparecerá en el reporte 16896 16897### Beneficios 16898 16899- Trazabilidad completa: prueba â issue â requerimiento 16900- El reporte PDF/HTML incluye la key de Jira 16901- Exportar resultados directamente a Xray`},{id:"jira-xray-export",title:"Exportar a Xray",content:`## Exportación a Xray 16902 16903### Formatos de Exportación 16904 16905| Formato | Uso | 16906|---------|-----| 16907| Xray JSON | Importar como Test Execution en Xray | 16908| Test Plan vinculado | Asociar resultados a un Test Plan existente | 16909 16910### Flujo de Exportación 16911 169121. Ejecuta tu prueba (manual o automatizada) 169132. La prueba está vinculada a una issue de Jira 169143. Al finalizar: click en "Exportar a Xray" 169154. Se genera el JSON de Test Execution 169165. Se puede subir manualmente o vÃa API 16917 16918### Exportación Automática (API) 16919 16920Si tienes configurado Client ID y Client Secret de Xray: 169211. La exportación se hace automáticamente al finalizar la prueba 169222. Se crea un Test Execution en Xray 169233. Los screenshots se adjuntan como evidencias 169244. El resultado (PASS/FAIL) se marca en cada step`}]},{id:"ia",title:"Inteligencia Artificial",icon:"",topics:[{id:"ia-descripcion",title:"¿Qué puede hacer la IA?",content:`## Inteligencia Artificial en HakaBuddy 16925 16926### Funcionalidades de IA 16927 16928| Función | Descripción | 16929|---------|-------------| 16930| Generar descripción de pasos | La IA sugiere tÃtulos descriptivos para los pasos durante pruebas manuales | 16931| Análisis de fallos | Cuando un paso falla, la IA analiza el screenshot y sugiere posibles causas | 16932| Optimización de scripts | Sugiere mejoras en selectores y estructura de scripts | 16933| Análisis de script | Revisa un script completo y sugiere validaciones faltantes | 16934| Generación de datos | Sugiere datos de prueba para campos detectados | 16935 16936### Cuándo se Usa 16937 16938- Durante pruebas manuales: al registrar cada paso 16939- Después de una ejecución fallida: análisis del error 16940- Al revisar scripts: sugerencias de mejora 16941- En la creación de Scenario Outlines: datos para la tabla`},{id:"ia-proveedores",title:"Proveedores y Modelos",content:`## Proveedores de IA 16942 16943### Google Gemini (Recomendado) 16944 16945- Rápido y económico 16946- Modelos: gemini-2.0-flash (recomendado), gemini-pro 16947- Ideal para uso diario 16948 16949### OpenAI 16950 16951- Alta precisión en análisis complejos 16952- Modelos: gpt-4o, gpt-4o-mini 16953- Mayor costo por consulta 16954 16955### Claude (Anthropic) 16956 16957- Excelente razonamiento 16958- Modelos: claude-3-7-sonnet 16959- Bueno para análisis detallados 16960 16961### Ollama (Local) 16962 16963- 100% local, sin enviar datos a la nube 16964- Sin costo de API 16965- Modelos: llama3, mistral, codestral, y cualquier modelo descargado
16966- Funciona sin internet 16967- Requiere Ollama instalado localmente 16968 16969### Cambiar Proveedor 16970 16971Se puede cambiar de proveedor en cualquier momento desde Configuraciones â IA. No se pierde historial ni configuración.`}]},{id:"sesiones",title:"Sesiones Autenticadas",icon:"",topics:[{id:"sesiones-concepto",title:"Concepto",content:`## Sesiones Autenticadas 16972 16973### ¿Qué son? 16974 16975Las sesiones autenticadas permiten grabar y ejecutar scripts de Playwright en sitios que requieren login con 2FA/MFA (como Salesforce, SAP, Azure AD) sin tener que autenticarte cada vez. 16976 16977### ¿Cómo funcionan? 16978 169791. Capturas una sesión: se abre un navegador donde haces login manualmente (incluyendo 2FA) 169802. Al cerrar el navegador, HakaBuddy guarda las cookies y localStorage 169813. Cuando grabas o ejecutas un script, seleccionas la sesión guardada 169824. El navegador se abre ya autenticado, sin pasar por el login 16983 16984### Compatibilidad 16985 16986Funciona con cualquier sitio que use cookies para sesión: 16987- Salesforce 16988- SAP 16989- Azure AD / Microsoft 365 16990- Google Workspace 16991- Jira / Confluence 16992- ServiceNow 16993- Cualquier aplicación web con login`},{id:"sesiones-capturar",title:"Capturar y Gestionar",content:`## Capturar una Sesión 16994 16995### Desde la UI 16996 169971. Ve a Pruebas Automatizadas â "Sesiones" 169982. Click en "Nueva Sesión" 169993. Ingresa un nombre (ej: "admin_salesforce") y la URL de login 170004. Se abre un navegador: haz login completo (incluyendo 2FA) 170015. Cuando estés dentro del sistema, cierra el navegador 170026. La sesión se guarda automáticamente 17003 17004### Gestionar Sesiones 17005 17006Desde el diálogo de Sesiones puedes: 17007- **Listar** todas las sesiones guardadas (nombre, URL, fecha) 17008- **Renovar** una sesión expirada (re-capturar con el mismo nombre) 17009- **Eliminar** sesiones que ya no necesitas 17010- **Ver info** de una sesión (cookies, origen, fecha) 17011 17012### Usar al Grabar 17013 17014Al iniciar una nueva grabación: 170151. En las opciones de grabación, selecciona "Usar sesión autenticada" 170162. Elige la sesión de la lista 170173. El navegador se abre ya logueado en la URL capturada 17018 17019### Usar al Ejecutar 17020 17021Al ejecutar un script: 170221. Si el script fue grabado con sesión, la usa automáticamente 170232. También puedes seleccionar manualmente una sesión diferente 17024 17025### Expiración 17026 17027Las sesiones expiran según la configuración del servidor (tÃpicamente 2-24 horas). Cuando expira, simplemente recaptura con el mismo nombre.`}]},{id:"debug",title:"Modo Debug con HakaPath",icon:"",topics:[{id:"debug-concepto",title:"¿Qué es el Modo Debug?",content:`## Modo Debug 17028 17029### ¿Qué es? 17030 17031El Modo Debug permite ejecutar scripts de Playwright paso a paso, deteniendo la ejecución en cada acción para inspeccionar el estado de la página, modificar pasos que fallen y generar selectores alternativos con HakaPath. 17032 17033### ¿Cuándo usarlo? 17034 17035- Un script que antes funcionaba ahora falla (la app cambió) 17036- Quieres entender qué hace exactamente cada paso del script 17037- Necesitas actualizar un selector que ya no funciona 17038- Quieres agregar validaciones en puntos especÃficos 17039 17040### Flujo 17041 170421. Selecciona un script y click en "Debug" 170432. Se abre el navegador y un panel lateral con los pasos 170443. Cada paso se muestra con su estado (pendiente, ejecutando, passed, failed) 170454. Click en "Siguiente" para avanzar paso a paso 170465. Si un paso falla, puedes editar el selector y reintentar 170476. Al finalizar, guardas las modificaciones al script`},{id:"debug-panel",title:"Panel de Debug",content:`## Panel de Debug 17048 17049### Interfaz 17050 17051El panel de debug muestra: 17052- Lista de todos los pasos del script (izquierda) 17053- Estado visual de cada paso: pendiente (gris), ejecutando (amarillo), passed (verde), failed (rojo) 17054- Botones de control: Ejecutar paso, Siguiente, Reintentar, Detener 17055- Detalle del paso actual (selector, acción, valor) 17056- Editor inline para modificar pasos 17057 17058### Cuando un Paso Falla 17059 17060Si un paso falla durante el debug: 170611. Se marca en rojo con el mensaje de error 170622. Puedes inspeccionar la página actual 170633. Opciones: 17064 - **Editar selector**: Modificar el localizador directamente 17065 - **Generar alternativas**: La IA sugiere selectores alternativos 17066 - **HakaPath**: Abre HakaPath para generar un selector robusto visualmente 17067 - **Reintentar**: Ejecutar el paso nuevamente con el selector modificado 17068 - **Saltar**: Continuar con el siguiente paso 17069 17070### Guardar Modificaciones 17071 17072Al finalizar el debug, si modificaste algún paso: 170731. HakaBuddy muestra un resumen de los cambios 170742. Puedes guardar las modificaciones al script original 170753. O guardar como nuevo script (mantener ambas versiones)`},{id:"debug-hakapath",title:"Integración con HakaPath",content:`## HakaPath en el Debug 17076 17077### ¿Qué es HakaPath? 17078 17079HakaPath es la extensión de Chrome para generar selectores robustos (XPath, CSS, data-testid). Cuando estás en modo Debug de HakaBuddy, puedes invocar HakaPath para generar un selector alternativo visualmente. 17080 17081### Flujo Integrado 17082 170831. Durante el debug, un paso falla porque el selector no encuentra el elemento 170842. Click en "Usar HakaPath" en el panel de debug 170853. Se activa la selección visual en el navegador 170864. Haces click en el elemento correcto 170875. HakaPath genera el selector (XPath, CSS, o data-testid) 170886. El selector se copia automáticamente al paso del script 170897. Reintenta el paso con el nuevo selector 17090 17091### Beneficio 17092 17093Combina la potencia del debug paso a paso con la generación visual de selectores, permitiendo actualizar scripts rápidamente cuando la aplicación cambia.`}]},{id:"historico",title:"Historico",icon:"",topics:[{id:"historico-pruebas",title:"Historial de Pruebas",content:`## Historial de Pruebas 17094 17095### Qué se Registra 17096 17097Cada prueba ejecutada (manual o automatizada) se almacena con: 17098- Fecha y hora de ejecución 17099- Producto y ambiente 17100- Tester (nombre del usuario) 17101- Tipo de prueba (manual/automatizada)
17102- Resultado (exitoso/fallido) 17103- Número de pasos y evidencias 17104- Reportes generados (PDF, HTML) 17105- Issue de Jira asociada (si aplica) 17106 17107### Filtros Disponibles 17108 17109- Por rango de fecha 17110- Por producto 17111- Por ambiente 17112- Por tester 17113- Por resultado (exitoso/fallido) 17114- Por tipo (manual/automatizada) 17115 17116### Acciones 17117 17118- Ver detalle completo de la prueba 17119- Descargar reportes (PDF/HTML) 17120- Re-ejecutar (para pruebas automatizadas) 17121- Duplicar (crear nueva prueba basada en una anterior) 17122- Eliminar registros antiguos`},{id:"historico-suites",title:"Historial de Suites",content:`## Historial de Ejecuciones de Suites 17123 17124### Qué se Registra 17125 17126Cada ejecución de suite se almacena con: 17127- Nombre de la suite ejecutada 17128- Fecha y hora 17129- Duración total 17130- Número de scripts: total, passed, failed 17131- Reporte HTML generado 17132- Enlace al reporte consolidado 17133 17134### Visualización 17135 17136- Lista cronológica de ejecuciones 17137- Indicador visual de resultado (verde = all passed, rojo = alguno failed) 17138- Acceso directo al reporte HTML de cada ejecución 17139- Comparación entre ejecuciones (tendencia de fallos)`}]},{id:"faq",title:"FAQ",icon:"",topics:[{id:"faq-general",title:"Preguntas Frecuentes",content:`## Preguntas Frecuentes 17140 17141### ¿Necesito saber programar para usar HakaBuddy? 17142 17143No para pruebas manuales ni para grabar scripts (la grabación es visual). Para editar scripts o crear custom steps sà necesitas conocimientos básicos de Python. 17144 17145### ¿Los datos se guardan en la nube? 17146 17147No. Todos los datos se guardan localmente en tu computador (SQLite). Nada se envÃa a servidores de Haka Lab. 17148 17149### ¿Puedo usar HakaBuddy sin internet? 17150 17151SÃ, excepto para: 17152- Login inicial (necesita validar licencia) 17153- IA cloud (Gemini/OpenAI/Claude) â usa Ollama para IA local sin internet 17154- Integración con Jira/Xray 17155- Push a Git 17156 17157### ¿Funciona en macOS con Apple Silicon (M1/M2/M3)? 17158 17159SÃ. El build de macOS soporta tanto Intel como Apple Silicon. Usa el build correspondiente a tu arquitectura. 17160 17161### ¿Puedo compartir pruebas entre compañeros? 17162 17163La base de datos es local por usuario. Para compartir: 17164- Exporta reportes (PDF/HTML) y comparte por email 17165- Usa la integración CI/CD para publicar suites 17166- Exporta a Xray para trazabilidad en Jira 17167 17168### ¿Qué pasa si actualizo la app? 17169 17170Los datos persisten entre actualizaciones. La base de datos se migra automáticamente si hay cambios de esquema. 17171 17172### ¿Puedo grabar pruebas en aplicaciones con 2FA/MFA? 17173 17174SÃ, usando Sesiones Autenticadas. Capturas una sesión una vez (con login manual incluyendo MFA) y después grabas/ejecutas sin necesidad de re-autenticarte. 17175 17176### ¿Los scripts grabados funcionan en CI/CD? 17177 17178SÃ. Al hacer Push a CI/CD, los scripts se adaptan automáticamente para ejecución headless. El workflow generado instala Playwright y ejecuta los scripts. 17179 17180### ¿Puedo editar los screenshots capturados? 17181 17182SÃ. HakaBuddy incluye un editor de imágenes integrado con herramientas para resaltar áreas, agregar flechas, texto y difuminar información sensible. 17183 17184### ¿Cómo actualizo un script cuando la app cambia? 17185 17186Usa el Modo Debug: ejecuta paso a paso, identifica qué falló, y usa HakaPath para generar el selector correcto. Los cambios se guardan directamente al script.`}]}];function Nne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return Tne.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - HakaBuddy | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"HakaBuddy - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:` 17187 fixed lg:sticky top-0 left-0 z-50 lg:z-10 17188 w-80 h-screen overflow-y-auto 17189 bg-darkGray border-r border-gray-800 17190 transition-transform duration-300 17191 ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"} 17192 `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"HakaBuddy"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Aplicación de Escritorio para QA"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(Ine,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function Ine({content:t}){return Pne(t).map((a,n)=>s.jsx(Rne,{block:a},n))}function Pne(t){var i;const e=[],a=t.split(` 17193`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(` 17194`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function Rne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(wb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
17194case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(wb,{text:e})},a))});case"table":return s.jsx(Lne,{rows:t.rows});default:return null}}function Lne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(wb,{text:o})},l))},r))})]})})}function wb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const One=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es HakaPath?",content:`## ¿Qué es HakaPath? 17195 17196HakaPath es una extensión de Chrome/Edge (Manifest V3) que captura elementos web mediante el menú contextual y genera múltiples localizadores XPath y CSS listos para usarse en suites de automatización. 17197 17198### Flujo Básico 17199 172001. Haz clic derecho sobre un elemento en cualquier página 172012. Selecciona "Obtener HakaPath" 172023. Se abre el popup con localizadores generados automáticamente 172034. Copia el que necesites o conviértelo al formato de tu framework 17204 17205### CaracterÃsticas Principales 17206 17207- **6 slots de localizadores**: 3 XPath + 3 CSS (incluyendo generación con IA) 17208- **Conteo de coincidencias**: badges que muestran cuántas veces aparece el selector en el DOM 17209- **Conversión a WebElement**: botón que transforma al formato de tu framework 17210- **Exportación POM**: genera Page Object Model en 4 lenguajes à 4 frameworks 17211- **Indicador de robustez** (Pro): puntúa cada localizador de 0 a 100 17212- **Detección de volatilidad**: advierte cuando un selector usa atributos dinámicos 17213- **5 pestañas**: Localizadores, Relativos, Semánticos, POM/Exportar, Configuración 17214 17215### Frameworks Soportados 17216 17217| Framework | Lenguajes | 17218|-----------|-----------| 17219| Selenium | Python, Java, JavaScript, C# | 17220| Playwright | Python, Java, JavaScript, C# | 17221| Cypress | JavaScript | 17222| Appium | Python, Java, JavaScript, C# |`},{id:"instalacion",title:"Instalación",content:`## Instalación 17223 17224### Desde Chrome Web Store 17225 17226Busca "HakaPath" en la Chrome Web Store e instala directamente. Compatible con Chrome 88+ y Edge 88+. 17227 17228### Modo Desarrollador 17229 172301. Descarga o clona el repositorio 172312. Abre \`chrome://extensions/\` y activa Developer mode 172323. Usa "Load unpacked" apuntando a la carpeta del proyecto 172334. Fija HakaPath a la barra del navegador (pin) 17234 17235### Primer Uso 17236 172371. Al abrir por primera vez, aparece selección de idioma (Español/English) â obligatorio 172382. Selecciona tipo de cuenta: 17239 - **Free**: Registro con nombre, email y empresa (sin contraseña) 17240 - **Pro**: Login con email/contraseña, Google o Microsoft 172413. Los clientes de Haka Lab tienen acceso Pro sin costo con su cuenta corporativa 17242 17243### Requisitos 17244 17245- Chrome 88+ o Edge 88+ (Chromium con Manifest V3) 17246- Chrome 127+ para Chrome Built-in AI (Gemini Nano local, opcional) 17247- Conexión a internet para login y proveedores de IA externos`},{id:"free-vs-pro",title:"Free vs Pro",content:`## Free vs Pro 17248 17249| Capacidad | Free | Pro | 17250|-----------|------|-----| 17251| Localizadores XPath | 1 slot local | 3 slots (2 locales + 1 IA) | 17252| Localizadores CSS | 1 slot local | 3 slots (2 locales + 1 IA) |
17253| Localizadores Semánticos | 1 de cada tipo | 2 de cada tipo | 17254| Localizadores Relativos | Above y Near | Los 5 (Above, Below, Near, Left, Right) | 17255| Proveedores de IA | Solo Chrome Built-in AI | Chrome AI + OpenAI + Claude + Gemini | 17256| Frameworks | Selenium, Playwright | Selenium, Playwright, Cypress, Appium | 17257| Indicador de robustez | No | Si, con puntaje y detalles | 17258| Exportación POM | Si | Si | 17259| Histórico | Si | Si | 17260| Tema oscuro/claro | Si | Si |`}]},{id:"localizadores",title:"Localizadores XPath y CSS",icon:"",topics:[{id:"loc-captura",title:"Capturar un Elemento",content:`## Capturar un Elemento 17261 17262### Pasos 17263 172641. Navega a cualquier página web 172652. Haz **click derecho** sobre el elemento que quieres localizar 172663. Selecciona **"Obtener HakaPath"** del menú contextual 172674. Se abre automáticamente la ventana de HakaPath con los localizadores 17268 17269### Lo que se Captura 17270 17271Al hacer click derecho, HakaPath recolecta: 17272- Tag, id, class, name, title, role, alt, href, type 17273- Texto visible (textContent) 17274- Atributos data-* (data-testid, data-qa, data-cy, etc.) 17275- Atributos aria-* (aria-label, aria-describedby) 17276- Placeholder, value, src 17277- outerHTML del elemento (contexto real) 17278- Información de hermanos (siblings): tag, id, class, texto 17279- Posición entre hermanos (siblingIndex) 17280- Información del padre (tag, id, name, title, class) 17281 17282### Evaluación Automática 17283 17284Cada localizador generado se evalúa contra el DOM real: 17285- **Badge verde [1]**: Exactamente 1 coincidencia (ideal, localizador único) 17286- **Badge rojo [4]**: Múltiples coincidencias (ambiguo, no recomendado) 17287- **Badge azul [0]**: Sin coincidencias (sugerido para mejora)`},{id:"loc-xpath",title:"Estrategias XPath",content:`## Estrategias de Generación XPath 17288 17289HakaPath usa 13+ estrategias para generar XPaths, priorizando las que dan exactamente 1 match: 17290 172911. **ID absoluto**: \`//*[@id="..."]\` 172922. **Atributos únicos**: data-testid, data-qa, name, aria-label 172933. **Atributos extra**: placeholder, type, href, src, value 172944. **Combinación de atributos**: múltiples atributos con AND 172955. **Parent + child con atributos**: contexto del padre 172966. **Parent + child con texto**: padre + texto del elemento 172977. **Clase especÃfica**: primera clase CSS del elemento 172988. **Posición con parent**: \`(parent//tag)[N]\` 172999. **Following/preceding-sibling**: relación con hermanos 1730010. **Texto exacto**: \`//*[text()='...']\` 1730111. **Contains text**: \`//*[contains(text(),'...')]\` 1730212. **JerarquÃa con Ãndices**: ruta completa con posiciones 1730313. **Ancestor + descendant**: patrones avanzados 1730414. **Combinaciones OR**: múltiples condiciones opcionales 17305 17306### Priorización 17307 17308Se priorizan en orden: 173091. Selectores con 1 sola coincidencia 173102. Selectores cortos y semánticos (data-testid, id, name) 173113. Selectores que no usan clases CSS (pueden ser dinámicas) 173124. Selectores que no dependen de posición`},{id:"loc-css",title:"Estrategias CSS",content:'## Estrategias de Generación CSS\n\n### Estrategias (en orden de prioridad)\n\n1. **ID**: `#element-id`\n2. **Atributos de testing**: `[data-testid="value"]`\n3. **Clase única**: `tag.class-name`\n4. **Atributos**: `tag[attr="value"]`\n5. **Combinadores**: `parent > child`, `ancestor descendant`\n6. **Pseudo-clases**: `:nth-child()`, `:first-child`\n7. **Atributos múltiples**: `tag[attr1="v1"][attr2="v2"]`\n8. **Selectores compuestos**: especificidad creciente\n\n### Validación de Compatibilidad\n\nHakaPath valida cada CSS generado contra el motor de Chrome actual:\n- Usa `CSS.supports(\'selector(...)\')` para verificar soporte\n- Prueba con `document.querySelector(sel)` para detectar errores de sintaxis\n- Muestra la versión de Chrome donde es compatible'},{id:"loc-acciones",title:"Acciones sobre Localizadores",content:`## Acciones Disponibles 17313 17314### Copiar (botón azul) 17315 17316- Copia el localizador al portapapeles 17317- Muestra notificación "Selector Copiado!" 17318- Automáticamente agrega la lÃnea al POM (pestaña POM/Exportar) 17319 17320### Convertir a WebElement (botón </>) 17321 17322Transforma el localizador al formato ejecutable del framework configurado: 17323 17324\`\`\` 17325Selenium (Python): driver.find_element(By.XPATH, "//...") 17326Selenium (Java): driver.findElement(By.xpath("//...")) 17327Playwright (Python): page.locator("...") 17328Playwright (Java/JS): page.locator("...") 17329Cypress: cy.get("...") / cy.xpath("...")
17330Appium (Python): driver.find_element(AppiumBy.XPATH, "...") 17331\`\`\` 17332 17333Click de nuevo: revierte al localizador crudo (toggle). 17334 17335### Badge de Coincidencias 17336 17337Muestra cuántas veces aparece el localizador en el DOM actual: 17338- **[1]** Verde: único (ideal) 17339- **[N]** Rojo: múltiples (ambiguo) 17340- **[0]** Azul: ninguna (sugerido para mejora)`}]},{id:"relativos",title:"Localizadores Relativos",icon:"",topics:[{id:"rel-descripcion",title:"Cómo Funcionan",content:`## Localizadores Relativos 17341 17342Los localizadores relativos encuentran elementos según su posición visual respecto a otro elemento. Soportado por Selenium 4+ y Playwright. 17343 17344### Tipos Disponibles 17345 17346| Tipo | Descripción | Disponibilidad | 17347|------|-------------|----------------| 17348| Above | Elemento posicionado debajo de una referencia | Free + Pro | 17349| Below | Elemento posicionado arriba de una referencia | Pro | 17350| Near | Elemento cercano a una referencia | Free + Pro | 17351| To Left Of | Elemento a la izquierda de una referencia | Pro | 17352| To Right Of | Elemento a la derecha de una referencia | Pro | 17353 17354### Formato según Framework 17355 17356\`\`\` 17357Selenium 4 (Java): RelativeLocator.with(By.tagName("a")).below(By.id("ref")) 17358Selenium 4 (Python): locate_with(By.TAG_NAME, "a").below(By.ID, "ref") 17359Selenium 4 (C#): RelativeBy.WithLocator(By.TagName("a")).Below(By.Id("ref")) 17360Playwright: page.locator("a:below(#ref)") 17361\`\`\` 17362 17363### Generación 17364 17365HakaPath analiza los hermanos (siblings) del elemento capturado para determinar referencias posicionales válidas. Si no hay hermanos identificables cercanos, se muestra "No se encontró referencia de hermano".`}]},{id:"semanticos",title:"Localizadores Semánticos",icon:"",topics:[{id:"sem-descripcion",title:"By Role, Text, TestId",content:`## Localizadores Semánticos 17366 17367Los localizadores semánticos usan atributos accesibles (rol, texto, label) para encontrar elementos. Recomendado por Playwright y Testing Library. 17368 17369### By Role 17370 17371Detecta el rol del elemento (explÃcito vÃa atributo "role" o implÃcito por el tag HTML): 17372 17373\`\`\` 17374getByRole('link', { name: 'Servicios' }) 17375getByRole('button', { name: 'Enviar' }) 17376getByRole('textbox', { name: 'Email' }) 17377\`\`\` 17378 17379Mapa de roles implÃcitos: buttonâbutton, aâlink, inputâtextbox, selectâcombobox, h1-h6âheading, navânavigation. 17380 17381El nombre accesible se obtiene de: aria-label > texto visible > title > alt > placeholder. 17382 17383### By Text / Label / Placeholder 17384 17385\`\`\` 17386getByText('Servicios') // Texto visible 17387getByLabel('Email') // aria-label o label asociad
17387o 17388getByPlaceholder('Ingresa tu email') // Placeholder del input 17389getByAltText('Logo empresa') // Alt de imagen 17390getByTitle('Cerrar modal') // Atributo title 17391\`\`\` 17392 17393### By TestId 17394 17395Busca atributos de testing: data-testid, data-test-id, data-test, data-qa, data-cy, data-pw. 17396 17397\`\`\` 17398getByTestId('header-servicios-link') 17399getByTestId('submit-button') 17400\`\`\` 17401 17402Fallback: usa el ID si parece estable (no autogenerado). 17403 17404### Formato según Framework 17405 17406\`\`\` 17407Playwright (Python/Java/JS): page.getByRole('button', { name: 'Login' }) 17408Playwright (C#): Page.GetByRole('button', { name: 'Login' }) 17409Cypress: cy.findByRole('button', { name: 'Login' }) 17410Selenium/Appium: Comentario indicando usar Playwright/Cypress 17411\`\`\``}]},{id:"pom",title:"POM / Exportar",icon:"",topics:[{id:"pom-generacion",title:"Generación Automática",content:`## Generación de Page Object Model 17412 17413### Funcionamiento 17414 17415Cada vez que copias un localizador (botón copiar en cualquier pestaña), se agrega automáticamente una lÃnea al POM con el formato correcto. 17416 17417### Ejemplo con Selenium + Python 17418 17419\`\`\`python 17420from selenium.webdriver.common.by import By 17421 17422 servicios_link = (By.XPATH, "//*[@id='header-servicios']") 17423 login_button = (By.CSS_SELECTOR, "#login-btn") 17424\`\`\` 17425 17426### Ejemplo con Playwright + Java 17427 17428\`\`\`java 17429import com.microsoft.playwright.*; 17430 17431 public Locator servicios = page.locator("//*[@id='header']"); 17432 public Locator login = page.locator("#login-btn"); 17433\`\`\` 17434 17435### 16 Combinaciones Soportadas 17436 17437| Framework | Python | Java | JavaScript | C# | 17438|-----------|--------|------|------------|-----| 17439| Selenium | Si | Si | Si | Si | 17440| Playwright | Si | Si | Si | Si | 17441| Cypress | â | â | Si | â | 17442| Appium | Si | Si | Si | Si | 17443 17444### Nombrado Automático 17445 17446Los nombres de variables se generan automáticamente basándose en: 17447- Tag del elemento + atributos relevantes 17448- Texto del localizador (IDs, clases semánticas) 17449- Formato camelCase o snake_case según el lenguaje`},{id:"pom-exportar",title:"Exportar y Descargar",content:`## Exportar POM 17450 17451### Descargar Archivo 17452 17453- Click en botón de descarga (Ãcono nube con flecha) 17454- Se descarga con la extensión correcta: .py, .java, .js, .cs 17455- Incluye header con firma HakaPath 17456- Incluye imports necesarios del framework 17457 17458### Textarea Editable 17459 17460- Puedes editar manualmente el contenido del POM 17461- Los cambios se persisten en chrome.storage.local 17462- Se mantiene entre sesiones hasta que se limpie 17463 17464### Limpiar POM 17465 17466- Click en botón limpiar (Ãcono varita) 17467- Pregunta confirmación antes de borrar 17468- Reinicia el textarea para empezar de nuevo`}]},{id:"ia",title:"Inteligencia Artificial",icon:"",topics:[{id:"ia-proveedores",title:"Proveedores y Modelos",content:`## Inteligencia Artificial 17469 17470HakaPath genera localizadores inteligentes en los slots 3 (XPath) y 6 (CSS) usando IA. 17471 17472### Proveedores 17473 17474| Proveedor | Modelos | Disponibilidad | 17475|-----------|---------|----------------| 17476| Chrome Built-in AI | Gemini Nano (local) | Free + Pro | 17477| OpenAI | GPT-4o Mini, GPT-4o, GPT-4.1 Nano/Mini/Full | Solo Pro | 17478| Claude (Anthropic) | Sonnet 4, Haiku 3.5, Opus 4 | Solo Pro | 17479| Google Gemini | 3.1 Flash Lite, 2.0 Flash, 2.5 Flash, 2.5 Pro | Solo Pro | 17480 17481### Chrome Built-in AI (Gemini Nano) 17482 17483- Ejecuta 100% localmente en el dispositivo 17484- No requiere API key ni conexión a internet 17485- Requiere Chrome 127+ con flags de IA habilitados 17486- Disponible en versión Free 17487- Limitación: inputs largos se truncan a ~4000 caracteres 17488 17489### Flujo de Generación 17490 174911. Usuario captura elemento (click derecho) 174922. Slots 1, 2, 4, 5 se generan instantáneamente (locales) 174933. Slots 3 y 6 muestran "Creando con IA, espera..." 174944. Se envÃa al proveedor: info del elemento, padre, hermanos, outerHTML 174955. La IA genera un XPath (slot 3) y un CSS (slot 6) optimizados 174966. Se evalúan coincidencias y se muestra badge "AI" 174977. Tiempo tÃpico: 1-5 segundos 17498 17499### Si la IA Falla 17500 17501- Se usa un tercer localizador local como fallback 17502- No se muestra etiqueta "AI" 17503- La funcionalidad principal no se ve afectada`}]},{id:"robustez",title:"Indicador de Robustez",icon:"",topics:[{id:"robustez-algoritmo",title:"Algoritmo y Puntuación",content:`## Indicador de Robustez (Solo Pro) 17504 17505### Puntuación: 0-100 17506 17507Cada localizador recibe un puntaje visual: 17508- **Verde (70-100)**: Robusto â usa atributos estables 17509- **Amarillo (40-69)**: Moderado â tiene algunos riesgos 17510- **Rojo (0-39)**: Frágil â depende de elementos volátiles 17511 17512### Penalizaciones (restan puntos) 17513
17514- Clases CSS dinámicas (patrones: ng-, react-, css-, hash, sc-) 17515- Ãndices posicionales ([1], [position()=]) 17516- IDs autogenerados (GUIDs, hashes, :r0:) 17517- Rutas absolutas (/html/body/...) 17518- Profundidad excesiva (>5 niveles) 17519- Atributos volátiles detectados por el observador DOM 17520 17521### Bonificaciones (suman puntos) 17522 17523- data-testid, data-qa, data-test (+15) 17524- aria-label, aria-describedby (+10) 17525- Atributo name (+10) 17526- Atributo role (+8) 17527- IDs estables (cortos, semánticos) (+12) 17528- Rutas cortas (<3 niveles) (+8) 17529- Coincidencia por texto (+5) 17530 17531### Tooltip Detallado 17532 17533Al pasar el mouse sobre el indicador: 17534\`\`\` 17535Puntuación de robustez: 85/100 17536Penalizaciones: clase dinámica detectada (-5) 17537Bonificaciones: usa data-testid (+15), ruta corta (+8) 17538\`\`\``},{id:"robustez-volatilidad",title:"Detección de Volatilidad",content:`## Detección de Volatilidad 17539 17540### MutationObserver 17541 17542Al capturar un elemento, HakaPath activa un observador DOM por 10 segundos: 17543- Observa hasta 3 niveles de ancestros 17544- Detecta cambios en atributos (attributeOldValue: true) 17545- Se desconecta automáticamente al finalizar 17546 17547### ¿Qué Detecta? 17548 17549- Atributos que cambian durante la observación (mutaciones reales) 17550- Clases con hashes (css-abc123, sc-dkzDqf) 17551- IDs con timestamps o UUIDs 17552- Atributos data-* que cambian en cada render 17553- Clases de estado (active, selected, hover, focus) 17554 17555### Cuando se Detecta Volatilidad 17556 17557Aparece un Ãcono de advertencia (triángulo amarillo) con: 17558- Tooltip: "Atributo volátil detectado: class cambió durante observación" 17559- Panel inferior con localizadores alternativos que evitan los atributos volátiles 17560 17561### Auto-Heal (Fingerprinting) 17562 17563Cada elemento capturado genera una huella digital con: 17564- Tag, atributos, texto, posición entre hermanos, ancestros 17565- Si un localizador falla en el futuro, se buscan candidatos por similitud ponderada`}]},{id:"configuracion",title:"Configuración",icon:"",topics:[{id:"config-opciones",title:"Opciones",content:`## Configuración 17566 17567### Opciones Disponibles 17568 17569| Opción | Valores | Nota | 17570|--------|---------|------| 17571| Framework | Selenium, Playwright, Cypress*, Appium* | *Solo Pro | 17572| Lenguaje WebElement | Python, Java, JavaScript, C# | Afecta conversión y POM | 17573| Idioma | Español / English | Requiere reiniciar | 17574| Máx. Histórico | 1-30 | LÃmite de entradas guardadas | 17575| Proveedor IA | Deshabilitado, Chrome AI, OpenAI*, Claude*, Gemini* | *Solo Pro | 17576| Modelo | Según proveedor | Seleccionable | 17577| API Key | Campo password | Solo proveedores externos | 17578| Tema | Oscuro / Claro | Toggle inmediato | 17579 17580### Importante 17581 17582- El lenguaje no se puede cambiar si hay contenido en el POM (debe limpiar primero) 17583- El cambio de framework afecta: formato de conversión, generación POM, formato de relativos 17584- Toda la configuración se guarda en chrome.storage.local`}]},{id:"faq",title:"FAQ",icon:"",topics:[{id:"faq-general",title:"Preguntas Frecuentes",content:`## Preguntas Frecuentes 17585 17586### ¿Funciona en cualquier página web? 17587 17588SÃ. HakaPath se inyecta como content script en todas las URLs y funciona en cualquier página web. 17589 17590### ¿Necesito internet para generar localizadores? 17591 17592No. Los localizadores locales (slots 1, 2, 4, 5) se generan sin internet. Solo la IA externa requiere conexión (excepto Chrome Built-in AI que es local). 17593 17594### ¿Por qué mi localizador tiene badge rojo? 17595 17596Badge rojo significa que el selector coincide con múltiples elementos en el DOM (no es único). Usa uno con badge verde [1] para asegurar unicidad. 17597 17598### ¿Qué hago si el badge es azul [0]? 17599 17600Badge azul significa que no se encontró ninguna coincidencia. Esto puede ocurrir si: 17601- El elemento es dinámico y ya no está en el DOM 17602- La IA sugirió un selector mejorado que requiere un atributo que se deberÃa agregar (data-testid) 17603 17604### ¿Por qué algunos slots dicen "Disponible en versión Pro"? 17605 17606En la versión Free, solo tienes 1 slot XPath y 1 slot CSS local. Los slots adicionales y la IA avanzada requieren cuenta Pro. 17607 17608### ¿Puedo usar HakaPath con Selenium y Playwright al mismo tiempo? 17609 17610Puedes cambiar de framework en cualquier momento desde la configuración. El POM se genera según el framework activo. Si cambias de framework, debes limpiar el POM actual. 17611 17612### ¿Los localizadores se guardan entre sesiones? 17613 17614El POM se guarda persistentemente en chrome.storage.local hasta que lo limpies. El historial también se mantiene entre sesiones. 17615 17616### ¿Cómo integro HakaPath con HakaBuddy? 17617 17618En HakaBuddy, durante el Modo Debug, puedes invocar HakaPath directamente para generar selectores alternativos cuando un paso del script falla. El selector generado se copia automáticamente al paso del script. 17619 17620### ¿Chrome Built-in AI (Gemini Nano) funciona en mi Chrome? 17621 17622Requiere Chrome 127+ con los flags de IA habilitados. Si no está disponible, HakaPath te mostrará un modal informativo con instrucciones para habilitarlo.`}]}];function Mne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return One.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - HakaPath | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>
17622{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"HakaPath - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:` 17623 fixed lg:sticky top-0 left-0 z-50 lg:z-10 17624 w-80 h-screen overflow-y-auto 17625 bg-darkGray border-r border-gray-800 17626 transition-transform duration-300 17627 ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"} 17628 `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"HakaPath"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Extensión Chrome v3.1"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(Dne,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function Dne({content:t}){return qne(t).map((a,n)=>s.jsx(zne,{block:a},n))}function qne(t){var i;const e=[],a=t.split(` 17629`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(` 17630`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function zne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(kb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
17630case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(kb,{text:e})},a))});case"table":return s.jsx(Vne,{rows:t.rows});default:return null}}function Vne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(kb,{text:o})},l))},r))})]})})}function kb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}function Hne(){const[t,e]=k.useState("google"),[a,n]=k.useState(""),[i,r]=k.useState(""),[o,l]=k.useState(!1),[c,d]=k.useState(""),{loginWithGoogle:u,loginWithLicense:p,user:m}=Zl(),h=Qa();k.useEffect(()=>{m&&h("/docs")},[m,h]);const g=async()=>{d(""),l(!0);try{await u(),h("/docs")}catch(x){d(x.message)}finally{l(!1)}},y=async x=>{if(x.preventDefault(),d(""),!a.trim()||!i.trim()){d("Ingresa tu email y clave de licencia");return}l(!0);try{await p(a.trim(),i.trim()),h("/docs")}catch(v){d(v.message)}finally{l(!1)}};return s.jsx("div",{className:"min-h-screen bg-gradient-to-br from-dark via-slate-900 to-dark flex flex-col items-center justify-center px-4",children:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},className:"w-full max-w-md flex flex-col items-center",children:[s.jsxs(_.div,{animate:{boxShadow:["0 0 20px rgba(0,200,255,0.1), 0 0 40px rgba(0,200,255,0.05)","0 0 40px rgba(0,200,255,0.3), 0 0 80px rgba(0,200,255,0.1)","0 0 20px rgba(0,200,255,0.1), 0 0 40px rgba(0,200,255,0.05)"]},transition:{duration:3,repeat:1/0,ease:"easeInOut"},className:"relative w-full bg-slate-800/50 backdrop-blur-sm border border-cyan-400/40 rounded-2xl p-8",children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:8,repeat:1/0,ease:"linear"},className:"absolute -top-5 -right-5 w-12 h-12 bg-slate-800 border border-cyan-400/40 rounded-full flex items-center justify-center shadow-[0_0_15px_rgba(0,200,255,0.2)]",children:s.jsx("svg",{className:"w-6 h-6 text-cyan-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",strokeWidth:1.5,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25"})})}),s.jsx("h1",{className:"text-2xl font-bold text-white mb-1",children:"Documentación de productos HakaLab"}),s.jsx("p",{className:"text-gray-400 text-sm mb-6",children:"Accede con tu cuenta o licencia"}),s.jsxs("div",{className:"flex mb-6 bg-dark rounded-lg p-1",children:[s.jsx("button",{onClick:()=>{e("google"),d("")},className:`flex-1 py-2 text-sm font-medium rounded-md transition-colors ${t==="google"?"bg-primary/20 text-primary":"text-gray-400 hover:text-gray-200"}`,children:"Google"}),s.jsx("button",{onClick:()=>{e("license"),d("")},className:`flex-1 py-2 text-sm font-medium rounded-md transition-colors ${t==="license"?"bg-primary/20 text-primary":"text-gray-400 hover:text-gray-200"}`,children:"Licencia"})]}),c&&s.jsx(_.div,{initial:{opacity:0}
17630,animate:{opacity:1},className:"mb-4 p-3 bg-red-500/10 border border-red-500/30 rounded-lg text-red-400 text-sm",children:c}),t==="google"?s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:g,disabled:o,className:"w-full flex items-center justify-center gap-3 bg-white text-gray-800 font-medium py-3 px-4 rounded-xl hover:bg-gray-100 transition-all disabled:opacity-50 disabled:cursor-not-allowed shadow-lg",children:o?s.jsx("div",{className:"animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-gray-800"}):s.jsxs(s.Fragment,{children:[s.jsxs("svg",{className:"w-5 h-5",viewBox:"0 0 24 24",children:[s.jsx("path",{fill:"#4285F4",d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),s.jsx("path",{fill:"#34A853",d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),s.jsx("path",{fill:"#FBBC05",d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),s.jsx("path",{fill:"#EA4335",d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]}),s.jsx("span",{children:"Continuar con Google"})]})}),s.jsxs("p",{className:"mt-3 text-center text-xs text-gray-500",children:["Solo cuentas ",s.jsx("span",{className:"text-primary",children:"@hakalab.com"})]})]}):s.jsxs("form",{onSubmit:y,className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"block text-sm text-gray-400 mb-1",children:"Email"}),s.jsx("input",{type:"email",value:a,onChange:x=>n(x.target.value),placeholder:"[email protected]",className:"w-full px-4 py-3 bg-dark border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]}),s.jsxs("div",{children:[s.jsx("label",{className:"block text-sm text-gray-400 mb-1",children:"Clave de Licencia"}),s.jsx("input",{type:"password",value:i,onChange:x=>r(x.target.value),placeholder:"Tu clave de licencia",className:"w-full px-4 py-3 bg-dark border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]}),s.jsx("button",{type:"submit",disabled:o,className:"w-full py-3 bg-primary text-dark font-semibold rounded-xl hover:bg-primary/90 transition-all disabled:opacity-50 disabled:cursor-not-allowed",children:o?"Validando...":"Ingresar"})]})]}),s.jsx("p",{className:"text-center text-gray-500 text-xs mt-6",children:"© 2026 HakaLab. Todos los derechos reservados."})]})})}const xj=[{productKey:"Engine Playwright",to:"/docs/haka-playwright-engine",logo:"/imagenes/docs-logos/Automation Engine.png",alt:"Haka Automation Engine",logoHeight:"h-8",description:"Framework de automatización de pruebas funcionales. Soporta Web, Mobile, Desktop, API y GenAI."},{productKey:"Haka AI Studio",to:"/docs/haka-ai-studio",logo:"/imagenes/docs-logos/AI Studio.png",alt:"Haka AI Studio",logoHeight:"h-8",description:"Extensión de VS Code con IA para grabar y generar pruebas automatizadas. Soporta Playwright y Selenium."},{productKey:"HakaBoost",to:"/docs/hakaboost",logo:"/imagenes/docs-logos/HakaBoost.png",alt:"HakaBoost",logoHeight:"h-6",description:"Copiloto de calida
17630d con IA para Jira y Azure DevOps. Genera tests Gherkin y mejora requerimientos."},{productKey:"Hakabuddy",to:"/docs/hakabuddy",logo:"/imagenes/docs-logos/HakaBuddy.png",alt:"HakaBuddy",logoHeight:"h-8",description:"Aplicación de escritorio para QA. Pruebas manuales y automatizadas con reportes profesionales."},{productKey:"HakaPath",to:"/docs/hakapath",logo:"/imagenes/docs-logos/HakaPath.png",alt:"HakaPath",logoHeight:"h-8",description:"Extensión Chrome para generar selectores robustos (XPath, CSS, data-testid) con un solo click."}];function Fne(){const{user:t,logout:e}=Zl();k.useEffect(()=>{document.title="Documentación | Haka Lab"},[]);const a=(t==null?void 0:t.productos)??[],i=(t==null?void 0:t.method)==="google"?xj:xj.filter(r=>a.includes(r.productKey));return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsx("span",{className:"text-white font-semibold text-lg",children:"Documentación de productos HakaLab"}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:t==null?void 0:t.email}),s.jsx("button",{onClick:e,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsx("main",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12",children:s.jsxs(_.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.4},children:[s.jsxs("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-2",children:["Bienvenido",t!=null&&t.name?`, ${t.name.split(" ")[0]}`:""]}),s.jsx("p",{className:"text-gray-400 mb-10",children:"Accede a la documentación de los productos Haka"}),i.length===0?s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 text-center",children:[s.jsx("p",{className:"text-gray-400",children:"Tu licencia no incluye acceso a documentación de ningún producto actualmente disponible."}),s.jsx("p",{className:"text-gray-500 text-sm mt-2",children:"Contacta a tu administrador o a soporte de HakaLab para ampliar tu acceso."})]}):s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:i.map(r=>s.jsx(Te,{to:r.to,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-6 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full",children:[s.jsx("img",{src:r.logo,alt:r.alt,className:`${r.logoHeight} mb-4`}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:r.description}),s.jsxs("div",{className:"mt-4 flex items-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ver documentación"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})},r.productKey))})]})})]})}function Ot({children:t}){const{user:e,loading:a}=Zl();return a?s.jsx("div",{className:"min-h-screen flex items-center justify-center bg-dark",children:s.jsx("div",{className:"w-10 h-10 border-4 border-primary border-t-transparent rounded-full animate-spin"})}):e?t:s.jsx(ew,{to:"/docs/login",replace:!0})}function Bne(){const[t,e]=k.useState(!1);return t?s.jsx("div",{className:"w-24 h-24 rounded-2xl bg-primary/10 border border-primary/20 flex items-center justify-center group-hover:bg-primary/15 transition-colors",children:s.jsxs("svg",{className:"w-11 h-11 text-primary",fill:"currentColor",viewBox:"0 0 24 24","aria-hidden":"true",children:[s.jsx("path",{d:"M10 8.64v6.72L15.27 12 10 8.64z"}),s.jsx("path",{fillRule:"evenodd",d:"M12 3c-3.09 0-5.4.2-6.88.4a2.71 2.71 0 0 0-2.3 2.2A18.7 18.7 0 0 0 2.5 12c0 2.3.2 4.2.32 5.4a2.71 2.71 0 0 0 2.3 2.2c1.48.2 3.79.4 6.88.4s5.4-.2 6.88-.4a2.71 2.71 0 0 0 2.3-2.2c.12-1.2.32-3.1.32-5.4 0-2.3-.2-4.2-.32-5.4a2.71 2.71 0 0 0-2.3-2.2C17.4 3.2 15.09 3 12 3Zm0 1.8c2.98 0 5.18.19 6.63.38.44.06.78.4.83.83.11 1.13.29 2.93.29 4.99 0 2.06-.18 3.86-.29 4.99a.92.92 0 0 1-.83.83c-1.45.19-3.65.38-6.63.38s-5.18-.19-6.63-.38a.92.92 0 0 1-.83-.83A47.6 47.6 0 0 1 4.25 12c0-2.06.18-3.86.29-4.99a.92.92 0 0 1 .83-.83C6.82 4.99 9.02 4.8 12 4.8Z",clipRule:"evenodd"})]})}
17630):s.jsx("img",{src:"/imagenes/docs-logos/videos.png",alt:"Video tutoriales",className:"w-24 h-24 object-contain",onError:()=>e(!0)})}function $u({productName:t,logo:e,logoHeight:a="h-8",docsPath:n,faqPath:i,videosPath:r}){const{user:o,logout:l}=Zl();return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(Te,{to:"/docs",className:"text-gray-400 hover:text-white transition-colors text-sm",children:"â Productos"}),s.jsx("span",{className:"text-gray-600",children:"|"}),s.jsx("span",{className:"text-white font-semibold text-lg",children:t})]}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:o==null?void 0:o.email}),s.jsx("button",{onClick:l,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsx("main",{className:"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16",children:s.jsxs(_.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.4},className:"text-center",children:[e&&s.jsx("img",{src:e,alt:t,className:`${a} mx-auto mb-6`}),s.jsx("p",{className:"text-gray-400 mb-12",children:"¿Qué necesitas?"}),s.jsxs("div",{className:`grid grid-cols-1 gap-6 mx-auto ${r?"md:grid-cols-3 max-w-4xl":"md:grid-cols-2 max-w-2xl"}`,children:[s.jsx(Te,{to:n,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full text-center",children:[s.jsx("div",{className:"flex items-center justify-center mx-auto mb-4",children:s.jsx("img",{src:"/imagenes/docs-logos/documentacion.png",alt:"Documentación",className:"w-24 h-24 object-contain"})}),s.jsx("h2",{className:"text-white font-semibold text-lg mb-2",children:"Documentación"}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:"GuÃas de uso, configuración, referencia técnica y ejemplos."}),s.jsxs("div",{className:"mt-5 flex items-center justify-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ir a la documentación"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})}),s.jsx(Te,{to:i,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full text-center",children:[s.jsx("div",{className:"flex items-center justify-center mx-auto mb-4",children:s.jsx("img",{src:"/imagenes/docs-logos/preguntas.png",alt:"Preguntas frecuentes",className:"w-24 h-24 object-contain"})}),s.jsx("h2",{className:"text-white font-semibold text-lg mb-2",children:"Preguntas frecuentes y soporte"}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:"Respuestas a preguntas comunes y formulario para crear un ticket de soporte."}),s.jsxs("div",{className:"mt-5 flex items-center justify-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ver preguntas y soporte"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})}),r&&s.jsx(Te,{to:r,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full text-center",children:[s.jsx("div",{className:"flex items-center justify-center mx-auto mb-4",children:s.jsx(Bne,{})}),s.jsx("h2",{className:"text-white font-semibold text-lg mb-2",children:"Video tutoriales"}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:"Curso en video paso a paso, desde la instalación hasta pruebas móviles."}),s.jsxs("div",{className:"mt-5 flex items-center justify-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ver el curso"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})})]})]})})]})}function Une(){return s.jsx($u,{productName:"Haka Automation Engine",logo:"/imagenes/docs-logos/Automation Engine.png",logoHeight:"h-11",docsPath:"/docs/haka-playwright-engine/docs",faqPath:"/docs/haka-playwright-engine/faq",videosPath:"/docs/haka-playwright-engine/videos"})}function $ne(){return s.jsx($u,{productName:"Haka AI Studio",logo:"/imagenes/docs-logos/AI Studio.png",logoHeight:"h-8",docsPath:"/docs/haka-ai-studio/docs",faqPath:"/docs/haka-ai-studio/faq"})}function Wne(){return s.jsx($u,{productName:"HakaBoost",logo:"/imagenes/docs-logos/HakaBoost.png",logoHeight:"h-6",docsPath:"/docs/hakaboost/docs",faqPath:"/docs/hakaboost/faq"})}function Gne(){return s.jsx($u,{productName:"HakaBuddy",logo:"/imagenes/docs-logos/HakaBuddy.png",logoHeight:"h-8",docsPath:"/docs/hakabuddy/docs",faqPath:"/docs/hakabuddy/faq"})}function Kne(){return s.jsx($u,{productName:"HakaPath",logo:"/imagenes/docs-logos/HakaPath.png",logoHeight:"h-8",docsPath:"/docs/hakapath/d
17630ocs",faqPath:"/docs/hakapath/faq"})}function vj({faq:t,index:e,isOpen:a,onToggle:n}){return s.jsxs("div",{className:"border border-gray-800 rounded-lg overflow-hidden",children:[s.jsxs("button",{onClick:n,className:"w-full text-left px-5 py-4 flex items-center justify-between bg-darkGray hover:bg-darkGray/80 transition-colors",children:[s.jsx("span",{className:"text-white text-sm font-medium pr-4",children:t.question}),s.jsx("svg",{className:`w-5 h-5 text-gray-400 flex-shrink-0 transition-transform duration-200 ${a?"rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),s.jsx(La,{children:a&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.2},className:"overflow-hidden",children:s.jsx("div",{className:"px-5 py-4 text-gray-400 text-sm leading-relaxed border-t border-gray-800 bg-dark/50",children:t.answer})})})]})}function Wu({productName:t,productKey:e,logo:a,logoHeight:n="h-8",hubPath:i,faqs:r=[]}){const{user:o,logout:l}=Zl(),[c,d]=k.useState(null),[u,p]=k.useState(""),m=k.useMemo(()=>{if(!u.trim())return r;const v=u.toLowerCase();return r.filter(w=>w.question.toLowerCase().includes(v)||w.answer.toLowerCase().includes(v))},[r,u]),h=Math.ceil(m.length/2),g=m.slice(0,h),y=m.slice(h),x=v=>{d(c===v?null:v)};return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsx("div",{className:"flex items-center gap-3",children:s.jsxs(Te,{to:i,className:"text-gray-400 hover:text-white transition-colors text-sm",children:["â ",t]})}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:o==null?void 0:o.email}),s.jsx("button",{onClick:l,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsx("main",{className:"max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-12",children:s.jsxs(_.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.4},children:[s.jsxs("div",{className:"flex items-center gap-3 mb-8",children:[a&&s.jsx("img",{src:a,alt:t,className:n}),s.jsx("h1",{className:"text-2xl md:text-3xl font-bold text-white",children:"Preguntas frecuentes y soporte"})]}),r.length>0&&s.jsxs("section",{className:"mb-12",children:[s.jsxs("div",{className:"mb-6",children:[s.jsxs("div",{className:"relative max-w-md",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",value:u,onChange:v=>{p(v.target.value),d(null)},placeholder:"Buscar en preguntas frecuentesâ¦",className:"w-full bg-darkGray border border-gray-700 rounded-lg pl-10 pr-4 py-2.5 text-white text-sm placeholder-gray-500 focus:outline-none focus:border-primary/50 transition-colors"}),u&&s.jsx("button",{onClick:()=>p(""),className:"absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-300",children:s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),u&&s.jsxs("p",{className:"text-gray-500 text-xs mt-2",children:[m.length," resultado",m.length!==1?"s":"",' para "',u,'"']})]}),m.length===0?s.jsxs("div",{className:"text-center py-8",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"No se encontraron preguntas que coincidan con tu búsqueda."}),s.jsx("button",{onClick:()=>p(""),className:"text-primary text-sm mt-2 hover:underline",children:"Limpiar búsqueda"})]}):s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s.jsx("div",{className:"space-y-2",children:g.map(v=>{const w=r.indexOf(v);return s.jsx(vj,{faq:v,index:w,isOpen:c===w,onToggle:()=>x(w)},w)})}),s.jsx("div",{className:"space-y-2",children:y.map(v=>{const w=r.indexOf(v);return s.jsx(vj,{faq:v,index:w,isOpen:c===w,onToggle:()=>x(w)},w)})})]})]})]})})]})}const Jne=[{question:"¿Cómo instalo Haka Playwright Engine?",answer:'Hay dos formas: (1) Con haka-init: crea una carpeta, activa un entorno virtual, ejecuta "pip install haka-playwright-engine" y luego "haka-init" para generar toda la estructura. Después "pip install -r requirements.txt" y "playwright install". (2) Desde el repositorio: clona https://github.com/HakaLab-2025/Engine-Playwright-Base,
17630crea un venv y ejecuta "pip install -r requirements.txt" seguido de "playwright install".'},{question:"¿Qué versión de Python necesito?",answer:"Python 3.11 o superior. Recomendamos 3.11 por compatibilidad y rendimiento."},{question:"¿Qué navegadores soporta?",answer:"Chromium, Firefox y WebKit (Safari) a través de Playwright. También soporta pruebas mobile con Appium y desktop con PyAutoGUI/OCR."},{question:"¿Funciona en Windows, macOS y Linux?",answer:'SÃ. El framework funciona en cualquier sistema operativo donde Python y Playwright estén soportados. En Linux CI, usa "playwright install --with-deps chromium" para instalar dependencias del sistema.'},{question:"¿Necesito instalar Playwright por separado?",answer:'Playwright se instala como dependencia de pip, pero debes ejecutar "playwright install" una vez para descargar los binarios de los navegadores. En CI/CD usa "playwright install --with-deps chromium".'},{question:"¿Cuáles son las opciones de instalación?",answer:"pip install haka-playwright-engine (básica), haka-playwright-engine[ai] (con IA/self-healing), haka-playwright-engine[ocr] (con OCR para desktop), haka-playwright-engine[salesforce] (con frontdoor.jsp) o haka-playwright-engine[all] (todo incluido)."},{question:"¿Cómo creo un proyecto nuevo?",answer:'Ejecuta "haka-init" en terminal. Crea automáticamente la estructura de carpetas (features/, steps/, json_poms/, .env, environment.py, behave.ini) con plantillas listas para usar.'},{question:"¿Qué es el archivo .env y qué contiene?",answer:"Es el archivo de configuración principal. Define navegador (BROWSER), modo headless (HEADLESS), timeouts (TIMEOUT), URLs (BASE_URL), credenciales (TEST_EMAIL/TEST_PASSWORD), screenshots, reportes, IA, integraciones, y más de 60 variables configurables."},{question:"¿Puedo tener diferentes .env por ambiente (QA, staging, prod)?",answer:'SÃ. Crea archivos como qa.env, staging.env, prod.env y ejecútalos con: haka-run --env staging.env. También puedes usar "haka-validate --env-file staging.env" para validar cada uno.'},{question:"¿Qué es behave.ini?",answer:"Archivo de configuración de Behave (el motor BDD). Define paths de features, formato de salida, tags por defecto, etc. El framework lo genera automáticamente con haka-init."},{question:"¿Qué es environment.py?",answer:"Archivo de hooks de Behave. Define qué pasa antes/después de cada escenario, feature o toda la ejecución. El framework proporciona hooks pre-configurados para screenshots, reportes HTML, manejo de browser, etc."},{question:"¿Qué son los JSON POMs?",answer:"Son archivos JSON que almacenan los selectores/localizadores de los elementos de cada página. En vez de hardcodear selectores en los steps, los referencias como $.PAGINA.elemento. Esto centraliza el mantenimiento: si un selector cambia, se actualiza en un solo lugar."},{question:"¿Cómo se estructura un JSON POM?",answer:'Cada archivo se llama en MAYUSCULAS (ej: LOGIN.json) y contiene pares clave-valor: {"campo_email": "input#email", "boton_submit": "button[type=submit]"}. Los selectores pueden ser CSS, XPath, text, placeholder, role o data-testid.'},{question:"¿Cómo referencio un elemento del POM en un step?",answer:'Usa la sintaxis $.PAGINA.elemento. Ejemplo: When hago click en el elemento "$.LOGIN.boton_submit". El framework resuelve el selector del JSON automáticamente.'},{question:"¿Puedo usar selectores directos sin POM?",answer:'SÃ. Puedes usar selectores inline: When hago click en el elemento "button#submit". Ãtil para pruebas rápidas, pero para mantenibilidad se recomienda POM.'},{question:"¿Los POMs soportan selectores dinámicos?",answer:`SÃ. Usa placeholders con {valor}: {"fila_tabla": "//tr[contains(.,'{valor}')]"}. En el step: When hago click en el elemento "$.TABLA.fila_tabla" con valor "Producto A". El {valor} se reemplaza dinámicamente.`},{question:"¿Cómo ejecuto las pruebas?",answer:'Tienes varias opciones: "behave" (todas), "behave features/login.feature" (un archivo), "behave -t @smoke" (por tag), o "haka-run --parallel 4" (paralelo con 4 workers).'},{question:"¿Cómo ejecuto pruebas en paralelo?",answer:'Usa "haka-run --parallel N" donde N es la cantidad de workers. Cada worker ejecuta features independientes con su propio browser. Para CI/CD también puedes usar sharding entre jobs.'},{question:"¿Cómo filtro qué pruebas ejecutar?",answer:'Usa tags de Behave: @smoke, @regression, @api, etc. Ejecuta con "behave -t @smoke" o "behave -t @smoke,@login" (OR) o "behave -t @smoke -t @web" (AND). También puedes excluir: "behave -t ~@slow".'},{question:"¿Puedo ejecutar en modo headless?",answer:"SÃ. Configura HEADLESS=true en tu .env. Es obligatorio en CI/CD (no hay pantalla). Para desarrollo local usa HEADLESS=false para ver el navegador."},{question:"¿Qué es SLOW_MO y para qué sirve?",answer:"SLOW_MO=500 agrega 500ms de pausa entre cada acción de Playwright. Ãtil para debugging visual: ves exactamente qué hace el framework paso a paso. No uses en CI/CD."},{question:"¿Cómo depuro un test que falla?",answer:"Usa PWDEBUG=1 behave para abrir Playwright Inspector (pausas interactivas). También puedes usar SLOW_MO=500, HEADLESS=false y SCREENSHOT_ON_FAILURE=true para investigar visualmente."},{question:"¿Cuántos steps tiene el framework?",answer:"Más de 500 steps únicos con 1100+ variantes. Cubren: web (clicks, formularios, navegación, validaciones), API REST, mobile, desktop, base de datos, email, archivos, GenAI, accesibilidad, performance y más."},{question:"¿Los steps están en español o inglés?",answer:'Ambos. Cada step tiene alias en español e inglés, y puedes mezclarlos en el mismo feature. Ejemplo: "Given voy a la url" y "Given I go to the url" son equivalentes.'},{question:"¿Cómo veo la lista completa de steps?",answer:'Ejecuta "haka-steps" en terminal. Muestra todos los steps disponibles organizados por categorÃa con su sintaxis exacta y parámetros.'},{question:"¿Puedo crear steps personalizados?",answer:"SÃ. Crea archivos .py en tu carpeta steps/ con decoradores @given/@when/@then de Behave. Puedes usar el contexto del framework (context.page, context.browser) y componer steps existentes con execute_steps()."},{question:"¿Qué es un Scenario Outline y cómo lo uso?",answer:"Es un escenario parametrizado con tabla Examples. El mismo escenario se ejecuta N veces con diferentes datos. Usa <variable> en los steps y define los valores en la tabla Examples debajo."}
17630,{question:"¿Qué es Background?",answer:"Pasos comunes que se ejecutan ANTES de cada Scenario en un Feature. TÃpicamente contiene la navegación inicial y login. Evita repetir los mismos Given en cada escenario."},{question:"¿Cómo uso variables del .env en los steps?",answer:'Usa la sintaxis ${ENV.NOMBRE}. Ejemplo: Given voy a la url "${ENV.BASE_URL}". El framework reemplaza el valor antes de ejecutar el step.'},{question:"¿Puedo generar datos aleatorios?",answer:"SÃ. El framework genera: texto aleatorio (${RANDOM_TEXT}), números (${RANDOM_NUMBER}), emails (${RANDOM_EMAIL}), RUT (${RANDOM_RUT}), fechas (${TODAY}, ${TOMORROW}, ${BUSINESS_DAY+5}), timestamps y más."},{question:"¿Cómo extraigo un valor de la página a una variable?",answer:'Usa: Then guardo el texto del elemento "$.PAGINA.precio" en la variable "precio_actual". Después referénciala con ${precio_actual} en steps posteriores.'},{question:"¿Las variables se comparten entre escenarios?",answer:"Por defecto cada escenario es independiente. Para compartir variables entre escenarios del mismo feature, usa variables de contexto global o extracciones en Background."},{question:"¿Cómo hago click en un elemento?",answer:'When hago click en el elemento "$.PAGINA.boton" (con POM) o When hago click en el elemento "button#submit" (selector directo). Soporta click simple, doble click, click derecho y click con offset.'},{question:"¿Cómo lleno un campo de texto?",answer:'When relleno el campo "$.LOGIN.email" con "[email protected]". También: When limpio y relleno el campo (borra antes), When escribo lentamente (simula humano con delays).'},{question:"¿Cómo manejo dropdowns/selects?",answer:'When selecciono la opción "Chile" en el select "$.FORM.pais". Soporta selección por texto visible, por valor y por Ãndice.'},{question:"¿Cómo subo archivos?",answer:'When adjunto el archivo "datos.pdf" en el campo "$.FORM.upload". El archivo debe estar en la carpeta del proyecto o usa ruta absoluta.'},{question:"¿Cómo manejo iframes?",answer:'When cambio al iframe "$.PAGINA.iframe_pago". Después interactúas normalmente con los elementos dentro. Para volver: When vuelvo al contexto principal.'},{question:"¿Cómo manejo múltiples pestañas/ventanas?",answer:'El framework detecta nuevas pestañas automáticamente. Usa: When cambio a la pestaña "2" (por Ãndice) o When cambio a la pestaña que contiene "checkout" (por URL/tÃtulo).'},{question:"¿Cómo hago drag & drop?",answer:'When arrastro el elemento "$.BOARD.tarea" al elemento "$.BOARD.columna_done". El sistema tiene múltiples fallbacks para máxima compatibilidad con diferentes frameworks frontend.'},{question:"¿Cómo manejo alertas/diálogos del navegador?",answer:'When acepto la alerta / When rechazo la alerta / Then verifico que la alerta contiene "¿Estás seguro?". El framework intercepta alerts, confirms y prompts automáticamente.'},{question:"¿Cómo verifico que un texto es visible en la página?",answer:'Then verifico que el elemento "$.PAGINA.titulo" contiene el texto "Bienvenido". También: Then el texto "Bienvenido" es visible en la página (sin selector especÃfico).'},{question:"¿Qué son las Soft Assertions?",answer:"Validaciones que NO detienen el test al fallar. Se acumulan y se reportan al final. ActÃvalas con el tag @soft_assertions en el Scenario. Ãtil para verificar múltiples campos en un formulario."},{question:"¿Puedo validar atributos CSS o HTML?",answer:'SÃ. Then verifico que el atributo "class" del elemento "$.FORM.campo" contiene "error". También valida estilos computados, visibilidad, habilitado/deshabilitado, checked, etc.'},{question:"¿Puedo hacer pruebas de API sin navegador?",answer:"SÃ. Usa el tag @no_browser en el Scenario. Los steps de API (GET, POST, PUT, DELETE, PATCH) funcionan sin abrir navegador. Valida status codes, body, headers y tiempos de respuesta."},{question:"¿Cómo hago una petición POST con body JSON?",answer:'When envÃo una petición POST a "/api/users" con body: (seguido de un DocString JSON). También puedes cargar el body desde archivo: When envÃo una petición POST a "/api/users" con el archivo "payload.json".'},{question:"¿Puedo validar un JSON Schema en la respuesta?",answer:'SÃ. Then la respuesta cumple con el JSON Schema del archivo "schemas/user.json". Valida tipos, campos requeridos, formatos y estructura completa.'},{question:"¿Puedo interceptar peticiones de red del navegador?",answer:"SÃ. El framework permite capturar requests/responses que hace el frontend (XHR/fetch) y validar su contenido, headers o status. Ãtil para verificar que el frontend envÃa los datos correctos al backend."},{question:"¿Puedo hacer pruebas mobile con este framework?",answer:"SÃ. Soporta Android e iOS mediante Appium. Los steps mobile cubren: taps, swipes, scroll, pinch/zoom, rotación, te
17630clado, navegación del dispositivo (back/home), y verificaciones de elementos nativos."},{question:"¿Qué necesito para pruebas mobile?",answer:"Appium Server instalado, el driver correspondiente (UiAutomator2 para Android, XCUITest para iOS), y un dispositivo/emulador. Configura APPIUM_URL, PLATFORM_NAME, DEVICE_NAME y APP_PATH en .env."},{question:"¿Los JSON POMs funcionan diferente en mobile?",answer:`SÃ. En mobile los POMs usan formato {"by": "xpath", "value": "//XCUIElementTypeButton[@name='Login']"} en vez del selector directo. Esto permite especificar la estrategia de localización (xpath, id, accessibility_id, class_name).`},{question:"¿Puedo automatizar aplicaciones de escritorio?",answer:"SÃ. El framework soporta testing desktop con PyAutoGUI (clicks por coordenadas o por imagen), OCR (lectura de texto en pantalla) y modo mixto web+desktop (combina navegador con app nativa)."},{question:"¿Cómo funciona el click por imagen en desktop?",answer:"Capturas un screenshot del botón/elemento como referencia (imagen PNG). El step busca esa imagen en la pantalla y hace click en su centro. Ãtil para apps sin accesibilidad expuesta."},{question:"¿Puedo conectarme a una base de datos durante los tests?",answer:"SÃ. Soporta SQLite, PostgreSQL y MySQL. Puedes ejecutar SELECT para validar datos, INSERT/UPDATE/DELETE para preparar escenarios, y guardar resultados en variables para usar en steps posteriores."}
17630,{question:"¿Puedo combinar pruebas web con validaciones de BD?",answer:"SÃ. Un mismo Scenario puede: crear un registro vÃa web, luego verificar con un SELECT que se guardó correctamente en la base de datos."},{question:"¿Qué proveedores de IA soporta?",answer:"Gemini (Google), OpenAI (GPT), Anthropic (Claude), Ollama (local/offline) y Azure OpenAI. Se auto-detecta por API keys presentes o se configura con AI_PROVIDER en .env."},{question:"¿Qué es el Self-Healing?",answer:"Cuando un selector falla (elemento no encontrado), la IA analiza el HTML de la página y sugiere selectores alternativos automáticamente. Configura SELF_HEALING_ENABLED=true en .env. Funciona con cualquier proveedor de IA."},{question:"¿Puedo hacer testing de sistemas de IA Generativa?",answer:"SÃ. Hay 20+ steps especializados para validar respuestas de IA: detección de alucinaciones, validación semántica, testing adversarial (jailbreaking), análisis de bias/toxicidad, validación de idioma, y Gemini como juez evaluador."},{question:"¿Qué es el AI Analysis Report?",answer:"Tras una ejecución, la IA analiza los resultados y genera un reporte con: causa raÃz probable de cada fallo, sugerencias de corrección, tendencias de estabilidad y recomendaciones. Se configura con AI_ANALYSIS_REPORT=true."},{question:"¿Ollama funciona sin internet?",answer:"SÃ. Ollama corre un modelo de IA localmente en tu máquina. Configura AI_PROVIDER=ollama y AI_MODEL=llama3.1. No requiere API key ni conexión, ideal para entornos on-premises o con restricciones de red."},{question:"¿Cómo evito repetir el login con MFA/2FA en cada test?",answer:'Usa sesiones guardadas: "haka-login --save nombre_sesion --url https://app.com/login". Esto abre un browser, te logueas manualmente (incluyendo MFA), y el estado se guarda. En los tests: Given inicio sesion guardada con el usuario "nombre_sesion".'},{question:"¿Las sesiones guardadas expiran?",answer:'SÃ. Depende del servidor: tÃpicamente 24-48 horas. Cuando expiran, recaptúralas con "haka-login --save nombre --url URL". Puedes verificar el estado con "haka-login --info nombre".'},{question:"¿Con qué sistemas funcionan las sesiones guardadas?",answer:"Con cualquier sistema que use cookies de sesión: Salesforce, SAP, Azure AD, Google Workspace, AWS Console, Okta, Auth0, y cualquier aplicación web con autenticación basada en cookies."},{question:"¿Qué reportes genera el framework?",answer:"Reporte HTML personalizado con screenshots embebidos (generado automáticamente), compatible con Allure, y opcionalmente un AI Analysis Report que usa IA para analizar resultados. Los screenshots se toman en cada fallo y opcionalmente en cada paso."},{question:"¿Cómo activo el reporte HTML?",answer:"Agrega el hook en tu environment.py (se incluye con haka-init). El reporte se genera automáticamente en html-reports/ al finalizar la ejecución."},{question:"¿Puedo tomar screenshots en cada paso, no solo al fallar?",answer:"SÃ. Configura SCREENSHOT_ON_EACH_STEP=true en .env. Ãtil para evidencia visual completa de la ejecución."},{question:"¿Es compatible con GitHub Actions / GitLab CI?",answer:"SÃ. Incluye configuraciones de ejemplo para GitHub Actions, GitLab CI, Bitbucket Pipelines y Azure DevOps. La clave es: instalar dependencias, configurar variables como secrets, ejecutar con HEADLESS=true, y subir reportes como artifacts."},{question:"¿Cómo integro con Jira / Xray?",answer:"Configura las variables XRAY_CLIENT_ID/SECRET en .env. El framework reporta resultados automáticamente a Xray Cloud tras cada ejecución. Cada tag del Scenario se mapea a un test case en Jira. No requiere código adicional."},{question:"¿Cómo integro con Haka Lens?",answer:"Configura HAKA_LENS_URL y HAKA_LENS_AUTH en .env. Los resultados se reportan automáticamente al finalizar. El tag del Scenario debe coincidir con la clave del test en Haka Lens."},{question:"¿Puedo reintentar escenarios que fallan?",answer:"SÃ. Configura RETRY_FAILED_SCENARIOS=true y MAX_SCENARIO_RETRIES=2 en .env. Los escenarios fallidos se reintentan automáticamente al final con un browser limpio. Ãtil para flakiness por timing."},{question:"¿Puedo ejecutar un step solo si un elemento está visible?",answer:'SÃ. Usa pasos condicionales: When si el elemento "$.PAGINA.cookie_banner" es visible, hago click en "$.PAGINA.aceptar_cookies". Si no es visible, el step se omite sin fallar.'},{question:"¿Cómo manejo popups/banners intermitentes?",answer:'Con pasos condicionales. El framework tiene steps tipo "si existe/es visible, entonces...". Ejemplo: When si el elemento "$.APP.popup_promo" existe, hago click en "$.APP.cerrar_popup".'},{question:"¿Puedo emular un dispositivo móvil en el browser?",answer:"SÃ. Configura VIEWPORT_WIDTH/VIEWPORT_HEIGHT en .env o usa browser_context con user_agent mobile. Playwright tiene presets de dispositivos (iPhone, Pixel, etc.)."},{question:"¿Puedo configurar geolocalización, idioma o zona horaria?",answer:"SÃ. En .env o en browser_context: GEO_LATITUDE, GEO_LONGITUDE, LOCALE (ej: es-CL), TIMEZONE (ej: America/Santiago). Ãtil para probar funcionalidades depen
17630dientes de ubicación."},{question:"¿Puedo usar proxy o modo offline?",answer:"SÃ. Configura PROXY_SERVER en .env para proxy. El framework también soporta modo offline (simular pérdida de conexión) y throttling de red."},{question:"¿Qué es Stealth Mode?",answer:"STEALTH_MODE=true hace que el navegador automatizado pase desapercibido ante detecciones anti-bot. Modifica fingerprints, headers y propiedades de navigator para simular un usuario real."},{question:"¿Tiene soporte especial para Salesforce?",answer:"SÃ. Con pip install haka-playwright-engine[salesforce] obtienes login vÃa frontdoor.jsp (bypasea MFA automáticamente vÃa API), soporte multi-sandbox/multi-usuario, y sesión reutilizable entre escenarios."},{question:"¿Por qué un test pasa local pero falla en CI?",answer:"Causas comunes: 1) HEADLESS no configurado, 2) resolución diferente (configura VIEWPORT), 3) timing más lento (aumenta TIMEOUT), 4) variables de entorno no inyectadas como secrets, 5) dependencias del sistema no instaladas (usa --with-deps)."},{question:"¿Qué hago si un elemento no se encuentra (TimeoutError)?",answer:"Verifica: 1) El selector es correcto (usa DevTools), 2) El timeout es suficiente (aumenta TIMEOUT), 3) El elemento no está en un iframe (usa step de cambio), 4) Necesita scroll previo, 5) Está detrás de una animación/loader."},{question:'¿Qué es "Step undefined" y cómo lo resuelvo?',answer:'Significa que el step que escribiste no coincide con ningún paso del framework. Verifica la sintaxis exacta con "haka-steps". Los steps son sensibles a espacios, comillas y parámetros.'},{question:"¿Cómo valido que mi .env está correcto?",answer:'Ejecuta "haka-validate" en terminal. Detecta: variables mal escritas (typos por Levenshtein), valores inválidos, dependencias cruzadas (ej: self-healing requiere API key de IA), y genera un reporte de la configuración.'},{question:"¿Puedo ver un video de la ejecución?",answer:"SÃ. Configura VIDEO_RECORDING=true en .env. Playwright graba un video de cada escenario que se guarda en la carpeta de reportes. Ãtil para debugging de tests inestables."},{question:"¿El framework genera un .env de ejemplo?",answer:'SÃ. Ejecuta "haka-validate --generate-env" para generar un archivo .env.example con todas las variables documentadas y sus valores por defecto.'}],Qne=[{question:"¿Cómo instalo Haka AI Studio?",answer:'Descarga el archivo .vsix y ejecuta en terminal: code --install-extension haka-ai-studio-1.6.3.vsix. También puedes instalarlo desde VS Code: Extensiones â menú ⯠â "Install from VSIXâ¦" y seleccionar el archivo.'},{question:"¿Qué versión de VS Code necesito?",answer:"Se requiere VS Code 1.85.0 o superior. Recomendamos mantener VS Code actualizado para evitar incompatibilidades."},{question:"¿Necesito instalar algo más además de la extensión?",answer:'Para grabar con Playwright necesitas Node.js 18+ y ejecutar "npx playwright install" una vez para descargar los navegadores. Para Selenium necesitas el driver del navegador correspondiente (chromedriver, geckodriver).'},{question:"¿Funciona en Windows, macOS y Linux?",answer:"SÃ. La extensión funciona en cualquier sistema operativo donde VS Code esté soportado."},{question:"¿Es compatible con VS Code remoto (SSH, WSL, Containers)?",answer:"La extensión funciona en VS Code local. En entornos remotos puede haber limitaciones con el grabador (que necesita un navegador visible), pero la edición de .feature, @aistudio, Kai y las funcionalidades de editor funcionan normalmente."},{question:"¿Cómo inicio sesión?",answer:"Al abrir el panel por primera vez, acepta los Términos de Uso y luego inicia sesión con tu cuenta de Google o con tu clave de licencia HakaLab. Los usuarios @hakalab.com tienen acceso completo con Google."},{question:"¿La licencia es por usuario o por dispositivo?",answer:"Es por dispositivo. Cada licencia se vincula al primer equipo donde se activa. Si cambias de computador, debes cerrar sesión en el anterior o contactar a soporte para liberar la licencia."},{question:'¿Qué hago si me aparece "Licencia ya en uso en otro dispositivo"?',answer:"Asegúrate de cerrar sesión en tu equipo anterior. Si no tienes acceso a ese equipo, contacta a soporte en [email protected] para que liberen tu licencia."},{question:"¿Qué proveedor de IA debo usar?",answer:"Recomendamos Gemini (Google) por su relación costo/beneficio: es ~25 veces más barato que OpenAI y genera resultados de calida
17630d comparable para pruebas automatizadas. El modelo recomendado es gemini-2.0-flash."},{question:"¿Cuánto cuesta usar la IA?",answer:"Con Gemini 2.0 Flash, cada generación de test cuesta aproximadamente $0.003 USD. Para un uso normal de ~100 generaciones al mes, el costo es alrededor de $0.20 USD/mes. OpenAI es más caro (~$0.01/test) y Claude intermedio (~$0.008/test)."},{question:"¿Dónde obtengo mi API Key de Gemini?",answer:"Ve a https://aistudio.google.com/apikey y crea una clave gratuita. Google ofrece un nivel gratuito generoso. Luego pega la clave en Config â Gemini AI â API Key."},{question:"¿Puedo usar OpenAI o Claude en vez de Gemini?",answer:"SÃ. La arquitectura soporta los tres proveedores. Configura tu API Key del proveedor preferido en la pestaña Config. Sin embargo, Gemini es el recomendado por costo y es el más probado."},{question:"¿Mis datos o código se envÃan a la nube?",answer:"Solo se envÃa la grabación del navegador (acciones realizadas) al proveedor de IA para generar el test. No se almacena código en servidores de HakaLab. La comunicación es directa entre tu VS Code y el proveedor de IA por HTTPS."},{question:"¿Dónde se almacena mi API Key?",answer:"En el almacenamiento cifrado de VS Code (context.secrets). Nunca se guarda en texto plano ni se envÃa a HakaLab."},{question:"¿Qué es Koru y cómo funciona?",answer:"Koru es el grabador de interacciones. Abre un navegador, graba todo lo que haces (clics, escritura, navegación) y luego usa IA para convertir esas acciones en un test Gherkin completo con Feature, Steps y Page Objects."},{question:"¿Qué navegadores puedo usar para grabar?",answer:"Con Playwright: Chromium, Chrome, Edge, Firefox y WebKit (Safari). Con Selenium: Chrome y Firefox. La resolución del navegador es configurable."},{question:"¿Cuál es la diferencia entre grabar con Playwright y Selenium?",answer:"Playwright usa el modo codegen nativo (más estable, captura selectores robustos). Selenium captura XPaths. Elige según el framework que uses para ejecutar las pruebas: si usas haka-playwright-engine, graba con Playwright."},{question:"¿Puedo grabar en un sitio que requiere login con MFA/2FA?",answer:'SÃ. Koru soporta "sesiones guardadas": puedes guardar el estado de autenticación (cookies, localStorage, sessionStorage) cifrado con Fernet. Al grabar, selecciona el perfil de sesión y el navegador se abre ya autenticado sin repetir el login.'},{question:"¿Cómo guardo una sesión para no repetir el login?",answer:'En Koru, después de loguearte manualmente una vez, usa la opción "Guardar sesión". La próxima vez que grabes, selecciona esa sesión antes de iniciar y el navegador se abrirá ya logueado.'},{question:"El grabador no se abre o muestra error al iniciar",answer:'Verifica que Playwright esté instalado: ejecuta "npx playwright install" en terminal. Si usas Selenium, verifica que el driver del navegador esté en tu PATH. También revisa que no haya otra instancia del grabador abierta.'},{question:"¿Puedo agregar validaciones (Then) después de grabar?",answer:"SÃ. Después de detener la grabación, hay una etapa para agregar validaciones antes de generar con IA. Puedes verificar textos visibles, estados de elementos, URLs, etc."},{question:"¿Qué genera la IA después de grabar?",answer:"Genera un archivo .feature completo con escenarios Gherkin, los archivos de steps (implementaciones Python) y Page Objects con los selectores de los elementos utilizados. Todo listo para ejecutar."},{question:"¿Qué es @aistudio y cómo lo uso?",answer:'Es un asistente inteligente que funciona dentro de archivos .feature. Escribe @aistudio seguido de lo que buscas para encontrar steps existentes. Agrega "?" para pedirle a la IA que genere algo nuevo.'},{question:"¿Cuál es la diferencia entre @aistudio y @aistudio?",answer:'Sin "?" busca en tus archivos locales y en los 1187 vectores del framework (instantáneo). Con "?" consulta a la IA generativa para crear steps o escenarios nuevos (tarda 1-5 segundos).'},{question:"¿@aistudio funciona sin conexión a internet?",answer:'La búsqueda local (sin "?") funciona offline porque escanea tus archivos .feature. La generación con IA (con "?") necesita conexión para consultar al proveedor.'},{question:"¿Puedo generar un Feature completo con @aistudio?",answer:'SÃ. Escribe algo como "@aistudio? genera todos los escenarios para un CRUD de usuarios" y la IA genera un Feature completo con Backgroun
17630d, Scenario Outline y Examples.'},{question:"@aistudio no muestra sugerencias",answer:'Verifica que estás en un archivo .feature y que el workspace contiene archivos .feature escaneados. Si usas "?" verifica que tu API Key esté configurada en Config. Revisa la barra de estado de VS Code por mensajes de error.'},{question:"¿Qué es Kai?",answer:"Kai es un chat con IA especializado en automatización de pruebas. Tiene conocimiento vectorizado del framework haka-playwright-engine y puede ayudarte con consultas sobre steps, mejores prácticas, debugging de tests y explicación de código generado."},{question:"¿Kai conoce mi proyecto o solo el framework?",answer:"Kai conoce los 1187 vectores del framework haka-playwright-engine y además puede consultar los archivos .feature de tu proyecto actual para dar respuestas contextualizadas."},{question:"¿Puedo preguntarle a Kai cómo resolver un error de ejecución?",answer:"SÃ. Pega el error o describe el problema y Kai te sugerirá soluciones basándose en el framework y mejores prácticas de automatización."},{question:"¿Los archivos .feature se colorean automáticamente?",answer:"SÃ. Al instalar la extensión, todos los archivos .feature reciben syntax highlighting automático con colores para keywords, steps, tags, variables, tablas y comentarios. Soporta Gherkin en español, inglés, francés, portugués y alemán."},{question:"¿Puedo personalizar los colores del Gherkin?",answer:"SÃ. En Config â Cucumber / Gherkin hay 7 color pickers que se aplican en tiempo real al editor. También puedes activar negrita en keywords y cursiva en tags/comentarios."},{question:"¿Cómo formateo un archivo .feature?",answer:'Clic derecho â "Haka: Formatear Documento (.feature)" o usa Ctrl+Shift+I. Alinea tablas, corrige indentación (Featureâ0, Scenarioâ2, Stepsâ4) y elimina espacios sobrantes.'},{question:'¿Qué hace "Convertir en Scenario Outline"?',answer:"Toma un Scenario normal, extrae los valores entre comillas, los reemplaza por variables (<param>) y genera una tabla Examples. No parametriza identificadores de Page Object ($.PAGINA.elemento)."},{question:"¿Go to Definition funciona con steps del framework?",answer:"Go to Definition (Ctrl+Click o F12) navega a la implementación si está en tus carpetas /steps/*.py. Si el step pertenece al framework, muestra un mensaje indicando que es interno de haka-playwright-engine."},{question:"¿Qué muestra el Hover sobre un step?",answer:"Muestra en cuántos archivos y escenarios se usa ese mismo step en tu proyecto, con la ruta y número de lÃnea de cada ocurrencia. Ãtil para entender el impacto de modificar un step."},{question:"¿Qué es la pestaña Rest?",answer:"Permite generar archivos .feature de pruebas REST (API) a partir de archivos OpenAPI/Swagger, colecciones Postman o comandos cURL. Genera escenarios de prueba para cada endpoint."},{question:"¿Qué es el Mock Server?",answer:"Es un servidor HTTP local configurable que simula APIs. Puedes definir endpoints con respuestas JSON personalizadas, status codes, delays y CORS. Ãtil para probar tu frontend sin depender del backend real."},{question:"¿En qué puerto corre el Mock Server?",answer:"El puerto es configurable. Por defecto usa un puerto libre disponible. Puedes cambiarlo en la configuración del mock."},{question:"¿En qué formato genera el código?",answer:"Genera archivos .feature (Gherkin), archivos de steps en Python (compatibles con Behave) y Page Objects en formato JSON. Todo listo para ejecutar con haka-playwright-engine o adaptable a otros frameworks."},{question:"¿El código generado sobrescribe mis archivos?",answer:"No. La exportación tiene lógica de merge inteligente: detecta imports y steps existentes y solo agrega lo nuevo. No duplica imports ni definiciones de steps que ya existan."},{question:"¿Puedo personalizar el prompt que usa la IA para generar?",answer:'SÃ. En Config â "Instrucción adicional" puedes escribir un prompt personalizado que se agrega al contexto de la IA. Ãtil para indicar convenciones de tu equipo o reglas especÃficas.'},{question:"¿El código generado es compatible con mi framework?",answer:"Está optimizado para haka-playwright-engine (Playwright + Behave), pero el formato Gherkin es universal. Para Selenium, el grabador genera código compatible con el motor Selenium del framework."},{question:"¿Qué es la vectorización?",answer:"Es un proceso que escanea los steps de tu proyecto y los convierte en representaciones numéricas (embeddings) para que @aistudio pueda buscar steps similares semánticamente, no solo por texto exacto."},{question:"¿Necesito vectorizar cada vez que agrego steps nuevos?",answer:'SÃ. Si agregas steps propios (no del framework), ejecuta la vectorización desde Config â Vectorización â "Escanear y vectorizar steps custom" para que @aistudio los encuentre.'},{question:"¿Los 1187 vectores del framework vienen pre-incluidos?",answer:"SÃ. Cubren Web (481), Validaciones (151), GuÃas (143), API (130), Mobile (129), Desktop (87), GenAI (52) y Base de Datos (14). Se buscan automáticamente sin necesidad de vectorizar nada."},{question:"La extensión no aparece en la barra de actividad",answer:"Reinicia VS Code después de instalar. Si persiste, verifica que el .vsix se instaló correctamente en Extensiones â Installed. Si aparece deshabilitada, habilÃtala manualmente."},{question:"La IA genera código con errores o steps que no existen",answer:'Esto puede pasar con prompts muy vagos. Sé más especÃfico en tus instrucciones. También puedes agregar contexto en Config â "Instru
17630cción adicional" indicando los steps disponibles o el formato preferido.'},{question:"El grabador se cierra inesperadamente",answer:'Puede deberse a falta de memoria, un navegador corrupto o un conflicto de puertos. Reinstala los navegadores con "npx playwright install" y verifica que ningún otro proceso use el puerto del grabador.'},{question:"No puedo conectarme al proveedor de IA (error de red)",answer:"Verifica tu conexión a internet. Si estás detrás de un proxy corporativo, configura las variables de entorno HTTP_PROXY/HTTPS_PROXY. También confirma que tu API Key sea válida y no haya expirado."},{question:"Los colores de Gherkin no se aplican",answer:'Asegúrate de que el archivo tenga extensión .feature. Si usas un tema de VS Code que sobreescribe los colores, ve a Config â Cucumber/Gherkin y ajusta los colores manualmente. El botón "Restablecer" vuelve a los valores por defecto.'},{question:"¿Cómo actualizo la extensión?",answer:"Descarga el nuevo .vsix y ejecuta code --install-extension haka-ai-studio-X.Y.Z.vsix. La nueva versión reemplaza la anterior automáticamente. Tu configuración y API Keys se conservan."},{question:"¿Haka AI Studio es compatible con otras extensiones de Gherkin/Cucumber?",answer:"Puede haber conflictos de syntax highlighting si tienes otra extensión de Gherkin instalada. Recomendamos desactivar las demás extensiones de Cucumber/Gherkin para evitar que se sobreescriban los colores o el completado."},{question:"¿La extensión recopila datos o telemetrÃa?",answer:"No. Haka AI Studio no envÃa telemetrÃa, no rastrea tu uso y no almacena datos en servidores de HakaLab. La única comunicación externa es con tu proveedor de IA configurado."},{question:"¿Las sesiones guardadas son seguras?",answer:"SÃ. Se cifran con Fernet (AES-128-CBC) y se almacenan localmente. La clave de cifrado está en el almacenamiento seguro de VS Code. Nadie sin acceso a tu equipo puede leer las sesiones."}],Xne=[{question:"¿Qué es HakaBoost?",answer:"Es una extensión de Chrome que actúa como copiloto de calida
17630d para equipos QA. Se integra como panel lateral en Jira Cloud y Azure DevOps, y usa IA para mejorar descripciones de tareas, generar escenarios de prueba en Gherkin, crear tests automáticamente y analizar cobertura."},{question:"¿Necesito saber programar para usarlo?",answer:"No. HakaBoost está diseñado para QA Analysts, Product Owners y cualquier persona que escriba o revise historias de usuario. La IA genera los escenarios de prueba automáticamente en formato Gherkin (lenguaje natural estructurado)."},{question:"¿En qué plataformas funciona?",answer:"Jira Cloud (*.atlassian.net) y Azure DevOps (dev.azure.com). Detecta automáticamente en cuál estás navegando y adapta su interfaz. No funciona en Jira Server/Data Center."},{question:"¿Cómo instalo HakaBoost?",answer:'Desde la Chrome Web Store, busca "HakaBoost" e instala. Aparecerá en tu barra de extensiones. También puedes cargarlo manualmente desde chrome://extensions en modo desarrollador.'},{question:"¿Qué navegador necesito?",answer:"Google Chrome 120 o superior (Manifest V3). También funciona en navegadores basados en Chromium (Edge, Brave) si soportan el Chrome Web Store."},{question:"¿Cómo abro el panel de HakaBoost?",answer:"Navega a un issue/work item en Jira o Azure DevOps, luego haz clic en el Ãcono de HakaBoost o usa el atajo Ctrl+Shift+Y (Windows) / Cmd+Shift+Y (Mac). Se abrirá como panel lateral."},{question:"¿Cuál es la diferencia entre Free y Pro?",answer:"Free: mejorar descripción + sugerir tests (funciones base). Pro: todo lo anterior + Análisis de calidad (recomendaciones, riesgos), Datos de prueba (válidos/inválidos/lÃmite), Análisis de cobertura (gaps), ofuscación personalizable, exportación a PDF y publicación como comentario."},{question:"¿Cómo me registro en el plan Free?",answer:'Al abrir HakaBoost por primera vez, selecciona "Free" e ingresa nombre, email y empresa. No requiere contraseña. Es inmediato.'},{question:"¿Cómo accedo al plan Pro?",answer:"Tres opciones: 1) Con clave de licencia (email + key), 2) Con Google (dominios autorizados), 3) Con Microsoft (dominios autorizados). Los clientes de Haka Lab tienen acceso Pro gratuito con su cuenta Google corporativa."},{question:"¿La licencia Pro es por usuario o por dispositivo?",answer:"Por dispositivo. Cada licencia se vincula al equipo donde la activas. Si inicias sesión en otro equipo, la sesión anterior se cierra automáticamente (detecta sesión concurrente)."},{question:'¿Qué pasa si me dice "sesión en otro dispositivo"?',answer:"Significa que la misma licencia se usó en otro equipo. Solo puede estar activa en uno a la vez. Si tú no la usaste en otro lugar, contacta a soporte ([email protected]) para verificar."},{question:"¿Qué motores de IA soporta?",answer:"Tres opciones: 1) Chrome Built-in AI (Gemini Nano) â 100% local, sin costo, sin enviar datos a internet. 2) Google Gemini (cloud) â modelos como gemini-2.5-flash. 3) OpenAI (cloud) â modelos como gpt-4o-mini."},{question:"¿Qué es Chrome Built-in AI?",answer:"Es el modelo Gemini Nano que corre directamente en tu computador dentro de Chrome, sin enviar datos a ningún servidor. Es gratuito, privado y no requiere API key. La primera vez descarga ~5GB del modelo."},{question:"¿Cuál IA me recomiendan?",answer:"Si la privacidad es prioridad: Chrome Built-in AI (100% local). Si necesitas la mejor calidad de resultados: Gemini Cloud (gemini-2.5-flash es rápido y económico). OpenAI es una alternativa si ya tienes cuenta."},{question:"¿Dónde obtengo mi API Key de Gemini u OpenAI?",answer:"Gemini: https://aistudio.google.com/apikey (gratis con lÃmites generosos). OpenAI: https://platform.openai.com/api-keys (requiere cuenta con créditos). Pega la key en Configuraciones â IA."},{question:"¿Cuánto cuesta usar la IA en la nube?",answer:"Gemini 2.5 Flash: ~$0.001-0.003 USD por consulta. OpenAI gpt-4o-mini: ~$0.005-0.01 por consulta. Chrome Built-in AI: completamente gratis (se ejecuta local)."},{question:"¿Puedo personalizar el prompt que usa la IA?",answer:"SÃ. En Configuraciones â IA hay un campo para modificar el prompt. La IA viene con un prompt optimizado de QA Analyst senior en BDD, pero puedes adaptarlo a las convenciones de tu equipo. Hay un botón para restaurar el original."},{question:"¿Cómo mejoro una descripción con IA?",answer:'Abre el issue en Jira/Azure, abre HakaBoost, haz clic en "Leer descripción" para cargarla, luego "Mejorar Desc.". La IA genera una versión mejorada con criterios de aceptación y escenarios Gherkin (según el modo que elijas).'},{question:"¿Puedo actualizar la descripción directamente en Jira/Azure?",answer:'SÃ. Después de mejorar, el botón "Actualizar Jira" o "Actualizar Azure" reemplaza la descripción del issue con la versión mejorada. Funciona via API REST directa.'},{question:"¿Qué modos de mejora hay?",answer:"7 modos: 1) Solo mejorar descripción, 2) Mejorar + criterios de aceptación, 3) Mejorar + criterios + Gherkin, 4) Mejorar + criterios + lenguaje natural, 5) Sugerir tests en Gherkin, 6) Sugerir tests en lenguaje natural, 7) Crear tests existentes (lee los que ya están escritos)."},{question:"¿Cómo creo tests desde los escenarios generados?",answer:'Después de generar escenarios, haz clic en "Sugerir Tests". HakaBoost parsea cada Scenario/Scenario Outline y te permite crear cada uno como un issue Test en Jira (o Test Case en Azure DevOps), vinculándolo automáticamente a la tarea principal.'},{question:"¿Los tests creados se vinculan al issue original?",answer:'SÃ. Cada test creado se vincula automáticamente al work item principal con el tipo de link configurado (por defecto "Test" en Jira o "Tested By" en Azure DevOps).'},{question:"¿HakaBoost funciona con Xray Cloud?",answer:'SÃ. Si configuras las credenciales de Xray (Client ID + Client Secret), los tests creados en Jira se configuran como tipo "Cucumber" en Xray y se les sube el Gherkin automáticamente. También puedes exportar archivos .feature.'},{question:"¿Cómo configuro Xray Cloud?",answer:"En Configuraciones â Xray, ingresa tu Client ID y Client Secret (se generan en Xray Cloud â Settings â API Keys). HakaBoost los usa para autenticar y subir los escenarios Gherkin a los tests."},{question:"¿Qué es el Análisis de Calidad (Pro)?",answer:"Genera un reporte con: recomendaciones de mejora, riesgos identificados, precondiciones sugeridas y evaluación de la calidad del requerimiento. Se puede exportar a PDF o publicar como comentario en el issue."},{question:"¿Qué son los Datos de Prueba (Pro)?",answer:"Sugiere datos concretos para cada escenario: valores válidos, inválidos, de lÃmite y edge cases. Los presenta visualmente con cards y badges de clasificación. Puede transformar Scenarios en Scenario Outlines con tablas Ex
17630amples."},{question:"¿Qué es el Análisis de Cobertura (Pro)?",answer:"Compara los escenarios generados contra la descripción original del issue e identifica brechas: funcionalidades mencionadas que no tienen test. Sugiere escenarios faltantes con tÃtulos concretos para completar la cobertura."},{question:"¿Qué formatos de exportación soporta?",answer:"Archivos .feature (Cucumber/Gherkin), Excel/CSV (datos de prueba tabulares) y PDF (reportes de análisis). La exportación .feature es compatible directamente con frameworks BDD como Behave, Cucumber o haka-playwright-engine."},{question:"¿Puedo publicar el análisis como comentario en el issue?",answer:'SÃ. Las tabs de Análisis, Datos de Prueba y Cobertura tienen un botón "Publicar como comentario" que agrega el resultado directamente como comentario en el issue de Jira o Azure DevOps.'},{question:"¿Mis datos se envÃan a algún servidor de HakaLab?",answer:"No. HakaBoost no envÃa datos a servidores propios. Los tokens y credenciales se almacenan localmente en tu navegador (chrome.storage). Solo se comunica con: tu Jira/Azure (vÃa API), tu proveedor de IA configurado, y Firebase para autenticación."},{question:"¿Qué es la ofuscación de datos?",answer:"Antes de enviar la descripción a la IA en la nube, HakaBoost reemplaza automáticamente datos sensibles (emails, URLs, IPs, teléfonos, RUT, UUIDs) por placeholders como [EMAIL_1], [URL_1]. La respuesta de la IA se des-ofusca para restaurar los valores originales."},{question:"¿Puedo agregar palabras personalizadas a la ofuscación?",answer:"SÃ. En Configuraciones â Ofuscación puedes agregar un diccionario de palabras (ej: nombre de tu empresa, clientes, proyectos internos) que se reemplazarán antes de enviar a la IA."},{question:"¿Chrome Built-in AI envÃa datos a internet?",answer:"No. Gemini Nano se ejecuta 100% en tu computador. Ningún dato sale de tu máquina. Es la opción más privada."},{question:"¿Dónde se guardan mis credenciales de Jira/Azure/IA?",answer:"En chrome.storage (almacenamiento local/sincronizado del navegador). Nunca se envÃan a servidores de HakaLab. Se eliminan al cerrar sesión o desinstalar la extensión."},{question:"¿Cómo configuro Jira Cloud?",answer:"En Configuraciones â Jira: ingresa tu URL base (ej: https://tu-sitio.atlassian.net), email y API Token. El API Token se genera en https://id.atlassian.com/manage-profile/security/api-tokens."},{question:"¿Cómo configuro Azure DevOps?",answer:"En Configuraciones â Azure DevOps: ingresa tu Organización, Proyecto y un Personal Access Token (PAT) con permisos de Work Items. El PAT se genera en Azure DevOps â User Settings â Personal Access Tokens."},{question:"¿Puedo cambiar el tipo de issue que crea?",answer:"SÃ. En Configuraciones puedes elegir el tipo de issue a crear (Test, Task, Bug, etc.) y el tipo de vÃnculo (Test, Relates, Blocks). Si el tipo seleccionado no existe en tu proyecto, usa un fallback automático."},{question:"¿Puedo cambiar el idioma de la interfaz?",answer:"SÃ. HakaBoost soporta español e inglés. Elige el idioma al registrarte o cámbialo en Configuraciones. Afecta toda la interfaz y los mensajes."},{question:"HakaBoost no se abre / no aparece el panel lateral",answer:"Verifica que estés en una URL de Jira Cloud (*.atlassian.net) o Azure DevOps (dev.azure.com). El panel solo se habilita en páginas soportadas. Si estás en la URL correcta, recarga la página y vuelve a intentar con Ctrl+Shift+Y."},{question:'"Error de conexión" al probar la configuración de Jira',answer:'Verifica: 1) La URL base no tiene "/" al final, 2) El email es el de tu cuenta Atlassian, 3) El API Token es válido y no ha expirado (genera uno nuevo si dudas), 4) Tu usuario tiene permisos en el proyecto.'},{question:'"Error de conexión" en Azure DevOps',answer:'Verifica: 1) La organización y proyecto están bien escritos (case-sensitive), 2) El PAT tiene permisos "Work Items: Read & Write", 3) El PAT no ha expirado.'},{question:"La IA no genera respuesta o tarda mucho",answer:"Chrome Built-in AI: puede tardar hasta 120s en la primera consulta (descarga del modelo). Si falla, verifica que tu equipo soporta Chrome AI (chrome://flags â Prompt API). Gemini/OpenAI: verifica que la API Key sea válida y tengas saldo/cuota."},{question:"No puedo leer la descripción del issue",answer:"HakaBoost usa múltiples estrategias para leer la descripción (DOM + API). Si falla: 1) Recarga la página del issue, 2) Espera a que cargue completamente, 3) Verifica que tus credenciales tengan permiso de lectura en ese proyecto."},{question:"Los tests no se crean en Jira / da error al crear",answer:'Causas: 1) Tu usuario no tiene permiso para crear issues en ese proyecto, 2) El tipo de issue "Test" no existe (configura otro tipo en Settings), 3) El proyecto tiene campos obligatorios no soportados. Revisa el mensaje de error especÃfico.'},{question:"¿Se puede usar con Jira Server o Data Center?",answer:"No. HakaBoost solo funciona con Jira Cloud (*.atlassian.net). Las APIs de Jira Server son diferentes
17630y no están soportadas actualmente."},{question:"¿Hay atajo de teclado?",answer:"SÃ. Ctrl+Shift+Y (Windows/Linux) o Cmd+Shift+Y (Mac) abre/cierra el panel lateral de HakaBoost."},{question:"¿Puedo usar HakaBoost sin conexión a internet?",answer:"Parcialmente. Con Chrome Built-in AI (si ya descargaste el modelo) puedes generar mejoras offline. Pero para leer/escribir en Jira/Azure y para IA en la nube necesitas conexión."},{question:"¿Cómo actualizo HakaBoost?",answer:"Si lo instalaste desde la Chrome Web Store, se actualiza automáticamente. Si lo cargaste manualmente, descarga la nueva versión y vuelve a cargarla desde chrome://extensions."}],Yne=[{question:"¿Qué es HakaBuddy?",answer:"Es una aplicación de escritorio para equipos QA que centraliza la gestión, ejecución y documentación de pruebas de software. Permite hacer pruebas manuales con evidencia visual, automatizar con Playwright, generar reportes profesionales en PDF/HTML, y publicar suites en CI/CD."},{question:"¿Necesito saber programar para usarlo?",answer:"No para pruebas manuales (capturas, video, pasos con evidencia, reportes). Para automatización con Playwright se requiere conocimiento básico del navegador, pero el grabador genera el código automáticamente sin escribir una lÃnea."},{question:"¿En qué se diferencia de otras herramientas de testing?",answer:"Es desktop (tus datos quedan locales, no en la nube), incluye automatización Playwright integrada (graba y ejecuta sin herramientas externas), genera reportes listos para entregar, y conecta directamente con Jira/Xray y CI/CD. Todo en un solo ejecutable."},{question:"¿En qué sistemas operativos funciona?",answer:"Windows 10+, macOS 12+ (Intel y Apple Silicon) y Linux (Ubuntu 20.04+, Fedora, Arch). Se distribuye como ejecutable nativo para cada plataforma (.exe, .app, AppImage)."},{question:"¿Necesito instalar algo más?",answer:"No para el uso básico. El ejecutable incluye todo. Para automatización con Playwright, la primera vez se descargan los navegadores automáticamente (~200MB). Para grabación de video necesitas ffmpeg instalado (solo macOS/Linux)."},{question:"¿Necesito conexión a internet?",answer:"No para las funciones principales (pruebas manuales, capturas, reportes, ejecución de scripts). La conexión es necesaria para: validar la licencia, conectar con Jira/Xray, usar IA (Gemini/OpenAI/Claude), y push a CI/CD."},{question:"¿Dónde se guardan mis datos?",answer:"Todo se guarda localmente en tu equipo: Windows: C:\\Users\\{tu_usuario}\\AppData\\Local\\Hakabuddy\\data\\, macOS: ~/Library/Application Support/Hakabuddy/data/, Linux: ~/.local/share/Hakabuddy/data/. Incluye la base de datos SQLite, capturas, scripts, reportes y configuración."},{question:"¿Los datos persisten al actualizar?",answer:"SÃ. La carpeta de datos es independiente del ejecutable. Al instalar una nueva versión, tus pruebas, scripts, suites y configuración se mantienen intactos."},{question:"¿Puedo mover mis datos a otro equipo?",answer:"SÃ. Copia la carpeta data/ completa al mismo path en el nuevo equipo. Contiene la base de datos SQLite y todos los archivos asociados (capturas, scripts, reportes)."},{question:"¿Cómo inicio sesión?",answer:"Tres opciones: 1) Con Google (solo cuentas @hakalab.com â acceso completo), 2) Con clave de licencia (email + key), 3) Modo invitado (solo pruebas manuales, sin CI/CD ni Jira ni IA)."},{question:"¿La licencia es por usuario o por dispositivo?",answer:"Por dispositivo. Al activar tu licencia se vincula al equipo. Si cambias de computador, debes cerrar sesión en el anterior (libera el dispositivo) o contactar soporte para liberar la licencia remotamente."},{question:'¿Qué hago si me dice "Licencia ya en uso en otro dispositivo"?',answer:"Cierra sesión en el equipo anterior (Menú â Cerrar sesión). Si no tienes acceso a ese equipo, contacta a [email protected] para que liberen tu licencia."},{question:"¿Qué puedo hacer en Modo Invitado?",answer:"Pruebas manuales completas: registrar pasos, capturar pantalla, grabar video, generar reportes PDF/HTML. No disponible: Playwright, CI/CD, Jira/Xray, IA."},{question:"¿Cómo creo una prueba manual?",answer:'En la pantalla principal haz clic en "Nueva prueba". Ingresa tÃtulo, selecciona producto/ambiente, y comienza a agregar pasos. Cada paso tiene: acción, estado (Exitoso/Fallido) y puedes adjuntar evidencia (captura, archivo, JSON).'},{question:"¿Cómo capturo la pantalla durante una prueba?",answer:"Tres modos: 1) Captura completa (toda la pantalla), 2) Ãrea seleccionad
17630a (dibujas un rectángulo), 3) Con temporizador (cuenta regresiva de 3-5 segundos). La captura se adjunta automáticamente al paso actual."},{question:"¿Puedo grabar video de la ejecución?",answer:"SÃ. Activa la grabación de video antes de ejecutar. Se graba toda la sesión y el video se adjunta al reporte. Soporta múltiples monitores en Windows y captura por ventana."},{question:"¿Puedo adjuntar archivos a un paso?",answer:"SÃ. Puedes adjuntar PDFs, archivos JSON, capturas adicionales y cualquier archivo como evidencia de un paso. Se incluyen en el reporte y se guardan con la prueba."},{question:"¿Puedo editar pasos después de crearlos?",answer:"SÃ. Puedes editar el tÃtulo, estado y evidencia de cualquier paso durante o después de la ejecución. También puedes reordenar y eliminar pasos."},{question:"¿Cómo registro un paso como fallido?",answer:'Al crear o editar un paso, selecciona el estado "Fallido". La captura del momento del fallo se adjunta como evidencia. El paso se marca en rojo en el reporte.'},{question:"¿Cómo grabo un script de Playwright?",answer:'En la pestaña Playwright, ingresa la URL inicial y haz clic en "Grabar". Se abre un navegador donde interactúas normalmente. Al cerrar, el código del script se captura y se guarda listo para ejecutar.'},{question:"¿Qué navegadores puedo usar para grabar?",answer:"Chromium (predeterminado), Google Chrome y Microsoft Edge. Puedes configurar la resolución (viewport), locale, timezone, user-agent y estado de autenticación previo."},{question:"¿Puedo ejecutar un script individual?",answer:'SÃ. Selecciona un script y haz clic en "Ejecutar". Se abre el navegador, ejecuta los pasos y captura screenshots de cada acción. Al finalizar muestra el resultado (exitoso/fallido) con el detalle.'},{question:"¿Qué es una suite de regresión?",answer:"Es un grupo ordenado de scripts que se ejecutan en secuencia. Puedes agregar, quitar y reordenar scripts. Al ejecutar una suite, cada script corre uno tras otro y se genera un reporte consolidado con el resultado de toda la suite."},{question:"¿Puedo ejecutar suites de regresión completas?",answer:'SÃ. Selecciona la suite y "Ejecutar suite". Muestra progreso en tiempo real (script actual, exitosos, fallidos). Al finalizar genera un reporte HTML con screenshots por paso y un resumen.'},{question:"¿Puedo inyectar autenticación en los scripts?",answer:"SÃ. Si tienes un archivo de estado de sesión (storage state de Playwright), puedes configurarlo en la suite. Cada script se ejecuta ya autenticado sin repetir el login."},{question:"¿Puedo ejecutar con datos (data-driven)?",answer:"SÃ. Los scripts soportan ejecución parametrizada (outline): defines un dataset y el script se ejecuta N veces con diferentes datos. Cada iteración se registra individualmente."},{question:"¿Puedo publicar mis suites en un repositorio Git?",answer:"SÃ. En la pestaña Git, configura tu repositorio (GitHub, GitLab o Bitbucket) y token. Con un clic publicas toda la suite: scripts, runner y workflow de CI/CD se suben al repositorio."},{question:"¿Qué workflows de CI/CD genera?",answer:"Genera automáticamente: GitHub Actions (.github/workflows/), GitLab CI (.gitlab-ci.yml) o Bitbucket Pipelines (bitbucket-pipelines.yml). El workflow instala dependencias, ejecuta la suite en headless y sube el reporte HTML como artefacto."},{question:"¿Qué es el runner que se publica?",answer:"Es un script Python que ejecuta todos los scripts de la suite en modo headless, captura screenshots y genera un reporte HTML autocontenido. Es lo que corre en el pipeline de CI/CD."},{question:"¿Necesito configurar algo en GitHub/GitLab/Bitbucket?",answer:"Solo necesitas un token con permisos de escritura en el repositorio. HakaBuddy se encarga de crear la estructura de archivos, el workflow y hacer el commit/push."},{question:"¿Qué tipos de reporte genera?",answer:"PDF (profesional con portada, contenido, evidencias, anexos y contraportada), HTML (autocontenido, modo oscuro, con logos y evidencias embebidas en base64), y Xray JSON (para importar resultados a Jira Xray)."},{question:"¿Puedo personalizar el reporte PDF?",answer:"SÃ. Puedes configurar logos, colores de la portada, nombre de la empresa, QA responsable, y usar plantillas (portada + contraportada custom). Los pasos incluyen capturas, estados y detalle."},{question:"¿El reporte HTML es compartible?",answer:"SÃ. Es un archivo .html único autocontenido (imágenes embebidas en base64, sin dependencias externas). Puedes enviarlo por email, subirlo a Confluence, o adjuntarlo en Jira."},{question:"¿Puedo generar reportes de suites de Playwright?",answer:"SÃ. Al ejecutar una suite se genera automáticamente un reporte HTML con el resultado de cada script, screenshots por paso, y un resumen visual de la ejecución."},{question:"¿Cómo conecto HakaBuddy con Jira?",answer:"En Configuraciones â Jira, ingresa: URL de Jira (ej: https://tu-sitio.atlassian.net), email y API Token. Puedes validar la conexión antes de guardar."},{question:"¿Qué puedo hacer con la integración Jira?",answer:"Conectarte a tableros, ver sprints e issues, seleccionar un issue para asociarlo a tu prueba, adjuntar reportes como attachment y agregar comentarios con el resultado de la ejecución."},{question:"¿Cómo exporto resultados a Xray?",answer:"Configura las credenciales de Xray Cloud (Client ID + Client Secret) en Configuraciones â Xray. Después, al finalizar una prueba puedes exportar el resultado con pasos, estados y evidencias directamente a Xray."},{question:"¿Los resultados de Xray incluyen screenshots?",answer:"SÃ. Cada paso del test execution incluye la evidencia en base64 (capturas de pantalla) y el estado individual de cada paso."},{question:"¿Qué proveedores de IA soporta?",answer:"Google Gemini (recomendado, económico), OpenAI (GPT-4o, GPT-4), Anthropic Claude y Ollama (local, sin internet). Se configura el proveedor y API key en Configuraciones â IA."},{question:"¿Qué puede hacer la IA en HakaBuddy?",answer:"Genera descripciones de pasos a partir de capturas, analiza fallos y sugiere causas raÃz, optimiza scripts de Playwright (mejora selectores, agrega esperas), y genera análisis de resultados de ejecución en reportes HTML."},{question:"¿Puedo usar Ollama (IA local) sin internet?",answer:"SÃ. Configura Ollama como proveedor e indica el modelo (ej: llama3.1). La IA corre en tu máquina sin enviar datos a internet. Ideal para ambientes con restricciones de red."},{question:"¿La IA ve mis datos sensibles?",answer:"Solo si usas IA en la nube (Gemini/OpenAI/Claude).
17630Con Ollama todo es local. Para los proveedores cloud, se envÃa solo el contexto necesario (descripción del paso o script) directamente al proveedor, sin pasar por servidores de HakaLab."},{question:"¿Qué son Productos, Células y Ambientes?",answer:'Son entidades organizativas. Producto: la aplicación bajo prueba (ej: "Portal Web"). Célula: el equipo (ej: "Squad Checkout"). Ambiente: dónde pruebas (ej: "QA", "Staging", "Producción"). Se configuran una vez y se seleccionan al crear pruebas.'},{question:"¿Puedo ver el historial de pruebas?",answer:'SÃ. La pestaña "Histórico" muestra todas las pruebas ejecutadas con filtros por fecha, producto y estado. Puedes abrir cualquier prueba anterior y ver sus pasos, evidencias y reportes.'},{question:"¿Puedo ver el historial de ejecuciones de suites?",answer:"SÃ. Cada suite tiene un registro de ejecuciones con fecha, duración, cantidad de scripts y resultado global. Puedes ver el detalle de cada ejecución pasada."},{question:"El grabador de Playwright no se abre",answer:"Verifica que los navegadores de Playwright estén instalados. Si es la primera vez, HakaBuddy los descarga automáticamente (~200MB). Asegúrate de tener espacio en disco y conexión a internet para la descarga inicial."},{question:"La captura de pantalla sale negra o vacÃa",answer:"En Linux con Wayland puede ocurrir. Intenta ejecutar con XWayland o configura la variable de entorno XDG_SESSION_TYPE=x11. En macOS, otorga permiso de grabación de pantalla en Preferencias del Sistema â Privacidad."},{question:"La grabación de video no funciona",answer:"En macOS/Linux necesitas ffmpeg instalado (brew install ffmpeg o apt install ffmpeg). En Windows funciona sin dependencias adicionales. Verifica que no haya otro software usando la cámara/pantalla."},{question:"Error de licencia al iniciar",answer:'Si ves "Licencia no válida": verifica que el email y la clave son correctos. Si ves "En uso en otro dispositivo": cierra sesión en el otro equipo primero. Si no tienes acceso, contacta soporte.'},{question:"El push a Git falla",answer:"Verifica: 1) El token tiene permisos de escritura (repo scope en GitHub, Developer role en GitLab), 2) El repositorio existe y tienes acceso, 3) La rama no tiene protecciones que bloqueen push directo."},{question:"No puedo conectar con Jira",answer:'Verifica: 1) La URL base es correcta (sin "/" al final), 2) El email es el de tu cuenta Atlassian, 3) El API Token es válido y vigente (genera uno nuevo en https://id.atlassian.com/manage-profile/security/api-tokens).'},{question:"¿Puedo usar HakaBuddy detrás de un proxy corporativo?",answer:"SÃ. Configura las variables de entorno HTTP_PROXY/HTTPS_PROXY del sistema antes de abrir HakaBuddy. La aplicación las respeta para todas las conexiones de red."},{question:"¿Cómo actualizo HakaBuddy?",answer:"Descarga el nuevo ejecutable y reemplaza el anterior. Tus datos se conservan (están en una carpeta aparte). No necesitas de
17630sinstalar la versión anterior."},{question:"¿Puedo tener varias versiones instaladas?",answer:"SÃ. Como es un ejecutable portable, puedes tener varias versiones en carpetas diferentes. Todas comparten la misma carpeta de datos, asà que tus pruebas son accesibles desde cualquier versión."}],Zne=[{question:"¿Qué es HakaPath?",answer:"Es una extensión de Chrome/Edge que genera localizadores XPath y CSS con inteligencia artificial para automatización de pruebas. Con un clic derecho sobre cualquier elemento web, genera múltiples selectores listos para usar en Selenium, Playwright, Cypress o Appium."},{question:"¿A quién está dirigido?",answer:"A QA Automation Engineers, SDETs y cualquier persona que necesite obtener selectores robustos para tests automatizados. No requiere experiencia avanzada en XPath/CSS porque la extensión genera los selectores automáticamente."},{question:"¿Con qué frameworks de testing es compatible?",answer:"Selenium (Python, Java, JavaScript, C#), Playwright (Python, Java, JavaScript, C#), Cypress (JavaScript) y Appium (Python, Java). La exportación genera código especÃfico para cada combinación framework + lenguaje."},{question:"¿Cómo instalo HakaPath?",answer:'Desde la Chrome Web Store, busca "HakaPath" e instálalo. También funciona en Edge (basado en Chromium). Para modo desarrollador: chrome://extensions â Developer mode â Load unpacked â selecciona la carpeta del proyecto.'},{question:"¿Qué navegador necesito?",answer:"Chrome 88+ o Edge 88+ (cualquier navegador Chromium con soporte Manifest V3). Para Chrome Built-in AI necesitas Chrome 127+ con los flags de IA habilitados."},{question:"¿Necesito instalar algo más?",answer:"No. La extensión funciona de forma autónoma. Solo necesitas una API key si quieres usar IA cloud (OpenAI, Claude o Gemini). Chrome Built-in AI (versión Free) funciona sin API key."},{question:"¿Cuál es la diferencia entre Free y Pro?",answer:"Free: 1 slot XPath + 1 slot CSS (locales) + Chrome Built-in AI + Selenium y Playwright + exportación POM + historial + tema oscuro. Pro: 3 slots XPath + 3 slots CSS (incluye IA cloud) + 4 frameworks + indicador de robustez + detección de volatilidad + todos los proveedores de IA."},{question:"¿Cómo me registro?",answer:"Al abrir HakaPath por primera vez: 1) Elige idioma (Español/English), 2) Selecciona Free (registro con nombre, email, empresa) o Pro (login con credenciales, Google o Microsoft). Los clientes Haka Lab tienen Pro gratis con su cuenta corporativa."},{question:"¿Los clientes de Haka Lab pagan por Pro?",answer:"No. Los clientes de Haka Lab tienen acceso Pro sin costo usando su cuenta Google o Microsoft corporativa para iniciar sesión."},{question:"¿Cómo capturo un elemento?",answer:'Clic derecho sobre cualquier elemento de la página â "Obtener HakaPath". Se abre el panel con los localizadores generados automáticamente en la pestaña Localizadores.'},{question:'¿Qué son los "slots" de localizadores?',answer:"Cada captura genera múltiples opciones: Slots 1-2 (XPath local), Slot 3 (XPath con IA), Slots 4-5 (CSS local), Slot 6 (CSS con IA). Puedes elegir el que mejor se adapte a tu caso. En Free solo tienes 1 XPath + 1 CSS."},{question:"¿Qué significa el badge con número que aparece junto a cada localizador?",answer:'Es el conteo de coincidencias: cuántos elementos del DOM actual coinciden con ese selector. Lo ideal es "1" (selector único). Si muestra "0" el selector está roto; si muestra ">1" podrÃa seleccionar el elemento equivocado.'},{question:"¿Cómo copio un localizador?",answer:'Haz clic en el localizador o en el botón de copiar. Se copia al portapapeles listo para pegar en tu código. El botón </> lo convierte a formato WebElement del framework configurado (ej: driver.find_element(By.XPATH, "...")).'},{question:"¿Qué es la conversión a WebElement?",answer:`El botón </> transforma el selector puro en una lÃnea de código completa para tu framework. Ejemplo: "//button[@id='login']" â driver.find_element(By.XPATH, "//button[@id='login']") en Selenium Python.`},{question:"¿Qué estrategias de XPath genera?",answer:"Más de 13: por ID, atributos únicos (data-testid, aria-label, name), combinación de atributos, padre+hijo, texto (exacto y contains), siblings, posición, clase especÃfica, jerarquÃa con Ãndices, ancestor+descendant, y combinaciones con OR."},{question:"¿Qué estrategias de CSS genera?",answer:'ID (#id), clase (tag.class), atributos (tag[attr="value"]), combinadores (parent > child), pseudo-clases (:nth-child), atributos múltiples, y selectores compuestos con especificidad creciente.'},{question:"¿Qué son los Localizadores Relativos?",answer:"Ubican un elemento por su posición respecto a otro: Above (arriba de), Below (debajo de), Near (cerca de), ToLeftOf (a la izquierda de), ToRightOf (a la derecha de). Ãtiles cuando el elemento no tiene atributos únicos pero está junto a uno que sÃ."},{question:"¿Qué son los Localizadores Semánticos?",answer:"Usan la semántica del HTML: By Role (getByRole), By Text (getByText), By Label (getByLabel), By Placeholder (getByPlaceholder), By TestId (getByTestId), By Alt/Title. Son los más robustos y recomendados por Playwright y Testing Library."},{question:"¿Los semánticos funcionan en todos los frameworks?",answer:"Nativamente en Playwright y Cypress (con Testing Library). Para Selenium/Appium se genera un comentario indicando el equivalente, ya que no tienen API nativa de localizadores semánticos."},{question:"¿Cómo funciona la generación con IA?",answer:"Al capturar un elemento, los slots de IA (3 y 6) envÃan la información del elemento (tag, atributos, texto, padre, hermanos, outerHTML truncado) al proveedor configurado. La IA genera selectores optimizados que se validan contra el DOM real."},{question:"¿Qué proveedores de IA soporta?",answer:"Chrome Built-in AI (Gemini Nano, local, gratis, sin API key), OpenAI (GPT-4o Mini/4o/4.1), Claude (Sonnet 4/Haiku/Opus 4), Google Gemini (2.0 Flash/2.5 Flash
17630/2.5 Pro/3.1 Flash Lite). Free solo tiene Chrome Built-in AI."},{question:"¿Chrome Built-in AI funciona sin internet?",answer:"SÃ. Gemini Nano se ejecuta localmente en tu computador, sin enviar datos a ningún servidor. Requiere Chrome 127+ con flags de IA habilitados y una descarga inicial del modelo (~5GB)."},{question:"¿Qué datos se envÃan a la IA?",answer:"Solo metadatos del elemento: tag, id, clases, texto, atributos y contexto de hermanos/padre. Nunca se envÃa la página completa. Con Chrome Built-in AI no sale nada de tu equipo."},{question:"¿Qué pasa si la IA no está disponible?",answer:"Los slots 3 y 6 se muestran como no disponibles, pero los slots locales (1, 2, 4, 5) funcionan normalmente sin IA. La extensión es completamente funcional sin conexión a IA."},{question:"¿Qué es el indicador de robustez?",answer:"Un puntaje de 0 a 100 que evalúa qué tan confiable es cada localizador. Verde (70-100): robusto, usa atributos estables. Amarillo (40-69): moderado, tiene riesgos. Rojo (0-39): frágil, depende de elementos que pueden cambiar."},{question:"¿Qué penaliza la robustez?",answer:"Clases CSS dinámicas (react-, css-, hashes), Ãndices posicionales ([1], [position()=]), IDs autogenerados (GUIDs, :r0:), rutas absolutas (/html/body/...), profundidad excesiva (>5 niveles), y atributos volátiles detectados."},{question:"¿Qué bonifica la robustez?",answer:"data-testid, data-qa, aria-label, aria-describedby, atributo name, atributo role, IDs estables (cortos, semánticos), rutas cortas (<3 niveles), y coincidencia por texto."},{question:"¿Qué es la detección de volatilidad?",answer:"Un observador DOM (MutationObserver) que analiza el elemento durante 10 segundos después de capturarlo. Si detecta que atributos cambian (clases dinámicas, IDs que mutan), te avisa con una alerta y sugiere localizadores alternativos que evitan esos atributos."},{question:"¿Qué es el generador POM?",answer:"Genera automáticamente un archivo Page Object Model con los localizadores que has capturado. Soporta Python (.py), Java (.java), JavaScript (.js) y C# (.cs) con imports y estructura correcta para cada lenguaje."},{question:"¿Cómo exporto los localizadores?",answer:"En la pestaña POM/Exportar, selecciona el framework y lenguaje. Puedes copiar el código generado o descargarlo como archivo. El histórico también se puede exportar completo."},{question:"¿Puedo exportar el historial completo?",answer:"SÃ. El historial guarda hasta 30 localizadores capturados y se puede exportar en formato POM (código) o como lista plana. Configura el máximo en Configuración â Máx. histórico."},{question:"¿Qué es el Auto-Heal?",answer:'Cada elemento capturado genera un "fingerprint" (huella digital: tag, atributos, texto, posición, ancestros). Si un localizador falla en el futuro, se buscan elementos similares por la huella y se sugieren candidatos de reemplazo usando similitud ponderada.'},{question:"¿Cómo funciona la similitud para auto-heal?",answer:"Se compara el fingerprint original con todos los elementos actuales usando pesos: Tag (15%), Atributos (30%), Texto (25%), Posición (10%), Ancestros (20%). Los candidatos con mayor similitud se sugieren como reemplazo."},{question:"¿Qué puedo configurar?",answer:"Framework (Selenium/Playwright/Cypress/Appium), lenguaje (Python/Java/JS/C#), idioma (Español/English), máximo de historial (1-30), proveedor de IA (Deshabilitado/Chrome AI/OpenAI/Claude/Gemini), y tema (Oscuro/Claro)."},{question:"¿Puedo cambiar el tema a claro?",answer:"SÃ. En Configuración hay un toggle para cambiar entre tema oscuro (predeterminado, paleta azul marino) y tema claro. Se guarda en tus preferencias."},{question:"¿Dónde se guardan mis API keys?",answer:"En chrome.storage.local (almacenamiento local del navegador, cifrado por Chrome). Nunca se envÃan a servidores de HakaLab ni a terceros; solo se usan para comunicarse con el proveedor de IA que configuraste."},{question:'No aparece "Obtener HakaPath" en el menú contextual',answer:"Verifica que la extensión esté activa en chrome://extensions. En algunas páginas protegidas (chrome://, about:, archivos locales) las extensiones no tienen acceso. Recarga la página e intenta de nuevo."},{question:'El slot de IA muestra "No disponible"',answer:"Si usas Chrome Built-in AI: verifica Chrome 127+ y que los flags de IA estén habilitados (chrome://flags â Prompt API for Gemini Nano). Si usas IA cloud: verifica que la API key sea válida en Configuración."},{question:'Un localizador muestra "0" coincidencias',answer:"El selector no encuentra el elemento en el DOM actual. Puede que: 1) El elemento esté dentro de un iframe (HakaPath opera en el contexto principal), 2) El elemento se cargó dinámicamente después de la captura, 3) El DOM cambió (navegaste a otra página)."},{question:"¿Funciona dentro de iframes?",answer:"HakaPath captura el elemento en el contexto principal de la página. Para elementos dentro de iframes, primero
17630necesitas navegar al iframe (click derecho dentro del iframe). El conteo de coincidencias se evalúa en el frame activo."},{question:"¿Funciona con Shadow DOM?",answer:"Parcialmente. Los elementos dentro de Shadow DOM abierto son accesibles, pero los selectores generados pueden necesitar ajuste manual para incluir el host del shadow root. En Shadow DOM cerrado la captura no es posible."},{question:"¿Funciona en SPAs (React, Angular, Vue)?",answer:"SÃ. Los selectores se generan y validan contra el DOM actual. La detección de volatilidad es especialmente útil aquà porque detecta clases CSS dinámicas que estos frameworks generan (css-hash, ng-*, _ngcontent-*)."},{question:"¿Cómo sé qué localizador elegir entre los slots?",answer:'Usa el indicador de robustez (Pro) como guÃa: elige el verde. En Free, prefiere los que tengan badge "1" (exactamente una coincidencia) y que usen atributos semánticos (data-testid, aria-label, name) sobre clases o posiciones.'},{question:"¿Puedo usar HakaPath sin conexión?",answer:"Para los localizadores locales (slots 1,2,4,5) no necesitas conexión. Chrome Built-in AI tampoco requiere internet (después de la descarga inicial del modelo). Solo la verificación de cuenta y los proveedores cloud necesitan conexión."}];function eie(){return s.jsx(Wu,{productName:"Haka Automation Engine",productKey:"Engine Playwright",logo:"/imagenes/docs-logos/Automation Engine.png",logoHeight:"h-8",hubPath:"/docs/haka-playwright-engine",faqs:Jne})}function tie(){return s.jsx(Wu,{productName:"Haka AI Studio",productKey:"Haka AI Studio",logo:"/imagenes/docs-logos/AI Studio.png",logoHeight:"h-8",hubPath:"/docs/haka-ai-studio",faqs:Qne})}function aie(){return s.jsx(Wu,{productName:"HakaBoost",productKey:"HakaBoost",logo:"/imagenes/docs-logos/HakaBoost.png",logoHeight:"h-6",hubPath:"/docs/hakaboost",faqs:Xne})}function nie(){return s.jsx(Wu,{productName:"HakaBuddy",productKey:"Hakabuddy",logo:"/imagenes/docs-logos/HakaBuddy.png",logoHeight:"h-8",hubPath:"/docs/hakabuddy",faqs:Yne})}function iie(){return s.jsx(Wu,{productName:"HakaPath",productKey:"HakaPath",logo:"/imagenes/docs-logos/HakaPath.png",logoHeight:"h-8",hubPath:"/docs/hakapath",faqs:Zne})}const bj=["Planificación","Diseño","Desarrollo","Testing","Deploy","Review","Launch"],bn=[{id:0,label:"Análisis",fullName:"Análisis, precondiciones y riesgos",description:"Análisis detallado de requerimientos, identificación de riesgos y establecimiento de precondiciones para garantizar la calidad desde el inicio.",color:"#1e3a8a",logo:"/imagenes/productos/hakaboost_logo.png"},{id:1,label:"Diseño pruebas",fullName:"Diseño de pruebas",description:"Diseño detallado del plan de pruebas con estrategias, casos de prueba y criterios de aceptación.",color:"#1e40af",logo:"/imagenes/productos/hakaboost_logo.png"},{id:2,label:"Construcción",fullName:"Construcción de pruebas",description:"Construcción y desarrollo de pruebas automatizadas y manuales según el plan definido.",color:"#2563eb",logos:["/imagenes/productos/hakartc_logo.png","/imagenes/productos/hakabuddy_logo.png","/imagenes/productos/hakapath_logo.png"]},{id:3,label:"Ejecución",fullName:"Ejecución de pruebas",description:"Ejecución de pruebas en diferentes ambientes y escenarios para validar la calidad del software.",color:"#3b82f6",logo:"/imagenes/productos/hakabuddy_logo.png"},{id:4,label:"CI/CD",fullName:"Testing en CI/CD",description:"Integración de pruebas en el pipeline de CI/CD para validación continua y automatizada.",color:"#1d4ed8"}
17630,{id:5,label:"Resultados",fullName:"Resultados de calidad",description:"Análisis de resultados, generación de reportes y toma de decisiones basada en métricas de calidad.",color:"#0369a1"},{id:6,label:"Métricas",fullName:"Métricas productivas",description:"Medición y análisis de indicadores clave de productividad y eficiencia del proceso de testing para mejora continua.",color:"#0284c7"}],rie=[0,260,500,640,980,1130,1480];function oie(){const[t,e]=k.useState(0),[a,n]=k.useState(!0);k.useEffect(()=>{if(!a)return;const r=setInterval(()=>e(o=>(o+1)%bn.length),4e3);return()=>clearInterval(r)},[a]);const i=r=>{n(!1),e(r),setTimeout(()=>n(!0),8e3)};return s.jsxs("div",{className:"relative w-full max-w-7xl mx-auto py-16",children:[s.jsxs("div",{className:"mb-12 text-center",children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-3",children:"Ruta de Calidad Continua"}),s.jsx("p",{className:"text-gray-400",children:"Seguimiento paso a paso del proceso de QA"})]}),s.jsx("div",{className:"relative",children:s.jsxs("svg",{className:"w-full h-auto",viewBox:"0 0 1400 550",preserveAspectRatio:"xMidYMid meet",children:[s.jsx("path",{d:"M 80 280 Q 150 280 200 230 Q 250 180 300 180 Q 350 180 400 230 Q 450 280 500 330 Q 550 380 650 380 Q 750 380 800 330 Q 850 280 900 230 Q 950 180 1050 180 Q 1150 180 1200 230 Q 1250 280 1320 280",fill:"none",stroke:"rgba(148,163,184,0.2)",strokeWidth:"40",strokeLinecap:"round"}),s.jsx(_.path,{d:"M 80 280 Q 150 280 200 230 Q 250 180 300 180 Q 350 180 400 230 Q 450 280 500 330 Q 550 380 650 380 Q 750 380 800 330 Q 850 280 900 230 Q 950 180 1050 180 Q 1150 180 1200 230 Q 1250 280 1320 280",fill:"none",stroke:"url(#pathGradient)",strokeWidth:"40",strokeLinecap:"round",strokeDasharray:"1780",strokeDashoffset:1780-rie[t],style:{transition:"stroke-dashoffset 1s ease-in-out"}}),s.jsx("defs",{children:s.jsxs("linearGradient",{id:"pathGradient",x1:"0%",y1:"0%",x2:"100%",y2:"0%",children:[s.jsx("stop",{offset:"0%",stopColor:"#06b6d4",stopOpacity:"0.8"}),s.jsx("stop",{offset:"100%",stopColor:"#3b82f6",stopOpacity:"0.8"})]})}),s.jsx("text",{x:"700",y:"30",textAnchor:"middle",fill:"#94a3b8",fontSize:"18",fontWeight:"600",className:"pointer-events-none",children:"Ciclo de desarrollo de Testing"}),bn.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("line",{x1:c.x,y1:c.y-28,x2:c.x,y2:80+20,stroke:d?"#06b6d4":"rgba(148,163,184,0.3)",strokeWidth:d?2:1,strokeDasharray:d?"0":"4 4",className:"transition-all duration-300"},`line-qa-${o}`)}),bn.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("g",{children:s.jsx("foreignObject",{x:c.x-75,y:80-20,width:"150",height:"40",children:s.jsx("div",{className:"flex justify-center",children:s.jsx("div",{className:`px-5 py-2 rounded-full text-sm font-medium transition-all duration-300 whitespace-nowrap ${d?"bg-cyan-500/20 border-2 border-cyan-400 text-cyan-300":"bg-slate-800/60 border border-slate-600 text-slate-300"}`,children:r.label})})})},`qa-${o}`)}),bj.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("g",{children:s.jsx("foreignObject",{x:c.x-55,y:480-20,width:"110",height:"40",children:s.jsx("div",{className:"flex justify-center",children:s.jsx("div",{className:`px-3 py-1.5 rounded-full text-xs font-medium transition-all duration-300 whitespace-nowrap ${d?"bg-blue-500/30 border border-blue-400 text-blue-200":"bg-slate-800/40 border border-slate-700 text-slate-400"}`,children:r})})})},`dev-${o}`)}),bj.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("line",{x1:c.x,y1:c.y+28,x2:c.x,y2:480-20,stroke:d?"#3b82f6":"rgba(148,163,184,0.3)",strokeWidth:d?2:1,strokeDasharray:d?"0":"4 4",className:"transition-all duration-300"},`line-dev-${o}`)}),s.jsx("text",{x:"700",y:"520",textAnchor:"middle",fill:"#94a3b8",fontSize:"18",fontWeight:"600",className:"pointer-events-none",children:"Ciclo de Desarrollo"}),bn.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t,u=o<t;return s.jsxs("g",{children:[d&&s.jsxs("circle",{cx:c.x,cy:c.y,r:"35",fill:"none",stroke:"#06b6d4",strokeWidth:"3",opacity:"0.6",children:[s.jsx("animate",{attributeName:"r",from:"35",to:"45",dur:"1.5s",repeatCount:"indef
17630inite"}),s.jsx("animate",{attributeName:"opacity",from:"0.6",to:"0",dur:"1.5s",repeatCount:"indefinite"})]}),s.jsx("circle",{cx:c.x,cy:c.y,r:"28",fill:d?"#06b6d4":u?r.color:"#1e293b",stroke:d?"#22d3ee":u?"#3b82f6":"#334155",strokeWidth:d?3:2,className:"cursor-pointer transition-all duration-300",onClick:()=>i(o),style:{filter:d?"drop-shadow(0 0 12px #06b6d4)":"none"}}),s.jsx("text",{x:c.x,y:c.y+5,textAnchor:"middle",fill:"white",fontSize:"16",fontWeight:"bold",className:"pointer-events-none",children:String(o+1).padStart(2,"0")})]},r.id)})]})}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.4},className:"mt-12 bg-white/5 backdrop-blur rounded-2xl p-8 border border-cyan-400/40",children:s.jsxs("div",{className:"flex items-start gap-6",children:[s.jsx("div",{className:"bg-gradient-to-br from-cyan-400 to-blue-600 text-white font-bold text-xl w-14 h-14 rounded-full flex items-center justify-center flex-shrink-0",children:String(t+1).padStart(2,"0")}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h3",{className:"text-2xl font-bold text-white mb-3",children:bn[t].fullName}),s.jsx("p",{className:"text-gray-300 leading-relaxed",children:bn[t].description}),bn[t].logo&&s.jsx("div",{className:"flex justify-center mt-6 pt-6 border-t border-white/10",children:s.jsx("img",{src:bn[t].logo,alt:"Product logo",className:"h-8 opacity-70"})}),bn[t].logos&&s.jsx("div",{className:"flex justify-center items-center gap-6 mt-6 pt-6 border-t border-white/10",children:bn[t].logos.map((r,o)=>s.jsx("img",{src:r,alt:"Product logo",className:"h-7 opacity-70"},o))})]})]})},t),s.jsx("div",{className:"flex justify-center gap-2 mt-8",children:bn.map(r=>s.jsx("button",{onClick:()=>i(r.id),className:`h-2 rounded-full transition-all duration-300 ${t===r.id?"bg-cyan-400 w-8":"bg-gray-600 hover:bg-gray-400 w-3"}`},r.id))})]})}function sie(){return s.jsx("div",{className:"min-h-screen bg-[#0a0e27] py-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl sm:text-5xl font-bold text-primary mb-4",children:"Calidad en Todo El Ciclo de Desarrollo"}),s.jsx("p",{className:"text-gray-300 text-lg",children:"Ciclo de Desarrollo y Quality Assurance"})]}),s.jsx(Og,{}),s.jsx("div",{className:"my-20 border-t border-white/10"}),s.jsx(oie,{})]})})}function lie(){const{t}=$();return k.useEffect(()=>{document.title="Términos y Condiciones | Haka Lab"},[]),s.jsx("div",{className:"bg-dark min-h-screen",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 py-16 sm:px-6 lg:px-8",children:[s.jsxs("div",{className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:t("terminos.titulo")}),s.jsxs("p",{className:"text-gray-400 text-lg",children:[t("terminos.ultimaActualizacion"),": 15 julio 2025"]})]}),s.jsxs("div",{className:"prose prose-invert prose-lg max-w-none",children:[s.jsx("div",{className:"mb-12 text-gray-300 leading-relaxed",children:s.jsx("p",{children:'Estos Términos y Condiciones de Uso (en adelante, los "Términos") regulan la relación entre Haka Lab SpA, empresa legalmente constituida con domicilio en Guardia Vieja #181, Providencia, Santiago, Chile (en adelante, "Haka Lab", "nosotros" o "nuestro(s)"), y el Usuario (en adelante, "usted" o "tu"), en relación con el uso de los productos y servicios digitales de Haka Lab.'})}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["1. ",t("terminos.definiciones.titulo")]}),s.jsxs("div",{className:"space-y-4 text-gray-300",children:[s.jsxs("div",{children:[s.jsx("p",{className:"font-semibold text-primary mb-2",children:'"Servicios":'}),s.jsx("p",{children:"se refiere a todos los productos, plataformas, aplicaciones, sitios web y herramientas desarrollados y ofrecidos por Haka Lab, incluyendo pero no limitados a HakaPath, HakaBuddy, HakaTools, asà como cualquier producto futuro."})]}),s.jsxs("div",{children:[s.jsx("p",{className:"font-semibold text-primary mb-2",children:'"Usuario" o "usted":'}),s.jsx("p",{children:"cualquier persona natural o jurÃdica que acceda, utilice o interactúe con los Servicios."}),s.jsx("p",{className:"mt-2 italic",children:"Si accede en representación de una entidad (por ejemplo, su empleador), declara contar con la facultad legal para vincular a dicha entidad con estos Términos."})]})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["2. ",t("terminos.aceptacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Al utilizar nuestros Servicios, usted acepta expresamente estos Términos. Si no está de acuerdo con ellos, debe abstenerse de utilizar nuestros productos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["3. ",t("terminos.licencia.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Haka Lab otorga al Usuario una licencia limitada, no exclusiva, intransferible y revocable para utilizar los Servicios con fines personales o empresariales legÃtimos, conforme a la ley y a estos Términos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["4. ",t("terminos.restricciones.titulo")]}),s.jsx("p",{className:"text-gray-300 mb-3",children:"El Usuario se compromete a no:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Copiar, modificar, descompilar o aplicar ingenierÃa inversa a los Servicios."}),s.jsx("li",{children:"Vender, sublicenciar o distribuir nuestros productos sin autorización escrita de Haka Lab."}),s.jsx("li",{children:"Usar los Servicios para fines ilÃcitos o contrarios a la moral y buenas costumbres."}),s.jsx("li",{children:"Infringir derechos de propiedad intelectual de Haka Lab o de terceros."})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["5. ",t("terminos.actualizaciones.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Haka Lab podrá actualizar, mejorar o discontinuar cualquier parte de los Servicios sin previo aviso. Algunas actualizaciones pueden ser obligatorias para seguir utilizando los productos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["6. ",t("terminos.privacidad.titulo")]}),s.jsxs("p",{className:"text-gray-300",children:["El uso de los Servicios está sujeto a nuestra PolÃtica de Privacidad. Al utilizar nuestros productos, usted consiente el tratamiento de sus datos personales conforme a dicha polÃtica. Puede consultarla en el siguiente enlace: ",s.jsx("a",{href:"/politica-privacidad",className:"text-primary hover:underline font-semibold",children:"PolÃtica de Privacidad"}),"."]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["7. ",t("terminos.limitacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"En la medida máxima permitida por la ley, Haka Lab no será responsable por daños directos, indirectos, incidentales o consecuentes derivados del uso de nuestros Servicios. El uso se realiza bajo su propio riesgo."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["8. ",t("terminos.terminacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Podremos suspender o cancelar el acceso a los Servicios si usted incumple estos Términos. En tal caso, usted deberá dejar de utilizarlos inmediatamente."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["9. ",t("terminos.legislacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Estos Términos se rigen por las leyes de la República de Chile. Toda controversia será sometida a los tribunales ordinarios de justicia de Santiago, Chile."})]}),s.jsxs("section",{className:"mb-16",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["10. ",t("terminos.modificaciones.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Nos reservamos el derecho de modificar estos Términos en cualquier momento. Los cambios serán publicados en nuestro sitio web y entrarán en vigor desde su publicación. Se podrá notificar a los usuarios por medios razonables (como avisos en la app o vÃa email)."})]}),s.jsx("div",{className:"border-t border-gray-700 pt-12 mt-12",children:s.jsxs("div",{className:"bg-slate-800/60 border border-cyan-400/30 rounded-xl p-8 text-center",children:[s.jsx("h2",{className:"text-2xl md:text-3xl font-bold text-white mb-4",children:"PolÃtica de Privacidad"}),s.jsx("p",{className:"text-gray-300 mb-6 max-w-2xl mx-auto",children:"Para conocer en detalle cómo recopilamos, utilizamos, almacenamos y protegemos sus datos personales, consulte nuestra PolÃtica de Privacidad completa."}),s.jsx("a",{href:"/politica-privacidad",className:"inline-block bg-gradient-to-r from-cyan-500 to-blue-500 text-white font-semibold px-8 py-3 rounded-lg hover:from-cyan-400 hover:to-blue-400 transition-all shadow-lg hover:shadow-cyan-500/25",children:"Ver PolÃtica de Privacidad"})]})})]})]})})}function cie(){return k.useEffect(()=>{document.title="PolÃtica de Privacidad | Haka Lab"},[]),s.jsx("div",{className:"bg-dark min-h-screen",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 py-16 sm:px-6 lg:px-8",children:[s.jsxs("div",{className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:"PolÃtica de Privacidad"}),s.jsx("p",{className:"text-gray-400 text-lg",children:"Ãltima actualización: 13 de mayo de 2026 â Versión 1.0"})]}),s.jsxs("div",{className:"prose prose-invert prose-lg max-w-none",children:[s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"1. Identificación del Responsable"}),s.jsxs("div",{className:"space-y-2 text-gray-300",children:[s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Responsable del tratamiento:"})," Hakalab SpA"]}),s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Correo de contacto:"})," ",s.jsx("a",{href:"mailto:[email protected]",className:"text-primary hover:underline",children:"[email protected]"})]}),s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Sitio web:"})," ",s.jsx("a",{href:"https://hakalab.com",className:"text-primary hover:underline",children:"https://hakalab.com"})]}),s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Productos:"}
vendor: 5,543 bytes, line 17630
17630)," HakaBoost, HakaBuddy, HakaPath, HakaRTC, Haka Insight, Haka AI Studio, Haka Engine Connector y demás productos desarrollados por Haka Lab"]})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"2. Alcance"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"Esta polÃtica de privacidad describe cómo Haka Lab recopila, utiliza, almacena y protege los datos personales de sus usuarios. Aplica a todas las personas que instalen y utilicen cualquiera de los productos de Haka Lab (HakaBoost, HakaBuddy, HakaPath, HakaRTC, Haka Insight, Haka AI Studio, Haka Engine Connector, entre otros), independientemente de su plan (Free o Pro)."}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Esta polÃtica se rige por la legislación chilena vigente, en particular:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Ley N° 21.719 sobre Protección de Datos Personales"}),s.jsx("li",{children:"Ley N° 21.663 â Ley Marco de Ciberseguridad"}),s.jsx("li",{children:"Constitución PolÃtica de la República de Chile, Art. 19 N° 4"})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"3. Datos que recopilamos"}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.1 Datos proporcionados directamente por el usuario"}),s.jsx("div",{className:"overflow-x-auto mb-6",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Finalidad"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Plan"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Nombre"}),s.jsx("td",{className:"px-4 py-2",children:"Identificación del usuario"}),s.jsx("td",{className:"px-4 py-2",children:"Free y Pro"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Correo electrónico"}),s.jsx("td",{className:"px-4 py-2",children:"Identificación, comunicación y validación de licencia"}),s.jsx("td",{className:"px-4 py-2",children:"Free y Pro"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Empresa"}),s.jsx("td",{className:"px-4 py-2",children:"Conocer el contexto organizacional del usuario"}),s.jsx("td",{className:"px-4 py-2",children:"Free"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Clave de licencia"}),s.jsx("td",{className:"px-4 py-2",children:"Validación del acceso Pro"}),s.jsx("td",{className:"px-4 py-2",children:"Pro"})]})]})]})}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.2 Datos generados automáticamente"}),s.jsx("div",{className:"overflow-x-auto mb-6",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Finalidad"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Almacenamiento"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"ID de instalación (UUID)"}),s.jsx("td",{className:"px-4 py-2",children:"Identificar el dispositivo para detección de sesiones concurrentes"}),s.jsx("td",{className:"px-4 py-2",children:"Local en el navegador"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Fecha del último chequeo de licencia"}),s.jsx("td",{className:"px-4 py-2",children:"Control de validación diaria"}),s.jsx("td",{className:"px-4 py-2",children:"Local en el navegador"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Preferencias de configuración (idioma, tema, modelo de IA)"}),s.jsx("td",{className:"px-4 py-2",children:"Personalización de la experiencia"}),s.jsx("td",{className:"px-4 py-2",children:"Local en el navegador"})]})]})]})}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.3 Datos que NO recopilamos"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-6",children:[s.jsx("li",{children:"No recopilamos contraseñas de Jira, Azure DevOps ni de servicios de IA"}),s.jsx("li",{children:"No recopilamos el contenido de las tareas o work items del usuario"}),s.jsx("li",{children:"No recopilamos historial de navegación"}),s.jsx("li",{children:"No recopilamos datos biométricos"}),s.jsx("li",{children:"No utilizamos cookies ni tecnologÃas de rastreo"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.4 Credenciales de terceros"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"El usuario puede configurar voluntariamente credenciales de servicios externos (Jira, Azure DevOps, OpenAI, Google Gemini, Claude, Xray). Estas credenciales:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Se almacenan exclusivamente en el navegador del usuario (chrome.storage)"}
17630),s.jsx("li",{children:"Nunca se envÃan a servidores de Hakalab"}),s.jsx("li",{children:"Se utilizan únicamente para conectar con los servicios que el usuario configuró"}),s.jsx("li",{children:"Se eliminan completamente al cerrar sesión"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3 mt-6",children:"3.5 Actividad del usuario en Haka Engine Connector"}),s.jsxs("p",{className:"text-gray-300 mb-3",children:["Haka Engine Connector captura la actividad del usuario (clics, entradas de texto, selecciones y navegaciones) ",s.jsx("span",{className:"font-semibold",children:"exclusivamente mientras la grabación está activa"})," (activada manualmente por el usuario). Esta información:"]}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Se envÃa únicamente al servidor local del usuario (127.0.0.1/localhost), que corre en su propia máquina"}),s.jsx("li",{children:s.jsx("span",{className:"font-semibold",children:"Nunca se transmite a servidores externos ni a la nube"})}),s.jsx("li",{children:"Se procesa localmente para generar archivos de prueba automatizada (features y localizadores)"}),s.jsx("li",{children:"No se almacena de forma persistente â se descarta al finalizar la generación"}),s.jsx("li",{children:"No se captura ninguna actividad fuera del modo de grabación"})]}),s.jsx("p",{className:"text-gray-300",children:"Adicionalmente, Haka Engine Connector almacena preferencias del usuario (último proyecto y nombre de sesión) en chrome.storage.local, que se eliminan al desinstalar la extensión."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"4. Bases de licitud del tratamiento"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"De acuerdo con la Ley N° 21.719, el tratamiento de datos personales en los productos de Haka Lab se fundamenta en las siguientes bases:"}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Tratamiento"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Base de licitud"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Registro de cuenta (nombre, email, empresa)"}),s.jsx("td",{className:"px-4 py-2",children:"Consentimiento del titular"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Validación de licencia (email, clave, id_app)"}),s.jsx("td",{className:"px-4 py-2",children:"Ejecución del contrato de servicio"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Almacenamiento de preferencias"}),s.jsx("td",{className:"px-4 py-2",children:"Interés legÃtimo del responsable"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Detección de sesiones concurrentes"}),s.jsx("td",{className:"px-4 py-2",children:"Ejecución del contrato de servicio"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"EnvÃo de descripciones a servicios de IA"}),s.jsx("td",{className:"px-4 py-2",children:"Consentimiento del titular"})]})]})]})})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"5. Finalidades del tratamiento"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los datos personales se tratan exclusivamente para las siguientes finalidades:"}),s.jsxs("ol",{className:"list-decimal list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Prestación del servicio:"})," Permitir el funcionamiento de los productos de Haka Lab y sus funcionalidades"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Gestión de licencias:"})," Validar el acceso al plan Pro y detectar uso no autorizado"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Mejora del producto:"})," Conocer el perfil general de nuestros usuarios (sin análisis individual)"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Comunicación:"})," Contactar al usuario únicamente para asuntos relacionados con su cuenta o el servicio"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Seguridad:"})," Detectar y prevenir accesos no autorizados"]})]}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los datos personales NO se utilizan para:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Publicidad personalizada"}),s.jsx("li",{children:"Venta a terceros"}),s.jsx("li",{children:"Elaboración de perfiles de comportamiento"}),s.jsx("li",{children:"Decisiones automatizadas que afecten al usuario"})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"6. Transferencia internacional de datos"}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"6.1 Servicios de inteligencia artificial"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Cuando el usuario utiliza servicios de IA en la nube (OpenAI, Google Gemini o Claude), las de
17630scripciones de las tareas se envÃan a servidores ubicados fuera de Chile (principalmente Estados Unidos) para su procesamiento. Esta transferencia:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Solo ocurre cuando el usuario ejecuta activamente una acción de IA"}),s.jsx("li",{children:"El usuario puede evitarla usando Chrome Built-in AI (procesamiento 100% local)"}),s.jsx("li",{children:"Se aplica ofuscación automática de datos sensibles (URLs, emails, IPs, teléfonos, identificadores) antes del envÃo"}),s.jsx("li",{children:"Los proveedores de IA procesan los datos según sus propias polÃticas de privacidad:"})]}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-8 mb-4",children:[s.jsxs("li",{children:["OpenAI: ",s.jsx("a",{href:"https://openai.com/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://openai.com/privacy"})]}),s.jsxs("li",{children:["Google (Gemini): ",s.jsx("a",{href:"https://policies.google.com/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://policies.google.com/privacy"})]}),s.jsxs("li",{children:["Anthropic (Claude): ",s.jsx("a",{href:"https://www.anthropic.com/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://www.anthropic.com/privacy"})]})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"6.2 Firebase (Google Cloud)"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los datos de registro (email, nombre, empresa) se almacenan en Firebase/Firestore (Google Cloud Platform), con servidores que pueden estar ubicados fuera de Chile. Google cumple con estándares internacionales de protección de datos y cuenta con certificaciones ISO 27001, SOC 2 y SOC 3."}),s.jsxs("p",{className:"text-gray-300 mb-4",children:["PolÃtica de privacidad de Firebase: ",s.jsx("a",{href:"https://firebase.google.com/support/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://firebase.google.com/support/privacy"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"6.3 Validación de licencia"}),s.jsx("p",{className:"text-gray-300",children:"La validación de licencia se realiza contra un servicio alojado en Google Cloud Functions (us-central1). Se envÃa únicamente: email, clave de licencia, nombre del producto e ID de instalación."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"7. Almacenamiento y seguridad"}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.1 Almacenamiento local"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"En productos que operan como extensiones de navegador, la mayorÃa de los datos se almacenan exclusivamente en el navegador del usuario:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Almacenamiento local:"})," Datos sensibles de sesión (tokens, credenciales) â no se sincronizan"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Almacenamiento sincronizado:"})," Preferencias de configuración (idioma, tema, modelo de IA)"]})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.2 Almacenamiento en la nube"}),s.jsx("div",{className:"overflow-x-auto mb-6",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Servicio"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Ubicación"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Email, nombre, empresa (usuarios Free)"}),s.jsx("td",{className:"px-4 py-2",children:"Firebase Firestore"}),s.jsx("td",{className:"px-4 py-2",children:"Google Cloud"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Email, plan, session_id (usuarios Pro Google/Microsoft)"}),s.jsx("td",{className:"px-4 py-2",children:"Firebase Firestore"}),s.jsx("td",{className:"px-4 py-2",children:"Google Cloud"})]})]})]})}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.3 Medidas de seguridad técnicas"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Comunicaciones cifradas mediante HTTPS/TLS en todas las conexiones"}),s.jsx("li",{children:"Tokens y credenciales enmascarados en la interfaz de usuario"}),s.jsx("li",{children:"Ofuscación automática de datos sensibles antes del envÃo a servicios de IA"}),s.jsx("li",{children:"Validación de sesión con detección de uso multi-dispositivo"}),s.jsx("li",{children:"Código fuente sin ofuscación ni código remoto (Manifest V3)"}),s.jsx("li",{children:"Permisos mÃnimos necesarios declarados en el manifiesto de la extensión"}),s.jsx("li",{children:"Sin uso de eval(), código dinámico ni dependencias externas en tiempo de ejecución"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.4 Plazos de conservación"}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Plazo de conservación"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Datos de registro (Firestore)"}),s.jsx("td",{className:"px-4 py-2",children:"Mientras la cuenta esté activa. Se eliminan a solicitud del titular"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Datos de sesión local"}),s.jsx("td",{className:"px-4 py-2",children:"Hasta que el usuario cierre sesión o desinstale el producto"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Credenciales de terceros"}),s.jsx("td",{className:"px-4 py-2",children:"Hasta que el usuario las elimine o cierre sesión"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Descripciones enviadas a IA"}),s.jsx("td",{className:"px-4 py-2",children:"No se almacenan. Se procesan en tiempo real y se descartan"})]})]})]})})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"8. Derechos del titular"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"De acuerdo con la Ley N° 21.719, todo usuario tiene derecho a:"}),s.jsx("div",{className:"overflow-x-auto mb-4",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Derecho"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Descripción"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Cómo ejercerlo"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Acceso"}),s.jsx("td",{className:"px-4 py-2",children:"Conocer qué datos personales tenemos sobre usted"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Rectificación"}),s.jsx("td",{className:"px-4 py-2",children:"Corregir datos inexactos o incompletos"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Supresión"}),s.jsx("td",{className:"px-4 py-2",children:"Solicitar la eliminación de sus datos"}),s.jsx("td",{className:"px-4 py-2",children:"Cerrar sesión + enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Oposición"}),s.jsx("td",{className:"px-4 py-2",children:"Oponerse al tratamiento de sus datos"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Portabilidad"}),s.jsx("td",{className:"px-4 py-2",children:"Recibir sus datos en formato estructurado"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Limitación"}),s.jsx("td",{className:"px-4 py-2",children:"Restringir el tratamiento en ciertos casos"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]})]})]})}),s.jsxs("p",{className:"text-gray-300 mb-3",children:[s.jsx("span",{className:"font-semibold",children:"Plazo de respuesta:"})," Responderemos a su solicitud dentro de 15 dÃas hábiles desde su recepción."]}),s.jsxs("p",{className:"text-gray-300 mb-3",children:[s.jsx("span",{className:"font-semibold",children:"Eliminación inmediata de datos locales:"}),' El usuario puede eliminar todos sus datos locales en cualquier momento cerrando sesión desde el producto (botón "Cerrar Sesión"). Esto elimina tokens, credenciales, preferencias y datos de sesión del navegador.']}),s.jsxs("p",{className:"text-gray-300",children:[s.jsx("span",{className:"font-semibold",children:"Reclamación ante la autoridad:"})," Si considera que sus derechos no han sido debidamente atendidos, puede presentar una reclamación ante la Agencia de Protección de Datos Personales de Chile."]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"9. Consentimiento"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"Al registrarse en cualquiera de los productos de Haka Lab, el usuario otorga su consentimiento libre, especÃfico, informado e inequÃvoco para el tratamiento de sus datos personales conforme a esta polÃtica."}),s.jsx("p",{className:"text-gray-300 mb-3",children:"El usuario puede retirar su
17630consentimiento en cualquier momento:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Cerrando sesión en el producto (elimina datos locales)"}),s.jsx("li",{children:"Solicitando la eliminación de sus datos en Firestore a [email protected]"}),s.jsx("li",{children:"Desinstalando el producto"})]}),s.jsx("p",{className:"text-gray-300",children:"El retiro del consentimiento no afecta la licitud del tratamiento realizado con anterioridad."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"10. Uso de inteligencia artificial"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los productos de Haka Lab utilizan servicios de inteligencia artificial para mejorar descripciones de tareas, generar escenarios de prueba y optimizar flujos de trabajo. Es importante que el usuario comprenda:"}),s.jsxs("ol",{className:"list-decimal list-inside space-y-2 text-gray-300 ml-4",children:[s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Las descripciones se envÃan a proveedores de IA externos"})," (OpenAI, Google, Anthropic) cuando se usa IA en la nube"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"La ofuscación automática"})," reemplaza datos sensibles (emails, URLs, IPs, teléfonos, identificadores) por placeholders antes del envÃo"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"El usuario puede agregar palabras personalizadas"})," al diccionario de ofuscación para proteger información especÃfica de su organización"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Chrome Built-in AI"})," procesa todo localmente sin enviar datos a ningún servidor externo"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Los proveedores de IA"})," pueden procesar los datos según sus propias polÃticas. Hakalab no tiene control sobre el tratamiento que estos proveedores realicen"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"No se almacenan las descripciones"})," enviadas a la IA. Se procesan en tiempo real y el resultado se muestra al usuario sin persistencia"]})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"11. Menores de edad"}),s.jsx("p",{className:"text-gray-300",children:"Los productos de Haka Lab son herramientas profesionales de calidad de software. No están dirigidos a menores de 18 años y no recopilamos intencionalmente datos de menores. Si detectamos que un menor ha proporcionado datos personales, procederemos a eliminarlos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"12. Modificaciones a esta polÃtica"}),s.jsx("p",{className:"text-gray-300",children:"Nos reservamos el derecho de actualizar esta polÃtica de privacidad para reflejar cambios en nuestras prácticas o en la legislación aplicable. Las modificaciones se publicarán en esta página con la fecha de actualización. Si los cambios son sustanciales, notificaremos a los usuarios a través de nuestros productos o por correo electrónico."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"13. Contacto"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Para cualquier consulta, solicitud o reclamo relacionado con el tratamiento de sus datos personales:"}),s.jsxs("div",{className:"space-y-2 text-gray-300 ml-4",children:[s.jsxs("p",{children:["ð§ ",s.jsx("a",{href:"mailto:[email protected]",className:"text-primary hover:underline",children:"[email protected]"})]}),s.jsx("p",{children:"ð¢ Hakalab SpA"}),s.jsx("p",{children:"ð Chile"})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"14. Legislación aplicable y jurisdicción"}),s.jsx("p",{className:"text-gray-300",children:"Esta polÃtica se rige por la legislación de la República de Chile. Cualquier controversia será sometida a los tribunales ordinarios de justicia de Santiago de Chile, sin perjuicio del derecho del titular a reclamar ante la Agencia de Protección de Datos Personales."})]}),s.jsx("div",{className:"border-t border-gray-700 pt-8 mt-12 text-center",children:s.jsx("p",{className:"text-gray-400 italic",children:"Documento vigente desde el 13 de mayo de 2026."})})]})]})})}function die(){const[t,e]=k.useState(!1),[a,n]=k.useState(""),{loginWithGoogle:i}=hs(),r=Qa(),o=async()=>{n(""),e(!0);try{await i(),r("/admin-blog/dashboard")}catch(l){n(l.message)}finally{e(!1)}};return s.jsx("div",{className:"min-h-screen bg-gradient-to-br from-dark via-slate-900 to-dark flex items-center justify-center px-4",children:s.jsxs(_.div,{initial:{opacity:0,y:20}
17630,animate:{opacity:1,y:0},transition:{duration:.6},className:"w-full max-w-md",children:[s.jsxs("div",{className:"text-center mb-8",children:[s.jsx("img",{src:"/imagenes/logo_haka.png",alt:"HakaLab",className:"h-16 mx-auto mb-4"}),s.jsx("p",{className:"text-gray-400",children:"Panel de Administración - Blog"})]}),s.jsxs("div",{className:"bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-8 shadow-2xl",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-2",children:"Iniciar Sesión"}),s.jsx("p",{className:"text-gray-400 text-sm mb-6",children:"Panel de Administración - Blog"}),a&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"mb-6 p-4 bg-red-500/10 border border-red-500/50 rounded-lg",children:s.jsx("p",{className:"text-red-400 text-sm",children:a})}),s.jsx("button",{onClick:o,disabled:t,className:"w-full px-4 py-3 bg-white text-gray-900 font-semibold rounded-lg hover:bg-gray-100 transition-all disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-3",children:t?s.jsxs(s.Fragment,{children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-4 h-4 border-2 border-gray-900 border-t-transparent rounded-full"}),"Iniciando sesión..."]}):s.jsxs(s.Fragment,{children:[s.jsxs("svg",{className:"w-5 h-5",viewBox:"0 0 24 24",children:[s.jsx("path",{fill:"currentColor",d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),s.jsx("path",{fill:"currentColor",d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),s.jsx("path",{fill:"currentColor",d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),s.jsx("path",{fill:"currentColor",d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]}),"Iniciar con Google"]})}),s.jsx("div",{className:"mt-6 p-4 bg-blue-500/10 border border-blue-500/30 rounded-lg",children:s.jsxs("p",{className:"text-xs text-blue-300",children:[s.jsx("strong",{children:"Nota:"})," Solo usuarios autorizados pueden acceder al panel de administración."]})})]}),s.jsx("p",{className:"text-center text-gray-500 text-sm mt-8",children:"© 2026 HakaLab. Todos los derechos reservados."})]})})}function Do({children:t}){const[e,a]=k.useState(!0),{user:n,logout:i}=hs(),r=Qa(),o=fn(),l=async()=>{try{await i(),r("/admin-blog")}catch(u){console.error("Error al cerrar sesión:",u)}},c=[{label:"Crear Blog",path:"/admin-blog/create",icon:"âï¸"},{label:"Editar Blogs",path:"/admin-blog/edit",icon:"ð"}],d=u=>o.pathname===u;return s.jsxs("div",{className:"min-h-screen bg-dark flex",children:[s.jsxs(_.div,{initial:{x:-300},animate:{x:0},transition:{duration:.3},className:`${e?"w-64":"w-20"} bg-slate-800 border-r border-slate-700 transition-all duration-300 flex flex-col`,children:[s.jsx("div",{className:"p-4 border-b border-slate-700",children:s.jsxs("div",{className:"flex items-center justify-between",children:[e&&s.jsx("div",{className:"flex items-center gap-2",children:s.jsx("img",{src:"../imagenes/logo_haka.png",alt:"HakaLab",className:"h-8"})}),s.jsx("button",{onClick:()=>a(!e),className:"p-2 hover:bg-slate-700 rounded-lg transition",children:e?"â":"â¶"})]})}),s.jsx("nav",{className:"flex-1 p-4 space-y-2",children:c.map(u=>s.jsxs("button",{onClick:()=>r(u.path),className:`w-full flex items-center gap-3 px-4 py-3 rounded-lg transition ${d(u.path)?"bg-primary/20 text-primary border border-primary/50":"text-gray-400 hover:bg-slate-700/50"}`,children:[s.jsx("span",{className:"text-xl",children:u.icon}),e&&s.jsx("span",{className:"text-sm font-medium",children:u.label})]},u.path))}),s.jsxs("div",{className:"p-4 border-t border-slate-700 space-y-3",children:[e&&s.jsxs("div",{className:"text-xs",children:[s.jsx("p",{className:"text-gray-500",children:"Conectado como:"}),s.jsx("p",{className:"text-white font-medium truncate",children:n==null?void 0:n.email})]}),s.jsx("button",{onClick:l,className:"w-full px-4 py-2 bg-red-500/10 text-red-400 hover:bg-red-500/20 rounded-lg transition text-sm font-medium",children:e?"Cerrar Sesión":"ðª"})]})]}),s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsxs("div",{className:"bg-slate-800/50 border-b border-slate-700 px-6 py-4 flex items-center justify-between",children:[s.jsx("h1",{className:"text-2xl font-bold text-white",children:"Panel de Administración"}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm",children:n==null?void 0:n.email}
17630),s.jsx("img",{src:`https://ui-avatars.com/api/?name=${n==null?void 0:n.email}&background=06b6d4&color=fff`,alt:"Avatar",className:"w-10 h-10 rounded-full"})]})]}),s.jsx("div",{className:"flex-1 overflow-auto p-6",children:t})]})]})}function uie(){const{user:t}=hs(),[e,a]=k.useState({published:0,drafts:0,tags:0}),[n,i]=k.useState(!0);return k.useEffect(()=>{(async()=>{try{i(!0);const o=jl(ga(St,"blogs"),Gn("published","==",!0)),c=(await Ni(o)).size,d=jl(ga(St,"blogs"),Gn("published","==",!1)),p=(await Ni(d)).size,h=(await Ni(ga(St,"tags"))).size;a({published:c,drafts:p,tags:h})}catch(o){console.error("Error al cargar estadÃsticas:",o)}finally{i(!1)}})()},[]),s.jsx(Do,{children:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6},className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Bienvenido al Panel de Blog"}),s.jsx("p",{className:"text-gray-400",children:"Gestiona tus artÃculos de blog desde aquÃ"})]}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:[s.jsx(_.div,{whileHover:{y:-5},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Blogs Publicados"}),n?s.jsx("div",{className:"mt-2",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full"})}):s.jsx("p",{className:"text-3xl font-bold text-white mt-2",children:e.published})]}),s.jsx("span",{className:"text-4xl",children:"ð"})]})}),s.jsx(_.div,{whileHover:{y:-5},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Borradores"}),n?s.jsx("div",{className:"mt-2",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full"})}):s.jsx("p",{className:"text-3xl font-bold text-white mt-2",children:e.drafts})]}),s.jsx("span",{className:"text-4xl",children:"ð"})]})}),s.jsx(_.div,{whileHover:{y:-5},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Etiquetas"}),n?s.jsx("div",{className:"mt-2",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full"})}):s.jsx("p",{className:"text-3xl font-bold text-white mt-2",children:e.tags})]}),s.jsx("span",{className:"text-4xl",children:"ð·ï¸"})]})})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("h3",{className:"text-xl font-bold text-white mb-4",children:"Acciones Rápidas"}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsx(_.button,{whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>window.location.href="/admin-blog/create",className:"px-6 py-3 bg-gradient-to-r from-cyan-500 to-blue-600 text-white rounded-lg font-semibold hover:shadow-lg hover:shadow-cyan-500/50 transition",children:"âï¸ Crear Nuevo Blog"}),s.jsx(_.button,{whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>window.location.href="/admin-blog/edit",className:"px-6 py-3 bg-slate-700 text-white rounded-lg font-semibold hover:bg-slate-600 transition",children:"ð Ver Mis Blogs"})]})]}),s.jsxs("div",{className:"bg-blue-500/10 border border-blue-500/30 rounded-lg p-6",children:[s.jsx("h3",{className:"text-lg font-bold text-blue-300 mb-2",children:"ð¡ Próximas CaracterÃsticas"}),s.jsxs("ul",{className:"text-blue-200 text-sm space-y-2",children:[s.jsx("li",{children:"â
Editor de blogs con rich text"}),s.jsx("li",{children:"â
Gestión de etiquetas"}),s.jsx("li",{children:"â
Subida de imágenes"}),s.jsx("li",{children:"â
Publicación automática"}),s.jsx("li",{children:"â
EstadÃsticas de blogs"})]})]})]})})}function Dt(t){this.content=t}Dt.prototype={constructor:Dt,find:function(t){for(var e=0;e<this.content.length;e+=2)if(this.content[e]===t)return e;return-1},get:function(t){var e=this.find(t);return e==-1?void 0:this.content[e+1]},update:function(t,e,a){var n=a&&a!=t?this.remove(a):this,i=n.find(t),r=n.content.slice();return i==-1?r.push(a||t,e):(r[i+1]=e,a&&(r[i]=a)),new Dt(r)},remove:function(t){var e=this.find(t);if(e==-1)return this;var a=this.content.slice();return a.splice(e,2),new Dt(a)},addToStart:function(t,e){return new Dt([t,e].concat(this.remove(t).content))},addToEnd:function(t,e){var a=this.remove(t).content.slice();return a.push(t,e),new Dt(a)},addBefore:function(t,e,a){var n=this.remove(e),i=n.content.slice(),r=n.find(t);return i.splice(r==-1?i.length:r,0,e,a),new Dt(i)}
vendor: 26,975 bytes, lines 17630-17631
17630,forEach:function(t){for(var e=0;e<this.content.length;e+=2)t(this.content[e],this.content[e+1])},prepend:function(t){return t=Dt.from(t),t.size?new Dt(t.content.concat(this.subtract(t).content)):this},append:function(t){return t=Dt.from(t),t.size?new Dt(this.subtract(t).content.concat(t.content)):this},subtract:function(t){var e=this;t=Dt.from(t);for(var a=0;a<t.content.length;a+=2)e=e.remove(t.content[a]);return e},toObject:function(){var t={};return this.forEach(function(e,a){t[e]=a}),t},get size(){return this.content.length>>1}};Dt.from=function(t){if(t instanceof Dt)return t;var e=[];if(t)for(var a in t)e.push(a,t[a]);return new Dt(e)};function VO(t,e,a){for(let n=0;;n++){if(n==t.childCount||n==e.childCount)return t.childCount==e.childCount?null:a;let i=t.child(n),r=e.child(n);if(i==r){a+=i.nodeSize;continue}if(!i.sameMarkup(r))return a;if(i.isText&&i.text!=r.text){for(let o=0;i.text[o]==r.text[o];o++)a++;return a}if(i.content.size||r.content.size){let o=VO(i.content,r.content,a+1);if(o!=null)return o}a+=i.nodeSize}}function HO(t,e,a,n){for(let i=t.childCount,r=e.childCount;;){if(i==0||r==0)return i==r?null:{a,b:n};let o=t.child(--i),l=e.child(--r),c=o.nodeSize;if(o==l){a-=c,n-=c;continue}if(!o.sameMarkup(l))return{a,b:n};if(o.isText&&o.text!=l.text){let d=0,u=Math.min(o.text.length,l.text.length);for(;d<u&&o.text[o.text.length-d-1]==l.text[l.text.length-d-1];)d++,a--,n--;return{a,b:n}}if(o.content.size||l.content.size){let d=HO(o.content,l.content,a-1,n-1);if(d)return d}a-=c,n-=c}}class V{constructor(e,a){if(this.content=e,this.size=a||0,a==null)for(let n=0;n<e.length;n++)this.size+=e[n].nodeSize}nodesBetween(e,a,n,i=0,r){for(let o=0,l=0;l<a;o++){let c=this.content[o],d=l+c.nodeSize;if(d>e&&n(c,i+l,r||null,o)!==!1&&c.content.size){let u=l+1;c.nodesBetween(Math.max(0,e-u),Math.min(c.content.size,a-u),n,i+u)}l=d}}descendants(e){this.nodesBetween(0,this.size,e)}textBetween(e,a,n,i){let r="",o=!0;return this.nodesBetween(e,a,(l,c)=>{let d=l.isText?l.text.slice(Math.max(e,c)-c,a-c):l.isLeaf?i?typeof i=="function"?i(l):i:l.type.spec.leafText?l.type.spec.leafText(l):"":"";l.isBlock&&(l.isLeaf&&d||l.isTextblock)&&n&&(o?o=!1:r+=n),r+=d},0),r}append(e){if(!e.size)return this;if(!this.size)return e;let a=this.lastChild,n=e.firstChild,i=this.content.slice(),r=0;for(a.isText&&a.sameMarkup(n)&&(i[i.length-1]=a.withText(a.text+n.text),r=1);r<e.content.length;r++)i.push(e.content[r]);return new V(i,this.size+e.size)}cut(e,a=this.size){if(e==0&&a==this.size)return this;let n=[],i=0;if(a>e)for(let r=0,o=0;o<a;r++){let l=this.content[r],c=o+l.nodeSize;c>e&&((o<e||c>a)&&(l.isText?l=l.cut(Math.max(0,e-o),Math.min(l.text.length,a-o)):l=l.cut(Math.max(0,e-o-1),Math.min(l.content.size,a-o-1))),n.push(l),i+=l.nodeSize),o=c}return new V(n,i)}cutByIndex(e,a){return e==a?V.empty:e==0&&a==this.content.length?this:new V(this.content.slice(e,a))}replaceChild(e,a){let n=this.content[e];if(n==a)return this;let i=this.content.slice(),r=this.size+a.nodeSize-n.nodeSize;return i[e]=a,new V(i,r)}addToStart(e){return new V([e].concat(this.content),this.size+e.nodeSize)}addToEnd(e){return new V(this.content.concat(e),this.size+e.nodeSize)}eq(e){if(this.content.length!=e.content.length)return!1;for(let a=0;a<this.content.length;a++)if(!this.content[a].eq(e.content[a]))return!1;return!0}get firstChild(){return this.content.length?this.content[0]:null}get lastChild(){return this.content.length?this.content[this.content.length-1]:null}get childCount(){return this.content.length}child(e){let a=this.content[e];if(!a)throw new RangeError("Index "+e+" out of range for "+this);return a}maybeChild(e){return this.content[e]||null}forEach(e){for(let a=0,n=0;a<this.content.length;a++){let i=this.content[a];e(i,n,a),n+=i.nodeSize}}findDiffStart(e,a=0){return VO(this,e,a)}findDiffEnd(e,a=this.size,n=e.size){return HO(this,e,a,n)}findIndex(e){if(e==0)return Xp(0,e);if(e==this.size)return Xp(this.content.length,e);if(e>this.size||e<0)throw new RangeError(`Position ${e} outside of fragment (${this})`);for(let a=0,n=0;;a++){let i=this.child(a),r=n+i.nodeSize;if(r>=e)return r==e?Xp(a+1,r):Xp(a,n);n=r}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(e=>e.toJSON()):null}static fromJSON(e,a){if(!a)return V.empty;if(!Array.isArray(a))throw new RangeError("Invalid input for Fragment.fromJSON");return new V(a.map(e.nodeFromJSON))}static fromArray(e){if(!e.length)return V.empty;let a,n=0;for(let i=0;i<e.length;i++){let r=e[i];n+=r.nodeSize,i&&r.isText&&e[i-1].sameMarkup(r)?(a||(a=e.slice(0,i)),a[a.length-1]=r.withText(a[a.length-1].text+r.text)):a&&a.push(r)}return new V(a||e,n)}static from(e){if(!e)return V.empty;if(e instanceof V)return e;if(Array.isArray(e))return this.fromArray(e);if(e.attrs)return new V([e],e.nodeSize);throw new RangeError("Can not convert "+e+" to a Fragment"+(e.nodesBetween?" (looks like multiple versions of prosemirror-model were loaded)":""))}}V.empty=new V([],0);const B0={index:0,offset:0};function Xp(t,e){return B0.index=t,B0.offset=e,B0}function Kh(t,e){if(t===e)return!0;if(!(t&&typeof t=="object")||!(e&&typeof e=="object"))return!1;let a=Array.isArray(t);if(Array.isArray(e)!=a)return!1;if(a){if(t.length!=e.length)return!1;for(let n=0;n<t.length;n++)if(!Kh(t[n],e[n]))return!1}else{for(let n in t)if(!(n in e)||!Kh(t[n],e[n]))return!1;for(let n in e)if(!(n in t))return!1}return!0}let qe=class Sb{constructor(e,a){this.type=e,this.attrs=a}addToSet(e){let a,n=!1;for(let i=0;i<e.length;i++){let r=e[i];if(this.eq(r))return e;if(this.type.excludes(r.type))a||(a=e.slice(0,i));else{if(r.type.excludes(this.type))return e;!n&&r.type.rank>this.type.rank&&(a||(a=e.slice(0,i)),a.push(this),n=!0),a&&a.push(r)}}return a||(a=e.slice()),n||a.push(this),a}removeFromSet(e){for(let a=0;a<e.length;a++)if(this.eq(e[a]))return e.slice(0,a).concat(e.slice(a+1));return e}isInSet(e){for(let a=0;a<e.length;a++)if(this.eq(e[a]))return!0;return!1}eq(e){return this==e||this.type==e.type&&Kh(this.attrs,e.attrs)}toJSON(){let e={type:this.type.name};for(let a in this.attrs){e.attrs=this.attrs;break}return e}static fromJSON(e,a){if(!a)throw new RangeError("Invalid input for Mark.fromJSON");let n=e.marks[a.type];if(!n)throw new RangeError(`There is no mark type ${a.type} in this schema`);let i=n.create(a.attrs);return n.checkAttrs(i.attrs),i}static sameSet(e,a){if(e==a)return!0;if(e.length!=a.length)return!1;for(let n=0;n<e.length;n++)if(!e[n].eq(a[n]))return!1;return!0}static setFrom(e){if(!e||Array.isArray(e)&&e.length==0)return Sb.none;if(e instanceof Sb)return[e];let a=e.slice();return a.sort((n,i)=>n.type.rank-i.type.rank),a}};qe.none=[];class Jh extends Error{}class K{constructor(e,a,n){this.content=e,this.openStart=a,this.openEnd=n}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(e,a){let n=BO(this.content,e+this.openStart,a);return n&&new K(n,this.openStart,this.openEnd)}removeBetween(e,a){return new K(FO(this.content,e+this.openStart,a+this.openStart),this.openStart,this.openEnd)}eq(e){return this.content.eq(e.content)&&this.openStart==e.openStart&&this.openEnd==e.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let e={content:this.content.toJSON()};return this.openStart>0&&(e.openStart=this.openStart),this.openEnd>0&&(e.openEnd=this.openEnd),e}static fromJSON(e,a){if(!a)return K.empty;let n=a.openStart||0,i=a.openEnd||0;if(typeof n!="number"||typeof i!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new K(V.fromJSON(e,a.content),n,i)}static maxOpen(e,a=!0){let n=0,i=0;for(let r=e.firstChild;r&&!r.isLeaf&&(a||!r.type.spec.isolating);r=r.firstChild)n++;for(let r=e.lastChild;r&&!r.isLeaf&&(a||!r.type.spec.isolating);r=r.lastChild)i++;return new K(e,n,i)}}K.empty=new K(V.empty,0,0);function FO(t,e,a){let{index:n,offset:i}=t.findIndex(e),r=t.maybeChild(n),{index:o,offset:l}=t.findIndex(a);if(i==e||r.isText){if(l!=a&&!t.child(o).isText)throw new RangeError("Removing non-flat range");return t.cut(0,e).append(t.cut(a))}if(n!=o)throw new RangeError("Removing non-flat range");return t.replaceChild(n,r.copy(FO(r.content,e-i-1,a-i-1)))}function BO(t,e,a,n){let{index:i,offset:r}=t.findIndex(e),o=t.maybeChild(i);if(r==e||o.isText)return n&&!n.canReplace(i,i,a)?null:t.cut(0,e).append(a).append(t.cut(e));let l=BO(o.content,e-r-1,a,o);return l&&t.replaceChild(i,o.copy(l))}function pie(t,e,a){if(a.openStart>t.depth)throw new Jh("Inserted content deeper than insertion position");if(t.depth-a.openStart!=e.depth-a.openEnd)throw new Jh("Inconsistent open depths");return UO(t,e,a,0)}function UO(t,e,a,n){let i=t.index(n),r=t.node(n);if(i==e.index(n)&&n<t.depth-a.openStart){let o=UO(t,e,a,n+1);return r.copy(r.content.replaceChild(i,o))}else if(a.content.size)if(!a.openStart&&!a.openEnd&&t.depth==n&&e.depth==n){let o=t.parent,l=o.content;return zo(o,l.cut(0,t.parentOffset).append(a.content).append(l.cut(e.parentOffset)))}else{let{start:o,end:l}=mie(a,t);return zo(r,WO(t,o,l,e,n))}else return zo(r,Qh(t,e,n))}function $O(t,e){if(!e.type.compatibleContent(t.type))throw new Jh("Cannot join "+e.type.name+" onto "+t.type.name)}function _b(t,e,a){let n=t.node(a);return $O(n,e.node(a)),n}function qo(t,e){let a=e.length-1;a>=0&&t.isText&&t.sameMarkup(e[a])?e[a]=t.withText(e[a].text+t.text):e.push(t)}function vd(t,e,a,n){let i=(e||t).node(a),r=0,o=e?e.index(a):i.childCount;t&&(r=t.index(a),t.depth>a?r++:t.textOffset&&(qo(t.nodeAfter,n),r++));for(let l=r;l<o;l++)qo(i.child(l),n);e&&e.depth==a&&e.textOffset&&qo(e.nodeBefore,n)}function zo(t,e){return t.type.checkContent(e),t.copy(e)}function WO(t,e,a,n,i){let r=t.depth>i&&_b(t,e,i+1),o=n.depth>i&&_b(a,n,i+1),l=[];return vd(null,t,i,l),r&&o&&e.index(i)==a.index(i)?($O(r,o),qo(zo(r,WO(t,e,a,n,i+1)),l)):(r&&qo(zo(r,Qh(t,e,i+1)),l),vd(e,a,i,l),o&&qo(zo(o,Qh(a,n,i+1)),l)),vd(n,null,i,l),new V(l)}function Qh(t,e,a){let n=[];if(vd(null,t,a,n),t.depth>a){let i=_b(t,e,a+1);qo(zo(i,Qh(t,e,a+1)),n)}return vd(e,null,a,n),new V(n)}function mie(t,e){let a=e.depth-t.openStart,i=e.node(a).copy(t.content);for(let r=a-1;r>=0;r--)i=e.node(r).copy(V.from(i));return{start:i.resolveNoCache(t.openStart+a),end:i.resolveNoCache(i.content.size-t.openEnd-a)}}class du{constructor(e,a,n){this.pos=e,this.path=a,this.parentOffset=n,this.depth=a.length/3-1}resolveDepth(e){return e==null?this.depth:e<0?this.depth+e:e}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(e){return this.path[this.resolveDepth(e)*3]}index(e){return this.path[this.resolveDepth(e)*3+1]}indexAfter(e){return e=this.resolveDepth(e),this.index(e)+(e==this.depth&&!this.textOffset?0:1)}start(e){return e=this.resolveDepth(e),e==0?0:this.path[e*3-1]+1}end(e){return e=this.resolveDepth(e),this.start(e)+this.node(e).content.size}before(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position before the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]}after(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position after the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]+this.path[e*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let e=this.parent,a=this.index(this.depth);if(a==e.childCount)return null;let n=this.pos-this.path[this.path.length-1],i=e.child(a);return n?e.child(a).cut(n):i}get nodeBefore(){let e=this.index(this.depth),a=this.pos-this.path[this.path.length-1];return a?this.parent.child(e).cut(0,a):e==0?null:this.parent.child(e-1)}posAtIndex(e,a){a=this.resolveDepth(a);let n=this.path[a*3],i=a==0?0:this.path[a*3-1]+1;for(let r=0;r<e;r++)i+=n.child(r).nodeSize;return i}marks(){let e=this.parent,a=this.index();if(e.content.size==0)return qe.none;if(this.textOffset)return e.child(a).marks;let n=e.maybeChild(a-1),i=e.maybeChild(a);if(!n){let l=n;n=i,i=l}let r=n.marks;for(var o=0;o<r.length;o++)r[o].type.spec.inclusive===!1&&(!i||!r[o].isInSet(i.marks))&&(r=r[o--].removeFromSet(r));return r}marksAcross(e){let a=this.parent.maybeChild(this.index());if(!a||!a.isInline)return null;let n=a.marks,i=e.parent.maybeChild(e.index());for(var r=0;r<n.length;r++)n[r].type.spec.inclusive===!1&&(!i||!n[r].isInSet(i.marks))&&(n=n[r--].removeFromSet(n));return n}sharedDepth(e){for(let a=this.depth;a>0;a--)if(this.start(a)<=e&&this.end(a)>=e)return a;return 0}blockRange(e=this,a){if(e.pos<this.pos)return e.blockRange(this);for(let n=this.depth-(this.parent.inlineContent||this.pos==e.pos?1:0);n>=0;n--)if(e.pos<=this.end(n)&&(!a||a(this.node(n))))return new Xh(this,e,n);return null}sameParent(e){return this.pos-this.parentOffset==e.pos-e.parentOffset}max(e){return e.pos>this.pos?e:this}min(e){return e.pos<this.pos?e:this}toString(){let e="";for(let a=1;a<=this.depth;a++)e+=(e?"/":"")+this.node(a).type.name+"_"+this.index(a-1);return e+":"+this.parentOffset}static resolve(e,a){if(!(a>=0&&a<=e.content.size))throw new RangeError("Position "+a+" out of range");let n=[],i=0,r=a;for(let o=e;;){let{index:l,offset:c}=o.content.findIndex(r),d=r-c;if(n.push(o,l,i+c),!d||(o=o.child(l),o.isText))break;r=d-1,i+=c+1}return new du(a,n,r)}static resolveCached(e,a){let n=wj.get(e);if(n)for(let r=0;r<n.elts.length;r++){let o=n.elts[r];if(o.pos==a)return o}else wj.set(e,n=new hie);let i=n.elts[n.i]=du.resolve(e,a);return n.i=(n.i+1)%fie,i}}class hie{constructor(){this.elts=[],this.i=0}}const fie=12,wj=new WeakMap;class Xh{constructor(e,a,n){this.$from=e,this.$to=a,this.depth=n}get start(){return this.$from.before(this.depth+1)}get end(){return this.$to.after(this.depth+1)}get parent(){return this.$from.node(this.depth)}get startIndex(){return this.$from.index(this.depth)}get endIndex(){return this.$to.indexAfter(this.depth)}}const gie=Object.create(null);class Rn{constructor(e,a,n,i=qe.none){this.type=e,this.attrs=a,this.marks=i,this.content=n||V.empty}get children(){return this.content.content}get nodeSize(){return this.isLeaf?1:2+this.content.size}get childCount(){return this.content.childCount}child(e){return this.content.child(e)}maybeChild(e){return this.content.maybeChild(e)}forEach(e){this.content.forEach(e)}nodesBetween(e,a,n,i=0){this.content.nodesBetween(e,a,n,i,this)}descendants(e){this.nodesBetween(0,this.content.size,e)}get textContent(){return this.isLeaf&&this.type.spec.leafText?this.type.spec.leafText(this):this.textBetween(0,this.content.size,"")}textBetween(e,a,n,i){return this.content.textBetween(e,a,n,i)}get firstChild(){return this.content.firstChild}get lastChild(){return this.content.lastChild}eq(e){return this==e||this.sameMarkup(e)&&this.content.eq(e.content)}sameMarkup(e){return this.hasMarkup(e.type,e.attrs,e.marks)}hasMarkup(e,a,n){return this.type==e&&Kh(this.attrs,a||e.defaultAttrs||gie)&&qe.sameSet(this.marks,n||qe.none)}copy(e=null){return e==this.content?this:new Rn(this.type,this.attrs,e,this.marks)}mark(e){return e==this.marks?this:new Rn(this.type,this.attrs,this.content,e)}cut(e,a=this.content.size){return e==0&&a==this.content.size?this:this.copy(this.content.cut(e,a))}slice(e,a=this.content.size,n=!1){if(e==a)return K.empty;let i=this.resolve(e),r=this.resolve(a),o=n?0:i.sharedDepth(a),l=i.start(o),d=i.node(o).content.cut(i.pos-l,r.pos-l);return new K(d,i.depth-o,r.depth-o)}replace(e,a,n){return pie(this.resolve(e),this.resolve(a),n)}nodeAt(e){for(let a=this;;){let{index:n,offset:i}=a.content.findIndex(e);if(a=a.maybeChild(n),!a)return null;if(i==e||a.isText)return a;e-=i+1}}childAfter(e){let{index:a,offset:n}=this.content.findIndex(e);return{node:this.content.maybeChild(a),index:a,offset:n}}childBefore(e){if(e==0)return{node:null,index:0,offset:0};let{index:a,offset:n}=this.content.findIndex(e);if(n<e)return{node:this.content.child(a),index:a,offset:n};let i=this.content.child(a-1);return{node:i,index:a-1,offset:n-i.nodeSize}}resolve(e){return du.resolveCached(this,e)}resolveNoCache(e){return du.resolve(this,e)}rangeHasMark(e,a,n){let i=!1;return a>e&&this.nodesBetween(e,a,r=>(n.isInSet(r.marks)&&(i=!0),!i)),i}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let e=this.type.name;return this.content.size&&(e+="("+this.content.toStringInner()+")"),GO(this.marks,e)}contentMatchAt(e){let a=this.type.contentMatch.matchFragment(this.content,0,e);if(!a)throw new Error("Called contentMatchAt on a node with invalid content");return a}canReplace(e,a,n=V.empty,i=0,r=n.childCount){let o=this.contentMatchAt(e).matchFragment(n,i,r),l=o&&o.matchFragment(this.content,a);if(!l||!l.validEnd)return!1;for(let c=i;c<r;c++)if(!this.type.allowsMarks(n.child(c).marks))return!1;return!0}canReplaceWith(e,a,n,i){if(i&&!this.type.allowsMarks(i))return!1;let r=this.contentMatchAt(e).matchType(n),o=r&&r.matchFragment(this.content,a);return o?o.validEnd:!1}canAppend(e){return e.content.size?this.canReplace(this.childCount,this.childCount,e.content):this.type.compatibleContent(e.type)}check(){this.type.checkContent(this.content),this.type.checkAttrs(this.attrs);let e=qe.none;for(let a=0;a<this.marks.length;a++){let n=this.marks[a];n.type.checkAttrs(n.attrs),e=n.addToSet(e)}if(!qe.sameSet(e,this.marks))throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(a=>a.type.name)}`);this.content.forEach(a=>a.check())}toJSON(){let e={type:this.type.name};for(let a in this.attrs){e.attrs=this.attrs;break}return this.content.size&&(e.content=this.content.toJSON()),this.marks.length&&(e.marks=this.marks.map(a=>a.toJSON())),e}static fromJSON(e,a){if(!a)throw new RangeError("Invalid input for Node.fromJSON");let n;if(a.marks){if(!Array.isArray(a.marks))throw new RangeError("Invalid mark data for Node.fromJSON");n=a.marks.map(e.markFromJSON)}if(a.type=="text"){if(typeof a.text!="string")throw new RangeError("Invalid text node in JSON");return e.text(a.text,n)}let i=V.fromJSON(e,a.content),r=e.nodeType(a.type).create(a.attrs,i,n);return r.type.checkAttrs(r.attrs),r}}Rn.prototype.text=void 0;class Yh extends Rn{constructor(e,a,n,i){if(super(e,a,null,i),!n)throw new RangeError("Empty text nodes are not allowed");this.text=n}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):GO(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(e,a){return this.text.slice(e,a)}get nodeSize(){return this.text.length}mark(e){return e==this.marks?this:new Yh(this.type,this.attrs,this.text,e)}withText(e){return e==this.text?this:new Yh(this.type,this.attrs,e,this.marks)}cut(e=0,a=this.text.length){return e==0&&a==this.text.length?this:this.withText(this.text.slice(e,a))}eq(e){return this.sameMarkup(e)&&this.text==e.text}toJSON(){let e=super.toJSON();return e.text=this.text,e}}function GO(t,e){for(let a=t.length-1;a>=0;a--)e=t[a].type.name+"("+e+")";return e}class as{constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]}static parse(e,a){let n=new yie(e,a);if(n.next==null)return as.empty;let i=KO(n);n.next&&n.err("Unexpected trailing text");let r=_ie(Sie(i));return Aie(r,n),r}matchType(e){for(let a=0;a<this.next.length;a++)if(this.next[a].type==e)return this.next[a].next;return null}matchFragment(e,a=0,n=e.childCount){let i=this;for(let r=a;i&&r<n;r++)i=i.matchType(e.child(r).type);return i}get inlineContent(){return this.next.length!=0&&this.next[0].type.isInline}get defaultType(){for(let e=0;e<this.next.length;e++){let{type:a}=this.next[e];if(!(a.isText||a.hasRequiredAttrs()))return a}return null}compatible(e){for(let a=0;a<this.next.length;a++)for(let n=0;n<e.next.length;n++)if(this.next[a].type==e.next[n].type)return!0;return!1}fillBefore(e,a=!1,n=0){let i=[this];function r(o,l){let c=o.matchFragment(e,n);if(c&&(!a||c.validEnd))return V.from(l.map(d=>d.createAndFill()));for(let d=0;d<o.next.length;d++){let{type:u,next:p}=o.next[d];if(!(u.isText||u.hasRequiredAttrs())&&i.indexOf(p)==-1){i.push(p);let m=r(p,l.concat(u));if(m)return m}}return null}return r(this,[])}findWrapping(e){for(let n=0;n<this.wrapCache.length;n+=2)if(this.wrapCache[n]==e)return this.wrapCache[n+1];let a=this.computeWrapping(e);return this.wrapCache.push(e,a),a}computeWrapping(e){let a=Object.create(null),n=[{match:this,type:null,via:null}];for(;n.length;){let i=n.shift(),r=i.match;if(r.matchType(e)){let o=[];for(let l=i;l.type;l=l.via)o.push(l.type);return o.reverse()}for(let o=0;o<r.next.length;o++){let{type:l,next:c}=r.next[o];!l.isLeaf&&!l.hasRequiredAttrs()&&!(l.name in a)&&(!i.type||c.validEnd)&&(n.push({match:l.contentMatch,type:l,via:i}),a[l.name]=!0)}}return null}get edgeCount(){return this.next.length}edge(e){if(e>=this.next.length)throw new RangeError(`There's no ${e}th edge in this content match`);return this.next[e]}toString(){let e=[];function a(n){e.push(n);for(let i=0;i<n.next.length;i++)e.indexOf(n.next[i].next)==-1&&a(n.next[i].next)}return a(this),e.map((n,i)=>{let r=i+(n.validEnd?"*":" ")+" ";for(let o=0;o<n.next.length;o++)r+=(o?", ":"")+n.next[o].type.name+"->"+e.indexOf(n.next[o].next);return r}).join(` 17631`)}}as.empty=new as(!0);class yie{constructor(e,a){this.string=e,this.nodeTypes=a,this.inline=null,this.pos=0,this.tokens=e.split(/\s*(?=\b|\W|$)/),this.tokens[this.tokens.length-1]==""&&this.tokens.pop(),this.tokens[0]==""&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(e){return this.next==e&&(this.pos++||!0)}err(e){throw new SyntaxError(e+" (in content expression '"+this.string+"')")}}function KO(t){let e=[];do e.push(xie(t));while(t.eat("|"));return e.length==1?e[0]:{type:"choice",exprs:e}}function xie(t){let e=[];do e.push(vie(t));while(t.next&&t.next!=")"&&t.next!="|");return e.length==1?e[0]:{type:"seq",exprs:e}}function vie(t){let e=kie(t);for(;;)if(t.eat("+"))e={type:"plus",expr:e};else if(t.eat("*"))e={type:"star",expr:e};else if(t.eat("?"))e={type:"opt",expr:e};else if(t.eat("{"))e=bie(t,e);else break;return e}function kj(t){/\D/.test(t.next)&&t.err("Expected number, got '"+t.next+"'");let e=Number(t.next);return t.pos++,e}function bie(t,e){let a=kj(t),n=a;return t.eat(",")&&(t.next!="}"?n=kj(t):n=-1),t.eat("}")||t.err("Unclosed braced range"),{type:"range",min:a,max:n,expr:e}}function wie(t,e){let a=t.nodeTypes,n=a[e];if(n)return[n];let i=[];for(let r in a){let o=a[r];o.isInGroup(e)&&i.push(o)}return i.length==0&&t.err("No node type or group '"+e+"' found"),i}function kie(t){if(t.eat("(")){let e=KO(t);return t.eat(")")||t.err("Missing closing paren"),e}else if(/\W/.test(t.next))t.err("Unexpected token '"+t.next+"'");else{let e=wie(t,t.next).map(a=>(t.inline==null?t.inline=a.isInline:t.inline!=a.isInline&&t.err("Mixing inline and block content"),{type:"name",value:a}));return t.pos++,e.length==1?e[0]:{type:"choice",exprs:e}}}function Sie(t){let e=[[]];return i(r(t,0),a()),e;function a(){return e.push([])-1}function n(o,l,c){let d={term:c,to:l};return e[o].push(d),d}function i(o,l){o.forEach(c=>c.to=l)}function r(o,l){if(o.type=="choice")return o.exprs.reduce((c,d)=>c.concat(r(d,l)),[]);if(o.type=="seq")for(let c=0;;c++){let d=r(o.exprs[c],l);if(c==o.exprs.length-1)return d;i(d,l=a())}else if(o.type=="star"){let c=a();return n(l,c),i(r(o.expr,c),c),[n(c)]}else if(o.type=="plus"){let c=a();return i(r(o.expr,l),c),i(r(o.expr,c),c),[n(c)]}else{if(o.type=="opt")return[n(l)].concat(r(o.expr,l));if(o.type=="range"){let c=l;for(let d=0;d<o.min;d++){let u=a();i(r(o.expr,c),u),c=u}if(o.max==-1)i(r(o.expr,c),c);else for(let d=o.min;d<o.max;d++){let u=a();n(c,u),i(r(o.expr,c),u),c=u}return[n(c)]}else{if(o.type=="name")return[n(l,void 0,o.value)];throw new Error("Unknown expr type")}}}}function JO(t,e){return e-t}function Sj(t,e){let a=[];return n(e),a.sort(JO);function n(i){let r=t[i];if(r.length==1&&!r[0].term)return n(r[0].to);a.push(i);for(let o=0;o<r.length;o++){let{term:l,to:c}=r[o];!l&&a.indexOf(c)==-1&&n(c)}}}function _ie(t){let e=Object.create(null);return a(Sj(t,0));function a(n){let i=[];n.forEach(o=>{t[o].forEach(({term:l,to:c})=>{if(!l)return;let d;for(let u=0;u<i.length;u++)i[u][0]==l&&(d=i[u][1]);Sj(t,c).forEach(u=>{d||i.push([l,d=[]]),d.indexOf(u)==-1&&d.push(u)})})});let r=e[n.join(",")]=new as(n.indexOf(t.length-1)>-1);for(let o=0;o<i.length;o++){let l=i[o][1].sort(JO);r.next.push({type:i[o][0],next:e[l.join(",")]||a(l)})}return r}}function Aie(t,e){for(let a=0,n=[t];a<n.length;a++){let i=n[a],r=!i.validEnd,o=[];for(let l=0;l<i.next.length;l++){let{type:c,next:d}=i.next[l];o.push(c.name),r&&!(c.isText||c.hasRequiredAttrs())&&(r=!1),n.indexOf(d)==-1&&n.push(d)}r&&e.err("Only non-generatable nodes ("+o.join(", ")+") in a required position (see https://prosemirror.net/docs/guide/#generatable)")}}function QO(t){let e=Object.create(null);for(let a in t){let n=t[a];if(!n.hasDefault)return null;e[a]=n.default}return e}function XO(t,e){let a=Object.create(null);for(let n in t){let i=e&&e[n];if(i===void 0){let r=t[n];if(r.hasDefault)i=r.default;else throw new RangeError("No value supplied for attribute "+n)}a[n]=i}return a}function YO(t,e,a,n){for(let i in e)if(!(i in t))throw new RangeError(`Unsupported attribute ${i} for ${a} of type ${i}`);for(let i in t){let r=t[i];r.validate&&r.validate(e[i])}}function ZO(t,e){let a=Object.create(null);if(e)for(let n in e)a[n]=new Cie(t,n,e[n]);return a}let _j=class eM{constructor(e,a,n){this.name=e,this.schema=a,this.spec=n,this.markSet=null,this.groups=n.group?n.group.split(" "):[],this.attrs=ZO(e,n.attrs),this.defaultAttrs=QO(this.attrs),this.contentMatch=null,this.inlineContent=null,this.isBlock=!(n.inline||e=="text"),this.isText=e=="text"}get isInline(){return!this.isBlock}get isTextblock(){return this.isBlock&&this.inlineContent}get isLeaf(){return this.contentMatch==as.empty}get isAtom(){return this.isLeaf||!!this.spec.atom}isInGroup(e){return this.groups.indexOf(e)>-1}get whitespace(){return this.spec.whitespace||(this.spec.code?"pre":"normal")}hasRequiredAttrs(){for(let e in this.attrs)if(this.attrs[e].isRequired)return!0;return!1}compatibleContent(e){return this==e||this.contentMatch.compatible(e.contentMatch)}computeAttrs(e){return!e&&this.defaultAttrs?this.defaultAttrs:XO(this.attrs,e)}create(e=null,a,n){if(this.isText)throw new Error("NodeType.create can't construct text nodes");return new Rn(this,this.computeAttrs(e),V.from(a),qe.setFrom(n))}createChecked(e=null,a,n){return a=V.from(a),this.checkContent(a),new Rn(this,this.computeAttrs(e),a,qe.setFrom(n))}createAndFill(e=null,a,n){if(e=this.computeAttrs(e),a=V.from(a),a.size){let o=this.contentMatch.fillBefore(a);if(!o)return null;a=o.append(a)}let i=this.contentMatch.matchFragment(a),r=i&&i.fillBefore(V.empty,!0);return r?new Rn(this,e,a.append(r),qe.setFrom(n)):null}validContent(e){let a=this.contentMatch.matchFragment(e);
vendor: 9,575 bytes, lines 17631-17632
17631if(!a||!a.validEnd)return!1;for(let n=0;n<e.childCount;n++)if(!this.allowsMarks(e.child(n).marks))return!1;return!0}checkContent(e){if(!this.validContent(e))throw new RangeError(`Invalid content for node ${this.name}: ${e.toString().slice(0,50)}`)}checkAttrs(e){YO(this.attrs,e,"node",this.name)}allowsMarkType(e){return this.markSet==null||this.markSet.indexOf(e)>-1}allowsMarks(e){if(this.markSet==null)return!0;for(let a=0;a<e.length;a++)if(!this.allowsMarkType(e[a].type))return!1;return!0}allowedMarks(e){if(this.markSet==null)return e;let a;for(let n=0;n<e.length;n++)this.allowsMarkType(e[n].type)?a&&a.push(e[n]):a||(a=e.slice(0,n));return a?a.length?a:qe.none:e}static compile(e,a){let n=Object.create(null);e.forEach((r,o)=>n[r]=new eM(r,a,o));let i=a.spec.topNode||"doc";if(!n[i])throw new RangeError("Schema is missing its top node type ('"+i+"')");if(!n.text)throw new RangeError("Every schema needs a 'text' type");for(let r in n.text.attrs)throw new RangeError("The text node type should not have attributes");return n}};function Eie(t,e,a){let n=a.split("|");return i=>{let r=i===null?"null":typeof i;if(n.indexOf(r)<0)throw new RangeError(`Expected value of type ${n} for attribute ${e} on type ${t}, got ${r}`)}}class Cie{constructor(e,a,n){this.hasDefault=Object.prototype.hasOwnProperty.call(n,"default"),this.default=n.default,this.validate=typeof n.validate=="string"?Eie(e,a,n.validate):n.validate}get isRequired(){return!this.hasDefault}}class Dg{constructor(e,a,n,i){this.name=e,this.rank=a,this.schema=n,this.spec=i,this.attrs=ZO(e,i.attrs),this.excluded=null;let r=QO(this.attrs);this.instance=r?new qe(this,r):null}create(e=null){return!e&&this.instance?this.instance:new qe(this,XO(this.attrs,e))}static compile(e,a){let n=Object.create(null),i=0;return e.forEach((r,o)=>n[r]=new Dg(r,i++,a,o)),n}removeFromSet(e){for(var a=0;a<e.length;a++)e[a].type==this&&(e=e.slice(0,a).concat(e.slice(a+1)),a--);return e}isInSet(e){for(let a=0;a<e.length;a++)if(e[a].type==this)return e[a]}checkAttrs(e){YO(this.attrs,e,"mark",this.name)}excludes(e){return this.excluded.indexOf(e)>-1}}class tM{constructor(e){this.linebreakReplacement=null,this.cached=Object.create(null);let a=this.spec={};for(let i in e)a[i]=e[i];a.nodes=Dt.from(e.nodes),a.marks=Dt.from(e.marks||{}),this.nodes=_j.compile(this.spec.nodes,this),this.marks=Dg.compile(this.spec.marks,this);let n=Object.create(null);for(let i in this.nodes){if(i in this.marks)throw new RangeError(i+" can not be both a node and a mark");let r=this.nodes[i],o=r.spec.content||"",l=r.spec.marks;if(r.contentMatch=n[o]||(n[o]=as.parse(o,this.nodes)),r.inlineContent=r.contentMatch.inlineContent,r.spec.linebreakReplacement){if(this.linebreakReplacement)throw new RangeError("Multiple linebreak nodes defined");if(!r.isInline||!r.isLeaf)throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");this.linebreakReplacement=r}r.markSet=l=="_"?null:l?Aj(this,l.split(" ")):l==""||!r.inlineContent?[]:null}for(let i in this.marks){let r=this.marks[i],o=r.spec.excludes;r.excluded=o==null?[r]:o==""?[]:Aj(this,o.split(" "))}this.nodeFromJSON=i=>Rn.fromJSON(this,i),this.markFromJSON=i=>qe.fromJSON(this,i),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(e,a=null,n,i){if(typeof e=="string")e=this.nodeType(e);else if(e instanceof _j){if(e.schema!=this)throw new RangeError("Node type from different schema used ("+e.name+")")}else throw new RangeError("Invalid node type: "+e);return e.createChecked(a,n,i)}text(e,a){let n=this.nodes.text;return new Yh(n,n.defaultAttrs,e,qe.setFrom(a))}mark(e,a){return typeof e=="string"&&(e=this.marks[e]),e.create(a)}nodeType(e){let a=this.nodes[e];if(!a)throw new RangeError("Unknown node type: "+e);return a}}function Aj(t,e){let a=[];for(let n=0;n<e.length;n++){let i=e[n],r=t.marks[i],o=r;if(r)a.push(r);else for(let l in t.marks){let c=t.marks[l];(i=="_"||c.spec.group&&c.spec.group.split(" ").indexOf(i)>-1)&&a.push(o=c)}if(!o)throw new SyntaxError("Unknown mark type: '"+e[n]+"'")}return a}function jie(t){return t.tag!=null}function Tie(t){return t.style!=null}class Rr{constructor(e,a){this.schema=e,this.rules=a,this.tags=[],this.styles=[];let n=this.matchedStyles=[];a.forEach(i=>{if(jie(i))this.tags.push(i);else if(Tie(i)){let r=/[^=]*/.exec(i.style)[0];n.indexOf(r)<0&&n.push(r),this.styles.push(i)}}),this.normalizeLists=!this.tags.some(i=>{if(!/^(ul|ol)\b/.test(i.tag)||!i.node)return!1;let r=e.nodes[i.node];return r.contentMatch.matchType(r)})}parse(e,a={}){let n=new Cj(this,a,!1);return n.addAll(e,qe.none,a.from,a.to),n.finish()}parseSlice(e,a={}){let n=new Cj(this,a,!0);return n.addAll(e,qe.none,a.from,a.to),K.maxOpen(n.finish())}matchTag(e,a,n){for(let i=n?this.tags.indexOf(n)+1:0;i<this.tags.length;i++){let r=this.tags[i];if(Pie(e,r.tag)&&(r.namespace===void 0||e.namespaceURI==r.namespace)&&(!r.context||a.matchesContext(r.context))){if(r.getAttrs){let o=r.getAttrs(e);if(o===!1)continue;r.attrs=o||void 0}return r}}}matchStyle(e,a,n,i){for(let r=i?this.styles.indexOf(i)+1:0;r<this.styles.length;r++){let o=this.styles[r],l=o.style;if(!(l.indexOf(e)!=0||o.context&&!n.matchesContext(o.context)||l.length>e.length&&(l.charCodeAt(e.length)!=61||l.slice(e.length+1)!=a))){if(o.getAttrs){let c=o.getAttrs(a);if(c===!1)continue;o.attrs=c||void 0}return o}}}static schemaRules(e){let a=[];function n(i){let r=i.priority==null?50:i.priority,o=0;for(;o<a.length;o++){let l=a[o];if((l.priority==null?50:l.priority)<r)break}a.splice(o,0,i)}for(let i in e.marks){let r=e.marks[i].spec.parseDOM;r&&r.forEach(o=>{n(o=jj(o)),o.mark||o.ignore||o.clearMark||(o.mark=i)})}for(let i in e.nodes){let r=e.nodes[i].spec.parseDOM;r&&r.forEach(o=>{n(o=jj(o)),o.node||o.ignore||o.mark||(o.node=i)})}return a}static fromSchema(e){return e.cached.domParser||(e.cached.domParser=new Rr(e,Rr.schemaRules(e)))}}const aM={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},Nie={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},nM={ol:!0,ul:!0},uu=1,Ab=2,bd=4;function Ej(t,e,a){return e!=null?(e?uu:0)|(e==="full"?Ab:0):t&&t.whitespace=="pre"?uu|Ab:a&~bd}class Yp{constructor(e,a,n,i,r,o){this.type=e,this.attrs=a,this.marks=n,this.solid=i,this.options=o,this.content=[],this.activeMarks=qe.none,this.match=r||(o&bd?null:e.contentMatch)}findWrapping(e){if(!this.match){if(!this.type)return[];let a=this.type.contentMatch.fillBefore(V.from(e));if(a)this.match=this.type.contentMatch.matchFragment(a);else{let n=this.type.contentMatch,i;return(i=n.findWrapping(e.type))?(this.match=n,i):null}}return this.match.findWrapping(e.type)}finish(e){if(!(this.options&uu)){let n=this.content[this.content.length-1],i;if(n&&n.isText&&(i=/[ \t\r\n\u000c]+$/.exec(n.text))){let r=n;n.text.length==i[0].length?this.content.pop():this.content[this.content.length-1]=r.withText(r.text.slice(0,r.text.length-i[0].length))}}let a=V.from(this.content);return!e&&this.match&&(a=a.append(this.match.fillBefore(V.empty,!0))),this.type?this.type.create(this.attrs,a,this.marks):a}inlineContext(e){return this.type?this.type.inlineContent:this.content.length?this.content[0].isInline:e.parentNode&&!aM.hasOwnProperty(e.parentNode.nodeName.toLowerCase())}}class Cj{constructor(e,a,n){this.parser=e,this.options=a,this.isOpen=n,this.open=0,this.localPreserveWS=!1;let i=a.topNode,r,o=Ej(null,a.preserveWhitespace,0)|(n?bd:0);i?r=new Yp(i.type,i.attrs,qe.none,!0,a.topMatch||i.type.contentMatch,o):n?r=new Yp(null,null,qe.none,!0,null,o):r=new Yp(e.schema.topNodeType,null,qe.none,!0,null,o),this.nodes=[r],this.find=a.findPositions,this.needsBlock=!1}get top(){return this.nodes[this.open]}addDOM(e,a){e.nodeType==3?this.addTextNode(e,a):e.nodeType==1&&this.addElement(e,a)}addTextNode(e,a){let n=e.nodeValue,i=this.top,r=i.options&Ab?"full":this.localPreserveWS||(i.options&uu)>0,{schema:o}=this.parser;if(r==="full"||i.inlineContext(e)||/[^ \t\r\n\u000c]/.test(n)){if(r)if(r==="full")n=n.replace(/\r\n?/g,` 17632`);else if(o.linebreakReplacement&&/[\r\n]/.test(n)&&this.top.findWrapping(o.linebreakReplacement.create())){let l=n.split(/\r?\n|\r/);for(let c=0;c<l.length;c++)c&&this.insertNode(o.linebreakReplacement.create(),a,!0),l[c]&&this.insertNode(o.text(l[c]),a,!/\S/.test(l[c]));n=""}else n=n.replace(/\r?\n|\r/g," ");else if(n=n.replace(/[ \t\r\n\u000c]+/g," "),/^[ \t\r\n\u000c]/.test(n)&&this.open==this.nodes.length-1){let l=i.content[i.content.length-1],c=e.previousSibling;(!l||c&&c.nodeName=="BR"||l.isText&&/[ \t\r\n\u000c]$/.test(l.text))&&(n=n.slice(1))}n&&this.insertNode(o.text(n),a,!/\S/.test(n)),this.findInText(e)}else this.findInside(e)}addElement(e,a,n){let i=this.localPreserveWS,r=this.top;(e.tagName=="PRE"||/pre/.test(e.style&&e.style.whiteSpace))&&(this.localPreserveWS=!0);let o=e.nodeName.toLowerCase(),l;nM.hasOwnProperty(o)&&this.parser.normalizeLists&&Iie(e);let c=this.options.ruleFromNode&&this.options.ruleFromNode(e)||(l=this.parser.matchTag(e,this,n));e:if(c?c.ignore:Nie.hasOwnProperty(o))this.findInside(e),this.ignoreFallback(e,a);else if(!c||c.skip||c.closeParent){c&&c.closeParent?this.open=Math.max(0,this.open-1):c&&c.skip.nodeType&&(e=c.skip);let d,u=this.needsBlock;if(aM.hasOwnProperty(o))r.content.length&&r.content[0].isInline&&this.open&&(this.open--,r=this.top),d=!0,r.type||(this.needsBlock=!0);else if(!e.firstChild){this.leafFallback(e,a);break e}
vendor: 4,920 bytes, lines 17632-17633
17632let p=c&&c.skip?a:this.readStyles(e,a);p&&this.addAll(e,p),d&&this.sync(r),this.needsBlock=u}else{let d=this.readStyles(e,a);d&&this.addElementByRule(e,c,d,c.consuming===!1?l:void 0)}this.localPreserveWS=i}leafFallback(e,a){e.nodeName=="BR"&&this.top.type&&this.top.type.inlineContent&&this.addTextNode(e.ownerDocument.createTextNode(` 17633`),a)}ignoreFallback(e,a){e.nodeName=="BR"&&(!this.top.type||!this.top.type.inlineContent)&&this.findPlace(this.parser.schema.text("-"),a,!0)}readStyles(e,a){let n=e.style;if(n&&n.length)for(let i=0;i<this.parser.matchedStyles.length;i++){let r=this.parser.matchedStyles[i],o=n.getPropertyValue(r);if(o)for(let l=void 0;;){let c=this.parser.matchStyle(r,o,this,l);if(!c)break;if(c.ignore)return null;if(c.clearMark?a=a.filter(d=>!c.clearMark(d)):a=a.concat(this.parser.schema.marks[c.mark].create(c.attrs)),c.consuming===!1)l=c;else break}}return a}addElementByRule(e,a,n,i){let r,o;if(a.node)if(o=this.parser.schema.nodes[a.node],o.isLeaf)this.insertNode(o.create(a.attrs),n,e.nodeName=="BR")||this.leafFallback(e,n);else{let c=this.enter(o,a.attrs||null,n,a.preserveWhitespace);c&&(r=!0,n=c)}else{let c=this.parser.schema.marks[a.mark];n=n.concat(c.create(a.attrs))}let l=this.top;if(o&&o.isLeaf)this.findInside(e);else if(i)this.addElement(e,n,i);else if(a.getContent)this.findInside(e),a.getContent(e,this.parser.schema).forEach(c=>this.insertNode(c,n,!1));else{let c=e;typeof a.contentElement=="string"?c=e.querySelector(a.contentElement):typeof a.contentElement=="function"?c=a.contentElement(e):a.contentElement&&(c=a.contentElement),this.findAround(e,c,!0),this.addAll(c,n),this.findAround(e,c,!1)}r&&this.sync(l)&&this.open--}addAll(e,a,n,i){let r=n||0;for(let o=n?e.childNodes[n]:e.firstChild,l=i==null?null:e.childNodes[i];o!=l;o=o.nextSibling,++r)this.findAtPoint(e,r),this.addDOM(o,a);this.findAtPoint(e,r)}findPlace(e,a,n){let i,r;for(let o=this.open,l=0;o>=0;o--){let c=this.nodes[o],d=c.findWrapping(e);if(d&&(!i||i.length>d.length+l)&&(i=d,r=c,!d.length))break;if(c.solid){if(n)break;l+=2}}if(!i)return null;this.sync(r);for(let o=0;o<i.length;o++)a=this.enterInner(i[o],null,a,!1);return a}insertNode(e,a,n){if(e.isInline&&this.needsBlock&&!this.top.type){let r=this.textblockFromContext();r&&(a=this.enterInner(r,null,a))}let i=this.findPlace(e,a,n);if(i){this.closeExtra();let r=this.top;r.match&&(r.match=r.match.matchType(e.type));let o=qe.none;for(let l of i.concat(e.marks))(r.type?r.type.allowsMarkType(l.type):Tj(l.type,e.type))&&(o=l.addToSet(o));return r.content.push(e.mark(o)),!0}return!1}enter(e,a,n,i){let r=this.findPlace(e.create(a),n,!1);return r&&(r=this.enterInner(e,a,n,!0,i)),r}enterInner(e,a,n,i=!1,r){this.closeExtra();let o=this.top;o.match=o.match&&o.match.matchType(e);let l=Ej(e,r,o.options);o.options&bd&&o.content.length==0&&(l|=bd);let c=qe.none;return n=n.filter(d=>(o.type?o.type.allowsMarkType(d.type):Tj(d.type,e))?(c=d.addToSet(c),!1):!0),this.nodes.push(new Yp(e,a,c,i,null,l)),this.open++,n}closeExtra(e=!1){let a=this.nodes.length-1;if(a>this.open){for(;a>this.open;a--)this.nodes[a-1].content.push(this.nodes[a].finish(e));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(!!(this.isOpen||this.options.topOpen))}sync(e){for(let a=this.open;a>=0;a--){if(this.nodes[a]==e)return this.open=a,!0;this.localPreserveWS&&(this.nodes[a].options|=uu)}return!1}get currentPos(){this.closeExtra();let e=0;for(let a=this.open;a>=0;a--){let n=this.nodes[a].content;for(let i=n.length-1;i>=0;i--)e+=n[i].nodeSize;a&&e++}return e}findAtPoint(e,a){if(this.find)for(let n=0;n<this.find.length;n++)this.find[n].node==e&&this.find[n].offset==a&&(this.find[n].pos=this.currentPos)}findInside(e){if(this.find)for(let a=0;a<this.find.length;a++)this.find[a].pos==null&&e.nodeType==1&&e.contains(this.find[a].node)&&(this.find[a].pos=this.currentPos)}findAround(e,a,n){if(e!=a&&this.find)for(let i=0;i<this.find.length;i++)this.find[i].pos==null&&e.nodeType==1&&e.contains(this.find[i].node)&&a.compareDocumentPosition(this.find[i].node)&(n?2:4)&&(this.find[i].pos=this.currentPos)}findInText(e){if(this.find)for(let a=0;a<this.find.length;a++)this.find[a].node==e&&(this.find[a].pos=this.currentPos-(e.nodeValue.length-this.find[a].offset))}matchesContext(e){if(e.indexOf("|")>-1)return e.split(/\s*\|\s*/).some(this.matchesContext,this);let a=e.split("/"),n=this.options.context,i=!this.isOpen&&(!n||n.parent.type==this.nodes[0].type),r=-(n?n.depth+1:0)+(i?0:1),o=(l,c)=>{for(;l>=0;l--){let d=a[l];if(d==""){if(l==a.length-1||l==0)continue;for(;c>=r;c--)if(o(l-1,c))return!0;return!1}else{let u=c>0||c==0&&i?this.nodes[c].type:n&&c>=r?n.node(c-r).type:null;if(!u||u.name!=d&&!u.isInGroup(d))return!1;c--}}return!0};return o(a.length-1,this.open)}textblockFromContext(){let e=this.options.context;if(e)for(let a=e.depth;a>=0;a--){let n=e.node(a).contentMatchAt(e.indexAfter(a)).defaultType;
vendor: 8,890 bytes, line 17633
17633if(n&&n.isTextblock&&n.defaultAttrs)return n}for(let a in this.parser.schema.nodes){let n=this.parser.schema.nodes[a];if(n.isTextblock&&n.defaultAttrs)return n}}}function Iie(t){for(let e=t.firstChild,a=null;e;e=e.nextSibling){let n=e.nodeType==1?e.nodeName.toLowerCase():null;n&&nM.hasOwnProperty(n)&&a?(a.appendChild(e),e=a):n=="li"?a=e:n&&(a=null)}}function Pie(t,e){return(t.matches||t.msMatchesSelector||t.webkitMatchesSelector||t.mozMatchesSelector).call(t,e)}function jj(t){let e={};for(let a in t)e[a]=t[a];return e}function Tj(t,e){let a=e.schema.nodes;for(let n in a){let i=a[n];if(!i.allowsMarkType(t))continue;let r=[],o=l=>{r.push(l);for(let c=0;c<l.edgeCount;c++){let{type:d,next:u}=l.edge(c);if(d==e||r.indexOf(u)<0&&o(u))return!0}};if(o(i.contentMatch))return!0}}class fs{constructor(e,a){this.nodes=e,this.marks=a}serializeFragment(e,a={},n){n||(n=U0(a).createDocumentFragment());let i=n,r=[];return e.forEach(o=>{if(r.length||o.marks.length){let l=0,c=0;for(;l<r.length&&c<o.marks.length;){let d=o.marks[c];if(!this.marks[d.type.name]){c++;continue}if(!d.eq(r[l][0])||d.type.spec.spanning===!1)break;l++,c++}for(;l<r.length;)i=r.pop()[1];for(;c<o.marks.length;){let d=o.marks[c++],u=this.serializeMark(d,o.isInline,a);u&&(r.push([d,i]),i.appendChild(u.dom),i=u.contentDOM||u.dom)}}i.appendChild(this.serializeNodeInner(o,a))}),n}serializeNodeInner(e,a){let{dom:n,contentDOM:i}=Bm(U0(a),this.nodes[e.type.name](e),null,e.attrs);if(i){if(e.isLeaf)throw new RangeError("Content hole not allowed in a leaf node spec");this.serializeFragment(e.content,a,i)}return n}serializeNode(e,a={}){let n=this.serializeNodeInner(e,a);for(let i=e.marks.length-1;i>=0;i--){let r=this.serializeMark(e.marks[i],e.isInline,a);r&&((r.contentDOM||r.dom).appendChild(n),n=r.dom)}return n}serializeMark(e,a,n={}){let i=this.marks[e.type.name];return i&&Bm(U0(n),i(e,a),null,e.attrs)}static renderSpec(e,a,n=null,i){return Bm(e,a,n,i)}static fromSchema(e){return e.cached.domSerializer||(e.cached.domSerializer=new fs(this.nodesFromSchema(e),this.marksFromSchema(e)))}static nodesFromSchema(e){let a=Nj(e.nodes);return a.text||(a.text=n=>n.text),a}static marksFromSchema(e){return Nj(e.marks)}}function Nj(t){let e={};for(let a in t){let n=t[a].spec.toDOM;n&&(e[a]=n)}return e}function U0(t){return t.document||window.document}const Ij=new WeakMap;function Rie(t){let e=Ij.get(t);return e===void 0&&Ij.set(t,e=Lie(t)),e}function Lie(t){let e=null;function a(n){if(n&&typeof n=="object")if(Array.isArray(n))if(typeof n[0]=="string")e||(e=[]),e.push(n);else for(let i=0;i<n.length;i++)a(n[i]);else for(let i in n)a(n[i])}return a(t),e}function Bm(t,e,a,n){if(typeof e=="string")return{dom:t.createTextNode(e)};if(e.nodeType!=null)return{dom:e};if(e.dom&&e.dom.nodeType!=null)return e;let i=e[0],r;if(typeof i!="string")throw new RangeError("Invalid array passed to renderSpec");if(n&&(r=Rie(n))&&r.indexOf(e)>-1)throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");let o=i.indexOf(" ");o>0&&(a=i.slice(0,o),i=i.slice(o+1));let l,c=a?t.createElementNS(a,i):t.createElement(i),d=e[1],u=1;if(d&&typeof d=="object"&&d.nodeType==null&&!Array.isArray(d)){u=2;for(let p in d)if(d[p]!=null){let m=p.indexOf(" ");m>0?c.setAttributeNS(p.slice(0,m),p.slice(m+1),d[p]):p=="style"&&c.style?c.style.cssText=d[p]:c.setAttribute(p,d[p])}}for(let p=u;p<e.length;p++){let m=e[p];if(m===0){if(p<e.length-1||p>u)throw new RangeError("Content hole must be the only child of its parent node");return{dom:c,contentDOM:c}}else{let{dom:h,contentDOM:g}=Bm(t,m,a,n);if(c.appendChild(h),g){if(l)throw new RangeError("Multiple content holes");l=g}}}return{dom:c,contentDOM:l}}const iM=65535,rM=Math.pow(2,16);function Oie(t,e){return t+e*rM}function Pj(t){return t&iM}function Mie(t){return(t-(t&iM))/rM}const oM=1,sM=2,Um=4,lM=8;class Eb{constructor(e,a,n){this.pos=e,this.delInfo=a,this.recover=n}get deleted(){return(this.delInfo&lM)>0}get deletedBefore(){return(this.delInfo&(oM|Um))>0}get deletedAfter(){return(this.delInfo&(sM|Um))>0}get deletedAcross(){return(this.delInfo&Um)>0}}class qa{constructor(e,a=!1){if(this.ranges=e,this.inverted=a,!e.length&&qa.empty)return qa.empty}recover(e){let a=0,n=Pj(e);if(!this.inverted)for(let i=0;i<n;i++)a+=this.ranges[i*3+2]-this.ranges[i*3+1];return this.ranges[n*3]+a+Mie(e)}mapResult(e,a=1){return this._map(e,a,!1)}map(e,a=1){return this._map(e,a,!0)}_map(e,a,n){let i=0,r=this.inverted?2:1,o=this.inverted?1:2;for(let l=0;l<this.ranges.length;l+=3){let c=this.ranges[l]-(this.inverted?i:0);if(c>e)break;let d=this.ranges[l+r],u=this.ranges[l+o],p=c+d;if(e<=p){let m=d?e==c?-1:e==p?1:a:a,h=c+i+(m<0?0:u);if(n)return h;let g=e==(a<0?c:p)?null:Oie(l/3,e-c),y=e==c?sM:e==p?oM:Um;return(a<0?e!=c:e!=p)&&(y|=lM),new Eb(h,y,g)}i+=u-d}return n?e+i:new Eb(e+i,0,null)}touches(e,a){let n=0,i=Pj(a),r=this.inverted?2:1,o=this.inverted?1:2;for(let l=0;l<this.ranges.length;l+=3){let c=this.ranges[l]-(this.inverted?n:0);if(c>e)break;let d=this.ranges[l+r],u=c+d;if(e<=u&&l==i*3)return!0;n+=this.ranges[l+o]-d}return!1}forEach(e){let a=this.inverted?2:1,n=this.inverted?1:2;for(let i=0,r=0;i<this.ranges.length;i+=3){let o=this.ranges[i],l=o-(this.inverted?r:0),c=o+(this.inverted?0:r),d=this.ranges[i+a],u=this.ranges[i+n];e(l,l+d,c,c+u),r+=u-d}}invert(){return new qa(this.ranges,!this.inverted)}toString(){return(this.inverted?"-":"")+JSON.stringify(this.ranges)}static offset(e){return e==0?qa.empty:new qa(e<0?[0,-e,0]:[0,0,e])}}qa.empty=new qa([]);class pu{constructor(e,a,n=0,i=e?e.length:0){this.mirror=a,this.from=n,this.to=i,this._maps=e||[],this.ownData=!(e||a)}get maps(){return this._maps}slice(e=0,a=this.maps.length){return new pu(this._maps,this.mirror,e,a)}appendMap(e,a){this.ownData||(this._maps=this._maps.slice(),this.mirror=this.mirror&&this.mirror.slice(),this.ownData=!0),this.to=this._maps.push(e),a!=null&&this.setMirror(this._maps.length-1,a)}appendMapping(e){for(let a=0,n=this._maps.length;a<e._maps.length;a++){let i=e.getMirror(a);this.appendMap(e._maps[a],i!=null&&i<a?n+i:void 0)}}getMirror(e){if(this.mirror){for(let a=0;a<this.mirror.length;a++)if(this.mirror[a]==e)return this.mirror[a+(a%2?-1:1)]}}setMirror(e,a){this.mirror||(this.mirror=[]),this.mirror.push(e,a)}appendMappingInverted(e){for(let a=e.maps.length-1,n=this._maps.length+e._maps.length;a>=0;a--){let i=e.getMirror(a);this.appendMap(e._maps[a].invert(),i!=null&&i>a?n-i-1:void 0)}}invert(){let e=new pu;return e.appendMappingInverted(this),e}map(e,a=1){if(this.mirror)return this._map(e,a,!0);for(let n=this.from;n<this.to;n++)e=this._maps[n].map(e,a);return e}mapResult(e,a=1){return this._map(e,a,!1)}_map(e,a,n){let i=0;for(let r=this.from;r<this.to;r++){let o=this._maps[r],l=o.mapResult(e,a);if(l.recover!=null){let c=this.getMirror(r);if(c!=null&&c>r&&c<this.to){r=c,e=this._maps[c].recover(l.recover);continue}}i|=l.delInfo,e=l.pos}return n?e:new Eb(e,i,null)}}const $0=Object.create(null);class sa{getMap(){return qa.empty}merge(e){return null}static fromJSON(e,a){if(!a||!a.stepType)throw new RangeError("Invalid input for Step.fromJSON");let n=$0[a.stepType];if(!n)throw new RangeError(`No step type ${a.stepType} defined`);return n.fromJSON(e,a)}static jsonID(e,a){if(e in $0)throw new RangeError("Duplicate use of step JSON ID "+e);return $0[e]=a,a.prototype.jsonID=e,a}}class yt{constructor(e,a){this.doc=e,this.failed=a}static ok(e){return new yt(e,null)}static fail(e){return new yt(null,e)}static fromReplace(e,a,n,i){try{return yt.ok(e.replace(a,n,i))}catch(r){if(r instanceof Jh)return yt.fail(r.message);throw r}}}function Jk(t,e,a){let n=[];for(let i=0;i<t.childCount;i++){let r=t.child(i);r.content.size&&(r=r.copy(Jk(r.content,e,r))),r.isInline&&(r=e(r,a,i)),n.push(r)}return V.fromArray(n)}class xr extends sa{constructor(e,a,n){super(),this.from=e,this.to=a,this.mark=n}apply(e){let a=e.slice(this.from,this.to),n=e.resolve(this.from),i=n.node(n.sharedDepth(this.to)),r=new K(Jk(a.content,(o,l)=>!o.isAtom||!l.type.allowsMarkType(this.mark.type)?o:o.mark(this.mark.addToSet(o.marks)),i),a.openStart,a.openEnd);return yt.fromReplace(e,this.from,this.to,r)}invert(){return new jn(this.from,this.to,this.mark)}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1);return a.deleted&&n.deleted||a.pos>=n.pos?null:new xr(a.pos,n.pos,this.mark)}merge(e){return e instanceof xr&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new xr(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new xr(a.from,a.to,e.markFromJSON(a.mark))}}sa.jsonID("addMark",xr);class jn extends sa{constructor(e,a,n){super(),this.from=e,this.to=a,this.mark=n}
vendor: 6,481 bytes, line 17633
17633apply(e){let a=e.slice(this.from,this.to),n=new K(Jk(a.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),a.openStart,a.openEnd);return yt.fromReplace(e,this.from,this.to,n)}invert(){return new xr(this.from,this.to,this.mark)}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1);return a.deleted&&n.deleted||a.pos>=n.pos?null:new jn(a.pos,n.pos,this.mark)}merge(e){return e instanceof jn&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new jn(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new jn(a.from,a.to,e.markFromJSON(a.mark))}}sa.jsonID("removeMark",jn);class vr extends sa{constructor(e,a){super(),this.pos=e,this.mark=a}apply(e){let a=e.nodeAt(this.pos);if(!a)return yt.fail("No node at mark step's position");let n=a.type.create(a.attrs,null,this.mark.addToSet(a.marks));return yt.fromReplace(e,this.pos,this.pos+1,new K(V.from(n),0,a.isLeaf?0:1))}invert(e){let a=e.nodeAt(this.pos);if(a){let n=this.mark.addToSet(a.marks);if(n.length==a.marks.length){for(let i=0;i<a.marks.length;i++)if(!a.marks[i].isInSet(n))return new vr(this.pos,a.marks[i]);return new vr(this.pos,this.mark)}}return new ns(this.pos,this.mark)}map(e){let a=e.mapResult(this.pos,1);return a.deletedAfter?null:new vr(a.pos,this.mark)}toJSON(){return{stepType:"addNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(e,a){if(typeof a.pos!="number")throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");return new vr(a.pos,e.markFromJSON(a.mark))}}sa.jsonID("addNodeMark",vr);class ns extends sa{constructor(e,a){super(),this.pos=e,this.mark=a}apply(e){let a=e.nodeAt(this.pos);if(!a)return yt.fail("No node at mark step's position");let n=a.type.create(a.attrs,null,this.mark.removeFromSet(a.marks));return yt.fromReplace(e,this.pos,this.pos+1,new K(V.from(n),0,a.isLeaf?0:1))}invert(e){let a=e.nodeAt(this.pos);return!a||!this.mark.isInSet(a.marks)?this:new vr(this.pos,this.mark)}map(e){let a=e.mapResult(this.pos,1);return a.deletedAfter?null:new ns(a.pos,this.mark)}toJSON(){return{stepType:"removeNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(e,a){if(typeof a.pos!="number")throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");return new ns(a.pos,e.markFromJSON(a.mark))}}sa.jsonID("removeNodeMark",ns);class Tt extends sa{constructor(e,a,n,i=!1){super(),this.from=e,this.to=a,this.slice=n,this.structure=i}apply(e){return this.structure&&Cb(e,this.from,this.to)?yt.fail("Structure replace would overwrite content"):yt.fromReplace(e,this.from,this.to,this.slice)}getMap(){return new qa([this.from,this.to-this.from,this.slice.size])}invert(e){return new Tt(this.from,this.from+this.slice.size,e.slice(this.from,this.to))}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1);return a.deletedAcross&&n.deletedAcross?null:new Tt(a.pos,Math.max(a.pos,n.pos),this.slice,this.structure)}merge(e){if(!(e instanceof Tt)||e.structure||this.structure)return null;if(this.from+this.slice.size==e.from&&!this.slice.openEnd&&!e.slice.openStart){let a=this.slice.size+e.slice.size==0?K.empty:new K(this.slice.content.append(e.slice.content),this.slice.openStart,e.slice.openEnd);return new Tt(this.from,this.to+(e.to-e.from),a,this.structure)}else if(e.to==this.from&&!this.slice.openStart&&!e.slice.openEnd){let a=this.slice.size+e.slice.size==0?K.empty:new K(e.slice.content.append(this.slice.content),e.slice.openStart,this.slice.openEnd);return new Tt(e.from,this.to,a,this.structure)}else return null}toJSON(){let e={stepType:"replace",from:this.from,to:this.to};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number")throw new RangeError("Invalid input for ReplaceStep.fromJSON");return new Tt(a.from,a.to,K.fromJSON(e,a.slice),!!a.structure)}}sa.jsonID("replace",Tt);class Pt extends sa{constructor(e,a,n,i,r,o,l=!1){super(),this.from=e,this.to=a,this.gapFrom=n,this.gapTo=i,this.slice=r,this.insert=o,this.structure=l}apply(e){if(this.structure&&(Cb(e,this.from,this.gapFrom)||Cb(e,this.gapTo,this.to)))return yt.fail("Structure gap-replace would overwrite content");let a=e.slice(this.gapFrom,this.gapTo);if(a.openStart||a.openEnd)return yt.fail("Gap is not a flat range");let n=this.slice.insertAt(this.insert,a.content);return n?yt.fromReplace(e,this.from,this.to,n):yt.fail("Content does not fit in gap")}getMap(){return new qa([this.from,this.gapFrom-this.from,this.insert,this.gapTo,this.to-this.gapTo,this.slice.size-this.insert])}invert(e){let a=this.gapTo-this.gapFrom;return new Pt(this.from,this.from+this.slice.size+a,this.from+this.insert,this.from+this.insert+a,e.slice(this.from,this.to).removeBetween(this.gapFrom-this.from,this.gapTo-this.from),this.gapFrom-this.from,this.structure)}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1),i=this.from==this.gapFrom?a.pos:e.map(this.gapFrom,-1),r=this.to==this.gapTo?n.pos:e.map(this.gapTo,1);return a.deletedAcross&&n.deletedAcross||i<a.pos||r>n.pos?null:new Pt(a.pos,n.pos,i,r,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number"||typeof a.gapFrom!="number"||typeof a.gapTo!="number"||typeof a.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Pt(a.from,a.to,a.gapFrom,a.gapTo,K.fromJSON(e,a.slice),a.insert,!!a.structure)}}sa.jsonID("replaceAround",Pt);function Cb(t,e,a){let n=t.resolve(e),i=a-e,r=n.depth;for(;i>0&&r>0&&n.indexAfter(r)==n.node(r).childCount;)r--,i--;if(i>0){let o=n.node(r).maybeChild(n.indexAfter(r));for(;i>0;){if(!o||o.isLeaf)return!0;o=o.firstChild,i--}}return!1}function Die(t,e,a,n){let i=[],r=[],o,l;t.doc.nodesBetween(e,a,(c,d,u)=>{if(!c.isInline)return;let p=c.marks;if(!n.isInSet(p)&&u.type.allowsMarkType(n.type)){let m=Math.max(d,e),h=Math.min(d+c.nodeSize,a),g=n.addToSet(p);for(let y=0;y<p.length;y++)p[y].isInSet(g)||(o&&o.to==m&&o.mark.eq(p[y])?o.to=h:i.push(o=new jn(m,h,p[y])));l&&l.to==m?l.to=h:r.push(l=new xr(m,h,n))}}
vendor: 4,283 bytes, lines 17633-17634
17633),i.forEach(c=>t.step(c)),r.forEach(c=>t.step(c))}function qie(t,e,a,n){let i=[],r=0;t.doc.nodesBetween(e,a,(o,l)=>{if(!o.isInline)return;r++;let c=null;if(n instanceof Dg){let d=o.marks,u;for(;u=n.isInSet(d);)(c||(c=[])).push(u),d=u.removeFromSet(d)}else n?n.isInSet(o.marks)&&(c=[n]):c=o.marks;if(c&&c.length){let d=Math.min(l+o.nodeSize,a);for(let u=0;u<c.length;u++){let p=c[u],m;for(let h=0;h<i.length;h++){let g=i[h];g.step==r-1&&p.eq(i[h].style)&&(m=g)}m?(m.to=d,m.step=r):i.push({style:p,from:Math.max(l,e),to:d,step:r})}}}),i.forEach(o=>t.step(new jn(o.from,o.to,o.style)))}function Qk(t,e,a,n=a.contentMatch,i=!0){let r=t.doc.nodeAt(e),o=[],l=e+1;for(let c=0;c<r.childCount;c++){let d=r.child(c),u=l+d.nodeSize,p=n.matchType(d.type);if(!p)o.push(new Tt(l,u,K.empty));else{n=p;for(let m=0;m<d.marks.length;m++)a.allowsMarkType(d.marks[m].type)||t.step(new jn(l,u,d.marks[m]));if(i&&d.isText&&a.whitespace!="pre"){let m,h=/\r?\n|\r/g,g;for(;m=h.exec(d.text);)g||(g=new K(V.from(a.schema.text(" ",a.allowedMarks(d.marks))),0,0)),o.push(new Tt(l+m.index,l+m.index+m[0].length,g))}}l=u}if(!n.validEnd){let c=n.fillBefore(V.empty,!0);t.replace(l,l,new K(c,0,0))}for(let c=o.length-1;c>=0;c--)t.step(o[c])}function zie(t,e,a){return(e==0||t.canReplace(e,t.childCount))&&(a==t.childCount||t.canReplace(0,a))}function ec(t){let a=t.parent.content.cutByIndex(t.startIndex,t.endIndex);for(let n=t.depth,i=0,r=0;;--n){let o=t.$from.node(n),l=t.$from.index(n)+i,c=t.$to.indexAfter(n)-r;if(n<t.depth&&o.canReplace(l,c,a))return n;if(n==0||o.type.spec.isolating||!zie(o,l,c))break;l&&(i=1),c<o.childCount&&(r=1)}return null}function Vie(t,e,a){let{$from:n,$to:i,depth:r}=e,o=n.before(r+1),l=i.after(r+1),c=o,d=l,u=V.empty,p=0;for(let g=r,y=!1;g>a;g--)y||n.index(g)>0?(y=!0,u=V.from(n.node(g).copy(u)),p++):c--;let m=V.empty,h=0;for(let g=r,y=!1;g>a;g--)y||i.after(g+1)<i.end(g)?(y=!0,m=V.from(i.node(g).copy(m)),h++):d++;t.step(new Pt(c,d,o,l,new K(u.append(m),p,h),u.size-p,!0))}function Xk(t,e,a=null,n=t){let i=Hie(t,e),r=i&&Fie(n,e);return r?i.map(Rj).concat({type:e,attrs:a}).concat(r.map(Rj)):null}function Rj(t){return{type:t,attrs:null}}function Hie(t,e){let{parent:a,startIndex:n,endIndex:i}=t,r=a.contentMatchAt(n).findWrapping(e);if(!r)return null;let o=r.length?r[0]:e;return a.canReplaceWith(n,i,o)?r:null}function Fie(t,e){let{parent:a,startIndex:n,endIndex:i}=t,r=a.child(n),o=e.contentMatch.findWrapping(r.type);if(!o)return null;let c=(o.length?o[o.length-1]:e).contentMatch;for(let d=n;c&&d<i;d++)c=c.matchType(a.child(d).type);return!c||!c.validEnd?null:o}function Bie(t,e,a){let n=V.empty;for(let o=a.length-1;o>=0;o--){if(n.size){let l=a[o].type.contentMatch.matchFragment(n);if(!l||!l.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}n=V.from(a[o].type.create(a[o].attrs,n))}let i=e.start,r=e.end;t.step(new Pt(i,r,i,r,new K(n,0,0),a.length,!0))}function Uie(t,e,a,n,i){if(!n.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let r=t.steps.length;t.doc.nodesBetween(e,a,(o,l)=>{let c=typeof i=="function"?i(o):i;if(o.isTextblock&&!o.hasMarkup(n,c)&&$ie(t.doc,t.mapping.slice(r).map(l),n)){let d=null;if(n.schema.linebreakReplacement){let h=n.whitespace=="pre",g=!!n.contentMatch.matchType(n.schema.linebreakReplacement);h&&!g?d=!1:!h&&g&&(d=!0)}d===!1&&dM(t,o,l,r),Qk(t,t.mapping.slice(r).map(l,1),n,void 0,d===null);let u=t.mapping.slice(r),p=u.map(l,1),m=u.map(l+o.nodeSize,1);return t.step(new Pt(p,m,p+1,m-1,new K(V.from(n.create(c,null,o.marks)),0,0),1,!0)),d===!0&&cM(t,o,l,r),!1}})}function cM(t,e,a,n){e.forEach((i,r)=>{if(i.isText){let o,l=/\r?\n|\r/g;for(;o=l.exec(i.text);){let c=t.mapping.slice(n).map(a+1+r+o.index);t.replaceWith(c,c+1,e.type.schema.linebreakReplacement.create())}}})}function dM(t,e,a,n){e.forEach((i,r)=>{if(i.type==i.type.schema.linebreakReplacement){let o=t.mapping.slice(n).map(a+1+r);t.replaceWith(o,o+1,e.type.schema.text(` 17634`))}})}function $ie(t,e,a){let n=t.resolve(e),i=n.index();return n.parent.canReplaceWith(i,i+1,a)}function Wie(t,e,a,n,i){let r=t.doc.nodeAt(e);if(!r)throw new RangeError("No node at given position");a||(a=r.type);let o=a.create(n,null,i||r.marks);if(r.isLeaf)return t.replaceWith(e,e+r.nodeSize,o);
vendor: 11,670 bytes, line 17634
17634if(!a.validContent(r.content))throw new RangeError("Invalid content for node type "+a.name);t.step(new Pt(e,e+r.nodeSize,e+1,e+r.nodeSize-1,new K(V.from(o),0,0),1,!0))}function Ii(t,e,a=1,n){let i=t.resolve(e),r=i.depth-a,o=n&&n[n.length-1]||i.parent;if(r<0||i.parent.type.spec.isolating||!i.parent.canReplace(i.index(),i.parent.childCount)||!o.type.validContent(i.parent.content.cutByIndex(i.index(),i.parent.childCount)))return!1;for(let d=i.depth-1,u=a-2;d>r;d--,u--){let p=i.node(d),m=i.index(d);if(p.type.spec.isolating)return!1;let h=p.content.cutByIndex(m,p.childCount),g=n&&n[u+1];g&&(h=h.replaceChild(0,g.type.create(g.attrs)));let y=n&&n[u]||p;if(!p.canReplace(m+1,p.childCount)||!y.type.validContent(h))return!1}let l=i.indexAfter(r),c=n&&n[0];return i.node(r).canReplaceWith(l,l,c?c.type:i.node(r+1).type)}function Gie(t,e,a=1,n){let i=t.doc.resolve(e),r=V.empty,o=V.empty;for(let l=i.depth,c=i.depth-a,d=a-1;l>c;l--,d--){r=V.from(i.node(l).copy(r));let u=n&&n[d];o=V.from(u?u.type.create(u.attrs,o):i.node(l).copy(o))}t.step(new Tt(e,e,new K(r.append(o),a,a),!0))}function eo(t,e){let a=t.resolve(e),n=a.index();return uM(a.nodeBefore,a.nodeAfter)&&a.parent.canReplace(n,n+1)}function Kie(t,e){e.content.size||t.type.compatibleContent(e.type);let a=t.contentMatchAt(t.childCount),{linebreakReplacement:n}=t.type.schema;for(let i=0;i<e.childCount;i++){let r=e.child(i),o=r.type==n?t.type.schema.nodes.text:r.type;if(a=a.matchType(o),!a||!t.type.allowsMarks(r.marks))return!1}return a.validEnd}function uM(t,e){return!!(t&&e&&!t.isLeaf&&Kie(t,e))}function qg(t,e,a=-1){let n=t.resolve(e);for(let i=n.depth;;i--){let r,o,l=n.index(i);if(i==n.depth?(r=n.nodeBefore,o=n.nodeAfter):a>0?(r=n.node(i+1),l++,o=n.node(i).maybeChild(l)):(r=n.node(i).maybeChild(l-1),o=n.node(i+1)),r&&!r.isTextblock&&uM(r,o)&&n.node(i).canReplace(l,l+1))return e;if(i==0)break;e=a<0?n.before(i):n.after(i)}}function Jie(t,e,a){let n=null,{linebreakReplacement:i}=t.doc.type.schema,r=t.doc.resolve(e-a),o=r.node().type;if(i&&o.inlineContent){let u=o.whitespace=="pre",p=!!o.contentMatch.matchType(i);u&&!p?n=!1:!u&&p&&(n=!0)}let l=t.steps.length;if(n===!1){let u=t.doc.resolve(e+a);dM(t,u.node(),u.before(),l)}o.inlineContent&&Qk(t,e+a-1,o,r.node().contentMatchAt(r.index()),n==null);let c=t.mapping.slice(l),d=c.map(e-a);if(t.step(new Tt(d,c.map(e+a,-1),K.empty,!0)),n===!0){let u=t.doc.resolve(d);cM(t,u.node(),u.before(),t.steps.length)}return t}function Qie(t,e,a){let n=t.resolve(e);if(n.parent.canReplaceWith(n.index(),n.index(),a))return e;if(n.parentOffset==0)for(let i=n.depth-1;i>=0;i--){let r=n.index(i);if(n.node(i).canReplaceWith(r,r,a))return n.before(i+1);if(r>0)return null}if(n.parentOffset==n.parent.content.size)for(let i=n.depth-1;i>=0;i--){let r=n.indexAfter(i);if(n.node(i).canReplaceWith(r,r,a))return n.after(i+1);if(r<n.node(i).childCount)return null}return null}function pM(t,e,a){let n=t.resolve(e);if(!a.content.size)return e;let i=a.content;for(let r=0;r<a.openStart;r++)i=i.firstChild.content;for(let r=1;r<=(a.openStart==0&&a.size?2:1);r++)for(let o=n.depth;o>=0;o--){let l=o==n.depth?0:n.pos<=(n.start(o+1)+n.end(o+1))/2?-1:1,c=n.index(o)+(l>0?1:0),d=n.node(o),u=!1;if(r==1)u=d.canReplace(c,c,i);else{let p=d.contentMatchAt(c).findWrapping(i.firstChild.type);u=p&&d.canReplaceWith(c,c,p[0])}if(u)return l==0?n.pos:l<0?n.before(o+1):n.after(o+1)}return null}function zg(t,e,a=e,n=K.empty){if(e==a&&!n.size)return null;let i=t.resolve(e),r=t.resolve(a);return mM(i,r,n)?new Tt(e,a,n):new Xie(i,r,n).fit()}function mM(t,e,a){return!a.openStart&&!a.openEnd&&t.start()==e.start()&&t.parent.canReplace(t.index(),e.index(),a.content)}class Xie{constructor(e,a,n){this.$from=e,this.$to=a,this.unplaced=n,this.frontier=[],this.placed=V.empty;for(let i=0;i<=e.depth;i++){let r=e.node(i);this.frontier.push({type:r.type,match:r.contentMatchAt(e.indexAfter(i))})}for(let i=e.depth;i>0;i--)this.placed=V.from(e.node(i).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let d=this.findFittable();d?this.placeNodes(d):this.openMore()||this.dropNode()}let e=this.mustMoveInline(),a=this.placed.size-this.depth-this.$from.depth,n=this.$from,i=this.close(e<0?this.$to:n.doc.resolve(e));if(!i)return null;let r=this.placed,o=n.depth,l=i.depth;for(;o&&l&&r.childCount==1;)r=r.firstChild.content,o--,l--;let c=new K(r,o,l);return e>-1?new Pt(n.pos,e,this.$to.pos,this.$to.end(),c,a):c.size||n.pos!=this.$to.pos?new Tt(n.pos,i.pos,c):null}findFittable(){let e=this.unplaced.openStart;for(let a=this.unplaced.content,n=0,i=this.unplaced.openEnd;n<e;n++){let r=a.firstChild;if(a.childCount>1&&(i=0),r.type.spec.isolating&&i<=n){e=n;break}a=r.content}for(let a=1;a<=2;a++)for(let n=a==1?e:this.unplaced.openStart;n>=0;n--){let i,r=null;n?(r=W0(this.unplaced.content,n-1).firstChild,i=r.content):i=this.unplaced.content;let o=i.firstChild;for(let l=this.depth;l>=0;l--){let{type:c,match:d}=this.frontier[l],u,p=null;if(a==1&&(o?d.matchType(o.type)||(p=d.fillBefore(V.from(o),!1)):r&&c.compatibleContent(r.type)))return{sliceDepth:n,frontierDepth:l,parent:r,inject:p};if(a==2&&o&&(u=d.findWrapping(o.type)))return{sliceDepth:n,frontierDepth:l,parent:r,wrap:u};if(r&&d.matchType(r.type))break}}}openMore(){let{content:e,openStart:a,openEnd:n}=this.unplaced,i=W0(e,a);return!i.childCount||i.firstChild.isLeaf?!1:(this.unplaced=new K(e,a+1,Math.max(n,i.size+a>=e.size-n?a+1:0)),!0)}dropNode(){let{content:e,openStart:a,openEnd:n}=this.unplaced,i=W0(e,a);if(i.childCount<=1&&a>0){let r=e.size-a<=a+i.size;this.unplaced=new K(Uc(e,a-1,1),a-1,r?a-1:n)}else this.unplaced=new K(Uc(e,a,1),a,n)}placeNodes({sliceDepth:e,frontierDepth:a,parent:n,inject:i,wrap:r}){for(;this.depth>a;)this.closeFrontierNode();if(r)for(let y=0;y<r.length;y++)this.openFrontierNode(r[y]);let o=this.unplaced,l=n?n.content:o.content,c=o.openStart-e,d=0,u=[],{match:p,type:m}=this.frontier[a];if(i){for(let y=0;y<i.childCount;y++)u.push(i.child(y));p=p.matchFragment(i)}let h=l.size+e-(o.content.size-o.openEnd);for(;d<l.childCount;){let y=l.child(d),x=p.matchType(y.type);if(!x)break;d++,(d>1||c==0||y.content.size)&&(p=x,u.push(hM(y.mark(m.allowedMarks(y.marks)),d==1?c:0,d==l.childCount?h:-1)))}let g=d==l.childCount;g||(h=-1),this.placed=$c(this.placed,a,V.from(u)),this.frontier[a].match=p,g&&h<0&&n&&n.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let y=0,x=l;y<h;y++){let v=x.lastChild;this.frontier.push({type:v.type,match:v.contentMatchAt(v.childCount)}),x=v.content}this.unplaced=g?e==0?K.empty:new K(Uc(o.content,e-1,1),e-1,h<0?o.openEnd:e-1):new K(Uc(o.content,e,d),o.openStart,o.openEnd)}mustMoveInline(){if(!this.$to.parent.isTextblock)return-1;let e=this.frontier[this.depth],a;if(!e.type.isTextblock||!G0(this.$to,this.$to.depth,e.type,e.match,!1)||this.$to.depth==this.depth&&(a=this.findCloseLevel(this.$to))&&a.depth==this.depth)return-1;let{depth:n}=this.$to,i=this.$to.after(n);for(;n>1&&i==this.$to.end(--n);)++i;return i}findCloseLevel(e){e:for(let a=Math.min(this.depth,e.depth);a>=0;a--){let{match:n,type:i}=this.frontier[a],r=a<e.depth&&e.end(a+1)==e.pos+(e.depth-(a+1)),o=G0(e,a,i,n,r);if(o){for(let l=a-1;l>=0;l--){let{match:c,type:d}=this.frontier[l],u=G0(e,l,d,c,!0);if(!u||u.childCount)continue e}return{depth:a,fit:o,move:r?e.doc.resolve(e.after(a+1)):e}}}}close(e){let a=this.findCloseLevel(e);if(!a)return null;for(;this.depth>a.depth;)this.closeFrontierNode();a.fit.childCount&&(this.placed=$c(this.placed,a.depth,a.fit)),e=a.move;for(let n=a.depth+1;n<=e.depth;n++){let i=e.node(n),r=i.type.contentMatch.fillBefore(i.content,!0,e.index(n));this.openFrontierNode(i.type,i.attrs,r)}return e}openFrontierNode(e,a=null,n){let i=this.frontier[this.depth];i.match=i.match.matchType(e),this.placed=$c(this.placed,this.depth,V.from(e.create(a,n))),this.frontier.push({type:e,match:e.contentMatch})}closeFrontierNode(){let a=this.frontier.pop().match.fillBefore(V.empty,!0);a.childCount&&(this.placed=$c(this.placed,this.frontier.length,a))}}function Uc(t,e,a){return e==0?t.cutByIndex(a,t.childCount):t.replaceChild(0,t.firstChild.copy(Uc(t.firstChild.content,e-1,a)))}function $c(t,e,a){return e==0?t.append(a):t.replaceChild(t.childCount-1,t.lastChild.copy($c(t.lastChild.content,e-1,a)))}function W0(t,e){for(let a=0;a<e;a++)t=t.firstChild.content;return t}function hM(t,e,a){if(e<=0)return t;let n=t.content;return e>1&&(n=n.replaceChild(0,hM(n.firstChild,e-1,n.childCount==1?a-1:0))),e>0&&(n=t.type.contentMatch.fillBefore(n).append(n),a<=0&&(n=n.append(t.type.contentMatch.matchFragment(n).fillBefore(V.empty,!0)))),t.copy(n)}function G0(t,e,a,n,i){let r=t.node(e),o=i?t.indexAfter(e):t.index(e);if(o==r.childCount&&!a.compatibleContent(r.type))return null;let l=n.fillBefore(r.content,!0,o);return l&&!Yie(a,r.content,o)?l:null}function Yie(t,e,a){for(let n=a;n<e.childCount;n++)if(!t.allowsMarks(e.child(n).marks))return!0;return!1}function Zie(t){return t.spec.defining||t.spec.definingForContent}function ere(t,e,a,n){if(!n.size)return t.deleteRange(e,a);let i=t.doc.resolve(e),r=t.doc.resolve(a);if(mM(i,r,n))return t.step(new Tt(e,a,n));let o=gM(i,r);o[o.length-1]==0&&o.pop();let l=-(i.depth+1);o.unshift(l);for(let m=i.depth,h=i.pos-1;m>0;m--,h--){let g=i.node(m).type.spec;if(g.defining||g.definingAsContext||g.isolating)break;o.indexOf(m)>-1?l=m:i.before(m)==h&&o.splice(1,0,-m)}let c=o.indexOf(l),d=[],u=n.openStart;for(let m=n.content,h=0;;h++){let g=m.firstChild;if(d.push(g),h==n.openStart)break;m=g.content}for(let m=u-1;m>=0;m--){let h=d[m],g=Zie(h.type);if(g&&!h.sameMarkup(i.node(Math.abs(l)-1)))u=m;else if(g||!h.type.isTextblock)break}for(let m=n.openStart;m>=0;m--){let h=(m+u+1)%(n.openStart+1),g=d[h];if(g)for(let y=0;y<o.length;y++){let x=o[(y+c)%o.length],v=!0;x<0&&(v=!1,x=-x);let w=i.node(x-1),S=i.index(x-1);if(w.canReplaceWith(S,S,g.type,g.marks))return t.replace(i.before(x),v?r.after(x):a,new K(fM(n.content,0,n.openStart,h),h,n.openEnd))}}let p=t.steps.length;for(let m=o.length-1;m>=0&&(t.replace(e,a,n),!(t.steps.length>p));m--){let h=o[m];h<0||(e=i.before(h),a=r.after(h))}}function fM(t,e,a,n,i){if(e<a){let r=t.firstChild;t=t.replaceChild(0,r.copy(fM(r.content,e+1,a,n,r)))}if(e>n){let r=i.contentMatchAt(0),o=r.fillBefore(t).append(t);t=o.append(r.matchFragment(o).fillBefore(V.empty,!0))}return t}function tre(t,e,a,n){if(!n.isInline&&e==a&&t.doc.resolve(e).parent.content.size){let i=Qie(t.doc,e,n.type);i!=null&&(e=a=i)}t.replaceRange(e,a,new K(V.from(n),0,0))}function are(t,e,a){let n=t.doc.resolve(e),i=t.doc.resolve(a),r=gM(n,i);for(let o=0;o<r.length;o++){let l=r[o],c=o==r.length-1;if(c&&l==0||n.node(l).type.contentMatch.validEnd)return t.delete(n.start(l),i.end(l));if(l>0&&(c||n.node(l-1).canReplace(n.index(l-1),i.indexAfter(l-1))))return t.delete(n.before(l),i.after(l))}for(let o=1;o<=n.depth&&o<=i.depth;o++)if(e-n.start(o)==n.depth-o&&a>n.end(o)&&i.end(o)-a!=i.depth-o&&n.start(o-1)==i.start(o-1)&&n.node(o-1).canReplace(n.index(o-1),i.index(o-1)))return t.delete(n.before(o),a);t.delete(e,a)}function gM(t,e){let a=[],n=Math.min(t.depth,e.depth);for(let i=n;i>=0;i--){let r=t.start(i);if(r<t.pos-(t.depth-i)||e.end(i)>e.pos+(e.depth-i)||t.node(i).type.spec.isolating||e.node(i).type.spec.isolating)break;(r==e.start(i)||i==t.depth&&i==e.depth&&t.parent.inlineContent&&e.parent.inlineContent&&i&&e.start(i-1)==r-1)&&a.push(i)}return a}class dl extends sa{constructor(e,a,n){super(),this.pos=e,this.attr=a,this.value=n}apply(e){let a=e.nodeAt(this.pos);if(!a)return yt.fail("No node at attribute step's position");let n=Object.create(null);for(let r in a.attrs)n[r]=a.attrs[r];n[this.attr]=this.value;let i=a.type.create(n,null,a.marks);
vendor: 5,172 bytes, line 17634
17634return yt.fromReplace(e,this.pos,this.pos+1,new K(V.from(i),0,a.isLeaf?0:1))}getMap(){return qa.empty}invert(e){return new dl(this.pos,this.attr,e.nodeAt(this.pos).attrs[this.attr])}map(e){let a=e.mapResult(this.pos,1);return a.deletedAfter?null:new dl(a.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(e,a){if(typeof a.pos!="number"||typeof a.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new dl(a.pos,a.attr,a.value)}}sa.jsonID("attr",dl);class mu extends sa{constructor(e,a){super(),this.attr=e,this.value=a}apply(e){let a=Object.create(null);for(let i in e.attrs)a[i]=e.attrs[i];a[this.attr]=this.value;let n=e.type.create(a,e.content,e.marks);return yt.ok(n)}getMap(){return qa.empty}invert(e){return new mu(this.attr,e.attrs[this.attr])}map(e){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(e,a){if(typeof a.attr!="string")throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new mu(a.attr,a.value)}}sa.jsonID("docAttr",mu);let Il=class extends Error{};Il=function t(e){let a=Error.call(this,e);return a.__proto__=t.prototype,a};Il.prototype=Object.create(Error.prototype);Il.prototype.constructor=Il;Il.prototype.name="TransformError";class yM{constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapping=new pu}get before(){return this.docs.length?this.docs[0]:this.doc}step(e){let a=this.maybeStep(e);if(a.failed)throw new Il(a.failed);return this}maybeStep(e){let a=e.apply(this.doc);return a.failed||this.addStep(e,a.doc),a}get docChanged(){return this.steps.length>0}addStep(e,a){this.docs.push(this.doc),this.steps.push(e),this.mapping.appendMap(e.getMap()),this.doc=a}replace(e,a=e,n=K.empty){let i=zg(this.doc,e,a,n);return i&&this.step(i),this}replaceWith(e,a,n){return this.replace(e,a,new K(V.from(n),0,0))}delete(e,a){return this.replace(e,a,K.empty)}insert(e,a){return this.replaceWith(e,e,a)}replaceRange(e,a,n){return ere(this,e,a,n),this}replaceRangeWith(e,a,n){return tre(this,e,a,n),this}deleteRange(e,a){return are(this,e,a),this}lift(e,a){return Vie(this,e,a),this}join(e,a=1){return Jie(this,e,a),this}wrap(e,a){return Bie(this,e,a),this}setBlockType(e,a=e,n,i=null){return Uie(this,e,a,n,i),this}setNodeMarkup(e,a,n=null,i){return Wie(this,e,a,n,i),this}setNodeAttribute(e,a,n){return this.step(new dl(e,a,n)),this}setDocAttribute(e,a){return this.step(new mu(e,a)),this}addNodeMark(e,a){return this.step(new vr(e,a)),this}removeNodeMark(e,a){let n=this.doc.nodeAt(e);if(!n)throw new RangeError("No node at position "+e);if(a instanceof qe)a.isInSet(n.marks)&&this.step(new ns(e,a));else{let i=n.marks,r,o=[];for(;r=a.isInSet(i);)o.push(new ns(e,r)),i=r.removeFromSet(i);for(let l=o.length-1;l>=0;l--)this.step(o[l])}return this}split(e,a=1,n){return Gie(this,e,a,n),this}addMark(e,a,n){return Die(this,e,a,n),this}removeMark(e,a,n){return qie(this,e,a,n),this}clearIncompatible(e,a,n){return Qk(this,e,a,n),this}}const K0=Object.create(null);class xe{constructor(e,a,n){this.$anchor=e,this.$head=a,this.ranges=n||[new nre(e.min(a),e.max(a))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let e=this.ranges;for(let a=0;a<e.length;a++)if(e[a].$from.pos!=e[a].$to.pos)return!1;return!0}content(){return this.$from.doc.slice(this.from,this.to,!0)}replace(e,a=K.empty){let n=a.content.lastChild,i=null;for(let l=0;l<a.openEnd;l++)i=n,n=n.lastChild;let r=e.steps.length,o=this.ranges;for(let l=0;l<o.length;l++){let{$from:c,$to:d}=o[l],u=e.mapping.slice(r);e.replaceRange(u.map(c.pos),u.map(d.pos),l?K.empty:a),l==0&&Mj(e,r,(n?n.isInline:i&&i.isTextblock)?-1:1)}}replaceWith(e,a){let n=e.steps.length,i=this.ranges;for(let r=0;r<i.length;r++){let{$from:o,$to:l}=i[r],c=e.mapping.slice(n),d=c.map(o.pos),u=c.map(l.pos);r?e.deleteRange(d,u):(e.replaceRangeWith(d,u,a),Mj(e,n,a.isInline?-1:1))}}static findFrom(e,a,n=!1){let i=e.parent.inlineContent?new ce(e):Ns(e.node(0),e.parent,e.pos,e.index(),a,n);if(i)return i;for(let r=e.depth-1;r>=0;r--){let o=a<0?Ns(e.node(0),e.node(r),e.before(r+1),e.index(r),a,n):Ns(e.node(0),e.node(r),e.after(r+1),e.index(r)+1,a,n);if(o)return o}return null}static near(e,a=1){return this.findFrom(e,a)||this.findFrom(e,-a)||new Ua(e.node(0))}static atStart(e){return Ns(e,e,0,0,1)||new Ua(e)}static atEnd(e){return Ns(e,e,e.content.size,e.childCount,-1)||new Ua(e)}static fromJSON(e,a){if(!a||!a.type)throw new RangeError("Invalid input for Selection.fromJSON");let n=K0[a.type];if(!n)throw new RangeError(`No selection type ${a.type} defined`);return n.fromJSON(e,a)}static jsonID(e,a){if(e in K0)throw new RangeError("Duplicate use of selection JSON ID "+e);return K0[e]=a,a.prototype.jsonID=e,a}getBookmark(){return ce.between(this.$anchor,this.$head).getBookmark()}}xe.prototype.visible=!0;class nre{constructor(e,a){this.$from=e,this.$to=a}}let Lj=!1;function Oj(t){!Lj&&!t.parent.inlineContent&&(Lj=!0,console.warn("TextSelection endpoint not pointing into a
17634node with inline content ("+t.parent.type.name+")"))}class ce extends xe{constructor(e,a=e){Oj(e),Oj(a),super(e,a)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(e,a){let n=e.resolve(a.map(this.head));if(!n.parent.inlineContent)return xe.near(n);let i=e.resolve(a.map(this.anchor));return new ce(i.parent.inlineContent?i:n,n)}replace(e,a=K.empty){if(super.replace(e,a),a==K.empty){let n=this.$from.marksAcross(this.$to);n&&e.ensureMarks(n)}}eq(e){return e instanceof ce&&e.anchor==this.anchor&&e.head==this.head}getBookmark(){return new Vg(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(e,a){if(typeof a.anchor!="number"||typeof a.head!="number")throw new RangeError("Invalid input for TextSelection.fromJSON");return new ce(e.resolve(a.anchor),e.resolve(a.head))}static create(e,a,n=a){let i=e.resolve(a);return new this(i,n==a?i:e.resolve(n))}static between(e,a,n){let i=e.pos-a.pos;if((!n||i)&&(n=i>=0?1:-1),!a.parent.inlineContent){let r=xe.findFrom(a,n,!0)||xe.findFrom(a,-n,!0);if(r)a=r.$head;else return xe.near(a,n)}return e.parent.inlineContent||(i==0?e=a:(e=(xe.findFrom(e,-n,!0)||xe.findFrom(e,n,!0)).$anchor,e.pos<a.pos!=i<0&&(e=a))),new ce(e,a)}}xe.jsonID("text",ce);class Vg{constructor(e,a){this.anchor=e,this.head=a}map(e){return new Vg(e.map(this.anchor),e.map(this.head))}resolve(e){return ce.between(e.resolve(this.anchor),e.resolve(this.head))}}class se extends xe{constructor(e){let a=e.nodeAfter,n=e.node(0).resolve(e.pos+a.nodeSize);super(e,n),this.node=a}map(e,a){let{deleted:n,pos:i}=a.mapResult(this.anchor),r=e.resolve(i);return n?xe.near(r):new se(r)}content(){return new K(V.from(this.node),0,0)}eq(e){return e instanceof se&&e.anchor==this.anchor}toJSON(){return{type:"node",anchor:this.anchor}}getBookmark(){return new Yk(this.anchor)}static fromJSON(e,a){if(typeof a.anchor!="number")throw new RangeError("Invalid input for NodeSelection.fromJSON");return new se(e.resolve(a.anchor))}static create(e,a){return new se(e.resolve(a))}static isSelectable(e){return!e.isText&&e.type.spec.selectable!==!1}}se.prototype.visible=!1;xe.jsonID("node",se);class Yk{constructor(e){this.anchor=e}map(e){let{deleted:a,pos:n}=e.mapResult(this.anchor);return a?new Vg(n,n):new Yk(n)}resolve(e){let a=e.resolve(this.anchor),n=a.nodeAfter;return n&&se.isSelectable(n)?new se(a):xe.near(a)}}class Ua extends xe{constructor(e){super(e.resolve(0),e.resolve(e.content.size))}replace(e,a=K.empty){if(a==K.empty){e.delete(0,e.doc.content.size);let n=xe.atStart(e.doc);n.eq(e.selection)||e.setSelection(n)}else super.replace(e,a)}toJSON(){return{type:"all"}}static fromJSON(e){return new Ua(e)}map(e){return new Ua(e)}eq(e){return e instanceof Ua}getBookmark(){return ire}}xe.jsonID("all",Ua);const ire={map(){return this},resolve(t){return new Ua(t)}};function Ns(t,e,a,n,i,r=!1){if(e.inlineContent)return ce.create(t,a);for(let o=n-(i>0?0:1);i>0?o<e.childCount:o>=0;o+=i){let l=e.child(o);if(l.isAtom){if(!r&&se.isSelectable(l))return se.create(t,a-(i<0?l.nodeSize:0))}else{let c=Ns(t,l,a+i,i<0?l.childCount:0,i,r);if(c)return c}a+=l.nodeSize*i}return null}function Mj(t,e,a){let n=t.steps.length-1;if(n<e)return;let i=t.steps[n];if(!(i instanceof Tt||i instanceof Pt))return;let r=t.mapping.maps[n],o;r.forEach((l,c,d,u)=>{o==null&&(o=u)}),t.setSelection(xe.near(t.doc.resolve(o),a))}const Dj=1,Zp=2,qj=4;class rre extends yM{constructor(e){super(e.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=e.selection,this.storedMarks=e.storedMarks}get selection(){return this.curSelectionFor<this.steps.length&&(this.curSelection=this.curSelection.map(this.doc,this.mapping.slice(this.curSelectionFor)),this.curSelectionFor=this.steps.length),this.curSelection}setSelection(e){if(e.$from.doc!=this.doc)throw new RangeError("Selection passed to setSelection must point at the current document");return this.curSelection=e,this.curSelectionFor=this.steps.length,this.updated=(this.updated|Dj)&~Zp,this.storedMarks=null,this}get selectionSet(){return(this.updated&Dj)>0}setStoredMarks(e){return this.storedMarks=e,this.updated|=Zp,this}ensureMarks(e){return qe.sameSet(this.storedMarks||this.selection.$from.marks(),e)||this.setStoredMarks(e),this}addStoredMark(e){return this.ensureMarks(e.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(e){return this.ensureMarks(e.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(this.updated&Zp)>0}addStep(e,a){super.addStep(e,a),this.updated=this.updated&~Zp,this.storedMarks=null}setTime(e){return this.time=e,this}replaceSelection(e){return this.selection.replace(this,e),this}replaceSelectionWith(e,a=!0){let n=this.selection;return a&&(e=e.mark(this.storedMarks||(n.empty?n.$from.marks():n.$from.marksAcross(n.$to)||qe.none))),n.replaceWith(this,e),this}deleteSelection(){return this.selection.replace(this),this}insertText(e,a,n){let i=this.doc.type.schema;if(a==null)return e?this.replaceSelectionWith(i.text(e),!0):this.deleteSelection();{if(n==null&&(n=a),!e)return this.deleteRange(a,n);let r=this.storedMarks;if(!r){let o=this.doc.resolve(a);r=n==a?o.marks():o.marksAcross(this.doc.resolve(n))}return this.replaceRangeWith(a,n,i.text(e,r)),!this.selection.empty&&this.selection.to==a+e.length&&this.setSelection(xe.near(this.selection.$to)),this}}setMeta(e,a){return this.meta[typeof e=="string"?e:e.key]=a,this}getMeta(e){return this.meta[typeof e=="string"?e:e.key]}get isGeneric(){for(let e in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=qj,this}get scrolledIntoView(){return(this.updated&qj)>0}}function zj(t,e){return!e||!t?t:t.bind(e)}class Wc{constructor(e,a,n){this.name=e,this.init=zj(a.init,n),this.apply=zj(a.apply,n)}}const ore=[new Wc("doc",{init(t){return t.doc||t.schema.topNodeType.createAndFill()},apply(t){return t.doc}}),new Wc("selection",{init(t,e){return t.selection||xe.atStart(e.doc)},apply(t){return t.selection}}),new Wc("storedMarks",{init(t){return t.storedMarks||null},apply(t,e,a,n){return n.selection.$cursor?t.storedMarks:null}}),new Wc("scrollToSelection",{init(){return 0},apply(t,e){return t.scrolledIntoView?e+1:e}})];class J0{constructor(e,a){this.schema=e,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=ore.slice(),a&&a.forEach(n=>{if(this.pluginsByKey[n.key])throw new RangeError("Adding different instances of a keyed plugin ("+n.key+")");this.plugins.push(n),this.pluginsByKey[n.key]=n,n.spec.state&&this.fields.push(new Wc(n.key,n.spec.state,n))})}}class Qs{constructor(e){this.config=e}get schema(){return this.config.schema}get plugins(){return this.config.plugins}
vendor: 4,627 bytes, line 17634
17634apply(e){return this.applyTransaction(e).state}filterTransaction(e,a=-1){for(let n=0;n<this.config.plugins.length;n++)if(n!=a){let i=this.config.plugins[n];if(i.spec.filterTransaction&&!i.spec.filterTransaction.call(i,e,this))return!1}return!0}applyTransaction(e){if(!this.filterTransaction(e))return{state:this,transactions:[]};let a=[e],n=this.applyInner(e),i=null;for(;;){let r=!1;for(let o=0;o<this.config.plugins.length;o++){let l=this.config.plugins[o];if(l.spec.appendTransaction){let c=i?i[o].n:0,d=i?i[o].state:this,u=c<a.length&&l.spec.appendTransaction.call(l,c?a.slice(c):a,d,n);if(u&&n.filterTransaction(u,o)){if(u.setMeta("appendedTransaction",e),!i){i=[];for(let p=0;p<this.config.plugins.length;p++)i.push(p<o?{state:n,n:a.length}:{state:this,n:0})}a.push(u),n=n.applyInner(u),r=!0}i&&(i[o]={state:n,n:a.length})}}if(!r)return{state:n,transactions:a}}}applyInner(e){if(!e.before.eq(this.doc))throw new RangeError("Applying a mismatched transaction");let a=new Qs(this.config),n=this.config.fields;for(let i=0;i<n.length;i++){let r=n[i];a[r.name]=r.apply(e,this[r.name],this,a)}return a}get tr(){return new rre(this)}static create(e){let a=new J0(e.doc?e.doc.type.schema:e.schema,e.plugins),n=new Qs(a);for(let i=0;i<a.fields.length;i++)n[a.fields[i].name]=a.fields[i].init(e,n);return n}reconfigure(e){let a=new J0(this.schema,e.plugins),n=a.fields,i=new Qs(a);for(let r=0;r<n.length;r++){let o=n[r].name;i[o]=this.hasOwnProperty(o)?this[o]:n[r].init(e,i)}return i}toJSON(e){let a={doc:this.doc.toJSON(),selection:this.selection.toJSON()};if(this.storedMarks&&(a.storedMarks=this.storedMarks.map(n=>n.toJSON())),e&&typeof e=="object")for(let n in e){if(n=="doc"||n=="selection")throw new RangeError("The JSON fields `doc` and `selection` are reserved");let i=e[n],r=i.spec.state;r&&r.toJSON&&(a[n]=r.toJSON.call(i,this[i.key]))}return a}static fromJSON(e,a,n){if(!a)throw new RangeError("Invalid input for EditorState.fromJSON");if(!e.schema)throw new RangeError("Required config field 'schema' missing");let i=new J0(e.schema,e.plugins),r=new Qs(i);return i.fields.forEach(o=>{if(o.name=="doc")r.doc=Rn.fromJSON(e.schema,a.doc);else if(o.name=="selection")r.selection=xe.fromJSON(r.doc,a.selection);else if(o.name=="storedMarks")a.storedMarks&&(r.storedMarks=a.storedMarks.map(e.schema.markFromJSON));else{if(n)for(let l in n){let c=n[l],d=c.spec.state;if(c.key==o.name&&d&&d.fromJSON&&Object.prototype.hasOwnProperty.call(a,l)){r[o.name]=d.fromJSON.call(c,e,a[l],r);return}}r[o.name]=o.init(e,r)}}),r}}function xM(t,e,a){for(let n in t){let i=t[n];i instanceof Function?i=i.bind(e):n=="handleDOMEvents"&&(i=xM(i,e,{})),a[n]=i}return a}class at{constructor(e){this.spec=e,this.props={},e.props&&xM(e.props,this,this.props),this.key=e.key?e.key.key:vM("plugin")}getState(e){return e[this.key]}}const Q0=Object.create(null);function vM(t){return t in Q0?t+"$"+ ++Q0[t]:(Q0[t]=0,t+"$")}class _t{constructor(e="key"){this.key=vM(e)}get(e){return e.config.pluginsByKey[this.key]}getState(e){return e[this.key]}}const Zk=(t,e)=>t.selection.empty?!1:(e&&e(t.tr.deleteSelection().scrollIntoView()),!0);function bM(t,e){let{$cursor:a}=t.selection;return!a||(e?!e.endOfTextblock("backward",t):a.parentOffset>0)?null:a}const wM=(t,e,a)=>{let n=bM(t,a);if(!n)return!1;let i=eS(n);if(!i){let o=n.blockRange(),l=o&&ec(o);return l==null?!1:(e&&e(t.tr.lift(o,l).scrollIntoView()),!0)}let r=i.nodeBefore;if(NM(t,i,e,-1))return!0;if(n.parent.content.size==0&&(Pl(r,"end")||se.isSelectable(r)))for(let o=n.depth;;o--){let l=zg(t.doc,n.before(o),n.after(o),K.empty);if(l&&l.slice.size<l.to-l.from){if(e){let c=t.tr.step(l);c.setSelection(Pl(r,"end")?xe.findFrom(c.doc.resolve(c.mapping.map(i.pos,-1)),-1):se.create(c.doc,i.pos-r.nodeSize)),e(c.scrollIntoView())}return!0}if(o==1||n.node(o-1).childCount>1)break}return r.isAtom&&i.depth==n.depth-1?(e&&e(t.tr.delete(i.pos-r.nodeSize,i.pos).scrollIntoView()),!0):!1},sre=(t,e,a)=>{let n=bM(t,a);if(!n)return!1;let i=eS(n);return i?kM(t,i,e):!1},lre=(t,e,a)=>{let n=_M(t,a);if(!n)return!1;let i=tS(n);return i?kM(t,i,e):!1};function kM(t,e,a){let n=e.nodeBefore,i=n,r=e.pos-1;for(;!i.isTextblock;r--){if(i.type.spec.isolating)return!1;let u=i.lastChild;if(!u)return!1;i=u}let o=e.nodeAfter,l=o,c=e.pos+1;for(;!l.isTextblock;c++){if(l.type.spec.isolating)return!1;let u=l.firstChild;if(!u)return!1;l=u}let d=zg(t.doc,r,c,K.empty);if(!d||d.from!=r||d instanceof Tt&&d.slice.size>=c-r)return!1;if(a){let u=t.tr.step(d);u.setSelection(ce.create(u.doc,r)),a(u.scrollIntoView())}return!0}function Pl(t,e,a=!1){for(let n=t;n;n=e=="start"?n.firstChild:n.lastChild){if(n.isTextblock)return!0;
vendor: 6,074 bytes, lines 17634-17635
17634if(a&&n.childCount!=1)return!1}return!1}const SM=(t,e,a)=>{let{$head:n,empty:i}=t.selection,r=n;if(!i)return!1;if(n.parent.isTextblock){if(a?!a.endOfTextblock("backward",t):n.parentOffset>0)return!1;r=eS(n)}let o=r&&r.nodeBefore;return!o||!se.isSelectable(o)?!1:(e&&e(t.tr.setSelection(se.create(t.doc,r.pos-o.nodeSize)).scrollIntoView()),!0)};function eS(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){if(t.index(e)>0)return t.doc.resolve(t.before(e+1));if(t.node(e).type.spec.isolating)break}return null}function _M(t,e){let{$cursor:a}=t.selection;return!a||(e?!e.endOfTextblock("forward",t):a.parentOffset<a.parent.content.size)?null:a}const AM=(t,e,a)=>{let n=_M(t,a);if(!n)return!1;let i=tS(n);if(!i)return!1;let r=i.nodeAfter;if(NM(t,i,e,1))return!0;if(n.parent.content.size==0&&(Pl(r,"start")||se.isSelectable(r))){let o=zg(t.doc,n.before(),n.after(),K.empty);if(o&&o.slice.size<o.to-o.from){if(e){let l=t.tr.step(o);l.setSelection(Pl(r,"start")?xe.findFrom(l.doc.resolve(l.mapping.map(i.pos)),1):se.create(l.doc,l.mapping.map(i.pos))),e(l.scrollIntoView())}return!0}}return r.isAtom&&i.depth==n.depth-1?(e&&e(t.tr.delete(i.pos,i.pos+r.nodeSize).scrollIntoView()),!0):!1},EM=(t,e,a)=>{let{$head:n,empty:i}=t.selection,r=n;if(!i)return!1;if(n.parent.isTextblock){if(a?!a.endOfTextblock("forward",t):n.parentOffset<n.parent.content.size)return!1;r=tS(n)}let o=r&&r.nodeAfter;return!o||!se.isSelectable(o)?!1:(e&&e(t.tr.setSelection(se.create(t.doc,r.pos)).scrollIntoView()),!0)};function tS(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){let a=t.node(e);if(t.index(e)+1<a.childCount)return t.doc.resolve(t.after(e+1));if(a.type.spec.isolating)break}return null}const cre=(t,e)=>{let a=t.selection,n=a instanceof se,i;if(n){if(a.node.isTextblock||!eo(t.doc,a.from))return!1;i=a.from}else if(i=qg(t.doc,a.from,-1),i==null)return!1;if(e){let r=t.tr.join(i);n&&r.setSelection(se.create(r.doc,i-t.doc.resolve(i).nodeBefore.nodeSize)),e(r.scrollIntoView())}return!0},dre=(t,e)=>{let a=t.selection,n;if(a instanceof se){if(a.node.isTextblock||!eo(t.doc,a.to))return!1;n=a.to}else if(n=qg(t.doc,a.to,1),n==null)return!1;return e&&e(t.tr.join(n).scrollIntoView()),!0},ure=(t,e)=>{let{$from:a,$to:n}=t.selection,i=a.blockRange(n),r=i&&ec(i);return r==null?!1:(e&&e(t.tr.lift(i,r).scrollIntoView()),!0)},CM=(t,e)=>{let{$head:a,$anchor:n}=t.selection;return!a.parent.type.spec.code||!a.sameParent(n)?!1:(e&&e(t.tr.insertText(` 17635`).scrollIntoView()),!0)};function aS(t){for(let e=0;e<t.edgeCount;e++){let{type:a}=t.edge(e);if(a.isTextblock&&!a.hasRequiredAttrs())return a}return null}const pre=(t,e)=>{let{$head:a,$anchor:n}=t.selection;if(!a.parent.type.spec.code||!a.sameParent(n))return!1;let i=a.node(-1),r=a.indexAfter(-1),o=aS(i.contentMatchAt(r));if(!o||!i.canReplaceWith(r,r,o))return!1;if(e){let l=a.after(),c=t.tr.replaceWith(l,l,o.createAndFill());c.setSelection(xe.near(c.doc.resolve(l),1)),e(c.scrollIntoView())}return!0},jM=(t,e)=>{let a=t.selection,{$from:n,$to:i}=a;if(a instanceof Ua||n.parent.inlineContent||i.parent.inlineContent)return!1;let r=aS(i.parent.contentMatchAt(i.indexAfter()));if(!r||!r.isTextblock)return!1;if(e){let o=(!n.parentOffset&&i.index()<i.parent.childCount?n:i).pos,l=t.tr.insert(o,r.createAndFill());l.setSelection(ce.create(l.doc,o+1)),e(l.scrollIntoView())}return!0},TM=(t,e)=>{let{$cursor:a}=t.selection;if(!a||a.parent.content.size)return!1;if(a.depth>1&&a.after()!=a.end(-1)){let r=a.before();if(Ii(t.doc,r))return e&&e(t.tr.split(r).scrollIntoView()),!0}let n=a.blockRange(),i=n&&ec(n);return i==null?!1:(e&&e(t.tr.lift(n,i).scrollIntoView()),!0)};function mre(t){return(e,a)=>{let{$from:n,$to:i}=e.selection;if(e.selection instanceof se&&e.selection.node.isBlock)return!n.parentOffset||!Ii(e.doc,n.pos)?!1:(a&&a(e.tr.split(n.pos).scrollIntoView()),!0);if(!n.depth)return!1;let r=[],o,l,c=!1,d=!1;for(let h=n.depth;;h--)if(n.node(h).isBlock){c=n.end(h)==n.pos+(n.depth-h),d=n.start(h)==n.pos-(n.depth-h),l=aS(n.node(h-1).contentMatchAt(n.indexAfter(h-1))),r.unshift(c&&l?{type:l}:null),o=h;break}else{if(h==1)return!1;r.unshift(null)}let u=e.tr;(e.selection instanceof ce||e.selection instanceof Ua)&&u.deleteSelection();let p=u.mapping.map(n.pos),m=Ii(u.doc,p,r.length,r);if(m||(r[0]=l?{type:l}:null,m=Ii(u.doc,p,r.length,r)),!m)return!1;if(u.split(p,r.length,r),!c&&d&&n.node(o).type!=l){let h=u.mapping.map(n.before(o)),g=u.doc.resolve(h);l&&n.node(o-1).canReplaceWith(g.index(),g.index()+1,l)&&u.setNodeMarkup(u.mapping.map(n.before(o)),l)}return a&&a(u.scrollIntoView()),!0}}const hre=mre(),fre=(t,e)=>{let{$from:a,to:n}=t.selection,i,r=a.sharedDepth(n);return r==0?!1:(i=a.before(r),e&&e(t.tr.setSelection(se.create(t.doc,i))),!0)};function gre(t,e,a){let n=e.nodeBefore,i=e.nodeAfter,r=e.index();return!n||!i||!n.type.compatibleContent(i.type)?!1:!n.content.size&&e.parent.canReplace(r-1,r)?(a&&a(t.tr.delete(e.pos-n.nodeSize,e.pos).scrollIntoView()),!0):!e.parent.canReplace(r,r+1)||!(i.isTextblock||eo(t.doc,e.pos))?!1:(a&&a(t.tr.join(e.pos).scrollIntoView()),!0)}function NM(t,e,a,n){let i=e.nodeBefore,r=e.nodeAfter,o,l,c=i.type.spec.isolating||r.type.spec.isolating;if(!c&&gre(t,e,a))return!0;let d=!c&&e.parent.canReplace(e.index(),e.index()+1);if(d&&(o=(l=i.contentMatchAt(i.childCount)).findWrapping(r.type))&&l.matchType(o[0]||r.type).validEnd){if(a){let h=e.pos+r.nodeSize,g=V.empty;for(let v=o.length-1;v>=0;v--)g=V.from(o[v].create(null,g));g=V.from(i.copy(g));let y=t.tr.step(new Pt(e.pos-1,h,e.pos,h,new K(g,1,0),o.length,!0)),x=y.doc.resolve(h+2*o.length);x.nodeAfter&&x.nodeAfter.type==i.type&&eo(y.doc,x.pos)&&y.join(x.pos),a(y.scrollIntoView())}return!0}let u=r.type.spec.isolating||n>0&&c?null:xe.findFrom(e,1),p=u&&u.$from.blockRange(u.$to),m=p&&ec(p);if(m!=null&&m>=e.depth)return a&&a(t.tr.lift(p,m).scrollIntoView()),!0;if(d&&Pl(r,"start",!0)&&Pl(i,"end")){let h=i,g=[];for(;g.push(h),!h.isTextblock;)h=h.lastChild;let y=r,x=1;for(;!y.isTextblock;y=y.firstChild)x++;if(h.canReplace(h.childCount,h.childCount,y.content)){if(a){let v=V.empty;for(let S=g.length-1;S>=0;
vendor: 4,510 bytes, line 17635
17635S--)v=V.from(g[S].copy(v));let w=t.tr.step(new Pt(e.pos-g.length,e.pos+r.nodeSize,e.pos+x,e.pos+r.nodeSize-x,new K(v,g.length,0),0,!0));a(w.scrollIntoView())}return!0}}return!1}function IM(t){return function(e,a){let n=e.selection,i=t<0?n.$from:n.$to,r=i.depth;for(;i.node(r).isInline;){if(!r)return!1;r--}return i.node(r).isTextblock?(a&&a(e.tr.setSelection(ce.create(e.doc,t<0?i.start(r):i.end(r)))),!0):!1}}const yre=IM(-1),xre=IM(1);function vre(t,e=null){return function(a,n){let{$from:i,$to:r}=a.selection,o=i.blockRange(r),l=o&&Xk(o,t,e);return l?(n&&n(a.tr.wrap(o,l).scrollIntoView()),!0):!1}}function Vj(t,e=null){return function(a,n){let i=!1;for(let r=0;r<a.selection.ranges.length&&!i;r++){let{$from:{pos:o},$to:{pos:l}}=a.selection.ranges[r];a.doc.nodesBetween(o,l,(c,d)=>{if(i)return!1;if(!(!c.isTextblock||c.hasMarkup(t,e)))if(c.type==t)i=!0;else{let u=a.doc.resolve(d),p=u.index();i=u.parent.canReplaceWith(p,p+1,t)}})}if(!i)return!1;if(n){let r=a.tr;for(let o=0;o<a.selection.ranges.length;o++){let{$from:{pos:l},$to:{pos:c}}=a.selection.ranges[o];r.setBlockType(l,c,t,e)}n(r.scrollIntoView())}return!0}}function nS(...t){return function(e,a,n){for(let i=0;i<t.length;i++)if(t[i](e,a,n))return!0;return!1}}nS(Zk,wM,SM);nS(Zk,AM,EM);nS(CM,jM,TM,hre);typeof navigator<"u"?/Mac|iP(hone|[oa]d)/.test(navigator.platform):typeof os<"u"&&os.platform&&os.platform()=="darwin";function bre(t,e=null){return function(a,n){let{$from:i,$to:r}=a.selection,o=i.blockRange(r);if(!o)return!1;let l=n?a.tr:null;return wre(l,o,t,e)?(n&&n(l.scrollIntoView()),!0):!1}}function wre(t,e,a,n=null){let i=!1,r=e,o=e.$from.doc;if(e.depth>=2&&e.$from.node(e.depth-1).type.compatibleContent(a)&&e.startIndex==0){if(e.$from.index(e.depth-1)==0)return!1;let c=o.resolve(e.start-2);r=new Xh(c,c,e.depth),e.endIndex<e.parent.childCount&&(e=new Xh(e.$from,o.resolve(e.$to.end(e.depth)),e.depth)),i=!0}let l=Xk(r,a,n,e);return l?(t&&kre(t,e,l,i,a),!0):!1}function kre(t,e,a,n,i){let r=V.empty;for(let u=a.length-1;u>=0;u--)r=V.from(a[u].type.create(a[u].attrs,r));t.step(new Pt(e.start-(n?2:0),e.end,e.start,e.end,new K(r,0,0),a.length,!0));let o=0;for(let u=0;u<a.length;u++)a[u].type==i&&(o=u+1);let l=a.length-o,c=e.start+a.length-(n?2:0),d=e.parent;for(let u=e.startIndex,p=e.endIndex,m=!0;u<p;u++,m=!1)!m&&Ii(t.doc,c,l)&&(t.split(c,l),c+=2*l),c+=d.child(u).nodeSize;return t}function Sre(t){return function(e,a){let{$from:n,$to:i}=e.selection,r=n.blockRange(i,o=>o.childCount>0&&o.firstChild.type==t);return r?a?n.node(r.depth-1).type==t?_re(e,a,t,r):Are(e,a,r):!0:!1}}function _re(t,e,a,n){let i=t.tr,r=n.end,o=n.$to.end(n.depth);r<o&&(i.step(new Pt(r-1,o,r,o,new K(V.from(a.create(null,n.parent.copy())),1,0),1,!0)),n=new Xh(i.doc.resolve(n.$from.pos),i.doc.resolve(o),n.depth));const l=ec(n);if(l==null)return!1;i.lift(n,l);let c=i.doc.resolve(i.mapping.map(r,-1)-1);return eo(i.doc,c.pos)&&c.nodeBefore.type==c.nodeAfter.type&&i.join(c.pos),e(i.scrollIntoView()),!0}function Are(t,e,a){let n=t.tr,i=a.parent;for(let h=a.end,g=a.endIndex-1,y=a.startIndex;g>y;g--)h-=i.child(g).nodeSize,n.delete(h-1,h+1);let r=n.doc.resolve(a.start),o=r.nodeAfter;if(n.mapping.map(a.end)!=a.start+r.nodeAfter.nodeSize)return!1;let l=a.startIndex==0,c=a.endIndex==i.childCount,d=r.node(-1),u=r.index(-1);if(!d.canReplace(u+(l?0:1),u+1,o.content.append(c?V.empty:V.from(i))))return!1;let p=r.pos,m=p+o.nodeSize;return n.step(new Pt(p-(l?1:0),m+(c?1:0),p+1,m-1,new K((l?V.empty:V.from(i.copy(V.empty))).append(c?V.empty:V.from(i.copy(V.empty))),l?0:1,c?0:1),l?0:1)),e(n.scrollIntoView()),!0}function Ere(t){return function(e,a){let{$from:n,$to:i}=e.selection,r=n.blockRange(i,d=>d.childCount>0&&d.firstChild.type==t);if(!r)return!1;let o=r.startIndex;if(o==0)return!1;let l=r.parent,c=l.child(o-1);if(c.type!=t)return!1;if(a){let d=c.lastChild&&c.lastChild.type==l.type,u=V.from(d?t.create():null),p=new K(V.from(t.create(null,V.from(l.type.create(null,u)))),d?3:1,0),m=r.start,h=r.end;a(e.tr.step(new Pt(m-(d?3:1),h,m,h,p,1,!0)).scrollIntoView())}return!0}}const zt=function(t){for(var e=0;;e++)if(t=t.previousSibling,!t)return e},Rl=function(t){let e=t.assignedSlot||t.parentNode;return e&&e.nodeType==11?e.host:e};let jb=null;const gi=function(t,e,a){let n=jb||(jb=document.createRange());return n.setEnd(t,a??t.nodeValue.length),n.setStart(t,e||0),n},Cre=function(){jb=null},is=function(t,e,a,n){return a&&(Hj(t,e,a,n,-1)||Hj(t,e,a,n,1))},jre=/^(img|br|input|textarea|hr)$/i;function Hj(t,e,a,n,i){for(var r;;){if(t==a&&e==n)return!0;
vendor: 4,508 bytes, line 17635
17635if(e==(i<0?0:on(t))){let o=t.parentNode;if(!o||o.nodeType!=1||Gu(t)||jre.test(t.nodeName)||t.contentEditable=="false")return!1;e=zt(t)+(i<0?0:1),t=o}else if(t.nodeType==1){let o=t.childNodes[e+(i<0?-1:0)];if(o.nodeType==1&&o.contentEditable=="false")if(!((r=o.pmViewDesc)===null||r===void 0)&&r.ignoreForSelection)e+=i;else return!1;else t=o,e=i<0?on(t):0}else return!1}}function on(t){return t.nodeType==3?t.nodeValue.length:t.childNodes.length}function Tre(t,e){for(;;){if(t.nodeType==3&&e)return t;if(t.nodeType==1&&e>0){if(t.contentEditable=="false")return null;t=t.childNodes[e-1],e=on(t)}else if(t.parentNode&&!Gu(t))e=zt(t),t=t.parentNode;else return null}}function Nre(t,e){for(;;){if(t.nodeType==3&&e<t.nodeValue.length)return t;if(t.nodeType==1&&e<t.childNodes.length){if(t.contentEditable=="false")return null;t=t.childNodes[e],e=0}else if(t.parentNode&&!Gu(t))e=zt(t)+1,t=t.parentNode;else return null}}function Ire(t,e,a){for(let n=e==0,i=e==on(t);n||i;){if(t==a)return!0;let r=zt(t);if(t=t.parentNode,!t)return!1;n=n&&r==0,i=i&&r==on(t)}}function Gu(t){let e;for(let a=t;a&&!(e=a.pmViewDesc);a=a.parentNode);return e&&e.node&&e.node.isBlock&&(e.dom==t||e.contentDOM==t)}const Hg=function(t){return t.focusNode&&is(t.focusNode,t.focusOffset,t.anchorNode,t.anchorOffset)};function yo(t,e){let a=document.createEvent("Event");return a.initEvent("keydown",!0,!0),a.keyCode=t,a.key=a.code=e,a}function Pre(t){let e=t.activeElement;for(;e&&e.shadowRoot;)e=e.shadowRoot.activeElement;return e}function Rre(t,e,a){if(t.caretPositionFromPoint)try{let n=t.caretPositionFromPoint(e,a);if(n)return{node:n.offsetNode,offset:Math.min(on(n.offsetNode),n.offset)}}catch{}if(t.caretRangeFromPoint){let n=t.caretRangeFromPoint(e,a);if(n)return{node:n.startContainer,offset:Math.min(on(n.startContainer),n.startOffset)}}}const ri=typeof navigator<"u"?navigator:null,Fj=typeof document<"u"?document:null,to=ri&&ri.userAgent||"",Tb=/Edge\/(\d+)/.exec(to),PM=/MSIE \d/.exec(to),Nb=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(to),Ra=!!(PM||Nb||Tb),Lr=PM?document.documentMode:Nb?+Nb[1]:Tb?+Tb[1]:0,dn=!Ra&&/gecko\/(\d+)/i.test(to);dn&&+(/Firefox\/(\d+)/.exec(to)||[0,0])[1];const Ib=!Ra&&/Chrome\/(\d+)/.exec(to),Nt=!!Ib,RM=Ib?+Ib[1]:0,Wt=!Ra&&!!ri&&/Apple Computer/.test(ri.vendor),Ll=Wt&&(/Mobile\/\w+/.test(to)||!!ri&&ri.maxTouchPoints>2),an=Ll||(ri?/Mac/.test(ri.platform):!1),LM=ri?/Win/.test(ri.platform):!1,Ai=/Android \d/.test(to),Ku=!!Fj&&"webkitFontSmoothing"in Fj.documentElement.style,Lre=Ku?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function Ore(t){let e=t.defaultView&&t.defaultView.visualViewport;return e?{left:0,right:e.width,top:0,bottom:e.height}:{left:0,right:t.documentElement.clientWidth,top:0,bottom:t.documentElement.clientHeight}}function ui(t,e){return typeof t=="number"?t:t[e]}function Mre(t){let e=t.getBoundingClientRect(),a=e.width/t.offsetWidth||1,n=e.height/t.offsetHeight||1;return{left:e.left,right:e.left+t.clientWidth*a,top:e.top,bottom:e.top+t.clientHeight*n}}function Bj(t,e,a){let n=t.someProp("scrollThreshold")||0,i=t.someProp("scrollMargin")||5,r=t.dom.ownerDocument;for(let o=a||t.dom;o;){if(o.nodeType!=1){o=Rl(o);continue}let l=o,c=l==r.body,d=c?Ore(r):Mre(l),u=0,p=0;if(e.top<d.top+ui(n,"top")?p=-(d.top-e.top+ui(i,"top")):e.bottom>d.bottom-ui(n,"bottom")&&(p=e.bottom-e.top>d.bottom-d.top?e.top+ui(i,"top")-d.top:e.bottom-d.bottom+ui(i,"bottom")),e.left<d.left+ui(n,"left")?u=-(d.left-e.left+ui(i,"left")):e.right>d.right-ui(n,"right")&&(u=e.right-d.right+ui(i,"right")),u||p)if(c)r.defaultView.scrollBy(u,p);else{let h=l.scrollLeft,g=l.scrollTop;p&&(l.scrollTop+=p),u&&(l.scrollLeft+=u);let y=l.scrollLeft-h,x=l.scrollTop-g;e={left:e.left-y,top:e.top-x,right:e.right-y,bottom:e.bottom-x}}let m=c?"fixed":getComputedStyle(o).position;if(/^(fixed|sticky)$/.test(m))break;o=m=="absolute"?o.offsetParent:Rl(o)}}function Dre(t){let e=t.dom.getBoundingClientRect(),a=Math.max(0,e.top),n,i;for(let r=(e.left+e.right)/2,o=a+1;o<Math.min(innerHeight,e.bottom);o+=5){let l=t.root.elementFromPoint(r,o);if(!l||l==t.dom||!t.dom.contains(l))continue;let c=l.getBoundingClientRect();if(c.top>=a-20){n=l,i=c.top;break}}return{refDOM:n,refTop:i,stack:OM(t.dom)}}function OM(t){let e=[],a=t.ownerDocument;for(let n=t;n&&(e.push({dom:n,top:n.scrollTop,left:n.scrollLeft}),t!=a);n=Rl(n));return e}function qre({refDOM:t,refTop:e,stack:a}){let n=t?t.getBoundingClientRect().top:0;MM(a,n==0?0:n-e)}function MM(t,e){for(let a=0;a<t.length;a++){let{dom:n,top:i,left:r}
vendor: 13,873 bytes, lines 17635-17636
17635=t[a];n.scrollTop!=i+e&&(n.scrollTop=i+e),n.scrollLeft!=r&&(n.scrollLeft=r)}}let As=null;function zre(t){if(t.setActive)return t.setActive();if(As)return t.focus(As);let e=OM(t);t.focus(As==null?{get preventScroll(){return As={preventScroll:!0},!0}}:void 0),As||(As=!1,MM(e,0))}function DM(t,e){let a,n=2e8,i,r=0,o=e.top,l=e.top,c,d;for(let u=t.firstChild,p=0;u;u=u.nextSibling,p++){let m;if(u.nodeType==1)m=u.getClientRects();else if(u.nodeType==3)m=gi(u).getClientRects();else continue;for(let h=0;h<m.length;h++){let g=m[h];if(g.top<=o&&g.bottom>=l){o=Math.max(g.bottom,o),l=Math.min(g.top,l);let y=g.left>e.left?g.left-e.left:g.right<e.left?e.left-g.right:0;if(y<n){a=u,n=y,i=y&&a.nodeType==3?{left:g.right<e.left?g.right:g.left,top:e.top}:e,u.nodeType==1&&y&&(r=p+(e.left>=(g.left+g.right)/2?1:0));continue}}else g.top>e.top&&!c&&g.left<=e.left&&g.right>=e.left&&(c=u,d={left:Math.max(g.left,Math.min(g.right,e.left)),top:g.top});!a&&(e.left>=g.right&&e.top>=g.top||e.left>=g.left&&e.top>=g.bottom)&&(r=p+1)}}return!a&&c&&(a=c,i=d,n=0),a&&a.nodeType==3?Vre(a,i):!a||n&&a.nodeType==1?{node:t,offset:r}:DM(a,i)}function Vre(t,e){let a=t.nodeValue.length,n=document.createRange(),i;for(let r=0;r<a;r++){n.setEnd(t,r+1),n.setStart(t,r);let o=er(n,1);if(o.top!=o.bottom&&iS(e,o)){i={node:t,offset:r+(e.left>=(o.left+o.right)/2?1:0)};break}}return n.detach(),i||{node:t,offset:0}}function iS(t,e){return t.left>=e.left-1&&t.left<=e.right+1&&t.top>=e.top-1&&t.top<=e.bottom+1}function Hre(t,e){let a=t.parentNode;return a&&/^li$/i.test(a.nodeName)&&e.left<t.getBoundingClientRect().left?a:t}function Fre(t,e,a){let{node:n,offset:i}=DM(e,a),r=-1;if(n.nodeType==1&&!n.firstChild){let o=n.getBoundingClientRect();r=o.left!=o.right&&a.left>(o.left+o.right)/2?1:-1}return t.docView.posFromDOM(n,i,r)}function Bre(t,e,a,n){let i=-1;for(let r=e,o=!1;r!=t.dom;){let l=t.docView.nearestDesc(r,!0),c;if(!l)return null;if(l.dom.nodeType==1&&(l.node.isBlock&&l.parent||!l.contentDOM)&&((c=l.dom.getBoundingClientRect()).width||c.height)&&(l.node.isBlock&&l.parent&&!/^T(R|BODY|HEAD|FOOT)$/.test(l.dom.nodeName)&&(!o&&c.left>n.left||c.top>n.top?i=l.posBefore:(!o&&c.right<n.left||c.bottom<n.top)&&(i=l.posAfter),o=!0),!l.contentDOM&&i<0&&!l.node.isText))return(l.node.isBlock?n.top<(c.top+c.bottom)/2:n.left<(c.left+c.right)/2)?l.posBefore:l.posAfter;r=l.dom.parentNode}return i>-1?i:t.docView.posFromDOM(e,a,-1)}function qM(t,e,a){let n=t.childNodes.length;if(n&&a.top<a.bottom)for(let i=Math.max(0,Math.min(n-1,Math.floor(n*(e.top-a.top)/(a.bottom-a.top))-2)),r=i;;){let o=t.childNodes[r];if(o.nodeType==1){let l=o.getClientRects();for(let c=0;c<l.length;c++){let d=l[c];if(iS(e,d))return qM(o,e,d)}}if((r=(r+1)%n)==i)break}return t}function Ure(t,e){let a=t.dom.ownerDocument,n,i=0,r=Rre(a,e.left,e.top);r&&({node:n,offset:i}=r);let o=(t.root.elementFromPoint?t.root:a).elementFromPoint(e.left,e.top),l;if(!o||!t.dom.contains(o.nodeType!=1?o.parentNode:o)){let d=t.dom.getBoundingClientRect();if(!iS(e,d)||(o=qM(t.dom,e,d),!o))return null}if(Wt)for(let d=o;n&&d;d=Rl(d))d.draggable&&(n=void 0);if(o=Hre(o,e),n){if(dn&&n.nodeType==1&&(i=Math.min(i,n.childNodes.length),i<n.childNodes.length)){let u=n.childNodes[i],p;u.nodeName=="IMG"&&(p=u.getBoundingClientRect()).right<=e.left&&p.bottom>e.top&&i++}let d;Ku&&i&&n.nodeType==1&&(d=n.childNodes[i-1]).nodeType==1&&d.contentEditable=="false"&&d.getBoundingClientRect().top>=e.top&&i--,n==t.dom&&i==n.childNodes.length-1&&n.lastChild.nodeType==1&&e.top>n.lastChild.getBoundingClientRect().bottom?l=t.state.doc.content.size:(i==0||n.nodeType!=1||n.childNodes[i-1].nodeName!="BR")&&(l=Bre(t,n,i,e))}l==null&&(l=Fre(t,o,e));let c=t.docView.nearestDesc(o,!0);return{pos:l,inside:c?c.posAtStart-c.border:-1}}function Uj(t){return t.top<t.bottom||t.left<t.right}function er(t,e){let a=t.getClientRects();if(a.length){let n=a[e<0?0:a.length-1];if(Uj(n))return n}return Array.prototype.find.call(a,Uj)||t.getBoundingClientRect()}const $re=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;function zM(t,e,a){let{node:n,offset:i,atom:r}=t.docView.domFromPos(e,a<0?-1:1),o=Ku||dn;if(n.nodeType==3)if(o&&($re.test(n.nodeValue)||(a<0?!i:i==n.nodeValue.length))){let c=er(gi(n,i,i),a);if(dn&&i&&/\s/.test(n.nodeValue[i-1])&&i<n.nodeValue.length){let d=er(gi(n,i-1,i-1),-1);if(d.top==c.top){let u=er(gi(n,i,i+1),-1);if(u.top!=c.top)return Nc(u,u.left<d.left)}}return c}else{let c=i,d=i,u=a<0?1:-1;return a<0&&!i?(d++,u=-1):a>=0&&i==n.nodeValue.length?(c--,u=1):a<0?c--:d++,Nc(er(gi(n,c,d),u),u<0)}if(!t.state.doc.resolve(e-(r||0)).parent.inlineContent){if(r==null&&i&&(a<0||i==on(n))){let c=n.childNodes[i-1];if(c.nodeType==1)return X0(c.getBoundingClientRect(),!1)}if(r==null&&i<on(n)){let c=n.childNodes[i];if(c.nodeType==1)return X0(c.getBoundingClientRect(),!0)}return X0(n.getBoundingClientRect(),a>=0)}if(r==null&&i&&(a<0||i==on(n))){let c=n.childNodes[i-1],d=c.nodeType==3?gi(c,on(c)-(o?0:1)):c.nodeType==1&&(c.nodeName!="BR"||!c.nextSibling)?c:null;if(d)return Nc(er(d,1),!1)}if(r==null&&i<on(n)){let c=n.childNodes[i];for(;c.pmViewDesc&&c.pmViewDesc.ignoreForCoords;)c=c.nextSibling;let d=c?c.nodeType==3?gi(c,0,o?0:1):c.nodeType==1?c:null:null;if(d)return Nc(er(d,-1),!0)}return Nc(er(n.nodeType==3?gi(n):n,-a),a>=0)}function Nc(t,e){if(t.width==0)return t;let a=e?t.left:t.right;return{top:t.top,bottom:t.bottom,left:a,right:a}}function X0(t,e){if(t.height==0)return t;let a=e?t.top:t.bottom;return{top:a,bottom:a,left:t.left,right:t.right}}function VM(t,e,a){let n=t.state,i=t.root.activeElement;n!=e&&t.updateState(e),i!=t.dom&&t.focus();try{return a()}finally{n!=e&&t.updateState(n),i!=t.dom&&i&&i.focus()}}function Wre(t,e,a){let n=e.selection,i=a=="up"?n.$from:n.$to;return VM(t,e,()=>{let{node:r}=t.docView.domFromPos(i.pos,a=="up"?-1:1);for(;;){let l=t.docView.nearestDesc(r,!0);if(!l)break;if(l.node.isBlock){r=l.contentDOM||l.dom;break}r=l.dom.parentNode}let o=zM(t,i.pos,1);for(let l=r.firstChild;l;l=l.nextSibling){let c;if(l.nodeType==1)c=l.getClientRects();else if(l.nodeType==3)c=gi(l,0,l.nodeValue.length).getClientRects();else continue;for(let d=0;d<c.length;d++){let u=c[d];if(u.bottom>u.top+1&&(a=="up"?o.top-u.top>(u.bottom-o.top)*2:u.bottom-o.bottom>(o.bottom-u.top)*2))return!1}}return!0})}const Gre=/[\u0590-\u08ac]/;function Kre(t,e,a){let{$head:n}=e.selection;if(!n.parent.isTextblock)return!1;let i=n.parentOffset,r=!i,o=i==n.parent.content.size,l=t.domSelection();return l?!Gre.test(n.parent.textContent)||!l.modify?a=="left"||a=="backward"?r:o:VM(t,e,()=>{let{focusNode:c,focusOffset:d,anchorNode:u,anchorOffset:p}=t.domSelectionRange(),m=l.caretBidiLevel;l.modify("move",a,"character");let h=n.depth?t.docView.domAfterPos(n.before()):t.dom,{focusNode:g,focusOffset:y}=t.domSelectionRange(),x=g&&!h.contains(g.nodeType==1?g:g.parentNode)||c==g&&d==y;try{l.collapse(u,p),c&&(c!=u||d!=p)&&l.extend&&l.extend(c,d)}catch{}return m!=null&&(l.caretBidiLevel=m),x}):n.pos==n.start()||n.pos==n.end()}let $j=null,Wj=null,Gj=!1;function Jre(t,e,a){return $j==e&&Wj==a?Gj:($j=e,Wj=a,Gj=a=="up"||a=="down"?Wre(t,e,a):Kre(t,e,a))}const un=0,Kj=1,Eo=2,oi=3;class Ju{constructor(e,a,n,i){this.parent=e,this.children=a,this.dom=n,this.contentDOM=i,this.dirty=un,n.pmViewDesc=this}matchesWidget(e){return!1}matchesMark(e){return!1}matchesNode(e,a,n){return!1}matchesHack(e){return!1}parseRule(){return null}stopEvent(e){return!1}get size(){let e=0;for(let a=0;a<this.children.length;a++)e+=this.children[a].size;return e}get border(){return 0}destroy(){this.parent=void 0,this.dom.pmViewDesc==this&&(this.dom.pmViewDesc=void 0);for(let e=0;e<this.children.length;e++)this.children[e].destroy()}posBeforeChild(e){for(let a=0,n=this.posAtStart;;a++){let i=this.children[a];if(i==e)return n;n+=i.size}}get posBefore(){return this.parent.posBeforeChild(this)}get posAtStart(){return this.parent?this.parent.posBeforeChild(this)+this.border:0}get posAfter(){return this.posBefore+this.size}get posAtEnd(){return this.posAtStart+this.size-2*this.border}localPosFromDOM(e,a,n){if(this.contentDOM&&this.contentDOM.contains(e.nodeType==1?e:e.parentNode))if(n<0){let r,o;if(e==this.contentDOM)r=e.childNodes[a-1];else{for(;e.parentNode!=this.contentDOM;)e=e.parentNode;r=e.previousSibling}for(;r&&!((o=r.pmViewDesc)&&o.parent==this);)r=r.previousSibling;return r?this.posBeforeChild(o)+o.size:this.posAtStart}else{let r,o;if(e==this.contentDOM)r=e.childNodes[a];else{for(;e.parentNode!=this.contentDOM;)e=e.parentNode;r=e.nextSibling}for(;r&&!((o=r.pmViewDesc)&&o.parent==this);)r=r.nextSibling;return r?this.posBeforeChild(o):this.posAtEnd}let i;if(e==this.dom&&this.contentDOM)i=a>zt(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))i=e.compareDocumentPosition(this.contentDOM)&2;else if(this.dom.firstChild){if(a==0)for(let r=e;;r=r.parentNode){if(r==this.dom){i=!1;break}if(r.previousSibling)break}if(i==null&&a==e.childNodes.length)for(let r=e;;r=r.parentNode){if(r==this.dom){i=!0;break}if(r.nextSibling)break}}return i??n>0?this.posAtEnd:this.posAtStart}nearestDesc(e,a=!1){for(let n=!0,i=e;i;i=i.parentNode){let r=this.getDesc(i),o;if(r&&(!a||r.node))if(n&&(o=r.nodeDOM)&&!(o.nodeType==1?o.contains(e.nodeType==1?e:e.parentNode):o==e))n=!1;else return r}}getDesc(e){let a=e.pmViewDesc;for(let n=a;n;n=n.parent)if(n==this)return a}posFromDOM(e,a,n){for(let i=e;i;i=i.parentNode){let r=this.getDesc(i);if(r)return r.localPosFromDOM(e,a,n)}return-1}descAt(e){for(let a=0,n=0;a<this.children.length;a++){let i=this.children[a],r=n+i.size;if(n==e&&r!=n){for(;!i.border&&i.children.length;)for(let o=0;o<i.children.length;o++){let l=i.children[o];if(l.size){i=l;break}}return i}if(e<r)return i.descAt(e-n-i.border);n=r}}domFromPos(e,a){if(!this.contentDOM)return{node:this.dom,offset:0,atom:e+1};let n=0,i=0;for(let r=0;n<this.children.length;n++){let o=this.children[n],l=r+o.size;if(l>e||o instanceof FM){i=e-r;break}r=l}if(i)return this.children[n].domFromPos(i-this.children[n].border,a);for(let r;n&&!(r=this.children[n-1]).size&&r instanceof HM&&r.side>=0;n--);if(a<=0){let r,o=!0;for(;r=n?this.children[n-1]:null,!(!r||r.dom.parentNode==this.contentDOM);n--,o=!1);return r&&a&&o&&!r.border&&!r.domAtom?r.domFromPos(r.size,a):{node:this.contentDOM,offset:r?zt(r.dom)+1:0}}else{let r,o=!0;for(;r=n<this.children.length?this.children[n]:null,!(!r||r.dom.parentNode==this.contentDOM);n++,o=!1);return r&&o&&!r.border&&!r.domAtom?r.domFromPos(0,a):{node:this.contentDOM,offset:r?zt(r.dom):this.contentDOM.childNodes.length}}}parseRange(e,a,n=0){if(this.children.length==0)return{node:this.contentDOM,from:e,to:a,fromOffset:0,toOffset:this.contentDOM.childNodes.length};let i=-1,r=-1;for(let o=n,l=0;;l++){let c=this.children[l],d=o+c.size;if(i==-1&&e<=d){let u=o+c.border;if(e>=u&&a<=d-c.border&&c.node&&c.contentDOM&&this.contentDOM.contains(c.contentDOM))return c.parseRange(e,a,u);e=o;for(let p=l;p>0;p--){let m=this.children[p-1];if(m.size&&m.dom.parentNode==this.contentDOM&&!m.emptyChildAt(1)){i=zt(m.dom)+1;break}e-=m.size}i==-1&&(i=0)}if(i>-1&&(d>a||l==this.children.length-1)){a=d;for(let u=l+1;u<this.children.length;u++){let p=this.children[u];if(p.size&&p.dom.parentNode==this.contentDOM&&!p.emptyChildAt(-1)){r=zt(p.dom);break}a+=p.size}r==-1&&(r=this.contentDOM.childNodes.length);break}o=d}return{node:this.contentDOM,from:e,to:a,fromOffset:i,toOffset:r}}emptyChildAt(e){if(this.border||!this.contentDOM||!this.children.length)return!1;let a=this.children[e<0?0:this.children.length-1];return a.size==0||a.emptyChildAt(e)}domAfterPos(e){let{node:a,offset:n}=this.domFromPos(e,0);if(a.nodeType!=1||n==a.childNodes.length)throw new RangeError("No node after pos "+e);return a.childNodes[n]}setSelection(e,a,n,i=!1){let r=Math.min(e,a),o=Math.max(e,a);for(let h=0,g=0;h<this.children.length;h++){let y=this.children[h],x=g+y.size;if(r>g&&o<x)return y.setSelection(e-g-y.border,a-g-y.border,n,i);g=x}let l=this.domFromPos(e,e?-1:1),c=a==e?l:this.domFromPos(a,a?-1:1),d=n.root.getSelection(),u=n.domSelectionRange(),p=!1;if((dn||Wt)&&e==a){let{node:h,offset:g}=l;if(h.nodeType==3){if(p=!!(g&&h.nodeValue[g-1]==` 17636`),p&&g==h.nodeValue.length)for(let y=h,x;y;y=y.parentNode){if(x=y.nextSibling){x.nodeName=="BR"&&(l=c={node:x.parentNode,offset:zt(x)+1});break}let v=y.pmViewDesc;if(v&&v.node&&v.node.isBlock)break}}else{let y=h.childNodes[g-1];p=y&&(y.nodeName=="BR"||y.contentEditable=="false")}}if(dn&&u.focusNode&&u.focusNode!=c.node&&u.focusNode.nodeType==1){let h=u.focusNode.childNodes[u.focusOffset];h&&h.contentEditable=="false"&&(i=!0)}if(!(i||p&&Wt)&&is(l.node,l.offset,u.anchorNode,u.anchorOffset)&&is(c.node,c.offset,u.focusNode,u.focusOffset))return;let m=!1;if((d.extend||e==a)&&!(p&&dn)){d.collapse(l.node,l.offset);try{e!=a&&d.extend(c.node,c.offset),m=!0}catch{}}if(!m){if(e>a){let g=l;l=c,c=g}let h=document.createRange();h.setEnd(c.node,c.offset),h.setStart(l.node,l.offset),d.removeAllRanges(),d.addRange(h)}}ignoreMutation(e){return!this.contentDOM&&e.type!="selection"}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(e,a){for(let n=0,i=0;i<this.children.length;i++){let r=this.children[i],o=n+r.size;if(n==o?e<=o&&a>=n:e<o&&a>n){let l=n+r.border,c=o-r.border;if(e>=l&&a<=c){this.dirty=e==n||a==o?Eo:Kj,e==l&&a==c&&(r.contentLost||r.dom.parentNode!=this.contentDOM)?r.dirty=oi:r.markDirty(e-l,a-l);return}else r.dirty=r.dom==r.contentDOM&&r.dom.parentNode==this.contentDOM&&!r.children.length?Eo:oi}n=o}this.dirty=Eo}markParentsDirty(){let e=1;for(let a=this.parent;a;a=a.parent,e++){let n=e==1?Eo:Kj;a.dirty<n&&(a.dirty=n)}}get domAtom(){return!1}get ignoreForCoords(){return!1}get ignoreForSelection(){return!1}isText(e){return!1}}class HM extends Ju{constructor(e,a,n,i){let r,o=a.type.toDOM;if(typeof o=="function"&&(o=o(n,()=>{if(!r)return i;if(r.parent)return r.parent.posBeforeChild(r)}
vendor: 4,625 bytes, line 17636
17636)),!a.type.spec.raw){if(o.nodeType!=1){let l=document.createElement("span");l.appendChild(o),o=l}o.contentEditable="false",o.classList.add("ProseMirror-widget")}super(e,[],o,null),this.widget=a,this.widget=a,r=this}matchesWidget(e){return this.dirty==un&&e.type.eq(this.widget.type)}parseRule(){return{ignore:!0}}stopEvent(e){let a=this.widget.spec.stopEvent;return a?a(e):!1}ignoreMutation(e){return e.type!="selection"||this.widget.spec.ignoreSelection}destroy(){this.widget.type.destroy(this.dom),super.destroy()}get domAtom(){return!0}get ignoreForSelection(){return!!this.widget.type.spec.relaxedSide}get side(){return this.widget.type.side}}class Qre extends Ju{constructor(e,a,n,i){super(e,[],a,null),this.textDOM=n,this.text=i}get size(){return this.text.length}localPosFromDOM(e,a){return e!=this.textDOM?this.posAtStart+(a?this.size:0):this.posAtStart+a}domFromPos(e){return{node:this.textDOM,offset:e}}ignoreMutation(e){return e.type==="characterData"&&e.target.nodeValue==e.oldValue}}class rs extends Ju{constructor(e,a,n,i,r){super(e,[],n,i),this.mark=a,this.spec=r}static create(e,a,n,i){let r=i.nodeViews[a.type.name],o=r&&r(a,i,n);return(!o||!o.dom)&&(o=fs.renderSpec(document,a.type.spec.toDOM(a,n),null,a.attrs)),new rs(e,a,o.dom,o.contentDOM||o.dom,o)}parseRule(){return this.dirty&oi||this.mark.type.spec.reparseInView?null:{mark:this.mark.type.name,attrs:this.mark.attrs,contentElement:this.contentDOM}}matchesMark(e){return this.dirty!=oi&&this.mark.eq(e)}markDirty(e,a){if(super.markDirty(e,a),this.dirty!=un){let n=this.parent;for(;!n.node;)n=n.parent;n.dirty<this.dirty&&(n.dirty=this.dirty),this.dirty=un}}slice(e,a,n){let i=rs.create(this.parent,this.mark,!0,n),r=this.children,o=this.size;a<o&&(r=Rb(r,a,o,n)),e>0&&(r=Rb(r,0,e,n));for(let l=0;l<r.length;l++)r[l].parent=i;return i.children=r,i}ignoreMutation(e){return this.spec.ignoreMutation?this.spec.ignoreMutation(e):super.ignoreMutation(e)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}}class Or extends Ju{constructor(e,a,n,i,r,o,l,c,d){super(e,[],r,o),this.node=a,this.outerDeco=n,this.innerDeco=i,this.nodeDOM=l}static create(e,a,n,i,r,o){let l=r.nodeViews[a.type.name],c,d=l&&l(a,r,()=>{if(!c)return o;if(c.parent)return c.parent.posBeforeChild(c)},n,i),u=d&&d.dom,p=d&&d.contentDOM;if(a.isText){if(!u)u=document.createTextNode(a.text);else if(u.nodeType!=3)throw new RangeError("Text must be rendered as a DOM text node")}else u||({dom:u,contentDOM:p}=fs.renderSpec(document,a.type.spec.toDOM(a),null,a.attrs));!p&&!a.isText&&u.nodeName!="BR"&&(u.hasAttribute("contenteditable")||(u.contentEditable="false"),a.type.spec.draggable&&(u.draggable=!0));let m=u;return u=$M(u,n,a),d?c=new Xre(e,a,n,i,u,p||null,m,d,r,o+1):a.isText?new Fg(e,a,n,i,u,m,r):new Or(e,a,n,i,u,p||null,m,r,o+1)}parseRule(){if(this.node.type.spec.reparseInView)return null;let e={node:this.node.type.name,attrs:this.node.attrs};if(this.node.type.whitespace=="pre"&&(e.preserveWhitespace="full"),!this.contentDOM)e.getContent=()=>this.node.content;else if(!this.contentLost)e.contentElement=this.contentDOM;else{for(let a=this.children.length-1;a>=0;a--){let n=this.children[a];if(this.dom.contains(n.dom.parentNode)){e.contentElement=n.dom.parentNode;break}}e.contentElement||(e.getContent=()=>V.empty)}return e}matchesNode(e,a,n){return this.dirty==un&&e.eq(this.node)&&Zh(a,this.outerDeco)&&n.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}updateChildren(e,a){let n=this.node.inlineContent,i=a,r=e.composing?this.localCompositionInfo(e,a):null,o=r&&r.pos>-1?r:null,l=r&&r.pos<0,c=new Zre(this,o&&o.node,e);aoe(this.node,this.innerDeco,(d,u,p)=>{d.spec.marks?c.syncToMarks(d.spec.marks,n,e,u):d.type.side>=0&&!p&&c.syncToMarks(u==this.node.childCount?qe.none:this.node.child(u).marks,n,e,u),c.placeWidget(d,e,i)},(d,u,p,m)=>{c.syncToMarks(d.marks,n,e,m);let h;c.findNodeMatch(d,u,p,m)||l&&e.state.selection.from>i&&e.state.selection.to<i+d.nodeSize&&(h=c.findIndexWithChild(r.node))>-1&&c.updateNodeAt(d,u,p,h,e)||c.updateNextNode(d,u,p,e,m,i)||c.addNode(d,u,p,e,i),i+=d.nodeSize}),c.syncToMarks([],n,e,0),this.node.isTextblock&&c.addTextblockHacks(),c.destroyRest(),(c.changed||this.dirty==Eo)&&(o&&this.protectLocalComposition(e,o),BM(this.contentDOM,this.children,e),Ll&&noe(this.dom))}localCompositionInfo(e,a){let{from:n,to:i}=e.state.selection;if(!(e.state.selection instanceof ce)||n<a||i>a+this.node.content.size)return null;let r=e.input.compositionNode;if(!r||!this.dom.contains(r.parentNode))return null;if(this.node.inlineContent){let o=r.nodeValue,l=ioe(this.node.content,o,n-a,i-a);
vendor: 5,034 bytes, line 17636
17636return l<0?null:{node:r,pos:l,text:o}}else return{node:r,pos:-1,text:""}}protectLocalComposition(e,{node:a,pos:n,text:i}){if(this.getDesc(a))return;let r=a;for(;r.parentNode!=this.contentDOM;r=r.parentNode){for(;r.previousSibling;)r.parentNode.removeChild(r.previousSibling);for(;r.nextSibling;)r.parentNode.removeChild(r.nextSibling);r.pmViewDesc&&(r.pmViewDesc=void 0)}let o=new Qre(this,r,a,i);e.input.compositionNodes.push(o),this.children=Rb(this.children,n,n+i.length,e,o)}update(e,a,n,i){return this.dirty==oi||!e.sameMarkup(this.node)?!1:(this.updateInner(e,a,n,i),!0)}updateInner(e,a,n,i){this.updateOuterDeco(a),this.node=e,this.innerDeco=n,this.contentDOM&&this.updateChildren(i,this.posAtStart),this.dirty=un}updateOuterDeco(e){if(Zh(e,this.outerDeco))return;let a=this.nodeDOM.nodeType!=1,n=this.dom;this.dom=UM(this.dom,this.nodeDOM,Pb(this.outerDeco,this.node,a),Pb(e,this.node,a)),this.dom!=n&&(n.pmViewDesc=void 0,this.dom.pmViewDesc=this),this.outerDeco=e}selectNode(){this.nodeDOM.nodeType==1&&(this.nodeDOM.classList.add("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&(this.nodeDOM.draggable=!0))}deselectNode(){this.nodeDOM.nodeType==1&&(this.nodeDOM.classList.remove("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&this.nodeDOM.removeAttribute("draggable"))}get domAtom(){return this.node.isAtom}}function Jj(t,e,a,n,i){$M(n,e,t);let r=new Or(void 0,t,e,a,n,n,n,i,0);return r.contentDOM&&r.updateChildren(i,0),r}class Fg extends Or{constructor(e,a,n,i,r,o,l){super(e,a,n,i,r,null,o,l,0)}parseRule(){let e=this.nodeDOM.parentNode;for(;e&&e!=this.dom&&!e.pmIsDeco;)e=e.parentNode;return{skip:e||!0}}update(e,a,n,i){return this.dirty==oi||this.dirty!=un&&!this.inParent()||!e.sameMarkup(this.node)?!1:(this.updateOuterDeco(a),(this.dirty!=un||e.text!=this.node.text)&&e.text!=this.nodeDOM.nodeValue&&(this.nodeDOM.nodeValue=e.text,i.trackWrites==this.nodeDOM&&(i.trackWrites=null)),this.node=e,this.dirty=un,!0)}inParent(){let e=this.parent.contentDOM;for(let a=this.nodeDOM;a;a=a.parentNode)if(a==e)return!0;return!1}domFromPos(e){return{node:this.nodeDOM,offset:e}}localPosFromDOM(e,a,n){return e==this.nodeDOM?this.posAtStart+Math.min(a,this.node.text.length):super.localPosFromDOM(e,a,n)}ignoreMutation(e){return e.type!="characterData"&&e.type!="selection"}slice(e,a,n){let i=this.node.cut(e,a),r=document.createTextNode(i.text);return new Fg(this.parent,i,this.outerDeco,this.innerDeco,r,r,n)}markDirty(e,a){super.markDirty(e,a),this.dom!=this.nodeDOM&&(e==0||a==this.nodeDOM.nodeValue.length)&&(this.dirty=oi)}get domAtom(){return!1}isText(e){return this.node.text==e}}class FM extends Ju{parseRule(){return{ignore:!0}}matchesHack(e){return this.dirty==un&&this.dom.nodeName==e}get domAtom(){return!0}get ignoreForCoords(){return this.dom.nodeName=="IMG"}}class Xre extends Or{constructor(e,a,n,i,r,o,l,c,d,u){super(e,a,n,i,r,o,l,d,u),this.spec=c}update(e,a,n,i){if(this.dirty==oi)return!1;if(this.spec.update&&(this.node.type==e.type||this.spec.multiType)){let r=this.spec.update(e,a,n);return r&&this.updateInner(e,a,n,i),r}else return!this.contentDOM&&!e.isLeaf?!1:super.update(e,a,n,i)}selectNode(){this.spec.selectNode?this.spec.selectNode():super.selectNode()}deselectNode(){this.spec.deselectNode?this.spec.deselectNode():super.deselectNode()}setSelection(e,a,n,i){this.spec.setSelection?this.spec.setSelection(e,a,n.root):super.setSelection(e,a,n,i)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}stopEvent(e){return this.spec.stopEvent?this.spec.stopEvent(e):!1}ignoreMutation(e){return this.spec.ignoreMutation?this.spec.ignoreMutation(e):super.ignoreMutation(e)}}function BM(t,e,a){let n=t.firstChild,i=!1;for(let r=0;r<e.length;r++){let o=e[r],l=o.dom;if(l.parentNode==t){for(;l!=n;)n=Qj(n),i=!0;n=n.nextSibling}else i=!0,t.insertBefore(l,n);if(o instanceof rs){let c=n?n.previousSibling:t.lastChild;BM(o.contentDOM,o.children,a),n=c?c.nextSibling:t.firstChild}}for(;n;)n=Qj(n),i=!0;i&&a.trackWrites==t&&(a.trackWrites=null)}const wd=function(t){t&&(this.nodeName=t)};wd.prototype=Object.create(null);const Co=[new wd];function Pb(t,e,a){if(t.length==0)return Co;let n=a?Co[0]:new wd,i=[n];for(let r=0;r<t.length;r++){let o=t[r].type.attrs;if(o){o.nodeName&&i.push(n=new wd(o.nodeName));for(let l in o){let c=o[l];c!=null&&(a&&i.length==1&&i.push(n=new wd(e.isInline?"span":"div")),l=="class"?n.class=(n.class?n.class+" ":"")+c:l=="style"?n.style=(n.style?n.style+";":"")+c:l!="nodeName"&&(n[l]=c))}}}return i}function UM(t,e,a,n){if(a==Co&&n==Co)return e;let i=e;for(let r=0;r<n.length;r++){let o=n[r],l=a[r];if(r){let c;l&&l.nodeName==o.nodeName&&i!=t&&(c=i.parentNode)&&c.nodeName.toLowerCase()==o.nodeName||(c=document.createElement(o.nodeName),c.pmIsDeco=!0,c.appendChild(i),l=Co[0]),i=c}Yre(i,l||Co[0],o)}return i}function Yre(t,e,a){for(let n in e)n!="class"&&n!="style"&&n!="nodeName"&&!(n in a)&&t.removeAttribute(n);for(let n in a)n!="class"&&n!="style"&&n!="nodeName"&&a[n]!=e[n]&&t.setAttribute(n,a[n]);
vendor: 6,195 bytes, line 17636
17636if(e.class!=a.class){let n=e.class?e.class.split(" ").filter(Boolean):[],i=a.class?a.class.split(" ").filter(Boolean):[];for(let r=0;r<n.length;r++)i.indexOf(n[r])==-1&&t.classList.remove(n[r]);for(let r=0;r<i.length;r++)n.indexOf(i[r])==-1&&t.classList.add(i[r]);t.classList.length==0&&t.removeAttribute("class")}if(e.style!=a.style){if(e.style){let n=/\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g,i;for(;i=n.exec(e.style);)t.style.removeProperty(i[1])}a.style&&(t.style.cssText+=a.style)}}function $M(t,e,a){return UM(t,t,Co,Pb(e,a,t.nodeType!=1))}function Zh(t,e){if(t.length!=e.length)return!1;for(let a=0;a<t.length;a++)if(!t[a].type.eq(e[a].type))return!1;return!0}function Qj(t){let e=t.nextSibling;return t.parentNode.removeChild(t),e}class Zre{constructor(e,a,n){this.lock=a,this.view=n,this.index=0,this.stack=[],this.changed=!1,this.top=e,this.preMatch=eoe(e.node.content,e)}destroyBetween(e,a){if(e!=a){for(let n=e;n<a;n++)this.top.children[n].destroy();this.top.children.splice(e,a-e),this.changed=!0}}destroyRest(){this.destroyBetween(this.index,this.top.children.length)}syncToMarks(e,a,n,i){let r=0,o=this.stack.length>>1,l=Math.min(o,e.length);for(;r<l&&(r==o-1?this.top:this.stack[r+1<<1]).matchesMark(e[r])&&e[r].type.spec.spanning!==!1;)r++;for(;r<o;)this.destroyRest(),this.top.dirty=un,this.index=this.stack.pop(),this.top=this.stack.pop(),o--;for(;o<e.length;){this.stack.push(this.top,this.index+1);let c=-1,d=this.top.children.length;i<this.preMatch.index&&(d=Math.min(this.index+3,d));for(let u=this.index;u<d;u++){let p=this.top.children[u];if(p.matchesMark(e[o])&&!this.isLocked(p.dom)){c=u;break}}if(c>-1)c>this.index&&(this.changed=!0,this.destroyBetween(this.index,c)),this.top=this.top.children[this.index];else{let u=rs.create(this.top,e[o],a,n);this.top.children.splice(this.index,0,u),this.top=u,this.changed=!0}this.index=0,o++}}findNodeMatch(e,a,n,i){let r=-1,o;if(i>=this.preMatch.index&&(o=this.preMatch.matches[i-this.preMatch.index]).parent==this.top&&o.matchesNode(e,a,n))r=this.top.children.indexOf(o,this.index);else for(let l=this.index,c=Math.min(this.top.children.length,l+5);l<c;l++){let d=this.top.children[l];if(d.matchesNode(e,a,n)&&!this.preMatch.matched.has(d)){r=l;break}}return r<0?!1:(this.destroyBetween(this.index,r),this.index++,!0)}updateNodeAt(e,a,n,i,r){let o=this.top.children[i];return o.dirty==oi&&o.dom==o.contentDOM&&(o.dirty=Eo),o.update(e,a,n,r)?(this.destroyBetween(this.index,i),this.index++,!0):!1}findIndexWithChild(e){for(;;){let a=e.parentNode;if(!a)return-1;if(a==this.top.contentDOM){let n=e.pmViewDesc;if(n){for(let i=this.index;i<this.top.children.length;i++)if(this.top.children[i]==n)return i}return-1}e=a}}updateNextNode(e,a,n,i,r,o){for(let l=this.index;l<this.top.children.length;l++){let c=this.top.children[l];if(c instanceof Or){let d=this.preMatch.matched.get(c);if(d!=null&&d!=r)return!1;let u=c.dom,p,m=this.isLocked(u)&&!(e.isText&&c.node&&c.node.isText&&c.nodeDOM.nodeValue==e.text&&c.dirty!=oi&&Zh(a,c.outerDeco));if(!m&&c.update(e,a,n,i))return this.destroyBetween(this.index,l),c.dom!=u&&(this.changed=!0),this.index++,!0;if(!m&&(p=this.recreateWrapper(c,e,a,n,i,o)))return this.destroyBetween(this.index,l),this.top.children[this.index]=p,p.contentDOM&&(p.dirty=Eo,p.updateChildren(i,o+1),p.dirty=un),this.changed=!0,this.index++,!0;break}}return!1}recreateWrapper(e,a,n,i,r,o){if(e.dirty||a.isAtom||!e.children.length||!e.node.content.eq(a.content)||!Zh(n,e.outerDeco)||!i.eq(e.innerDeco))return null;let l=Or.create(this.top,a,n,i,r,o);if(l.contentDOM){l.children=e.children,e.children=[];for(let c of l.children)c.parent=l}return e.destroy(),l}addNode(e,a,n,i,r){let o=Or.create(this.top,e,a,n,i,r);o.contentDOM&&o.updateChildren(i,r+1),this.top.children.splice(this.index++,0,o),this.changed=!0}placeWidget(e,a,n){let i=this.index<this.top.children.length?this.top.children[this.index]:null;if(i&&i.matchesWidget(e)&&(e==i.widget||!i.widget.type.toDOM.parentNode))this.index++;else{let r=new HM(this.top,e,a,n);this.top.children.splice(this.index++,0,r),this.changed=!0}}addTextblockHacks(){let e=this.top.children[this.index-1],a=this.top;for(;e instanceof rs;)a=e,e=a.children[a.children.length-1];(!e||!(e instanceof Fg)||/\n$/.test(e.node.text)||this.view.requiresGeckoHackNode&&/\s$/.test(e.node.text))&&((Wt||Nt)&&e&&e.dom.contentEditable=="false"&&this.addHackNode("IMG",a),this.addHackNode("BR",this.top))}addHackNode(e,a){if(a==this.top&&this.index<a.children.length&&a.children[this.index].matchesHack(e))this.index++;else{let n=document.createElement(e);e=="IMG"&&(n.className="ProseMirror-separator",n.alt=""),e=="BR"&&(n.className="ProseMirror-trailingBreak");let i=new FM(this.top,[],n,null);a!=this.top?a.children.push(i):a.children.splice(this.index++,0,i),this.changed=!0}}isLocked(e){return this.lock&&(e==this.lock||e.nodeType==1&&e.contains(this.lock.parentNode))}}function eoe(t,e){let a=e,n=a.children.length,i=t.childCount,r=new Map,o=[];e:for(;i>0;){let l;for(;;)if(n){let d=a.children[n-1];if(d instanceof rs)a=d,n=d.children.length;else{l=d,n--;break}}else{if(a==e)break e;n=a.parent.children.indexOf(a),a=a.parent}let c=l.node;if(c){if(c!=t.child(i-1))break;--i,r.set(l,i),o.push(l)}}return{index:i,matched:r,matches:o.reverse()}}function toe(t,e){return t.type.side-e.type.side}function aoe(t,e,a,n){let i=e.locals(t),r=0;if(i.length==0){for(let d=0;d<t.childCount;d++){let u=t.child(d);n(u,i,e.forChild(r,u),d),r+=u.nodeSize}return}let o=0,l=[],c=null;for(let d=0;;){let u,p;for(;o<i.length&&i[o].to==r;){let x=i[o++];x.widget&&(u?(p||(p=[u])).push(x):u=x)}if(u)if(p){p.sort(toe);for(let x=0;x<p.length;x++)a(p[x],d,!!c)}else a(u,d,!!c);let m,h;if(c)h=-1,m=c,c=null;else if(d<t.childCount)h=d,m=t.child(d++);else break;for(let x=0;x<l.length;x++)l[x].to<=r&&l.splice(x--,1);for(;o<i.length&&i[o].from<=r&&i[o].to>r;)l.push(i[o++]);let g=r+m.nodeSize;if(m.isText){let x=g;o<i.length&&i[o].from<x&&(x=i[o].from);for(let v=0;v<l.length;v++)l[v].to<x&&(x=l[v].to);x<g&&(c=m.cut(x-r),m=m.cut(0,x-r),g=x,h=-1)}else for(;o<i.length&&i[o].to<g;)o++;let y=m.isInline&&!m.isLeaf?l.filter(x=>!x.inline):l.slice();n(m,y,e.forChild(r,m),h),r=g}}
vendor: 7,315 bytes, line 17636
17636function noe(t){if(t.nodeName=="UL"||t.nodeName=="OL"){let e=t.style.cssText;t.style.cssText=e+"; list-style: square !important",window.getComputedStyle(t).listStyle,t.style.cssText=e}}function ioe(t,e,a,n){for(let i=0,r=0;i<t.childCount&&r<=n;){let o=t.child(i++),l=r;if(r+=o.nodeSize,!o.isText)continue;let c=o.text;for(;i<t.childCount;){let d=t.child(i++);if(r+=d.nodeSize,!d.isText)break;c+=d.text}if(r>=a){if(r>=n&&c.slice(n-e.length-l,n-l)==e)return n-e.length;let d=l<n?c.lastIndexOf(e,n-l-1):-1;if(d>=0&&d+e.length+l>=a)return l+d;if(a==n&&c.length>=n+e.length-l&&c.slice(n-l,n-l+e.length)==e)return n}}return-1}function Rb(t,e,a,n,i){let r=[];for(let o=0,l=0;o<t.length;o++){let c=t[o],d=l,u=l+=c.size;d>=a||u<=e?r.push(c):(d<e&&r.push(c.slice(0,e-d,n)),i&&(r.push(i),i=void 0),u>a&&r.push(c.slice(a-d,c.size,n)))}return r}function rS(t,e=null){let a=t.domSelectionRange(),n=t.state.doc;if(!a.focusNode)return null;let i=t.docView.nearestDesc(a.focusNode),r=i&&i.size==0,o=t.docView.posFromDOM(a.focusNode,a.focusOffset,1);if(o<0)return null;let l=n.resolve(o),c,d;if(Hg(a)){for(c=o;i&&!i.node;)i=i.parent;let p=i.node;if(i&&p.isAtom&&se.isSelectable(p)&&i.parent&&!(p.isInline&&Ire(a.focusNode,a.focusOffset,i.dom))){let m=i.posBefore;d=new se(o==m?l:n.resolve(m))}}else{if(a instanceof t.dom.ownerDocument.defaultView.Selection&&a.rangeCount>1){let p=o,m=o;for(let h=0;h<a.rangeCount;h++){let g=a.getRangeAt(h);p=Math.min(p,t.docView.posFromDOM(g.startContainer,g.startOffset,1)),m=Math.max(m,t.docView.posFromDOM(g.endContainer,g.endOffset,-1))}if(p<0)return null;[c,o]=m==t.state.selection.anchor?[m,p]:[p,m],l=n.resolve(o)}else c=t.docView.posFromDOM(a.anchorNode,a.anchorOffset,1);if(c<0)return null}let u=n.resolve(c);if(!d){let p=e=="pointer"||t.state.selection.head<l.pos&&!r?1:-1;d=oS(t,u,l,p)}return d}function WM(t){return t.editable?t.hasFocus():KM(t)&&document.activeElement&&document.activeElement.contains(t.dom)}function Pi(t,e=!1){let a=t.state.selection;if(GM(t,a),!!WM(t)){if(!e&&t.input.mouseDown&&t.input.mouseDown.allowDefault&&Nt){let n=t.domSelectionRange(),i=t.domObserver.currentSelection;if(n.anchorNode&&i.anchorNode&&is(n.anchorNode,n.anchorOffset,i.anchorNode,i.anchorOffset)){t.input.mouseDown.delayedSelectionSync=!0,t.domObserver.setCurSelection();return}}if(t.domObserver.disconnectSelection(),t.cursorWrapper)ooe(t);else{let{anchor:n,head:i}=a,r,o;Xj&&!(a instanceof ce)&&(a.$from.parent.inlineContent||(r=Yj(t,a.from)),!a.empty&&!a.$from.parent.inlineContent&&(o=Yj(t,a.to))),t.docView.setSelection(n,i,t,e),Xj&&(r&&Zj(r),o&&Zj(o)),a.visible?t.dom.classList.remove("ProseMirror-hideselection"):(t.dom.classList.add("ProseMirror-hideselection"),"onselectionchange"in document&&roe(t))}t.domObserver.setCurSelection(),t.domObserver.connectSelection()}}const Xj=Wt||Nt&&RM<63;function Yj(t,e){let{node:a,offset:n}=t.docView.domFromPos(e,0),i=n<a.childNodes.length?a.childNodes[n]:null,r=n?a.childNodes[n-1]:null;if(Wt&&i&&i.contentEditable=="false")return Y0(i);if((!i||i.contentEditable=="false")&&(!r||r.contentEditable=="false")){if(i)return Y0(i);if(r)return Y0(r)}}function Y0(t){return t.contentEditable="true",Wt&&t.draggable&&(t.draggable=!1,t.wasDraggable=!0),t}function Zj(t){t.contentEditable="false",t.wasDraggable&&(t.draggable=!0,t.wasDraggable=null)}function roe(t){let e=t.dom.ownerDocument;e.removeEventListener("selectionchange",t.input.hideSelectionGuard);let a=t.domSelectionRange(),n=a.anchorNode,i=a.anchorOffset;e.addEventListener("selectionchange",t.input.hideSelectionGuard=()=>{(a.anchorNode!=n||a.anchorOffset!=i)&&(e.removeEventListener("selectionchange",t.input.hideSelectionGuard),setTimeout(()=>{(!WM(t)||t.state.selection.visible)&&t.dom.classList.remove("ProseMirror-hideselection")},20))})}function ooe(t){let e=t.domSelection();if(!e)return;let a=t.cursorWrapper.dom,n=a.nodeName=="IMG";n?e.collapse(a.parentNode,zt(a)+1):e.collapse(a,0),!n&&!t.state.selection.visible&&Ra&&Lr<=11&&(a.disabled=!0,a.disabled=!1)}function GM(t,e){if(e instanceof se){let a=t.docView.descAt(e.from);a!=t.lastSelectedViewDesc&&(eT(t),a&&a.selectNode(),t.lastSelectedViewDesc=a)}else eT(t)}function eT(t){t.lastSelectedViewDesc&&(t.lastSelectedViewDesc.parent&&t.lastSelectedViewDesc.deselectNode(),t.lastSelectedViewDesc=void 0)}function oS(t,e,a,n){return t.someProp("createSelectionBetween",i=>i(t,e,a))||ce.between(e,a,n)}function tT(t){return t.editable&&!t.hasFocus()?!1:KM(t)}function KM(t){let e=t.domSelectionRange();if(!e.anchorNode)return!1;try{return t.dom.contains(e.anchorNode.nodeType==3?e.anchorNode.parentNode:e.anchorNode)&&(t.editable||t.dom.contains(e.focusNode.nodeType==3?e.focusNode.parentNode:e.focusNode))}catch{return!1}}function soe(t){let e=t.docView.domFromPos(t.state.selection.anchor,0),a=t.domSelectionRange();return is(e.node,e.offset,a.anchorNode,a.anchorOffset)}function Lb(t,e){let{$anchor:a,$head:n}=t.selection,i=e>0?a.max(n):a.min(n),r=i.parent.inlineContent?i.depth?t.doc.resolve(e>0?i.after():i.before()):null:i;return r&&xe.findFrom(r,e)}function nr(t,e){return t.dispatch(t.state.tr.setSelection(e).scrollIntoView()),!0}function aT(t,e,a){let n=t.state.selection;if(n instanceof ce)if(a.indexOf("s")>-1){let{$head:i}=n,r=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter;if(!r||r.isText||!r.isLeaf)return!1;let o=t.state.doc.resolve(i.pos+r.nodeSize*(e<0?-1:1));return nr(t,new ce(n.$anchor,o))}else if(n.empty){if(t.endOfTextblock(e>0?"forward":"backward")){let i=Lb(t.state,e);return i&&i instanceof se?nr(t,i):!1}else if(!(an&&a.indexOf("m")>-1)){let i=n.$head,r=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter,o;if(!r||r.isText)return!1;let l=e<0?i.pos-r.nodeSize:i.pos;return r.isAtom||(o=t.docView.descAt(l))&&!o.contentDOM?se.isSelectable(r)?nr(t,new se(e<0?t.state.doc.resolve(i.pos-r.nodeSize):i)):Ku?nr(t,new ce(t.state.doc.resolve(e<0?l:l+r.nodeSize))):!1:!1}}else return!1;else{if(n instanceof se&&n.node.isInline)return nr(t,new ce(e>0?n.$to:n.$from));{let i=Lb(t.state,e);return i?nr(t,i):!1}}}function ef(t){return t.nodeType==3?t.nodeValue.length:t.childNodes.length}function kd(t,e){let a=t.pmViewDesc;return a&&a.size==0&&(e<0||t.nextSibling||t.nodeName!="BR")}function Es(t,e){return e<0?loe(t):coe(t)}function loe(t){let e=t.domSelectionRange(),a=e.focusNode,n=e.focusOffset;if(!a)return;let i,r,o=!1;for(dn&&a.nodeType==1&&n<ef(a)&&kd(a.childNodes[n],-1)&&(o=!0);;)if(n>0){if(a.nodeType!=1)break;{let l=a.childNodes[n-1];if(kd(l,-1))i=a,r=--n;else if(l.nodeType==3)a=l,n=a.nodeValue.length;else break}}else{if(JM(a))break;{let l=a.previousSibling;for(;l&&kd(l,-1);)i=a.parentNode,r=zt(l),l=l.previousSibling;if(l)a=l,n=ef(a);else{if(a=a.parentNode,a==t.dom)break;n=0}}}o?Ob(t,a,n):i&&Ob(t,i,r)}function coe(t){let e=t.domSelectionRange(),a=e.focusNode,n=e.focusOffset;if(!a)return;let i=ef(a),r,o;for(;;)if(n<i){if(a.nodeType!=1)break;let l=a.childNodes[n];if(kd(l,1))r=a,o=++n;else break}else{if(JM(a))break;{let l=a.nextSibling;for(;l&&kd(l,1);)r=l.parentNode,o=zt(l)+1,l=l.nextSibling;if(l)a=l,n=0,i=ef(a);else{if(a=a.parentNode,a==t.dom)break;n=i=0}}}r&&Ob(t,r,o)}function JM(t){let e=t.pmViewDesc;return e&&e.node&&e.node.isBlock}function doe(t,e){for(;t&&e==t.childNodes.length&&!Gu(t);)e=zt(t)+1,t=t.parentNode;for(;t&&e<t.childNodes.length;){let a=t.childNodes[e];if(a.nodeType==3)return a;
vendor: 4,229 bytes, lines 17636-17639
17636if(a.nodeType==1&&a.contentEditable=="false")break;t=a,e=0}}function uoe(t,e){for(;t&&!e&&!Gu(t);)e=zt(t),t=t.parentNode;for(;t&&e;){let a=t.childNodes[e-1];if(a.nodeType==3)return a;if(a.nodeType==1&&a.contentEditable=="false")break;t=a,e=t.childNodes.length}}function Ob(t,e,a){if(e.nodeType!=3){let r,o;(o=doe(e,a))?(e=o,a=0):(r=uoe(e,a))&&(e=r,a=r.nodeValue.length)}let n=t.domSelection();if(!n)return;if(Hg(n)){let r=document.createRange();r.setEnd(e,a),r.setStart(e,a),n.removeAllRanges(),n.addRange(r)}else n.extend&&n.extend(e,a);t.domObserver.setCurSelection();let{state:i}=t;setTimeout(()=>{t.state==i&&Pi(t)},50)}function nT(t,e){let a=t.state.doc.resolve(e);if(!(Nt||LM)&&a.parent.inlineContent){let i=t.coordsAtPos(e);if(e>a.start()){let r=t.coordsAtPos(e-1),o=(r.top+r.bottom)/2;if(o>i.top&&o<i.bottom&&Math.abs(r.left-i.left)>1)return r.left<i.left?"ltr":"rtl"}if(e<a.end()){let r=t.coordsAtPos(e+1),o=(r.top+r.bottom)/2;if(o>i.top&&o<i.bottom&&Math.abs(r.left-i.left)>1)return r.left>i.left?"ltr":"rtl"}}return getComputedStyle(t.dom).direction=="rtl"?"rtl":"ltr"}function iT(t,e,a){let n=t.state.selection;if(n instanceof ce&&!n.empty||a.indexOf("s")>-1||an&&a.indexOf("m")>-1)return!1;let{$from:i,$to:r}=n;if(!i.parent.inlineContent||t.endOfTextblock(e<0?"up":"down")){let o=Lb(t.state,e);if(o&&o instanceof se)return nr(t,o)}if(!i.parent.inlineContent){let o=e<0?i:r,l=n instanceof Ua?xe.near(o,e):xe.findFrom(o,e);return l?nr(t,l):!1}return!1}function rT(t,e){if(!(t.state.selection instanceof ce))return!0;let{$head:a,$anchor:n,empty:i}=t.state.selection;if(!a.sameParent(n))return!0;if(!i)return!1;if(t.endOfTextblock(e>0?"forward":"backward"))return!0;let r=!a.textOffset&&(e<0?a.nodeBefore:a.nodeAfter);if(r&&!r.isText){let o=t.state.tr;return e<0?o.delete(a.pos-r.nodeSize,a.pos):o.delete(a.pos,a.pos+r.nodeSize),t.dispatch(o),!0}return!1}function oT(t,e,a){t.domObserver.stop(),e.contentEditable=a,t.domObserver.start()}function poe(t){if(!Wt||t.state.selection.$head.parentOffset>0)return!1;let{focusNode:e,focusOffset:a}=t.domSelectionRange();if(e&&e.nodeType==1&&a==0&&e.firstChild&&e.firstChild.contentEditable=="false"){let n=e.firstChild;oT(t,n,"true"),setTimeout(()=>oT(t,n,"false"),20)}return!1}function moe(t){let e="";return t.ctrlKey&&(e+="c"),t.metaKey&&(e+="m"),t.altKey&&(e+="a"),t.shiftKey&&(e+="s"),e}function hoe(t,e){let a=e.keyCode,n=moe(e);if(a==8||an&&a==72&&n=="c")return rT(t,-1)||Es(t,-1);if(a==46&&!e.shiftKey||an&&a==68&&n=="c")return rT(t,1)||Es(t,1);if(a==13||a==27)return!0;if(a==37||an&&a==66&&n=="c"){let i=a==37?nT(t,t.state.selection.from)=="ltr"?-1:1:-1;return aT(t,i,n)||Es(t,i)}else if(a==39||an&&a==70&&n=="c"){let i=a==39?nT(t,t.state.selection.from)=="ltr"?1:-1:1;return aT(t,i,n)||Es(t,i)}else{if(a==38||an&&a==80&&n=="c")return iT(t,-1,n)||Es(t,-1);if(a==40||an&&a==78&&n=="c")return poe(t)||iT(t,1,n)||Es(t,1);if(n==(an?"m":"c")&&(a==66||a==73||a==89||a==90))return!0}return!1}function sS(t,e){t.someProp("transformCopied",h=>{e=h(e,t)});let a=[],{content:n,openStart:i,openEnd:r}=e;for(;i>1&&r>1&&n.childCount==1&&n.firstChild.childCount==1;){i--,r--;let h=n.firstChild;a.push(h.type.name,h.attrs!=h.type.defaultAttrs?h.attrs:null),n=h.content}let o=t.someProp("clipboardSerializer")||fs.fromSchema(t.state.schema),l=t5(),c=l.createElement("div");c.appendChild(o.serializeFragment(n,{document:l}));let d=c.firstChild,u,p=0;for(;d&&d.nodeType==1&&(u=e5[d.nodeName.toLowerCase()]);){for(let h=u.length-1;h>=0;h--){let g=l.createElement(u[h]);for(;c.firstChild;)g.appendChild(c.firstChild);c.appendChild(g),p++}d=c.firstChild}d&&d.nodeType==1&&d.setAttribute("data-pm-slice",`${i} ${r}${p?` -${p}`:""} ${JSON.stringify(a)}`);let m=t.someProp("clipboardTextSerializer",h=>h(e,t))||e.content.textBetween(0,e.content.size,` 17637 17638`);return{dom:c,text:m,slice:e}}function QM(t,e,a,n,i){let r=i.parent.type.spec.code,o,l;if(!a&&!e)return null;let c=!!e&&(n||r||!a);if(c){if(t.someProp("transformPastedText",m=>{e=m(e,r||n,t)}),r)return l=new K(V.from(t.state.schema.text(e.replace(/\r\n?/g,` 17639`))),0,0),t.someProp("transformPasted",m=>{l=m(l,t,!0)}),l;let p=t.someProp("clipboardTextParser",m=>m(e,i,n,t));if(p)l=p;else{let m=i.marks(),{schema:h}=t.state,g=fs.fromSchema(h);
vendor: 8,907 bytes, line 17639
17639o=document.createElement("div"),e.split(/(?:\r\n?|\n)+/).forEach(y=>{let x=o.appendChild(document.createElement("p"));y&&x.appendChild(g.serializeNode(h.text(y,m)))})}}else t.someProp("transformPastedHTML",p=>{a=p(a,t)}),o=xoe(a),Ku&&voe(o);let d=o&&o.querySelector("[data-pm-slice]"),u=d&&/^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(d.getAttribute("data-pm-slice")||"");if(u&&u[3])for(let p=+u[3];p>0;p--){let m=o.firstChild;for(;m&&m.nodeType!=1;)m=m.nextSibling;if(!m)break;o=m}if(l||(l=(t.someProp("clipboardParser")||t.someProp("domParser")||Rr.fromSchema(t.state.schema)).parseSlice(o,{preserveWhitespace:!!(c||u),context:i,ruleFromNode(m){return m.nodeName=="BR"&&!m.nextSibling&&m.parentNode&&!foe.test(m.parentNode.nodeName)?{ignore:!0}:null}})),u)l=boe(sT(l,+u[1],+u[2]),u[4]);else if(l=K.maxOpen(goe(l.content,i),!0),l.openStart||l.openEnd){let p=0,m=0;for(let h=l.content.firstChild;p<l.openStart&&!h.type.spec.isolating;p++,h=h.firstChild);for(let h=l.content.lastChild;m<l.openEnd&&!h.type.spec.isolating;m++,h=h.lastChild);l=sT(l,p,m)}return t.someProp("transformPasted",p=>{l=p(l,t,c)}),l}const foe=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function goe(t,e){if(t.childCount<2)return t;for(let a=e.depth;a>=0;a--){let i=e.node(a).contentMatchAt(e.index(a)),r,o=[];if(t.forEach(l=>{if(!o)return;let c=i.findWrapping(l.type),d;if(!c)return o=null;if(d=o.length&&r.length&&YM(c,r,l,o[o.length-1],0))o[o.length-1]=d;else{o.length&&(o[o.length-1]=ZM(o[o.length-1],r.length));let u=XM(l,c);o.push(u),i=i.matchType(u.type),r=c}}),o)return V.from(o)}return t}function XM(t,e,a=0){for(let n=e.length-1;n>=a;n--)t=e[n].create(null,V.from(t));return t}function YM(t,e,a,n,i){if(i<t.length&&i<e.length&&t[i]==e[i]){let r=YM(t,e,a,n.lastChild,i+1);if(r)return n.copy(n.content.replaceChild(n.childCount-1,r));if(n.contentMatchAt(n.childCount).matchType(i==t.length-1?a.type:t[i+1]))return n.copy(n.content.append(V.from(XM(a,t,i+1))))}}function ZM(t,e){if(e==0)return t;let a=t.content.replaceChild(t.childCount-1,ZM(t.lastChild,e-1)),n=t.contentMatchAt(t.childCount).fillBefore(V.empty,!0);return t.copy(a.append(n))}function Mb(t,e,a,n,i,r){let o=e<0?t.firstChild:t.lastChild,l=o.content;return t.childCount>1&&(r=0),i<n-1&&(l=Mb(l,e,a,n,i+1,r)),i>=a&&(l=e<0?o.contentMatchAt(0).fillBefore(l,r<=i).append(l):l.append(o.contentMatchAt(o.childCount).fillBefore(V.empty,!0))),t.replaceChild(e<0?0:t.childCount-1,o.copy(l))}function sT(t,e,a){return e<t.openStart&&(t=new K(Mb(t.content,-1,e,t.openStart,0,t.openEnd),e,t.openEnd)),a<t.openEnd&&(t=new K(Mb(t.content,1,a,t.openEnd,0,0),t.openStart,a)),t}const e5={thead:["table"],tbody:["table"],tfoot:["table"],caption:["table"],colgroup:["table"],col:["table","colgroup"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","tbody","tr"]};let lT=null;function t5(){return lT||(lT=document.implementation.createHTMLDocument("title"))}let Z0=null;function yoe(t){let e=window.trustedTypes;return e?(Z0||(Z0=e.defaultPolicy||e.createPolicy("ProseMirrorClipboard",{createHTML:a=>a})),Z0.createHTML(t)):t}function xoe(t){let e=/^(\s*<meta [^>]*>)*/.exec(t);e&&(t=t.slice(e[0].length));let a=t5().createElement("div"),n=/<([a-z][^>\s]+)/i.exec(t),i;if((i=n&&e5[n[1].toLowerCase()])&&(t=i.map(r=>"<"+r+">").join("")+t+i.map(r=>"</"+r+">").reverse().join("")),a.innerHTML=yoe(t),i)for(let r=0;r<i.length;r++)a=a.querySelector(i[r])||a;return a}function voe(t){let e=t.querySelectorAll(Nt?"span:not([class]):not([style])":"span.Apple-converted-space");for(let a=0;a<e.length;a++){let n=e[a];n.childNodes.length==1&&n.textContent=="Â "&&n.parentNode&&n.parentNode.replaceChild(t.ownerDocument.createTextNode(" "),n)}}function boe(t,e){if(!t.size)return t;let a=t.content.firstChild.type.schema,n;try{n=JSON.parse(e)}catch{return t}let{content:i,openStart:r,openEnd:o}=t;for(let l=n.length-2;l>=0;l-=2){let c=a.nodes[n[l]];if(!c||c.hasRequiredAttrs())break;i=V.from(c.create(n[l+1],i)),r++,o++}return new K(i,r,o)}const ya={},xa={},woe={touchstart:!0,touchmove:!0};class koe{constructor(){this.shiftKey=!1,this.mouseDown=null,this.lastKeyCode=null,this.lastKeyCodeTime=0,this.lastClick={time:0,x:0,y:0,type:"",button:0},this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastIOSEnter=0,this.lastIOSEnterFallbackTimeout=-1,this.lastFocus=0,this.lastTouch=0,this.lastChromeDelete=0,this.composing=!1,this.compositionNode=null,this.composingTimeout=-1,this.compositionNodes=[],this.compositionEndedAt=-2e8,this.compositionID=1,this.badSafariComposition=!1,this.compositionPendingChanges=0,this.domChangeCount=0,this.eventHandlers=Object.create(null),this.hideSelectionGuard=null}}function Soe(t){for(let e in ya){let a=ya[e];t.dom.addEventListener(e,t.input.eventHandlers[e]=n=>{Aoe(t,n)&&!lS(t,n)&&(t.editable||!(n.type in xa))&&a(t,n)},woe[e]?{passive:!0}:void 0)}Wt&&t.dom.addEventListener("input",()=>null),Db(t)}function br(t,e){t.input.lastSelectionOrigin=e,t.input.lastSelectionTime=Date.now()}function _oe(t){t.domObserver.stop();for(let e in t.input.eventHandlers)t.dom.removeEventListener(e,t.input.eventHandlers[e]);clearTimeout(t.input.composingTimeout),clearTimeout(t.input.lastIOSEnterFallbackTimeout)}function Db(t){t.someProp("handleDOMEvents",e=>{for(let a in e)t.input.eventHandlers[a]||t.dom.addEventListener(a,t.input.eventHandlers[a]=n=>lS(t,n))})}function lS(t,e){return t.someProp("handleDOMEvents",a=>{let n=a[e.type];return n?n(t,e)||e.defaultPrevented:!1})}function Aoe(t,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let a=e.target;a!=t.dom;a=a.parentNode)if(!a||a.nodeType==11||a.pmViewDesc&&a.pmViewDesc.stopEvent(e))return!1;return!0}function Eoe(t,e){!lS(t,e)&&ya[e.type]&&(t.editable||!(e.type in xa))&&ya[e.type](t,e)}xa.keydown=(t,e)=>{let a=e;if(t.input.shiftKey=a.keyCode==16||a.shiftKey,!n5(t,a)&&(t.input.lastKeyCode=a.keyCode,t.input.lastKeyCodeTime=Date.now(),!(Ai&&Nt&&a.keyCode==13)))if(a.keyCode!=229&&t.domObserver.forceFlush(),Ll&&a.keyCode==13&&!a.ctrlKey&&!a.altKey&&!a.metaKey){let n=Date.now();t.input.lastIOSEnter=n,t.input.lastIOSEnterFallbackTimeout=setTimeout(()=>{t.input.lastIOSEnter==n&&(t.someProp("handleKeyDown",i=>i(t,yo(13,"Enter"))),t.input.lastIOSEnter=0)},200)}else t.someProp("handleKeyDown",n=>n(t,a))||hoe(t,a)?a.preventDefault():br(t,"key")};xa.keyup=(t,e)=>{e.keyCode==16&&(t.input.shiftKey=!1)};xa.keypress=(t,e)=>{let a=e;if(n5(t,a)||!a.charCode||a.ctrlKey&&!a.altKey||an&&a.metaKey)return;if(t.someProp("handleKeyPress",i=>i(t,a))){a.preventDefault();return}let n=t.state.selection;if(!(n instanceof ce)||!n.$from.sameParent(n.$to)){let i=String.fromCharCode(a.charCode),r=()=>t.state.tr.insertText(i).scrollIntoView();!/[\r\n]/.test(i)&&!t.someProp("handleTextInput",o=>o(t,n.$from.pos,n.$to.pos,i,r))&&t.dispatch(r()),a.preventDefault()}};function Bg(t){return{left:t.clientX,top:t.clientY}}function Coe(t,e){let a=e.x-t.clientX,n=e.y-t.clientY;return a*a+n*n<100}function cS(t,e,a,n,i){if(n==-1)return!1;let r=t.state.doc.resolve(n);for(let o=r.depth+1;o>0;o--)if(t.someProp(e,l=>o>r.depth?l(t,a,r.nodeAfter,r.before(o),i,!0):l(t,a,r.node(o),r.before(o),i,!1)))return!0;return!1}function ul(t,e,a){if(t.focused||t.focus(),t.state.selection.eq(e))return;let n=t.state.tr.setSelection(e);n.setMeta("pointer",!0),t.dispatch(n)}function joe(t,e){if(e==-1)return!1;let a=t.state.doc.resolve(e),n=a.nodeAfter;return n&&n.isAtom&&se.isSelectable(n)?(ul(t,new se(a)),!0):!1}function Toe(t,e){if(e==-1)return!1;let a=t.state.selection,n,i;a instanceof se&&(n=a.node);let r=t.state.doc.resolve(e);for(let o=r.depth+1;o>0;o--){let l=o>r.depth?r.nodeAfter:r.node(o);if(se.isSelectable(l)){n&&a.$from.depth>0&&o>=a.$from.depth&&r.before(a.$from.depth+1)==a.$from.pos?i=r.before(a.$from.depth):i=r.before(o);break}}return i!=null?(ul(t,se.create(t.state.doc,i)),!0):!1}function Noe(t,e,a,n,i){return cS(t,"handleClickOn",e,a,n)||t.someProp("handleClick",r=>r(t,e,n))||(i?Toe(t,a):joe(t,a))}function Ioe(t,e,a,n){return cS(t,"handleDoubleClickOn",e,a,n)||t.someProp("handleDoubleClick",i=>i(t,e,n))}function Poe(t,e,a,n){return cS(t,"handleTripleClickOn",e,a,n)||t.someProp("handleTripleClick",i=>i(t,e,n))||Roe(t,a,n)}function Roe(t,e,a){if(a.button!=0)return!1;let n=t.state.doc;if(e==-1)return n.inlineContent?(ul(t,ce.create(n,0,n.content.size)),!0):!1;let i=n.resolve(e);for(let r=i.depth+1;r>0;r--){let o=r>i.depth?i.nodeAfter:i.node(r),l=i.before(r);if(o.inlineContent)ul(t,ce.create(n,l+1,l+1+o.content.size));else if(se.isSelectable(o))ul(t,se.create(n,l));else continue;return!0}}function dS(t){return tf(t)}const a5=an?"metaKey":"ctrlKey";ya.mousedown=(t,e)=>{let a=e;t.input.shiftKey=a.shiftKey;let n=dS(t),i=Date.now(),r="singleClick";i-t.input.lastClick.time<500&&Coe(a,t.input.lastClick)&&!a[a5]&&t.input.lastClick.button==a.button&&(t.input.lastClick.type=="singleClick"?r="doubleClick":t.input.last
vendor: 18,917 bytes, line 17639
17639Click.type=="doubleClick"&&(r="tripleClick")),t.input.lastClick={time:i,x:a.clientX,y:a.clientY,type:r,button:a.button};let o=t.posAtCoords(Bg(a));o&&(r=="singleClick"?(t.input.mouseDown&&t.input.mouseDown.done(),t.input.mouseDown=new Loe(t,o,a,!!n)):(r=="doubleClick"?Ioe:Poe)(t,o.pos,o.inside,a)?a.preventDefault():br(t,"pointer"))};class Loe{constructor(e,a,n,i){this.view=e,this.pos=a,this.event=n,this.flushed=i,this.delayedSelectionSync=!1,this.mightDrag=null,this.startDoc=e.state.doc,this.selectNode=!!n[a5],this.allowDefault=n.shiftKey;let r,o;if(a.inside>-1)r=e.state.doc.nodeAt(a.inside),o=a.inside;else{let u=e.state.doc.resolve(a.pos);r=u.parent,o=u.depth?u.before():0}const l=i?null:n.target,c=l?e.docView.nearestDesc(l,!0):null;this.target=c&&c.nodeDOM.nodeType==1?c.nodeDOM:null;let{selection:d}=e.state;(n.button==0&&r.type.spec.draggable&&r.type.spec.selectable!==!1||d instanceof se&&d.from<=o&&d.to>o)&&(this.mightDrag={node:r,pos:o,addAttr:!!(this.target&&!this.target.draggable),setUneditable:!!(this.target&&dn&&!this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout(()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")},20),this.view.domObserver.start()),e.root.addEventListener("mouseup",this.up=this.up.bind(this)),e.root.addEventListener("mousemove",this.move=this.move.bind(this)),br(e,"pointer")}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout(()=>Pi(this.view)),this.view.input.mouseDown=null}up(e){if(this.done(),!this.view.dom.contains(e.target))return;let a=this.pos;this.view.state.doc!=this.startDoc&&(a=this.view.posAtCoords(Bg(e))),this.updateAllowDefault(e),this.allowDefault||!a?br(this.view,"pointer"):Noe(this.view,a.pos,a.inside,e,this.selectNode)?e.preventDefault():e.button==0&&(this.flushed||Wt&&this.mightDrag&&!this.mightDrag.node.isAtom||Nt&&!this.view.state.selection.visible&&Math.min(Math.abs(a.pos-this.view.state.selection.from),Math.abs(a.pos-this.view.state.selection.to))<=2)?(ul(this.view,xe.near(this.view.state.doc.resolve(a.pos))),e.preventDefault()):br(this.view,"pointer")}move(e){this.updateAllowDefault(e),br(this.view,"pointer"),e.buttons==0&&this.done()}updateAllowDefault(e){!this.allowDefault&&(Math.abs(this.event.x-e.clientX)>4||Math.abs(this.event.y-e.clientY)>4)&&(this.allowDefault=!0)}}ya.touchstart=t=>{t.input.lastTouch=Date.now(),dS(t),br(t,"pointer")};ya.touchmove=t=>{t.input.lastTouch=Date.now(),br(t,"pointer")};ya.contextmenu=t=>dS(t);function n5(t,e){return t.composing?!0:Wt&&Math.abs(e.timeStamp-t.input.compositionEndedAt)<500?(t.input.compositionEndedAt=-2e8,!0):!1}const Ooe=Ai?5e3:-1;xa.compositionstart=xa.compositionupdate=t=>{if(!t.composing){t.domObserver.flush();let{state:e}=t,a=e.selection.$to;if(e.selection instanceof ce&&(e.storedMarks||!a.textOffset&&a.parentOffset&&a.nodeBefore.marks.some(n=>n.type.spec.inclusive===!1)||Nt&&LM&&Moe(t)))t.markCursor=t.state.storedMarks||a.marks(),tf(t,!0),t.markCursor=null;else if(tf(t,!e.selection.empty),dn&&e.selection.empty&&a.parentOffset&&!a.textOffset&&a.nodeBefore.marks.length){let n=t.domSelectionRange();for(let i=n.focusNode,r=n.focusOffset;i&&i.nodeType==1&&r!=0;){let o=r<0?i.lastChild:i.childNodes[r-1];if(!o)break;if(o.nodeType==3){let l=t.domSelection();l&&l.collapse(o,o.nodeValue.length);break}else i=o,r=-1}}t.input.composing=!0}i5(t,Ooe)};function Moe(t){let{focusNode:e,focusOffset:a}=t.domSelectionRange();if(!e||e.nodeType!=1||a>=e.childNodes.length)return!1;let n=e.childNodes[a];return n.nodeType==1&&n.contentEditable=="false"}xa.compositionend=(t,e)=>{t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=e.timeStamp,t.input.compositionPendingChanges=t.domObserver.pendingRecords().length?t.input.compositionID:0,t.input.compositionNode=null,t.input.badSafariComposition?t.domObserver.forceFlush():t.input.compositionPendingChanges&&Promise.resolve().then(()=>t.domObserver.flush()),t.input.compositionID++,i5(t,20))};function i5(t,e){clearTimeout(t.input.composingTimeout),e>-1&&(t.input.composingTimeout=setTimeout(()=>tf(t),e))}function r5(t){for(t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=qoe());t.input.compositionNodes.length>0;)t.input.compositionNodes.pop().markParentsDirty()}function Doe(t){let e=t.domSelectionRange();if(!e.focusNode)return null;let a=Tre(e.focusNode,e.focusOffset),n=Nre(e.focusNode,e.focusOffset);if(a&&n&&a!=n){let i=n.pmViewDesc,r=t.domObserver.lastChangedTextNode;if(a==r||n==r)return r;if(!i||!i.isText(n.nodeValue))return n;if(t.input.compositionNode==n){let o=a.pmViewDesc;if(!(!o||!o.isText(a.nodeValue)))return n}}return a||n}function qoe(){let t=document.createEvent("Event");return t.initEvent("event",!0,!0),t.timeStamp}function tf(t,e=!1){if(!(Ai&&t.domObserver.flushingSoon>=0)){if(t.domObserver.forceFlush(),r5(t),e||t.docView&&t.docView.dirty){let a=rS(t),n=t.state.selection;return a&&!a.eq(n)?t.dispatch(t.state.tr.setSelection(a)):(t.markCursor||e)&&!n.$from.node(n.$from.sharedDepth(n.to)).inlineContent?t.dispatch(t.state.tr.deleteSelection()):t.updateState(t.state),!0}return!1}}function zoe(t,e){if(!t.dom.parentNode)return;let a=t.dom.parentNode.appendChild(document.createElement("div"));a.appendChild(e),a.style.cssText="position: fixed; left: -10000px; top: 10px";let n=getSelection(),i=document.createRange();i.selectNodeContents(e),t.dom.blur(),n.removeAllRanges(),n.addRange(i),setTimeout(()=>{a.parentNode&&a.parentNode.removeChild(a),t.focus()},50)}const hu=Ra&&Lr<15||Ll&&Lre<604;ya.copy=xa.cut=(t,e)=>{let a=e,n=t.state.selection,i=a.type=="cut";if(n.empty)return;let r=hu?null:a.clipboardData,o=n.content(),{dom:l,text:c}=sS(t,o);r?(a.preventDefault(),r.clearData(),r.setData("text/html",l.innerHTML),r.setData("text/plain",c)):zoe(t,l),i&&t.dispatch(t.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))};function Voe(t){return t.openStart==0&&t.openEnd==0&&t.content.childCount==1?t.content.firstChild:null}function Hoe(t,e){if(!t.dom.parentNode)return;let a=t.input.shiftKey||t.state.selection.$from.parent.type.spec.code,n=t.dom.parentNode.appendChild(document.createElement(a?"textarea":"div"));a||(n.contentEditable="true"),n.style.cssText="position: fixed; left: -10000px; top: 10px",n.focus();let i=t.input.shiftKey&&t.input.lastKeyCode!=45;setTimeout(()=>{t.focus(),n.parentNode&&n.parentNode.removeChild(n),a?fu(t,n.value,null,i,e):fu(t,n.textContent,n.innerHTML,i,e)},50)}function fu(t,e,a,n,i){let r=QM(t,e,a,n,t.state.selection.$from);if(t.someProp("handlePaste",c=>c(t,i,r||K.empty)))return!0;if(!r)return!1;let o=Voe(r),l=o?t.state.tr.replaceSelectionWith(o,n):t.state.tr.replaceSelection(r);return t.dispatch(l.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}function o5(t){let e=t.getData("text/plain")||t.getData("Text");if(e)return e;let a=t.getData("text/uri-list");return a?a.replace(/\r?\n/g," "):""}xa.paste=(t,e)=>{let a=e;if(t.composing&&!Ai)return;let n=hu?null:a.clipboardData,i=t.input.shiftKey&&t.input.lastKeyCode!=45;n&&fu(t,o5(n),n.getData("text/html"),i,a)?a.preventDefault():Hoe(t,a)};class s5{constructor(e,a,n){this.slice=e,this.move=a,this.node=n}}const Foe=an?"altKey":"ctrlKey";function l5(t,e){let a=t.someProp("dragCopies",n=>!n(e));return a??!e[Foe]}ya.dragstart=(t,e)=>{let a=e,n=t.input.mouseDown;if(n&&n.done(),!a.dataTransfer)return;let i=t.state.selection,r=i.empty?null:t.posAtCoords(Bg(a)),o;if(!(r&&r.pos>=i.from&&r.pos<=(i instanceof se?i.to-1:i.to))){if(n&&n.mightDrag)o=se.create(t.state.doc,n.mightDrag.pos);else if(a.target&&a.target.nodeType==1){let p=t.docView.nearestDesc(a.target,!0);p&&p.node.type.spec.draggable&&p!=t.docView&&(o=se.create(t.state.doc,p.posBefore))}}let l=(o||t.state.selection).content(),{dom:c,text:d,slice:u}=sS(t,l);(!a.dataTransfer.files.length||!Nt||RM>120)&&a.dataTransfer.clearData(),a.dataTransfer.setData(hu?"Text":"text/html",c.innerHTML),a.dataTransfer.effectAllowed="copyMove",hu||a.dataTransfer.setData("text/plain",d),t.dragging=new s5(u,l5(t,a),o)};ya.dragend=t=>{let e=t.dragging;window.setTimeout(()=>{t.dragging==e&&(t.dragging=null)},50)};xa.dragover=xa.dragenter=(t,e)=>e.preventDefault();xa.drop=(t,e)=>{try{Boe(t,e,t.dragging)}finally{t.dragging=null}};function Boe(t,e,a){if(!e.dataTransfer)return;let n=t.posAtCoords(Bg(e));if(!n)return;let i=t.state.doc.resolve(n.pos),r=a&&a.slice;r?t.someProp("transformPasted",h=>{r=h(r,t,!1)}):r=QM(t,o5(e.dataTransfer),hu?null:e.dataTransfer.getData("text/html"),!1,i);let o=!!(a&&l5(t,e));if(t.someProp("handleDrop",h=>h(t,e,r||K.empty,o))){e.preventDefault();return}if(!r)return;e.preventDefault();let l=r?pM(t.state.doc,i.pos,r):i.pos;l==null&&(l=i.pos);let c=t.state.tr;if(o){let{node:h}=a;h?h.replace(c):c.deleteSelection()}let d=c.mapping.map(l),u=r.openStart==0&&r.openEnd==0&&r.content.childCount==1,p=c.doc;if(u?c.replaceRangeWith(d,d,r.content.firstChild):c.replaceRange(d,d,r),c.doc.eq(p))return;let m=c.doc.resolve(d);if(u&&se.isSelectable(r.content.firstChild)&&m.nodeAfter&&m.nodeAfter.sameMarkup(r.content.firstChild))c.setSelection(new se(m));else{let h=c.mapping.map(l);c.mapping.maps[c.mapping.maps.length-1].forEach((g,y,x,v)=>h=v),c.setSelection(oS(t,m,c.doc.resolve(h)))}t.focus(),t.dispatch(c.setMeta("uiEvent","drop"))}ya.focus=t=>{t.input.lastFocus=Date.now(),t.focused||(t.domObserver.stop(),t.dom.classList.add("ProseMirror-focused"),t.domObserver.start(),t.focused=!0,setTimeout(()=>{t.docView&&t.hasFocus()&&!t.domObserver.currentSelection.eq(t.domSelectionRange())&&Pi(t)},20))};ya.blur=(t,e)=>{let a=e;t.focused&&(t.domObserver.stop(),t.dom.classList.remove("ProseMirror-focused"),t.domObserver.start(),a.relatedTarget&&t.dom.contains(a.relatedTarget)&&t.domObserver.currentSelection.clear(),t.focused=!1)};ya.beforeinput=(t,e)=>{if(Nt&&Ai&&e.inputType=="deleteContentBackward"){t.domObserver.flushSoon();let{domChangeCount:n}=t.input;setTimeout(()=>{if(t.input.domChangeCount!=n||(t.dom.blur(),t.focus(),t.someProp("handleKeyDown",r=>r(t,yo(8,"Backspace")))))return;let{$cursor:i}=t.state.selection;i&&i.pos>0&&t.dispatch(t.state.tr.delete(i.pos-1,i.pos).scrollIntoView())},50)}};for(let t in xa)ya[t]=xa[t];function gu(t,e){if(t==e)return!0;for(let a in t)if(t[a]!==e[a])return!1;for(let a in e)if(!(a in t))return!1;return!0}class af{constructor(e,a){this.toDOM=e,this.spec=a||Vo,this.side=this.spec.side||0}map(e,a,n,i){let{pos:r,deleted:o}=e.mapResult(a.from+i,this.side<0?-1:1);return o?null:new ha(r-n,r-n,this)}valid(){return!0}eq(e){return this==e||e instanceof af&&(this.spec.key&&this.spec.key==e.spec.key||this.toDOM==e.toDOM&&gu(this.spec,e.spec))}destroy(e){this.spec.destroy&&this.spec.destroy(e)}}class Mr{constructor(e,a){this.attrs=e,this.spec=a||Vo}map(e,a,n,i){let r=e.map(a.from+i,this.spec.inclusiveStart?-1:1)-n,o=e.map(a.to+i,this.spec.inclusiveEnd?1:-1)-n;return r>=o?null:new ha(r,o,this)}valid(e,a){return a.from<a.to}eq(e){return this==e||e instanceof Mr&&gu(this.attrs,e.attrs)&&gu(this.spec,e.spec)}static is(e){return e.type instanceof Mr}destroy(){}}class uS{constructor(e,a){this.attrs=e,this.spec=a||Vo}map(e,a,n,i){let r=e.mapResult(a.from+i,1);if(r.deleted)return null;let o=e.mapResult(a.to+i,-1);return o.deleted||o.pos<=r.pos?null:new ha(r.pos-n,o.pos-n,this)}valid(e,a){let{index:n,offset:i}=e.content.findIndex(a.from),r;return i==a.from&&!(r=e.child(n)).isText&&i+r.nodeSize==a.to}eq(e){return this==e||e instanceof uS&&gu(this.attrs,e.attrs)&&gu(this.spec,e.spec)}destroy(){}}class ha{constructor(e,a,n){this.from=e,this.to=a,this.type=n}copy(e,a){return new ha(e,a,this.type)}eq(e,a=0){return this.type.eq(e.type)&&this.from+a==e.from&&this.to+a==e.to}map(e,a,n){return this.type.map(e,this,a,n)}static widget(e,a,n){return new ha(e,e,new af(a,n))}static inline(e,a,n,i){return new ha(e,a,new Mr(n,i))}static node(e,a,n,i){return new ha(e,a,new uS(n,i))}get spec(){return this.type.spec}get inline(){return this.type instanceof Mr}get widget(){return this.type instanceof af}}const Is=[],Vo={};class Qe{constructor(e,a){this.local=e.length?e:Is,this.children=a.length?a:Is}static create(e,a){return a.length?nf(a,e,0,Vo):Zt}find(e,a,n){let i=[];return this.findInner(e??0,a??1e9,i,0,n),i}findInner(e,a,n,i,r){for(let o=0;o<this.local.length;o++){let l=this.local[o];l.from<=a&&l.to>=e&&(!r||r(l.spec))&&n.push(l.copy(l.from+i,l.to+i))}for(let o=0;o<this.children.length;o+=3)if(this.children[o]<a&&this.children[o+1]>e){let l=this.children[o]+1;this.children[o+2].findInner(e-l,a-l,n,i+l,r)}}map(e,a,n){return this==Zt||e.maps.length==0?this:this.mapInner(e,a,0,0,n||Vo)}mapInner(e,a,n,i,r){let o;for(let l=0;l<this.local.length;l++){let c=this.local[l].map(e,n,i);c&&c.type.valid(a,c)?(o||(o=[])).push(c):r.onRemove&&r.onRemove(this.local[l].spec)}return this.children.length?Uoe(this.children,o||[],e,a,n,i,r):o?new Qe(o.sort(Ho),Is):Zt}add(e,a){return a.length?this==Zt?Qe.create(e,a):this.addInner(e,a,0):this}addInner(e,a,n){let i,r=0;e.forEach((l,c)=>{let d=c+n,u;if(u=d5(a,l,d)){for(i||(i=this.children.slice());r<i.length&&i[r]<c;)r+=3;i[r]==c?i[r+2]=i[r+2].addInner(l,u,d+1):i.splice(r,0,c,c+l.nodeSize,nf(u,l,d+1,Vo)),r+=3}});let o=c5(r?u5(a):a,-n);for(let l=0;l<o.length;l++)o[l].type.valid(e,o[l])||o.splice(l--,1);return new Qe(o.length?this.local.concat(o).sort(Ho):this.local,i||this.children)}remove(e){return e.length==0||this==Zt?this:this.removeInner(e,0)}removeInner(e,a){let n=this.children,i=this.local;for(let r=0;r<n.length;r+=3){let o,l=n[r]+a,c=n[r+1]+a;for(let u=0,p;u<e.length;u++)(p=e[u])&&p.from>l&&p.to<c&&(e[u]=null,(o||(o=[])).push(p));if(!o)continue;n==this.children&&(n=this.children.slice());let d=n[r+2].removeInner(o,l+1);d!=Zt?n[r+2]=d:(n.splice(r,3),r-=3)}if(i.length){for(let r=0,o;r<e.length;r++)if(o=e[r])for(let l=0;l<i.length;l++)i[l].eq(o,a)&&(i==this.local&&(i=this.local.slice()),i.splice(l--,1))}return n==this.children&&i==this.local?this:i.length||n.length?new Qe(i,n):Zt}forChild(e,a){if(this==Zt)return this;if(a.isLeaf)return Qe.empty;let n,i;for(let l=0;l<this.children.length;l+=3)if(this.children[l]>=e){this.children[l]==e&&(n=this.children[l+2]);break}let r=e+1,o=r+a.content.size;for(let l=0;l<this.local.length;l++){let c=this.local[l];if(c.from<o&&c.to>r&&c.type instanceof Mr){let d=Math.max(r,c.from)-r,u=Math.min(o,c.to)-r;d<u&&(i||(i=[])).push(c.copy(d,u))}}if(i){let l=new Qe(i.sort(Ho),Is);return n?new pr([l,n]):l}return n||Zt}eq(e){if(this==e)return!0;if(!(e instanceof Qe)||this.local.length!=e.local.length||this.children.length!=e.children.length)return!1;for(let a=0;a<this.local.length;a++)if(!this.local[a].eq(e.local[a]))return!1;for(let a=0;a<this.children.length;a+=3)if(this.children[a]!=e.children[a]||this.children[a+1]!=e.children[a+1]||!this.children[a+2].eq(e.children[a+2]))return!1;return!0}locals(e){return pS(this.localsInner(e))}localsInner(e){if(this==Zt)return Is;if(e.inlineContent||!this.local.some(Mr.is))return this.local;let a=[];for(let n=0;n<this.local.length;n++)this.local[n].type instanceof Mr||a.push(this.local[n]);return a}forEachSet(e){e(this)}}Qe.empty=new Qe([],[]);Qe.removeOverlap=pS;const Zt=Qe.empty;class pr{constructor(e){this.members=e}map(e,a){const n=this.members.map(i=>i.map(e,a,Vo));return pr.from(n)}forChild(e,a){if(a.isLeaf)return Qe.empty;let n=[];for(let i=0;i<this.members.length;i++){let r=this.members[i].forChild(e,a);r!=Zt&&(r instanceof pr?n=n.concat(r.members):n.push(r))}return pr.from(n)}eq(e){if(!(e instanceof pr)||e.members.length!=this.members.length)return!1;for(let a=0;a<this.members.length;a++)if(!this.members[a].eq(e.members[a]))return!1;return!0}locals(e){let a,n=!0;for(let i=0;i<this.members.length;i++){let r=this.members[i].localsInner(e);if(r.length)if(!a)a=r;else{n&&(a=a.slice(),n=!1);for(let o=0;o<r.length;o++)a.push(r[o])}}return a?pS(n?a:a.sort(Ho)):Is}static from(e){switch(e.length){case 0:return Zt;case 1:return e[0];default:return new pr(e.every(a=>a instanceof Qe)?e:e.reduce((a,n)=>a.concat(n instanceof Qe?n:n.members),[]))}}forEachSet(e){for(let a=0;a<this.members.length;a++)this.members[a].forEachSet(e)}}function Uoe(t,e,a,n,i,r,o){let l=t.slice();for(let d=0,u=r;d<a.maps.length;d++){let p=0;a.maps[d].forEach((m,h,g,y)=>{let x=y-g-(h-m);for(let v=0;v<l.length;v+=3){let w=l[v+1];if(w<0||m>w+u-p)continue;let S=l[v]+u-p;h>=S?l[v+1]=m<=S?-2:-1:m>=u&&x&&(l[v]+=x,l[v+1]+=x)}p+=x}),u=a.maps[d].map(u,-1)}let c=!1;for(let d=0;d<l.length;d+=3)if(l[d+1]<0){if(l[d+1]==-2){c=!0,l[d+1]=-1;continue}let u=a.map(t[d]+r),p=u-i;if(p<0||p>=n.content.size){c=!0;continue}let m=a.map(t[d+1]+r,-1),h=m-i,{index:g,offset:y}=n.content.findIndex(p),x=n.maybeChild(g);if(x&&y==p&&y+x.nodeSize==h){let v=l[d+2].mapInner(a,x,u+1,t[d]+r+1,o);v!=Zt?(l[d]=p,l[d+1]=h,l[d+2]=v):(l[d+1]=-2,c=!0)}else c=!0}if(c){let d=$oe(l,t,e,a,i,r,o),u=nf(d,n,0,o);e=u.local;for(let p=0;p<l.length;p+=3)l[p+1]<0&&(l.splice(p,3),p-=3);for(let p=0,m=0;p<u.children.length;p+=3){let h=u.children[p];for(;m<l.length&&l[m]<h;)m+=3;l.splice(m,0,u.children[p],u.children[p+1],u.children[p+2])}}return new Qe(e.sort(Ho),l)}function c5(t,e){if(!e||!t.length)return t;let a=[];for(let n=0;n<t.length;n++){let i=t[n];a.push(new ha(i.from+e,i.to+e,i.type))}return a}function $oe(t,e,a,n,i,r,o){function l(c,d){for(let u=0;u<c.local.length;u++){let p=c.local[u].map(n,i,d);p?a.push(p):o.onRemove&&o.onRemove(c.local[u].spec)}for(let u=0;u<c.children.length;u+=3)l(c.children[u+2],c.children[u]+d+1)}for(let c=0;c<t.length;c+=3)t[c+1]==-1&&l(t[c+2],e[c]+r+1);return a}function d5(t,e,a){if(e.isLeaf)return null;let n=a+e.nodeSize,i=null;for(let r=0,o;r<t.length;r++)(o=t[r])&&o.from>a&&o.to<n&&((i||(i=[])).push(o),t[r]=null);return i}function u5(t){let e=[];for(let a=0;a<t.length;a++)t[a]!=null&&e.push(t[a]);return e}function nf(t,e,a,n){let i=[],r=!1;e.forEach((l,c)=>{let d=d5(t,l,c+a);if(d){r=!0;let u=nf(d,l,a+c+1,n);u!=Zt&&i.push(c,c+l.nodeSize,u)}});let o=c5(r?u5(t):t,-a).sort(Ho);for(let l=0;l<o.length;l++)o[l].type.valid(e,o[l])||(n.onRemove&&n.onRemove(o[l].spec),o.splice(l--,1));return o.length||i.length?new Qe(o,i):Zt}function Ho(t,e){return t.from-e.from||t.to-e.to}function pS(t){let e=t;for(let a=0;a<e.length-1;a++){let n=e[a];if(n.from!=n.to)for(let i=a+1;i<e.length;i++){let r=e[i];if(r.from==n.from){r.to!=n.to&&(e==t&&(e=t.slice()),e[i]=r.copy(r.from,n.to),cT(e,i+1,r.copy(n.to,r.to)));continue}else{r.from<n.to&&(e==t&&(e=t.slice()),e[a]=n.copy(n.from,r.from),cT(e,i,n.copy(r.from,n.to))
vendor: 8,710 bytes, line 17639
17639);break}}}return e}function cT(t,e,a){for(;e<t.length&&Ho(a,t[e])>0;)e++;t.splice(e,0,a)}function ex(t){let e=[];return t.someProp("decorations",a=>{let n=a(t.state);n&&n!=Zt&&e.push(n)}),t.cursorWrapper&&e.push(Qe.create(t.state.doc,[t.cursorWrapper.deco])),pr.from(e)}const Woe={childList:!0,characterData:!0,characterDataOldValue:!0,attributes:!0,attributeOldValue:!0,subtree:!0},Goe=Ra&&Lr<=11;class Koe{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(e){this.anchorNode=e.anchorNode,this.anchorOffset=e.anchorOffset,this.focusNode=e.focusNode,this.focusOffset=e.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(e){return e.anchorNode==this.anchorNode&&e.anchorOffset==this.anchorOffset&&e.focusNode==this.focusNode&&e.focusOffset==this.focusOffset}}class Joe{constructor(e,a){this.view=e,this.handleDOMChange=a,this.queue=[],this.flushingSoon=-1,this.observer=null,this.currentSelection=new Koe,this.onCharData=null,this.suppressingSelectionUpdates=!1,this.lastChangedTextNode=null,this.observer=window.MutationObserver&&new window.MutationObserver(n=>{for(let i=0;i<n.length;i++)this.queue.push(n[i]);Ra&&Lr<=11&&n.some(i=>i.type=="childList"&&i.removedNodes.length||i.type=="characterData"&&i.oldValue.length>i.target.nodeValue.length)?this.flushSoon():Wt&&e.composing&&n.some(i=>i.type=="childList"&&i.target.nodeName=="TR")?(e.input.badSafariComposition=!0,this.flushSoon()):this.flush()}),Goe&&(this.onCharData=n=>{this.queue.push({target:n.target,type:"characterData",oldValue:n.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this)}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout(()=>{this.flushingSoon=-1,this.flush()},20))}forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}start(){this.observer&&(this.observer.takeRecords(),this.observer.observe(this.view.dom,Woe)),this.onCharData&&this.view.dom.addEventListener("DOMCharacterDataModified",this.onCharData),this.connectSelection()}stop(){if(this.observer){let e=this.observer.takeRecords();if(e.length){for(let a=0;a<e.length;a++)this.queue.push(e[a]);window.setTimeout(()=>this.flush(),20)}this.observer.disconnect()}this.onCharData&&this.view.dom.removeEventListener("DOMCharacterDataModified",this.onCharData),this.disconnectSelection()}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout(()=>this.suppressingSelectionUpdates=!1,50)}onSelectionChange(){if(tT(this.view)){if(this.suppressingSelectionUpdates)return Pi(this.view);if(Ra&&Lr<=11&&!this.view.state.selection.empty){let e=this.view.domSelectionRange();if(e.focusNode&&is(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset))return this.flushSoon()}this.flush()}}setCurSelection(){this.currentSelection.set(this.view.domSelectionRange())}ignoreSelectionChange(e){if(!e.focusNode)return!0;let a=new Set,n;for(let r=e.focusNode;r;r=Rl(r))a.add(r);for(let r=e.anchorNode;r;r=Rl(r))if(a.has(r)){n=r;break}let i=n&&this.view.docView.nearestDesc(n);if(i&&i.ignoreMutation({type:"selection",target:n.nodeType==3?n.parentNode:n}))return this.setCurSelection(),!0}pendingRecords(){if(this.observer)for(let e of this.observer.takeRecords())this.queue.push(e);return this.queue}flush(){let{view:e}=this;if(!e.docView||this.flushingSoon>-1)return;let a=this.pendingRecords();a.length&&(this.queue=[]);let n=e.domSelectionRange(),i=!this.suppressingSelectionUpdates&&!this.currentSelection.eq(n)&&tT(e)&&!this.ignoreSelectionChange(n),r=-1,o=-1,l=!1,c=[];if(e.editable)for(let u=0;u<a.length;u++){let p=this.registerMutation(a[u],c);p&&(r=r<0?p.from:Math.min(p.from,r),o=o<0?p.to:Math.max(p.to,o),p.typeOver&&(l=!0))}if(dn&&c.length){let u=c.filter(p=>p.nodeName=="BR");if(u.length==2){let[p,m]=u;p.parentNode&&p.parentNode.parentNode==m.parentNode?m.remove():p.remove()}else{let{focusNode:p}=this.currentSelection;for(let m of u){let h=m.parentNode;h&&h.nodeName=="LI"&&(!p||Yoe(e,p)!=h)&&m.remove()}}}else if((Nt||Wt)&&c.some(u=>u.nodeName=="BR")&&(e.input.lastKeyCode==8||e.input.lastKeyCode==46)){for(let u of c)if(u.nodeName=="BR"&&u.parentNode){let p=u.nextSibling;p&&p.nodeType==1&&p.contentEditable=="false"&&u.parentNode.removeChild(u)}}let d=null;r<0&&i&&e.input.lastFocus>Date.now()-200&&Math.max(e.input.lastTouch,e.input.lastClick.time)<Date.now()-300&&Hg(n)&&(d=rS(e))&&d.eq(xe.near(e.state.doc.resolve(0),1))?(e.input.lastFocus=0,Pi(e),this.currentSelection.set(n),e.scrollToSelection()):(r>-1||i)&&(r>-1&&(e.docView.markDirty(r,o),Qoe(e)),e.input.badSafariComposition&&(e.input.badSafariComposition=!1,Zoe(e,c)),this.handleDOMChange(r,o,l,c),e.docView&&e.docView.dirty?e.updateState(e.state):this.currentSelection.eq(n)||Pi(e),this.currentSelection.set(n))}registerMutation(e,a){if(a.indexOf(e.target)>-1)return null;let n=this.view.docView.nearestDesc(e.target);if(e.type=="attributes"&&(n==this.view.docView||e.attributeName=="contenteditable"||e.attributeName=="style"&&!e.oldValue&&!e.target.getAttribute("style"))||!n||n.ignoreMutation(e))return null;if(e.type=="childList"){for(let u=0;u<e.addedNodes.length;u++){let p=e.addedNodes[u];a.push(p),p.nodeType==3&&(this.lastChangedTextNode=p)}if(n.contentDOM&&n.contentDOM!=n.dom&&!n.contentDOM.contains(e.target))return{from:n.posBefore,to:n.posAfter};let i=e.previousSibling,r=e.nextSibling;if(Ra&&Lr<=11&&e.addedNodes.length)for(let u=0;u<e.addedNodes.length;u++){let{previousSibling:p,nextSibling:m}=e.addedNodes[u];(!p||Array.prototype.indexOf.call(e.addedNodes,p)<0)&&(i=p),(!m||Array.prototype.indexOf.call(e.addedNodes,m)<0)&&(r=m)}let o=i&&i.parentNode==e.target?zt(i)+1:0,l=n.localPosFromDOM(e.target,o,-1),c=r&&r.parentNode==e.target?zt(r):e.target.childNodes.length,d=n.localPosFromDOM(e.target,c,1);return{from:l,to:d}}else return e.type=="attributes"?{from:n.posAtStart-n.border,to:n.posAtEnd+n.border}:(this.lastChangedTextNode=e.target,{from:n.posAtStart,to:n.posAtEnd,typeOver:e.target.nodeValue==e.oldValue})}}let dT=new WeakMap,uT=!1;function Qoe(t){if(!dT.has(t)&&(dT.set(t,null),["normal","nowrap","pre-line"].indexOf(getComputedStyle(t.dom).whiteSpace)!==-1)){if(t.requiresGeckoHackNode=dn,uT)return;console.warn("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."),uT=!0}}function pT(t,e){let a=e.startContainer,n=e.startOffset,i=e.endContainer,r=e.endOffset,o=t.domAtPos(t.state.selection.anchor);return is(o.node,o.offset,i,r)&&([a,n,i,r]=[i,r,a,n]),{anchorNode:a,anchorOffset:n,focusNode:i,focusOffset:r}}function Xoe(t,e){if(e.getComposedRanges){let i=e.getComposedRanges(t.root)[0];if(i)return pT(t,i)}let a;function n(i){i.preventDefault(),i.stopImmediatePropagation(),a=i.getTargetRanges()[0]}return t.dom.addEventListener("beforeinput",n,!0),document.execCommand("indent"),t.dom.removeEventListener("beforeinput",n,!0),a?pT(t,a):null}function Yoe(t,e){for(let a=e.parentNode;a&&a!=t.dom;a=a.parentNode){let n=t.docView.nearestDesc(a,!0);if(n&&n.node.isBlock)return a}return null}function Zoe(t,e){var a;let{focusNode:n,focusOffset:i}=t.domSelectionRange();for(let r of e)if(((a=r.parentNode)===null||a===void 0?void 0:a.nodeName)=="TR"){let o=r.nextSibling;for(;o&&o.nodeName!="TD"&&o.nodeName!="TH";)o=o.nextSibling;if(o){let l=o;for(;;){let c=l.firstChild;if(!c||c.nodeType!=1||c.contentEditable=="false"||/^(BR|IMG)$/.test(c.nodeName))break;l=c}l.insertBefore(r,l.firstChild),n==r&&t.domSelection().collapse(r,i)}else r.parentNode.removeChild(r)}}function ese(t,e,a){let{node:n,fromOffset:i,toOffset:r,from:o,to:l}=t.docView.parseRange(e,a),c=t.domSelectionRange(),d,u=c.anchorNode;if(u&&t.dom.contains(u.nodeType==1?u:u.parentNode)&&(d=[{node:u,offset:c.anchorOffset}],Hg(c)||d.push({node:c.focusNode,offset:c.focusOffset})),Nt&&t.input.lastKeyCode===8)for(let x=r;x>i;x--){let v=n.childNodes[x-1],w=v.pmViewDesc;if(v.nodeName=="BR"&&!w){r=x;break}if(!w||w.size)break}let p=t.state.doc,m=t.someProp("domParser")||Rr.fromSchema(t.state.schema),h=p.resolve(o),g=null,y=m.parse(n,{topNode:h.parent,topMatch:h.parent.contentMatchAt(h.index()),topOpen:!0,from:i,to:r,preserveWhitespace:h.parent.type.whitespace=="pre"?"full":!0,findPositions:d,ruleFromNode:tse,context:h});if(d&&d[0].pos!=null){let x=d[0].pos,v=d[1]&&d[1].pos;v==null&&(v=x),g={anchor:x+o,head:v+o}}return{doc:y,sel:g,from:o,to:l}}function tse(t){let e=t.pmViewDesc;if(e)return e.parseRule();
vendor: 3,578 bytes, line 17639
17639if(t.nodeName=="BR"&&t.parentNode){if(Wt&&/^(ul|ol)$/i.test(t.parentNode.nodeName)){let a=document.createElement("div");return a.appendChild(document.createElement("li")),{skip:a}}else if(t.parentNode.lastChild==t||Wt&&/^(tr|table)$/i.test(t.parentNode.nodeName))return{ignore:!0}}else if(t.nodeName=="IMG"&&t.getAttribute("mark-placeholder"))return{ignore:!0};return null}const ase=/^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|img|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;function nse(t,e,a,n,i){let r=t.input.compositionPendingChanges||(t.composing?t.input.compositionID:0);if(t.input.compositionPendingChanges=0,e<0){let C=t.input.lastSelectionTime>Date.now()-50?t.input.lastSelectionOrigin:null,E=rS(t,C);if(E&&!t.state.selection.eq(E)){if(Nt&&Ai&&t.input.lastKeyCode===13&&Date.now()-100<t.input.lastKeyCodeTime&&t.someProp("handleKeyDown",N=>N(t,yo(13,"Enter"))))return;let j=t.state.tr.setSelection(E);C=="pointer"?j.setMeta("pointer",!0):C=="key"&&j.scrollIntoView(),r&&j.setMeta("composition",r),t.dispatch(j)}return}let o=t.state.doc.resolve(e),l=o.sharedDepth(a);e=o.before(l+1),a=t.state.doc.resolve(a).after(l+1);let c=t.state.selection,d=ese(t,e,a),u=t.state.doc,p=u.slice(d.from,d.to),m,h;t.input.lastKeyCode===8&&Date.now()-100<t.input.lastKeyCodeTime?(m=t.state.selection.to,h="end"):(m=t.state.selection.from,h="start"),t.input.lastKeyCode=null;let g=ose(p.content,d.doc.content,d.from,m,h);if(g&&t.input.domChangeCount++,(Ll&&t.input.lastIOSEnter>Date.now()-225||Ai)&&i.some(C=>C.nodeType==1&&!ase.test(C.nodeName))&&(!g||g.endA>=g.endB)&&t.someProp("handleKeyDown",C=>C(t,yo(13,"Enter")))){t.input.lastIOSEnter=0;return}if(!g)if(n&&c instanceof ce&&!c.empty&&c.$head.sameParent(c.$anchor)&&!t.composing&&!(d.sel&&d.sel.anchor!=d.sel.head))g={start:c.from,endA:c.to,endB:c.to};else{if(d.sel){let C=mT(t,t.state.doc,d.sel);if(C&&!C.eq(t.state.selection)){let E=t.state.tr.setSelection(C);r&&E.setMeta("composition",r),t.dispatch(E)}}return}t.state.selection.from<t.state.selection.to&&g.start==g.endB&&t.state.selection instanceof ce&&(g.start>t.state.selection.from&&g.start<=t.state.selection.from+2&&t.state.selection.from>=d.from?g.start=t.state.selection.from:g.endA<t.state.selection.to&&g.endA>=t.state.selection.to-2&&t.state.selection.to<=d.to&&(g.endB+=t.state.selection.to-g.endA,g.endA=t.state.selection.to)),Ra&&Lr<=11&&g.endB==g.start+1&&g.endA==g.start&&g.start>d.from&&d.doc.textBetween(g.start-d.from-1,g.start-d.from+1)==" Â "&&(g.start--,g.endA--,g.endB--);let y=d.doc.resolveNoCache(g.start-d.from),x=d.doc.resolveNoCache(g.endB-d.from),v=u.resolve(g.start),w=y.sameParent(x)&&y.parent.inlineContent&&v.end()>=g.endA;if((Ll&&t.input.lastIOSEnter>Date.now()-225&&(!w||i.some(C=>C.nodeName=="DIV"||C.nodeName=="P"))||!w&&y.pos<d.doc.content.size&&(!y.sameParent(x)||!y.parent.inlineContent)&&y.pos<x.pos&&!/\S/.test(d.doc.textBetween(y.pos,x.pos,"","")))&&t.someProp("handleKeyDown",C=>C(t,yo(13,"Enter")))){t.input.lastIOSEnter=0;return}if(t.state.selection.anchor>g.start&&rse(u,g.start,g.endA,y,x)&&t.someProp("handleKeyDown",C=>C(t,yo(8,"Backspace")))){Ai&&Nt&&t.domObserver.suppressSelectionUpdates();return}Nt&&g.endB==g.start&&(t.input.lastChromeDelete=Date.now()),Ai&&!w&&y.start()!=x.start()&&x.parentOffset==0&&y.depth==x.depth&&d.sel&&d.sel.anchor==d.sel.head&&d.sel.head==g.endA&&(g.endB-=2,x=d.doc.resolveNoCache(g.endB-d.from),setTimeout(()=>{t.someProp("handleKeyDown",function(C){return C(t,yo(13,"Enter"))})},20));let S=g.start,T=g.endA,P=C=>
vendor: 12,478 bytes, line 17639
17639{let E=C||t.state.tr.replace(S,T,d.doc.slice(g.start-d.from,g.endB-d.from));if(d.sel){let j=mT(t,E.doc,d.sel);j&&!(Nt&&t.composing&&j.empty&&(g.start!=g.endB||t.input.lastChromeDelete<Date.now()-100)&&(j.head==S||j.head==E.mapping.map(T)-1)||Ra&&j.empty&&j.head==S)&&E.setSelection(j)}return r&&E.setMeta("composition",r),E.scrollIntoView()},M;if(w)if(y.pos==x.pos){Ra&&Lr<=11&&y.parentOffset==0&&(t.domObserver.suppressSelectionUpdates(),setTimeout(()=>Pi(t),20));let C=P(t.state.tr.delete(S,T)),E=u.resolve(g.start).marksAcross(u.resolve(g.endA));E&&C.ensureMarks(E),t.dispatch(C)}else if(g.endA==g.endB&&(M=ise(y.parent.content.cut(y.parentOffset,x.parentOffset),v.parent.content.cut(v.parentOffset,g.endA-v.start())))){let C=P(t.state.tr);M.type=="add"?C.addMark(S,T,M.mark):C.removeMark(S,T,M.mark),t.dispatch(C)}else if(y.parent.child(y.index()).isText&&y.index()==x.index()-(x.textOffset?0:1)){let C=y.parent.textBetween(y.parentOffset,x.parentOffset),E=()=>P(t.state.tr.insertText(C,S,T));t.someProp("handleTextInput",j=>j(t,S,T,C,E))||t.dispatch(E())}else t.dispatch(P());else t.dispatch(P())}function mT(t,e,a){return Math.max(a.anchor,a.head)>e.content.size?null:oS(t,e.resolve(a.anchor),e.resolve(a.head))}function ise(t,e){let a=t.firstChild.marks,n=e.firstChild.marks,i=a,r=n,o,l,c;for(let u=0;u<n.length;u++)i=n[u].removeFromSet(i);for(let u=0;u<a.length;u++)r=a[u].removeFromSet(r);if(i.length==1&&r.length==0)l=i[0],o="add",c=u=>u.mark(l.addToSet(u.marks));else if(i.length==0&&r.length==1)l=r[0],o="remove",c=u=>u.mark(l.removeFromSet(u.marks));else return null;let d=[];for(let u=0;u<e.childCount;u++)d.push(c(e.child(u)));if(V.from(d).eq(t))return{mark:l,type:o}}function rse(t,e,a,n,i){if(a-e<=i.pos-n.pos||tx(n,!0,!1)<i.pos)return!1;let r=t.resolve(e);if(!n.parent.isTextblock){let l=r.nodeAfter;return l!=null&&a==e+l.nodeSize}if(r.parentOffset<r.parent.content.size||!r.parent.isTextblock)return!1;let o=t.resolve(tx(r,!0,!0));return!o.parent.isTextblock||o.pos>a||tx(o,!0,!1)<a?!1:n.parent.content.cut(n.parentOffset).eq(o.parent.content)}function tx(t,e,a){let n=t.depth,i=e?t.end():t.pos;for(;n>0&&(e||t.indexAfter(n)==t.node(n).childCount);)n--,i++,e=!1;if(a){let r=t.node(n).maybeChild(t.indexAfter(n));for(;r&&!r.isLeaf;)r=r.firstChild,i++}return i}function ose(t,e,a,n,i){let r=t.findDiffStart(e,a);if(r==null)return null;let{a:o,b:l}=t.findDiffEnd(e,a+t.size,a+e.size);if(i=="end"){let c=Math.max(0,r-Math.min(o,l));n-=o+c-r}if(o<r&&t.size<e.size){let c=n<=r&&n>=o?r-n:0;r-=c,r&&r<e.size&&hT(e.textBetween(r-1,r+1))&&(r+=c?1:-1),l=r+(l-o),o=r}else if(l<r){let c=n<=r&&n>=l?r-n:0;r-=c,r&&r<t.size&&hT(t.textBetween(r-1,r+1))&&(r+=c?1:-1),o=r+(o-l),l=r}return{start:r,endA:o,endB:l}}function hT(t){if(t.length!=2)return!1;let e=t.charCodeAt(0),a=t.charCodeAt(1);return e>=56320&&e<=57343&&a>=55296&&a<=56319}class p5{constructor(e,a){this._root=null,this.focused=!1,this.trackWrites=null,this.mounted=!1,this.markCursor=null,this.cursorWrapper=null,this.lastSelectedViewDesc=void 0,this.input=new koe,this.prevDirectPlugins=[],this.pluginViews=[],this.requiresGeckoHackNode=!1,this.dragging=null,this._props=a,this.state=a.state,this.directPlugins=a.plugins||[],this.directPlugins.forEach(vT),this.dispatch=this.dispatch.bind(this),this.dom=e&&e.mount||document.createElement("div"),e&&(e.appendChild?e.appendChild(this.dom):typeof e=="function"?e(this.dom):e.mount&&(this.mounted=!0)),this.editable=yT(this),gT(this),this.nodeViews=xT(this),this.docView=Jj(this.state.doc,fT(this),ex(this),this.dom,this),this.domObserver=new Joe(this,(n,i,r,o)=>nse(this,n,i,r,o)),this.domObserver.start(),Soe(this),this.updatePluginViews()}get composing(){return this.input.composing}get props(){if(this._props.state!=this.state){let e=this._props;this._props={};for(let a in e)this._props[a]=e[a];this._props.state=this.state}return this._props}update(e){e.handleDOMEvents!=this._props.handleDOMEvents&&Db(this);let a=this._props;this._props=e,e.plugins&&(e.plugins.forEach(vT),this.directPlugins=e.plugins),this.updateStateInner(e.state,a)}setProps(e){let a={};for(let n in this._props)a[n]=this._props[n];a.state=this.state;for(let n in e)a[n]=e[n];this.update(a)}updateState(e){this.updateStateInner(e,this._props)}updateStateInner(e,a){var n;let i=this.state,r=!1,o=!1;e.storedMarks&&this.composing&&(r5(this),o=!0),this.state=e;let l=i.plugins!=e.plugins||this._props.plugins!=a.plugins;if(l||this._props.plugins!=a.plugins||this._props.nodeViews!=a.nodeViews){let h=xT(this);lse(h,this.nodeViews)&&(this.nodeViews=h,r=!0)}(l||a.handleDOMEvents!=this._props.handleDOMEvents)&&Db(this),this.editable=yT(this),gT(this);let c=ex(this),d=fT(this),u=i.plugins!=e.plugins&&!i.doc.eq(e.doc)?"reset":e.scrollToSelection>i.scrollToSelection?"to selection":"preserve",p=r||!this.docView.matchesNode(e.doc,d,c);(p||!e.selection.eq(i.selection))&&(o=!0);let m=u=="preserve"&&o&&this.dom.style.overflowAnchor==null&&Dre(this);if(o){this.domObserver.stop();let h=p&&(Ra||Nt)&&!this.composing&&!i.selection.empty&&!e.selection.empty&&sse(i.selection,e.selection);if(p){let g=Nt?this.trackWrites=this.domSelectionRange().focusNode:null;this.composing&&(this.input.compositionNode=Doe(this)),(r||!this.docView.update(e.doc,d,c,this))&&(this.docView.updateOuterDeco(d),this.docView.destroy(),this.docView=Jj(e.doc,d,c,this.dom,this)),g&&(!this.trackWrites||!this.dom.contains(this.trackWrites))&&(h=!0)}h||!(this.input.mouseDown&&this.domObserver.currentSelection.eq(this.domSelectionRange())&&soe(this))?Pi(this,h):(GM(this,e.selection),this.domObserver.setCurSelection()),this.domObserver.start()}this.updatePluginViews(i),!((n=this.dragging)===null||n===void 0)&&n.node&&!i.doc.eq(e.doc)&&this.updateDraggedNode(this.dragging,i),u=="reset"?this.dom.scrollTop=0:u=="to selection"?this.scrollToSelection():m&&qre(m)}scrollToSelection(){let e=this.domSelectionRange().focusNode;if(!(!e||!this.dom.contains(e.nodeType==1?e:e.parentNode))){if(!this.someProp("handleScrollToSelection",a=>a(this)))if(this.state.selection instanceof se){let a=this.docView.domAfterPos(this.state.selection.from);a.nodeType==1&&Bj(this,a.getBoundingClientRect(),e)}else Bj(this,this.coordsAtPos(this.state.selection.head,1),e)}}destroyPluginViews(){let e;for(;e=this.pluginViews.pop();)e.destroy&&e.destroy()}updatePluginViews(e){if(!e||e.plugins!=this.state.plugins||this.directPlugins!=this.prevDirectPlugins){this.prevDirectPlugins=this.directPlugins,this.destroyPluginViews();for(let a=0;a<this.directPlugins.length;a++){let n=this.directPlugins[a];n.spec.view&&this.pluginViews.push(n.spec.view(this))}for(let a=0;a<this.state.plugins.length;a++){let n=this.state.plugins[a];n.spec.view&&this.pluginViews.push(n.spec.view(this))}}else for(let a=0;a<this.pluginViews.length;a++){let n=this.pluginViews[a];n.update&&n.update(this,e)}}updateDraggedNode(e,a){let n=e.node,i=-1;if(this.state.doc.nodeAt(n.from)==n.node)i=n.from;else{let r=n.from+(this.state.doc.content.size-a.doc.content.size);(r>0&&this.state.doc.nodeAt(r))==n.node&&(i=r)}this.dragging=new s5(e.slice,e.move,i<0?void 0:se.create(this.state.doc,i))}someProp(e,a){let n=this._props&&this._props[e],i;if(n!=null&&(i=a?a(n):n))return i;for(let o=0;o<this.directPlugins.length;o++){let l=this.directPlugins[o].props[e];if(l!=null&&(i=a?a(l):l))return i}let r=this.state.plugins;if(r)for(let o=0;o<r.length;o++){let l=r[o].props[e];if(l!=null&&(i=a?a(l):l))return i}}hasFocus(){if(Ra){let e=this.root.activeElement;if(e==this.dom)return!0;if(!e||!this.dom.contains(e))return!1;for(;e&&this.dom!=e&&this.dom.contains(e);){if(e.contentEditable=="false")return!1;e=e.parentElement}return!0}return this.root.activeElement==this.dom}focus(){this.domObserver.stop(),this.editable&&zre(this.dom),Pi(this),this.domObserver.start()}get root(){let e=this._root;if(e==null){for(let a=this.dom.parentNode;a;a=a.parentNode)if(a.nodeType==9||a.nodeType==11&&a.host)return a.getSelection||(Object.getPrototypeOf(a).getSelection=()=>a.ownerDocument.getSelection()),this._root=a}return e||document}updateRoot(){this._root=null}posAtCoords(e){return Ure(this,e)}coordsAtPos(e,a=1){return zM(this,e,a)}domAtPos(e,a=0){return this.docView.domFromPos(e,a)}nodeDOM(e){let a=this.docView.descAt(e);return a?a.nodeDOM:null}posAtDOM(e,a,n=-1){let i=this.docView.posFromDOM(e,a,n);if(i==null)throw new RangeError("DOM position not inside the editor");return i}endOfTextblock(e,a){return Jre(this,a||this.state,e)}pasteHTML(e,a){return fu(this,"",e,!1,a||new ClipboardEvent("paste"))}pasteText(e,a){return fu(this,e,null,!0,a||new ClipboardEvent("paste"))}serializeForClipboard(e){return sS(this,e)}destroy(){this.docView&&(_oe(this),this.destroyPluginViews(),this.mounted?(this.docView.update(this.state.doc,[],ex(this),this),this.dom.textContent=""):this.dom.parentNode&&this.dom.parentNode.removeChild(this.dom),this.docView.destroy(),this.docView=null,Cre())}get isDestroyed(){return this.docView==null}dispatchEvent(e){return Eoe(this,e)}domSelectionRange(){let e=this.domSelection();return e?Wt&&this.root.nodeType===11&&Pre(this.dom.ownerDocument)==this.dom&&Xoe(this,e)||e:{focusNode:null,focusOffset:0,anchorNode:null,anchorOffset:0}}domSelection(){return this.root.getSelection()}}p5.prototype.dispatch=function(t){let e=this._props.dispatchTransaction;e?e.call(this,t):this.updateState(this.state.apply(t))};function fT(t){let e=Object.create(null);return e.class="ProseMirror",e.contenteditable=String(t.editable),t.someProp("attributes",a=>{if(typeof a=="function"&&(a=a(t.state)),a)for(let n in a)n=="class"?e.class+=" "+a[n]:n=="style"?e.style=(e.style?e.style+";":"")+a[n]:!e[n]&&n!="contenteditable"&&n!="nodeName"&&(e[n]=String(a[n]))}),e.translate||(e.translate="no"),[ha.node(0,t.state.doc.content.size,e)]}function gT(t){if(t.markCursor){let e=document.createElement("img");e.className="ProseMirror-separator",e.setAttribute("mark-placeholder","true"),e.setAttribute("alt",""),t.cursorWrapper={dom:e,deco:ha.widget(t.state.selection.from,e,{raw:!0,marks:t.markCursor})}}else t.cursorWrapper=null}function yT(t){return!t.someProp("editable",e=>e(t.state)===!1)}function sse(t,e){let a=Math.min(t.$anchor.sharedDepth(t.head),e.$anchor.sharedDepth(e.head));return t.$anchor.start(a)!=e.$anchor.start(a)}function xT(t){let e=Object.create(null);function a(n){for(let i in n)Object.prototype.hasOwnProperty.call(e,i)||(e[i]=n[i])}return t.someProp("nodeViews",a),t.someProp("markViews",a),e}function lse(t,e){let a=0,n=0;for(let i in t){if(t[i]!=e[i])return!0;a++}for(let i in e)n++;return a!=n}function vT(t){if(t.spec.state||t.spec.filterTransaction||t.spec.appendTransaction)throw new RangeError("Plugins passed directly to the view must not have a state component")}var Ur={8:"Backspace",9:"Tab",10:"Enter",12:"NumLock",13:"Enter",16:"Shift",17:"Control",18:"Alt",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",44:"PrintScreen",45:"Insert",46:"Delete",59:";",61:"=",91:"Meta",92:"Meta",106:"*",107:"+",108:",",109:"-",110:".",111:"/",144:"NumLock",145:"ScrollLock",160:"Shift",161:"Shift",162:"Control",163:"Control",164:"Alt",165:"Alt",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},rf={48:")",49:"!",50:"@",51:"#",52:"$",53:"%",54:"^",55:"&",56:"*",57:"(",59:":",61:"+",173:"_",186:":",187:"+",188:"<",189:"_",190:">",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},cse=typeof navigator<"u"&&/Mac/.test(navigator.platform),dse=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);for(var Vt=0;Vt<10;Vt++)Ur[48+Vt]=Ur[96+Vt]=String(Vt);for(var Vt=1;Vt<=24;Vt++)Ur[Vt+111]="F"+Vt;for(var Vt=65;Vt<=90;Vt++)Ur[Vt]=String.fromCharCode(Vt+32),rf[Vt]=String.fromCharCode(Vt);for(var ax in Ur)rf.hasOwnProperty(ax)||(rf[ax]=Ur[ax]);function use(t){var e=cse&&t.metaKey&&t.shiftKey&&!t.ctrlKey&&!t.altKey||dse&&t.shiftKey&&t.key&&t.key.length==1||t.key=="Unidentified",a=!e&&t.key||(t.shiftKey?rf:Ur)[t.keyCode]||t.key||"Unidentified";return a=="Esc"&&(a="Escape"),a=="Del"&&(a="Delete"),a=="Left"&&(a="ArrowLeft"),a=="Up"&&(a="ArrowUp"),a=="Right"&&(a="ArrowRight"),a=="Down"&&(a="ArrowDown"),a}const pse=typeof navigator<"u"&&/Mac|iP(hone|[oa]d)/.test(navigator.platform),mse=typeof navigator<"u"&&/Win/.test(navigator.platform);function hse(t){let e=t.split(/-(?!$)/),a=e[e.length-1];a=="Space"&&(a=" ");let n,i,r,o;for(let l=0;l<e.length-1;l++){let c=e[l];
vendor: 18,325 bytes, line 17639
17639if(/^(cmd|meta|m)$/i.test(c))o=!0;else if(/^a(lt)?$/i.test(c))n=!0;else if(/^(c|ctrl|control)$/i.test(c))i=!0;else if(/^s(hift)?$/i.test(c))r=!0;else if(/^mod$/i.test(c))pse?o=!0:i=!0;else throw new Error("Unrecognized modifier name: "+c)}return n&&(a="Alt-"+a),i&&(a="Ctrl-"+a),o&&(a="Meta-"+a),r&&(a="Shift-"+a),a}function fse(t){let e=Object.create(null);for(let a in t)e[hse(a)]=t[a];return e}function nx(t,e,a=!0){return e.altKey&&(t="Alt-"+t),e.ctrlKey&&(t="Ctrl-"+t),e.metaKey&&(t="Meta-"+t),a&&e.shiftKey&&(t="Shift-"+t),t}function gse(t){return new at({props:{handleKeyDown:m5(t)}})}function m5(t){let e=fse(t);return function(a,n){let i=use(n),r,o=e[nx(i,n)];if(o&&o(a.state,a.dispatch,a))return!0;if(i.length==1&&i!=" "){if(n.shiftKey){let l=e[nx(i,n,!1)];if(l&&l(a.state,a.dispatch,a))return!0}if((n.altKey||n.metaKey||n.ctrlKey)&&!(mse&&n.ctrlKey&&n.altKey)&&(r=Ur[n.keyCode])&&r!=i){let l=e[nx(r,n)];if(l&&l(a.state,a.dispatch,a))return!0}}return!1}}var yse=Object.defineProperty,mS=(t,e)=>{for(var a in e)yse(t,a,{get:e[a],enumerable:!0})};function Ug(t){const{state:e,transaction:a}=t;let{selection:n}=a,{doc:i}=a,{storedMarks:r}=a;return{...e,apply:e.apply.bind(e),applyTransaction:e.applyTransaction.bind(e),plugins:e.plugins,schema:e.schema,reconfigure:e.reconfigure.bind(e),toJSON:e.toJSON.bind(e),get storedMarks(){return r},get selection(){return n},get doc(){return i},get tr(){return n=a.selection,i=a.doc,r=a.storedMarks,a}}}var $g=class{constructor(t){this.editor=t.editor,this.rawCommands=this.editor.extensionManager.commands,this.customState=t.state}get hasCustomState(){return!!this.customState}get state(){return this.customState||this.editor.state}get commands(){const{rawCommands:t,editor:e,state:a}=this,{view:n}=e,{tr:i}=a,r=this.buildProps(i);return Object.fromEntries(Object.entries(t).map(([o,l])=>[o,(...d)=>{const u=l(...d)(r);return!i.getMeta("preventDispatch")&&!this.hasCustomState&&n.dispatch(i),u}]))}get chain(){return()=>this.createChain()}get can(){return()=>this.createCan()}createChain(t,e=!0){const{rawCommands:a,editor:n,state:i}=this,{view:r}=n,o=[],l=!!t,c=t||i.tr,d=()=>(!l&&e&&!c.getMeta("preventDispatch")&&!this.hasCustomState&&r.dispatch(c),o.every(p=>p===!0)),u={...Object.fromEntries(Object.entries(a).map(([p,m])=>[p,(...g)=>{const y=this.buildProps(c,e),x=m(...g)(y);return o.push(x),u}])),run:d};return u}createCan(t){const{rawCommands:e,state:a}=this,n=!1,i=t||a.tr,r=this.buildProps(i,n);return{...Object.fromEntries(Object.entries(e).map(([l,c])=>[l,(...d)=>c(...d)({...r,dispatch:void 0})])),chain:()=>this.createChain(i,n)}}buildProps(t,e=!0){const{rawCommands:a,editor:n,state:i}=this,{view:r}=n,o={tr:t,editor:n,view:r,state:Ug({state:i,transaction:t}),dispatch:e?()=>{}:void 0,chain:()=>this.createChain(t,e),can:()=>this.createCan(t),get commands(){return Object.fromEntries(Object.entries(a).map(([l,c])=>[l,(...d)=>c(...d)(o)]))}};return o}},h5={};mS(h5,{blur:()=>xse,clearContent:()=>vse,clearNodes:()=>bse,command:()=>wse,createParagraphNear:()=>kse,cut:()=>Sse,deleteCurrentNode:()=>_se,deleteNode:()=>Ase,deleteRange:()=>Ese,deleteSelection:()=>Cse,enter:()=>jse,exitCode:()=>Tse,extendMarkRange:()=>Nse,first:()=>Ise,focus:()=>Rse,forEach:()=>Lse,insertContent:()=>Ose,insertContentAt:()=>qse,joinBackward:()=>Hse,joinDown:()=>Vse,joinForward:()=>Fse,joinItemBackward:()=>Bse,joinItemForward:()=>Use,joinTextblockBackward:()=>$se,joinTextblockForward:()=>Wse,joinUp:()=>zse,keyboardShortcut:()=>Kse,lift:()=>Jse,liftEmptyBlock:()=>Qse,liftListItem:()=>Xse,newlineInCode:()=>Yse,resetAttributes:()=>Zse,scrollIntoView:()=>ele,selectAll:()=>tle,selectNodeBackward:()=>ale,selectNodeForward:()=>nle,selectParentNode:()=>ile,selectTextblockEnd:()=>rle,selectTextblockStart:()=>ole,setContent:()=>sle,setMark:()=>jle,setMeta:()=>Tle,setNode:()=>Nle,setNodeSelection:()=>Ile,setTextDirection:()=>Ple,setTextSelection:()=>Rle,sinkListItem:()=>Lle,splitBlock:()=>Ole,splitListItem:()=>Mle,toggleList:()=>qle,toggleMark:()=>zle,toggleNode:()=>Vle,toggleWrap:()=>Hle,undoInputRule:()=>Fle,unsetAllMarks:()=>Ble,unsetMark:()=>Ule,unsetTextDirection:()=>$le,updateAttributes:()=>Wle,wrapIn:()=>Gle,wrapInList:()=>Kle});var xse=()=>({editor:t,view:e})=>(requestAnimationFrame(()=>{var a;t.isDestroyed||(e.dom.blur(),(a=window==null?void 0:window.getSelection())==null||a.removeAllRanges())}),!0),vse=(t=!0)=>({commands:e})=>e.setContent("",{emitUpdate:t}),bse=()=>({state:t,tr:e,dispatch:a})=>{const{selection:n}=e,{ranges:i}=n;return a&&i.forEach(({$from:r,$to:o})=>{t.doc.nodesBetween(r.pos,o.pos,(l,c)=>{if(l.type.isText)return;const{doc:d,mapping:u}=e,p=d.resolve(u.map(c)),m=d.resolve(u.map(c+l.nodeSize)),h=p.blockRange(m);if(!h)return;const g=ec(h);if(l.type.isTextblock){const{defaultType:y}=p.parent.contentMatchAt(p.index());e.setNodeMarkup(h.start,y)}(g||g===0)&&e.lift(h,g)})}),!0},wse=t=>e=>t(e),kse=()=>({state:t,dispatch:e})=>jM(t,e),Sse=(t,e)=>({editor:a,tr:n})=>{const{state:i}=a,r=i.doc.slice(t.from,t.to);n.deleteRange(t.from,t.to);const o=n.mapping.map(e);return n.insert(o,r.content),n.setSelection(new ce(n.doc.resolve(Math.max(o-1,0)))),!0},_se=()=>({tr:t,dispatch:e})=>{const{selection:a}=t,n=a.$anchor.node();if(n.content.size>0)return!1;const i=t.selection.$anchor;for(let r=i.depth;r>0;r-=1)if(i.node(r).type===n.type){if(e){const l=i.before(r),c=i.after(r);t.delete(l,c).scrollIntoView()}return!0}return!1};function vt(t,e){if(typeof t=="string"){if(!e.nodes[t])throw Error(`There is no node type named '${t}'. Maybe you forgot to add the extension?`);return e.nodes[t]}return t}var Ase=t=>({tr:e,state:a,dispatch:n})=>{const i=vt(t,a.schema),r=e.selection.$anchor;for(let o=r.depth;o>0;o-=1)if(r.node(o).type===i){if(n){const c=r.before(o),d=r.after(o);e.delete(c,d).scrollIntoView()}return!0}return!1},Ese=t=>({tr:e,dispatch:a})=>{const{from:n,to:i}=t;return a&&e.delete(n,i),!0},Cse=()=>({state:t,dispatch:e})=>Zk(t,e),jse=()=>({commands:t})=>t.keyboardShortcut("Enter"),Tse=()=>({state:t,dispatch:e})=>pre(t,e);function hS(t){return Object.prototype.toString.call(t)==="[object RegExp]"}function of(t,e,a={strict:!0}){const n=Object.keys(e);return n.length?n.every(i=>a.strict?e[i]===t[i]:hS(e[i])?e[i].test(t[i]):e[i]===t[i]):!0}function f5(t,e,a={}){return t.find(n=>n.type===e&&of(Object.fromEntries(Object.keys(a).map(i=>[i,n.attrs[i]])),a))}function bT(t,e,a={}){return!!f5(t,e,a)}function fS(t,e,a){if(!t||!e)return;let n=t.parent.childAfter(t.parentOffset);if((!n.node||!n.node.marks.some(d=>d.type===e))&&(n=t.parent.childBefore(t.parentOffset)),!n.node||!n.node.marks.some(d=>d.type===e))return;if(!a){const d=n.node.marks.find(u=>u.type===e);d&&(a=d.attrs)}if(!f5([...n.node.marks],e,a))return;let r=n.index,o=t.start()+n.offset,l=r+1,c=o+n.node.nodeSize;for(;r>0&&bT([...t.parent.child(r-1).marks],e,a);)r-=1,o-=t.parent.child(r).nodeSize;for(;l<t.parent.childCount&&bT([...t.parent.child(l).marks],e,a);)c+=t.parent.child(l).nodeSize,l+=1;return{from:o,to:c}}function $i(t,e){if(typeof t=="string"){if(!e.marks[t])throw Error(`There is no mark type named '${t}'. Maybe you forgot to add the extension?`);return e.marks[t]}return t}var Nse=(t,e)=>({tr:a,state:n,dispatch:i})=>{const r=$i(t,n.schema),{doc:o,selection:l}=a,{$from:c,from:d,to:u}=l;if(i){const p=fS(c,r,e);if(p&&p.from<=d&&p.to>=u){const m=ce.create(o,p.from,p.to);a.setSelection(m)}}return!0},Ise=t=>e=>{const a=typeof t=="function"?t(e):t;for(let n=0;n<a.length;n+=1)if(a[n](e))return!0;return!1};function g5(t){return t instanceof ce}function jo(t=0,e=0,a=0){return Math.min(Math.max(t,e),a)}function y5(t,e=null){if(!e)return null;const a=xe.atStart(t),n=xe.atEnd(t);if(e==="start"||e===!0)return a;if(e==="end")return n;const i=a.from,r=n.to;return e==="all"?ce.create(t,jo(0,i,r),jo(t.content.size,i,r)):ce.create(t,jo(e,i,r),jo(e,i,r))}function wT(){return navigator.platform==="Android"||/android/i.test(navigator.userAgent)}function sf(){return["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}function Pse(){return typeof navigator<"u"?/^((?!chrome|android).)*safari/i.test(navigator.userAgent):!1}var Rse=(t=null,e={})=>({editor:a,view:n,tr:i,dispatch:r})=>{e={scrollIntoView:!0,...e};const o=()=>{(sf()||wT())&&n.dom.focus(),Pse()&&!sf()&&!wT()&&n.dom.focus({preventScroll:!0}),requestAnimationFrame(()=>{a.isDestroyed||(n.focus(),e!=null&&e.scrollIntoView&&a.commands.scrollIntoView())})};try{if(n.hasFocus()&&t===null||t===!1)return!0}catch{return!1}if(r&&t===null&&!g5(a.state.selection))return o(),!0;const l=y5(i.doc,t)||a.state.selection,c=a.state.selection.eq(l);return r&&(c||i.setSelection(l),c&&i.storedMarks&&i.setStoredMarks(i.storedMarks),o()),!0},Lse=(t,e)=>a=>t.every((n,i)=>e(n,{...a,index:i})),Ose=(t,e)=>({tr:a,commands:n})=>n.insertContentAt({from:a.selection.from,to:a.selection.to},t,e),x5=t=>{const e=t.childNodes;for(let a=e.length-1;a>=0;a-=1){const n=e[a];n.nodeType===3&&n.nodeValue&&/^(\n\s\s|\n)$/.test(n.nodeValue)?t.removeChild(n):n.nodeType===1&&x5(n)}return t};function em(t){if(typeof window>"u")throw new Error("[tiptap error]: there is no window object available, so this function cannot be used");const e=`<body>${t}</body>`,a=new window.DOMParser().parseFromString(e,"text/html").body;return x5(a)}function yu(t,e,a){if(t instanceof Rn||t instanceof V)return t;a={slice:!0,parseOptions:{},...a};const n=typeof t=="object"&&t!==null,i=typeof t=="string";if(n)try{if(Array.isArray(t)&&t.length>0)return V.fromArray(t.map(l=>e.nodeFromJSON(l)));const o=e.nodeFromJSON(t);return a.errorOnInvalidContent&&o.check(),o}catch(r){if(a.errorOnInvalidContent)throw new Error("[tiptap error]: Invalid JSON content",{cause:r});return console.warn("[tiptap warn]: Invalid content.","Passed value:",t,"Error:",r),yu("",e,a)}if(i){if(a.errorOnInvalidContent){let o=!1,l="";const c=new tM({topNode:e.spec.topNode,marks:e.spec.marks,nodes:e.spec.nodes.append({__tiptap__private__unknown__catch__all__node:{content:"inline*",group:"block",parseDOM:[{tag:"*",getAttrs:d=>(o=!0,l=typeof d=="string"?d:d.outerHTML,null)}]}})});if(a.slice?Rr.fromSchema(c).parseSlice(em(t),a.parseOptions):Rr.fromSchema(c).parse(em(t),a.parseOptions),a.errorOnInvalidContent&&o)throw new Error("[tiptap error]: Invalid HTML content",{cause:new Error(`Invalid element found: ${l}`)})}const r=Rr.fromSchema(e);return a.slice?r.parseSlice(em(t),a.parseOptions).content:r.parse(em(t),a.parseOptions)}return yu("",e,a)}function Mse(t,e,a){const n=t.steps.length-1;if(n<e)return;const i=t.steps[n];if(!(i instanceof Tt||i instanceof Pt))return;const r=t.mapping.maps[n];let o=0;r.forEach((l,c,d,u)=>{o===0&&(o=u)}),t.setSelection(xe.near(t.doc.resolve(o),a))}var Dse=t=>!("type"in t),qse=(t,e,a)=>({tr:n,dispatch:i,editor:r})=>{var o;if(i){a={parseOptions:r.options.parseOptions,updateSelection:!0,applyInputRules:!1,applyPasteRules:!1,...a};let l;const c=x=>{r.emit("contentError",{editor:r,error:x,disableCollaboration:()=>{"collaboration"in r.storage&&typeof r.storage.collaboration=="object"&&r.storage.collaboration&&(r.storage.collaboration.isDisabled=!0)}})},d={preserveWhitespace:"full",...a.parseOptions};if(!a.errorOnInvalidContent&&!r.options.enableContentCheck&&r.options.emitContentError)try{yu(e,r.schema,{parseOptions:d,errorOnInvalidContent:!0})}catch(x){c(x)}try{l=yu(e,r.schema,{parseOptions:d,errorOnInvalidContent:(o=a.errorOnInvalidContent)!=null?o:r.options.enableContentCheck})}catch(x){return c(x),!1}let{from:u,to:p}=typeof t=="number"?{from:t,to:t}:{from:t.from,to:t.to},m=!0,h=!0;if((Dse(l)?l:[l]).forEach(x=>{x.check(),m=m?x.isText&&x.marks.length===0:!1,h=h?x.isBlock:!1}),u===p&&h){const{parent:x}=n.doc.resolve(u);x.isTextblock&&!x.type.spec.code&&!x.childCount&&(u-=1,p+=1)}let y;if(m){if(Array.isArray(e))y=e.map(x=>x.text||"").join("");else if(e instanceof V){let x="";e.forEach(v=>{v.text&&(x+=v.text)}),y=x}else typeof e=="object"&&e&&e.text?y=e.text:y=e;n.insertText(y,u,p)}else{y=l;const x=n.doc.resolve(u),v=x.node(),w=x.parentOffset===0,S=v.isText||v.isTextblock,T=v.content.size>0;w&&S&&T&&h&&(u=Math.max(0,u-1)),n.replaceWith(u,p,y)}a.updateSelection&&Mse(n,n.steps.length-1,-1),a.applyInputRules&&n.setMeta("applyInputRules",{from:u,text:y}),a.applyPasteRules&&n.setMeta("applyPasteRules",{from:u,text:y})}return!0},zse=()=>({state:t,dispatch:e})=>cre(t,e),Vse=()=>({state:t,dispatch:e})=>dre(t,e),Hse=()=>({state:t,dispatch:e})=>wM(t,e),Fse=()=>({state:t,dispatch:e})=>AM(t,e),Bse=()=>({state:t,dispatch:e,tr:a})=>{try{const n=qg(t.doc,t.selection.$from.pos,-1);return n==null?!1:(a.join(n,2),e&&e(a),!0)}catch{return!1}},Use=()=>({state:t,dispatch:e,tr:a})=>{try{const n=qg(t.doc,t.selection.$from.pos,1);return n==null?!1:(a.join(n,2),e&&e(a),!0)}catch{return!1}},$se=()=>({state:t,dispatch:e})=>sre(t,e),Wse=()=>({state:t,dispatch:e})=>lre(t,e);function v5(){return typeof navigator<"u"?/Mac/.test(navigator.platform):!1}function Gse(t){const e=t.split(/-(?!$)/);let a=e[e.length-1];a==="Space"&&(a=" ");let n,i,r,o;for(let l=0;l<e.length-1;l+=1){const c=e[l];if(/^(cmd|meta|m)$/i.test(c))o=!0;else if(/^a(lt)?$/i.test(c))n=!0;else if(/^(c|ctrl|control)$/i.test(c))i=!0;else if(/^s(hift)?$/i.test(c))r=!0;else if(/^mod$/i.test(c))sf()||v5()?o=!0:i=!0;else throw new Error(`Unrecognized modifier name: ${c}`)}return n&&(a=`Alt-${a}`),i&&(a=`Ctrl-${a}`),o&&(a=`Meta-${a}`),r&&(a=`Shift-${a}`),a}var Kse=t=>({editor:e,view:a,tr:n,dispatch:i})=>{const r=Gse(t).split(/-(?!$)/),o=r.find(d=>!["Alt","Ctrl","Meta","Shift"].includes(d)),l=new KeyboardEvent("keydown",{key:o==="Space"?" ":o,altKey:r.includes("Alt"),ctrlKey:r.includes("Ctrl"),metaKey:r.includes("Meta"),shiftKey:r.includes("Shift"),bubbles:!0,cancelable:!0}),c=e.captureTransaction(()=>{a.someProp("handleKeyDown",d=>d(a,l))});return c==null||c.steps.forEach(d=>{const u=d.map(n.mapping);u&&i&&n.maybeStep(u)}),!0};function $r(t,e,a={}){const{from:n,to:i,empty:r}=t.selection,o=e?vt(e,t.schema):null,l=[];t.doc.nodesBetween(n,i,(p,m)=>{if(p.isText)return;const h=Math.max(n,m),g=Math.min(i,m+p.nodeSize);l.push({node:p,from:h,to:g})});const c=i-n,d=l.filter(p=>o?o.name===p.node.type.name:!0).filter(p=>of(p.node.attrs,a,{strict:!1}));return r?!!d.length:d.reduce((p,m)=>p+m.to-m.from,0)>=c}var Jse=(t,e={})=>({state:a,dispatch:n})=>{const i=vt(t,a.schema);return $r(a,i,e)?ure(a,n):!1},Qse=()=>({state:t,dispatch:e})=>TM(t,e),Xse=t=>({state:e,dispatch:a})=>{const n=vt(t,e.schema);return Sre(n)(e,a)},Yse=()=>({state:t,dispatch:e})=>CM(t,e);function Wg(t,e){return e.nodes[t]?"node":e.marks[t]?"mark":null}function kT(t,e){const a=typeof e=="string"?[e]:e;return Object.keys(t).reduce((n,i)=>(a.includes(i)||(n[i]=t[i]),n),{})}var Zse=(t,e)=>({tr:a,state:n,dispatch:i})=>{let r=null,o=null;const l=Wg(typeof t=="string"?t:t.name,n.schema);if(!l)return!1;l==="node"&&(r=vt(t,n.schema)),l==="mark"&&(o=$i(t,n.schema));let c=!1;return a.selection.ranges.forEach(d=>{n.doc.nodesBetween(d.$from.pos,d.$to.pos,(u,p)=>{r&&r===u.type&&(c=!0,i&&a.setNodeMarkup(p,void 0,kT(u.attrs,e))),o&&u.marks.length&&u.marks.forEach(m=>{o===m.type&&(c=!0,i&&a.addMark(p,p+u.nodeSize,o.create(kT(m.attrs,e))))})})}),c},ele=()=>({tr:t,dispatch:e})=>(e&&t.scrollIntoView(),!0),tle=()=>({tr:t,dispatch:e})=>{if(e){const a=new Ua(t.doc);t.setSelection(a)}return!0},ale=()=>({state:t,dispatch:e})=>SM(t,e),nle=()=>({state:t,dispatch:e})=>EM(t,e),ile=()=>({state:t,dispatch:e})=>fre(t,e),rle=()=>({state:t,dispatch:e})=>xre(t,e),ole=()=>({state:t,dispatch:e})=>yre(t,e);function qb(t,e,a={},n={}){return yu(t,e,{slice:!1,parseOptions:a,errorOnInvalidContent:n.errorOnInvalidContent})}var sle=(t,{errorOnInvalidContent:e,emitUpdate:a=!0,parseOptions:n={}}={})=>({editor:i,tr:r,dispatch:o,commands:l})=>{const{doc:c}=r;if(n.preserveWhitespace!=="full"){const d=qb(t,i.schema,n,{errorOnInvalidContent:e??i.options.enableContentCheck});return o&&r.replaceWith(0,c.content.size,d).setMeta("preventUpdate",!a),!0}return o&&r.setMeta("preventUpdate",!a),l.insertContentAt({from:0,to:c.content.size},t,{parseOptions:n,errorOnInvalidContent:e??i.options.enableContentCheck})};function b5(t,e){const a=$i(e,t.schema),{from:n,to:i,empty:r}=t.selection,o=[];r?(t.storedMarks&&o.push(...t.storedMarks),o.push(...t.selection.$head.marks())):t.doc.nodesBetween(n,i,c=>{o.push(...c.marks)});const l=o.find(c=>c.type.name===a.name);return l?{...l.attrs}:{}}function w5(t,e){const a=new yM(t);return e.forEach(n=>{n.steps.forEach(i=>{a.step(i)})}),a}function lle(t){for(let e=0;e<t.edgeCount;e+=1){const{type:a}=t.edge(e);if(a.isTextblock&&!a.hasRequiredAttrs())return a}return null}function cle(t,e,a){const n=[];return t.nodesBetween(e.from,e.to,(i,r)=>{a(i)&&n.push({node:i,pos:r})}),n}function dle(t,e){for(let a=t.depth;a>0;a-=1){const n=t.node(a);if(e(n))return{pos:a>0?t.before(a):0,start:t.start(a),depth:a,node:n}}}function Gg(t){return e=>dle(e.$from,t)}function te(t,e,a){return t.config[e]===void 0&&t.parent?te(t.parent,e,a):typeof t.config[e]=="function"?t.config[e].bind({...a,parent:t.parent?te(t.parent,e,a):null}):t.config[e]}function gS(t){return t.map(e=>{const a={name:e.name,options:e.options,storage:e.storage},n=te(e,"addExtensions",a);return n?[e,...gS(n())]:e}).flat(10)}function yS(t,e){const a=fs.fromSchema(e).serializeFragment(t),i=document.implementation.createHTMLDocument().createElement("div");return i.appendChild(a),i.innerHTML}function k5(t){return typeof t=="function"}function Pe(t,e=void 0,...a){return k5(t)?e?t.bind(e)(...a):t(...a):t}function ule(t={}){return Object.keys(t).length===0&&t.constructor===Object}function Ol(t){const e=t.filter(i=>i.type==="extension"),a=t.filter(i=>i.type==="node"),n=t.filter(i=>i.type==="mark");return{baseExtensions:e,nodeExtensions:a,markExtensions:n}}function S5(t){const e=[],{nodeExtensions:a,markExtensions:n}=Ol(t),i=[...a,...n],r={default:null,validate:void 0,rendered:!0,renderHTML:null,parseHTML:null,keepOnSplit:!0,isRequired:!1},o=a.filter(d=>d.name!=="text").map(d=>d.name),l=n.map(d=>d.name),c=[...o,...l];return t.forEach(d=>{const u={name:d.name,options:d.options,storage:d.storage,extensions:i},p=te(d,"addGlobalAttributes",u);if(!p)return;p().forEach(h=>{let g;Array.isArray(h.types)?g=h.types:h.types==="*"?g=c:h.types==="nodes"?g=o:h.types==="marks"?g=l:g=[],g.forEach(y=>
17639{Object.entries(h.attributes).forEach(([x,v])=>{e.push({type:y,name:x,attribute:{...r,...v}})})})})}),i.forEach(d=>{const u={name:d.name,options:d.options,storage:d.storage},p=te(d,"addAttributes",u);if(!p)return;const m=p();Object.entries(m).forEach(([h,g])=>{const y={...r,...g};typeof(y==null?void 0:y.default)=="function"&&(y.default=y.default()),y!=null&&y.isRequired&&(y==null?void 0:y.default)===void 0&&delete y.default,e.push({type:d.name,name:h,attribute:y})})}),e}function ple(t){const e=[];let a="",n=!1,i=!1,r=0;const o=t.length;for(let l=0;l<o;l+=1){const c=t[l];if(c==="'"&&!i){n=!n,a+=c;continue}if(c==='"'&&!n){i=!i,a+=c;continue}if(!n&&!i){if(c==="("){r+=1,a+=c;continue}if(c===")"&&r>0){r-=1,a+=c;continue}if(c===";"&&r===0){e.push(a),a="";continue}}a+=c}return a&&e.push(a),e}function ST(t){const e=[],a=ple(t||""),n=a.length;for(let i=0;i<n;i+=1){const r=a[i],o=r.indexOf(":");if(o===-1)continue;const l=r.slice(0,o).trim(),c=r.slice(o+1).trim();l&&c&&e.push([l,c])}return e}function ct(...t){return t.filter(e=>!!e).reduce((e,a)=>{const n={...e};return Object.entries(a).forEach(([i,r])=>{if(!n[i]){n[i]=r;return}if(i==="class"){const l=r?String(r).split(" "):[],c=n[i]?n[i].split(" "):[],d=l.filter(u=>!c.includes(u));n[i]=[...c,...d].join(" ")}else if(i==="style"){const l=new Map([...ST(n[i]),...ST(r)]);n[i]=Array.from(l.entries()).map(([c,d])=>`${c}: ${d}`).join("; ")}else n[i]=r}),n},{})}function xu(t,e){return e.filter(a=>a.type===t.type.name).filter(a=>a.attribute.rendered).map(a=>a.attribute.renderHTML?a.attribute.renderHTML(t.attrs)||{}:{[a.name]:t.attrs[a.name]}).reduce((a,n)=>ct(a,n),{})}function mle(t){return typeof t!="string"?t:t.match(/^[+-]?(?:\d*\.)?\d+$/)?Number(t):t==="true"?!0:t==="false"?!1:t}function _T(t,e){return"style"in t?t:{...t,getAttrs:a=>{const n=t.getAttrs?t.getAttrs(a):t.attrs;if(n===!1)return!1;const i=e.reduce((r,o)=>{const l=o.attribute.parseHTML?o.attribute.parseHTML(a):mle(a.getAttribute(o.name));return l==null?r:{...r,[o.name]:l}},{});return{...n,...i}}}}function AT(t){return Object.fromEntries(Object.entries(t).filter(([e,a])=>e==="attrs"&&ule(a)?!1:a!=null))}function ET(t){var e,a;const n={};return!((e=t==null?void 0:t.attribute)!=null&&e.isRequired)&&"default"in((t==null?void 0:t.attribute)||{})&&(n.default=t.attribute.default),((a=t==null?void 0:t.attribute)==null?void 0:a.validate)!==void 0&&(n.validate=t.attribute.validate),[t.name,n]}function hle(t,e){var a;const n=S5(t),{nodeExtensions:i,markExtensions:r}=Ol(t),o=(a=i.find(d=>te(d,"topNode")))==null?void 0:a.name,l=Object.fromEntries(i.map(d=>{const u=n.filter(v=>v.type===d.name),p={name:d.name,options:d.options,storage:d.storage,editor:e},m=t.reduce((v,w)=>{const S=te(w,"extendNodeSchema",p);return{...v,...S?S(d):{}}},{}),h=AT({...m,content:Pe(te(d,"content",p)),marks:Pe(te(d,"marks",p)),group:Pe(te(d,"group",p)),inline:Pe(te(d,"inline",p)),atom:Pe(te(d,"atom",p)),selectable:Pe(te(d,"selectable",p)),draggable:Pe(te(d,"draggable",p)),code:Pe(te(d,"code",p)),whitespace:Pe(te(d,"whitespace",p)),linebreakReplacement:Pe(te(d,"linebreakReplacement",p)),defining:Pe(te(d,"defining",p)),isolating:Pe(te(d,"isolating",p)),attrs:Object.fromEntries(u.map(ET))}),g=Pe(te(d,"parseHTML",p));g&&(h.parseDOM=g.map(v=>_T(v,u)));const y=te(d,"renderHTML",p);y&&(h.toDOM=v=>y({node:v,HTMLAttributes:xu(v,u)}));const x=te(d,"renderText",p);return x&&(h.toText=x),[d.name,h]})),c=Object.fromEntries(r.map(d=>{const u=n.filter(x=>x.type===d.name),p={name:d.name,options:d.options,storage:d.storage,editor:e},m=t.reduce((x,v)=>{const w=te(v,"extendMarkSchema",p);return{...x,...w?w(d):{}}},{}),h=AT({...m,inclusive:Pe(te(d,"inclusive",p)),excludes:Pe(te(d,"excludes",p)),group:Pe(te(d,"group",p)),spanning:Pe(te(d,"spanning",p)),code:Pe(te(d,"code",p)),attrs:Object.fromEntries(u.map(ET))}),g=Pe(te(d,"parseHTML",p));g&&(h.parseDOM=g.map(x=>_T(x,u)));const y=te(d,"renderHTML",p);return y&&(h.toDOM=x=>y({mark:x,HTMLAttributes:xu(x,u)})),[d.name,h]}));return new tM({topNode:o,nodes:l,marks:c})}function fle(t){const e=t.filter((a,n)=>t.indexOf(a)!==n);return Array.from(new Set(e))}function Sd(t){return t.sort((a,n)=>{const i=te(a,"priority")||100,r=te(n,"priority")||100;return i>r?-1:i<r?1:0})}function _5(t){const e=Sd(gS(t)),a=fle(e.map(n=>n.name));return a.length&&console.warn(`[tiptap warn]: Duplicate extension names found: [${a.map(n=>`'${n}'`).join(", ")}]. This can lead to issues.`),e}function A5(t,e,a){const{from:n,to:i}=e,{blockSeparator:r=` 17640
17641`,textSerializers:o={}}=a||{};let l="";return t.nodesBetween(n,i,(c,d,u,p)=>{var m;c.isBlock&&d>n&&(l+=r);const h=o==null?void 0:o[c.type.name];if(h)return u&&(l+=h({node:c,pos:d,parent:u,index:p,range:e})),!1;c.isText&&(l+=(m=c==null?void 0:c.text)==null?void 0:m.slice(Math.max(n,d)-d,i-d))}),l}function gle(t,e){const a={from:0,to:t.content.size};return A5(t,a,e)}function E5(t){return Object.fromEntries(Object.entries(t.nodes).filter(([,e])=>e.spec.toText).map(([e,a])=>[e,a.spec.toText]))}function yle(t,e){const a=vt(e,t.schema),{from:n,to:i}=t.selection,r=[];t.doc.nodesBetween(n,i,l=>{r.push(l)});const o=r.reverse().find(l=>l.type.name===a.name);return o?{...o.attrs}:{}}function C5(t,e){const a=Wg(typeof e=="string"?e:e.name,t.schema);return a==="node"?yle(t,e):a==="mark"?b5(t,e):{}}function xle(t,e=JSON.stringify){const a={};return t.filter(n=>{const i=e(n);return Object.prototype.hasOwnProperty.call(a,i)?!1:a[i]=!0})}function vle(t){const e=xle(t);return e.length===1?e:e.filter((a,n)=>!e.filter((r,o)=>o!==n).some(r=>a.oldRange.from>=r.oldRange.from&&a.oldRange.to<=r.oldRange.to&&a.newRange.from>=r.newRange.from&&a.newRange.to<=r.newRange.to))}function j5(t){const{mapping:e,steps:a}=t,n=[];return e.maps.forEach((i,r)=>{const o=[];if(i.ranges.length)i.forEach((l,c)=>{o.push({from:l,to:c})});else{const{from:l,to:c}=a[r];if(l===void 0||c===void 0)return;o.push({from:l,to:c})}o.forEach(({from:l,to:c})=>{const d=e.slice(r).map(l,-1),u=e.slice(r).map(c),p=e.invert().map(d,-1),m=e.invert().map(u);n.push({oldRange:{from:p,to:m},newRange:{from:d,to:u}})})}),vle(n)}function xS(t,e,a){const n=[];return t===e?a.resolve(t).marks().forEach(i=>{const r=a.resolve(t),o=fS(r,i.type);o&&n.push({mark:i,...o})}):a.nodesBetween(t,e,(i,r)=>{!i||(i==null?void 0:i.nodeSize)===void 0||n.push(...i.marks.map(o=>({from:r,to:r+i.nodeSize,mark:o})))}),n}var ble=(t,e,a,n=20)=>{const i=t.doc.resolve(a);let r=n,o=null;for(;r>0&&o===null;){const l=i.node(r);(l==null?void 0:l.type.name)===e?o=l:r-=1}return[o,r]};function Ic(t,e){return e.nodes[t]||e.marks[t]||null}function $m(t,e,a){return Object.fromEntries(Object.entries(a).filter(([n])=>{const i=t.find(r=>r.type===e&&r.name===n);return i?i.attribute.keepOnSplit:!1}))}var wle=(t,e=500)=>{let a="";const n=t.parentOffset;return t.parent.nodesBetween(Math.max(0,n-e),n,(i,r,o,l)=>{var c,d;const u=((d=(c=i.type.spec).toText)==null?void 0:d.call(c,{node:i,pos:r,parent:o,index:l}))||i.textContent||"%leaf%";a+=i.isAtom&&!i.isText?u:u.slice(0,Math.max(0,n-r))}),a};function zb(t,e,a={}){const{empty:n,ranges:i}=t.selection,r=e?$i(e,t.schema):null;if(n)return!!(t.storedMarks||t.selection.$from.marks()).filter(p=>r?r.name===p.type.name:!0).find(p=>of(p.attrs,a,{strict:!1}));let o=0;const l=[];if(i.forEach(({$from:p,$to:m})=>{const h=p.pos,g=m.pos;t.doc.nodesBetween(h,g,(y,x)=>{if(r&&y.inlineContent&&!y.type.allowsMarkType(r))return!1;if(!y.isText&&!y.marks.length)return;const v=Math.max(h,x),w=Math.min(g,x+y.nodeSize),S=w-v;o+=S,l.push(...y.marks.map(T=>({mark:T,from:v,to:w})))})}),o===0)return!1;const c=l.filter(p=>r?r.name===p.mark.type.name:!0).filter(p=>of(p.mark.attrs,a,{strict:!1})).reduce((p,m)=>p+m.to-m.from,0),d=l.filter(p=>r?p.mark.type!==r&&p.mark.type.excludes(r):!0).reduce((p,m)=>p+m.to-m.from,0);return(c>0?c+d:c)>=o}function kle(t,e,a={}){if(!e)return $r(t,null,a)||zb(t,null,a);const n=Wg(e,t.schema);return n==="node"?$r(t,e,a):n==="mark"?zb(t,e,a):!1}var Sle=(t,e)=>{const{$from:a,$to:n,$anchor:i}=t.selection;if(e){const r=Gg(l=>l.type.name===e)(t.selection);if(!r)return!1;const o=t.doc.resolve(r.pos+1);return i.pos+1===o.end()}return!(n.parentOffset<n.parent.nodeSize-2||a.pos!==n.pos)},_le=t=>{const{$from:e,$to:a}=t.selection;return!(e.parentOffset>0||e.pos!==a.pos)};function CT(t,e){return Array.isArray(e)?e.some(a=>(typeof a=="string"?a:a.name)===t.name):e}function ix(t,e){const{nodeExtensions:a}=Ol(e),n=a.find(o=>o.name===t);if(!n)return!1;const i={name:n.name,options:n.options,storage:n.storage},r=Pe(te(n,"group",i));return typeof r!="string"?!1:r.split(" ").includes("list")}function Kg(t,{checkChildren:e=!0,ignoreWhitespace:a=!1}={}){var n;if(a){if(t.type.name==="hardBreak")return!0;
vendor: 43,382 bytes, lines 17641-17714
17641if(t.isText)return!/\S/.test((n=t.text)!=null?n:"")}if(t.isText)return!t.text;if(t.isAtom||t.isLeaf)return!1;if(t.content.childCount===0)return!0;if(e){let i=!0;return t.content.forEach(r=>{i!==!1&&(Kg(r,{ignoreWhitespace:a,checkChildren:e})||(i=!1))}),i}return!1}function T5(t){return t instanceof se}var N5=class I5{constructor(e){this.position=e}static fromJSON(e){return new I5(e.position)}toJSON(){return{position:this.position}}};function Ale(t,e){const a=e.mapping.mapResult(t.position);return{position:new N5(a.pos),mapResult:a}}function Ele(t){return new N5(t)}function Cle(t,e,a){var n;const{selection:i}=e;let r=null;if(g5(i)&&(r=i.$cursor),r){const l=(n=t.storedMarks)!=null?n:r.marks();return r.parent.type.allowsMarkType(a)&&(!!a.isInSet(l)||!l.some(d=>d.type.excludes(a)))}const{ranges:o}=i;return o.some(({$from:l,$to:c})=>{let d=l.depth===0?t.doc.inlineContent&&t.doc.type.allowsMarkType(a):!1;return t.doc.nodesBetween(l.pos,c.pos,(u,p,m)=>{if(d)return!1;if(u.isInline){const h=!m||m.type.allowsMarkType(a),g=!!a.isInSet(u.marks)||!u.marks.some(y=>y.type.excludes(a));d=h&&g}return!d}),d})}var jle=(t,e={})=>({tr:a,state:n,dispatch:i})=>{const{selection:r}=a,{empty:o,ranges:l}=r,c=$i(t,n.schema);if(i)if(o){const d=b5(n,c);a.addStoredMark(c.create({...d,...e}))}else l.forEach(d=>{const u=d.$from.pos,p=d.$to.pos;n.doc.nodesBetween(u,p,(m,h)=>{const g=Math.max(h,u),y=Math.min(h+m.nodeSize,p);m.marks.find(v=>v.type===c)?m.marks.forEach(v=>{c===v.type&&a.addMark(g,y,c.create({...v.attrs,...e}))}):a.addMark(g,y,c.create(e))})});return Cle(n,a,c)},Tle=(t,e)=>({tr:a})=>(a.setMeta(t,e),!0),Nle=(t,e={})=>({state:a,dispatch:n,chain:i})=>{const r=vt(t,a.schema);let o;return a.selection.$anchor.sameParent(a.selection.$head)&&(o=a.selection.$anchor.parent.attrs),r.isTextblock?i().command(({commands:l})=>Vj(r,{...o,...e})(a)?!0:l.clearNodes()).command(({state:l})=>Vj(r,{...o,...e})(l,n)).run():(console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.'),!1)},Ile=t=>({tr:e,dispatch:a})=>{if(a){const{doc:n}=e,i=jo(t,0,n.content.size),r=se.create(n,i);e.setSelection(r)}return!0},Ple=(t,e)=>({tr:a,state:n,dispatch:i})=>{const{selection:r}=n;let o,l;return typeof e=="number"?(o=e,l=e):e&&"from"in e&&"to"in e?(o=e.from,l=e.to):(o=r.from,l=r.to),i&&a.doc.nodesBetween(o,l,(c,d)=>{c.isText||a.setNodeMarkup(d,void 0,{...c.attrs,dir:t})}),!0},Rle=t=>({tr:e,dispatch:a})=>{if(a){const{doc:n}=e,{from:i,to:r}=typeof t=="number"?{from:t,to:t}:t,o=ce.atStart(n).from,l=ce.atEnd(n).to,c=jo(i,o,l),d=jo(r,o,l),u=ce.create(n,c,d);e.setSelection(u)}return!0},Lle=t=>({state:e,dispatch:a})=>{const n=vt(t,e.schema);return Ere(n)(e,a)};function jT(t,e){const a=t.storedMarks||t.selection.$to.parentOffset&&t.selection.$from.marks();if(a){const n=a.filter(i=>e==null?void 0:e.includes(i.type.name));t.tr.ensureMarks(n)}}var Ole=({keepMarks:t=!0}={})=>({tr:e,state:a,dispatch:n,editor:i})=>{const{selection:r,doc:o}=e,{$from:l,$to:c}=r,d=i.extensionManager.attributes,u=$m(d,l.node().type.name,l.node().attrs);if(r instanceof se&&r.node.isBlock)return!l.parentOffset||!Ii(o,l.pos)?!1:(n&&(t&&jT(a,i.extensionManager.splittableMarks),e.split(l.pos).scrollIntoView()),!0);if(!l.parent.isBlock)return!1;const p=c.parentOffset===c.parent.content.size,m=l.depth===0?void 0:lle(l.node(-1).contentMatchAt(l.indexAfter(-1)));let h=p&&m?[{type:m,attrs:u}]:void 0,g=Ii(e.doc,e.mapping.map(l.pos),1,h);if(!h&&!g&&Ii(e.doc,e.mapping.map(l.pos),1,m?[{type:m}]:void 0)&&(g=!0,h=m?[{type:m,attrs:u}]:void 0),n){if(g&&(r instanceof ce&&e.deleteSelection(),e.split(e.mapping.map(l.pos),1,h),m&&!p&&!l.parentOffset&&l.parent.type!==m)){const y=e.mapping.map(l.before()),x=e.doc.resolve(y);l.node(-1).canReplaceWith(x.index(),x.index()+1,m)&&e.setNodeMarkup(e.mapping.map(l.before()),m)}t&&jT(a,i.extensionManager.splittableMarks),e.scrollIntoView()}return g},Mle=(t,e={})=>({tr:a,state:n,dispatch:i,editor:r})=>{var o;const l=vt(t,n.schema),{$from:c,$to:d}=n.selection,u=n.selection.node;if(u&&u.isBlock||c.depth<2||!c.sameParent(d))return!1;const p=c.node(-1);if(p.type!==l)return!1;const m=r.extensionManager.attributes;if(c.parent.content.size===0&&c.node(-1).childCount===c.indexAfter(-1)){if(c.depth===2||c.node(-3).type!==l||c.index(-2)!==c.node(-2).childCount-1)return!1;if(i){let v=V.empty;const w=c.index(-1)?1:c.index(-2)?2:3;for(let E=c.depth-w;E>=c.depth-3;E-=1)v=V.from(c.node(E).copy(v));const S=c.indexAfter(-1)<c.node(-2).childCount?1:c.indexAfter(-2)<c.node(-3).childCount?2:3,T={...$m(m,c.node().type.name,c.node().attrs),...e},P=((o=l.contentMatch.defaultType)==null?void 0:o.createAndFill(T))||void 0;v=v.append(V.from(l.createAndFill(null,P)||void 0));const M=c.before(c.depth-(w-1));a.replace(M,c.after(-S),new K(v,4-w,0));let C=-1;a.doc.nodesBetween(M,a.doc.content.size,(E,j)=>{if(C>-1)return!1;E.isTextblock&&E.content.size===0&&(C=j+1)}),C>-1&&a.setSelection(ce.near(a.doc.resolve(C))),a.scrollIntoView()}return!0}const h=d.pos===c.end()?p.contentMatchAt(0).defaultType:null,g={...$m(m,p.type.name,p.attrs),...e},y={...$m(m,c.node().type.name,c.node().attrs),...e};a.delete(c.pos,d.pos);const x=h?[{type:l,attrs:g},{type:h,attrs:y}]:[{type:l,attrs:g}];if(!Ii(a.doc,c.pos,2))return!1;if(i){const{selection:v,storedMarks:w}=n,{splittableMarks:S}=r.extensionManager,T=w||v.$to.parentOffset&&v.$from.marks();if(a.split(c.pos,2,x).scrollIntoView(),!T||!i)return!0;const P=T.filter(M=>S.includes(M.type.name));a.ensureMarks(P)}return!0},rx=(t,e)=>{const a=Gg(o=>o.type===e)(t.selection);if(!a)return!0;const n=t.doc.resolve(Math.max(0,a.pos-1)).before(a.depth);if(n===void 0)return!0;const i=t.doc.nodeAt(n);return a.node.type===(i==null?void 0:i.type)&&eo(t.doc,a.pos)&&t.join(a.pos),!0},ox=(t,e)=>{const a=Gg(o=>o.type===e)(t.selection);if(!a)return!0;const n=t.doc.resolve(a.start).after(a.depth);if(n===void 0)return!0;const i=t.doc.nodeAt(n);return a.node.type===(i==null?void 0:i.type)&&eo(t.doc,n)&&t.join(n),!0};function Dle(t){const e=t.doc,a=e.firstChild;if(!a)return null;const n=e.resolve(1),i=e.resolve(a.nodeSize-1);return ce.between(n,i)}var qle=(t,e,a,n={})=>({editor:i,tr:r,state:o,dispatch:l,chain:c,commands:d,can:u})=>{const{extensions:p,splittableMarks:m}=i.extensionManager,h=vt(t,o.schema),g=vt(e,o.schema),{selection:y,storedMarks:x}=o,{$from:v,$to:w}=y,S=v.blockRange(w),T=x||y.$to.parentOffset&&y.$from.marks();if(!S)return!1;const P=Gg(R=>ix(R.type.name,p))(y),M=y.from===0&&y.to===o.doc.content.size,C=o.doc.content.content,E=C.length===1?C[0]:null,j=M&&E&&ix(E.type.name,p)?{node:E,pos:0}:null,N=P??j,L=!!P&&S.depth>=1&&S.depth-P.depth<=1,O=!!j;if((L||O)&&N){if(N.node.type===h)return M&&O?c().command(({tr:R,dispatch:G})=>{const ee=Dle(R);return ee?(R.setSelection(ee),G&&G(R),!0):!1}).liftListItem(g).run():d.liftListItem(g);if(ix(N.node.type.name,p)&&h.validContent(N.node.content))return c().command(()=>(r.setNodeMarkup(N.pos,h),!0)).command(()=>rx(r,h)).command(()=>ox(r,h)).run()}return!a||!T||!l?c().command(()=>u().wrapInList(h,n)?!0:d.clearNodes()).wrapInList(h,n).command(()=>rx(r,h)).command(()=>ox(r,h)).run():c().command(()=>{const R=u().wrapInList(h,n),G=T.filter(ee=>m.includes(ee.type.name));return r.ensureMarks(G),R?!0:d.clearNodes()}).wrapInList(h,n).command(()=>rx(r,h)).command(()=>ox(r,h)).run()},zle=(t,e={},a={})=>({state:n,commands:i})=>{const{extendEmptyMarkRange:r=!1}=a,o=$i(t,n.schema);return zb(n,o,e)?i.unsetMark(o,{extendEmptyMarkRange:r}):i.setMark(o,e)},Vle=(t,e,a={})=>({state:n,commands:i})=>{const r=vt(t,n.schema),o=vt(e,n.schema),l=$r(n,r,a);let c;return n.selection.$anchor.sameParent(n.selection.$head)&&(c=n.selection.$anchor.parent.attrs),l?i.setNode(o,c):i.setNode(r,{...c,...a})},Hle=(t,e={})=>({state:a,commands:n})=>{const i=vt(t,a.schema);return $r(a,i,e)?n.lift(i):n.wrapIn(i,e)},Fle=()=>({state:t,dispatch:e})=>{const a=t.plugins;for(let n=0;n<a.length;n+=1){const i=a[n];let r;if(i.spec.isInputRules&&(r=i.getState(t))){if(e){const o=t.tr,l=r.transform;for(let c=l.steps.length-1;c>=0;c-=1)o.step(l.steps[c].invert(l.docs[c]));if(r.text){const c=o.doc.resolve(r.from).marks();o.replaceWith(r.from,r.to,t.schema.text(r.text,c))}else o.delete(r.from,r.to)}return!0}}return!1},Ble=()=>({tr:t,dispatch:e})=>{const{selection:a}=t,{empty:n,ranges:i}=a;return n||e&&i.forEach(r=>{t.removeMark(r.$from.pos,r.$to.pos)}),!0},Ule=(t,e={})=>({tr:a,state:n,dispatch:i})=>{var r;const{extendEmptyMarkRange:o=!1}=e,{selection:l}=a,c=$i(t,n.schema),{$from:d,empty:u,ranges:p}=l;if(!i)return!0;if(u&&o){let{from:m,to:h}=l;const g=(r=d.marks().find(x=>x.type===c))==null?void 0:r.attrs,y=fS(d,c,g);y&&(m=y.from,h=y.to),a.removeMark(m,h,c)}else p.forEach(m=>{a.removeMark(m.$from.pos,m.$to.pos,c)});return a.removeStoredMark(c),!0},$le=t=>({tr:e,state:a,dispatch:n})=>{const{selection:i}=a;let r,o;return typeof t=="number"?(r=t,o=t):t&&"from"in t&&"to"in t?(r=t.from,o=t.to):(r=i.from,o=i.to),n&&e.doc.nodesBetween(r,o,(l,c)=>{if(l.isText)return;const d={...l.attrs};delete d.dir,e.setNodeMarkup(c,void 0,d)}),!0},Wle=(t,e={})=>({tr:a,state:n,dispatch:i})=>{let r=null,o=null;const l=Wg(typeof t=="string"?t:t.name,n.schema);if(!l)return!1;l==="node"&&(r=vt(t,n.schema)),l==="mark"&&(o=$i(t,n.schema));let c=!1;return a.selection.ranges.forEach(d=>{const u=d.$from.pos,p=d.$to.pos;let m,h,g,y;a.selection.empty?n.doc.nodesBetween(u,p,(x,v)=>{r&&r===x.type&&(c=!0,g=Math.max(v,u),y=Math.min(v+x.nodeSize,p),m=v,h=x)}):n.doc.nodesBetween(u,p,(x,v)=>{v<u&&r&&r===x.type&&(c=!0,g=Math.max(v,u),y=Math.min(v+x.nodeSize,p),m=v,h=x),v>=u&&v<=p&&(r&&r===x.type&&(c=!0,i&&a.setNodeMarkup(v,void 0,{...x.attrs,...e})),o&&x.marks.length&&x.marks.forEach(w=>{if(o===w.type&&(c=!0,i)){const S=Math.max(v,u),T=Math.min(v+x.nodeSize,p);a.addMark(S,T,o.create({...w.attrs,...e}))}}))}),h&&(m!==void 0&&i&&a.setNodeMarkup(m,void 0,{...h.attrs,...e}),o&&h.marks.length&&h.marks.forEach(x=>{o===x.type&&i&&a.addMark(g,y,o.create({...x.attrs,...e}))}))}),c},Gle=(t,e={})=>({state:a,dispatch:n})=>{const i=vt(t,a.schema);return vre(i,e)(a,n)},Kle=(t,e={})=>({state:a,dispatch:n})=>{const i=vt(t,a.schema);return bre(i,e)(a,n)},Jle=class{constructor(){this.callbacks={}}on(t,e){return this.callbacks[t]||(this.callbacks[t]=[]),this.callbacks[t].push(e),this}emit(t,...e){const a=this.callbacks[t];return a&&a.forEach(n=>n.apply(this,e)),this}off(t,e){const a=this.callbacks[t];return a&&(e?this.callbacks[t]=a.filter(n=>n!==e):delete this.callbacks[t]),this}once(t,e){const a=(...n)=>{this.off(t,a),e.apply(this,n)};return this.on(t,a)}removeAllListeners(){this.callbacks={}}},Jg=class{constructor(t){var e;this.find=t.find,this.handler=t.handler,this.undoable=(e=t.undoable)!=null?e:!0}},Qle=(t,e)=>{if(hS(e))return e.exec(t);const a=e(t);if(!a)return null;const n=[a.text];return n.index=a.index,n.input=t,n.data=a.data,a.replaceWith&&(a.text.includes(a.replaceWith)||console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'),n.push(a.replaceWith)),n};function tm(t){var e;const{editor:a,from:n,to:i,text:r,rules:o,plugin:l}=t,{view:c}=a;if(c.composing)return!1;const d=c.state.doc.resolve(n);if(d.parent.type.spec.code||(e=d.nodeBefore||d.nodeAfter)!=null&&e.marks.find(m=>m.type.spec.code))return!1;let u=!1;const p=wle(d)+r;return o.forEach(m=>{if(u)return;const h=Qle(p,m.find);if(!h)return;const g=c.state.tr,y=Ug({state:c.state,transaction:g}),x={from:n-(h[0].length-r.length),to:i},{commands:v,chain:w,can:S}=new $g({editor:a,state:y});m.handler({state:y,range:x,match:h,commands:v,chain:w,can:S})===null||!g.steps.length||(m.undoable&&g.setMeta(l,{transform:g,from:n,to:i,text:r}),c.dispatch(g),u=!0)}),u}function Xle(t){const{editor:e,rules:a}=t,n=new at({state:{init(){return null},apply(i,r,o){const l=i.getMeta(n);if(l)return l;const c=i.getMeta("applyInputRules");return!!c&&setTimeout(()=>{let{text:u}=c;typeof u=="string"?u=u:u=yS(V.from(u),o.schema);const{from:p}=c,m=p+u.length;tm({editor:e,from:p,to:m,text:u,rules:a,plugin:n})}),i.selectionSet||i.docChanged?null:r}},props:{handleTextInput(i,r,o,l){return tm({editor:e,from:r,to:o,text:l,rules:a,plugin:n})},handleDOMEvents:{compositionend:i=>(setTimeout(()=>{const{$cursor:r}=i.state.selection;r&&tm({editor:e,from:r.pos,to:r.pos,text:"",rules:a,plugin:n})}),!1)},handleKeyDown(i,r){if(r.key!=="Enter")return!1;const{$cursor:o}=i.state.selection;return o?tm({editor:e,from:o.pos,to:o.pos,text:` 17642`,rules:a,plugin:n}):!1}},isInputRules:!0});return n}function Yle(t){return Object.prototype.toString.call(t).slice(8,-1)}function am(t){return Yle(t)!=="Object"?!1:t.constructor===Object&&Object.getPrototypeOf(t)===Object.prototype}function P5(t,e){const a={...t};return am(t)&&am(e)&&Object.keys(e).forEach(n=>{am(e[n])&&am(t[n])?a[n]=P5(t[n],e[n]):a[n]=e[n]}),a}var vS=class{constructor(t={}){this.type="extendable",this.parent=null,this.child=null,this.name="",this.config={name:this.name},this.config={...this.config,...t},this.name=this.config.name}get options(){return{...Pe(te(this,"addOptions",{name:this.name}))||{}}}get storage(){return{...Pe(te(this,"addStorage",{name:this.name,options:this.options}))||{}}}configure(t={}){const e=this.extend({...this.config,addOptions:()=>P5(this.options,t)});return e.name=this.name,e.parent=this.parent,e}extend(t={}){const e=new this.constructor({...this.config,...t});return e.parent=this,this.child=e,e.name="name"in t?t.name:e.parent.name,e}},ao=class R5 extends vS{constructor(){super(...arguments),this.type="mark"}static create(e={}){const a=typeof e=="function"?e():e;return new R5(a)}static handleExit({editor:e,mark:a}){const{tr:n}=e.state,i=e.state.selection.$from;if(i.pos===i.end()){const o=i.marks();if(!!!o.find(d=>(d==null?void 0:d.type.name)===a.name))return!1;const c=o.find(d=>(d==null?void 0:d.type.name)===a.name);return c&&n.removeStoredMark(c),n.insertText(" ",i.pos),e.view.dispatch(n),!0}return!1}configure(e){return super.configure(e)}extend(e){const a=typeof e=="function"?e():e;return super.extend(a)}};function Zle(t){return typeof t=="number"}var ece=class{constructor(t){this.find=t.find,this.handler=t.handler}},tce=(t,e,a)=>{if(hS(e))return[...t.matchAll(e)];const n=e(t,a);return n?n.map(i=>{const r=[i.text];return r.index=i.index,r.input=t,r.data=i.data,i.replaceWith&&(i.text.includes(i.replaceWith)||console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".'),r.push(i.replaceWith)),r}):[]};function ace(t){const{editor:e,state:a,from:n,to:i,rule:r,pasteEvent:o,dropEvent:l}=t,{commands:c,chain:d,can:u}=new $g({editor:e,state:a}),p=[];return a.doc.nodesBetween(n,i,(h,g)=>{var y,x,v,w,S;if((x=(y=h.type)==null?void 0:y.spec)!=null&&x.code||!(h.isText||h.isTextblock||h.isInline))return;const T=(S=(w=(v=h.content)==null?void 0:v.size)!=null?w:h.nodeSize)!=null?S:0,P=Math.max(n,g),M=Math.min(i,g+T);if(P>=M)return;const C=h.isText?h.text||"":h.textBetween(P-g,M-g,void 0,"");tce(C,r.find,o).forEach(j=>{if(j.index===void 0)return;const N=P+j.index+1,L=N+j[0].length,O={from:a.tr.mapping.map(N),to:a.tr.mapping.map(L)},R=r.handler({state:a,range:O,match:j,commands:c,chain:d,can:u,pasteEvent:o,dropEvent:l});p.push(R)})}),p.every(h=>h!==null)}var nm=null,nce=t=>{var e;const a=new ClipboardEvent("paste",{clipboardData:new DataTransfer});return(e=a.clipboardData)==null||e.setData("text/html",t),a};function ice(t){const{editor:e,rules:a}=t;let n=null,i=!1,r=!1,o=typeof ClipboardEvent<"u"?new ClipboardEvent("paste"):null,l;try{l=typeof DragEvent<"u"?new DragEvent("drop"):null}catch{l=null}const c=({state:u,from:p,to:m,rule:h,pasteEvt:g})=>{const y=u.tr,x=Ug({state:u,transaction:y});if(!(!ace({editor:e,state:x,from:Math.max(p-1,0),to:m.b-1,rule:h,pasteEvent:g,dropEvent:l})||!y.steps.length)){try{l=typeof DragEvent<"u"?new DragEvent("drop"):null}catch{l=null}return o=typeof ClipboardEvent<"u"?new ClipboardEvent("paste"):null,y}};return a.map(u=>new at({view(p){const m=g=>{var y;n=(y=p.dom.parentElement)!=null&&y.contains(g.target)?p.dom.parentElement:null,n&&(nm=e)},h=()=>{nm&&(nm=null)};return window.addEventListener("dragstart",m),window.addEventListener("dragend",h),{destroy(){window.removeEventListener("dragstart",m),window.removeEventListener("dragend",h)}}},props:{handleDOMEvents:{drop:(p,m)=>{if(r=n===p.dom.parentElement,l=m,!r){const h=nm;h!=null&&h.isEditable&&setTimeout(()=>{const g=h.state.selection;g&&h.commands.deleteRange({from:g.from,to:g.to})},10)}return!1},paste:(p,m)=>{var h;const g=(h=m.clipboardData)==null?void 0:h.getData("text/html");return o=m,i=!!(g!=null&&g.includes("data-pm-slice")),!1}}},appendTransaction:(p,m,h)=>{const g=p[0],y=g.getMeta("uiEvent")==="paste"&&!i,x=g.getMeta("uiEvent")==="drop"&&!r,v=g.getMeta("applyPasteRules"),w=!!v;if(!y&&!x&&!w)return;if(w){let{text:P}=v;typeof P=="string"?P=P:P=yS(V.from(P),h.schema);const{from:M}=v,C=M+P.length,E=nce(P);return c({rule:u,state:h,from:M,to:{b:C},pasteEvt:E})}const S=m.doc.content.findDiffStart(h.doc.content),T=m.doc.content.findDiffEnd(h.doc.content);if(!(!Zle(S)||!T||S===T.b))return c({rule:u,state:h,from:S,to:T,pasteEvt:o})}}))}var Qg=class{constructor(t,e){this.splittableMarks=[],this.editor=e,this.baseExtensions=t,this.extensions=_5(t),this.schema=hle(this.extensions,e),this.setupExtensions()}get commands(){return this.extensions.reduce((t,e)=>{const a={name:e.name,options:e.options,storage:this.editor.extensionStorage[e.name],editor:this.editor,type:Ic(e.name,this.schema)},n=te(e,"addCommands",a);return n?{...t,...n()}:t},{})}get plugins(){const{editor:t}=this;return Sd([...this.extensions].reverse()).flatMap(n=>{const i={name:n.name,options:n.options,storage:this.editor.extensionStorage[n.name],editor:t,type:Ic(n.name,this.schema)},r=[],o=te(n,"addKeyboardShortcuts",i);let l={};if(n.type==="mark"&&te(n,"exitable",i)&&(l.ArrowRight=()=>ao.handleExit({editor:t,mark:n})),o){const m=Object.fromEntries(Object.entries(o()).map(([h,g])=>[h,()=>g({editor:t})]));l={...l,...m}}const c=gse(l);r.push(c);const d=te(n,"addInputRules",i);if(CT(n,t.options.enableInputRules)&&d){const m=d();if(m&&m.length){const h=Xle({editor:t,rules:m}),g=Array.isArray(h)?h:[h];r.push(...g)}}const u=te(n,"addPasteRules",i);if(CT(n,t.options.enablePasteRules)&&u){const m=u();if(m&&m.length){const h=ice({editor:t,rules:m});r.push(...h)}}const p=te(n,"addProseMirrorPlugins",i);if(p){const m=p();r.push(...m)}return r})}get attributes(){return S5(this.extensions)}get nodeViews(){const{editor:t}=this,{nodeExtensions:e}=Ol(this.extensions);return Object.fromEntries(e.filter(a=>!!te(a,"addNodeView")).map(a=>{const n=this.attributes.filter(c=>c.type===a.name),i={name:a.name,options:a.options,storage:this.editor.extensionStorage[a.name],editor:t,type:vt(a.name,this.schema)},r=te(a,"addNodeView",i);if(!r)return[];const o=r();if(!o)return[];const l=(c,d,u,p,m)=>{const h=xu(c,n);return o({node:c,view:d,getPos:u,decorations:p,innerDecorations:m,editor:t,extension:a,HTMLAttributes:h})};return[a.name,l]}))}dispatchTransaction(t){const{editor:e}=this;return Sd([...this.extensions].reverse()).reduceRight((n,i)=>{const r={name:i.name,options:i.options,storage:this.editor.extensionStorage[i.name],editor:e,type:Ic(i.name,this.schema)},o=te(i,"dispatchTransaction",r);return o?l=>{o.call(r,{transaction:l,next:n})}:n},t)}transformPastedHTML(t){const{editor:e}=this;return Sd([...this.extensions]).reduce((n,i)=>{const r={name:i.name,options:i.options,storage:this.editor.extensionStorage[i.name],editor:e,type:Ic(i.name,this.schema)},o=te(i,"transformPastedHTML",r);return o?(l,c)=>{const d=n(l,c);return o.call(r,d)}:n},t||(n=>n))}get markViews(){const{editor:t}=this,{markExtensions:e}=Ol(this.extensions);return Object.fromEntries(e.filter(a=>!!te(a,"addMarkView")).map(a=>{const n=this.attributes.filter(l=>l.type===a.name),i={name:a.name,options:a.options,storage:this.editor.extensionStorage[a.name],editor:t,type:$i(a.name,this.schema)},r=te(a,"addMarkView",i);if(!r)return[];const o=(l,c,d)=>{const u=xu(l,n);return r()({mark:l,view:c,inline:d,editor:t,extension:a,HTMLAttributes:u,updateAttributes:p=>{vce(l,t,p)}})};return[a.name,o]}))}setupExtensions(){const t=this.extensions;this.editor.extensionStorage=Object.fromEntries(t.map(e=>[e.name,e.storage])),t.forEach(e=>{var a;const n={name:e.name,options:e.options,storage:this.editor.extensionStorage[e.name],editor:this.editor,type:Ic(e.name,this.schema)};e.type==="mark"&&((a=Pe(te(e,"keepOnSplit",n)))==null||a)&&this.splittableMarks.push(e.name);const i=te(e,"onBeforeCreate",n),r=te(e,"onCreate",n),o=te(e,"onUpdate",n),l=te(e,"onSelectionUpdate",n),c=te(e,"onTransaction",n),d=te(e,"onFocus",n),u=te(e,"onBlur",n),p=te(e,"onDestroy",n);i&&this.editor.on("beforeCreate",i),r&&this.editor.on("create",r),o&&this.editor.on("update",o),l&&this.editor.on("selectionUpdate",l),c&&this.editor.on("transaction",c),d&&this.editor.on("focus",d),u&&this.editor.on("blur",u),p&&this.editor.on("destroy",p)})}};Qg.resolve=_5;Qg.sort=Sd;Qg.flatten=gS;var rce={};mS(rce,{ClipboardTextSerializer:()=>O5,Commands:()=>M5,Delete:()=>D5,Drop:()=>q5,Editable:()=>z5,FocusEvents:()=>H5,Keymap:()=>F5,Paste:()=>B5,Tabindex:()=>U5,TextDirection:()=>$5,focusEventsPluginKey:()=>V5});var ze=class L5 extends vS{constructor(){super(...arguments),this.type="extension"}static create(e={}){const a=typeof e=="function"?e():e;return new L5(a)}configure(e){return super.configure(e)}extend(e){const a=typeof e=="function"?e():e;return super.extend(a)}},O5=ze.create({name:"clipboardTextSerializer",addOptions(){return{blockSeparator:void 0}},addProseMirrorPlugins(){return[new at({key:new _t("clipboardTextSerializer"),props:{clipboardTextSerializer:()=>{const{editor:t}=this,{state:e,schema:a}=t,{doc:n,selection:i}=e,{ranges:r}=i,o=Math.min(...r.map(u=>u.$from.pos)),l=Math.max(...r.map(u=>u.$to.pos)),c=E5(a);return A5(n,{from:o,to:l},{...this.options.blockSeparator!==void 0?{blockSeparator:this.options.blockSeparator}:{},textSerializers:c})}}})]}}),M5=ze.create({name:"commands",addCommands(){return{...h5}}}),D5=ze.create({name:"delete",onUpdate({transaction:t,appendedTransactions:e}){var a,n,i;const r=()=>{var o,l,c,d;if((d=(c=(l=(o=this.editor.options.coreExtensionOptions)==null?void 0:o.delete)==null?void 0:l.filterTransaction)==null?void 0:c.call(l,t))!=null?d:t.getMeta("y-sync$"))return;const u=w5(t.before,[t,...e]);j5(u).forEach(h=>{u.mapping.mapResult(h.oldRange.from).deletedAfter&&u.mapping.mapResult(h.oldRange.to).deletedBefore&&u.before.nodesBetween(h.oldRange.from,h.oldRange.to,(g,y)=>{const x=y+g.nodeSize-2,v=h.oldRange.from<=y&&x<=h.oldRange.to;this.editor.emit("delete",{type:"node",node:g,from:y,to:x,newFrom:u.mapping.map(y),newTo:u.mapping.map(x),deletedRange:h.oldRange,newRange:h.newRange,partial:!v,editor:this.editor,transaction:t,combinedTransform:u})})});const m=u.mapping;u.steps.forEach((h,g)=>{var y,x;if(h instanceof jn){const v=m.slice(g).map(h.from,-1),w=m.slice(g).map(h.to),S=m.invert().map(v,-1),T=m.invert().map(w),P=v>0?(y=u.doc.nodeAt(v-1))==null?void 0:y.marks.some(C=>C.eq(h.mark)):!1,M=(x=u.doc.nodeAt(w))==null?void 0:x.marks.some(C=>C.eq(h.mark));this.editor.emit("delete",{type:"mark",mark:h.mark,from:h.from,to:h.to,deletedRange:{from:S,to:T},newRange:{from:v,to:w},partial:!!(M||P),editor:this.editor,transaction:t,combinedTransform:u})}})};(i=(n=(a=this.editor.options.coreExtensionOptions)==null?void 0:a.delete)==null?void 0:n.async)==null||i?setTimeout(r,0):r()}}),q5=ze.create({name:"drop",addProseMirrorPlugins(){return[new at({key:new _t("tiptapDrop"),props:{handleDrop:(t,e,a,n)=>{this.editor.emit("drop",{editor:this.editor,event:e,slice:a,moved:n})}}})]}}),z5=ze.create({name:"editable",addProseMirrorPlugins(){return[new at({key:new _t("editable"),props:{editable:()=>this.editor.options.editable}})]}}),V5=new _t("focusEvents"),H5=ze.create({name:"focusEvents",addProseMirrorPlugins(){const{editor:t}=this;return[new at({key:V5,props:{handleDOMEvents:{focus:(e,a)=>{t.isFocused=!0;const n=t.state.tr.setMeta("focus",{event:a}).setMeta("addToHistory",!1);return e.dispatch(n),!1},blur:(e,a)=>{t.isFocused=!1;const n=t.state.tr.setMeta("blur",{event:a}).setMeta("addToHistory",!1);return e.dispatch(n),!1}}}})]}}),F5=ze.create({name:"keymap",addKeyboardShortcuts(){const t=()=>this.editor.commands.first(({commands:o})=>[()=>o.undoInputRule(),()=>o.command(({tr:l})=>{const{selection:c,doc:d}=l,{empty:u,$anchor:p}=c,{pos:m,parent:h}=p,g=p.parent.isTextblock&&m>0?l.doc.resolve(m-1):p,y=g.parent.type.spec.isolating,x=p.pos-p.parentOffset,v=y&&g.parent.childCount===1?x===p.pos:xe.atStart(d).from===m;return!u||!h.type.isTextblock||h.textContent.length||!v||v&&p.parent.type.name==="paragraph"?!1:o.clearNodes()}),()=>o.deleteSelection(),()=>o.joinBackward(),()=>o.selectNodeBackward()]),e=()=>this.editor.commands.first(({commands:o})=>[()=>o.deleteSelection(),()=>o.deleteCurrentNode(),()=>o.joinForward(),()=>o.selectNodeForward()]),n={Enter:()=>this.editor.commands.first(({commands:o})=>[()=>o.newlineInCode(),()=>o.createParagraphNear(),()=>o.liftEmptyBlock(),()=>o.splitBlock()]),"Mod-Enter":()=>this.editor.commands.exitCode(),Backspace:t,"Mod-Backspace":t,"Shift-Backspace":t,Delete:e,"Mod-Delete":e,"Mod-a":()=>this.editor.commands.selectAll()},i={...n},r={...n,"Ctrl-h":t,"Alt-Backspace":t,"Ctrl-d":e,"Ctrl-Alt-Backspace":e,"Alt-Delete":e,"Alt-d":e,"Ctrl-a":()=>this.editor.commands.selectTextblockStart(),"Ctrl-e":()=>this.editor.commands.selectTextblockEnd()};return sf()||v5()?r:i},addProseMirrorPlugins(){return[new at({key:new _t("clearDocument"),appendTransaction:(t,e,a)=>{if(t.some(y=>y.getMeta("composition")))return;const n=t.some(y=>y.docChanged)&&!e.doc.eq(a.doc),i=t.some(y=>y.getMeta("preventClearDocument"));if(!n||i)return;const{empty:r,from:o,to:l}=e.selection,c=xe.atStart(e.doc).from,d=xe.atEnd(e.doc).to;if(r||!(o===c&&l===d)||!Kg(a.doc))return;const m=a.tr,h=Ug({state:a,transaction:m}),{commands:g}=new $g({editor:this.editor,state:h});if(g.clearNodes(),!!m.steps.length)return m}})]}}),B5=ze.create({name:"paste",addProseMirrorPlugins(){return[new at({key:new _t("tiptapPaste"),props:{handlePaste:(t,e,a)=>{this.editor.emit("paste",{editor:this.editor,event:e,slice:a})}}})]}}),U5=ze.create({name:"tabindex",addProseMirrorPlugins(){return[new at({key:new _t("tabindex"),props:{attributes:()=>this.editor.isEditable?{tabindex:"0"}:{}}})]}}),$5=ze.create({name:"textDirection",addOptions(){return{direction:void 0}},addGlobalAttributes(){if(!this.options.direction)return[];const{nodeExtensions:t}=Ol(this.extensions);return[{types:t.filter(e=>e.name!=="text").map(e=>e.name),attributes:{dir:{default:this.options.direction,parseHTML:e=>{const a=e.getAttribute("dir");return a&&(a==="ltr"||a==="rtl"||a==="auto")?a:this.options.direction},renderHTML:e=>e.dir?{dir:e.dir}:{}}}}]},addProseMirrorPlugins(){return[new at({key:new _t("textDirection"),props:{attributes:()=>{const t=this.options.direction;return t?{dir:t}:{}}}})]}}),oce=class Gc{constructor(e,a,n=!1,i=null){this.currentNode=null,this.actualDepth=null,this.isBlock=n,this.resolvedPos=e,this.editor=a,this.currentNode=i}get name(){return this.node.type.name}get node(){return this.currentNode||this.resolvedPos.node()}get element(){return this.editor.view.domAtPos(this.pos).node}get depth(){var e;return(e=this.actualDepth)!=null?e:this.resolvedPos.depth}get pos(){return this.resolvedPos.pos}get content(){return this.node.content}set content(e){let a=this.from,n=this.to;if(this.isBlock){if(this.content.size===0){console.error(`You canât set content on a block node. Tried to set content on ${this.name} at ${this.pos}`);return}a=this.from+1,n=this.to-1}this.editor.commands.insertContentAt({from:a,to:n},e)}get attributes(){return this.node.attrs}get textContent(){return this.node.textContent}get size(){return this.node.nodeSize}get from(){return this.isBlock?this.pos:this.resolvedPos.start(this.resolvedPos.depth)}get range(){return{from:this.from,to:this.to}}get to(){return this.isBlock?this.pos+this.size:this.resolvedPos.end(this.resolvedPos.depth)+(this.node.isText?0:1)}get parent(){if(this.depth===0)return null;const e=this.resolvedPos.start(this.resolvedPos.depth-1),a=this.resolvedPos.doc.resolve(e);return new Gc(a,this.editor)}get before(){let e=this.resolvedPos.doc.resolve(this.from-(this.isBlock?1:2));return e.depth!==this.depth&&(e=this.resolvedPos.doc.resolve(this.from-3)),new Gc(e,this.editor)}get after(){let e=this.resolvedPos.doc.resolve(this.to+(this.isBlock?2:1));return e.depth!==this.depth&&(e=this.resolvedPos.doc.resolve(this.to+3)),new Gc(e,this.editor)}get children(){const e=[];return this.node.content.forEach((a,n)=>{const i=a.isBlock&&!a.isTextblock,r=a.isAtom&&!a.isText,o=a.isInline,l=this.pos+n+(r?0:1);if(l<0||l>this.resolvedPos.doc.nodeSize-2)return;const c=this.resolvedPos.doc.resolve(l);if(!i&&!o&&c.depth<=this.depth)return;const d=new Gc(c,this.editor,i,i||o?a:null);i&&(d.actualDepth=this.depth+1),e.push(d)}),e}get firstChild(){return this.children[0]||null}get lastChild(){const e=this.children;return e[e.length-1]||null}closest(e,a={}){let n=null,i=this.parent;for(;i&&!n;){if(i.node.type.name===e)if(Object.keys(a).length>0){const r=i.node.attrs,o=Object.keys(a);for(let l=0;l<o.length;l+=1){const c=o[l];if(r[c]!==a[c])break}}else n=i;i=i.parent}return n}querySelector(e,a={}){return this.querySelectorAll(e,a,!0)[0]||null}querySelectorAll(e,a={},n=!1){let i=[];if(!this.children||this.children.length===0)return i;const r=Object.keys(a);return this.children.forEach(o=>{n&&i.length>0||(o.node.type.name===e&&r.every(c=>a[c]===o.node.attrs[c])&&i.push(o),!(n&&i.length>0)&&(i=i.concat(o.querySelectorAll(e,a,n))))}),i}setAttribute(e){const{tr:a}=this.editor.state;a.setNodeMarkup(this.from,void 0,{...this.node.attrs,...e}),this.editor.view.dispatch(a)}},sce=`.ProseMirror { 17643 position: relative; 17644} 17645 17646.ProseMirror { 17647 word-wrap: break-word; 17648 white-space: pre-wrap; 17649 white-space: break-spaces; 17650 -webkit-font-variant-ligatures: none; 17651 font-variant-ligatures: none; 17652 font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ 17653} 17654 17655.ProseMirror [contenteditable="false"] { 17656 white-space: normal; 17657} 17658 17659.ProseMirror [contenteditable="false"] [contenteditable="true"] { 17660 white-space: pre-wrap; 17661} 17662 17663.ProseMirror pre { 17664 white-space: pre-wrap; 17665} 17666 17667img.ProseMirror-separator { 17668 display: inline !important; 17669 border: none !important; 17670 margin: 0 !important; 17671 width: 0 !important; 17672 height: 0 !important; 17673} 17674 17675.ProseMirror-gapcursor { 17676 display: none; 17677 pointer-events: none; 17678 position: absolute; 17679 margin: 0; 17680} 17681 17682.ProseMirror-gapcursor:after { 17683 content: ""; 17684 display: block; 17685 position: absolute; 17686 top: -2px; 17687 width: 20px; 17688 border-top: 1px solid black; 17689 animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite; 17690} 17691 17692@keyframes ProseMirror-cursor-blink { 17693 to { 17694 visibility: hidden; 17695 } 17696} 17697 17698.ProseMirror-hideselection *::selection { 17699 background: transparent; 17700} 17701 17702.ProseMirror-hideselection *::-moz-selection { 17703 background: transparent; 17704} 17705 17706.ProseMirror-hideselection * { 17707 caret-color: transparent; 17708} 17709 17710.ProseMirror-focused .ProseMirror-gapcursor { 17711 display: block; 17712}`;function lce(t,e,a){const n=document.querySelector("style[data-tiptap-style]");if(n!==null)return n;const i=document.createElement("style");return e&&i.setAttribute("nonce",e),i.setAttribute("data-tiptap-style",""),i.innerHTML=t,document.getElementsByTagName("head")[0].appendChild(i),i}var cce=class extends Jle{constructor(t={}){super(),this.css=null,this.className="tiptap",this.editorView=null,this.isFocused=!1,this.isInitialized=!1,this.extensionStorage={},this.instanceId=Math.random().toString(36).slice(2,9),this.options={element:typeof document<"u"?document.createElement("div"):null,content:"",injectCSS:!0,injectNonce:void 0,extensions:[],autofocus:!1,editable:!0,textDirection:void 0,editorProps:{},parseOptions:{},coreExtensionOptions:{},enableInputRules:!0,enablePasteRules:!0,enableCoreExtensions:!0,enableContentCheck:!1,emitContentError:!1,onBeforeCreate:()=>null,onCreate:()=>null,onMount:()=>null,onUnmount:()=>null,onUpdate:()=>null,onSelectionUpdate:()=>null,onTransaction:()=>null,onFocus:()=>null,onBlur:()=>null,onDestroy:()=>null,onContentError:({error:n})=>{throw n},onPaste:()=>null,onDrop:()=>null,onDelete:()=>null,enableExtensionDispatchTransaction:!0},this.isCapturingTransaction=!1,this.capturedTransaction=null,this.utils={getUpdatedPosition:Ale,createMappablePosition:Ele},this.setOptions(t),this.createExtensionManager(),this.createCommandManager(),this.createSchema(),this.on("beforeCreate",this.options.onBeforeCreate),this.emit("beforeCreate",{editor:this}),this.on("mount",this.options.onMount),this.on("unmount",this.options.onUnmount),this.on("contentError",this.options.onContentError),this.on("create",this.options.onCreate),this.on("update",this.options.onUpdate),this.on("selectionUpdate",this.options.onSelectionUpdate),this.on("transaction",this.options.onTransaction),this.on("focus",this.options.onFocus),this.on("blur",this.options.onBlur),this.on("destroy",this.options.onDestroy),this.on("drop",({event:n,slice:i,moved:r})=>this.options.onDrop(n,i,r)),this.on("paste",({event:n,slice:i})=>this.options.onPaste(n,i)),this.on("delete",this.options.onDelete);const e=this.createDoc(),a=y5(e,this.options.autofocus);this.editorState=Qs.create({doc:e,schema:this.schema,selection:a||void 0}),this.options.element&&this.mount(this.options.element)}mount(t){if(typeof document>"u")throw new Error("[tiptap error]: The editor cannot be mounted because there is no 'document' defined in this environment.");this.createView(t),this.emit("mount",{editor:this}),this.css&&!document.head.contains(this.css)&&document.head.appendChild(this.css),window.setTimeout(()=>{this.isDestroyed||(this.options.autofocus!==!1&&this.options.autofocus!==null&&this.commands.focus(this.options.autofocus),this.emit("create",{editor:this}),this.isInitialized=!0)},0)}unmount(){if(this.editorView){const t=this.editorView.dom;t!=null&&t.editor&&delete t.editor,this.editorView.destroy()}if(this.editorView=null,this.isInitialized=!1,this.css&&!document.querySelectorAll(`.${this.className}`).length)try{typeof this.css.remove=="function"?this.css.remove():this.css.parentNode&&this.css.parentNode.removeChild(this.css)}catch(t){console.warn("Failed to remove CSS element:",t)}this.css=null,this.emit("unmount",{editor:this})}get storage(){return this.extensionStorage}get commands(){return this.commandManager.commands}chain(){return this.commandManager.chain()}can(){return this.commandManager.can()}injectCSS(){this.options.injectCSS&&typeof document<"u"&&(this.css=lce(sce,this.options.injectNonce))}setOptions(t={}){this.options={...this.options,...t},!(!this.editorView||!this.state||this.isDestroyed)&&(this.options.editorProps&&this.view.setProps(this.options.editorProps),this.view.updateState(this.state))}setEditable(t,e=!0){this.setOptions({editable:t}),e&&this.emit("update",{editor:this,transaction:this.state.tr,appendedTransactions:[]})}get isEditable(){return this.options.editable&&this.view&&this.view.editable}get view(){return this.editorView?this.editorView:new Proxy({state:this.editorState,updateState:t=>{this.editorState=t},dispatch:t=>{this.dispatchTransaction(t)},composing:!1,dragging:null,editable:!0,isDestroyed:!1},{get:(t,e)=>{if(this.editorView)return this.editorView[e];if(e==="state")return this.editorState;if(e in t)return Reflect.get(t,e);throw new Error(`[tiptap error]: The editor view is not available. Cannot access view['${e}']. The editor may not be mounted yet.`)}})}get state(){return this.editorView&&(this.editorState=this.view.state),this.editorState}registerPlugin(t,e){const a=k5(e)?e(t,[...this.state.plugins]):[...this.state.plugins,t],n=this.state.reconfigure({plugins:a});return this.view.updateState(n),n}unregisterPlugin(t){if(this.isDestroyed)return;const e=this.state.plugins;let a=e;if([].concat(t).forEach(i=>{const r=typeof i=="string"?`${i}$`:i.key;a=a.filter(o=>!o.key.startsWith(r))}),e.length===a.length)return;const n=this.state.reconfigure({plugins:a});return this.view.updateState(n),n}createExtensionManager(){var t,e;const n=[...this.options.enableCoreExtensions?[z5,O5.configure({blockSeparator:(e=(t=this.options.coreExtensionOptions)==null?void 0:t.clipboardTextSerializer)==null?void 0:e.blockSeparator}),M5,H5,F5,U5,q5,B5,D5,$5.configure({direction:this.options.textDirection})].filter(i=>typeof this.options.enableCoreExtensions=="object"?this.options.enableCoreExtensions[i.name]!==!1:!0):[],...this.options.extensions].filter(i=>["extension","node","mark"].includes(i==null?void 0:i.type));this.extensionManager=new Qg(n,this)}createCommandManager(){this.commandManager=new $g({editor:this})}createSchema(){this.schema=this.extensionManager.schema}createDoc(){let t;try{t=qb(this.options.content,this.schema,this.options.parseOptions,{errorOnInvalidContent:this.options.enableContentCheck})}catch(e){if(!(e instanceof Error)||!["[tiptap error]: Invalid JSON content","[tiptap error]: Invalid HTML content"].includes(e.message))throw e;this.emit("contentError",{editor:this,error:e,disableCollaboration:()=>{"collaboration"in this.storage&&typeof this.storage.collaboration=="object"&&this.storage.collaboration&&(this.storage.collaboration.isDisabled=!0),this.options.extensions=this.options.extensions.filter(a=>a.name!=="collaboration"),this.createExtensionManager()}}),t=qb(this.options.content,this.schema,this.options.parseOptions,{errorOnInvalidContent:!1})}return t}createView(t){const{editorProps:e,enableExtensionDispatchTransaction:a}=this.options,n=e.dispatchTransaction||this.dispatchTransaction.bind(this),i=a?this.extensionManager.dispatchTransaction(n):n,r=e.transformPastedHTML,o=this.extensionManager.transformPastedHTML(r);this.editorView=new p5(t,{...e,attributes:{role:"textbox",...e==null?void 0:e.attributes},dispatchTransaction:i,transformPastedHTML:o,state:this.editorState,markViews:this.extensionManager.markViews,nodeViews:this.extensionManager.nodeViews});const l=this.state.reconfigure({plugins:this.extensionManager.plugins});this.view.updateState(l),this.prependClass(),this.injectCSS();const c=this.view.dom;c.editor=this}createNodeViews(){this.view.isDestroyed||this.view.setProps({markViews:this.extensionManager.markViews,nodeViews:this.extensionManager.nodeViews})}prependClass(){this.view.dom.className=`${this.className} ${this.view.dom.className}`}captureTransaction(t){this.isCapturingTransaction=!0,t(),this.isCapturingTransaction=!1;const e=this.capturedTransaction;return this.capturedTransaction=null,e}dispatchTransaction(t){if(this.view.isDestroyed)return;if(this.isCapturingTransaction){if(!this.capturedTransaction){this.capturedTransaction=t;return}t.steps.forEach(d=>{var u;return(u=this.capturedTransaction)==null?void 0:u.step(d)});return}const{state:e,transactions:a}=this.state.applyTransaction(t),n=!this.state.selection.eq(e.selection),i=a.includes(t),r=this.state;if(this.emit("beforeTransaction",{editor:this,transaction:t,nextState:e}),!i)return;this.view.updateState(e),this.emit("transaction",{editor:this,transaction:t,appendedTransactions:a.slice(1)}),n&&this.emit("selectionUpdate",{editor:this,transaction:t});const o=a.findLast(d=>d.getMeta("focus")||d.getMeta("blur")),l=o==null?void 0:o.getMeta("focus"),c=o==null?void 0:o.getMeta("blur");l&&this.emit("focus",{editor:this,event:l.event,transaction:o}),c&&this.emit("blur",{editor:this,event:c.event,transaction:o}),!(t.getMeta("preventUpdate")||!a.some(d=>d.docChanged)||r.doc.eq(e.doc))&&this.emit("update",{editor:this,transaction:t,appendedTransactions:a.slice(1)})}getAttributes(t){return C5(this.state,t)}isActive(t,e){const a=typeof t=="string"?t:null,n=typeof t=="string"?e:t;return kle(this.state,a,n)}getJSON(){return this.state.doc.toJSON()}getHTML(){return yS(this.state.doc.content,this.schema)}getText(t){const{blockSeparator:e=` 17713 17714`,textSerializers:a={}}=t||{};return gle(this.state.doc,{blockSeparator:e,textSerializers:{...E5(this.schema),...a}})}get isEmpty(){return Kg(this.state.doc)}destroy(){this.emit("destroy"),this.unmount(),this.removeAllListeners()}get isDestroyed(){var t,e;return(e=(t=this.editorView)==null?void 0:t.isDestroyed)!=null?e:!0}$node(t,e){var a;return((a=this.$doc)==null?void 0:a.querySelector(t,e))||null}$nodes(t,e){var a;return((a=this.$doc)==null?void 0:a.querySelectorAll(t,e))||null}$pos(t){const e=this.state.doc.resolve(t);return new oce(e,this)}get $doc(){return this.$pos(0)}};function Ml(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n})=>{const i=Pe(t.getAttributes,void 0,n);if(i===!1||i===null)return null;const{tr:r}=e,o=n[n.length-1],l=n[0];if(o){const c=l.search(/\S/),d=a.from+l.indexOf(o),u=d+o.length;if(xS(a.from,a.to,e.doc).filter(h=>h.mark.type.excluded.find(y=>y===t.type&&y!==h.mark.type)).filter(h=>h.to>d).length)return null;u<a.to&&r.delete(u,a.to),d>a.from&&r.delete(a.from+c,d);const m=a.from+c+o.length;r.addMark(a.from+c,m,t.type.create(i||{})),r.removeStoredMark(t.type)}},undoable:t.undoable})}function W5(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n})=>{const i=Pe(t.getAttributes,void 0,n)||{},{tr:r}=e,o=a.from;let l=a.to;const c=t.type.create(i);if(n[1]){const d=n[0].lastIndexOf(n[1]);let u=o+d;u>l?u=l:l=u+n[1].length;const p=n[0][n[0].length-1];r.insertText(p,o+n[0].length-1),r.replaceWith(u,l,c)}else if(n[0]){const d=t.type.isInline?o:o-1;r.insert(d,t.type.create(i)).delete(r.mapping.map(o),r.mapping.map(l))}r.scrollIntoView()},undoable:t.undoable})}function Vb(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n})=>{const i=e.doc.resolve(a.from),r=Pe(t.getAttributes,void 0,n)||{};if(!i.node(-1).canReplaceWith(i.index(-1),i.indexAfter(-1),t.type))return null;e.tr.delete(a.from,a.to).setBlockType(a.from,a.from,t.type,r)},undoable:t.undoable})}function Dl(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n,chain:i})=>{const r=Pe(t.getAttributes,void 0,n)||{},o=e.tr.delete(a.from,a.to),c=o.doc.resolve(a.from).blockRange(),d=c&&Xk(c,t.type,r);if(!d)return null;if(o.wrap(c,d),t.keepMarks&&t.editor){const{selection:p,storedMarks:m}=e,{splittableMarks:h}=t.editor.extensionManager,g=m||p.$to.parentOffset&&p.$from.marks();if(g){const y=g.filter(x=>h.includes(x.type.name));o.ensureMarks(y)}}if(t.keepAttributes){const p=t.type.name==="bulletList"||t.type.name==="orderedList"?"listItem":"taskList";i().updateAttributes(p,r).run()}const u=o.doc.resolve(a.from-1).nodeBefore;u&&u.type===t.type&&eo(o.doc,a.from-1)&&(!t.joinPredicate||t.joinPredicate(n,u))&&o.join(a.from-1)},undoable:t.undoable})}var dce=t=>"touches"in t,uce=class{constructor(t){this.directions=["bottom-left","bottom-right","top-left","top-right"],this.minSize={height:8,width:8},this.preserveAspectRatio=!1,this.classNames={container:"",wrapper:"",handle:"",resizing:""},this.initialWidth=0,this.initialHeight=0,this.aspectRatio=1,this.isResizing=!1,this.activeHandle=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.isShiftKeyPressed=!1,this.lastEditableState=void 0,this.handleMap=new Map,this.handleMouseMove=l=>{if(!this.isResizing||!this.activeHandle)return;const c=l.clientX-this.startX,d=l.clientY-this.startY;this.handleResize(c,d)},this.handleTouchMove=l=>{if(!this.isResizing||!this.activeHandle)return;const c=l.touches[0];if(!c)return;const d=c.clientX-this.startX,u=c.clientY-this.startY;this.handleResize(d,u)},this.handleMouseUp=()=>
17714{if(!this.isResizing)return;const l=this.element.offsetWidth,c=this.element.offsetHeight;this.onCommit(l,c),this.isResizing=!1,this.activeHandle=null,this.container.dataset.resizeState="false",this.classNames.resizing&&this.container.classList.remove(this.classNames.resizing),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.removeEventListener("keydown",this.handleKeyDown),document.removeEventListener("keyup",this.handleKeyUp)},this.handleKeyDown=l=>{l.key==="Shift"&&(this.isShiftKeyPressed=!0)},this.handleKeyUp=l=>{l.key==="Shift"&&(this.isShiftKeyPressed=!1)};var e,a,n,i,r,o;this.node=t.node,this.editor=t.editor,this.element=t.element,this.contentElement=t.contentElement,this.getPos=t.getPos,this.onResize=t.onResize,this.onCommit=t.onCommit,this.onUpdate=t.onUpdate,(e=t.options)!=null&&e.min&&(this.minSize={...this.minSize,...t.options.min}),(a=t.options)!=null&&a.max&&(this.maxSize=t.options.max),(n=t==null?void 0:t.options)!=null&&n.directions&&(this.directions=t.options.directions),(i=t.options)!=null&&i.preserveAspectRatio&&(this.preserveAspectRatio=t.options.preserveAspectRatio),(r=t.options)!=null&&r.className&&(this.classNames={container:t.options.className.container||"",wrapper:t.options.className.wrapper||"",handle:t.options.className.handle||"",resizing:t.options.className.resizing||""}),(o=t.options)!=null&&o.createCustomHandle&&(this.createCustomHandle=t.options.createCustomHandle),this.wrapper=this.createWrapper(),this.container=this.createContainer(),this.applyInitialSize(),this.attachHandles(),this.editor.on("update",this.handleEditorUpdate.bind(this))}get dom(){return this.container}get contentDOM(){var t;return(t=this.contentElement)!=null?t:null}handleEditorUpdate(){const t=this.editor.isEditable;t!==this.lastEditableState&&(this.lastEditableState=t,t?t&&this.handleMap.size===0&&this.attachHandles():this.removeHandles())}update(t,e,a){return t.type!==this.node.type?!1:(this.node=t,this.onUpdate?this.onUpdate(t,e,a):!0)}destroy(){this.isResizing&&(this.container.dataset.resizeState="false",this.classNames.resizing&&this.container.classList.remove(this.classNames.resizing),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.removeEventListener("keydown",this.handleKeyDown),document.removeEventListener("keyup",this.handleKeyUp),this.isResizing=!1,this.activeHandle=null),this.editor.off("update",this.handleEditorUpdate.bind(this)),this.container.remove()}createContainer(){const t=document.createElement("div");return t.dataset.resizeContainer="",t.dataset.node=this.node.type.name,t.style.display=this.node.type.isInline?"inline-flex":"flex",this.classNames.container&&(t.className=this.classNames.container),t.appendChild(this.wrapper),t}createWrapper(){const t=document.createElement("div");return t.style.position="relative",t.style.display="block",t.dataset.resizeWrapper="",this.classNames.wrapper&&(t.className=this.classNames.wrapper),t.appendChild(this.element),t}createHandle(t){const e=document.createElement("div");return e.dataset.resizeHandle=t,e.style.position="absolute",this.classNames.handle&&(e.className=this.classNames.handle),e}positionHandle(t,e){const a=e.includes("top"),n=e.includes("bottom"),i=e.includes("left"),r=e.includes("right");a&&(t.style.top="0"),n&&(t.style.bottom="0"),i&&(t.style.left="0"),r&&(t.style.right="0"),(e==="top"||e==="bottom")&&(t.style.left="0",t.style.right="0"),(e==="left"||e==="right")&&(t.style.top="0",t.style.bottom="0")}attachHandles(){this.directions.forEach(t=>{let e;this.createCustomHandle?e=this.createCustomHandle(t):e=this.createHandle(t),e instanceof HTMLElement||(console.warn(`[ResizableNodeView] createCustomHandle("${t}") did not return an HTMLElement. Falling back to default handle.`),e=this.createHandle(t)),this.createCustomHandle||this.positionHandle(e,t),e.addEventListener("mousedown",a=>this.handleResizeStart(a,t)),e.addEventListener("touchstart",a=>this.handleResizeStart(a,t)),this.handleMap.set(t,e),this.wrapper.appendChild(e)})}
17714removeHandles(){this.handleMap.forEach(t=>t.remove()),this.handleMap.clear()}applyInitialSize(){const t=this.node.attrs.width,e=this.node.attrs.height;t?(this.element.style.width=`${t}px`,this.initialWidth=t):this.initialWidth=this.element.offsetWidth,e?(this.element.style.height=`${e}px`,this.initialHeight=e):this.initialHeight=this.element.offsetHeight,this.initialWidth>0&&this.initialHeight>0&&(this.aspectRatio=this.initialWidth/this.initialHeight)}handleResizeStart(t,e){t.preventDefault(),t.stopPropagation(),this.isResizing=!0,this.activeHandle=e,dce(t)?(this.startX=t.touches[0].clientX,this.startY=t.touches[0].clientY):(this.startX=t.clientX,this.startY=t.clientY),this.startWidth=this.element.offsetWidth,this.startHeight=this.element.offsetHeight,this.startWidth>0&&this.startHeight>0&&(this.aspectRatio=this.startWidth/this.startHeight),this.getPos(),this.container.dataset.resizeState="true",this.classNames.resizing&&this.container.classList.add(this.classNames.resizing),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("touchmove",this.handleTouchMove),document.addEventListener("mouseup",this.handleMouseUp),document.addEventListener("keydown",this.handleKeyDown),document.addEventListener("keyup",this.handleKeyUp)}handleResize(t,e){if(!this.activeHandle)return;const a=this.preserveAspectRatio||this.isShiftKeyPressed,{width:n,height:i}=this.calculateNewDimensions(this.activeHandle,t,e),r=this.applyConstraints(n,i,a);this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,this.onResize&&this.onResize(r.width,r.height)}calculateNewDimensions(t,e,a){let n=this.startWidth,i=this.startHeight;const r=t.includes("right"),o=t.includes("left"),l=t.includes("bottom"),c=t.includes("top");return r?n=this.startWidth+e:o&&(n=this.startWidth-e),l?i=this.startHeight+a:c&&(i=this.startHeight-a),(t==="right"||t==="left")&&(n=this.startWidth+(r?e:-e)),(t==="top"||t==="bottom")&&(i=this.startHeight+(l?a:-a)),this.preserveAspectRatio||this.isShiftKeyPressed?this.applyAspectRatio(n,i,t):{width:n,height:i}}applyConstraints(t,e,a){var n,i,r,o;if(!a){let d=Math.max(this.minSize.width,t),u=Math.max(this.minSize.height,e);return(n=this.maxSize)!=null&&n.width&&(d=Math.min(this.maxSize.width,d)),(i=this.maxSize)!=null&&i.height&&(u=Math.min(this.maxSize.height,u)),{width:d,height:u}}let l=t,c=e;return l<this.minSize.width&&(l=this.minSize.width,c=l/this.aspectRatio),c<this.minSize.height&&(c=this.minSize.height,l=c*this.aspectRatio),(r=this.maxSize)!=null&&r.width&&l>this.maxSize.width&&(l=this.maxSize.width,c=l/this.aspectRatio),(o=this.maxSize)!=null&&o.height&&c>this.maxSize.height&&(c=this.maxSize.height,l=c*this.aspectRatio),{width:l,height:c}}applyAspectRatio(t,e,a){const n=a==="left"||a==="right",i=a==="top"||a==="bottom";return n?{width:t,height:t/this.aspectRatio}:i?{width:e*this.aspectRatio,height:e}:{width:t,height:t/this.aspectRatio}}};function pce(t,e){const{selection:a}=t,{$from:n}=a;if(a instanceof se){const r=n.index();return n.parent.canReplaceWith(r,r+1,e)}let i=n.depth;for(;i>=0;){const r=n.index(i);if(n.node(i).contentMatchAt(r).matchType(e))return!0;i-=1}return!1}var mce={};mS(mce,{createAtomBlockMarkdownSpec:()=>hce,createBlockMarkdownSpec:()=>fce,createInlineMarkdownSpec:()=>xce,parseAttributes:()=>bS,parseIndentedBlocks:()=>Hb,renderNestedMarkdownContent:()=>kS,serializeAttributes:()=>wS});function bS(t){if(!(t!=null&&t.trim()))return{};const e={},a=[],n=t.replace(/["']([^"']*)["']/g,d=>(a.push(d),`__QUOTED_${a.length-1}__`)),i=n.match(/(?:^|\s)\.([a-zA-Z][\w-]*)/g);if(i){const d=i.map(u=>u.trim().slice(1));e.class=d.join(" ")}const r=n.match(/(?:^|\s)#([a-zA-Z][\w-]*)/);r&&(e.id=r[1]);const o=/([a-zA-Z][\w-]*)\s*=\s*(__QUOTED_\d+__)/g;Array.from(n.matchAll(o)).forEach(([,d,u])=>{var p;const m=parseInt(((p=u.match(/__QUOTED_(\d+)__/))==null?void 0:p[1])||"0",10),h=a[m];h&&(e[d]=h.slice(1,-1))});const c=n.replace(/(?:^|\s)\.([a-zA-Z][\w-]*)/g,"").replace(/(?:^|\s)#([a-zA-Z][\w-]*)/g,"").replace(/([a-zA-Z][\w-]*)\s*=\s*__QUOTED_\d+__/g,"").trim();
vendor: 5,016 bytes, lines 17714-17724
17714return c&&c.split(/\s+/).filter(Boolean).forEach(u=>{u.match(/^[a-zA-Z][\w-]*$/)&&(e[u]=!0)}),e}function wS(t){if(!t||Object.keys(t).length===0)return"";const e=[];return t.class&&String(t.class).split(/\s+/).filter(Boolean).forEach(n=>e.push(`.${n}`)),t.id&&e.push(`#${t.id}`),Object.entries(t).forEach(([a,n])=>{a==="class"||a==="id"||(n===!0?e.push(a):n!==!1&&n!=null&&e.push(`${a}="${String(n)}"`))}),e.join(" ")}function hce(t){const{nodeName:e,name:a,parseAttributes:n=bS,serializeAttributes:i=wS,defaultAttributes:r={},requiredAttributes:o=[],allowedAttributes:l}=t,c=a||e,d=u=>{if(!l)return u;const p={};return l.forEach(m=>{m in u&&(p[m]=u[m])}),p};return{parseMarkdown:(u,p)=>{const m={...r,...u.attributes};return p.createNode(e,m,[])},markdownTokenizer:{name:e,level:"block",start(u){var p;const m=new RegExp(`^:::${c}(?:\\s|$)`,"m"),h=(p=u.match(m))==null?void 0:p.index;return h!==void 0?h:-1},tokenize(u,p,m){const h=new RegExp(`^:::${c}(?:\\s+\\{([^}]*)\\})?\\s*:::(?:\\n|$)`),g=u.match(h);if(!g)return;const y=g[1]||"",x=n(y);if(!o.find(w=>!(w in x)))return{type:e,raw:g[0],attributes:x}}},renderMarkdown:u=>{const p=d(u.attrs||{}),m=i(p),h=m?` {${m}}`:"";return`:::${c}${h} :::`}}}function fce(t){const{nodeName:e,name:a,getContent:n,parseAttributes:i=bS,serializeAttributes:r=wS,defaultAttributes:o={},content:l="block",allowedAttributes:c}=t,d=a||e,u=p=>{if(!c)return p;const m={};return c.forEach(h=>{h in p&&(m[h]=p[h])}),m};return{parseMarkdown:(p,m)=>{let h;if(n){const y=n(p);h=typeof y=="string"?[{type:"text",text:y}]:y}else l==="block"?h=m.parseChildren(p.tokens||[]):h=m.parseInline(p.tokens||[]);const g={...o,...p.attributes};return m.createNode(e,g,h)},markdownTokenizer:{name:e,level:"block",start(p){var m;const h=new RegExp(`^:::${d}`,"m"),g=(m=p.match(h))==null?void 0:m.index;return g!==void 0?g:-1},tokenize(p,m,h){var g;const y=new RegExp(`^:::${d}(?:\\s+\\{([^}]*)\\})?\\s*\\n`),x=p.match(y);if(!x)return;const[v,w=""]=x,S=i(w);let T=1;const P=v.length;let M="";const C=/^:::([\w-]*)(\s.*)?/gm,E=p.slice(P);for(C.lastIndex=0;;){const j=C.exec(E);if(j===null)break;const N=j.index,L=j[1];if(!((g=j[2])!=null&&g.endsWith(":::"))){if(L)T+=1;else if(T-=1,T===0){const O=E.slice(0,N);M=O.trim();const R=p.slice(0,P+N+j[0].length);let G=[];if(M)if(l==="block")for(G=h.blockTokens(O),G.forEach(ee=>{ee.text&&(!ee.tokens||ee.tokens.length===0)&&(ee.tokens=h.inlineTokens(ee.text))});G.length>0;){const ee=G[G.length-1];if(ee.type==="paragraph"&&(!ee.text||ee.text.trim()===""))G.pop();else break}else G=h.inlineTokens(M);return{type:e,raw:R,attributes:S,content:M,tokens:G}}}}}},renderMarkdown:(p,m)=>{const h=u(p.attrs||{}),g=r(h),y=g?` {${g}}`:"",x=m.renderChildren(p.content||[],` 17715 17716`);return`:::${d}${y} 17717 17718${x} 17719 17720:::`}}}function gce(t){if(!t.trim())return{};const e={},a=/(\w+)=(?:"([^"]*)"|'([^']*)')/g;let n=a.exec(t);for(;n!==null;){const[,i,r,o]=n;e[i]=r||o,n=a.exec(t)}return e}function yce(t){return Object.entries(t).filter(([,e])=>e!=null).map(([e,a])=>`${e}="${a}"`).join(" ")}function xce(t){const{nodeName:e,name:a,getContent:n,parseAttributes:i=gce,serializeAttributes:r=yce,defaultAttributes:o={},selfClosing:l=!1,allowedAttributes:c}=t,d=a||e,u=m=>{if(!c)return m;const h={};return c.forEach(g=>{const y=typeof g=="string"?g:g.name,x=typeof g=="string"?void 0:g.skipIfDefault;if(y in m){const v=m[y];if(x!==void 0&&v===x)return;h[y]=v}}),h},p=d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return{parseMarkdown:(m,h)=>{const g={...o,...m.attributes};if(l)return h.createNode(e,g);const y=n?n(m):m.content||"";return y?h.createNode(e,g,[h.createTextNode(y)]):h.createNode(e,g,[])},markdownTokenizer:{name:e,level:"inline",start(m){const h=l?new RegExp(`\\[${p}\\s*[^\\]]*\\]`):new RegExp(`\\[${p}\\s*[^\\]]*\\][\\s\\S]*?\\[\\/${p}\\]`),g=m.match(h),y=g==null?void 0:g.index;return y!==void 0?y:-1},tokenize(m,h,g){const y=l?new RegExp(`^\\[${p}\\s*([^\\]]*)\\]`):new RegExp(`^\\[${p}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${p}\\]`),x=m.match(y);if(!x)return;let v="",w="";if(l){const[,T]=x;w=T}else{const[,T,P]=x;w=T,v=P||""}const S=i(w.trim());return{type:e,raw:x[0],content:v.trim(),attributes:S}}},renderMarkdown:m=>{let h="";n?h=n(m):m.content&&m.content.length>0&&(h=m.content.filter(v=>v.type==="text").map(v=>v.text).join(""));const g=u(m.attrs||{}),y=r(g),x=y?` ${y}`:"";return l?`[${d}${x}]`:`[${d}${x}]${h}[/${d}]`}}}function Hb(t,e,a){var n,i,r,o;const l=t.split(` 17721`),c=[];let d="",u=0;const p=e.baseIndentSize||2;for(;u<l.length;){const m=l[u],h=m.match(e.itemPattern);if(!h){if(c.length>0)break;if(m.trim()===""){u+=1,d=`${d}${m} 17722`;continue}else return}const g=e.extractItemData(h),{indentLevel:y,mainContent:x}=g;d=`${d}${m} 17723`;const v=[x];for(u+=1;u<l.length;){const P=l[u];if(P.trim()===""){const C=l.slice(u+1).findIndex(N=>N.trim()!=="");if(C===-1)break;if((((i=(n=l[u+1+C].match(/^(\s*)/))==null?void 0:n[1])==null?void 0:i.length)||0)>y){v.push(P),d=`${d}${P} 17724`,u+=1;continue}else break}if((((o=(r=P.match(/^(\s*)/))==null?void 0:r[1])==null?void 0:o.length)||0)>
17724y)v.push(P),d=`${d}${P} 17725`,u+=1;else break}let w;const S=v.slice(1);if(S.length>0){const P=S.map(M=>M.slice(y+p)).join(` 17726`);P.trim()&&(e.customNestedParser?w=e.customNestedParser(P):w=a.blockTokens(P))}const T=e.createToken(g,w);c.push(T)}if(c.length!==0)return{items:c,raw:d}}function kS(t,e,a,n){if(!t||!Array.isArray(t.content))return"";const i=typeof a=="function"?a(n):a,[r,...o]=t.content,l=e.renderChildren([r]);let c=`${i}${l}`;return o&&o.length>0&&o.forEach((d,u)=>{var p,m;const h=(m=(p=e.renderChild)==null?void 0:p.call(e,d,u+1))!=null?m:e.renderChildren([d]);if(h!=null){const g=h.split(` 17727`).map(y=>y?e.indent(y):e.indent("")).join(` 17728`);c+=d.type==="paragraph"?` 17729 17730${g}`:` 17731${g}`}}),c}function vce(t,e,a={}){const{state:n}=e,{doc:i,tr:r}=n,o=t;i.descendants((l,c)=>{const d=r.mapping.map(c),u=r.mapping.map(c)+l.nodeSize;let p=null;if(l.marks.forEach(h=>{if(h!==o)return!1;p=h}),!p)return;let m=!1;if(Object.keys(a).forEach(h=>{a[h]!==p.attrs[h]&&(m=!0)}),m){const h=t.type.create({...t.attrs,...a});r.removeMark(d,u,t.type),r.addMark(d,u,h)}}),r.docChanged&&e.view.dispatch(r)}var Oa=class G5 extends vS{constructor(){super(...arguments),this.type="node"}static create(e={}){const a=typeof e=="function"?e():e;return new G5(a)}configure(e){return super.configure(e)}extend(e){const a=typeof e=="function"?e():e;return super.extend(a)}};function ss(t){return new ece({find:t.find,handler:({state:e,range:a,match:n,pasteEvent:i})=>{const r=Pe(t.getAttributes,void 0,n,i);if(r===!1||r===null)return null;const{tr:o}=e,l=n[n.length-1],c=n[0];let d=a.to;if(l){const u=c.search(/\S/),p=a.from+c.indexOf(l),m=p+l.length;if(xS(a.from,a.to,e.doc).filter(y=>y.mark.type.excluded.find(v=>v===t.type&&v!==y.mark.type)).filter(y=>y.to>p).length)return null;m<a.to&&o.delete(m,a.to),p>a.from&&o.delete(a.from+u,p),d=a.from+u+l.length,o.addMark(a.from+u,d,t.type.create(r||{})),n.index!==void 0&&n.input!==void 0&&n.index+n[0].length>=n.input.length||o.removeStoredMark(t.type)}}})}const{getOwnPropertyNames:bce,getOwnPropertySymbols:wce}=Object,{hasOwnProperty:kce}=Object.prototype;function sx(t,e){return function(n,i,r){return t(n,i,r)&&e(n,i,r)}}function im(t){return function(a,n,i){if(!a||!n||typeof a!="object"||typeof n!="object")return t(a,n,i);const{cache:r}=i,o=r.get(a),l=r.get(n);if(o&&l)return o===n&&l===a;r.set(a,n),r.set(n,a);const c=t(a,n,i);return r.delete(a),r.delete(n),c}}function Sce(t){return t!=null?t[Symbol.toStringTag]:void 0}function TT(t){return bce(t).concat(wce(t))}const _ce=Object.hasOwn||((t,e)=>kce.call(t,e));function gs(t,e){return t===e||!t&&!e&&t!==t&&e!==e}const Ace="__v",Ece="__o",Cce="_owner",{getOwnPropertyDescriptor:NT,keys:IT}=Object;function jce(t,e){return t.byteLength===e.byteLength&&lf(new Uint8Array(t),new Uint8Array(e))}function Tce(t,e,a){let n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!a.equals(t[n],e[n],n,n,t,e,a))return!1;return!0}function Nce(t,e){return t.byteLength===e.byteLength&&lf(new Uint8Array(t.buffer,t.byteOffset,t.byteLength),new Uint8Array(e.buffer,e.byteOffset,e.byteLength))}function Ice(t,e){return gs(t.getTime(),e.getTime())}function Pce(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function Rce(t,e){return t===e}function PT(t,e,a){const n=t.size;if(n!==e.size)return!1;if(!n)return!0;const i=new Array(n),r=t.entries();let o,l,c=0;for(;(o=r.next())&&!o.done;){const d=e.entries();let u=!1,p=0;for(;(l=d.next())&&!l.done;){if(i[p]){p++;continue}const m=o.value,h=l.value;if(a.equals(m[0],h[0],c,p,t,e,a)&&a.equals(m[1],h[1],m[0],h[0],t,e,a)){u=i[p]=!0;break}p++}if(!u)return!1;c++}return!0}const Lce=gs;function Oce(t,e,a){const n=IT(t);let i=n.length;if(IT(e).length!==i)return!1;for(;i-- >0;)if(!K5(t,e,a,n[i]))return!1;return!0}function Pc(t,e,a){const n=TT(t);let i=n.length;if(TT(e).length!==i)return!1;let r,o,l;for(;i-- >0;)if(r=n[i],!K5(t,e,a,r)||(o=NT(t,r),l=NT(e,r),(o||l)&&(!o||!l||o.configurable!==l.configurable||o.enumerable!==l.enumerable||o.writable!==l.writable)))return!1;return!0}function Mce(t,e){return gs(t.valueOf(),e.valueOf())}function Dce(t,e){return t.source===e.source&&t.flags===e.flags}function RT(t,e,a){const n=t.size;if(n!==e.size)return!1;if(!n)return!0;const i=new Array(n),r=t.values();let o,l;for(;(o=r.next())&&!o.done;){const c=e.values();let d=!1,u=0;for(;(l=c.next())&&!l.done;){if(!i[u]&&a.equals(o.value,l.value,o.value,l.value,t,e,a)){d=i[u]=!0;break}u++}if(!d)return!1}return!0}function lf(t,e){let a=t.byteLength;if(e.byteLength!==a||t.byteOffset!==e.byteOffset)return!1;for(;a-- >0;)if(t[a]!==e[a])return!1;return!0}function qce(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function K5(t,e,a,n){return(n===Cce||n===Ece||n===Ace)&&(t.$$typeof||e.$$typeof)?!0:_ce(e,n)&&a.equals(t[n],e[n],n,n,t,e,a)}const zce="[object ArrayBuffer]",Vce="[object Arguments]",Hce="[object Boolean]",Fce="[object DataView]",Bce="[object Date]",Uce="[object Error]",$ce="[object Map]",Wce="[object Number]",Gce="[object Object]",Kce="[object RegExp]",Jce="[object Set]",Qce="[object String]",Xce={"[object Int8Array]":!0,"[object Uint8Array]":!0,"[object Uint8ClampedArray]":!0,"[object Int16Array]":!0,"[object Uint16Array]":!0,"[object Int32Array]":!0,"[object Uint32Array]":!0,"[object Float16Array]":!0,"[object Float32Array]":!0,"[object Float64Array
17731]":!0,"[object BigInt64Array]":!0,"[object BigUint64Array]":!0},Yce="[object URL]",Zce=Object.prototype.toString;function ede({areArrayBuffersEqual:t,areArraysEqual:e,areDataViewsEqual:a,areDatesEqual:n,areErrorsEqual:i,areFunctionsEqual:r,areMapsEqual:o,areNumbersEqual:l,areObjectsEqual:c,arePrimitiveWrappersEqual:d,areRegExpsEqual:u,areSetsEqual:p,areTypedArraysEqual:m,areUrlsEqual:h,unknownTagComparators:g}){return function(x,v,w){if(x===v)return!0;if(x==null||v==null)return!1;const S=typeof x;if(S!==typeof v)return!1;if(S!=="object")return S==="number"?l(x,v,w):S==="function"?r(x,v,w):!1;const T=x.constructor;if(T!==v.constructor)return!1;if(T===Object)return c(x,v,w);if(Array.isArray(x))return e(x,v,w);if(T===Date)return n(x,v,w);if(T===RegExp)return u(x,v,w);if(T===Map)return o(x,v,w);if(T===Set)return p(x,v,w);const P=Zce.call(x);if(P===Bce)return n(x,v,w);if(P===Kce)return u(x,v,w);if(P===$ce)return o(x,v,w);if(P===Jce)return p(x,v,w);if(P===Gce)return typeof x.then!="function"&&typeof v.then!="function"&&c(x,v,w);if(P===Yce)return h(x,v,w);if(P===Uce)return i(x,v,w);if(P===Vce)return c(x,v,w);if(Xce[P])return m(x,v,w);if(P===zce)return t(x,v,w);if(P===Fce)return a(x,v,w);if(P===Hce||P===Wce||P===Qce)return d(x,v,w);if(g){let M=g[P];if(!M){const C=Sce(x);C&&(M=g[C])}if(M)return M(x,v,w)}return!1}}function tde({circular:t,createCustomConfig:e,strict:a}){let n={areArrayBuffersEqual:jce,areArraysEqual:a?Pc:Tce,areDataViewsEqual:Nce,areDatesEqual:Ice,areErrorsEqual:Pce,areFunctionsEqual:Rce,areMapsEqual:a?sx(PT,Pc):PT,areNumbersEqual:Lce,areObjectsEqual:a?Pc:Oce,arePrimitiveWrappersEqual:Mce,areRegExpsEqual:Dce,areSetsEqual:a?sx(RT,Pc):RT,areTypedArraysEqual:a?sx(lf,Pc):lf,areUrlsEqual:qce,unknownTagComparators:void 0};if(e&&(n=Object.assign({},n,e(n))),t){const i=im(n.areArraysEqual),r=im(n.areMapsEqual),o=im(n.areObjectsEqual),l=im(n.areSetsEqual);n=Object.assign({},n,{areArraysEqual:i,areMapsEqual:r,areObjectsEqual:o,areSetsEqual:l})}return n}function ade(t){return function(e,a,n,i,r,o,l){return t(e,a,l)}}function nde({circular:t,comparator:e,createState:a,equals:n,strict:i}){if(a)return function(l,c){const{cache:d=t?new WeakMap:void 0,meta:u}=a();return e(l,c,{cache:d,equals:n,meta:u,strict:i})};if(t)return function(l,c){return e(l,c,{cache:new WeakMap,equals:n,meta:void 0,strict:i})};const r={cache:void 0,equals:n,meta:void 0,strict:i};return function(l,c){return e(l,c,r)}}const ide=no();no({strict:!0});no({circular:!0});no({circular:!0,strict:!0});no({createInternalComparator:()=>gs});no({strict:!0,createInternalComparator:()=>gs});no({circular:!0,createInternalComparator:()=>gs});no({circular:!0,createInternalComparator:()=>gs,strict:!0});function no(t={}){const{circular:e=!1,createInternalComparator:a,createState:n,strict:i=!1}=t,r=tde(t),o=ede(r),l=a?a(o):ade(o);return nde({circular:e,comparator:o,createState:n,equals:l,strict:i})}var J5={exports:{}},Q5={};/** 17732 * @license React 17733 * use-sync-external-store-shim/with-selector.production.js 17734 * 17735 * Copyright (c) Meta Platforms, Inc. and affiliates. 17736 * 17737 * This source code is licensed under the MIT license found in the 17738 * LICENSE file in the root directory of this source tree. 17739 */var Xg=k,rde=ig;function ode(t,e){return t===e&&(t!==0||1/t===1/e)||t!==t&&e!==e}var sde=typeof Object.is=="function"?Object.is:ode,lde=rde.useSyncExternalStore,cde=Xg.useRef,dde=Xg.useEffect,ude=Xg.useMemo,pde=Xg.useDebugValue;Q5.useSyncExternalStoreWithSelector=function(t,e,a,n,i){var r=cde(null);if(r.current===null){var o={hasValue:!1,value:null};r.current=o}else o=r.current;r=ude(function(){function c(h){if(!d){if(d=!0,u=h,h=n(h),i!==void 0&&o.hasValue){var g=o.value;if(i(g,h))return p=g}return p=h}if(g=p,sde(u,h))return g;var y=n(h);return i!==void 0&&i(g,y)?(u=h,g):(u=h,p=y)}var d=!1,u,p,m=a===void 0?null:a;return[function(){return c(e())},m===null?void 0:function(){return c(m())}]},[e,a,n,i]);var l=lde(t,r[0],r[1]);return dde(function(){o.hasValue=!0,o.value=l},[l]),pde(l),l};J5.exports=Q5;var mde=J5.exports,hde=(...t)=>e=>{t.forEach(a=>{typeof a=="function"?a(e):a&&(a.current=e)})},fde=({contentComponent:t})=>{const e=ig.useSyncExternalStore(t.subscribe,t.getSnapshot,t.getServerSnapshot);return s.jsx(s.Fragment,{children:Object.values(e)})};function gde(){const t=new Set;let e={};return{subscribe(a){return t.add(a),()=>{t.delete(a)}},getSnapshot(){return e},getServerSnapshot(){return e},setRenderer(a,n){e={...e,[a]:Iz.createPortal(n.reactElement,n.element,a)},t.forEach(i=>
17739i())},removeRenderer(a){const n={...e};delete n[a],e=n,t.forEach(i=>i())}}}var yde=class extends Re.Component{constructor(t){var e;super(t),this.editorContentRef=Re.createRef(),this.initialized=!1,this.state={hasContentComponentInitialized:!!((e=t.editor)!=null&&e.contentComponent)}}componentDidMount(){this.init()}componentDidUpdate(){this.init()}init(){var t;const e=this.props.editor;if(e&&!e.isDestroyed&&((t=e.view.dom)!=null&&t.parentNode)){if(e.contentComponent)return;const a=this.editorContentRef.current;a.append(...e.view.dom.parentNode.childNodes),e.setOptions({element:a}),e.contentComponent=gde(),this.state.hasContentComponentInitialized||(this.unsubscribeToContentComponent=e.contentComponent.subscribe(()=>{this.setState(n=>n.hasContentComponentInitialized?n:{hasContentComponentInitialized:!0}),this.unsubscribeToContentComponent&&this.unsubscribeToContentComponent()})),e.createNodeViews(),this.initialized=!0}}componentWillUnmount(){var t;const e=this.props.editor;if(e){this.initialized=!1,e.isDestroyed||e.view.setProps({nodeViews:{}}),this.unsubscribeToContentComponent&&this.unsubscribeToContentComponent(),e.contentComponent=null;try{if(!((t=e.view.dom)!=null&&t.parentNode))return;const a=document.createElement("div");a.append(...e.view.dom.parentNode.childNodes),e.setOptions({element:a})}catch{}}}render(){const{editor:t,innerRef:e,...a}=this.props;return s.jsxs(s.Fragment,{children:[s.jsx("div",{ref:hde(e,this.editorContentRef),...a}),(t==null?void 0:t.contentComponent)&&s.jsx(fde,{contentComponent:t.contentComponent})]})}},xde=k.forwardRef((t,e)=>{const a=Re.useMemo(()=>Math.floor(Math.random()*4294967295).toString(),[t.editor]);return Re.createElement(yde,{key:a,innerRef:e,...t})}),vde=Re.memo(xde),bde=typeof window<"u"?k.useLayoutEffect:k.useEffect,wde=class{constructor(t){this.transactionNumber=0,this.lastTransactionNumber=0,this.subscribers=new Set,this.editor=t,this.lastSnapshot={editor:t,transactionNumber:0},this.getSnapshot=this.getSnapshot.bind(this),this.getServerSnapshot=this.getServerSnapshot.bind(this),this.watch=this.watch.bind(this),this.subscribe=this.subscribe.bind(this)}getSnapshot(){return this.transactionNumber===this.lastTransactionNumber?this.lastSnapshot:(this.lastTransactionNumber=this.transactionNumber,this.lastSnapshot={editor:this.editor,transactionNumber:this.transactionNumber},this.lastSnapshot)}getServerSnapshot(){return{editor:null,transactionNumber:0}}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}watch(t){if(this.editor=t,this.editor){const e=()=>{this.transactionNumber+=1,this.subscribers.forEach(n=>n())},a=this.editor;return a.on("transaction",e),()=>{a.off("transaction",e)}}}};function kde(t){var e;const[a]=k.useState(()=>new wde(t.editor)),n=mde.useSyncExternalStoreWithSelector(a.subscribe,a.getSnapshot,a.getServerSnapshot,t.selector,(e=t.equalityFn)!=null?e:ide);return bde(()=>a.watch(t.editor),[t.editor,a]),k.useDebugValue(n),n}var Sde=!1,Fb=typeof window>"u",_de=Fb||!!(typeof window<"u"&&window.next),Ade=class X5{constructor(e){this.editor=null,this.subscriptions=new Set,this.isComponentMounted=!1,this.previousDeps=null,this.instanceId="",this.options=e,this.subscriptions=new Set,this.setEditor(this.getInitialEditor()),this.scheduleDestroy(),this.getEditor=this.getEditor.bind(this),this.getServerSnapshot=this.getServerSnapshot.bind(this),this.subscribe=this.subscribe.bind(this),this.refreshEditorInstance=this.refreshEditorInstance.bind(this),this.scheduleDestroy=this.scheduleDestroy.bind(this),this.onRender=this.onRender.bind(this),this.createEditor=this.createEditor.bind(this)}setEditor(e){this.editor=e,this.instanceId=Math.random().toString(36).slice(2,9),this.subscriptions.forEach(a=>a())}getInitialEditor(){return this.options.current.immediatelyRender===void 0?Fb||_de?null:this.createEditor():(this.options.current.immediatelyRender,this.options.current.immediatelyRender?this.createEditor():null)}createEditor(){const e={...this.options.current,onBeforeCreate:(...n)=>{var i,r;return(r=(i=this.options.current).onBeforeCreate)==null?void 0:r.call(i,...n)},onBlur:(...n)=>{var i,r;return(r=(i=this.options.current).onBlur)==null?void 0:r.call(i,...n)},onCreate:(...n)=>{var i,r;return(r=(i=this.options.current).onCreate)==null?void 0:r.call(i,...n)},onDestroy:(...n)=>{var i,r;return(r=(i=this.options.current).onDestroy)==null?void 0:r.call(i,...n)},onFocus:(...n)=>{var i,r;return(r=(i=this.options.current).onFocus)==null?void 0:r.call(i,...n)},onSelectionUpdate:(...n)=>{var i,r;return(r=(i=this.options.current).onSelectionUpdate)==null?void 0:r.call(i,...n)},onTransaction:(...n)=>{var i,r;return(r=(i=this.options.current).onTransaction)==null?void 0:r.call(i,...n)},onUpdate:(...n)=>{var i,r;return(r=(i=this.options.current).onUpdate)==null?void 0:r.call(i,...n)},onContentError:(...n)=>{var i,r;return(r=(i=this.options.current).onContentError)==null?void 0:r.call(i,...n)},onDrop:(...n)=>{var i,r;return(r=(i=this.options.current).onDrop)==null?void 0:r.call(i,...n)},onPaste:(...n)=>{var i,r;return(r=(i=this.options.current).onPaste)==null?void 0:r.call(i,...n)},onDelete:(...n)=>{var i,r;return(r=(i=this.options.current).onDelete)==null?void 0:r.call(i,...n)}};return new cce(e)}getEditor(){return this.editor}getServerSnapshot(){return null}subscribe(e){return this.subscriptions.add(e),()=>{this.subscriptions.delete(e)}}static compareOptions(e,a){return Object.keys(e).every(n=>["onCreate","onBeforeCreate","onDestroy","onUpdate","onTransaction","onFocus","onBlur","onSelectionUpdate","onContentError","onDrop","onPaste"].includes(n)?!0:n==="extensions"&&e.extensions&&a.extensions?e.extensions.length!==a.extensions.length?!1:e.extensions.every((i,r)=>{var o;return i===((o=a.extensions)==null?void 0:o[r])}):e[n]===a[n])}onRender(e){return()=>(this.isComponentMounted=!0,clearTimeout(this.scheduledDestructionTimeout),this.editor&&!this.editor.isDestroyed&&e.length===0?X5.compareOptions(this.options.current,this.editor.options)||this.editor.setOptions({...this.options.current,editable:this.editor.isEditable}
17739):this.refreshEditorInstance(e),()=>{this.isComponentMounted=!1,this.scheduleDestroy()})}refreshEditorInstance(e){if(this.editor&&!this.editor.isDestroyed){if(this.previousDeps===null){this.previousDeps=e;return}if(this.previousDeps.length===e.length&&this.previousDeps.every((n,i)=>n===e[i]))return}this.editor&&!this.editor.isDestroyed&&this.editor.destroy(),this.setEditor(this.createEditor()),this.previousDeps=e}scheduleDestroy(){const e=this.instanceId,a=this.editor;this.scheduledDestructionTimeout=setTimeout(()=>{if(this.isComponentMounted&&this.instanceId===e){a&&a.setOptions(this.options.current);return}a&&!a.isDestroyed&&(a.destroy(),this.instanceId===e&&this.setEditor(null))},1)}};function Ede(t={},e=[]){const a=k.useRef(t);a.current=t;const[n]=k.useState(()=>new Ade(a)),i=ig.useSyncExternalStore(n.subscribe,n.getEditor,n.getServerSnapshot);return k.useDebugValue(i),k.useEffect(n.onRender(e)),kde({editor:i,selector:({transactionNumber:r})=>t.shouldRerenderOnTransaction===!1||t.shouldRerenderOnTransaction===void 0?null:t.immediatelyRender&&r===0?0:r+1}),i}var Cde=k.createContext({editor:null});Cde.Consumer;var jde=k.createContext({onDragStart:()=>{},nodeViewContentChildren:void 0,nodeViewContentRef:()=>{}}),Tde=()=>k.useContext(jde);Re.forwardRef((t,e)=>{const{onDragStart:a}=Tde(),n=t.as||"div";return s.jsx(n,{...t,ref:e,"data-node-view-wrapper":"",onDragStart:a,style:{whiteSpace:"normal",...t.style}})});Re.createContext({markViewContentRef:()=>{}});var cf=(t,e)=>{if(t==="slot")return 0;if(t instanceof Function)return t(e);const{children:a,...n}=e??{};if(t==="svg")throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");return[t,n,a]},Nde=/^\s*>\s$/,Ide=Oa.create({name:"blockquote",addOptions(){return{HTMLAttributes:{}}},content:"block+",group:"block",defining:!0,parseHTML(){return[{tag:"blockquote"}]},renderHTML({HTMLAttributes:t}){return cf("blockquote",{...ct(this.options.HTMLAttributes,t),children:cf("slot",{})})},parseMarkdown:(t,e)=>e.createNode("blockquote",void 0,e.parseChildren(t.tokens||[])),renderMarkdown:(t,e)=>{if(!t.content)return"";const a=">",n=[];return t.content.forEach(i=>{const l=e.renderChildren([i]).split(` 17740`).map(c=>c.trim()===""?a:`${a} ${c}`);n.push(l.join(` 17741`))}),n.join(` 17742${a} 17743`)},addCommands(){return{setBlockquote:()=>({commands:t})=>t.wrapIn(this.name),toggleBlockquote:()=>({commands:t})=>t.toggleWrap(this.name),unsetBlockquote:()=>({commands:t})=>t.lift(this.name)}},addKeyboardShortcuts(){return{"Mod-Shift-b":()=>this.editor.commands.toggleBlockquote()}},addInputRules(){return[Dl({find:Nde,type:this.type})]}}),Pde=/(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/,Rde=/(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g,Lde=/(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/,Ode=/(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g,Mde=ao.create({name:"bold",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"strong"},{tag:"b",getAttrs:t=>t.style.fontWeight!=="normal"&&null},{style:"font-weight=400",clearMark:t=>t.type.name===this.name},{style:"font-weight",getAttrs:t=>/^(bold(er)?|[5-9]\d{2,})$/.test(t)&&null}]},renderHTML({HTMLAttributes:t}){return cf("strong",{...ct(this.options.HTMLAttributes,t),children:cf("slot",{})})},markdownTokenName:"strong",parseMarkdown:(t,e)=>e.applyMark("bold",e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>`**${e.renderChildren(t)}**`,addCommands(){return{setBold:()=>({commands:t})=>t.setMark(this.name),toggleBold:()=>({commands:t})=>t.toggleMark(this.name),unsetBold:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-b":()=>this.editor.commands.toggleBold(),"Mod-B":()=>this.editor.commands.toggleBold()}},addInputRules(){return[Ml({find:Pde,type:this.type}),Ml({find:Lde,type:this.type})]},addPasteRules(){return[ss({find:Rde,type:this.type}),ss({find:Ode,type:this.type})]}}),Dde=/(^|[^`])`([^`]+)`(?!`)$/,qde=/(^|[^`])`([^`]+)`(?!`)/g,zde=ao.create({name:"code",addOptions(){return{HTMLAttributes:{}}},excludes:"_",code:!0,exitable:!0,parseHTML(){return[{tag:"code"}]},renderHTML({HTMLAttributes:t}){return["code",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"codespan",parseMarkdown:(t,e)=>
vendor: 7,314 bytes, lines 17743-17764
17743e.applyMark("code",[{type:"text",text:t.text||""}]),renderMarkdown:(t,e)=>t.content?`\`${e.renderChildren(t.content)}\``:"",addCommands(){return{setCode:()=>({commands:t})=>t.setMark(this.name),toggleCode:()=>({commands:t})=>t.toggleMark(this.name),unsetCode:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-e":()=>this.editor.commands.toggleCode()}},addInputRules(){return[Ml({find:Dde,type:this.type})]},addPasteRules(){return[ss({find:qde,type:this.type})]}}),lx=4,Vde=/^```([a-z]+)?[\s\n]$/,Hde=/^~~~([a-z]+)?[\s\n]$/,Fde=Oa.create({name:"codeBlock",addOptions(){return{languageClassPrefix:"language-",exitOnTripleEnter:!0,exitOnArrowDown:!0,defaultLanguage:null,enableTabIndentation:!1,tabSize:lx,HTMLAttributes:{}}},content:"text*",marks:"",group:"block",code:!0,defining:!0,addAttributes(){return{language:{default:this.options.defaultLanguage,parseHTML:t=>{var e;const{languageClassPrefix:a}=this.options;if(!a)return null;const r=[...((e=t.firstElementChild)==null?void 0:e.classList)||[]].filter(o=>o.startsWith(a)).map(o=>o.replace(a,""))[0];return r||null},rendered:!1}}},parseHTML(){return[{tag:"pre",preserveWhitespace:"full"}]},renderHTML({node:t,HTMLAttributes:e}){return["pre",ct(this.options.HTMLAttributes,e),["code",{class:t.attrs.language?this.options.languageClassPrefix+t.attrs.language:null},0]]},markdownTokenName:"code",parseMarkdown:(t,e)=>{var a;return((a=t.raw)==null?void 0:a.startsWith("```"))===!1&&t.codeBlockStyle!=="indented"?[]:e.createNode("codeBlock",{language:t.lang||null},t.text?[e.createTextNode(t.text)]:[])},renderMarkdown:(t,e)=>{var a;let n="";const i=((a=t.attrs)==null?void 0:a.language)||"";return t.content?n=[`\`\`\`${i}`,e.renderChildren(t.content),"```"].join(` 17744`):n=`\`\`\`${i} 17745 17746\`\`\``,n},addCommands(){return{setCodeBlock:t=>({commands:e})=>e.setNode(this.name,t),toggleCodeBlock:t=>({commands:e})=>e.toggleNode(this.name,"paragraph",t)}},addKeyboardShortcuts(){return{"Mod-Alt-c":()=>this.editor.commands.toggleCodeBlock(),Backspace:()=>{const{empty:t,$anchor:e}=this.editor.state.selection,a=e.pos===1;return!t||e.parent.type.name!==this.name?!1:a||!e.parent.textContent.length?this.editor.commands.clearNodes():!1},Tab:({editor:t})=>{var e;if(!this.options.enableTabIndentation)return!1;const a=(e=this.options.tabSize)!=null?e:lx,{state:n}=t,{selection:i}=n,{$from:r,empty:o}=i;if(r.parent.type!==this.type)return!1;const l=" ".repeat(a);return o?t.commands.insertContent(l):t.commands.command(({tr:c})=>{const{from:d,to:u}=i,h=n.doc.textBetween(d,u,` 17747`,` 17748`).split(` 17749`).map(g=>l+g).join(` 17750`);return c.replaceWith(d,u,n.schema.text(h)),!0})},"Shift-Tab":({editor:t})=>{var e;if(!this.options.enableTabIndentation)return!1;const a=(e=this.options.tabSize)!=null?e:lx,{state:n}=t,{selection:i}=n,{$from:r,empty:o}=i;return r.parent.type!==this.type?!1:o?t.commands.command(({tr:l})=>{var c;const{pos:d}=r,u=r.start(),p=r.end(),h=n.doc.textBetween(u,p,` 17751`,` 17752`).split(` 17753`);let g=0,y=0;const x=d-u;for(let M=0;M<h.length;M+=1){if(y+h[M].length>=x){g=M;break}y+=h[M].length+1}const w=((c=h[g].match(/^ */))==null?void 0:c[0])||"",S=Math.min(w.length,a);if(S===0)return!0;let T=u;for(let M=0;M<g;M+=1)T+=h[M].length+1;return l.delete(T,T+S),d-T<=S&&l.setSelection(ce.create(l.doc,T)),!0}):t.commands.command(({tr:l})=>{const{from:c,to:d}=i,m=n.doc.textBetween(c,d,` 17754`,` 17755`).split(` 17756`).map(h=>{var g;const y=((g=h.match(/^ */))==null?void 0:g[0])||"",x=Math.min(y.length,a);return h.slice(x)}).join(` 17757`);return l.replaceWith(c,d,n.schema.text(m)),!0})},Enter:({editor:t})=>{if(!this.options.exitOnTripleEnter)return!1;const{state:e}=t,{selection:a}=e,{$from:n,empty:i}=a;if(!i||n.parent.type!==this.type)return!1;const r=n.parentOffset===n.parent.nodeSize-2,o=n.parent.textContent.endsWith(` 17758 17759`);return!r||!o?!1:t.chain().command(({tr:l})=>(l.delete(n.pos-2,n.pos),!0)).exitCode().run()},ArrowDown:({editor:t})=>{if(!this.options.exitOnArrowDown)return!1;const{state:e}=t,{selection:a,doc:n}=e,{$from:i,empty:r}=a;if(!r||i.parent.type!==this.type||!(i.parentOffset===i.parent.nodeSize-2))return!1;const l=i.after();return l===void 0?!1:n.nodeAt(l)?t.commands.command(({tr:d})=>(d.setSelection(xe.near(n.resolve(l))),!0)):t.commands.exitCode()}}},addInputRules(){return[Vb({find:Vde,type:this.type,getAttributes:t=>({language:t[1]})}),Vb({find:Hde,type:this.type,getAttributes:t=>({language:t[1]})})]},addProseMirrorPlugins(){return[new at({key:new _t("codeBlockVSCodeHandler"),props:{handlePaste:(t,e)=>{if(!e.clipboardData||this.editor.isActive(this.type.name))return!1;const a=e.clipboardData.getData("text/plain"),n=e.clipboardData.getData("vscode-editor-data"),i=n?JSON.parse(n):void 0,r=i==null?void 0:i.mode;if(!a||!r)return!1;const{tr:o,schema:l}=t.state,c=l.text(a.replace(/\r\n?/g,` 17760`));return o.replaceSelectionWith(this.type.create({language:r},c)),o.selection.$from.parent.type!==this.type&&o.setSelection(ce.near(o.doc.resolve(Math.max(0,o.selection.from-2)))),o.setMeta("paste",!0),t.dispatch(o),!0}}})]}}),Bde=Oa.create({name:"doc",topNode:!0,content:"block+",renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,` 17761 17762`):""}),Ude=Oa.create({name:"hardBreak",markdownTokenName:"br",addOptions(){return{keepMarks:!0,HTMLAttributes:{}}},inline:!0,group:"inline",selectable:!1,linebreakReplacement:!0,parseHTML(){return[{tag:"br"}]},renderHTML({HTMLAttributes:t}){return["br",ct(this.options.HTMLAttributes,t)]},renderText(){return` 17763`},renderMarkdown:()=>` 17764`,parseMarkdown:()=>({type:"hardBreak"}),addCommands(){return{setHardBreak:()=>({commands:t,chain:e,state:a,editor:n})=>t.first([()=>t.exitCode(),()=>t.command(()=>{const{selection:i,storedMarks:r}=a;if(i.$from.parent.type.spec.isolating)return!1;const{keepMarks:o}=this.options,{splittableMarks:l}=n.extensionManager,c=r||i.$to.parentOffset&&i.$from.marks();return e().insertContent({type:this.name}).command(({tr:d,dispatch:u})=>{if(u&&c&&o){const p=c.filter(m=>l.includes(m.type.name));d.ensureMarks(p)}return!0}).run()})])}},addKeyboardShortcuts(){return{"Mod-Enter":()=>this.editor.commands.setHardBreak(),"Shift-Enter":()=>this.editor.commands.setHardBreak()}}}),$de=Oa.create({name:"heading",addOptions(){return{levels:[1,2,3,4,5,6],HTMLAttributes:{}}},content:"inline*",group:"block",defining:!0,addAttributes(){return{level:{default:1,rendered:!1}}},parseHTML(){return this.options.levels.map(t=>({tag:`h${t}`,attrs:{level:t}}))},renderHTML({node:t,HTMLAttributes:e}){return[`h${this.options.levels.includes(t.attrs.level)?t.attrs.level:this.options.levels[0]}`,ct(this.options.HTMLAttributes,e),0]},parseMarkdown:(t,e)=>e.createNode("heading",{level:t.depth||1},e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>{var a;const n=(a=t.attrs)!=null&&a.level?parseInt(t.attrs.level,10):1,i="#".repeat(n);return t.content?`${i} ${e.renderChildren(t.content)}`:""},addCommands(){return{setHeading:t=>({commands:e})=>this.options.levels.includes(t.level)?e.setNode(this.name,t):!1,toggleHeading:t=>({commands:e})=>this.options.levels.includes(t.level)?e.toggleNode(this.name,"paragraph",t):!1}},addKeyboardShortcuts(){return this.options.levels.reduce((t,e)=>({...t,[`Mod-Alt-${e}`]:()=>this.editor.commands.toggleHeading({level:e})}),{})},addInputRules(){return this.options.levels.map(t=>Vb({find:new RegExp(`^(#{${Math.min(...this.options.levels)},${t}}
17764)\\s$`),type:this.type,getAttributes:{level:t}}))}}),Wde=Oa.create({name:"horizontalRule",addOptions(){return{HTMLAttributes:{},nextNodeType:"paragraph"}},group:"block",parseHTML(){return[{tag:"hr"}]},renderHTML({HTMLAttributes:t}){return["hr",ct(this.options.HTMLAttributes,t)]},markdownTokenName:"hr",parseMarkdown:(t,e)=>e.createNode("horizontalRule"),renderMarkdown:()=>"---",addCommands(){return{setHorizontalRule:()=>({chain:t,state:e})=>{if(!pce(e,e.schema.nodes[this.name]))return!1;const{selection:a}=e,{$to:n}=a,i=t();return T5(a)?i.insertContentAt(n.pos,{type:this.name}):i.insertContent({type:this.name}),i.command(({state:r,tr:o,dispatch:l})=>{if(l){const{$to:c}=o.selection,d=c.end();if(c.nodeAfter)c.nodeAfter.isTextblock?o.setSelection(ce.create(o.doc,c.pos+1)):c.nodeAfter.isBlock?o.setSelection(se.create(o.doc,c.pos)):o.setSelection(ce.create(o.doc,c.pos));else{const u=r.schema.nodes[this.options.nextNodeType]||c.parent.type.contentMatch.defaultType,p=u==null?void 0:u.create();p&&(o.insert(d,p),o.setSelection(ce.create(o.doc,d+1)))}o.scrollIntoView()}return!0}).run()}}},addInputRules(){return[W5({find:/^(?:---|â-|___\s|\*\*\*\s)$/,type:this.t
vendor: 4,463 bytes, line 17764
17764ype})]}}),Gde=/(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/,Kde=/(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g,Jde=/(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/,Qde=/(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g,Xde=ao.create({name:"italic",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"em"},{tag:"i",getAttrs:t=>t.style.fontStyle!=="normal"&&null},{style:"font-style=normal",clearMark:t=>t.type.name===this.name},{style:"font-style=italic"}]},renderHTML({HTMLAttributes:t}){return["em",ct(this.options.HTMLAttributes,t),0]},addCommands(){return{setItalic:()=>({commands:t})=>t.setMark(this.name),toggleItalic:()=>({commands:t})=>t.toggleMark(this.name),unsetItalic:()=>({commands:t})=>t.unsetMark(this.name)}},markdownTokenName:"em",parseMarkdown:(t,e)=>e.applyMark("italic",e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>`*${e.renderChildren(t)}*`,addKeyboardShortcuts(){return{"Mod-i":()=>this.editor.commands.toggleItalic(),"Mod-I":()=>this.editor.commands.toggleItalic()}},addInputRules(){return[Ml({find:Gde,type:this.type}),Ml({find:Jde,type:this.type})]},addPasteRules(){return[ss({find:Kde,type:this.type}),ss({find:Qde,type:this.type})]}});const Yde="aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2
17764ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2",Zde="ελ1Ï
2бг1ел3деÑи4еÑ2каÑолик6ом3мÐ
17764ºÐ´2он1Ñква6онлайн5Ñг3ÑÑÑ2Ñ2ÑайÑ3Ñб3ÑкÑ3Òаз3Õ°Õ¡Õµ3×שר××5×§××3Ø§Ø¨ÙØ¸Ø¨Ù5راÙ
ÙÙ5ÙØ§Ø±Ø¯Ù4Ø¨ØØ±ÙÙ5جزائر5Ø³Ø¹ÙØ¯ÙØ©6عÙÙØ§Ù5Ù
غرب5Ù
ارات5ÛØ±Ø§Ù5بارت2زار4ÙØªÙ3ھارت5تÙÙØ³4Ø³ÙØ¯Ø§Ù3Ø±ÙØ©5Ø´Ø¨ÙØ©4عراÙ2ب2Ù
اÙ4ÙÙØ³Ø·ÙÙ6ÙØ·Ø±3ÙØ§Ø«ÙÙÙÙ6ÙÙ
3Ù
صر2ÙÙØ³Ùا5ÙØ±ÙتاÙÙØ§7ÙØ¹4ÙÙ
راÙ5پاکستاÙ7ÚØ§Ø±Øª4à¤à¥à¤®3नà¥à¤3à¤à¤¾à¤°à¤¤0मà¥3à¥à¤¤5सà¤à¤à¤ न5বাà¦à¦²à¦¾5à¦à¦¾à¦°à¦¤2ৰত4à¨à¨¾à¨°à¨¤4àªàª¾àª°àª¤4à¬à¬¾à¬°à¬¤4à®à®¨à¯à®¤à®¿à®¯à®¾6லà®à¯à®à¯6à®à®¿à®à¯à®à®ªà¯à®ªà¯à®°à¯11à°à°¾à°°à°¤à±5à²à²¾à²°à²¤4à´à´¾à´°à´¤à´5à¶½à¶à¶à·4à¸à¸à¸¡3à¹à¸à¸¢3ລາວ3áá2ã¿ããª3ã¢ãã¾ã³4ã¯ã©ã¦ã4ã°ã¼ã°ã«4ã³ã 2ã¹ãã¢3ã»ã¼ã«3ãã¡ãã·ã§ã³6ãã¤ã³ã4ä¸ç2ä¸ä¿¡1å½1å1æç½3äºé©¬é3ä¼ä¸2ä½å±±2ä¿¡æ¯2å¥åº·2å
«å¦2å
¬å¸1ç2å°æ¹¾1ç£2åå1åº1æ 2åé0大é
åº5å¨çº¿2大æ¿2天主æ3娱ä¹2å®¶é»2广ä¸2å¾®å2æ
å2æç±ä½ 3ææº2æè2æ¿å¡1åº2æ°å å¡2é»2æ¶å°2æ¸ç±2æºæ2淡马é¡3游æ2æ¾³é2ç¹ç2ç§»å¨2ç»ç»æºæ4ç½å1åº1ç«1ç»2èé2è°·æ2è´ç©2é販2éå¢2é»è¨çç§4é£å©æµ¦3é£å2é¤å
2馿 ¼éæ3港2ë·ë·1ì»´2ì¼ì±2íêµ2",Bb="numeric",Ub="ascii",$b="alpha",_d="asciinumeric",Kc="alphanumeric",Wb="domain",Y5="emoji",eue="scheme",tue="slashscheme",cx="whitespace";function aue(t,e){return t in e||(e[t]=[]),e[t]}function To(t,e,a){e[Bb]&&(e[_d]=!0,e[Kc]=!0),e[Ub]&&(e[_d]=!0,e[$b]=!0),e[_d]&&(e[Kc]=!0),e[$b]&&(e[Kc]=!0),e[Kc]&&(e[Wb]=!0),e[Y5]&&(e[Wb]=!0);for(const n in e){const i=aue(n,a);i.indexOf(t)<0&&i.push(t)}}function nue(t,e){const a={};for(const n in e)e[n].indexOf(t)>=0&&(a[n]=!0);return a}function Sa(t=null){this.j={},this.jr=[],this.jd=null,this.t=t}Sa.groups={};Sa.prototype={accepts(){return!!this.t},go(t){const e=this,a=e.j[t];if(a)return a;for(let n=0;n<e.jr.length;n++){const i=e.jr[n][0],r=e.jr[n][1];if(r&&i.test(t))return r}return e.jd},has(t,e=!1){return e?t in this.j:!!this.go(t)},ta(t,e,a,n){for(let i=0;i<t.length;i++)this.tt(t[i],e,a,n)},tr(t,e,a,n){n=n||Sa.groups;let i;return e&&e.j?i=e:(i=new Sa(e),a&&n&&To(e,a,n)),this.jr.push([t,i]),i},ts(t,e,a,n){let i=this;const r=t.length;if(!r)return i;for(let o=0;o<r-1;o++)i=i.tt(t[o]);return i.tt(t[r-1],e,a,n)},tt(t,e,a,n){n=n||Sa.groups;const i=this;if(e&&e.j)return i.j[t]=e,e;const r=e;let o,l=i.go(t);if(l?(o=new Sa,Object.assign(o.j,l.j),o.jr.push.apply(o.jr,l.jr),o.jd=l.jd,o.t=l.t):o=new Sa,r){if(n)if(o.t&&typeof o.t=="string"){const c=Object.assign(nue(o.t,n),a);To(r,c,n)}else a&&To(r,a,n);o.t=r}return i.j[t]=o,o}};const ye=(t,e,a,n,i)=>t.ta(e,a,n,i),it=(t,e,a,n,i)=>t.tr(e,a,n,i),LT=(t,e,a,n,i)=>t.ts(e,a,n,i),B=(t,e,a,n,i)=>t.tt(e,a,n,i),hi="WORD",Gb="UWORD",Z5="ASCIINUMERICAL",eD="ALPHANUMERICAL",vu="LOCALHOST",Kb="TLD",Jb="UTLD",Wm="SCHEME",Ps="SLASH_SCHEME",SS="NUM",Qb="WS",_S="NL",Ad="OPENBRACE",Ed="CLOSEBRACE",df="OPENBRACKET",uf="CLOSEBRACKET",pf="OPENPAREN",mf="CLOSEPAREN",hf="OPENANGLEBRACKET",ff="CLOSEANGLEBRACKET",gf="FULLWIDTHLEFTPAREN",yf="FULLWIDTHRIGHTPAREN",xf="LEFTCORNERBRACKET",vf="RIGHTCORNERBRACKET",bf="LEFTWHITECORNERBRACKET",wf="RIGHTWHITECORNERBRACKET",kf="FULLWIDTHLESSTHAN",Sf="FULLWIDTHGREATERTHAN",_f="AMPERSAND",Af="APOSTROPHE",Ef="ASTERISK",ir="AT",Cf="BACKSLASH",jf="BACKTICK",Tf="CARET",mr="COLON",AS="COMMA",Nf="DOLLAR",Bn="DOT",If="EQUALS",ES="EXCLAMATION",en="HYPHEN",Cd="PERCENT",Pf="PIPE",Rf="PLUS",Lf="POUND",jd="QUERY",CS="QUOTE",tD="FULLWIDTHMIDDLEDOT",jS="SEMI",Un="SLASH",Td="TILDE",Of="UNDERSCORE",aD="EMOJI",Mf="SYM";var nD=Object.freeze({__proto__:null,ALPHANUMERICAL:eD,AMPERSAND:_f,APOSTROPHE:Af,ASCIINUMERICAL:Z5,ASTERISK:Ef,AT:ir,BACKSLASH:Cf,BACKTICK:jf,CARET:Tf,CLOSEANGLEBRACKET:ff,CLOSEBRACE:Ed,CLOSEBRACKET:uf,CLOSEPAREN:mf,COLON:mr,COMMA:AS,DOLLAR:Nf,DOT:Bn,EMOJI:aD,EQUALS:If,EXCLAMATION:ES,FULLWIDTHGREATERTHAN:Sf,FULLWIDTHLEFTPAREN:gf,FULLWIDTHLESSTHAN:kf,FULLWIDTHMIDDLEDOT:tD,FULLWIDTHRIGHTPAREN:yf,HYPHEN:en,LEFTCORNERBRACKET:xf,LEFTWHITECORNERBRACKET:bf,LOCALHOST:vu,NL:_S,NUM:SS,OPENANGLEBRACKET:hf,OPENBRACE:Ad,OPENBRACKET:df,OPENPAREN:pf,PERCENT:Cd,PIPE:Pf,PLUS:Rf,POUND:Lf,QUERY:jd,QUOTE:CS,RIGHTCORNERBRACKET:vf,RIGHTWHITECORNERBRACKET:wf,SC
vendor: 31,414 bytes, lines 17764-17779
17764HEME:Wm,SEMI:jS,SLASH:Un,SLASH_SCHEME:Ps,SYM:Mf,TILDE:Td,TLD:Kb,UNDERSCORE:Of,UTLD:Jb,UWORD:Gb,WORD:hi,WS:Qb});const pi=/[a-z]/,Rc=new RegExp("\\p{L}","u"),dx=new RegExp("\\p{Emoji}","u"),mi=/\d/,ux=/\s/,OT="\r",px=` 17765`,iue="ï¸",rue="â",mx="";let rm=null,om=null;function oue(t=[]){const e={};Sa.groups=e;const a=new Sa;rm==null&&(rm=MT(Yde)),om==null&&(om=MT(Zde)),B(a,"'",Af),B(a,"{",Ad),B(a,"}",Ed),B(a,"[",df),B(a,"]",uf),B(a,"(",pf),B(a,")",mf),B(a,"<",hf),B(a,">",ff),B(a,"ï¼",gf),B(a,"ï¼",yf),B(a,"ã",xf),B(a,"ã",vf),B(a,"ã",bf),B(a,"ã",wf),B(a,"ï¼",kf),B(a,"ï¼",Sf),B(a,"&",_f),B(a,"*",Ef),B(a,"@",ir),B(a,"`",jf),B(a,"^",Tf),B(a,":",mr),B(a,",",AS),B(a,"$",Nf),B(a,".",Bn),B(a,"=",If),B(a,"!",ES),B(a,"-",en),B(a,"%",Cd),B(a,"|",Pf),B(a,"+",Rf),B(a,"#",Lf),B(a,"?",jd),B(a,'"',CS),B(a,"/",Un),B(a,";",jS),B(a,"~",Td),B(a,"_",Of),B(a,"\\",Cf),B(a,"ã»",tD);const n=it(a,mi,SS,{[Bb]:!0});it(n,mi,n);const i=it(n,pi,Z5,{[_d]:!0}),r=it(n,Rc,eD,{[Kc]:!0}),o=it(a,pi,hi,{[Ub]:!0});it(o,mi,i),it(o,pi,o),it(i,mi,i),it(i,pi,i);const l=it(a,Rc,Gb,{[$b]:!0});it(l,pi),it(l,mi,r),it(l,Rc,l),it(r,mi,r),it(r,pi),it(r,Rc,r);const c=B(a,px,_S,{[cx]:!0}),d=B(a,OT,Qb,{[cx]:!0}),u=it(a,ux,Qb,{[cx]:!0});B(a,mx,u),B(d,px,c),B(d,mx,u),it(d,ux,u),B(u,OT),B(u,px),it(u,ux,u),B(u,mx,u);const p=it(a,dx,aD,{[Y5]:!0});B(p,"#"),it(p,dx,p),B(p,iue,p);const m=B(p,rue);B(m,"#"),it(m,dx,p);const h=[[pi,o],[mi,i]],g=[[pi,null],[Rc,l],[mi,r]];for(let y=0;y<rm.length;y++)Xi(a,rm[y],Kb,hi,h);for(let y=0;y<om.length;y++)Xi(a,om[y],Jb,Gb,g);To(Kb,{tld:!0,ascii:!0},e),To(Jb,{utld:!0,alpha:!0},e),Xi(a,"file",Wm,hi,h),Xi(a,"mailto",Wm,hi,h),Xi(a,"http",Ps,hi,h),Xi(a,"https",Ps,hi,h),Xi(a,"ftp",Ps,hi,h),Xi(a,"ftps",Ps,hi,h),To(Wm,{scheme:!0,ascii:!0},e),To(Ps,{slashscheme:!0,ascii:!0},e),t=t.sort((y,x)=>y[0]>x[0]?1:-1);for(let y=0;y<t.length;y++){const x=t[y][0],w=t[y][1]?{[eue]:!0}:{[tue]:!0};x.indexOf("-")>=0?w[Wb]=!0:pi.test(x)?mi.test(x)?w[_d]=!0:w[Ub]=!0:w[Bb]=!0,LT(a,x,x,w)}return LT(a,"localhost",vu,{ascii:!0}),a.jd=new Sa(Mf),{start:a,tokens:Object.assign({groups:e},nD)}}function iD(t,e){const a=sue(e.replace(/[A-Z]/g,l=>l.toLowerCase())),n=a.length,i=[];let r=0,o=0;for(;o<n;){let l=t,c=null,d=0,u=null,p=-1,m=-1;for(;o<n&&(c=l.go(a[o]));)l=c,l.accepts()?(p=0,m=0,u=l):p>=0&&(p+=a[o].length,m++),d+=a[o].length,r+=a[o].length,o++;r-=p,o-=m,d-=p,i.push({t:u.t,v:e.slice(r-d,r),s:r-d,e:r})}return i}function sue(t){const e=[],a=t.length;let n=0;for(;n<a;){let i=t.charCodeAt(n),r,o=i<55296||i>56319||n+1===a||(r=t.charCodeAt(n+1))<56320||r>57343?t[n]:t.slice(n,n+2);e.push(o),n+=o.length}return e}function Xi(t,e,a,n,i){let r;const o=e.length;for(let l=0;l<o-1;l++){const c=e[l];t.j[c]?r=t.j[c]:(r=new Sa(n),r.jr=i.slice(),t.j[c]=r),t=r}return r=new Sa(a),r.jr=i.slice(),t.j[e[o-1]]=r,r}function MT(t){const e=[],a=[];let n=0,i="0123456789";for(;n<t.length;){let r=0;for(;i.indexOf(t[n+r])>=0;)r++;if(r>0){e.push(a.join(""));for(let o=parseInt(t.substring(n,n+r),10);o>0;o--)a.pop();n+=r}else a.push(t[n]),n++}return e}const bu={defaultProtocol:"http",events:null,format:DT,formatHref:DT,nl2br:!1,tagName:"a",target:null,rel:null,validate:!0,truncate:1/0,className:null,attributes:null,ignoreTags:[],render:null};function TS(t,e=null){let a=Object.assign({},bu);t&&(a=Object.assign(a,t instanceof TS?t.o:t));const n=a.ignoreTags,i=[];for(let r=0;r<n.length;r++)i.push(n[r].toUpperCase());this.o=a,e&&(this.defaultRender=e),this.ignoreTags=i}TS.prototype={o:bu,ignoreTags:[],defaultRender(t){return t},check(t){return this.get("validate",t.toString(),t)},get(t,e,a){const n=e!=null;let i=this.o[t];return i&&(typeof i=="object"?(i=a.t in i?i[a.t]:bu[t],typeof i=="function"&&n&&(i=i(e,a))):typeof i=="function"&&n&&(i=i(e,a.t,a)),i)},getObj(t,e,a){let n=this.o[t];return typeof n=="function"&&e!=null&&(n=n(e,a.t,a)),n},render(t){const e=t.render(this);return(this.get("render",null,t)||this.defaultRender)(e,t.t,t)}};function DT(t){return t}function rD(t,e){this.t="token",this.v=t,this.tk=e}rD.prototype={isLink:!1,toString(){return this.v},toHref(t){return this.toString()},toFormattedString(t){const e=this.toString(),a=t.get("truncate",e,this),n=t.get("format",e,this);return a&&n.length>a?n.substring(0,a)+"â¦":n},toFormattedHref(t){return t.get("formatHref",this.toHref(t.get("defaultProtocol")),this)},startIndex(){return this.tk[0].s},endIndex(){return this.tk[this.tk.length-1].e},toObject(t=bu.defaultProtocol){return{type:this.t,value:this.toString(),isLink:this.isLink,href:this.toHref(t),start:this.startIndex(),end:this.endIndex()}},toFormattedObject(t){return{type:this.t,value:this.toFormattedString(t),isLink:this.isLink,href:this.toFormattedHref(t),start:this.startIndex(),end:this.endIndex()}},validate(t){return t.get("validate",this.toString(),this)},render(t){const e=this,a=this.toHref(t.get("defaultProtocol")),n=t.get("formatHref",a,this),i=t.get("tagName",a,e),r=this.toFormattedString(t),o={},l=t.get("className",a,e),c=t.get("target",a,e),d=t.get("rel",a,e),u=t.getObj("attributes",a,e),p=t.getObj("events",a,e);return o.href=n,l&&(o.class=l),c&&(o.target=c),d&&(o.rel=d),u&&Object.assign(o,u),{tagName:i,attributes:o,content:r,eventListeners:p}}};function Yg(t,e){class a extends rD{constructor(i,r){super(i,r),this.t=t}}for(const n in e)a.prototype[n]=e[n];return a.t=t,a}const qT=Yg("email",{isLink:!0,toHref(){return"mailto:"+this.toString()}}),zT=Yg("text"),lue=Yg("nl"),sm=Yg("url",{isLink:!0,toHref(t=bu.defaultProtocol){return this.hasProtocol()?this.v:`${t}://${this.v}`},hasProtocol(){const t=this.tk;return t.length>=2&&t[0].t!==vu&&t[1].t===mr}}),Ya=t=>new Sa(t);function cue({groups:t}){const e=t.domain.concat([_f,Ef,ir,Cf,jf,Tf,Nf,If,en,SS,Cd,Pf,Rf,Lf,Un,Mf,Td,Of]),a=[Af,mr,AS,Bn,ES,Cd,jd,CS,jS,hf,ff,Ad,Ed,uf,df,pf,mf,gf,yf,xf,vf,bf,wf,kf,Sf],n=[_f,Af,Ef,Cf,jf,Tf,Nf,If,en,Ad,Ed,Cd,Pf,Rf,Lf,jd,Un,Mf,Td,Of],i=Ya(),r=B(i,Td);ye(r,n,r),ye(r,t.domain,r);const o=Ya(),l=Ya(),c=Ya();ye(i,t.domain,o),ye(i,t.scheme,l),ye(i,t.slashscheme,c),ye(o,n,r),ye(o,t.domain,o);const d=B(o,ir);B(r,ir,d),B(l,ir,d),B(c,ir,d);const u=B(r,Bn);ye(u,n,r),ye(u,t.domain,r);const p=Ya();ye(d,t.domain,p),ye(p,t.domain,p);const m=B(p,Bn);ye(m,t.domain,p);const h=Ya(qT);ye(m,t.tld,h),ye(m,t.utld,h),B(d,vu,h);const g=B(p,en);B(g,en,g),ye(g,t.domain,p),ye(h,t.domain,p),B(h,Bn,m),B(h,en,g);const y=B(h,mr);ye(y,t.numeric,qT);const x=B(o,en),v=B(o,Bn);B(x,en,x),ye(x,t.domain,o),ye(v,n,r),ye(v,t.domain,o);const w=Ya(sm);ye(v,t.tld,w),ye(v,t.utld,w),ye(w,t.domain,o),ye(w,n,r),B(w,Bn,v),B(w,en,x),B(w,ir,d);const S=B(w,mr),T=Ya(sm);ye(S,t.numeric,T);const P=Ya(sm),M=Ya();ye(P,e,P),ye(P,a,M),ye(M,e,P),ye(M,a,M),B(w,Un,P),B(T,Un,P);const C=B(l,mr),E=B(c,mr),j=B(E,Un),N=B(j,Un);ye(l,t.domain,o),B(l,Bn,v),B(l,en,x),ye(c,t.domain,o),B(c,Bn,v),B(c,en,x),ye(C,t.domain,P),B(C,Un,P),B(C,jd,P),ye(N,t.domain,P),ye(N,e,P),B(N,Un,P);const L=[[Ad,Ed],[df,uf],[pf,mf],[hf,ff],[gf,yf],[xf,vf],[bf,wf],[kf,Sf]];for(let O=0;O<L.length;O++){const[R,G]=L[O],ee=B(P,R);B(M,R,ee),B(ee,G,P);const ke=Ya(sm);ye(ee,e,ke);const ae=Ya();ye(ee,a),ye(ke,e,ke),ye(ke,a,ae),ye(ae,e,ke),ye(ae,a,ae),B(ke,G,P),B(ae,G,P)}return B(i,vu,w),B(i,_S,lue),{start:i,tokens:nD}}function due(t,e,a){let n=a.length,i=0,r=[],o=[];for(;i<n;){let l=t,c=null,d=null,u=0,p=null,m=-1;for(;i<n&&!(c=l.go(a[i].t));)o.push(a[i++]);for(;i<n&&(d=c||l.go(a[i].t));)c=null,l=d,l.accepts()?(m=0,p=l):m>=0&&m++,i++,u++;if(m<0)i-=u,i<n&&(o.push(a[i]),i++);else{o.length>0&&(r.push(hx(zT,e,o)),o=[]),i-=m,u-=m;const h=p.t,g=a.slice(i-u,i);r.push(hx(h,e,g))}}return o.length>0&&r.push(hx(zT,e,o)),r}function hx(t,e,a){const n=a[0].s,i=a[a.length-1].e,r=e.slice(n,i);return new t(r,a)}const uue=typeof console<"u"&&console&&console.warn||(()=>{}),pue="until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time.",Be={scanner:null,parser:null,tokenQueue:[],pluginQueue:[],customSchemes:[],initialized:!1};function mue(){return Sa.groups={},Be.scanner=null,Be.parser=null,Be.tokenQueue=[],Be.pluginQueue=[],Be.customSchemes=[],Be.initialized=!1,Be}function VT(t,e=!1){if(Be.initialized&&uue(`linkifyjs: already initialized - will not register custom scheme "${t}" ${pue}`),!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(t))throw new Error(`linkifyjs: incorrect scheme format. 177661. Must only contain digits, lowercase ASCII letters or "-" 177672. Cannot start or end with "-" 177683. "-" cannot repeat`);Be.customSchemes.push([t,e])}function hue(){Be.scanner=oue(Be.customSchemes);for(let t=0;t<Be.tokenQueue.length;t++)Be.tokenQueue[t][1]({scanner:Be.scanner});Be.parser=cue(Be.scanner.tokens);for(let t=0;t<Be.pluginQueue.length;t++)Be.pluginQueue[t][1]({scanner:Be.scanner,parser:Be.parser});return Be.initialized=!0,Be}function NS(t){return Be.initialized||hue(),due(Be.parser.start,t,iD(Be.scanner.start,t))}NS.scan=iD;function oD(t,e=null,a=null){if(e&&typeof e=="object"){if(a)throw Error(`linkifyjs: Invalid link type ${e}; must be a string`);a=e,e=null}const n=new TS(a),i=NS(t),r=[];for(let o=0;o<i.length;o++){const l=i[o];l.isLink&&(!e||l.t===e)&&n.check(l)&&r.push(l.toFormattedObject(n))}return r}var IS="[\0-  áá â-\u2029âã]",fue=new RegExp(IS),gue=new RegExp(`${IS}$`),yue=new RegExp(IS,"g");function xue(t){return t.length===1?t[0].isLink:t.length===3&&t[1].isLink?["()","[]"].includes(t[0].value+t[2].value):!1}function vue(t){return new at({key:new _t("autolink"),appendTransaction:(e,a,n)=>{const i=e.some(d=>d.docChanged)&&!a.doc.eq(n.doc),r=e.some(d=>d.getMeta("preventAutolink"));if(!i||r)return;const{tr:o}=n,l=w5(a.doc,[...e]);if(j5(l).forEach(({newRange:d})=>{const u=cle(n.doc,d,h=>h.isTextblock);let p,m;if(u.length>1)p=u[0],m=n.doc.textBetween(p.pos,p.pos+p.node.nodeSize,void 0," ");else if(u.length){const h=n.doc.textBetween(d.from,d.to," "," ");if(!gue.test(h))return;p=u[0],m=n.doc.textBetween(p.pos,d.to,void 0," ")}if(p&&m){const h=m.split(fue).filter(Boolean);if(h.length<=0)return!1;const g=h[h.length-1],y=p.pos+m.lastIndexOf(g);if(!g)return!1;const x=NS(g).map(v=>v.toObject(t.defaultProtocol));if(!xue(x))return!1;x.filter(v=>v.isLink).map(v=>({...v,from:y+v.start+1,to:y+v.end+1})).filter(v=>n.schema.marks.code?!n.doc.rangeHasMark(v.from,v.to,n.schema.marks.code):!0).filter(v=>t.validate(v.value)).filter(v=>t.shouldAutoLink(v.value)).forEach(v=>{xS(v.from,v.to,n.doc).some(w=>w.mark.type===t.type)||o.addMark(v.from,v.to,t.type.create({href:v.href}))})}}),!!o.steps.length)return o}})}function bue(t){return new at({key:new _t("handleClickLink"),props:{handleClick:(e,a,n)=>{var i,r;if(n.button!==0||!e.editable)return!1;let o=null;if(n.target instanceof HTMLAnchorElement)o=n.target;else{const c=n.target;if(!c)return!1;const d=t.editor.view.dom;o=c.closest("a"),o&&!d.contains(o)&&(o=null)}if(!o)return!1;let l=!1;if(t.enableClickSelection&&(l=t.editor.commands.extendMarkRange(t.type.name)),t.openOnClick){const c=C5(e.state,t.type.name),d=(i=o.href)!=null?i:c.href,u=(r=o.target)!=null?r:c.target;d&&(window.open(d,u),l=!0)}return l}}})}function wue(t){return new at({key:new _t("handlePasteLink"),props:{handlePaste:(e,a,n)=>{const{shouldAutoLink:i}=t,{state:r}=e,{selection:o}=r,{empty:l}=o;if(l)return!1;let c="";n.content.forEach(u=>{c+=u.textContent});const d=oD(c,{defaultProtocol:t.defaultProtocol}).find(u=>u.isLink&&u.value===c);return!c||!d||i!==void 0&&!i(d.value)?!1:t.editor.commands.setMark(t.type,{href:d.href})}}})}function uo(t,e){const a=["http","https","ftp","ftps","mailto","tel","callto","sms","cid","xmpp"];return e&&e.forEach(n=>{const i=typeof n=="string"?n:n.scheme;i&&a.push(i)}),!t||t.replace(yue,"").match(new RegExp(`^(?:(?:${a.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,"i"))}var kue=ao.create({name:"link",priority:1e3,keepOnSplit:!1,exitable:!0,onCreate(){this.options.validate&&!this.options.shouldAutoLink&&(this.options.shouldAutoLink=this.options.validate,console.warn("The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.")),this.options.protocols.forEach(t=>{if(typeof t=="string"){VT(t);return}VT(t.scheme,t.optionalSlashes)})},onDestroy(){mue()},inclusive(){return this.options.autolink},addOptions(){return{openOnClick:!0,enableClickSelection:!1,linkOnPaste:!0,autolink:!0,protocols:[],defaultProtocol:"http",HTMLAttributes:{target:"_blank",rel:"noopener noreferrer nofollow",class:null},isAllowedUri:(t,e)=>!!uo(t,e.protocols),validate:t=>!!t,shouldAutoLink:t=>{const e=/^[a-z][a-z0-9+.-]*:\/\//i.test(t),a=/^[a-z][a-z0-9+.-]*:/i.test(t);if(e||a&&!t.includes("@"))return!0;const i=(t.includes("@")?t.split("@").pop():t).split(/[/?#:]/)[0];return!(/^\d{1,3}(\.\d{1,3}){3}$/.test(i)||!/\./.test(i))}}},addAttributes(){return{href:{default:null,parseHTML(t){return t.getAttribute("href")}},target:{default:this.options.HTMLAttributes.target},rel:{default:this.options.HTMLAttributes.rel},class:{default:this.options.HTMLAttributes.class}}},parseHTML(){return[{tag:"a[href]",getAttrs:t=>{const e=t.getAttribute("href");return!e||!this.options.isAllowedUri(e,{defaultValidate:a=>!!uo(a,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?!1:null}}]},renderHTML({HTMLAttributes:t}){return this.options.isAllowedUri(t.href,{defaultValidate:e=>!!uo(e,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?["a",ct(this.options.HTMLAttributes,t),0]:["a",ct(this.options.HTMLAttributes,{...t,href:""}),0]},markdownTokenName:"link",parseMarkdown:(t,e)=>e.applyMark("link",e.parseInline(t.tokens||[]),{href:t.href,title:t.title||null}),renderMarkdown:(t,e)=>{var a;const n=((a=t.attrs)==null?void 0:a.href)||"";return`[${e.renderChildren(t)}](${n})`},addCommands(){return{setLink:t=>({chain:e})=>{const{href:a}=t;return this.options.isAllowedUri(a,{defaultValidate:n=>!!uo(n,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?e().setMark(this.name,t).setMeta("preventAutolink",!0).run():!1},toggleLink:t=>({chain:e})=>{const{href:a}=t||{};return a&&!this.options.isAllowedUri(a,{defaultValidate:n=>!!uo(n,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?!1:e().toggleMark(this.name,t,{extendEmptyMarkRange:!0}).setMeta("preventAutolink",!0).run()},unsetLink:()=>({chain:t})=>t().unsetMark(this.name,{extendEmptyMarkRange:!0}).setMeta("preventAutolink",!0).run()}},addPasteRules(){return[ss({find:t=>{const e=[];if(t){const{protocols:a,defaultProtocol:n}=this.options,i=oD(t).filter(r=>r.isLink&&this.options.isAllowedUri(r.value,{defaultValidate:o=>!!uo(o,a),protocols:a,defaultProtocol:n}));i.length&&i.forEach(r=>{this.options.shouldAutoLink(r.value)&&e.push({text:r.value,data:{href:r.href},index:r.start})})}return e},type:this.type,getAttributes:t=>{var e;return{href:(e=t.data)==null?void 0:e.href}}})]},addProseMirrorPlugins(){const t=[],{protocols:e,defaultProtocol:a}=this.options;return this.options.autolink&&t.push(vue({type:this.type,defaultProtocol:this.options.defaultProtocol,validate:n=>this.options.isAllowedUri(n,{defaultValidate:i=>!!uo(i,e),protocols:e,defaultProtocol:a}),shouldAutoLink:this.options.shouldAutoLink})),t.push(bue({type:this.type,editor:this.editor,openOnClick:this.options.openOnClick==="whenNotEditable"?!0:this.options.openOnClick,enableClickSelection:this.options.enableClickSelection})),this.options.linkOnPaste&&t.push(wue({editor:this.editor,defaultProtocol:this.options.defaultProtocol,type:this.type,shouldAutoLink:this.options.shouldAutoLink})),t}}),Sue=Object.defineProperty,_ue=(t,e)=>{for(var a in e)Sue(t,a,{get:e[a],enumerable:!0})},Aue="listItem",HT="textStyle",FT=/^\s*([-+*])\s$/,sD=Oa.create({name:"bulletList",addOptions(){return{itemTypeName:"listItem",HTMLAttributes:{},keepMarks:!1,keepAttributes:!1}},group:"block list",content(){return`${this.options.itemTypeName}+`},parseHTML(){return[{tag:"ul"}]},renderHTML({HTMLAttributes:t}){return["ul",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"list",parseMarkdown:(t,e)=>t.type!=="list"||t.ordered?[]:{type:"bulletList",content:t.items?e.parseChildren(t.items):[]},renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,` 17769`):"",markdownOptions:{indentsContent:!0},addCommands(){return{toggleBulletList:()=>({commands:t,chain:e})=>this.options.keepAttributes?e().toggleList(this.name,this.options.itemTypeName,this.options.keepMarks).updateAttributes(Aue,this.editor.getAttributes(HT)).run():t.toggleList(this.name,this.options.itemTypeName,this.options.keepMarks)}},addKeyboardShortcuts(){return{"Mod-Shift-8":()=>this.editor.commands.toggleBulletList()}},addInputRules(){let t=Dl({find:FT,type:this.type});return(this.options.keepMarks||this.options.keepAttributes)&&(t=Dl({find:FT,type:this.type,keepMarks:this.options.keepMarks,keepAttributes:this.options.keepAttributes,getAttributes:()=>this.editor.getAttributes(HT),editor:this.editor})),[t]}}),lD=Oa.create({name:"listItem",addOptions(){return{HTMLAttributes:{},bulletListTypeName:"bulletList",orderedListTypeName:"orderedList"}},content:"paragraph block*",defining:!0,parseHTML(){return[{tag:"li"}]},renderHTML({HTMLAttributes:t}){return["li",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"list_item",parseMarkdown:(t,e)=>{if(t.type!=="list_item")return[];let a=[];if(t.tokens&&t.tokens.length>0)if(t.tokens.some(i=>i.type==="paragraph"))a=e.parseChildren(t.tokens);else{const i=t.tokens[0];if(i&&i.type==="text"&&i.tokens&&i.tokens.length>0){if(a=[{type:"paragraph",content:e.parseInline(i.tokens)}],t.tokens.length>1){const o=t.tokens.slice(1),l=e.parseChildren(o);a.push(...l)}}else a=e.parseChildren(t.tokens)}return a.length===0&&(a=[{type:"paragraph",content:[]}]),{type:"listItem",content:a}},renderMarkdown:(t,e,a)=>kS(t,e,n=>n.parentType==="bulletList"?"- ":n.parentType==="orderedList"?`${n.index+1}. `:"- ",a),addKeyboardShortcuts(){return{Enter:()=>this.editor.commands.splitListItem(this.name),Tab:()=>this.editor.commands.sinkListItem(this.name),"Shift-Tab":()=>this.editor.commands.liftListItem(this.name)}}}),Eue={};_ue(Eue,{findListItemPos:()=>Qu,getNextListDepth:()=>PS,handleBackspace:()=>Xb,handleDelete:()=>Yb,hasListBefore:()=>cD,hasListItemAfter:()=>Cue,hasListItemBefore:()=>dD,listItemHasSubList:()=>uD,nextListIsDeeper:()=>pD,nextListIsHigher:()=>mD});var Qu=(t,e)=>{const{$from:a}=e.selection,n=vt(t,e.schema);let i=null,r=a.depth,o=a.pos,l=null;for(;r>0&&l===null;)i=a.node(r),i.type===n?l=r:(r-=1,o-=1);return l===null?null:{$pos:e.doc.resolve(o),depth:l}},PS=(t,e)=>{const a=Qu(t,e);if(!a)return!1;const[,n]=ble(e,t,a.$pos.pos+4);return n},cD=(t,e,a)=>{const{$anchor:n}=t.selection,i=Math.max(0,n.pos-2),r=t.doc.resolve(i).node();return!(!r||!a.includes(r.type.name))},dD=(t,e)=>{var a;const{$anchor:n}=e.selection,i=e.doc.resolve(n.pos-2);return!(i.index()===0||((a=i.nodeBefore)==null?void 0:a.type.name)!==t)},uD=(t,e,a)=>{if(!a)return!1;const n=vt(t,e.schema);let i=!1;return a.descendants(r=>{r.type===n&&(i=!0)}),i},Xb=(t,e,a)=>{if(t.commands.undoInputRule())return!0;if(t.state.selection.from!==t.state.selection.to)return!1;if(!$r(t.state,e)&&cD(t.state,e,a)){const{$anchor:l}=t.state.selection,c=t.state.doc.resolve(l.before()-1),d=[];c.node().descendants((m,h)=>{m.type.name===e&&d.push({node:m,pos:h})});const u=d.at(-1);if(!u)return!1;const p=t.state.doc.resolve(c.start()+u.pos+1);return t.chain().cut({from:l.start()-1,to:l.end()+1},p.end()).joinForward().run()}if(!$r(t.state,e)||!_le(t.state))return!1;const n=Qu(e,t.state);if(!n)return!1;const r=t.state.doc.resolve(n.$pos.pos-2).node(n.depth),o=uD(e,t.state,r);return dD(e,t.state)&&!o?t.commands.joinItemBackward():t.chain().liftListItem(e).run()},pD=(t,e)=>{const a=PS(t,e),n=Qu(t,e);return!n||!a?!1:a>n.depth},mD=(t,e)=>{const a=PS(t,e),n=Qu(t,e);return!n||!a?!1:a<n.depth},Yb=(t,e)=>{if(!$r(t.state,e)||!Sle(t.state,e))return!1;const{selection:a}=t.state,{$from:n,$to:i}=a;return!a.empty&&n.sameParent(i)?!1:pD(e,t.state)?t.chain().focus(t.state.selection.from+4).lift(e).joinBackward().run():mD(e,t.state)?t.chain().joinForward().joinBackward().run():t.commands.joinItemForward()},Cue=(t,e)=>{var a;const{$anchor:n}=e.selection,i=e.doc.resolve(n.pos-n.parentOffset-2);return!(i.index()===i.parent.childCount-1||((a=i.nodeAfter)==null?void 0:a.type.name)!==t)},hD=ze.create({name:"listKeymap",addOptions(){return{listTypes:[{itemName:"listItem",wrapperNames:["bulletList","orderedList"]},{itemName:"taskItem",wrapperNames:["taskList"]}]}},addKeyboardShortcuts(){return{Delete:({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a})=>{t.state.schema.nodes[a]!==void 0&&Yb(t,a)&&(e=!0)}),e},"Mod-Delete":({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a})=>{t.state.schema.nodes[a]!==void 0&&Yb(t,a)&&(e=!0)}),e},Backspace:({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a,wrapperNames:n})=>{t.state.schema.nodes[a]!==void 0&&Xb(t,a,n)&&(e=!0)}),e},"Mod-Backspace":({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a,wrapperNames:n})=>{t.state.schema.nodes[a]!==void 0&&Xb(t,a,n)&&(e=!0)}),e}}}}),BT=/^(\s*)(\d+)\.\s+(.*)$/,jue=/^\s/;function Tue(t){const e=[];let a=0,n=0;for(;a<t.length;){const i=t[a],r=i.match(BT);if(!r)break;const[,o,l,c]=r,d=o.length;let u=c,p=a+1;const m=[i];for(;p<t.length;){const h=t[p];if(h.match(BT))break;if(h.trim()==="")m.push(h),u+=` 17770`,p+=1;else if(h.match(jue))m.push(h),u+=` 17771${h.slice(d+2)}`,p+=1;else break}e.push({indent:d,number:parseInt(l,10),content:u.trim(),raw:m.join(` 17772`)}),n=p,a=p}return[e,n]}function fD(t,e,a){var n;const i=[];let r=0;for(;r<t.length;){const o=t[r];if(o.indent===e){const l=o.content.split(` 17773`),c=((n=l[0])==null?void 0:n.trim())||"",d=[];c&&d.push({type:"paragraph",raw:c,tokens:a.inlineTokens(c)});const u=l.slice(1).join(` 17774`).trim();if(u){const h=a.blockTokens(u);d.push(...h)}let p=r+1;const m=[];for(;p<t.length&&t[p].indent>e;)m.push(t[p]),p+=1;if(m.length>0){const h=Math.min(...m.map(y=>y.indent)),g=fD(m,h,a);d.push({type:"list",ordered:!0,start:m[0].number,items:g,raw:m.map(y=>y.raw).join(` 17775`)})}i.push({type:"list_item",raw:o.raw,tokens:d}),r=p}else r+=1}return i}function Nue(t,e){return t.map(a=>{if(a.type!=="list_item")return e.parseChildren([a])[0];const n=[];return a.tokens&&a.tokens.length>0&&a.tokens.forEach(i=>{if(i.type==="paragraph"||i.type==="list"||i.type==="blockquote"||i.type==="code")n.push(...e.parseChildren([i]));else if(i.type==="text"&&i.tokens){const r=e.parseChildren([i]);n.push({type:"paragraph",content:r})}else{const r=e.parseChildren([i]);r.length>0&&n.push(...r)}}),{type:"listItem",content:n}})}var Iue="listItem",UT="textStyle",$T=/^(\d+)\.\s$/,gD=Oa.create({name:"orderedList",addOptions(){return{itemTypeName:"listItem",HTMLAttributes:{},keepMarks:!1,keepAttributes:!1}},group:"block list",content(){return`${this.options.itemTypeName}+`},addAttributes(){return{start:{default:1,parseHTML:t=>t.hasAttribute("start")?parseInt(t.getAttribute("start")||"",10):1},type:{default:null,parseHTML:t=>t.getAttribute("type")}}},parseHTML(){return[{tag:"ol"}]},renderHTML({HTMLAttributes:t}){const{start:e,...a}=t;return e===1?["ol",ct(this.options.HTMLAttributes,a),0]:["ol",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"list",parseMarkdown:(t,e)=>{if(t.type!=="list"||!t.ordered)return[];const a=t.start||1,n=t.items?Nue(t.items,e):[];return a!==1?{type:"orderedList",attrs:{start:a},content:n}:{type:"orderedList",content:n}},renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,` 17776`):"",markdownTokenizer:{name:"orderedList",level:"block",start:t=>{const e=t.match(/^(\s*)(\d+)\.\s+/),a=e==null?void 0:e.index;return a!==void 0?a:-1},tokenize:(t,e,a)=>{var n;const i=t.split(` 17777`),[r,o]=Tue(i);if(r.length===0)return;const l=fD(r,0,a);return l.length===0?void 0:{type:"list",ordered:!0,start:((n=r[0])==null?void 0:n.number)||1,items:l,raw:i.slice(0,o).join(` 17778`)}}},markdownOptions:{indentsContent:!0},addCommands(){return{toggleOrderedList:()=>({commands:t,chain:e})=>this.options.keepAttributes?e().toggleList(this.name,this.options.itemTypeName,this.options.keepMarks).updateAttributes(Iue,this.editor.getAttributes(UT)).run():t.toggleList(this.name,this.options.itemTypeName,this.options.keepMarks)}},addKeyboardShortcuts(){return{"Mod-Shift-7":()=>this.editor.commands.toggleOrderedList()}},addInputRules(){let t=Dl({find:$T,type:this.type,getAttributes:e=>({start:+e[1]}),joinPredicate:(e,a)=>a.childCount+a.attrs.start===+e[1]});return(this.options.keepMarks||this.options.keepAttributes)&&(t=Dl({find:$T,type:this.type,keepMarks:this.options.keepMarks,keepAttributes:this.options.keepAttributes,getAttributes:e=>({start:+e[1],...this.editor.getAttributes(UT)}),joinPredicate:(e,a)=>a.childCount+a.attrs.start===+e[1],editor:this.editor})),[t]}}),Pue=/^\s*(\[([( |x])?\])\s$/,Rue=Oa.create({name:"taskItem",addOptions(){return{nested:!1,HTMLAttributes:{},taskListTypeName:"taskList",a11y:void 0}},content(){return this.options.nested?"paragraph block*":"paragraph+"},defining:!0,addAttributes(){return{checked:{default:!1,keepOnSplit:!1,parseHTML:t=>{const e=t.getAttribute("data-checked");return e===""||e==="true"},renderHTML:t=>({"data-checked":t.checked})}}},parseHTML(){return[{tag:`li[data-type="${this.name}"]`,priority:51}]},renderHTML({node:t,HTMLAttributes:e}){return["li",ct(this.options.HTMLAttributes,e,{"data-type":this.name}),["label",["input",{type:"checkbox",checked:t.attrs.checked?"checked":null}],["span"]],["div",0]]},parseMarkdown:(t,e)=>{const a=[];if(t.tokens&&t.tokens.length>0?a.push(e.createNode("paragraph",{},e.parseInline(t.tokens))):t.text?a.push(e.createNode("paragraph",{},[e.createNode("text",{text:t.text})])):a.push(e.createNode("paragraph",{},[])),t.nestedTokens&&t.nestedTokens.length>0){const n=e.parseChildren(t.nestedTokens);a.push(...n)}return e.createNode("taskItem",{checked:t.checked||!1},a)},renderMarkdown:(t,e)=>{var a;const i=`- [${(a=t.attrs)!=null&&a.checked?"x":" "}] `;return kS(t,e,i)},addKeyboardShortcuts(){const t={Enter:()=>this.editor.commands.splitListItem(this.name),"Shift-Tab":()=>this.editor.commands.liftListItem(this.name)};return this.options.nested?{...t,Tab:()=>this.editor.commands.sinkListItem(this.name)}:t},addNodeView(){return({node:t,HTMLAttributes:e,getPos:a,editor:n})=>{const i=document.createElement("li"),r=document.createElement("label"),o=document.createElement("span"),l=document.createElement("input"),c=document.createElement("div"),d=p=>{var m,h;l.ariaLabel=((h=(m=this.options.a11y)==null?void 0:m.checkboxLabel)==null?void 0:h.call(m,p,l.checked))||`Task item checkbox for ${p.textContent||"empty task item"}`};d(t),r.contentEditable="false",l.type="checkbox",l.addEventListener("mousedown",p=>p.preventDefault()),l.addEventListener("change",p=>{if(!n.isEditable&&!this.options.onReadOnlyChecked){l.checked=!l.checked;return}const{checked:m}=p.target;n.isEditable&&typeof a=="function"&&n.chain().focus(void 0,{scrollIntoView:!1}).command(({tr:h})=>{const g=a();if(typeof g!="number")return!1;const y=h.doc.nodeAt(g);return h.setNodeMarkup(g,void 0,{...y==null?void 0:y.attrs,checked:m}),!0}).run(),!n.isEditable&&this.options.onReadOnlyChecked&&(this.options.onReadOnlyChecked(t,m)||(l.checked=!l.checked))}),Object.entries(this.options.HTMLAttributes).forEach(([p,m])=>{i.setAttribute(p,m)}),i.dataset.checked=t.attrs.checked,l.checked=t.attrs.checked,r.append(l,o),i.append(r,c),Object.entries(e).forEach(([p,m])=>{i.setAttribute(p,m)});let u=new Set(Object.keys(e));return{dom:i,contentDOM:c,update:p=>{if(p.type!==this.type)return!1;i.dataset.checked=p.attrs.checked,l.checked=p.attrs.checked,d(p);const m=n.extensionManager.attributes,h=xu(p,m),g=new Set(Object.keys(h)),y=this.options.HTMLAttributes;return u.forEach(x=>{g.has(x)||(x in y?i.setAttribute(x,y[x]):i.removeAttribute(x))}),Object.entries(h).forEach(([x,v])=>{v==null?x in y?i.setAttribute(x,y[x]):i.removeAttribute(x):i.setAttribute(x,v)}),u=g,!0}}}},addInputRules(){return[Dl({find:Pue,type:this.type,getAttributes:t=>({checked:t[t.length-1]==="x"})})]}}),Lue=Oa.create({name:"taskList",addOptions(){return{itemTypeName:"taskItem",HTMLAttributes:{}}},group:"block list",content(){return`${this.options.itemTypeName}+`},parseHTML(){return[{tag:`ul[data-type="${this.name}"]`,priority:51}]},renderHTML({HTMLAttributes:t}){return["ul",ct(this.options.HTMLAttributes,t,{"data-type":this.name}),0]},parseMarkdown:(t,e)=>e.createNode("taskList",{},e.parseChildren(t.items||[])),renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,` 17779`):"",markdownTokenizer:{name:"taskList",level:"block",start(t){var e;const a=(e=t.match(/^\s*[-+*]\s+\[([ xX])\]\s+/))==null?void 0:e.index;return a!==void 0?a:-1},tokenize(t,e,a){const n=r=>{const o=Hb(r,{itemPattern:/^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,extractItemData:l=>({indentLevel:l[1].length,mainContent:l[4],checked:l[3].toLowerCase()==="x"}),createToken:(l,c)=>({type:"taskItem",raw:"",mainContent:l.mainContent,indentLevel:l.indentLevel,checked:l.checked,text:l.mainContent,tokens:a.inlineTokens(l.mainContent),nestedTokens:c}),customNestedParser:n},a);return o?[{type:"taskList",raw:o.raw,items:o.items}]:a.blockTokens(r)},i=Hb(t,{itemPattern:/^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,extractItemData:r=>({indentLevel:r[1].length,mainContent:r[4],checked:r[3].toLowerCase()==="x"}),createToken:(r,o)=>({type:"taskItem",raw:"",mainContent:r.mainContent,indentLevel:r.indentLevel,checked:r.checked,text:r.mainContent,tokens:a.inlineTokens(r.mainContent),nestedTokens:o}),customNestedParser:n},a);if(i)return{type:"taskList",raw:i.raw,items:i.items}}},markdownOptions:{indentsContent:!0},addCommands(){return{toggleTaskList:()=>({commands:t})=>t.toggleList(this.name,this.options.itemTypeName)}},addKeyboardShortcuts(){return{"Mod-Shift-9":()=>this.editor.commands.toggleTaskList()}}});ze.create({name:"listKit",addExtensions(){const t=[];return this.options.bulletList!==!1&&t.push(sD.configure(this.options.bulletList)),this.options.listItem!==!1&&t.push(lD.configure(this.options.listItem)),this.options.listKeymap!==!1&&t.push(hD.configure(this.options.listKeymap)),this.options.orderedList!==!1&&t.push(gD.configure(this.options.orderedList)),this.options.taskItem!==!1&&t.push(Rue.configure(this.options.taskItem)),this.options.taskList!==!1&&t.push(Lue.configure(this.options.taskList)),t}});var Oue=Oa.create({name:"paragraph",priority:1e3,addOptions(){return{HTMLAttributes:{}}},group:"block",content:"inline*",parseHTML(){return[{tag:"p"}]},renderHTML({HTMLAttributes:t}){return["p",ct(this.options.HTMLAttributes,t),0]},parseMarkdown:(t,e)=>{const a=t.tokens||[];return a.length===1&&a[0].type==="image"?e.parseChildren([a[0]]):e.createNode("paragraph",void 0,e.parseInline(a))},renderMarkdown:(t,e)=>!t||!Array.isArray(t.content)?"":e.renderChildren(t.content),addCommands(){return{setParagraph:()=>({commands:t})=>t.setNode(this.name)}},addKeyboardShortcuts(){return{"Mod-Alt-0":()=>this.editor.commands.setParagraph()}}}),Mue=/(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/,Due=/(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g,que=ao.create({name:"strike",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"s"},{tag:"del"},{tag:"strike"},{style:"text-decoration",consuming:!1,getAttrs:t=>t.includes("line-through")?{}:!1}]},renderHTML({HTMLAttributes:t}){return["s",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"del",parseMarkdown:(t,e)=>
vendor: 5,396 bytes, line 17779
17779e.applyMark("strike",e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>`~~${e.renderChildren(t)}~~`,addCommands(){return{setStrike:()=>({commands:t})=>t.setMark(this.name),toggleStrike:()=>({commands:t})=>t.toggleMark(this.name),unsetStrike:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-Shift-s":()=>this.editor.commands.toggleStrike()}},addInputRules(){return[Ml({find:Mue,type:this.type})]},addPasteRules(){return[ss({find:Due,type:this.type})]}}),zue=Oa.create({name:"text",group:"inline",parseMarkdown:t=>({type:"text",text:t.text||""}),renderMarkdown:t=>t.text||""}),Vue=ao.create({name:"underline",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"u"},{style:"text-decoration",consuming:!1,getAttrs:t=>t.includes("underline")?{}:!1}]},renderHTML({HTMLAttributes:t}){return["u",ct(this.options.HTMLAttributes,t),0]},parseMarkdown(t,e){return e.applyMark(this.name||"underline",e.parseInline(t.tokens||[]))},renderMarkdown(t,e){return`++${e.renderChildren(t)}++`},markdownTokenizer:{name:"underline",level:"inline",start(t){return t.indexOf("++")},tokenize(t,e,a){const i=/^(\+\+)([\s\S]+?)(\+\+)/.exec(t);if(!i)return;const r=i[2].trim();return{type:"underline",raw:i[0],text:r,tokens:a.inlineTokens(r)}}},addCommands(){return{setUnderline:()=>({commands:t})=>t.setMark(this.name),toggleUnderline:()=>({commands:t})=>t.toggleMark(this.name),unsetUnderline:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-u":()=>this.editor.commands.toggleUnderline(),"Mod-U":()=>this.editor.commands.toggleUnderline()}}});function Hue(t={}){return new at({view(e){return new Fue(e,t)}})}class Fue{constructor(e,a){var n;this.editorView=e,this.cursorPos=null,this.element=null,this.timeout=-1,this.width=(n=a.width)!==null&&n!==void 0?n:1,this.color=a.color===!1?void 0:a.color||"black",this.class=a.class,this.handlers=["dragover","dragend","drop","dragleave"].map(i=>{let r=o=>{this[i](o)};return e.dom.addEventListener(i,r),{name:i,handler:r}})}destroy(){this.handlers.forEach(({name:e,handler:a})=>this.editorView.dom.removeEventListener(e,a))}update(e,a){this.cursorPos!=null&&a.doc!=e.state.doc&&(this.cursorPos>e.state.doc.content.size?this.setCursor(null):this.updateOverlay())}setCursor(e){e!=this.cursorPos&&(this.cursorPos=e,e==null?(this.element.parentNode.removeChild(this.element),this.element=null):this.updateOverlay())}updateOverlay(){let e=this.editorView.state.doc.resolve(this.cursorPos),a=!e.parent.inlineContent,n,i=this.editorView.dom,r=i.getBoundingClientRect(),o=r.width/i.offsetWidth,l=r.height/i.offsetHeight;if(a){let p=e.nodeBefore,m=e.nodeAfter;if(p||m){let h=this.editorView.nodeDOM(this.cursorPos-(p?p.nodeSize:0));if(h){let g=h.getBoundingClientRect(),y=p?g.bottom:g.top;p&&m&&(y=(y+this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top)/2);let x=this.width/2*l;n={left:g.left,right:g.right,top:y-x,bottom:y+x}}}}if(!n){let p=this.editorView.coordsAtPos(this.cursorPos),m=this.width/2*o;n={left:p.left-m,right:p.left+m,top:p.top,bottom:p.bottom}}let c=this.editorView.dom.offsetParent;this.element||(this.element=c.appendChild(document.createElement("div")),this.class&&(this.element.className=this.class),this.element.style.cssText="position: absolute; z-index: 50; pointer-events: none;",this.color&&(this.element.style.backgroundColor=this.color)),this.element.classList.toggle("prosemirror-dropcursor-block",a),this.element.classList.toggle("prosemirror-dropcursor-inline",!a);let d,u;if(!c||c==document.body&&getComputedStyle(c).position=="static")d=-pageXOffset,u=-pageYOffset;else{let p=c.getBoundingClientRect(),m=p.width/c.offsetWidth,h=p.height/c.offsetHeight;d=p.left-c.scrollLeft*m,u=p.top-c.scrollTop*h}this.element.style.left=(n.left-d)/o+"px",this.element.style.top=(n.top-u)/l+"px",this.element.style.width=(n.right-n.left)/o+"px",this.element.style.height=(n.bottom-n.top)/l+"px"}scheduleRemoval(e){clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.setCursor(null),e)}dragover(e){if(!this.editorView.editable)return;let a=this.editorView.posAtCoords({left:e.clientX,top:e.clientY}),n=a&&a.inside>=0&&this.editorView.state.doc.nodeAt(a.inside),i=n&&n.type.spec.disableDropCursor,r=typeof i=="function"?i(this.editorView,a,e):i;if(a&&!r){let o=a.pos;if(this.editorView.dragging&&this.editorView.dragging.slice){let l=pM(this.editorView.state.doc,o,this.editorView.dragging.slice);l!=null&&(o=l)}this.setCursor(o),this.scheduleRemoval(5e3)}}dragend(){this.scheduleRemoval(20)}drop(){this.scheduleRemoval(20)}dragleave(e){this.editorView.dom.contains(e.relatedTarget)||this.setCursor(null)}}class st extends xe{constructor(e){super(e,e)}map(e,a){let n=e.resolve(a.map(this.head));return st.valid(n)?new st(n):xe.near(n)}content(){return K.empty}eq(e){return e instanceof st&&e.head==this.head}toJSON(){return{type:"gapcursor",pos:this.head}}static fromJSON(e,a){if(typeof a.pos!="number")throw new RangeError("Invalid input for GapCursor.fromJSON");return new st(e.resolve(a.pos))}getBookmark(){return new RS(this.anchor)}static valid(e){let a=e.parent;if(a.isTextblock||!Bue(e)||!Uue(e))return!1;let n=a.type.spec.allowGapCursor;if(n!=null)return n;let i=a.contentMatchAt(e.index()).defaultType;return i&&i.isTextblock}static findGapCursorFrom(e,a,n=!1){e:for(;;){if(!n&&st.valid(e))return e;let i=e.pos,r=null;for(let o=e.depth;;o--){let l=e.node(o);if(a>
vendor: 5,640 bytes, line 17779
177790?e.indexAfter(o)<l.childCount:e.index(o)>0){r=l.child(a>0?e.indexAfter(o):e.index(o)-1);break}else if(o==0)return null;i+=a;let c=e.doc.resolve(i);if(st.valid(c))return c}for(;;){let o=a>0?r.firstChild:r.lastChild;if(!o){if(r.isAtom&&!r.isText&&!se.isSelectable(r)){e=e.doc.resolve(i+r.nodeSize*a),n=!1;continue e}break}r=o,i+=a;let l=e.doc.resolve(i);if(st.valid(l))return l}return null}}}st.prototype.visible=!1;st.findFrom=st.findGapCursorFrom;xe.jsonID("gapcursor",st);class RS{constructor(e){this.pos=e}map(e){return new RS(e.map(this.pos))}resolve(e){let a=e.resolve(this.pos);return st.valid(a)?new st(a):xe.near(a)}}function yD(t){return t.isAtom||t.spec.isolating||t.spec.createGapCursor}function Bue(t){for(let e=t.depth;e>=0;e--){let a=t.index(e),n=t.node(e);if(a==0){if(n.type.spec.isolating)return!0;continue}for(let i=n.child(a-1);;i=i.lastChild){if(i.childCount==0&&!i.inlineContent||yD(i.type))return!0;if(i.inlineContent)return!1}}return!0}function Uue(t){for(let e=t.depth;e>=0;e--){let a=t.indexAfter(e),n=t.node(e);if(a==n.childCount){if(n.type.spec.isolating)return!0;continue}for(let i=n.child(a);;i=i.firstChild){if(i.childCount==0&&!i.inlineContent||yD(i.type))return!0;if(i.inlineContent)return!1}}return!0}function $ue(){return new at({props:{decorations:Jue,createSelectionBetween(t,e,a){return e.pos==a.pos&&st.valid(a)?new st(a):null},handleClick:Gue,handleKeyDown:Wue,handleDOMEvents:{beforeinput:Kue}}})}const Wue=m5({ArrowLeft:lm("horiz",-1),ArrowRight:lm("horiz",1),ArrowUp:lm("vert",-1),ArrowDown:lm("vert",1)});function lm(t,e){const a=t=="vert"?e>0?"down":"up":e>0?"right":"left";return function(n,i,r){let o=n.selection,l=e>0?o.$to:o.$from,c=o.empty;if(o instanceof ce){if(!r.endOfTextblock(a)||l.depth==0)return!1;c=!1,l=n.doc.resolve(e>0?l.after():l.before())}let d=st.findGapCursorFrom(l,e,c);return d?(i&&i(n.tr.setSelection(new st(d))),!0):!1}}function Gue(t,e,a){if(!t||!t.editable)return!1;let n=t.state.doc.resolve(e);if(!st.valid(n))return!1;let i=t.posAtCoords({left:a.clientX,top:a.clientY});return i&&i.inside>-1&&se.isSelectable(t.state.doc.nodeAt(i.inside))?!1:(t.dispatch(t.state.tr.setSelection(new st(n))),!0)}function Kue(t,e){if(e.inputType!="insertCompositionText"||!(t.state.selection instanceof st))return!1;let{$from:a}=t.state.selection,n=a.parent.contentMatchAt(a.index()).findWrapping(t.state.schema.nodes.text);if(!n)return!1;let i=V.empty;for(let o=n.length-1;o>=0;o--)i=V.from(n[o].createAndFill(null,i));let r=t.state.tr.replace(a.pos,a.pos,new K(i,0,0));return r.setSelection(ce.near(r.doc.resolve(a.pos+1))),t.dispatch(r),!1}function Jue(t){if(!(t.selection instanceof st))return null;let e=document.createElement("div");return e.className="ProseMirror-gapcursor",Qe.create(t.doc,[ha.widget(t.selection.head,e,{key:"gapcursor"})])}var Df=200,Rt=function(){};Rt.prototype.append=function(e){return e.length?(e=Rt.from(e),!this.length&&e||e.length<Df&&this.leafAppend(e)||this.length<Df&&e.leafPrepend(this)||this.appendInner(e)):this};Rt.prototype.prepend=function(e){return e.length?Rt.from(e).append(this):this};Rt.prototype.appendInner=function(e){return new Que(this,e)};Rt.prototype.slice=function(e,a){return e===void 0&&(e=0),a===void 0&&(a=this.length),e>=a?Rt.empty:this.sliceInner(Math.max(0,e),Math.min(this.length,a))};Rt.prototype.get=function(e){if(!(e<0||e>=this.length))return this.getInner(e)};Rt.prototype.forEach=function(e,a,n){a===void 0&&(a=0),n===void 0&&(n=this.length),a<=n?this.forEachInner(e,a,n,0):this.forEachInvertedInner(e,a,n,0)};Rt.prototype.map=function(e,a,n){a===void 0&&(a=0),n===void 0&&(n=this.length);var i=[];return this.forEach(function(r,o){return i.push(e(r,o))},a,n),i};Rt.from=function(e){return e instanceof Rt?e:e&&e.length?new xD(e):Rt.empty};var xD=function(t){function e(n){t.call(this),this.values=n}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var a={length:{configurable:!0},depth:{configurable:!0}};return e.prototype.flatten=function(){return this.values},e.prototype.sliceInner=function(i,r){return i==0&&r==this.length?this:new e(this.values.slice(i,r))},e.prototype.getInner=function(i){return this.values[i]},e.prototype.forEachInner=function(i,r,o,l){for(var c=r;c<o;c++)if(i(this.values[c],l+c)===!1)return!1},e.prototype.forEachInvertedInner=function(i,r,o,l){for(var c=r-1;c>=o;c--)if(i(this.values[c],l+c)===!1)return!1},e.prototype.leafAppend=function(i){if(this.length+i.length<=Df)return new e(this.values.concat(i.flatten()))},e.prototype.leafPrepend=function(i){if(this.length+i.length<=Df)return new e(i.flatten().concat(this.values))},a.length.get=function(){return this.values.length},a.depth.get=function(){return 0},Object.defineProperties(e.prototype,a),e}(Rt);Rt.empty=new xD([]);var Que=function(t){function e(a,n){t.call(this),this.left=a,this.right=n,this.length=a.length+n.length,this.depth=Math.max(a.depth,n.depth)+1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.flatten=function(){return this.left.flatten().concat(this.right.flatten())},e.prototype.getInner=function(n){return n<this.left.length?this.left.get(n):this.right.get(n-this.left.length)},e.prototype.forEachInner=function(n,i,r,o){var l=this.left.length;if(i<l&&this.left.forEachInner(n,i,Math.min(r,l),o)===!1||r>l&&this.right.forEachInner(n,Math.max(i-l,0),Math.min(this.length,r)-l,o+l)===!1)return!1},e.prototype.forEachInvertedInner=function(n,i,r,o){var l=this.left.length;if(i>l&&this.right.forEachInvertedInner(n,i-l,Math.max(r,l)-l,o+l)===!1||r<l&&this.left.forEachInvertedInner(n,Math.min(i,l),r,o)===!1)return!1}
vendor: 4,834 bytes, line 17779
17779,e.prototype.sliceInner=function(n,i){if(n==0&&i==this.length)return this;var r=this.left.length;return i<=r?this.left.slice(n,i):n>=r?this.right.slice(n-r,i-r):this.left.slice(n,r).append(this.right.slice(0,i-r))},e.prototype.leafAppend=function(n){var i=this.right.leafAppend(n);if(i)return new e(this.left,i)},e.prototype.leafPrepend=function(n){var i=this.left.leafPrepend(n);if(i)return new e(i,this.right)},e.prototype.appendInner=function(n){return this.left.depth>=Math.max(this.right.depth,n.depth)+1?new e(this.left,new e(this.right,n)):new e(this,n)},e}(Rt);const Xue=500;class An{constructor(e,a){this.items=e,this.eventCount=a}popEvent(e,a){if(this.eventCount==0)return null;let n=this.items.length;for(;;n--)if(this.items.get(n-1).selection){--n;break}let i,r;a&&(i=this.remapping(n,this.items.length),r=i.maps.length);let o=e.tr,l,c,d=[],u=[];return this.items.forEach((p,m)=>{if(!p.step){i||(i=this.remapping(n,m+1),r=i.maps.length),r--,u.push(p);return}if(i){u.push(new $n(p.map));let h=p.step.map(i.slice(r)),g;h&&o.maybeStep(h).doc&&(g=o.mapping.maps[o.mapping.maps.length-1],d.push(new $n(g,void 0,void 0,d.length+u.length))),r--,g&&i.appendMap(g,r)}else o.maybeStep(p.step);if(p.selection)return l=i?p.selection.map(i.slice(r)):p.selection,c=new An(this.items.slice(0,n).append(u.reverse().concat(d)),this.eventCount-1),!1},this.items.length,0),{remaining:c,transform:o,selection:l}}addTransform(e,a,n,i){let r=[],o=this.eventCount,l=this.items,c=!i&&l.length?l.get(l.length-1):null;for(let u=0;u<e.steps.length;u++){let p=e.steps[u].invert(e.docs[u]),m=new $n(e.mapping.maps[u],p,a),h;(h=c&&c.merge(m))&&(m=h,u?r.pop():l=l.slice(0,l.length-1)),r.push(m),a&&(o++,a=void 0),i||(c=m)}let d=o-n.depth;return d>Zue&&(l=Yue(l,d),o-=d),new An(l.append(r),o)}remapping(e,a){let n=new pu;return this.items.forEach((i,r)=>{let o=i.mirrorOffset!=null&&r-i.mirrorOffset>=e?n.maps.length-i.mirrorOffset:void 0;n.appendMap(i.map,o)},e,a),n}addMaps(e){return this.eventCount==0?this:new An(this.items.append(e.map(a=>new $n(a))),this.eventCount)}rebased(e,a){if(!this.eventCount)return this;let n=[],i=Math.max(0,this.items.length-a),r=e.mapping,o=e.steps.length,l=this.eventCount;this.items.forEach(m=>{m.selection&&l--},i);let c=a;this.items.forEach(m=>{let h=r.getMirror(--c);if(h==null)return;o=Math.min(o,h);let g=r.maps[h];if(m.step){let y=e.steps[h].invert(e.docs[h]),x=m.selection&&m.selection.map(r.slice(c+1,h));x&&l++,n.push(new $n(g,y,x))}else n.push(new $n(g))},i);let d=[];for(let m=a;m<o;m++)d.push(new $n(r.maps[m]));let u=this.items.slice(0,i).append(d).append(n),p=new An(u,l);return p.emptyItemCount()>Xue&&(p=p.compress(this.items.length-n.length)),p}emptyItemCount(){let e=0;return this.items.forEach(a=>{a.step||e++}),e}compress(e=this.items.length){let a=this.remapping(0,e),n=a.maps.length,i=[],r=0;return this.items.forEach((o,l)=>{if(l>=e)i.push(o),o.selection&&r++;else if(o.step){let c=o.step.map(a.slice(n)),d=c&&c.getMap();if(n--,d&&a.appendMap(d,n),c){let u=o.selection&&o.selection.map(a.slice(n));u&&r++;let p=new $n(d.invert(),c,u),m,h=i.length-1;(m=i.length&&i[h].merge(p))?i[h]=m:i.push(p)}}else o.map&&n--},this.items.length,0),new An(Rt.from(i.reverse()),r)}}An.empty=new An(Rt.empty,0);function Yue(t,e){let a;return t.forEach((n,i)=>{if(n.selection&&e--==0)return a=i,!1}),t.slice(a)}class $n{constructor(e,a,n,i){this.map=e,this.step=a,this.selection=n,this.mirrorOffset=i}merge(e){if(this.step&&e.step&&!e.selection){let a=e.step.merge(this.step);if(a)return new $n(a.getMap().invert(),a,this.selection)}}}class rr{constructor(e,a,n,i,r){this.done=e,this.undone=a,this.prevRanges=n,this.prevTime=i,this.prevComposition=r}}const Zue=20;function epe(t,e,a,n){let i=a.getMeta(Fo),r;if(i)return i.historyState;a.getMeta(npe)&&(t=new rr(t.done,t.undone,null,0,-1));let o=a.getMeta("appendedTransaction");if(a.steps.length==0)return t;if(o&&o.getMeta(Fo))return o.getMeta(Fo).redo?new rr(t.done.addTransform(a,void 0,n,Gm(e)),t.undone,WT(a.mapping.maps),t.prevTime,t.prevComposition):new rr(t.done,t.undone.addTransform(a,void 0,n,Gm(e)),null,t.prevTime,t.prevComposition);if(a.getMeta("addToHistory")!==!1&&!(o&&o.getMeta("addToHistory")===!1)){let l=a.getMeta("composition"),c=t.prevTime==0||!o&&t.prevComposition!=l&&(t.prevTime<(a.time||0)-n.newGroupDelay||!tpe(a,t.prevRanges)),d=o?fx(t.prevRanges,a.mapping):WT(a.mapping.maps);return new rr(t.done.addTransform(a,c?e.selection.getBookmark():void 0,n,Gm(e)),An.empty,d,a.time,l??t.prevComposition)}else return(r=a.getMeta("rebased"))?new rr(t.done.rebased(a,r),t.undone.rebased(a,r),fx(t.prevRanges,a.mapping),t.prevTime,t.prevComposition):new rr(t.done.addMaps(a.mapping.maps),t.undone.addMaps(a.mapping.maps),fx(t.prevRanges,a.mapping),t.prevTime,t.prevComposition)}function tpe(t,e){if(!e)return!1;if(!t.docChanged)return!0;let a=!1;
vendor: 9,331 bytes, line 17779
17779return t.mapping.maps[0].forEach((n,i)=>{for(let r=0;r<e.length;r+=2)n<=e[r+1]&&i>=e[r]&&(a=!0)}),a}function WT(t){let e=[];for(let a=t.length-1;a>=0&&e.length==0;a--)t[a].forEach((n,i,r,o)=>e.push(r,o));return e}function fx(t,e){if(!t)return null;let a=[];for(let n=0;n<t.length;n+=2){let i=e.map(t[n],1),r=e.map(t[n+1],-1);i<=r&&a.push(i,r)}return a}function ape(t,e,a){let n=Gm(e),i=Fo.get(e).spec.config,r=(a?t.undone:t.done).popEvent(e,n);if(!r)return null;let o=r.selection.resolve(r.transform.doc),l=(a?t.done:t.undone).addTransform(r.transform,e.selection.getBookmark(),i,n),c=new rr(a?l:r.remaining,a?r.remaining:l,null,0,-1);return r.transform.setSelection(o).setMeta(Fo,{redo:a,historyState:c})}let gx=!1,GT=null;function Gm(t){let e=t.plugins;if(GT!=e){gx=!1,GT=e;for(let a=0;a<e.length;a++)if(e[a].spec.historyPreserveItems){gx=!0;break}}return gx}const Fo=new _t("history"),npe=new _t("closeHistory");function ipe(t={}){return t={depth:t.depth||100,newGroupDelay:t.newGroupDelay||500},new at({key:Fo,state:{init(){return new rr(An.empty,An.empty,null,0,-1)},apply(e,a,n){return epe(a,n,e,t)}},config:t,props:{handleDOMEvents:{beforeinput(e,a){let n=a.inputType,i=n=="historyUndo"?bD:n=="historyRedo"?wD:null;return!i||!e.editable?!1:(a.preventDefault(),i(e.state,e.dispatch))}}}})}function vD(t,e){return(a,n)=>{let i=Fo.getState(a);if(!i||(t?i.undone:i.done).eventCount==0)return!1;if(n){let r=ape(i,a,t);r&&n(e?r.scrollIntoView():r)}return!0}}const bD=vD(!1,!0),wD=vD(!0,!0);ze.create({name:"characterCount",addOptions(){return{limit:null,mode:"textSize",textCounter:t=>t.length,wordCounter:t=>t.split(" ").filter(e=>e!=="").length}},addStorage(){return{characters:()=>0,words:()=>0}},onBeforeCreate(){this.storage.characters=t=>{const e=(t==null?void 0:t.node)||this.editor.state.doc;if(((t==null?void 0:t.mode)||this.options.mode)==="textSize"){const n=e.textBetween(0,e.content.size,void 0," ");return this.options.textCounter(n)}return e.nodeSize},this.storage.words=t=>{const e=(t==null?void 0:t.node)||this.editor.state.doc,a=e.textBetween(0,e.content.size," "," ");return this.options.wordCounter(a)}},addProseMirrorPlugins(){let t=!1;return[new at({key:new _t("characterCount"),appendTransaction:(e,a,n)=>{if(t)return;const i=this.options.limit;if(i==null||i===0){t=!0;return}const r=this.storage.characters({node:n.doc});if(r>i){const o=r-i,l=0,c=o;console.warn(`[CharacterCount] Initial content exceeded limit of ${i} characters. Content was automatically trimmed.`);const d=n.tr.deleteRange(l,c);return t=!0,d}t=!0},filterTransaction:(e,a)=>{const n=this.options.limit;if(!e.docChanged||n===0||n===null||n===void 0)return!0;const i=this.storage.characters({node:a.doc}),r=this.storage.characters({node:e.doc});if(r<=n||i>n&&r>n&&r<=i)return!0;if(i>n&&r>n&&r>i||!e.getMeta("paste"))return!1;const l=e.selection.$head.pos,c=r-n,d=l-c,u=l;return e.deleteRange(d,u),!(this.storage.characters({node:e.doc})>n)}})]}});var rpe=ze.create({name:"dropCursor",addOptions(){return{color:"currentColor",width:1,class:void 0}},addProseMirrorPlugins(){return[Hue(this.options)]}});ze.create({name:"focus",addOptions(){return{className:"has-focus",mode:"all"}},addProseMirrorPlugins(){return[new at({key:new _t("focus"),props:{decorations:({doc:t,selection:e})=>{const{isEditable:a,isFocused:n}=this.editor,{anchor:i}=e,r=[];if(!a||!n)return Qe.create(t,[]);let o=0;this.options.mode==="deepest"&&t.descendants((c,d)=>{if(c.isText)return;if(!(i>=d&&i<=d+c.nodeSize-1))return!1;o+=1});let l=0;return t.descendants((c,d)=>{if(c.isText||!(i>=d&&i<=d+c.nodeSize-1))return!1;if(l+=1,this.options.mode==="deepest"&&o-l>0||this.options.mode==="shallowest"&&l>1)return this.options.mode==="deepest";r.push(ha.node(d,d+c.nodeSize,{class:this.options.className}))}),Qe.create(t,r)}}})]}});var ope=ze.create({name:"gapCursor",addProseMirrorPlugins(){return[$ue()]},extendNodeSchema(t){var e;const a={name:t.name,options:t.options,storage:t.storage};return{allowGapCursor:(e=Pe(te(t,"allowGapCursor",a)))!=null?e:null}}});ze.create({name:"placeholder",addOptions(){return{emptyEditorClass:"is-editor-empty",emptyNodeClass:"is-empty",placeholder:"Write something â¦",showOnlyWhenEditable:!0,showOnlyCurrent:!0,includeChildren:!1}},addProseMirrorPlugins(){return[new at({key:new _t("placeholder"),props:{decorations:({doc:t,selection:e})=>{const a=this.editor.isEditable||!this.options.showOnlyWhenEditable,{anchor:n}=e,i=[];if(!a)return null;const r=this.editor.isEmpty;return t.descendants((o,l)=>{const c=n>=l&&n<=l+o.nodeSize,d=!o.isLeaf&&Kg(o);if((c||!this.options.showOnlyCurrent)&&d){const u=[this.options.emptyNodeClass];r&&u.push(this.options.emptyEditorClass);const p=ha.node(l,l+o.nodeSize,{class:u.join(" "),"data-placeholder":typeof this.options.placeholder=="function"?this.options.placeholder({editor:this.editor,node:o,pos:l,hasAnchor:c}):this.options.placeholder});i.push(p)}return this.options.includeChildren}),Qe.create(t,i)}}})]}});ze.create({name:"selection",addOptions(){return{className:"selection"}},addProseMirrorPlugins(){const{editor:t,options:e}=this;return[new at({key:new _t("selection"),props:{decorations(a){return a.selection.empty||t.isFocused||!t.isEditable||T5(a.selection)||t.view.dragging?null:Qe.create(a.doc,[ha.inline(a.selection.from,a.selection.to,{class:e.className})])}}})]}});function KT({types:t,node:e}){return e&&Array.isArray(t)&&t.includes(e.type)||(e==null?void 0:e.type)===t}var spe=ze.create({name:"trailingNode",addOptions(){return{node:void 0,notAfter:[]}},addProseMirrorPlugins(){var t;const e=new _t(this.name),a=this.options.node||((t=this.editor.schema.topNodeType.contentMatch.defaultType)==null?void 0:t.name)||"paragraph",n=Object.entries(this.editor.schema.nodes).map(([,i])=>i).filter(i=>(this.options.notAfter||[]).concat(a).includes(i.name));return[new at({key:e,appendTransaction:(i,r,o)=>{const{doc:l,tr:c,schema:d}=o,u=e.getState(o),p=l.content.size,m=d.nodes[a];if(u)return c.insert(p,m.create())},state:{init:(i,r)=>{const o=r.tr.doc.lastChild;return!KT({node:o,types:n})},apply:(i,r)=>{if(!i.docChanged||i.getMeta("__uniqueIDTransaction"))return r;const o=i.doc.lastChild;return!KT({node:o,types:n})}}})]}}),lpe=ze.create({name:"undoRedo",addOptions(){return{depth:100,newGroupDelay:500}},addCommands(){return{undo:()=>({state:t,dispatch:e})=>bD(t,e),redo:()=>({state:t,dispatch:e})=>wD(t,e)}},addProseMirrorPlugins(){return[ipe(this.options)]},addKeyboardShortcuts(){return{"Mod-z":()=>this.editor.commands.undo(),"Shift-Mod-z":()=>this.editor.commands.redo(),"Mod-y":()=>this.editor.commands.redo(),"Mod-Ñ":()=>this.editor.commands.undo(),"Shift-Mod-Ñ":()=>this.editor.commands.redo()}}}),cpe=ze.create({name:"starterKit",addExtensions(){var t,e,a,n;const i=[];return this.options.bold!==!1&&i.push(Mde.configure(this.options.bold)),this.options.blockquote!==!1&&i.push(Ide.configure(this.options.blockquote)),this.options.bulletList!==!1&&i.push(sD.configure(this.options.bulletList)),this.options.code!==!1&&i.push(zde.configure(this.options.code)),this.options.codeBlock!==!1&&i.push(Fde.configure(this.options.codeBlock)),this.options.document!==!1&&i.push(Bde.configure(this.options.document)),this.options.dropcursor!==!1&&i.push(rpe.configure(this.options.dropcursor)),this.options.gapcursor!==!1&&i.push(ope.configure(this.options.gapcursor)),this.options.hardBreak!==!1&&i.push(Ude.configure(this.options.hardBreak)),this.options.heading!==!1&&i.push($de.configure(this.options.heading)),this.options.undoRedo!==!1&&i.push(lpe.configure(this.options.undoRedo)),this.options.horizontalRule!==!1&&i.push(Wde.configure(this.options.horizontalRule)),this.options.italic!==!1&&i.push(Xde.configure(this.options.italic)),this.options.listItem!==!1&&i.push(lD.configure(this.options.listItem)),this.options.listKeymap!==!1&&i.push(hD.configure((t=this.options)==null?void 0:t.listKeymap)),this.options.link!==!1&&i.push(kue.configure((e=this.options)==null?void 0:e.link)),this.options.orderedList!==!1&&i.push(gD.configure(this.options.orderedList)),this.options.paragraph!==!1&&i.push(Oue.configure(this.options.paragraph)),this.options.strike!==!1&&i.push(que.configure(this.options.strike)),this.options.text!==!1&&i.push(zue.configure(this.options.text)),this.options.underline!==!1&&i.push(Vue.configure((a=this.options)==null?void 0:a.underline)),this.options.trailingNode!==!1&&i.push(spe.configure((n=this.options)==null?void 0:n.trailingNode)),i}}),dpe=cpe,upe=/(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/,ppe=Oa.create({name:"image",addOptions(){return{inline:!1,allowBase64:!1,HTMLAttributes:{},resize:!1}},inline(){return this.options.inline},group(){return this.options.inline?"inline":"block"},draggable:!0,addAttributes(){return{src:{default:null},alt:{default:null},title:{default:null},width:{default:null},height:{default:null}}},parseHTML(){return[{tag:this.options.allowBase64?"img[src]":'img[src]:not([src^="data:"])'}]},renderHTML({HTMLAttributes:t}){return["img",ct(this.options.HTMLAttributes,t)]},parseMarkdown:(t,e)=>e.createNode("image",{src:t.href,title:t.title,alt:t.text}),renderMarkdown:t=>{var e,a,n,i,r,o;const l=(a=(e=t.attrs)==null?void 0:e.src)!=null?a:"",c=(i=(n=t.attrs)==null?void 0:n.alt)!=null?i:"",d=(o=(r=t.attrs)==null?void 0:r.title)!=null?o:"";return d?``:``}
17779,addNodeView(){if(!this.options.resize||!this.options.resize.enabled||typeof document>"u")return null;const{directions:t,minWidth:e,minHeight:a,alwaysPreserveAspectRatio:n}=this.options.resize;return({node:i,getPos:r,HTMLAttributes:o,editor:l})=>{const c=document.createElement("img");Object.entries(o).forEach(([p,m])=>{if(m!=null)switch(p){case"width":case"height":break;default:c.setAttribute(p,m);break}}),c.src=o.src;const d=new uce({element:c,editor:l,node:i,getPos:r,onResize:(p,m)=>{c.style.width=`${p}px`,c.style.height=`${m}px`},onCommit:(p,m)=>{const h=r();h!==void 0&&this.editor.chain().setNodeSelection(h).updateAttributes(this.name,{width:p,height:m}).run()},onUpdate:(p,m,h)=>p.type===i.type,options:{directions:t,min:{width:e,height:a},preserveAspectRatio:n===!0}}),u=d.dom;return u.style.visibility="hidden",u.style.pointerEvents="none",c.onload=()=>{u.style.visibility="",u.style.pointerEvents=""},d}},addCommands(){return{setImage:t=>({commands:e})=>e.insertContent({type:this.name,attrs:t})}},addInputRules(){return[W5({find:upe,type:this.type,getAttributes:t=>{const[,,e,a,n]=t;return{src:a,alt:e,title:n}}})]}}),mpe=ppe,hpe=20,kD=(t,e=0)=>{const a=[];return!t.children.length||e>hpe||Array.from(t.children).forEach(n=>{n.tagName==="SPAN"?a.push(n):n.children.length&&a.push(...kD(n,e+1))}),a},fpe=t=>{if(!t.children.length)return;const e=kD(t);e&&e.forEach(a=>{var n,i;const r=a.getAttribute("style"),o=(i=(n=a.parentElement)==null?void 0:n.closest("span"))==null?void 0:i.getAttribute("style");a.setAttribute("style",`${o};${r}`)})},SD=ao.create({name:"textStyle",priority:101,addOptions(){return{HTMLAttributes:{},mergeNestedSpanStyles:!0}},parseHTML(){return[{tag:"span",consuming:!1,getAttrs:t=>t.hasAttribute("style")?(this.options.mergeNestedSpanStyles&&fpe(t),{}):!1}]},renderHTML({HTMLAttributes:t}){return["span",ct(this.options.HTMLAttributes,t),0]},addCommands(){return{toggleTextStyle:t=>({commands:e})=>e.toggleMark(this.name,t),removeEmptyTextStyle:()=>({tr:t})=>{const{selection:e}=t;return t.doc.nodesBetween(e.from,e.to,(a,n)=>{if(a.isTextblock)return!0;a.marks.filter(i=>i.type===this.type).some(i=>Object.values(i.attrs).some(r=>!!r))||t.removeMark(n,n+a.nodeSize,this.type)}),!0}}}}),gpe=ze.create({name:"backgroundColor",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{backgroundColor:{default:null,parseHTML:t=>{var e;const a=t.getAttribute("style");if(a){const n=a.split(";").map(i=>i.trim()).filter(Boolean);for(let i=n.length-1;i>=0;i-=1){const r=n[i].split(":");if(r.length>=2){const o=r[0].trim().toLowerCase(),l=r.slice(1).join(":").trim();if(o==="background-color")return l.replace(/['"]+/g,"")}}}return(e=t.style.backgroundColor)==null?void 0:e.replace(/['"]+/g,"")},renderHTML:t=>t.backgroundColor?{style:`background-color: ${t.backgroundColor}`}:{}}}}]},addCommands(){return{setBackgroundColor:t=>({chain:e})=>e().setMark("textStyle",{backgroundColor:t}).run(),unsetBackgroundColor:()=>({chain:t})=>t().setMark("textStyle",{backgroundColor:null}).removeEmptyTextStyle().run()}}}),_D=ze.create({name:"color",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{color:{default:null,parseHTML:t=>{var e;const a=t.getAttribute("style");if(a){const n=a.split(";").map(i=>i.trim()).filter(Boolean);for(let i=n.length-1;i>=0;i-=1){const r=n[i].split(":");if(r.length>=2){const o=r[0].trim().toLowerCase(),l=r.slice(1).join(":").trim();if(o==="color")return l.replace(/['"]+/g,"")}}}return(e=t.style.color)==null?void 0:e.replace(/['"]+/g,"")},renderHTML:t=>t.color?{style:`color: ${t.color}`}:{}}}}]},addCommands(){return{setColor:t=>({chain:e})=>e().setMark("textStyle",{color:t}).run(),unsetColor:()=>({chain:t})=>t().setMark("textStyle",{color:null}).removeEmptyTextStyle().run()}}}),AD=ze.create({name:"fontFamily",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{fontFamily:{default:null,parseHTML:t=>t.style.fontFamily,renderHTML:t=>t.fontFamily?{style:`font-family: ${t.fontFamily}`}:{}}}}]},addCommands(){return{setFontFamily:t=>({chain:e})=>e().setMark("textStyle",{fontFamily:t}).run(),unsetFontFamily:()=>({chain:t})=>t().setMark("textStyle",{fontFamily:null}).removeEmptyTextStyle().run()}}}),ype=ze.create({name:"fontSize",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{fontSize:{default:null,parseHTML:t=>t.style.fontSize,renderHTML:t=>t.fontSize?{style:`font-size: ${t.fontSize}`}:{}}}}]},addCommands(){return{setFontSize:t=>({chain:e})=>e().setMark("textStyle",{fontSize:t}).run(),unsetFontSize:()=>({chain:t})=>t().setMark("textStyle",{fontSize:null}).removeEmptyTextStyle().run()}}}),xpe=ze.create({name:"lineHeight",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{lineHeight:{default:null,parseHTML:t=>t.style.lineHeight,renderHTML:t=>t.lineHeight?{style:`line-height: ${t.lineHeight}`}:{}}}}]},addCommands(){return{setLineHeight:t=>({chain:e})=>e().setMark("textStyle",{lineHeight:t}).run(),unsetLineHeight:()=>({chain:t})=>t().setMark("textStyle",{lineHeight:null}).removeEmptyTextStyle().run()}}});ze.create({name:"textStyleKit",addExtensions(){const t=[];return this.options.backgroundColor!==!1&&t.push(gpe.configure(this.options.backgroundColor)),this.options.color!==!1&&t.push(_D.configure(this.options.color)),this.options.fontFamily!==!1&&t.push(AD.configure(this.options.fontFamily)),this.options.fontSize!==!1&&t.push(ype.configure(this.options.fontSize)),this.options.lineHeight!==!1&&t.push(xpe.configure(this.options.lineHeight)),this.options.textStyle!==!1&&t.push(SD.configure(this.options.textStyle)),t}});var vpe=AD;const bpe=1024*1024,wpe=[{label:"12px",value:"12px"},{label:"14px",value:"14px"},{label:"16px",value:"16px"},{label:"18px",value:"18px"},{label:"20px",value:"20px"},{label:"24px",value:"24px"},{label:"28px",value:"28px"},{label:"32px",value:"32px"}],kpe=[{label:"Sans Serif",value:"system-ui, -apple-system, sans-serif"},{label:"Serif",value:"Georgia, serif"},{label:"Monospace",value:"Courier New, monospace"},{label:"Arial",value:"Arial, sans-serif"}],Spe=[{label:"1.0",value:"1"},{label:"1.2",value:"1.2"},{label:"1.5",value:"1.5"},{label:"1.8",value:"1.8"},{label:"2.0",value:"2"}];function _pe({value:t,onChange:e,onImageSizeError:a}){const[n,i]=k.useState(!1),[r,o]=k.useState(""),[l,c]=k.useState(!1),d=Ede({extensions:[dpe,mpe.configure({allowBase64:!0}),SD,_D,vpe],content:t,onUpdate:({editor:p})=>{e(p.getHTML())}}),u=async()=>{const p=document.createElement("input");p.setAttribute("type","file"),p.setAttribute("accept","image/*"),p.click(),p.onchange=async()=>{const m=p.files[0];if(m){if(m.size>bpe){const h=(m.size/1024/1024).toFixed(2);o(`La imagen es demasiado grande (${h} MB). Máximo permitido: 1 MB`),c(!0),a&&a(`La imagen es demasiado grande (${h} MB). Máximo permitido: 1 MB`);return}try{i(!0);const h=Nk(Gk,`blog-images/${Date.now()}-${m.name}`);await jk(h,m);
17779const g=await Tk(h);d&&d.chain().focus().setImage({src:g}).run()}catch(h){console.error("Error al subir imagen:",h),alert("Error al subir la imagen")}finally{i(!1)}}}};return d?s.jsxs("div",{className:"relative",children:[s.jsxs("div",{className:"fixed right-6 top-32 z-50 w-16 bg-slate-800/95 backdrop-blur-md rounded-lg border border-slate-600 shadow-2xl p-2 space-y-2 max-h-[calc(100vh-200px)] overflow-y-auto",children:[s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleBold().run(),disabled:!d.can().chain().focus().toggleBold().run(),className:`w-full p-2 rounded text-sm font-bold ${d.isActive("bold")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Negrita",children:"B"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleItalic().run(),disabled:!d.can().chain().focus().toggleItalic().run(),className:`w-full p-2 rounded text-sm italic ${d.isActive("italic")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Cursiva",children:"I"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleStrike().run(),disabled:!d.can().chain().focus().toggleStrike().run(),className:`w-full p-2 rounded text-sm line-through ${d.isActive("strike")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Tachado",children:"S"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleHeading({level:2}).run(),className:`w-full p-2 rounded text-xs font-bold ${d.isActive("heading",{level:2})?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"TÃtulo H2",children:"H2"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleHeading({level:3}).run(),className:`w-full p-2 rounded text-xs font-bold ${d.isActive("heading",{level:3})?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"TÃtulo H3",children:"H3"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleBulletList().run(),className:`w-full p-2 rounded text-sm ${d.isActive("bulletList")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Lista con viñetas",children:"â¢"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleOrderedList().run(),className:`w-full p-2 rounded text-sm ${d.isActive("orderedList")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Lista numerada",children:"1."})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleBlockquote().run(),className:`w-full p-2 rounded text-sm ${d.isActive("blockquote")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Cita",children:'"'}),s.jsx("button",{onClick:()=>d.chain().focus().toggleCodeBlock().run(),className:`w-full p-2 rounded text-xs font-mono ${d.isActive("codeBlock")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Bloque de código",children:"<>"}),s.jsx("button",{onClick:u,disabled:n,className:"w-full p-2 bg-slate-700 text-gray-200 rounded hover:bg-slate-600 text-sm disabled:opacity-50",title:"Insertar imagen",children:n?"â³":"ð¼ï¸"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("label",{htmlFor:"text-color-picker-float",className:"w-full p-2 bg-slate-700 text-gray-200 rounded hover:bg-slate-600 text-xl cursor-pointer flex items-center justify-center",title:"Seleccionar color de texto",children:"ð¨"}),s.jsx("input",{id:"text-color-picker-float",type:"color",onChange:p=>{d.chain().focus().setColor(p.target.value).run()},value:d.getAttributes("textStyle").color||"#e5e7eb",className:"w-full h-8 rounded cursor-pointer border border-slate-500",title:"Elegir color personalizado"}),s.jsx("button",{onClick:()=>d.chain().focus().unsetColor().run(),className:"w-full p-2 bg-slate-700 text-gray-200 rounded hover:bg-slate-600 text-sm",title:"Quitar color",children:"â"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsx("button",{onClick:()=>d.chain().focus().clearNodes().run(),className:"w-full p-2 bg-red-500/20 text-red-400 rounded hover:bg-red-500/30 text-xs",title:"Limpiar formato",children:"ðï¸"})]}),s.jsx("div",{className:"space-y-2 p-2 bg-slate-700 rounded-t-lg border border-slate-600 mb-0",children:s.jsxs("div",{className:"flex flex-wrap gap-2",children:[s.jsxs("select",{onChange:p=>{p.target.value&&d.chain().focus().setMark("textStyle",{fontSize:p.target.value}).run()},className:"px-2 py-1 rounded text-sm bg-slate-600 text-gray-200 hover:bg-slate-500 border border-slate-500",children:[s.jsx("option",{value:"",children:"Tamaño"}),wpe.map(p=>s.jsx("option",{value:p.value,children:p.label},p.value))]}),s.jsxs("select",{onChange:p=>{p.target.value&&d.chain().focus().setFontFamily(p.target.value).run()},className:"px-2 py-1 rounded text-sm bg-slate-600 text-gray-200 hover:bg-slate-500 border border-slate-500",children:[s.jsx("option",{value:"",children:"Fuente"}),kpe.map(p=>s.jsx("option",{value:p.value,children:p.label},p.value))]}),s.jsxs("select",{onChange:p=>{p.target.value&&d.chain().focus().setMark("textStyle",{lineHeight:p.target.value}).run()},className:"px-2 py-1 rounded text-sm bg-slate-600 text-gray-200 hover:bg-slate-500 border border-slate-500",children:[s.jsx("option",{value:"",children:"Espaciado"}),Spe.map(p=>s.jsxs("option",{value:p.value,children:["LÃnea ",p.label]},p.value))]})]})}),s.jsxs("div",{className:"relative mt-0 pr-20",children:[s.jsx(vde,{editor:d,className:"bg-slate-800 border border-slate-600 rounded-b-lg p-4 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",style:{minHeight:"400px"}}),n&&s.jsx(_.div,{initial:{opacity:0}
17779,animate:{opacity:1},className:"absolute inset-0 bg-black/50 rounded-b-lg flex items-center justify-center z-50",children:s.jsxs("div",{className:"text-white text-center",children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-white border-t-transparent rounded-full mx-auto mb-2"}),s.jsx("p",{children:"Subiendo imagen..."})]})})]}),l&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:s.jsxs(_.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},className:"bg-slate-800 border border-red-500/50 rounded-lg p-6 max-w-sm mx-4",children:[s.jsx("h3",{className:"text-lg font-bold text-red-400 mb-2",children:"â ï¸ Imagen demasiado grande"}),s.jsx("p",{className:"text-gray-300 mb-6",children:r}),s.jsx("button",{onClick:()=>c(!1),className:"w-full px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"Entendido"})]})}),s.jsx("style",{children:` 17780 .ProseMirror { 17781 outline: none; 17782 color: #e5e7eb; 17783 line-height: 1.8; 17784 } 17785 17786 .ProseMirror p { 17787 margin: 1.25rem 0; 17788 color: #e5e7eb; 17789 line-height: 1.8; 17790 } 17791 17792 .ProseMirror h2 { 17793 font-size: 1.5rem; 17794 font-weight: bold; 17795 margin: 1.5rem 0 1rem 0; 17796 color: #e5e7eb; 17797 line-height: 1.6; 17798 } 17799 17800 .ProseMirror h3 { 17801 font-size: 1.25rem; 17802 font-weight: bold; 17803 margin: 1.25rem 0 0.75rem 0; 17804 color: #e5e7eb; 17805 line-height: 1.6; 17806 } 17807 17808 .ProseMirror ul, 17809 .ProseMirror ol { 17810 margin: 1rem 0; 17811 padding-left: 2rem; 17812 color: #e5e7eb; 17813 line-height: 1.8; 17814 } 17815 17816 .ProseMirror li { 17817 margin: 0.5rem 0; 17818 line-height: 1.8; 17819 } 17820 17821 .ProseMirror blockquote { 17822 border-left: 4px solid #06b6d4; 17823 padding-left: 1rem; 17824 margin: 1.25rem 0; 17825 color: #9ca3af; 17826 font-style: italic; 17827 line-height: 1.8; 17828 } 17829 17830 .ProseMirror code { 17831 background-color: #1f2937; 17832 padding: 0.2rem 0.4rem; 17833 border-radius: 0.25rem; 17834 font-family: monospace; 17835 color: #fbbf24; 17836 } 17837 17838 .ProseMirror pre { 17839 background-color: #111827; 17840 color: #e5e7eb; 17841 padding: 1rem; 17842 border-radius: 0.5rem; 17843 overflow-x: auto; 17844 margin: 1.25rem 0; 17845 border: 1px solid #374151; 17846 line-height: 1.6; 17847 } 17848 17849 .ProseMirror pre code { 17850 background-color: transparent; 17851 padding: 0; 17852 color: inherit; 17853 } 17854 17855 .ProseMirror img { 17856 max-width: 100%; 17857 height: auto; 17858 margin: 1.5rem 0; 17859 border-radius: 0.5rem; 17860 } 17861 `})]}):s.jsx("div",{children:"Cargando editor..."})}const Ape=1024*1024;function ED({initialData:t=null,initialBlog:e=null,isEditing:a=!1,onSave:n=null}){const{user:i}=hs(),r=e||t,[o,l]=k.useState({title:(r==null?void 0:r.title)||"",excerpt:(r==null?void 0:r.excerpt)||"",content:(r==null?void 0:r.content)||"",headerImage:(r==null?void 0:r.headerImage)||null,tags:(r==null?void 0:r.tags)||[],published:(r==null?void 0:r.published)||!1,language:(r==null?void 0:r.language)||"es"}),[c,d]=k.useState((r==null?void 0:r.slug)||""),[u,p]=k.useState(null),[m,h]=k.useState((r==null?void 0:r.headerImage)||null),[g,y]=k.useState([]),[x,v]=k.useState(""),[w,S]=k.useState(!1),[T,P]=k.useState(""),[M,C]=k.useState(""),[E,j]=k.useState(""),[N,L]=k.useState(!1),[O,R]=k.useState(!1),[G,ee]=k.useState("");k.useEffect(()=>{(async()=>{try{const ge=ga(St,"tags"),We=(await Ni(ge)).docs.map(si=>({id:si.id,...si.data()}));y(We)}catch(ge){console.error("Error cargando etiquetas:",ge)}})()},[]);const ke=ne=>{const{name:ge,value:Me}=ne.target;l(We=>({...We,[ge]:Me}))},ae=ne=>ne.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-"),F=ne=>{const ge=ne.target.files[0];if(ge){if(ge.size>Ape){j(`La imagen es demasiado grande (${(ge.size/1024/1024).toFixed(2)} MB). Máximo permitido: 1 MB`),L(!0);return}p(ge);const Me=new FileReader;Me.onloadend=()=>{h(Me.result)}
17861,Me.readAsDataURL(ge)}},Z=()=>{p(null),h(null),l(ne=>({...ne,headerImage:null}))},re=async()=>{if(x.trim())try{const ne=ae(x);if(g.find(Vn=>Vn.slug===ne)){P("Esta etiqueta ya existe");return}const Me=ga(St,"tags"),si={id:(await Tl(Me,{name:x,slug:ne,description:"",color:"#06b6d4"})).id,name:x,slug:ne,description:"",color:"#06b6d4"};y(Vn=>[...Vn,si]),l(Vn=>({...Vn,tags:[...Vn.tags,x]})),v(""),P("")}catch(ne){P("Error al crear la etiqueta"),console.error(ne)}},fe=(ne,ge)=>{l(Me=>({...Me,tags:Me.tags.includes(ge)?Me.tags.filter(We=>We!==ge):[...Me.tags,ge]}))},ve=()=>o.title.trim()?o.excerpt.trim()?o.content.trim()?!m&&!t?(P("La imagen de encabezado es requerida"),!1):o.tags.length===0?(P("Debes seleccionar al menos una etiqueta"),!1):!0:(P("El contenido es requerido"),!1):(P("El resumen es requerido"),!1):(P("El tÃtulo es requerido"),!1),Ie=async()=>{if(ve())try{S(!0),P(""),C("");let ne=o.headerImage;if(u)try{const We=Nk(Gk,`blog-headers/${Date.now()}-${u.name}`),si=await jk(We,u);ne=await Tk(si.ref)}catch(We){console.error("Error al subir imagen:",We),P("Error al subir la imagen. Intenta de nuevo."),S(!1);return}const ge=c.trim()?ae(c):ae(o.title),Me={title:o.title,slug:ge,excerpt:o.excerpt,content:o.content,headerImage:ne,tags:o.tags,author:i.email,published:o.published,language:o.language,views:(r==null?void 0:r.views)||0,featured:(r==null?void 0:r.featured)||!1,updatedAt:new Date};if(r&&r.id){const We=lu(St,"blogs",r.id);await h3(We,Me),C("Blog actualizado exitosamente")}else{Me.createdAt=new Date;const We=ga(St,"blogs"),si=await Tl(We,Me),Vn=`/blog/${ge}`;ee(Vn),R(!0),l({title:"",excerpt:"",content:"",headerImage:null,tags:[],published:!1,language:"es"}),p(null),h(null)}n&&n(),setTimeout(()=>C(""),3e3)}catch(ne){P("Error al guardar el blog: "+ne.message),console.error(ne)}finally{S(!1)}};return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6},className:"space-y-6",children:[T&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"p-4 bg-red-500/10 border border-red-500/50 rounded-lg text-red-400",children:T}),M&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"p-4 bg-green-500/10 border border-green-500/50 rounded-lg text-green-400",children:M}),N&&s.jsx(_.div,{initial:{opacity:0}
17861,animate:{opacity:1},className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:s.jsxs(_.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},className:"bg-slate-800 border border-red-500/50 rounded-lg p-6 max-w-sm mx-4",children:[s.jsx("h3",{className:"text-lg font-bold text-red-400 mb-2",children:"â ï¸ Imagen demasiado grande"}),s.jsx("p",{className:"text-gray-300 mb-6",children:E}),s.jsx("button",{onClick:()=>L(!1),className:"w-full px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"Entendido"})]})}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:"Imagen de Encabezado"}),m?s.jsxs("div",{className:"relative",children:[s.jsx("img",{src:m,alt:"Preview",className:"w-full h-64 object-cover rounded-lg"}),s.jsx("button",{onClick:Z,className:"absolute top-2 right-2 px-3 py-1 bg-red-500 text-white rounded-lg hover:bg-red-600 transition",children:"Remover"})]}):s.jsxs("label",{className:"block border-2 border-dashed border-slate-600 rounded-lg p-8 text-center cursor-pointer hover:border-primary transition",children:[s.jsx("input",{type:"file",accept:"image/*",onChange:F,className:"hidden"}),s.jsxs("div",{className:"text-gray-400",children:[s.jsx("p",{className:"text-lg mb-2",children:"ð¸ Arrastra una imagen aquà o haz clic"}),s.jsx("p",{className:"text-sm",children:"PNG, JPG, GIF (máx. 5MB)"})]})]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-2",children:"TÃtulo del Blog"}),s.jsx("input",{type:"text",name:"title",value:o.title,onChange:ke,placeholder:"Escribe el tÃtulo de tu blog",className:"w-full px-4 py-3 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition"}),s.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[s.jsx("span",{className:"text-xs text-gray-500",children:"Slug:"}),s.jsx("input",{type:"text",value:c||ae(o.title)||"",onChange:ne=>d(ne.target.value.toLowerCase().replace(/[^a-z0-9\s-]/g,"").replace(/\s+/g,"-")),placeholder:ae(o.title)||"tu-titulo-aqui",className:"flex-1 px-2 py-1 text-xs bg-slate-700/30 border border-slate-600/50 rounded text-cyan-400 placeholder-gray-600 focus:outline-none focus:border-primary transition"}),c&&s.jsx("button",{type:"button",onClick:()=>d(""),className:"text-xs text-gray-500 hover:text-gray-300 transition",title:"Usar slug automático del tÃtulo",children:"â Reset"})]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-2",children:"Resumen (Excerpt)"}),s.jsx("textarea",{name:"excerpt",value:o.excerpt,onChange:ke,placeholder:"Escribe un resumen corto de tu blog",rows:"3",className:"w-full px-4 py-3 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition resize-none"}),s.jsxs("p",{className:"text-xs text-gray-500 mt-2",children:[o.excerpt.length,"/160 caracteres"]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-4",children:"Contenido del Blog"}),s.jsx(_pe,{value:o.content,onChange:ne=>l(ge=>({...ge,content:ne}))})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:"Etiquetas"}),s.jsxs("div",{className:"mb-6",children:[s.jsx("p",{className:"text-sm text-gray-400 mb-3",children:"Selecciona etiquetas:"}),s.jsx("div",{className:"flex flex-wrap gap-2",children:g.map(ne=>s.jsx("button",{onClick:()=>fe(ne.id,ne.name),className:`px-4 py-2 rounded-full text-sm font-medium transition ${o.tags.includes(ne.name)?"bg-primary text-white":"bg-slate-700 text-gray-300 hover:bg-slate-600"}`,children:ne.name},ne.id))})]}),s.jsxs("div",{className:"flex gap-2",children:[s.jsx("input",{type:"text",value:x,onChange:ne=>v(ne.target.value),placeholder:"Nombre de nueva etiqueta",className:"flex-1 px-4 py-2 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary transition",onKeyPress:ne=>ne.key==="Enter"&&re()}),s.jsx("button",{onClick:re,className:"px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"+ Agregar"})]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-3",children:"Idioma del Blog"}),s.jsxs("div",{className:"flex gap-4",children:[s.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[s.jsx("input",{type:"radio",name:"language",value:"es",checked:o.language==="es",onChange:ne=>l(ge=>({...ge,language:ne.target.value})),className:"w-4 h-4"}),s.jsx("span",{className:"text-gray-300",children:"ðªð¸ Español"})]}),s.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[s.jsx("input",{type:"radio",name:"language",value:"en",checked:o.language==="en",onChange:ne=>l(ge=>({...ge,language:ne.target.value})),className:"w-4 h-4"}),s.jsx("span",{className:"text-gray-300",children:"ð¬ð§ English"})]})]}),s.jsxs("p",{className:"text-xs text-gray-500 mt-2",children:["Este blog será visible solo cuando el sitio esté en ",o.language==="es"?"español":"inglés"]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsxs("label",{className:"flex items-center gap-3 cursor-pointer",children:[s.jsx("input",{type:"checkbox",checked:o.published,onChange:ne=>l(ge=>({...ge,published:ne.target.checked})),className:"w-5 h-5 rounded"}),s.jsx("span",{className:"text-white font-medium",children:"Publicar blog inmediatamente"})]}),s.jsx("p",{className:"text-xs text-gray-500 mt-2",children:o.published?"â
Este blog será visible públicamente":"ⳠEste blog será guardado como borrador"})]}),s.jsx("div",{className:"flex gap-4",children:s.jsx("button",{onClick:Ie,disabled:w,className:"flex-1 px-6 py-3 bg-gradient-to-r from-cyan-500 to-blue-600 text-white rounded-lg font-semibold hover:shadow-lg hover:shadow-cyan-500/50 transition disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2",children:w?s.jsxs(s.Fragment,{children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-4 h-4 border-2 border-white border-t-transparent roun
17861ded-full"}),"Guardando..."]}):s.jsx(s.Fragment,{children:"ð¾ Guardar Blog"})})}),O&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",onClick:()=>R(!1),children:s.jsxs(_.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},className:"bg-slate-800 border border-green-500/50 rounded-lg p-8 max-w-md mx-4 relative",onClick:ne=>ne.stopPropagation(),children:[s.jsx("button",{onClick:()=>R(!1),className:"absolute top-4 right-4 text-gray-400 hover:text-white transition-colors text-2xl leading-none","aria-label":"Cerrar",children:"Ã"}),s.jsxs("div",{className:"text-center",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring"},className:"text-5xl mb-4",children:"â
"}),s.jsx("h3",{className:"text-2xl font-bold text-green-400 mb-2",children:"¡Blog creado exitosamente!"}),s.jsx("p",{className:"text-gray-300 mb-6",children:"Tu artÃculo ha sido publicado y está disponible en:"}),s.jsxs("div",{className:"bg-slate-700/50 border border-slate-600 rounded-lg p-4 mb-6",children:[s.jsx("p",{className:"text-sm text-gray-400 mb-2",children:"URL del blog:"}),s.jsx("p",{className:"text-primary font-mono text-sm break-all",children:G})]}),s.jsxs("div",{className:"flex gap-3",children:[s.jsx("button",{onClick:()=>{R(!1)},className:"flex-1 px-4 py-2 bg-slate-700 text-gray-300 rounded-lg hover:bg-slate-600 transition font-medium",children:"Crear otro"}),s.jsx("a",{href:G,target:"_blank",rel:"noopener noreferrer",className:"flex-1 px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium text-center",children:"Ver blog"})]})]})]})})]})}function Epe(){return s.jsx(Do,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Crear Blog"}),s.jsx("p",{className:"text-gray-400",children:"Escribe un nuevo artÃculo para tu blog"})]}),s.jsx(ED,{isEditing:!1})]})})}function Cpe(){const[t,e]=k.useState([]),[a,n]=k.useState(!0),[i,r]=k.useState(""),[o,l]=k.useState(""),[c,d]=k.useState("all"),u=Qa(),{user:p}=hs();k.useEffect(()=>{(async()=>{try{n(!0);const x=ga(St,"blogs"),v=jl(x,Gn("author","==",p.email)),S=(await Ni(v)).docs.map(T=>({id:T.id,...T.data()}));e(S.sort((T,P)=>{var M,C;return((M=P.createdAt)==null?void 0:M.toDate())-((C=T.createdAt)==null?void 0:C.toDate())}))}catch(x){r("Error al cargar blogs: "+x.message),console.error(x)}finally{n(!1)}})()},[p.email]);const m=t.filter(y=>{const x=y.title.toLowerCase().includes(o.toLowerCase()),v=c==="all"||c==="published"&&y.published||c==="draft"&&!y.published;return x&&v}),h=async y=>{if(window.confirm("¿Estás seguro de que deseas eliminar este blog?"))try{await _J(lu(St,"blogs",y)),e(t.filter(x=>x.id!==y))}catch(x){r("Error al eliminar blog: "+x.message)}},g=async(y,x)=>{try{const v=lu(St,"blogs",y);await h3(v,{published:!x}),e(t.map(w=>w.id===y?{...w,published:!x}:w))}catch(v){r("Error al actualizar blog: "+v.message)}};return a?s.jsx(Do,{children:s.jsx("div",{className:"flex items-center justify-center h-96",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})})}):s.jsx(Do,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Editar Blogs"}),s.jsx("p",{className:"text-gray-400",children:"Gestiona tus artÃculos de blog publicados y borradores"})]}),i&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"p-4 bg-red-500/10 border border-red-500/50 rounded-lg text-red-400",children:i}),s.jsx("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6 space-y-4",children:s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsx("input",{type:"text",placeholder:"Buscar blogs...",value:o,onChange:y=>l(y.target.value),className:"px-4 py-2 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary transition"}),s.jsxs("select",{value:c,onChange:y=>
17861d(y.target.value),className:"px-4 py-2 bg-slate-700/50 border border-slate-600 rounded-lg text-white focus:outline-none focus:border-primary transition",children:[s.jsx("option",{value:"all",children:"Todos los blogs"}),s.jsx("option",{value:"published",children:"Publicados"}),s.jsx("option",{value:"draft",children:"Borradores"})]})]})}),m.length===0?s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-12 text-center",children:[s.jsx("p",{className:"text-gray-400 text-lg mb-4",children:"No hay blogs para mostrar"}),s.jsx("button",{onClick:()=>u("/admin-blog/create"),className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"Crear tu primer blog"})]}):s.jsx("div",{className:"space-y-4",children:m.map((y,x)=>{var v,w;return s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:x*.1},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6 hover:border-slate-600 transition",children:s.jsxs("div",{className:"flex gap-6",children:[y.headerImage&&s.jsx("img",{src:y.headerImage,alt:y.title,className:"w-24 h-24 object-cover rounded-lg flex-shrink-0"}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-start justify-between gap-4 mb-2",children:[s.jsx("h3",{className:"text-lg font-bold text-white truncate",children:y.title}),s.jsx("span",{className:`px-3 py-1 rounded-full text-xs font-medium whitespace-nowrap ${y.published?"bg-green-500/20 text-green-400":"bg-yellow-500/20 text-yellow-400"}`,children:y.published?"â
Publicado":"â³ Borrador"})]}),s.jsx("p",{className:"text-gray-400 text-sm mb-3 line-clamp-2",children:y.excerpt}),s.jsxs("div",{className:"flex flex-wrap gap-2 mb-4",children:[y.tags.slice(0,3).map(S=>s.jsxs("span",{className:"px-2 py-1 bg-slate-700 text-gray-300 text-xs rounded",children:["#",S]},S)),y.tags.length>3&&s.jsxs("span",{className:"px-2 py-1 text-gray-500 text-xs",children:["+",y.tags.length-3," más"]})]}),s.jsxs("p",{className:"text-xs text-gray-500 mb-4",children:["Creado: ",(w=(v=y.createdAt)==null?void 0:v.toDate)==null?void 0:w.call(v).toLocaleDateString("es-ES")," ⢠Vistas: ",y.views||0]}),s.jsxs("div",{className:"flex gap-2 flex-wrap",children:[s.jsx("button",{onClick:()=>u(`/admin-blog/edit/${y.id}`),className:"px-4 py-2 bg-blue-500/20 text-blue-400 hover:bg-blue-500/30 rounded-lg text-sm font-medium transition",children:"âï¸ Editar"}),s.jsx("button",{onClick:()=>g(y.id,y.published),className:`px-4 py-2 rounded-lg text-sm font-medium transition ${y.published?"bg-yellow-500/20 text-yellow-400 hover:bg-yellow-500/30":"bg-green-500/20 text-green-400 hover:bg-green-500/30"}`,children:y.published?"ð Despublicar":"ð Publicar"}),s.jsx("a",{href:`/blog/${y.slug}`,target:"_blank",rel:"noopener noreferrer",className:"px-4 py-2 bg-slate-700 text-gray-300 hover:bg-slate-600 rounded-lg text-sm font-medium transition",children:"ðï¸ Ver"}),s.jsx("button",{onClick:()=>h(y.id),className:"px-4 py-2 bg-red-500/20 text-red-400 hover:bg-red-500/30 rounded-lg text-sm font-medium transition",children:"ðï¸ Eliminar"})]})]})]})},y.id)})}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 text-center",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Total de Blogs"}),s.jsx("p",{className:"text-2xl font-bold text-white mt-2",children:t.length})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 text-center",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Publicados"}),s.jsx("p",{className:"text-2xl font-bold text-green-400 mt-2",children:t.filter(y=>y.published).length})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 text-center",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Borradores"}),s.jsx("p",{className:"text-2xl font-bold text-yellow-400 mt-2",children:t.filter(y=>!y.published).length})]})]})]})})}function jpe(){const{id:t}=jP(),e=Qa(),{user:a}=hs(),[n,i]=k.useState(null),[r,o]=k.useState(!0),[l,c]=k.useState("");return k.useEffect(()=>{(async()=>{try{o(!0);const u=lu(St,"blogs",t),p=await SJ(u);if(!p.exists()){c("Blog no encontrado");return}const m={id:p.id,...p.data()};if(m.author!==a.email){c("No tienes permiso para editar este blog");return}i(m)}catch(u){console.error("Error al cargar blog:",u),c("Error al cargar el blog")}finally{o(!1)}})()}
17861,[t,a.email]),r?s.jsx(Do,{children:s.jsx("div",{className:"flex items-center justify-center h-96",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})})}):l?s.jsx(Do,{children:s.jsxs("div",{className:"text-center py-12",children:[s.jsx("p",{className:"text-red-400 text-lg mb-4",children:l}),s.jsx("button",{onClick:()=>e("/admin-blog/edit"),className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition",children:"Volver a blogs"})]})}):s.jsx(Do,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Editar Blog"}),s.jsx("p",{className:"text-gray-400",children:"Actualiza tu artÃculo de blog"})]}),n&&s.jsx(ED,{initialBlog:n,isEditing:!0})]})})}function CD({blog:t,index:e}){var r,o,l;const{t:a}=$(),n=a("blog",{returnObjects:!0}),i=t.excerpt||((r=t.content)==null?void 0:r.replace(/<[^>]*>/g,"").substring(0,150))+"...";return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:e*.1},className:"bg-slate-800/50 border border-slate-700 rounded-lg overflow-hidden hover:border-primary/50 transition group",children:[t.headerImage&&s.jsx("div",{className:"relative h-48 overflow-hidden",children:s.jsx("img",{src:t.headerImage,alt:t.title,className:"w-full h-full object-cover group-hover:scale-105 transition duration-300"})}),s.jsxs("div",{className:"p-6",children:[s.jsxs("div",{className:"flex items-center justify-between mb-3",children:[s.jsx("span",{className:"text-xs text-primary font-medium",children:(l=(o=t.createdAt)==null?void 0:o.toDate)==null?void 0:l.call(o).toLocaleDateString("es-ES")}),s.jsxs("span",{className:"text-xs text-gray-400",children:[t.views||0," ",n.vistas]})]}),s.jsx("h3",{className:"text-xl font-bold text-white mb-3 line-clamp-2 group-hover:text-primary transition",children:t.title}),s.jsx("p",{className:"text-gray-400 text-sm mb-4 line-clamp-3",children:i}),s.jsx("div",{className:"mb-4",children:s.jsxs("p",{className:"text-xs text-gray-400",children:[s.jsxs("span",{className:"text-gray-500",children:[n.por,": "]}),s.jsx("span",{className:"text-primary font-medium",children:t.author})]})}),s.jsxs(Te,{to:`/blog/${t.slug}`,className:"inline-block px-4 py-2 bg-primary/20 text-primary hover:bg-primary hover:text-white rounded-lg text-sm font-medium transition",children:[n.leerMas," â"]})]})]})}function Tpe({tags:t,selectedTags:e,onTagChange:a}){const{t:n}=$(),i=n("blog",{returnObjects:!0}),r=o=>{e.includes(o)?a(e.filter(l=>l!==o)):a([...e,o])};return s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6 h-fit sticky top-24",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:i.filtrarPorEtiqueta}),t.length===0?s.jsx("p",{className:"text-gray-400 text-sm",children:"No hay etiquetas disponibles"}):s.jsx("div",{className:"space-y-2",children:t.map(o=>s.jsxs("label",{className:"flex items-center gap-3 cursor-pointer group",children:[s.jsx("input",{type:"checkbox",checked:e.includes(o),onChange:()=>r(o),className:"w-4 h-4 rounded border-slate-600 bg-slate-700 text-primary cursor-pointer"}),s.jsxs("span",{className:"text-gray-300 group-hover:text-primary transition text-sm",children:["#",o]}),s.jsxs("span",{className:"text-gray-500 text-xs ml-auto",children:["(",t.filter(l=>l===o).length,")"]})]},o))}),e.length>0&&s.jsx("button",{onClick:()=>a([]),className:"mt-4 w-full px-4 py-2 bg-slate-700 hover:bg-slate-600 text-gray-300 rounded-lg text-sm font-medium transition",children:i.limpiarFiltros})]})}let cm=null;const jD=async()=>{if(cm)return cm;try{const t=ga(St,"tags");return cm=(await Ni(t)).docs.map(a=>({id:a.id,...a.data()})),cm}catch(t){return console.error("Error cargando etiquetas:",t),[]}},Npe=async(t,e=null)=>{if(!t||t.length<20||!/^[a-f0-9]{20,}$/.test(t))return t;const n=(e||await jD()).find(i=>i.id===t);return(n==null?void 0:n.name)||t},Zb=async(t=[])=>{if(!t||t.length===0)return[];const e=await jD();return Promise.all(t.map(a=>Npe(a,e)))};function Ipe(){const{i18n:t}=$(),{t:e}=$(),a=e("blog",{returnObjects:!0}),n=t.language||"es";Mg({title:"Blog - Haka Lab",description:"ArtÃculos sobre testing, calida
17861d de software y automatización de pruebas",keywords:"blog, testing, calidad, automatización, software"});const[i,r]=k.useState([]),[o,l]=k.useState(!0),[c,d]=k.useState(""),[u,p]=k.useState([]),[m,h]=k.useState([]);k.useEffect(()=>{(async()=>{try{l(!0);const x=ga(St,"blogs"),v=jl(x,Gn("published","==",!0),Gn("language","==",n));let S=(await Ni(v)).docs.map(P=>({id:P.id,...P.data()}));S=await Promise.all(S.map(async P=>({...P,tags:await Zb(P.tags)}))),S.sort((P,M)=>{var C,E;return((C=M.createdAt)==null?void 0:C.toDate())-((E=P.createdAt)==null?void 0:E.toDate())}),r(S);const T=new Set;S.forEach(P=>{var M;(M=P.tags)==null||M.forEach(C=>T.add(C))}),h(Array.from(T).sort())}catch(x){console.error("Error al cargar blogs:",x)}finally{l(!1)}})()},[n]);const g=i.filter(y=>{var w;const x=y.title.toLowerCase().includes(c.toLowerCase())||((w=y.excerpt)==null?void 0:w.toLowerCase().includes(c.toLowerCase())),v=u.length===0||u.some(S=>{var T;return(T=y.tags)==null?void 0:T.includes(S)});return x&&v});return s.jsx("div",{children:s.jsxs("main",{children:[s.jsx("section",{className:"bg-gradient-to-b from-slate-900 to-dark py-8 md:py-12",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"text-center",children:[s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:a.titleFront}),s.jsx("p",{className:"text-xl text-gray-400 max-w-2xl mx-auto",children:a.descripcion})]})})}),s.jsx("section",{className:"py-8 md:py-12",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-4 gap-8",children:[s.jsx("div",{className:"lg:col-span-1",children:s.jsx(Tpe,{tags:m,selectedTags:u,onTagChange:p})}),s.jsxs("div",{className:"lg:col-span-3",children:[s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:s.jsx("input",{type:"text",placeholder:a.buscar,value:c,onChange:y=>d(y.target.value),className:"w-full px-6 py-3 bg-slate-800/50 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary transition"})}),o?s.jsx("div",{className:"flex items-center justify-center h-96",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})}):g.length===0?s.jsx(_.div,{initial:{opacity:0}
17861,animate:{opacity:1},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-12 text-center",children:s.jsx("p",{className:"text-gray-400 text-lg",children:i.length===0?"No hay artÃculos publicados aún":"No se encontraron artÃculos con los filtros seleccionados"})}):s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:g.map((y,x)=>s.jsx(CD,{blog:y,index:x},y.id))}),g.length>0&&s.jsxs(_.p,{initial:{opacity:0},animate:{opacity:1},className:"text-center text-gray-400 text-sm mt-8",children:[a.mostrando," ",g.length," ",a.de," ",i.length," ",a.articulos]})]})]})})})]})})}function Ppe(){var m,h,g,y;const{slug:t}=jP(),e=Qa(),{i18n:a}=$(),n=a.language||"es",[i,r]=k.useState(null),[o,l]=k.useState([]),[c,d]=k.useState(!0),[u,p]=k.useState("");return k.useEffect(()=>{(async()=>{try{d(!0);const v=ga(St,"blogs"),w=jl(v,Gn("slug","==",t),Gn("published","==",!0),Gn("language","==",n)),S=await Ni(w);if(S.empty){p("Blog no encontrado");return}let T={id:S.docs[0].id,...S.docs[0].data()};T.tags=await Zb(T.tags),r(T);const P=ga(St,"blogs"),M=jl(P,Gn("published","==",!0),Gn("language","==",n));let E=(await Ni(M)).docs.map(N=>({id:N.id,...N.data()}));E=await Promise.all(E.map(async N=>({...N,tags:await Zb(N.tags)})));const j=E.filter(N=>{var L;return N.id!==T.id&&((L=N.tags)==null?void 0:L.some(O=>{var R;return(R=T.tags)==null?void 0:R.includes(O)}))}).slice(0,3);l(j)}catch(v){console.error("Error al cargar blog:",v),p("Error al cargar el blog")}finally{d(!1)}})()},[t,n]),Mg({title:(i==null?void 0:i.title)||"Blog - Haka Lab",description:(i==null?void 0:i.excerpt)||"ArtÃculo del blog de Haka Lab",keywords:((m=i==null?void 0:i.tags)==null?void 0:m.join(", "))||"blog, testing"}),c?s.jsx("div",{className:"flex items-center justify-center min-h-screen",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})}):u||!i?s.jsx("div",{className:"flex items-center justify-center min-h-screen",children:s.jsxs("div",{className:"text-center",children:[s.jsx("p",{className:"text-gray-400 text-lg mb-4",children:u}),s.jsx("button",{onClick:()=>e("/blog"),className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition",children:"Volver al blog"})]})}):s.jsxs("div",{children:[i.headerImage&&s.jsx(_.div,{initial:{opacity:0}
17861,animate:{opacity:1},className:"flex justify-center py-8",children:s.jsx("img",{src:i.headerImage,alt:i.title,className:"max-w-4xl w-full h-64 object-cover rounded-lg"})}),s.jsx("section",{className:"py-16 md:py-24",children:s.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-6 lg:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[s.jsxs("div",{className:"flex items-center justify-between mb-4",children:[s.jsx("span",{className:"text-sm text-primary font-medium",children:(g=(h=i.createdAt)==null?void 0:h.toDate)==null?void 0:g.call(h).toLocaleDateString("es-ES")}),s.jsxs("span",{className:"text-sm text-gray-400",children:[i.views||0," vistas"]})]}),s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:i.title}),s.jsx("div",{className:"flex flex-wrap gap-2",children:(y=i.tags)==null?void 0:y.map(x=>s.jsxs("span",{className:"px-3 py-1 bg-primary/20 text-primary rounded-full text-sm",children:["#",x]},x))})]}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:"blog-content max-w-none mb-16",dangerouslySetInnerHTML:{__html:i.content},style:{fontSize:"inherit",lineHeight:"inherit",fontFamily:"inherit"}}),s.jsx("style",{children:` 17862 .blog-content { 17863 color: #e5e7eb; 17864 line-height: 1.8; 17865 } 17866 17867 .blog-content p { 17868 margin: 1.25rem 0; 17869 color: #e5e7eb; 17870 line-height: inherit; 17871 } 17872 17873 .blog-content h2 { 17874 font-size: 1.5rem; 17875 font-weight: bold; 17876 margin: 1.5rem 0 1rem 0; 17877 color: #e5e7eb; 17878 line-height: 1.6; 17879 } 17880 17881 .blog-content h3 { 17882 font-size: 1.25rem; 17883 font-weight: bold; 17884 margin: 1.25rem 0 0.75rem 0; 17885 color: #e5e7eb; 17886 line-height: 1.6; 17887 } 17888 17889 .blog-content ul, 17890 .blog-content ol { 17891 margin: 1rem 0; 17892 padding-left: 2rem; 17893 color: #e5e7eb; 17894 line-height: inherit; 17895 } 17896 17897 .blog-content li { 17898 margin: 0.5rem 0; 17899 line-height: inherit; 17900 } 17901 17902 .blog-content blockquote { 17903 border-left: 4px solid #06b6d4; 17904 padding-left: 1rem; 17905 margin: 1.25rem 0; 17906 color: #9ca3af; 17907 font-style: italic; 17908 line-height: inherit; 17909 } 17910 17911 .blog-content code { 17912 background-color: #1f2937; 17913 padding: 0.2rem 0.4rem; 17914 border-radius: 0.25rem; 17915 font-family: monospace; 17916 color: #fbbf24; 17917 } 17918 17919 .blog-content pre { 17920 background-color: #111827; 17921 color: #e5e7eb; 17922 padding: 1rem; 17923 border-radius: 0.5rem; 17924 overflow-x: auto; 17925 margin: 1.25rem 0; 17926 border: 1px solid #374151; 17927 line-height: 1.6; 17928 } 17929 17930 .blog-content pre code { 17931 background-color: transparent; 17932 padding: 0; 17933 color: inherit; 17934 } 17935 17936 .blog-content img { 17937 max-width: 100%; 17938 height: auto; 17939 margin: 1.5rem 0; 17940 border-radius: 0.5rem; 17941 } 17942 17943 .blog-content span[style*="font-size"], 17944 .blog-content span[style*="line-height"], 17945 .blog-content span[style*="font-family"] { 17946 all: revert; 17947 } 17948 `}),s.jsx(_.div,{initial:{opacity:0}
17948,animate:{opacity:1},transition:{delay:.2},className:"border-t border-slate-700 pt-8 mb-16",children:s.jsxs("p",{className:"text-gray-400",children:[s.jsx("span",{className:"font-medium text-white",children:"Autor:"})," ",i.author||"Haka Lab"]})}),o.length>0&&s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-8",children:"ArtÃculos relacionados"}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:o.map((x,v)=>s.jsx(CD,{blog:x,index:v},x.id))})]}),s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.4},className:"mt-16 text-center",children:s.jsx("button",{onClick:()=>e("/blog"),className:"px-6 py-3 bg-primary/20 text-primary hover:bg-primary hover:text-white rounded-lg font-medium transition",children:"â Volver al blog"})})]})})]})}function JT(){const{t}=$(),e=Qa();return k.useEffect(()=>{document.title="404 - Página no encontrada | Haka Lab";const a=document.querySelector('meta[name="description"]');a&&a.setAttribute("content","La página que buscas no existe. Vuelve a Haka Lab para explorar nuestros servicios de testing y automatización.");const n=document.querySelector('meta[name="robots"]');if(n)n.setAttribute("content","noindex, nofollow");else{const i=document.createElement("meta");i.name="robots",i.content="noindex, nofollow",document.head.appendChild(i)}},[]),s.jsxs("div",{className:"min-h-screen bg-dark flex flex-col items-center justify-center relative overflow-hidden",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"relative z-10 text-center px-4",children:[s.jsx("h1",{className:"text-9xl font-bold text-primary opacity-20 select-none",children:"404"}),s.jsx("div",{className:"absolute inset-0 flex items-center justify-center"}),s.jsx("p",{className:"text-xl text-gray-400 mt-8 max-w-lg mx-auto mb-6",children:"Lo sentimos, la página que buscas no existe o ha sido movida. Puede que la URL esté mal escrita o que el contenido ya no esté disponible."}),s.jsx("p",{className:"text-lg text-gray-500 max-w-md mx-auto mb-10",children:"Explora nuestros servicios de testing automatizado, performance y soluciones de calidad de software."}),s.jsxs("div",{className:"flex flex-col sm:flex-row gap-4 justify-center",children:[s.jsx("button",{onClick:()=>e("/"),className:"bg-primary border-2 border-primary text-dark px-8 py-3 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:"Volver al Inicio"}),s.jsx("button",{onClick:()=>e("/servicios"),className:"border-2 border-primary/50 text-primary px-8 py-3 rounded-2xl text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:"Ver Servicios"})]}),s.jsxs("div",{className:"mt-12 text-sm text-gray-500",children:[s.jsx("p",{className:"mb-4",children:"También puedes visitar:"}),s.jsxs("div",{className:"flex flex-wrap justify-center gap-4",children:[s.jsx("button",{onClick:()=>e("/productos"),className:"hover:text-primary transition-colors",children:"Productos"}),s.jsx("span",{children:"â¢"}),s.jsx("button",{onClick:()=>e("/nosotros"),className:"hover:text-primary transition-colors",children:"Nosotros"}),s.jsx("span",{children:"â¢"}),s.jsx("button",{onClick:()=>e("/casosdeexito"),className:"hover:text-primary transition-colors",children:"Casos de Ãxito"}),s.jsx("span",{children:"â¢"}),s.jsx("button",{onClick:()=>e("/blog"),className:"hover:text-primary transition-colors",children:"Blog"})]})]})]}),s.jsx("div",{className:"absolute bottom-0 w-full",children:s.jsx(ie,{variant:1})})]})}function Rpe(){const{pathname:t}=fn();k.useEffect(()=>{window.scrollTo({top:0,left:0,behavior:"auto"})},[t])}function Lpe(){const t=fn();k.useEffect(()=>{LO().then(e=>{if(e){const a=RO();OO(a,"page_view",{page_path:t.pathname,page_title:document.title,page_location:window.location.href})}})},[t.pathname])}function Ope(){return Rpe(),Lpe(),null}function Mpe(){const{isOpen:t,modalTitle:e,closeModal:a}=oa();return s.jsx(Yr,{isOpen:t,onClose:a,title:e})}function Dpe(){return s.jsx(nee,{children:s.jsx(z8,{children:s.jsxs(j8,{children:[s.jsx(Ope,{}),s.jsxs("div",{className:"min-h-screen bg-dark flex flex-col",children:[s.jsx(PH,{}),s.jsx("main",{className:"flex-grow",style:{overflowX:"clip"},children:s.jsxs(n8,{children:[s.jsx(le,{path:"/",element:s.jsx(xee,{})}),s.jsx(le,{path:"/servicios",element:s.jsx(Cee,{})}),s.jsx(le,{path:"/nosotros",element:s.jsx(Pee,{})}),s.jsx(le,{path:"/casosdeexito",element:s.jsx(Yee,{})}),s.jsx(le,{path:"/productos",element:s.jsx(nte,{})}),s.jsx(le,{path:"/hakaboost",element:s.jsx(cte,{})}),s.jsx(le,{path:"/hakabuddy",element:s.jsx(gte,{})}),s.jsx(le,{path:"/hakapath",element:s.jsx(kte,{})}),s.jsx(le,{path:"/hakartc",element:s.jsx(Cte,{})}),s.jsx(le,{path:"/haka-insight",element:s.jsx(Rte,{})}),s.jsx(le,{path:"/haka-engine",element:s.jsx(Dte,{})}),s.jsx(le,{path:"/haka-ai-studio",element:s.jsx($te,{})}),s.jsx(le,{path:"/hakalens",element:s.jsx(eae,{})}),s.jsx(le,{path:"/haka-automation-engine",element:s.jsx(Xae,{})}),s.jsx(le,{path:"/salesforce-testing",element:s.jsx(Uae,{})}),s.jsx(le,{path:"/productos/terms",element:s.jsx(lie,{})}),s.jsx(le,{path:"/politica-privacidad",element:s.jsx(cie,{})}),s.jsx(le,{path:"/docs/haka-playwright-engine",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Une,{})})})}),s.jsx(le,{path:"/docs/haka-playwright-engine/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(rne,{})})})}),s.jsx(le,{path:"/docs/haka-playwright-engine/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(eie,{})})})}),s.jsx(le,{path:"/docs/haka-playwright-engine/videos",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(gne,{})})})}),s.jsx(le,{path:"/docs/haka-ai-studio",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx($ne,{})})})}),s.jsx(le,{path:"/docs/haka-ai-studio/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(xne,{})})})}),s.jsx(le,{path:"/docs/haka-ai-studio/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(tie,{})})})}),s.jsx(le,{path:"/docs/hakaboost",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Wne,{})})})}),s.jsx(le,{path:"/docs/hakaboost/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(_ne,{})})})}),s.jsx(le,{path:"/docs/hakaboost/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(aie,{})})})}),s.jsx(le,{path:"/docs/hakabuddy",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Gne,{})})})}),s.jsx(le,{path:"/docs/hakabuddy/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Nne,{})})})}),s.jsx(le,{path:"/docs/hakabuddy/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(nie,{})})})}),s.jsx(le,{path:"/docs/hakapath",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Kne,{})})})}
17948),s.jsx(le,{path:"/docs/hakapath/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Mne,{})})})}),s.jsx(le,{path:"/docs/hakapath/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(iie,{})})})}),s.jsx(le,{path:"/docs/login",element:s.jsx(At,{children:s.jsx(Hne,{})})}),s.jsx(le,{path:"/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Fne,{})})})}),s.jsx(le,{path:"/framework-hakalab",element:s.jsx(q0,{children:s.jsx(ane,{})})}),s.jsx(le,{path:"/haka-quick-analysis",element:s.jsx(q0,{children:s.jsx(Rae,{})})}),s.jsx(le,{path:"/intest",element:s.jsx(q0,{children:s.jsx(sie,{})})}),s.jsx(le,{path:"/blog",element:s.jsx(Ipe,{})}),s.jsx(le,{path:"/blog/:slug",element:s.jsx(Ppe,{})}),s.jsx(le,{path:"/admin-blog",element:s.jsx(die,{})}),s.jsx(le,{path:"/admin-blog/dashboard",element:s.jsx(Gp,{children:s.jsx(uie,{})})}),s.jsx(le,{path:"/admin-blog/create",element:s.jsx(Gp,{children:s.jsx(Epe,{})})}),s.jsx(le,{path:"/admin-blog/edit",element:s.jsx(Gp,{children:s.jsx(Cpe,{})})}),s.jsx(le,{path:"/admin-blog/edit/:id",element:s.jsx(Gp,{children:s.jsx(jpe,{})})}),s.jsx(le,{path:"/404",element:s.jsx(JT,{})}),s.jsx(le,{path:"*",element:s.jsx(JT,{})})]})}),s.jsx(tee,{}),s.jsx(aee,{}),s.jsx(Mpe,{})]})]})})})}const qpe={tagline:"Soluciones de Testing"},zpe={inicio:"Inicio",servicios:"Servicios",nosotros:"Nosotros",casosDeExito:"Casos de éxito",productos:"Productos",contacto:"Contacto"},Vpe={title:"Contáctanos",subtitle:"Si estás pensando en dar un salto tecnológico, en Haka Lab podemos ayudarte.",nombre:"Nombre",empresa:"Empresa",email:"Correo electrónico",mensaje:"¿En qué podemos ayudarte?",enviar:"Enviar solicitud",nombrePlaceholder:"Ingresa tu nombre",empresaPlaceholder:"Ingresa tu empresa",emailPlaceholder:"Ingresa tu correo",mensajePlaceholder:"Ingresa tu solicitud o comentario",enviando:"Enviando...",exitoEnvio:"â ¡Mensaje enviado con éxito! Te contactaremos pronto.",errorEnvio:"â Error al enviar. Por favor intenta nuevamente."},Hpe={title:"Trabaja con Nosotros",subtitle:"En Haka Lab estamos en la búsqueda de especialistas en calidad de software y automatización, dejanos tu CV!",nombre:"Nombre",nombrePlaceholder:"Ingresa tu nombre",email:"Correo electrónico",emailPlaceholder:"Ingresa tu correo",pais:"PaÃs de residencia",paisPlaceholder:"Ingresa tu paÃs de residencia",telefono:"Teléfono",telefonoPlaceholder:"Ingresa tu teléfono",cv:"Adjuntar CV",cvPlaceholder:"Haz clic para seleccionar tu CV (.pdf, .doc, .docx)",cvFormatos:"Formatos aceptados: PDF, DOC, DOCX. Máximo 2MB.",enviar:"Enviar postulación",enviando:"Enviando...",exitoEnvio:"â ¡Postulación enviada con éxito! Te contactaremos pronto.",errorEnvio:"â Error al enviar. Por favor intenta nuevamente.",archivoInvalido:"Solo se permiten archivos PDF, DOC o DOCX.",archivoGrande:"El archivo no debe superar los 2MB."},Fpe={title:"También te podrÃa interesar",saberMas:"Saber más",impulsadoPorIA:"Impulsado por IA"},Bpe={title:"Descarga Hakaboost Ahora",subtitle:"Para descargar Hakaboost ingresa tus datos",cargo:"Cargo",sistemaOperativo:"Sistema Operativo",aceptaTerminos:"Acepto los términos y condiciones",descargar:"Descargar",descargando:"Descargando...",debesAceptar:"Debes aceptar los términos y condiciones.",exitoDescarga:"â ¡Descarga iniciada! Revisa tu email.",errorDescarga:"â Debes aceptar los términos y condiciones.",nombrePlaceholder:"Tu nombre",cargoPlaceholder:"Tu cargo",empresaPlaceholder:"Tu empresa",sistemaOperativoPlaceholder:"Selecciona tu SO",hero:{descripcion:"El copiloto de calida
17948d para Jira y Azure DevOps. Acelera tus flujos de testing y QA hasta un 70% con IA.",gratis:"Totalmente Gratis"},presentacion:{titulo:"Acelera tus flujos de testing y QA hasta en un 70% con IA"},queHace:{titulo:"¿Qué hace?",descripcion1:"HakaBoost es una extensión para Chrome que se integra como un panel lateral en Jira y Azure DevOps, revolucionando la forma en que los equipos de calidad trabajan. Con solo unos clics, mejora descripciones de tareas, genera escenarios de prueba, crea tests automáticamente y analiza la calidad de tus requerimientos.",descripcion2:"Una de sus caracterÃsticas más potentes es su capacidad para usar múltiples motores de IA, incluyendo la IA local de Chrome. Obtén sugerencias inteligentes para criterios de aceptación y casos de prueba en formato Gherkin, y crea issues en Jira o work items en Azure DevOps de forma automática.",features:["Mejora descripciones transformándolas en historias de usuario completas con criterios de aceptación y escenarios Gherkin","Crea tests automáticamente: parsea escenarios Gherkin y crea issues en Jira o work items en Azure DevOps vinculados a la tarea principal","Integración con Xray: soporte para crear tests de tipo Cucumber y exportar archivos .feature","Análisis Inteligente (Pro): genera reportes de calidad, sugiere datos de prueba y analiza la cobertura de los tests","Exportación Múltiple (Pro): exporta análisis a PDF y publica como comentarios en Jira/Azure"]},caracteristicas:{titulo:"CaracterÃsticas",items:["Complemento Web: se integra de forma nativa en Jira Cloud y Azure DevOps","IA Múltiple: soporte para Chrome Built-in AI (Gemini Nano, 100% local), Google Gemini y OpenAI","Autenticación Segura: sistema de cuentas Free y Pro con inicio de sesión social (Google) y email/contraseña","Modo Oscuro/Claro: interfaz moderna y personalizable","Ofuscación de Datos: protege tu información sensible (URLs, emails, IPs) antes de enviarla a las IAs en la nube","Soporte Bilingüe: disponible en Español e Inglés","Pestañas Pro con Análisis Avanzado: análisis de calidad, sugerencia de datos de prueba y análisis de cobertura"]},beneficios:{titulo:"Beneficios",descripcion:"HakaBoost transforma tu flujo de trabajo de QA con beneficios tangibles desde el primer dÃa.",items:["Aceleración del Ciclo de QA: reduce el tiempo de diseño y creación de pruebas hasta en un 70%","Calidad Mejorada: genera criterios de aceptación claros y una cobertura de pruebas más completa desde el inicio","Flexibilidad de IA: elige entre la privacidad total de la IA local o la potencia de los modelos en la nube","Flujo de Trabajo Integrado: todas las herramientas que necesitas, directamente en Jira y Azure DevOps, sin cambiar de contexto","Consistencia y Estandarización: fomenta el uso de BDD y Gherkin en todo el equipo","Funciones Pro: desbloquea análisis avanzados para llevar tu estrategia de calidad al siguiente nivel","Acceso Pro Gratuito para Clientes: todos los clientes de Haka Lab tienen acceso sin costo a HakaBoost Pro"]},potencia:{titulo:"HakaBoost potencia la calidad de tus tareas",descripcion:"HakaBoost es una extensión para navegadores basados en Chromium (Chrome, Edge) que, gracias a múltiples motores de IA (incluyendo IA local de Chrome), permite mejorar descripciones de tareas en Jira y Azure DevOps, generar escenarios de prueba en Gherkin, crear tests automáticamente y analizar la calidad de tus requerimientos. Todo sin salir de tu herramienta de gestión."}},Upe={title:"Prueba HakaBuddy Ahora",subtitle:"Ingresa tus datos para descargar la versión gratuita",nombre:"Nombre",cargo:"Cargo",sistemaOperativo:"Sistema Operativo",aceptaTerminos:"Acepto los términos y condiciones",descargar:"Descargar Gratis",descargando:"Descargando...",debesAceptar:"Debes aceptar los términos y condiciones.",exitoDescarga:"â ¡Descarga iniciada! Revisa tu email.",errorDescarga:"â Debes aceptar los términos y condiciones.",nombrePlaceholder:"Tu nombre",cargoPlaceholder:"Tu cargo",empresaPlaceholder:"Tu empresa",sistemaOperativoPlaceholder:"Selecciona tu SO",hero:{descripcion:"La herramienta de QA que combina pruebas manuales y automatizadas en un solo lugar.",gratis:"Prueba gratis â Plan Pro disponible"},presentacion:{titulo:"Reduce el tiempo de testing hasta en un 80% con automatización inteligente."}},$pe={titulo:"¡Registro Exitoso!",mensaje:"La descarga iniciará automáticamente, por favor espera.",submensaje:"La descarga puede demorar hasta un minuto dependiendo de tu conexión a internet. Puede que necesites aceptarla en tu navegador.",boton:"Entendido"},Wpe={cargandoTweets:"Cargando tweets...",verEnX:"Ver en X â",videoNoSoportado:"Tu navegador no soporta el elemento de video.",altEquipoHakalab:"HakaLab - Expertos en QA Salesforce y SAP",altHeroImage:"HakaLab - Expertos en QA Salesforce y SAP"},Gpe={empresa:"© 2026 Haka Lab. Todos los derechos reservados.",enlaces:"Enlaces",siguenos:"SÃguenos",privacidad:"Privacidad",terminos:"Términos",contacto:"Contacto",twitter:"Twitter",linkedin:"LinkedIn",github:"GitHub",ereshaka:"¿Eres Haka?",trabajaConNosotros:"Trabaja con Nosotros",codigoConducta:"Código de Conducta",politicaSeguridadSalud:"PolÃtica de Seguridad y Salud"},Kpe={tweets:"Cargando tweets..."},Jpe={descargar:"Descargar",ayuda:"Te ayudará en la automatización de pruebas y las hará hasta un 70% más veloces y con menos fallas.",titulo1:"Descubre nuestro complemento desarrollado para generar XPaths",gratis1:"Totalmente Gratis"},Qpe={descargar:"Descargar",hero:{descripcion:"Captura, organiza y exp
17948orta REST sin salir del navegador",gratis:"Totalmente Gratis"},presentacion:{titulo:"Hasta 95% más veloz capturando tráfico de red, Exporta tus flujos a Postman y CSV en un clic."}},Xpe={titulo:"¡Conoce todos nuestros casos de éxito!",placeholder:"Tu email",boton:"Descargar casos de éxito",mensaje:"El archivo se descargará automáticamente"},Ype={titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre HakaBoost",items:[{question:"¿Qué es HakaBoost y para qué sirve?",answer:"HakaBoost es un copiloto de testing que te ayuda a mejorar las descripciones de tus historias de usuario en Jira y crear casos de prueba automáticamente usando inteligencia artificial."},{question:"¿Necesito pagar por usar HakaBoost?",answer:"No, HakaBoost es completamente gratis. Puedes usarlo sin costo alguno en tu instancia de Jira."},{question:"¿Qué IA debo elegir: OpenAI, Gemini o Chrome?",answer:"Puedes elegir según tus preferencias. OpenAI y Gemini son opciones en la nube, mientras que Chrome te ofrece una IA 100% local basada en Gemini para mayor privacidad."},{question:"¿Funciona sin conexión a internet?",answer:"SÃ, si utilizas la opción de IA local (Chrome built-in), HakaBoost funciona completamente sin conexión a internet."},{question:"¿Necesito configurar algo antes de usar HakaBoost?",answer:"Solo necesitas instalar la extensión en tu navegador y seleccionar qué IA deseas utilizar. El resto es automático."},{question:"¿Cómo obtengo mi token de Jira?",answer:"Puedes generar un token de Jira desde tu perfil en Jira Cloud. Ve a Configuración > Seguridad > Crear y gestionar tokens de API."},{question:"¿HakaBoost guarda mis datos en algún servidor?",answer:"No, tus datos permanecen en tu instancia de Jira. Si usas IA local, todo se procesa localmente sin enviar información a servidores externos."},{question:"¿Puedo usar HakaBoost en cualquier proyecto de Jira?",answer:"SÃ, HakaBoost funciona con cualquier proyecto de Jira Cloud. Solo necesitas tener acceso a ese proyecto."},{question:"¿Qué hace exactamente el botón 'Mejorar Descripción'?",answer:"El botón 'Mejorar Descripción' utiliza IA para analizar tu historia de usuario actual y sugerir mejoras basadas en buenas prácticas de calida
17948d y testing."}]},Zpe={titulo:"¿Qué hace?",descripcion:"HakaBuddy es una aplicación de escritorio para Windows y macOS que permite gestionar pruebas manuales con evidencia visual, automatizar pruebas con Playwright, ejecutar en CI/CD, y generar reportes profesionales enriquecidos con inteligencia artificial.",features:["Crea pruebas manuales con capturas de pantalla, JSON, video y anotaciones como evidencia.","Graba pruebas automatizadas directamente en el navegador sin escribir código.","Ejecuta scripts paso a paso con un debugger visual que permite editar y reintentar en tiempo real.","Genera reportes PDF, HTML y DOCX con layout personalizable y enriquecimiento con IA.","Sube pruebas a GitHub, GitLab o Bitbucket y ejecútalas automáticamente en CI/CD.","Integra con Jira y Xray para trazabilidad completa de tus pruebas."],caracteristicas:"CaracterÃsticas",caracteristicasItems:["Pruebas manuales: capturas de pantalla completa o área, editor de anotaciones, video, adjuntos JSON/PDF.","Pruebas automatizadas con Playwright: grabación, ejecución, debug paso a paso, selectores alternativos.","Pruebas data-driven (Outline): ejecuta el mismo script con múltiples conjuntos de datos.","Suites de regresión: agrupa scripts y ejecútalos en secuencia.","Reportes PDF, HTML y DOCX con maquetador visual drag & drop y enriquecimiento con IA.","Integración con Jira, Xray, GitHub, GitLab y Bitbucket.","Ejecución en CI/CD con generación automática de workflows.","Gestión de sesiones autenticadas con cifrado AES-256.","Optimización de scripts con IA (Gemini): elimina redundancias y mejora legibilidad."],beneficios:"Beneficios",beneficiosDescripcion:"Acelera tu proceso de QA de principio a fin.",beneficiosItems:["Reduce el tiempo de creación de reportes manuales entre un 50% y 70%.","Automatiza pruebas sin escribir código â solo graba y reproduce.","Debugger visual para corregir scripts sin salir de la herramienta.","Un solo push sube tus pruebas a CI/CD con workflow listo para ejecutar.","Reportes profesionales con IA que describen cada paso en lenguaje natural.","Conexión directa con Jira para subir evidencia y crear tests automáticamente.","Funciona offline â toda la información se almacena localmente.","Disponible para Windows y macOS."]},eme={titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre HakaBuddy",items:[{question:"¿Qué es HakaBuddy y para qué sirve?",answer:"HakaBuddy es una aplicación de escritorio para gestión de pruebas de softw
17948are (QA). Permite ejecutar pruebas manuales con captura de evidencia, automatizar pruebas con Playwright, ejecutar en pipelines CI/CD, y generar reportes profesionales en PDF, HTML y DOCX. Está disponible para Windows y macOS."},{question:"¿Cómo creo una prueba manual?",answer:"Completa el formulario con los datos del test (célula, producto, ambiente, URL, tÃtulo, objetivo), presiona 'Iniciar Test' y registra cada paso con su tÃtulo, estado y captura de pantalla. Al finalizar, genera el reporte en el formato que prefieras."},{question:"¿Cómo grabo una prueba automatizada?",answer:"Selecciona 'Automatizada', configura la URL y presiona 'Grabar'. Se abrirá un navegador donde realizas las acciones normalmente. Al cerrar el navegador, el script se genera automáticamente. Luego puedes ejecutarlo, debuggearlo paso a paso, o subirlo a CI/CD."},{question:"¿Qué es el Debug paso a paso?",answer:"Es un modo que abre el navegador y ejecuta tu script acción por acción. En cada paso puedes ver qué elemento se está interactuando (resaltado en amarillo), editar el selector si falla, generar selectores alternativos (XPath, CSS, ID), y reintentar inmediatamente. Los cambios se guardan al script al finalizar."},{question:"¿Qué es HakaPath y cómo se integra?",answer:"HakaPath es una extensión de Chrome que genera localizadores robustos (XPath, CSS, semánticos, relativos). En el modo Debug de HakaBuddy, HakaPath se carga automáticamente en el navegador en versión Pro, listo para usar sin login."},{question:"¿Qué son las pruebas data-driven (Outline)?",answer:"Permiten ejecutar el mismo script con diferentes conjuntos de datos. Por ejemplo, un formulario de registro con 5 usuarios distintos. Defines las variables y los data sets, y HakaBuddy ejecuta una iteración por cada conjunto, reportando resultados individuales."},{question:"¿Puedo personalizar los reportes PDF?",answer:"SÃ. Puedes configurar logos (izquierdo y derecho), banner, color de cabecera, portada y contraportada. Además, el maquetador visual te permite posicionar cada elemento del reporte arrastrándolo en un canvas A4."},{question:"¿Cómo funciona la integración con CI/CD?",answer:"Seleccionas las suites que quieres publicar, presionas 'Publicar' y HakaBuddy sube los scripts al repositorio junto con un workflow configurado (GitHub Actions, GitLab CI o Bitbucket Pipelines). Las pruebas se ejecutan automáticamente en cada push."},{question:"¿Qué opciones tengo para exportar resultados?",answer:"Reporte PDF completo, reporte HTML autocontenido, reporte DOCX (Word), JSON compatible con Xray, imágenes en ZIP, y subida directa a Jira como adjunto."},{question:"¿Puedo conectar con Jira Cloud?",answer:"SÃ. Configuras URL, token y email de Jira. Esto te permite obtener historias de usuario del tablero, vincular tests a tickets, subir reportes como adjuntos y crear tests automáticamente."},{question:"¿Puedo conectar con Xray?",answer:"SÃ. Configuras Client ID y Client Secret de Xray Cloud. Esto permite exportar resultados de ejecución directamente a Xray con mapeo de estados PASS/FAIL por paso."},{question:"¿HakaBuddy almacena los reportes?",answer:"SÃ. Tiene un historial con filtros por fecha y producto donde puedes volver a generar cualquier reporte, descargar capturas, ver videos y acceder a todos los resultados anteriores."},{question:"¿Tiene lÃmite de pruebas o reportes?",answer:"No. Tanto en la versión gratuita como en Pro, no hay lÃmite en la cantidad de pruebas o reportes que puedes crear."},{question:"¿Qué pasa con las sesiones autenticadas?",answer:"HakaBuddy puede capturar y reutilizar sesiones de login (cookies y localStorage). Esto permite grabar y ejecutar pruebas en sitios con autenticación (como Salesforce) sin repetir el login o 2FA cada vez. Las sesiones se cifran con AES-256 antes de subir a repositorios."},{question:"¿La versión gratuita tiene fecha de expiración?",answer:"No. La versión gratuita es permanente y permite crear pruebas manuales sin lÃmite. Las funcionalidades de automatización, integraciones y reportes avanzados requieren el plan Pro."}]}
17948,tme={titulo:"¿Qué hace?",descripcion1:"HakaBoost es un complemento de HakaLab especializado en Jira que permite acelerar la calidad de las descripciones de una tarea y crear fácilmente los test.",descripcion2:"HakaBoost lee automáticamente la issue en pantalla, mejora la descripción con IA (Cloud o Local), detecta y crea escenarios en Gherkin y crea Tests en Jira/Xray vinculados a la historia principal. Todo sin salir de Jira.",features:["Permite descargar el historial de Xpaths generados en hasta 5 diferentes tipos de archivos.","Crea hasta 4 localizadores Xpath de forma automática. Utilizando un algoritmo de creación preciso.","Conserva un historial de hasta 30 Xpaths generados para su posterior consulta o reutilización.","Permite convertir los Xpath a código de selenium en hasta 4 lenguajes de programación.","Por cada Xpath generado identifica automáticamente el número de elementos coincidentes en el DOM."],caracteristicas:"CaracterÃsticas",caracteristicasItems:["Complemento Web. Se integra fácil y nativamente en Google Chrome y Microsoft Edge.","Descargable directamente desde Chrome Store.","Construcción de Xpath utilizando la metodologÃa Haka Lab para creación de localizadores efectivos.","Idiomas: Español e Inglés.","Revisión automática del DOM de html para la identificación de coincidencias."]},ame={titulo:"¿Qué hace?",features:["Permite exportar las solicitudes capturadas a una colección de Postman.","Permite exportar un resumen de las solicitudes a un archivo CSV.","Conserva un historial de las solicitudes capturadas para su posterior consulta o reutilización.","Permite filtrar las solicitudes por URL."],caracteristicas:"CaracterÃsticas",caracteristicasItems:["Captura de tráfico de red hasta un 95% más veloz.","Múltiples opciones de exportación, permite seleccionar entre Postman y CSV.","Organización de solicitudes por pasos con un solo click.","Historial de solicitudes, permite realizar grupos de solicitudes por página y exportar el documento."]},nme={titulo:"Haka RTC",descripcion1:"Diseñada para navegadores basados en Chromium, Haka RTC revoluciona la forma de capturar tráfico REST para tus proyectos de QA. Con pocos clics, registra las solicitudes desde DevTools, las organiza por pasos y permite exportar a Postman o CSV para documentar y reutilizar escenarios con rapidez.",descripcion2:"Además, incorpora filtros dinámicos y lista de exclusión para aislar servicios propios y omitir terceros no autorizados, junto con historial y conteo de repeticiones que aportan precisión y aceleran pruebas (incluidas las de estrés). Gratis y lista para usar en Chrome/Edge."},ime={titulo:"Haka Path es una valiosa extensión",descripcion1:"Diseñado especÃficamente para navegadores web que revoluciona la forma en que generas XPaths para tus proyectos de automatización de pruebas. Con solo dos clics, esta herramienta te permite crear XPaths de manera eficiente y efectiva, acelerando significativamente tu flujo de trabajo.",descripcion2:"Una de las caracterÃsticas destacadas de Haka Path es generar múltiples opciones de XPaths y mostrar cuántos elementos coinciden en tiempo real, brindando mayor precisión, flexibilidad y ahorro de tiempo en la creación de localizadores para tus pruebas automatizadas."},rme={hero:{descripcion:"Extensión para editores basados en VSX (Visual Studio Code, Kiro, Antigravity y más) que revoluciona la automatización de pruebas con Inteligencia Artificial",exclusivo:"Exclusivo de Haka Lab",cta:"Solicitar Acceso",compatibilidad:"Compatible con VS Code · Kiro · Antigravity · Cursor · Windsurf y cualquier editor basado en VSX"},presentacion:{titulo:"Automatización de pruebas con IA, directo en tu editor",subtitulo:"Haka AI Studio se instala como extensión en tu editor favorito basado en VSX. Sin cambiar de herramienta, aplica Inteligencia Artificial de manera estratég
17948ica para reducir los tiempos de creación de pruebas y optimizar los procesos",etapas:{automatizacion:{titulo:"Automatización",descripcion:"Genera scripts robustos de forma automatizada."},seguridad:{titulo:"Seguridad",descripcion:"La información enviada a la IA es mÃnima y ofuscada para alinearnos con las leyes de seguridad y gobernanza de datos."},ia:{titulo:"IA",descripcion:"La IA se encarga de los procesos más costosos de desarrollar pruebas automatizadas."},talento:{titulo:"Talento Humano",descripcion:"Nuestros Ingenieros supervisan lo creado por la IA, ajustan y aseguran la seguridad y funcionamiento."},impacto:{titulo:"Impacto Real",descripcion:"Entre un 70 y 80% de reducción de tiempos en la creación de tests automatizados."}}},potencia:{titulo:"CaracterÃsticas Principales",subtitulo:"Potenciado por Gemini AI para llevar tu automatización al siguiente nivel",grabacion:{titulo:"Grabación Inteligente",descripcion:"Captura tus interacciones en tiempo real con dos modos: Playwright (selectores semánticos modernos) y Selenium (XPath optimizados con validación de unicidad)."},generacion:{titulo:"Generación con IA",descripcion:"Gemini AI analiza tus grabaciones y genera casos de prueba en Gherkin, implementaciones Python completas, Page Objects optimizados y steps personalizados."},busqueda:{titulo:"Búsqueda Vectorial Inteligente",descripcion:"Sistema de embeddings que detecta pasos reutilizables, evita duplicación de código, sugiere mejores prácticas y aprende de tus patrones de testing."},chat:{titulo:"Chat Interactivo con Kai",descripcion:"Asistente de IA integrado que responde preguntas sobre testing, ayuda a refinar casos de prueba, sugiere mejoras y explica el código generado."},analisis:{titulo:"Análisis de Reutilización",descripcion:"Detecta automáticamente secuencias de pasos repetitivas, oportunidades de refactorización, patrones comunes y código duplicado."},velocidad:{titulo:"Velocidad Extrema",descripcion:"Reduce el tiempo de creación de tests en un 70%. Lo que tomaba 2-4 horas ahora toma 15-30 minutos."}},queHace:{titulo:"Beneficios Clave",subtitulo:"Impacto real en tu proceso de automatización",reduccion:"De reducción de tiempo en creación de tests automatizados",beneficios:["Genera código de alta calidad","Reutiliza steps preexistentes","Vectorización progresiva para conocimiento en tiempo real","Utiliza un estándar de alta calidad","Libera al QA Engineer para otras tareas de calidad","Acelera la puesta en marcha del proyecto","Reduce el onboarding técnico",'Gracias a su chat de IA integrado "KAI" soluciona inconvenientes de scripting de forma rápida']},comparativa:{titulo:"Automatización Tradicional vs Haka AI Studio",subtitulo:"Descubre la diferencia que hace la IA en tu flujo de trabajo",aspecto:"Aspecto",sinHaka:"Sin Haka AI Studio",conHaka:"Con Haka AI Studio",tabla:{tiempo:{aspecto:"Tiempo de creación",sin:"1 hora por test",con:"12-18 minutos"},seguridad:{aspecto:"Seguridad",sin:"No hay control sobre lo que se envÃa a la IA",con:"Ofuscación automática y personalizable de URLs, mails, dominios"},selectores:{aspecto:"Selectores",sin:"Manualmente escritos, propensos a errores",con:"Generados y validados automáticamente"},reutilizacion:{aspecto:"Reutilización de código",sin:"Manual, requiere búsqueda y análisis",con:"Automática con búsqueda vectorial"},formato:{aspecto:"Formato de tests",sin:"Código Python directo",con:"Gherkin legible + implementación"},mantenimiento:{aspecto:"Mantenimiento",sin:"Alto - selectores frágiles",con:"Bajo - selectores optimizados"}},destacado:{titulo:"Lo que antes tomaba 1 hora, ahora toma 12-18 minutos",descripcion:"Entre 70% y 80% de reducción en tiempo de creación de tests"}},casosUso:{titulo:"Mentalidad Lean Aplicada a los Procesos de Calidad",subtitulo:"Haka AI Studio se une a las Power Ups de Haka Lab para optimizar procesos y maximizar el ROI",frontEnd:{titulo:"Testing de Front End",descripcion:"Permite construir pruebas para cualquier tipo de aplicación web, no requiere especificaciones sobre cómo ha sido construida."},backend:{titulo:"Testing Backend",descripcion:"Gracias a que está optimizado para trabajar con los Haka Engines de Automatización, es posible integrar fácilmente pruebas o pasos de backend a las pruebas creadas."},regresion:{titulo:"Pruebas de Regresión",descripcion:"Disponibiliza pruebas de regresión en suites completas de forma acelerada."},ayudante:{titulo:"Ayudante de QA",descripcion:"El chat interno KAI permite, en segundos, a los ingenieros de calida
17948d diagnosticar problemas en sus pruebas, realizar correcciones y mejorar su robustez."},talento:{titulo:"IA al Servicio del Talento",descripcion:"Haka AI Studio usa la IA de forma estratégica, en lugar de pedirle que construya todo, nos servimos de su capa generativa para la orquestación inteligente, lo que mantiene la seguridad al máximo."}},faq:{titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre Haka AI Studio",items:[{question:"¿Qué es Haka AI Studio?",answer:"Haka AI Studio es una extensión exclusiva de Visual Studio Code que combina la potencia de la inteligencia artificial con las mejores prácticas de automatización de pruebas. Graba tus interacciones en el navegador y genera automáticamente casos de prueba completos en formato Gherkin/BDD con implementaciones listas para ejecutar."},{question:"¿Qué frameworks soporta?",answer:"Haka AI Studio soporta Playwright y Selenium, los dos frameworks más populares de automatización web. Puedes grabar con un framework y generar código para el otro."},{question:"¿Necesito conocimientos de programación de pruebas?",answer:"Si. Aunque Haka AI Studio automatiza la creación de scripts (y reduce el esfuerzo significativamente), el conocimiento de los profesionales de calidad es vital."},{question:"¿Cómo funciona la búsqueda vectorial?",answer:"El sistema de búsqueda vectorial analiza tu framework existente y detecta automáticamente pasos reutilizables. Esto evita duplicación de código y asegura que sigas los patrones establecidos en tu proyecto."},{question:"¿Puedo personalizar el código generado?",answer:"SÃ, completamente. Puedes usar el chat de Kai para refinar los tests, agregar validaciones adicionales o ajustar cualquier aspecto del código generado."},{question:"¿Haka AI Studio está disponible públicamente?",answer:"SÃ, Haka AI Studio ahora tiene una versión free con menores prestaciones y sin acceso a la vectorización. La versión pro exclusiva de clientes Haka Lab contiene todas las caracteristicas avanzadas."},{question:"¿Qué necesito para usar Haka AI Studio?",answer:"Necesitas Visual Studio Code 1.85.0 o superior, Kiro, Antigravity u otros IDES basados en VSX, Node.js 20.x o superior, una API Key de Gemini, Claude o OpenAI y Python 3.8+ para ejecutar los tests."},{question:"¿Cuánto tiempo ahorro realmente?",answer:"En promedio, nuestras métricas reportan una reducción entre el 70% ~ 80% en el tiempo de creación de tests. Lo que antes tomaba 2-4 horas ahora toma 15-30 minutos."}]}},ome={titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre HakaPath",items:[{question:"¿Qué debo hacer después de instalar HakaPath?",answer:"Tras instalar el complemento es necesario fijar el complemento al navegador desde el menú de complementos en Google Chrome, luego debes reiniciar el navegador. No se requieren acciones adicionales a estos dos pasos."},{question:"¿Cómo generar un xpath?",answer:'Para generar un xpath simplemente identifica al elemento web del que desees obtener el xpath, haz click derecho sobre él y selecciona "Obtener Hakapath".'},{question:"¿Qué estrategia de localización utiliza HakaPath?",answer:"HakaPath utiliza una estrategia de localización basada en buenas prácticas de xpath. De manera automática HakaPath construye el xpath según los principales componentes disponibles en el elemento web clickeado: id, name, class, etc."},{question:"¿Hasta cuántos xpath se pueden generar?",answer:"HakaPath permite generar xpath de forma ilimitada. Cada vez que generas un xpath se entregan hasta 4 opciones posibles de localización (en la versión registrada del complemento)."},{question:"¿En qué se diferencian los resultados del xpath generado?",answer:"HakaPath genera hasta 4 xpaths de forma automática (en la versión registrada) cuya diferencia está en la especialización de la estrategia de localización, de esta forma se ofrecen diferentes estrategias como: Localización general mediante comodÃn (*), Localización especÃfica mediante tag del componente web, Localización especÃfica de segundo orden, añadiendo el parent del elemento seleccionado, Localización especÃfica de tercer orden, intentando acceder al elemento web parent desde un child."}
17948,{question:"¿A qué lenguajes se pueden convertir automáticamente los xpaths generados?",answer:"HakaPath permite convertir los xpaths generados en código de Selenium para obtener un webElement, se ofrecen hasta 4 lenguajes disponibles en las opciones de configuración: Python (por defecto), Java, Javascript y C#."},{question:'HakaPath no entrega xpaths, queda en "esperandoâ¦" ¿Qué debo hacer?',answer:'Si estás utilizando Google Chrome en vista de dispositivos mobile (escalado de tamaño) verifica que no esté activa la opción "Barra de herramientas de dispositivo", ya que esta opción sobrepone una capa sobre la web para mostrar las herramientas de dispositivos móviles lo cual interfiere con HakaPath.'},{question:"¿En qué situaciones HakaPath puede no entregar un resultado correcto?",answer:"Si bien en la gran mayorÃa de los casos HakaPath entregará localizadores exactos pueden darse casos donde sea difÃcil hacerlo, esto puede originarse en la forma en que esté diseñado el sitio web o aplicación, en particular en aquellos donde se sobreponen capas de componentes una sobre la otra."},{question:"¿Cómo se identifican las coincidencias del XPath?",answer:"Hakapath busca automáticamente en el DOM del HTML coincidencias para cada xpath generado tal cual se hace cuando manualmente ingresas un xpath en el inspector del navegador. En ocasiones puede darse el caso que no se encuentren coincidencias, esto implica que el xpath no coincide con ningún elemento del DOM. Lo mostramos igual en el listado de Xpaths generado en caso de ser útil para utilizarlo de base para generar un localizador mucho más especializado."},{question:"¿Para qué sirve la identificación y conteos de elementos coincidentes con el xpath?",answer:"Esto te permitirá conocer con exactitud cuál es el xpath más certero, además conocer el número de coincidencias te permitirá identificar el tipo de estrategia para utilizar con tu xpath al momento de crear un web element particular o una lista de ellos desde selenium."}]},sme={hero:{title:"Somos Especialistas en",title2:"Calidad de Software",subtitle:"Expertos en QA automatizado y testing que transforman la calidad en ventaja competitiva para tu negocio.",cta:"Casos de éxito",scheduleCall:"Hablemos de calidad"},services:[{title:"QA Salesforce y Continuous Testing",description:"Nuestra metodologÃa y experiencia en testing nos permite asegurar la calidad de tus desarrollos en Salesforce en múltiples capas, acelerando el Time To Market y ahorrando costos en aseguramiento continuo de calidad a través de regresiones automatizadas."},{title:"QA SAP y Testing Funcional",description:"Desde la etapa de planificación hasta la implementación final del producto ayudamos a nuestros partners a construir con calidad, disminuyendo errores, mejorando la confianza y resiliencia del producto, ahorrando costos y promoviendo el aseguramiento continuo mediante pruebas automatizadas."},{title:"Continuous Performance",description:"A través de diferentes estrategias escalables preparamos tu ecosistema para enfrentar exitosamente eventos de alta demanda, entregando información valiosa sobre el uso real de infraestructura y capacidades permitimos ahorrar costos en infraestructura cloud garantizando el retorno de inversión."},{title:"Continuous Data Testing",description:"Trabajamos sobre los desafÃos especÃficos de la infraestructura de datos, análisis y evaluación de la integridad, seguridad y eficiencia de los sistemas de datos."}],methodology:{title:"MetodologÃa",subtitle:"Nuestro ADN: Calidad + Innovación + Entrega de Valor.",description:"Una metodologÃa ágil, escalable y centrada en resultados medibles.",bottomText:"Aseguramos la calidad de software mediante diferentes enfoques de testing, para garantizar la estabilidad, confianza y operatividad de tus productos",steps:[{title:"Detección de riesgos",description:"Identificamos puntos crÃticos"},{title:"Priorización",description:"Enfocamos esfuerzos estratég
17948icamente"},{title:"Ejecución ágil y automatizada",description:"Implementamos con velocidad"},{title:"Feedback continuo y escalabilidad",description:"Mejoramos constantemente"}]},errorCost:{title:{before:'"El costo de un error tras despliegue es ',highlight:"10 veces mayor",after:' al de prevenirlo."'},description:"Ignorar el testing en etapas tempranas impacta directamente en el ROI de tu inversión, degrada la experiencia del usuario y rompe la confianza en tu marca.",risks:["Errores crÃticos que se descubren en producción.","Pérdida de presupuesto en correcciones reactivas.","Erosión de la reputación y fidelidad del usuario."],impactTitle:"Impacto en el Negocio",impacts:[{label:"Pérdida de Productividad",percentage:"+55%"},{label:"Deuda Técnica Acumulada",percentage:"+75%"}],disclaimer:"*Datos basados en auditorÃas de salud de ecosistemas Salesforce pre-Haka Lab."},testimonials:{title:"Testimonios",subtitle:"¿Qué dicen nuestros clientes?",items:[{text:`Destaco de forma especial: 17949 17950El gran compromiso de la empresa en apoyar a la organización en los desafÃos que han enfrentado. Un alto nivel técnico y profesional en sus equipos entregando soluciones de muy buena calidad. Una increÃble vocación de servicios que se ve reflejada en la calidad de los servicios que prestan. Realmente ponen al cliente al centro.`,author:"Jesus Rodriguez",position:"CTO",company:"Sodimac"},{text:"Gracias a Haka Lab, hemos podido establecer un proceso de certificación robusto y automatizado en nuestra plataforma CRM Salesforce, lo que ha mejorado el tiempo de comercialización de nuestros desarrollos",author:"Francisco Rodriguez",position:"Subgerente CRM",company:"Consorcio"},{text:"Se destaca la adaptación a los equipos y el apoyo constante y su compromiso frente a los desafÃos planteados. Por lo tanto puedo recomendar perfectamente cualquier servicio que Haka Lab pueda prestar en el ámbito de automatización de pruebas.",author:"Humberto Proschle",position:"Gerente TecnologÃa",company:"Casa Ideas"}]},clients:{title:"Nuestros clientes",description:"Trabajamos con empresas lÃderes en sus industrias, ayudándolas a alcanzar sus objetivos tecnológicos con soluciones innovadoras y de calidad."},partners:{title:"Nuestros partners"}},lme={hero:{title:"¿Quiénes Somos?",subtitle:"En Haka Lab, impulsamos la calidad tecnológica. Con más de 7 años de experiencia, colaboramos con empresas de diversos sectores â retail, banca, salud y servicios â para garantizar soluciones tecnológicas que se alinean con sus objetivos y cultura organizacional.",cta:"Contáctanos"},identidad:{intro:"Creemos que la calidad nace del compromiso humano, no solo del código. Por eso nuestra identidad también se refleja en Koru y Kai, dos personajes que simbolizan lo que nos impulsa:"},koru:{descripcion:"Koru representa la innovación y la automatización, siempre buscando nuevas formas de crear valor."},kai:{descripcion:"Kai encarna la colaboración y la confianza, la fuerza que asegura que cada entrega esté acompañada de excelencia."},haka:{conclusion:"Juntos, hacen el haka: un baile que transmite unidad, energÃa y propósito compartido. Asà es como trabajamos cada dÃa en Haka Lab: con pasión, en comunidad y siempre enfocados en generar Entrega Continua de Valor."},caracteristicas:{esencia:{title:"Nuestra Esencia",description:"Nos dedicamos a mejorar continuamente nuestros procesos y servicios, asegurando que cada proyecto supere las expectativas en calidad y eficiencia."},vision:{title:"Visión",description:"Aspiramos a impactar positivamente en nuestros partners y clientes, fomentando una cultura de innovación y mejora continua."},mision:{title:"Misión",description:"Nos enfocamos en ofrecer soluciones tecnológicas que aporten valor sostenible, respaldadas por un servicio de excelencia y una cultura organizacional sólida."},compromiso:{title:"Compromiso",description:"Nos comprometemos a impulsar el crecimiento y éxito de nuestros clientes mediante soluciones tecnológicas innovadoras y de alta calidad."}},redes:{titulo:"SÃguenos en Nuestras Redes Sociales",subtitulo:"Mantente actualizado con nuestras últimas noticias y actualizaciones",verMasNoticias:"Ver más noticias"}},cme={titulo:"Nuestros Servicios",descripcion:"Ofrecemos soluciones integrales de testing y calidad diseña
17950das para garantizar la excelencia de tus productos tecnológicos. Desde testing funcional hasta análisis de datos, cubrimos todas las etapas de tu ciclo de desarrollo.",contactanos:"Contáctanos",servicesDescription:"Nuestros servicios están diseñados para garantizar la calidad, automatización y escalabilidad de tus soluciones tecnológicas.",agileCycle:{introText:"Integramos la visión de calidad en todas las etapas del ciclo de vida de desarrollo del software eficientando el proceso y reduciendo costos.",centerText:{line1:"Ciclo de Vida de",line2:"Desarrollo de Software"},devStages:["Planificación","Diseño","Desarrollo","Testing","Deploy","Review","Launch"],qaStages:[{label:"Análisis",fullName:"Análisis, precondiciones y riesgos",description:"Análisis detallado de requerimientos, identificación de riesgos y establecimiento de precondiciones para garantizar la calidad desde el inicio."},{label:"Diseño pruebas",fullName:"Diseño de pruebas",description:"Diseño detallado del plan de pruebas con estrategias, casos de prueba y criterios de aceptación."},{label:"Construcción",fullName:"Construcción de pruebas",description:"Construcción y desarrollo de pruebas automatizadas y manuales según el plan definido."},{label:"Ejecución",fullName:"Ejecución de pruebas",description:"Ejecución de pruebas en diferentes ambientes y escenarios para validar la calidad del software."},{label:"Verificación regresiva (CI/CD)",fullName:"Testing en CI/CD",description:"Integración de pruebas en el pipeline de CI/CD para validación continua y automatizada."},{label:"Evaluación",fullName:"Evaluación de resultados",description:"Análisis de resultados, generación de reportes y toma de decisiones basada en métricas de calida
17950d."},{label:"Medición",fullName:"Medición de indicadores en producción",description:"Medición y análisis de indicadores clave de productividad y eficiencia del proceso de testing para mejora continua."}]},performance:{title:"Continuous Performance",subtitle:"Nuestro marco de trabajo amplÃa el enfoque tradicional de pruebas de performance integrando Observabilidad y monitoreo continuo para garantizar una preparación de infraestructura y ecosistemas frente a cualquier desafÃo.",cta:"Solicitar una demo gratis",features:["Estrategias de pruebas que se adaptan a los requerimientos de tu negocio.","Mejora continua mediante la ejecución constante de pruebas.","Foco en la experiencia del cliente y objetivos de negocio.","ReporterÃa personalizada y custom.","Proceso integrado activamente."]},continuos:{title:"Continuous Testing",subtitle:"Funcional - Salesforce - SAP"},services:[{title:"Testing Salesforce",description:"Aseguramos la calidad del producto gracias a nuestro framework de pruebas especialmente desarrollado y robustecido para Salesforce, optimizando los tiempos de certificación mediante la creación de estrategias de ejecución en paralelo, escenarios de múltiples combinatorias, identificación de objetos personalizada, regresión e integración continua para minimizar el impacto en la operación del negocio.",benefit:"Acelera el time-to-market de tus proyectos Salesforce en un 40% con testing especializado.",features:["Disminución hasta en un 70% el tiempo de certificación.","Propio Framework de Automatización.","ReporterÃa y evidencia custom.","Ejecuciones multi browser."]},{title:"Testing Funcional",description:"Implementamos los más altos estándares de calidad en el ciclo completo de desarrollo de software. Desde la etapa de planificación hasta la implementación final del producto, brindando apoyo técnico y metodológico a los equipos en el cumplimiento de sus desafÃos, teniendo como eje central la automatización de pruebas bajo una mirada integrativa de todo el proceso.",benefit:"Reduce costos operativos hasta un 60% mediante automatización inteligente y detección temprana de errores.",features:["Certificación en paralelo para reducir hasta un 80% el delivery.","Automatización altamente reutilizable.","Estrategias de calida
17950d continua."]},{title:"Testing SAP",description:"Integramos sistemas legados como BD, OMS, APIs, IMS y distintas plataformas de ecommerce a través de nuestro framework de automatización de pruebas. Hemos incorporado además tecnologÃas como visión por computadora, control de periféricos, y todo lo necesario para garantizar las validaciones eficaces que reducen riesgos, costos y que maximizan el beneficio.",benefit:"Minimiza riesgos en implementaciones SAP crÃticas, protegiendo inversiones millonarias.",features:["Automatización por fases y entrega de valor al corto plazo.","Disminución en tiempo de certificación.","ReporterÃa personalizada."]}],data:{title:"Data Testing",subtitle:"Trabajamos sobre los desafÃos especÃficos de la infraestructura de datos, profundizamos en el análisis y evaluación de la integridad, seguridad y eficiencia de sistemas de datos. Además, identificamos fallos tempranamente y áreas de mejora, asegurando la robustez y fiabilidad de bases de datos y almacenamiento de información, optimizando la gestión de información y garantizando su seguridad.",cta:"Solicitar una demo gratis",features:["Reducción de hasta un 90% de tiempo relacionado a los procesos de data testing.","Testing, análisis y evaluación.","Ejecuciones regresivas constantes.","Verificación de consistencia de datos constante."]}},dme={titulo2:"Conoce nuestras herramientas de testing",hero:{title:"Soluciones estratégicas para tu",title2:" calidad de software",subtitle:"Simplifica tus procesos de calida
17950d con nuestras herramientas impulsadas por Inteligencia Artificial estratégica.",cta:"Solicitar una demo gratis"},titulo:"Impulsa tu trabajo en QA y desarrollo con nuestras herramientas Haka",descripcion:"Simplifica tus tareas diarias, reduce tiempos y automatiza con inteligencia.",hakaboost:{descripcion:"Acelera la creación de test en Jira hasta en un 97% con IA"},hakabuddy:{descripcion:"Crea reportes de pruebas manuales en minutos, no en horas"},hakapath:{descripcion:"Genera XPaths automáticamente con precisión y velocidad"},hakatools:{descripcion:"Suite completa de herramientas para automatización de pruebas"},hakartc:{descripcion:"Captura y exporta tráfico REST para tus pruebas de API"},hakainsight:{descripcion:"Analiza tu código y crea explicaciones simples con diagramas interactivos automáticamente"},hakaengine:{descripcion:"Framework BDD de automatización de pruebas con Playwright, self-healing con IA y 1800+ steps listos para usar"},hakaaistudio:{descripcion:"Acelera la automatización con nuestro Engine impulsado por IA"},hakaistudio:{descripcion:"Extensión VS Code con IA que transforma grabaciones en tests automatizados completos"}},ume={titulo:"Ciclo de Testing",descripcion:"Nuestros productos impactan directamente en las diferentes etapas del ciclo de pruebas, permitiéndonos acelerar los procesos y optimizar el aseguramiento de la calidad.",productoLabel:"Product:",entendido:"Excelente",pasos:[`Planning 17951y análisis`,`Diseño de 17952pruebas`,`Ejecución de 17953pruebas`,`Reporte de 17954hallazgos`,`Análisis y 17955visibilidad`,`Mejora 17956continua`],descriptions:["Definimos objetivos claros de calidad, identificamos riesgos y establecemos criterios de aceptación. Analizamos requisitos funcionales y no funcionales para garantizar que cada aspecto del software cumpla con los estándares de calidad desde el inicio.","Creamos escenarios de prueba exhaustivos que cubren flujos principales, casos lÃmite y situaciones excepcionales. Diseñamos estrategias de testing que aseguran la cobertura completa del código y la validación de todos los requisitos de negocio.","Implementamos scripts de automatización robustos y mantenibles. Configuramos entornos de prueba que replican producción y establecemos pipelines de CI/CD para integrar el testing en cada etapa del desarrollo, detectando defectos tempranamente.","Ejecutamos pruebas funcionales, de regresión, performance y seguridad de forma automatizada. Validamos que cada funcionalidad opere correctamente bajo diferentes condiciones y cargas, asegurando la estabilidad y confiabilidad del sistema.","Analizamos métricas de calida
17956d, identificamos patrones de defectos y generamos reportes detallados. Proporcionamos visibilidad completa del estado de calidad del software, facilitando la toma de decisiones informadas sobre el release.","Refinamos procesos de testing basándonos en lecciones aprendidas. Optimizamos la cobertura de pruebas, reducimos tiempos de ejecución y mejoramos la detección temprana de defectos. Implementamos feedback loops para elevar continuamente los estándares de calidad."],productDescriptions:{hakaboost:"Planning y análisis, Diseño de pruebas",hakabuddy:"Diseño de pruebas, Ejecución, Reportes, Análisis y visibilidad",hakapath:"Ejecución de pruebas",hakartc:"Diseño de pruebas",hakainsight:"Analiza y comprende tu código fuente fácilmente",hakaengine:"Automatización de pruebas funcionales sin código",hakaaistudio:"Automatización de pruebas con Inteligencia Artificial"}},pme={hero:{title:"¿Tus sistemas fallan justo cuando más los necesitas?",subtitle:"En Haka Lab solucionamos esos dolores con tecnologÃa, velocidad y calidad real. Conoce cómo empresas como la tuya convirtieron sus desafÃos en historias de éxito - con resultados en horas ahorradas, bugs eliminados y clientes felices.",btn:"Solicita una evaluación gratuita"},desafioLabel:"DesafÃo:",solucionLabel:"Solución:",testimonioLabel:"Testimonio",qaLabel:"QA",cta:{titulo:"¿Quieres lograr estos resultados?",descripcion:"Agenda tu diagnóstico gratuito y descubre cómo adaptamos nuestros frameworks a tu entorno.",boton:"Solicita una evaluación gratuita"},cases:{walmart:{company:"Walmart",title:"100% Uptime durante Cyber Day",problem:"La operación omnicanal requerÃa garantizar estabilidad en todos los sistemas durante eventos crÃticos de alta tráfico (como lanzamientos y campañas promocionales), evitando errores y caÃdas en producción.",solution:"Implementamos una estrategia de automatización E2E con foco en performance, integrando los diferentes servicios de los flujos ecommerce mediante diferentes estrategias de calida
17956d que permitieron garantizar el éxito de las estrategias comerciales en eventos de alta demanda e impacto para la compañÃa.",results:[{metric:"100%",description:"Aseguramos un 100% de cumplimiento del time to market, sin retrasos en releases clave."},{metric:"65%",description:"Disminuimos en un 65% las incidencias crÃticas relacionadas al rendimiento del sistema."},{metric:"99.98%",description:"Habilitamos alertas preventivas en tiempo real, elevando la disponibilidad del ecosistema digital a un 99.98%"}],qa:"Transformamos el QA en un eje estratégico para anticiparnos a los riesgos y mejorar la experiencia del cliente."},melt:{company:"Melt Pizzas",title:"Monitoreo Sintético",problem:"Melt Pizzas buscaba asegurar que su infraestructura soportara el crecimiento acelerado de sus canales digitales, especialmente en contextos de alta demanda.",solution:"Realizamos monitoreo sintético y pruebas de performance para validar si la infraestructura actual soportaba el crecimiento esperado. Se emitieron recomendaciones estratégicas a partir del análisis de carga y experiencia de usuario.",results:[{description:"Establecimos una base de monitoreo permanente que permite escalar sin sacrificar calidad ni disponibilidad."},{description:"ReporterÃa personalizada para presentar los datos obtenidos de las pruebas, con gráficos para representar kpis relevantes a gerencia."},{description:"Validación proactiva de la capacidad de respuesta de la infraestructura."}]},consorcio:{company:"Consorcio",title:"CRM Salesforce",problem:"Proceso manual de certificación lento y sin trazabilidad.",solution:"Automatización al 100% de pruebas funcionales de Salesforce con ejecución desde CI/CD.",results:[{description:"Reducimos un 70% los tiempos de paso a producción."},{description:"Mejoramos la visibilidad del proceso y eliminamos deuda técnica en semanas."}],testimonial:{text:"Gracias a Haka Lab, hemos podido establecer un proceso de certificación robusto y automatizado en nuestra plataforma CRM Salesforce, lo que ha mejorado el Time to Market de nuestros desarrollos",author:"Francisco RodrÃguez",position:"Subgerente CRM Salesforce",company:"Implementation Leader"}},casaideas:{company:"Casa Ideas",title:"Automatización Flujo de Ecommerce e integraciones SAP y Magento",problem:"Flujo E2E complejo de certificar el cual tenÃa múltiples errores en producción.",solution:"Automatizamos SAP Logon v760 en conjunto del E2E de la compra en el ecommerce para luego validar que los datos que se generaban cuadraran y llegaran correctamente a SAP, Magento, Omnix y Dbnet.",results:[{description:"Automatización de pruebas integrales con SAP y legados."},{description:"Ejecución de pruebas en máquinas virtuales automatizadas."}],testimonial:{text:"Para el lanzamiento de nuestra nueva plataforma e-commerce decidimos contratar los servicios de Haka Lab ya que demostraron un alto grado de conocimiento técnico en el proceso de automatización de pruebas. El proyecto logró sus objetivos y se destaca de forma especial: - Innovación y manejo de la tecnologÃa - Uso de MetodologÃas - Soporte y acompañamiento en el proceso de diseño y elaboración de pruebas - Adaptación constante al cambio - Apoyo técnico y compromiso. En forma adicional, se destaca la adaptación a los equipos y el apoyo constante y su compromiso frente a los desafÃos planteados. Por lo tanto puede recomendar perfectamente cualquier servicio que Haka Lab pueda prestar en el ámbito de la automatización de pruebas.",author:"Equipo Casa Ideas",position:""}},sodimac:{company:"Sodimac Homecenter",title:"Backoffice cierre y cuadratura",problem:"Dificultad en el proceso y altos tiempos para el cierre y cuadratura de los POS de ventas.",solution:"Automatizamos un proceso crÃtico que antes tomaba 8 horas y lo redujimos a solo 70 minutos, superando barreras tecnológicas complejas con componentes legados (UXPOS, SAP, Control-M) y visión computarizada.",results:[{description:"Reducción de tiempo del proceso manual del Back office de Cierre y Cuadratura de 8 horas a 70 minutos automatizado."},{description:"Automatización de componentes UXPOS, SAP y Control-M"}],testimonial:{text:"Destacó de forma especial el gran compromiso de la empresa en apoyar a la organización en los desafÃos que han afrontado. Un alto
17956nivel técnico y profesional en sus equipos entregando soluciones de muy buena calidad. Una increÃble vocación de servicios que se ve reflejada en la calidad de los servicios que prestan. Realmente ponen al cliente al centro.",author:"Jesús RodrÃguez",position:"CTO Sodimac",company:""}},scotiabank:{company:"Scotiabank",title:"Digital Factory",problem:"",solution:"Fuimos pioneros en implementar una estrategia de Continuous Testing y Delivery en la Fábrica Digital de una de las principales entidades bancarias de Chile. Incorporamos prácticas como ATDD y BDD para alinear al negocio con el desarrollo y asegurar la calidad desde el primer sprint. Nos hicimos cargo de la certificación completa de la fábrica, integrando calidad en todas las capas.",results:[{description:"Certificación total de los productos digitales en paralelo al desarrollo."},{description:"Implementación exitosa de ATDD y BDD como base de madurez QA."},{description:"Reducción en los ciclos de entrega gracias al Continuous Delivery."},{description:"Establecimos un modelo de calida
17956d continuo que hoy sigue vigente."}]},parquearauco:{company:"Parque Arauco",title:"Migración SAP Hana a AWS",problem:"Parque Arauco enfrentaba el desafÃo de asegurar la calidad en una migración compleja hacia AWS, involucrando múltiples capas de datos, servicios cloud y componentes crÃticos del negocio.",solution:"Desplegamos nuestro framework de automatización especializado para certificación de datos, aplicando tecnologÃas como Spark, Glue, Hyde, C3, Lambda y Python. Implementamos pruebas regresivas con enfoque en trazabilidad e integridad end-to-end, integrándolos activamente a los equipos del cliente con entregas iterativas y feedback continuo.",results:[{description:"Disminución de tiempos de certificación gracias a las regresivas constantes identificando errores de manera temprana."},{description:"Propio Framework de Automatización para certificaciones de datos con tecnologÃas como Spark, Hyde, Glue, C3, Lambda, Python."}]}}},mme={titulo:"Blog",titleFront:"Blog de HakaLab",descripcion:"ArtÃculos sobre testing, calida
17956d de software y automatización de pruebas",leerMas:"Leer más",verEnBlog:"Ver en blog",articulosRelacionados:"ArtÃculos relacionados",volverAlBlog:"Volver al blog",buscar:"Buscar artÃculos...",filtrarPorEtiqueta:"Filtrar por etiqueta",limpiarFiltros:"Limpiar filtros",noHayArticulos:"No hay artÃculos publicados aún",noEncontrados:"No se encontraron artÃculos con los filtros seleccionados",mostrando:"Mostrando",de:"de",articulos:"artÃculos",vistas:"vistas",autor:"Autor",creado:"Creado",etiquetas:"Etiquetas",por:"Por"},hme={title:"Agendar Cita",name:"Nombre",email:"Email",company:"Empresa",date:"Fecha",time:"Hora",message:"Mensaje (opcional)",schedule:"Agendar",scheduling:"Agendando...",cancel:"Cancelar",success:"¡Cita agendada exitosamente!",successMessage:"Te enviaremos un email de confirmación",errorRequired:"Por favor completa todos los campos requeridos",noCalendarUrl:"El calendario no está configurado",close:"Cerrar",calendlyMessage:"Haz clic en el botón para abrir el calendario y agendar tu cita",openCalendar:"Abrir Calendario"},fme={title:"El Costo de los Bugs en el Ciclo de Desarrollo",subtitle:"Costo de encontrar un bug en el ciclo de desarrollo de software",message:"Al integrarnos a tu equipo, aceleramos la detección de bugs a etapas tempranas.",conclusion:"Eso Ahorra Dinero",ciclos:"Ciclo Desarrollo",stages:[{label:"Planificación"},{label:"Diseño"},{label:"Coding"},{label:"Testing"},{label:"Producción"}]},gme={titulo:"Partner Oficial de",titulo2:"XRAY",titulo3:"by Sembi",subtitulo:"Somos implementadores oficiales de XRAY en Jira Cloud y especialistas en su uso profesional para el acompañamiento de la calidad de software en nuestros clientes.",conversemos:"Hablemos de calidad"},yme={partners:"Partners Estratégicos",lideres:"LÃderes en Salesforce Quality"},xme={title:"Impacto en ROI",title2:"Eficiencia"},vme={welcome:{title:"Autoevaluación de calidad Haka Lab",subtitle:"Responde las siguientes preguntas para medir el nivel de calidad que aplicas hoy en dÃa sobre tus desarrollos de software",email:"Correo electrónico",emailPlaceholder:"[email protected]",company:"Empresa",companyPlaceholder:"Nombre de tu empresa",industry:"Industria",industryPlaceholder:"Selecciona tu industria",developmentType:"Tipo de desarrollo",developmentTypePlaceholder:"Selecciona el tipo de desarrollo",startButton:"Iniciar Evaluación",requiredField:"Este campo es requerido",invalidEmail:"El email no es válido"},quiz:{progress:"Progreso",question:"Pregunta",of:"de",continueButton:"Continuar",previousButton:"Anterior",seeResultsButton:"Conocer Resultados",allQuestionsRequired:"Por favor responde todas las preguntas antes de continuar"},rating:{never:"Nunca",rarely:"Raramente",sometimes:"A veces",frequently:"Frecuentemente",always:"Siempre"},results:{title:"Tus Resultados",yourScore:"Tu Puntaje",outOf:"de",points:"puntos",maturityLevel:"Nivel de Madurez",analysis:"Análisis Personalizado",redFlags:"Banderas Rojas Identificadas",noRedFlags:"¡Excelente! No se identificaron banderas rojas crÃticas.",recommendations:"¿Cómo podemos ayudarte?",recommendationsSubtitle:"Servicios recomendados según tu evaluación",contactButton:"Contactar con HakaLab",learnMore:"Conocer más",highScoreMessage:"¡Felicitaciones! Tu equipo tiene una cultura de calidad establecida. Podemos ayudarte a optimizar aún más tus procesos.",savingResults:"Guardando resultados...",resultsSaved:"Resultados guardados exitosamente"},maturityLevels:{reactive:{name:"Calidad Reactiva",label:"Nivel CrÃtico",diagnosis:"El equipo apaga incendios. QA es un cuello de botella al final del proceso y hay poca visibilidad de lo que pasa en producción."},transition:{name:"Calidad en Transición",label:"Nivel Medio",diagnosis:"Existen esfuerzos (quizás algunas pruebas unitarias o ambientes de QA), pero falta consistencia y métricas para mejorar."},advanced:{name:"Calidad Avanzada",label:"Nivel Pro",diagnosis:"El equipo tiene cultura de calidad. QA está integrado y hay métricas."}},redFlags:{silos:{title:"Alerta de Silos",message:"Tu equipo de QA está aislado; esto genera retrabajo y costos altos de corrección."},production_risk:{title:"Alerta de Riesgo en Producción",message:"Estás volando a ciegas; no estás aprendiendo de tus errores en producción."},technical_debt:{title:"Alerta de Deuda Técnica",message:"Tu regresión manual se volverá insostenible pronto. La automatización es tu siguiente paso."}},services:{qa_assessment:{name:"QA Assessment & Strategy",description:"Definimos procesos desde cero, establecemos DOR/DOD y movemos QA hacia la izquierda (Shift Left)."},test_automation:{name:"Test Automation",description:"Automatizamos pruebas humo y regresiones para liberar tiempo y mejorar la confianza."},continuous_testing:{name:"Continuous Testing",description:"Integramos pruebas en tu pipeline CI/CD para detectar problemas temprano."},performance_testing:{name:"Performance Testing",description:"Optimizamos la carga del sistema y aseguramos que tu aplicación escale."},data_testing:{name:"Data Testing",description:"Validamos la calidad y precisión de tus datos en pipelines y reportes."},resource_optimization:{name:"Optimización de Recursos",description:"Optimizamos tus procesos de QA existentes para maximizar eficiencia y reducir costos."}},errors:{loadingQuestions:"Error al cargar las preguntas",savingResults:"Error al guardar los resultados",generic:"Ocurrió un error. Por favor intenta nuevamente."}},bme={hero:{badge:"Motor de Automatización",title:"Haka Automation Engine",titleHighlight:"Inteligencia aplicada a la calidad",subtitle:"Nuestro motor de automatización especializado integra las mejores tecnologÃas de testing para construir pruebas automatizadas hasta 40% más rápido, reduciendo costos y garantizando calidad continua.",ctaContact:"Solicitar Demo"},diagram:{title:"Arquitectura del Motor",subtitle:"Basados en nuestra experiencia creamos una solución completa en capas que optimiza cada etapa del proceso de testing",layer1:{title:"Base Tecnológica",description:"Selenium, Playwright y Behave (Gherkin) para pruebas modernas y estables con ejecución paralela"}
17956,layer2:{title:"Impulsado por Experiencia e IA",description:"Permite construir pruebas para front-end, API REST, BBDD y Gen AI a gran velocidad"},layer3:{title:"Integraciones Nativas",description:"Conexión directa con Jira, Xray, Zephyr y Grafana para resultados en tiempo real"},layer4:{title:"Reportes Automáticos",description:"Reportes HTML/Video construidos de forma automática junto con las pruebas para facilitar el seguimiento, revisión de indicadores y trazabilidad completa"},layer5:{title:"CI/CD Ready",description:"Preparado para pipelines de integración y despliegue continuo"},note:"Nuestros productos impulsan al motor para eficientar el proceso, máximar la calidad y reducir costos de construcción y ejecución de pruebas"},aiTesting:{badge:"Innovación en Testing",title:"Motor Impulsado por IA",subtitle:"Nuestro motor está impulsado y preparado para testear aplicaciones que usan IA Generativa, mediante análisis semánticos avanzados y estrategias RAG (Retrieval-Augmented Generation).",innovationBadge:"Innovación",features:{genAI:{title:"Testing de IA Generativa",description:"Validación especializada para aplicaciones que utilizan GEN AI para generar interacciones o respuestas a sus usuarios"},semantic:{title:"Análisis Semántico",description:"Evaluación inteligente del significado y contexto de las respuestas generadas por IA ahorrando costos asociados a validadores externos"},rag:{title:"Estrategias RAG",description:"Testing a sistemas que combinan recuperación de información con generación de contenido con diferentes estrategias de validación y análisis cuantitativo de resultados"},validation:{title:"Validación de Calidad",description:"Verificación de precisión, coherencia y relevancia en respuestas de IA en alineación a las espectativas técnologicas y de negocio del cliente"}},stat:{label:"Preparados para el futuro",value:"Gen AI Testing",description:"Testing especializado para la nueva era de aplicaciones inteligentes"},diagram:{input:{title:"Input de Usuario",description:"Consulta o prompt"},genAI:{title:"IA Generativa",description:"Procesamiento + RAG"},output:{title:"Respuesta Generada",description:"Contenido de IA"},testing:{title:"Haka Automation Engine",description:"Validación Semántica"}}},comparison:{title:"Comparativa de Eficiencia",subtitle:"Descubre cómo Haka Automation Engine acelera tu proceso de testing, optimiza recursos, máximiza la eficiencia y ahorra costos.",traditional:{badge:"Método Tradicional",title:"Sin Motor Especializado",description:"Construcción manual de cada componente de prueba, curva de implementación alta, sin estandar técnologico claro ni métodologia garantizada.",point1:"Desarrollo desde cero",point2:"Mayor tiempo de implementación",point3:"Costos elevados de recursos"},hakalab:{badge:"Con Hakalab",title:"Haka Automation Engine",description:"Componentes y productos Haka Lab, optimizados e impulsados para la construcción, ejecución y documentación.",point1:"Automatización lista para implementar",point2:"Productos propios que apoyan el proceso de calidad",point3:"Reducción de costos significativa"},savings:"Menos tiempo de desarrollo"},benefits:{title:"Beneficios Clave",subtitle:"Por qué Haka Automation Engine marca la diferencia",speed:{title:"Velocidad Optimizada",description:"Reduce hasta 40% el tiempo de construcción de pruebas con componentes preconstruidos"},coverage:{title:"Cobertura Maximizada",description:"Pruebas en todas las capas: front-end, API REST, bases de datos y Gen AI"},continuous:{title:"Calidad Continua",description:"Integración con CI/CD para regresiones automáticas y feedback inmediato"},reports:{title:"Reportes Robustos",description:"Documentación automática con evidencias, métricas y trazabilidad completa"},integrations:{title:"Integraciones Nativas",description:"Conexión directa con Jira, Xray, Zephyr y Grafana sin configuración compleja"},cost:{title:"Ahorro de Costos",description:"Optimización de recursos y reducción de tiempo se traduce en ahorro real"}},technologies:{title:"TecnologÃas Integradas",subtitle:"Un ecosistema completo de herramientas lÃderes en la industria",products:{title:"Productos Hakalab Incluidos",description:"Todos nuestros productos están diseña
17956dos para trabajar con el motor y acelerar tu testing"}},cta:{badge:"Comienza Ahora",demoTitle:"Demo de Ejecución Automatizada",demoSubtitle:"Observa cómo Haka Automation Engine ejecuta pruebas automatizadas fácilmente",videoLoading:"Cargando video...",videoLoadingSubtitle:"Por favor espera unos segundos",title:"¿Listo para acelerar tu testing?",description:"Agenda una demo personalizada y descubre cómo Haka Automation Engine puede transformar tu proceso de QA",scheduleDemo:"Agendar Demo",contact:"Contactar",stat1:"Menos tiempo",stat2:"Pasos preconstruidos",stat3:"Automatizable"}},wme={hero:{badge:"Framework Integral",title:"Framework HakaLab",titleHighlight:"Personas + MetodologÃa + TecnologÃas",subtitle:"Trabajando en conjunto para asegurar la calidad de tus productos",ctaContact:"Solicitar Demo"},pillars:{title:"Framework HakaLab",subtitle:"Nuestra solución se centra en tres pilares fundamentales que trabajan en sinergia, aprendizaje y mejora continua",people:{title:"Personas",description:"Nuestros profesionales llevan la cultura de calidad Haka a nuestroos clientes, con expertis métodologica y técnica en base a una pensamiento Lean.."},methodology:{title:"Framework Metodológico",description:"Implementamos prácticas de calida
17956d en todo el ciclo de desarrollo de software mediante las mejores prácticas de la industria."},technology:{title:"Framework Tecnológico",description:"Utilizamos una solución tecnológica propia construida sobre las herramientas de testing y automatización más robustas en la actualidad, impulsado por IA y nuestra experiencia."}},methodology:{title:"Framework Metodológico",subtitle:"Implementamos prácticas de calidad en todo el ciclo de desarrollo mediante metodologÃas ágiles y mejora continua",quote:"Integramos el framework metodológico Haka Lab según las necesidades y capacidades del cliente en un modelo evolutivo de mejora continua, valor y retorno de inversión constante.",author:"MatÃas Carrasco",authorRole:"CEO Haka Lab"},technology:{subtitle:"TecnologÃas robustas potenciadas por la experiencia de nuestra experiencia",techTitle:"Stack Tecnológico",aiPowered:"Impulsado por IA",differentiator:{title:"¿Qué nos diferencia?",description:"Sustentados en el framework metodologico nuestros especialistas dominan las técnologiaspara acelerar procesos, reducir costos y maximizar la calidad. Potenciamos cada proyecto con nuestros Power Ups Haka."},powerups:{title:"Power-Ups Haka",description:"Nuestros productos propios que multiplican la eficiencia del framework tecnológico:"},cta:"Conocer Haka Automation Engine",tools:{selenium:"Automatización de navegadores web",playwright:"Testing moderno de aplicaciones web",cucumber:"Framework BDD con Gherkin",python:"Lenguaje para scripts de testing",jenkins:"Automatización CI/CD",docker:"Contenedores para ambientes consistentes",github:"Control de versiones y colaboración",jira:"Gestión de proyectos y seguimiento",xray:"Gestión de casos de prueba en Jira",grafana:"Visualización de métricas y dashboards",html:"Reportes HTML automatizados",apirest:"Testing de APIs REST",bbdd:"Testing de bases de datos",front:"Testing de interfaces frontend",chrome:"Navegador para testing automatizado",appium:"Automatización de apps móviles"}}},kme={titulo:"Términos y Condiciones de Uso",ultimaActualizacion:"Ãltima actualización",definiciones:{titulo:"Definiciones"},aceptacion:{titulo:"Aceptación de los Términos"},licencia:{titulo:"Licencia de Uso"},restricciones:{titulo:"Restricciones de Uso"},actualizaciones:{titulo:"Actualizaciones y Cambios en los Servicios"},privacidad:{titulo:"Privacidad y Protección de Datos"},limitacion:{titulo:"Limitación de Responsabilidad"},terminacion:{titulo:"Terminación"},legislacion:{titulo:"Legislación Aplicable"},modificaciones:{titulo:"Modificaciones a los Términos"},politicaPrivacidad:{titulo:"PolÃtica de Privacidad de Haka Lab",informacion:{titulo:"Información que Recopilamos"},finalidades:{titulo:"Finalidades del Tratamiento"},baseLegal:{titulo:"Base Legal y Consentimiento"},transferencia:{titulo:"Transferencia y Compartición de Datos"},seguridad:{titulo:"Seguridad de la Información"},derechos:{titulo:"Sus Derechos"},cambios:{titulo:"Cambios a esta PolÃtica"},contacto:{titulo:"Contacto"}}},Sme={titulo:"Preguntas Frecuentes sobre QA y Testing",subtitulo:"Resuelve tus dudas sobre servicios de Quality Assurance, testing automatizado y cómo podemos ayudar a tu empresa.",items:[{question:"¿Qué es QA y por qué es importante para mi empresa?",answer:"QA (Quality Assurance) es el proceso que garantiza que tu software funcione correctamente antes de que llegue a tus clientes.",details:["Sin QA, los errores en producción generan pérdidas económicas directas y dañan la reputación de tu marca.","Invertir en calidad desde el inicio reduce costos operativos y acelera los tiempos de entrega.","En HakaLab llevamos más de 10 años ayudando a empresas en Chile a convertir la calidad en una ventaja competitiva."],highlight:"más de 10 años"},{question:"¿Qué servicios de QA ofrece HakaLab?",answer:"Ofrecemos un modelo integral de aseguramiento de calida
17956d que cubre todo el ciclo de vida del software:",details:["Automatización de pruebas para acelerar releases y reducir tiempos de entrega.","Pruebas de rendimiento para garantizar disponibilidad en momentos crÃticos de alta demanda.","Certificación de calidad para implementaciones Salesforce y SAP.","ConsultorÃa estratégica para optimizar procesos de testing y madurar equipos.","Validación de datos para asegurar la integridad de tu información."],highlight:"ciclo de vida del software"},{question:"¿En qué se diferencia HakaLab de otras empresas de QA en Chile?",answer:"Tres pilares nos diferencian:",details:["Capacidad adaptativa: nos integramos al ecosistema del cliente sin imponer tecnologÃas, adaptando procesos a su contexto de negocio.","Más de 7 productos propios impulsados por IA que aceleran los procesos de calidad y generan eficiencias únicas en el mercado.","MetodologÃa probada por más de 10 años + talento humano altamente especializado = resultados medibles que impactan directamente en el ROI."],highlight:"70% de aceleración en ciclos de entrega"},{question:"¿Cómo puede la automatización de pruebas reducir costos?",answer:"Un error detectado en producción cuesta hasta 10 veces más que prevenirlo en etapas tempranas.",details:["Reduce hasta un 80% el tiempo de validación en cada entrega.","Libera a tu equipo para tareas de mayor valor estratégico.","Acelera el time-to-market de nuevas funcionalidades.","Garantiza calidad continua sin esfuerzo manual repetitivo."],highlight:"80% el tiempo de validación"},{question:"¿Qué capacidad tecnológica tiene HakaLab?",answer:"Contamos con un ecosistema tecnológico amplio y flexible que se adapta a cada cliente:",details:["Herramientas lÃderes del mercado para automatización, rendimiento e integración continua.","Más de 7 productos propios con IA: motores de automatización, copiloto de calida
17956d, reportes inteligentes y análisis de código.","Nos integramos con los ecosistemas existentes del cliente para potenciar la capacidad del equipo sin fricciones."],highlight:"más de 7 productos propios"},{question:"¿Trabajan con empresas de cualquier tamaño?",answer:"SÃ. Nuestro modelo se adapta al tamaño y madurez de cada organización:",details:["Startups en etapas tempranas que necesitan construir una estrategia de calidad desde cero.","Empresas medianas en crecimiento que buscan escalar y profesionalizar sus procesos de testing.","Corporaciones Fortune 500 que requieren optimizar y automatizar operaciones de QA a gran escala."],highlight:"Fortune 500"},{question:"¿Cuánto tiempo toma ver resultados con HakaLab?",answer:"Resultados iniciales son visibles desde las primeras 2-4 semanas:",details:["Nuestro motor de automatización propio implementa soluciones hasta un 40% más rápido que enfoques tradicionales.","Desde el primer sprint se generan entregas de valor incremental.","Nuestro motor está preparado para testear aplicaciones con Inteligencia Artificial, posicionándonos como partners de largo plazo."],highlight:"40% más rápido"}]},_me={header:qpe,nav:zpe,contactModal:Vpe,trabajaModal:Hpe,relatedProducts:Fpe,hakaboost:Bpe,hakabuddy:Upe,descargaExitoModal:$pe,common:Wpe,footer:Gpe,cargando:Kpe,hakapath:Jpe,hakartc:Qpe,ctaNewsletter:Xpe,faq:Ype,hakabuddy_queHace:Zpe,hakabuddy_faq:eme,hakapath_queHace:tme,hakartc_queHace:ame,potencia_hakartc:nme,potencia_hakapath:ime,hakaistudio:rme,hakapath_faq:ome,home:sme,nosotros:lme,servicios:cme,productos:dme,cicloTesting:ume,casosExito:pme,blog:mme,scheduleModal:hme,bugCostCycle:fme,partners:gme,badges:yme,roibox:xme,quickAnalysis:vme,hakaAutomationEngine:bme,frameworkHakalab:wme,terminos:kme,faqServicios:Sme},Ame={tagline:"Testing Solutions"},Eme={inicio:"Home",servicios:"Services",nosotros:"About Us",casosDeExito:"Success Cases",productos:"Products",contacto:"Contact"},Cme={title:"Contact Us",subtitle:"If you're thinking about making a technological leap, Haka Lab can help you.",nombre:"Name",empresa:"Company",email:"Email",mensaje:"How can we help you?",enviar:"Send Request",nombrePlaceholder:"Enter your name",empresaPlaceholder:"Enter your company",emailPlaceholder:"Enter your email",mensajePlaceholder:"Enter your request or comment",enviando:"Sending...",exitoEnvio:"â Message sent successfully! We will contact you soon.",errorEnvio:"â Error sending. Please try again."},jme={title:"Work With Us",subtitle:"At Haka Lab we are looking for software quality and automation specialists, send us your CV!",nombre:"Name",nombrePlaceholder:"Enter your name",email:"Email",emailPlaceholder:"Enter your email",pais:"Country of residence",paisPlaceholder:"Enter your country of residence",telefono:"Phone",telefonoPlaceholder:"Enter your phone number",cv:"Attach CV",cvPlaceholder:"Click to select your CV (.pdf, .doc, .docx)",cvFormatos:"Accepted formats: PDF, DOC, DOCX. Max 2MB.",enviar:"Submit application",enviando:"Sending...",exitoEnvio:"â Application sent successfully! We will contact you soon.",errorEnvio:"â Error sending. Please try again.",archivoInvalido:"Only PDF, DOC or DOCX files are allowed.",archivoGrande:"File must not exceed 2MB."},Tme={title:"You might also be interested in",saberMas:"Learn More",impulsadoPorIA:"AI Powered"},Nme={title:"Download Hakaboost Now",subtitle:"To download Hakaboost enter your details",cargo:"Position",sistemaOperativo:"Operating System",aceptaTerminos:"I accept the terms and conditions",descargar:"Download",descargando:"Downloading...",debesAceptar:"You must accept the terms and conditions.",exitoDescarga:"â Download started! Check your email.",errorDescarga:"â You must accept the terms and conditions.",nombrePlaceholder:"Your name",cargoPlaceholder:"Your position",empresaPlaceholder:"Your company",sistemaOperativoPlaceholder:"Select your OS",hero:{descripcion:"The quality copilot for Jira and Azure DevOps. Speed up your testing and QA workflows by up to 70% with AI.",gratis:"Completely Free"},presentacion:{titulo:"Speed up your testing and QA workflows by up to 70% with AI"},queHace:{titulo:"What does it do?",descripcion1:"HakaBoost is a Chrome extension that integrates as a side panel in Jira and Azure DevOps, revolutionizing how quality team
17956s work. With just a few clicks, it improves task descriptions, generates test scenarios, creates tests automatically, and analyzes the quality of your requirements.",descripcion2:"One of its most powerful features is its ability to use multiple AI engines, including Chrome's local AI. Get intelligent suggestions for acceptance criteria and test cases in Gherkin format, and create issues in Jira or work items in Azure DevOps automatically.",features:["Improves descriptions by transforming them into complete user stories with acceptance criteria and Gherkin scenarios","Creates tests automatically: parses Gherkin scenarios and creates issues in Jira or work items in Azure DevOps linked to the main task","Xray Integration: support for creating Cucumber-type tests and exporting .feature files","Intelligent Analysis (Pro): generates quality reports, suggests test data, and analyzes test coverage","Multiple Export (Pro): export analysis to PDF and post as comments in Jira/Azure"]},caracteristicas:{titulo:"Features",items:["Web Plugin: integrates natively into Jira Cloud and Azure DevOps","Multiple AI: support for Chrome Built-in AI (Gemini Nano, 100% local), Google Gemini, and OpenAI","Secure Authentication: Free and Pro account system with social login (Google) and email/password","Dark/Light Mode: modern and customizable interface","Data Obfuscation: protects your sensitive information (URLs, emails, IPs) before sending it to cloud AIs","Bilingual Support: available in Spanish and English","Pro Tabs with Advanced Analysis: quality analysis, test data suggestion, and coverage analysis"]},beneficios:{titulo:"Benefits",descripcion:"HakaBoost transforms your QA workflow with tangible benefits from day one.",items:["Accelerated QA Cycle: reduces test design and creation time by up to 70%","Improved Quality: generates clear acceptance criteria and more comprehensive test coverage from the start","AI Flexibility: choose between the total privacy of local AI or the power of cloud models","Integrated Workflow: all the tools you need, directly in Jira and Azure DevOps, without context switching","Consistency and Standardization: encourages the use of BDD and Gherkin across the team","Pro Features: unlock advanced analysis to take your quality strategy to the next level","Free Pro Access for Clients: all Haka Lab clients get free access to HakaBoost Pro"]},potencia:{titulo:"HakaBoost empowers the quality of your tasks",descripcion:"HakaBoost is an extension for Chromium-based browsers (Chrome, Edge) that, thanks to multiple AI engines (including Chrome's local AI), allows you to improve task descriptions in Jira and Azure DevOps, generate test scenarios in Gherkin, create tests automatically, and analyze the quality of your requirements. All without leaving your management tool."}},Ime={title:"Download Hakabuddy Now",subtitle:"To download Hakabuddy enter your details",cargo:"Position",sistemaOperativo:"Operating System",aceptaTerminos:"I accept the terms and conditions",descargar:"Download",descargando:"Downloading...",debesAceptar:"You must accept the terms and conditions.",exitoDescarga:"â Download started! Check your email.",errorDescarga:"â You must accept the terms and conditions.",nombrePlaceholder:"Your name",cargoPlaceholder:"Your position",empresaPlaceholder:"Your company",sistemaOperativoPlaceholder:"Select your OS",hero:{descripcion:"Facilitates the creation of manual reports.",gratis:"Completely Free"},presentacion:{titulo:"Reducing creation time by up to 70%."}},Pme={titulo:"Registration Successful!",mensaje:"The download will start automatically, please wait.",submensaje:"The download may take up to a minute depending on your internet connection. You may need to accept it in your browser.",boton:"Got it"},Rme={cargandoTweets:"Loading tweets...",verEnX:"View on X â",videoNoSoportado:"Your browser does not support the video element.",altEquipoHakalab:"HakaLab - Salesforce and SAP QA Experts",altHeroImage:"HakaLab - Salesforce and SAP QA Experts"},Lme={empresa:"© 2026 Haka Lab. All rights reserved.",enlaces:"Links",siguenos:"Follow Us",privacidad:"Privacy",terminos:"Terms",contacto:"Contact",twitter:"Twitter",linkedin:"LinkedIn",github:"GitHub",ereshaka:"Are you Haka?",trabajaConNosotros:"Work With Us",codigoConducta:"Code of Conduct",politicaSeguridadSalud:"Health & Safety Policy"},Ome={tweets:"Loading tweets..."},Mme={descargar:"Download",ayuda:"It will help you automate tests and make them up to 70% faster and with fewer errors.",titulo1:"Discover our plugin developed to generate XPaths",gratis1:"Completely Free"},Dme={descargar:"Download",hero:{descripcion:"Capture, organize and export REST without leaving the browser",gratis:"Completely Free"},presentacion:{titulo:"Up to 95% faster capturing network traffic, Export your flows to Postman and CSV in one click."}}
17956,qme={titulo:"Know all our success cases!",placeholder:"Your email",boton:"Download success stories",mensaje:"The file will be downloaded automatically."},zme={titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about HakaBoost",items:[{question:"What is HakaBoost and what is it for?",answer:"HakaBoost is a testing copilot that helps you improve the descriptions of your user stories in Jira and create test cases automatically using artificial intelligence."},{question:"Do I need to pay to use HakaBoost?",answer:"No, HakaBoost is completely free. You can use it at no cost in your Jira instance."},{question:"Which AI should I choose: OpenAI, Gemini or Chrome?",answer:"You can choose based on your preferences. OpenAI and Gemini are cloud options, while Chrome offers you 100% local AI based on Gemini for greater privacy."},{question:"Does it work without internet connection?",answer:"Yes, if you use the local AI option (Chrome built-in), HakaBoost works completely without internet connection."},{question:"Do I need to configure anything before using HakaBoost?",answer:"You only need to install the extension in your browser and select which AI you want to use. The rest is automatic."},{question:"How do I get my Jira token?",answer:"You can generate a Jira token from your profile in Jira Cloud. Go to Settings > Security > Create and manage API tokens."},{question:"Does HakaBoost save my data on any server?",answer:"No, your data remains in your Jira instance. If you use local AI, everything is processed locally without sending information to external servers."},{question:"Can I use HakaBoost in any Jira project?",answer:"Yes, HakaBoost works with any Jira Cloud project. You just need to have access to that project."},{question:"What exactly does the 'Improve Description' button do?",answer:"The 'Improve Description' button uses AI to analyze your current user story and suggest improvements based on quality and testing best practices."}]},Vme={titulo:"What does it do?",descripcion:"Haka Buddy is a desktop application available for Windows and MAC OS that facilitates the creation of manual reports, reducing creation time by between 50% and 70%",features:["With Haka Buddy you can create test reports in an easy and simple way.","Add what you need and insert screenshots, json documents and more.","It's practical! You'll have a complete report in PDF format automatically when you finish a test."],caracteristicas:"Features",caracteristicasItems:["You can generate as many steps as you need.","Assign a status to each step.","Take full screen screenshots of your tests or custom screen.","Add or upload attachments at any step of the test.","You can include texts as a test step (Designed for APIs testing and DB).","When you generate the report you can choose between: PDF Report. Images in ZIP. JSON XRAY. All at the same time if you need it!"],beneficios:"Benefits",beneficiosDescripcion:"Speed up test creation in Jira by up to 97%",beneficiosItems:["Register your teams.","Register different environments.","You can load your last test data.","Regenerate any test report created before.","Download the images captured in a test.","You can download a JSON to create the test steps in Jira automatically.","Customize your reports: Upload custom covers and give identity to your reports.","Connection with JIRA. You can get user stories, upload reports automatically and more!"]},Hme={titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about Hakabuddy",items:[{question:"What is HakaBuddy and what is it for?",answer:"Haka Buddy is a desktop application designed to facilitate the creation of manual tests. It allows you to record step by step, status, test data, screenshots and other relevant details. When the test is finished, the application generates a complete report in PDF format."},{question:"How to create a test in Hakabuddy?",answer:"Creating a new test in Hakabuddy is simple, in the following video we will create a test following the basic options, from the initial information, step by step and export of the final file."},{question:"Can I customize the report covers?",answer:"Yes. You can customize all the covers of the PDF report, additionally in version 2.0, you can customize 100% of the HTML report"},{question:"What options do I have to export results?",answer:"The application offers you a variety of test results, including; the complete PDF report, the images you captured during the test (independently), a .JSON that can be used to import the results to XRAY manually, the ability to automatically record the results in JIRA (requires having an active connection to a JIRA board), and if you have an active connection to Jira and Xray, Hakabuddy allows you to create the manual test automatically in your board."},{question:"Can I connect with JIRA CLOUD?",answer:"Yes, with Hakabuddy you can connect to Jira, this will allow you to get the user stories from the configured jira board, upload reports and attach comments to the selected issues."},{question:"What type of evidence can I attach in a test report?",answer:"You can attach full screen screenshots, cropped and edited screenshots, jsons and attachments."},{question:"Does Hakabuddy store the reports?",answer:"Yes, Hakabuddy has its own history in which you can review all generated reports, images and additional files."},{question:"Is there a limit to the total number of reports I can create?",answer:"No, Hakabuddy has no limit on the number of reports you can create."},{question:"What additional functions does the 'Open own browser' option enable in Hakabuddy?",answer:"The own browser (based on playwright) allows you to record video of the test performed and capture full screen vertically."}]},Fme={titulo:"What does it do?",descripcion1:"HakaBoost is a HakaLab add-on specialized in Jira that allows you to accelerate the quality of task descriptions and easily create tests.",descripcion2:"Haka
17956Boost automatically reads the issue on screen, improves the description with AI (Cloud or Local), detects and creates Gherkin scenarios and creates Tests in Jira/Xray linked to the main story. All without leaving Jira.",features:["Allows you to download the history of generated Xpaths in up to 5 different file types.","Creates up to 4 Xpath locators automatically. Using a precise creation algorithm.","Keeps a history of up to 30 generated Xpaths for later consultation or reuse.","Allows you to convert Xpath to selenium code in up to 4 programming languages.","For each generated Xpath it automatically identifies the number of matching elements in the DOM."],caracteristicas:"Features",caracteristicasItems:["Web add-on. Integrates easily and natively in Google Chrome and Microsoft Edge.","Downloadable directly from Chrome Store.","Xpath construction using the Haka Lab methodology for creating effective locators.","Languages; Spanish and English.","Automatic review of html DOM for identifying matches."]},Bme={titulo:"What does it do?",features:["Allows you to export captured requests to a Postman collection.","Allows you to export a summary of requests to a CSV file.","Keeps a history of captured requests for later consultation or reuse.","Allows you to filter requests by URL."],caracteristicas:"Features",caracteristicasItems:["Network traffic capture up to 95% faster.","Multiple export options, allows you to choose between Postman and CSV.","Organization of requests by steps with a single click.","Request history, allows you to make groups of requests by page and export the document."]},Ume={titulo:"Haka RTC",descripcion1:"Designed for Chromium-based browsers, Haka RTC revolutionizes the way you capture REST traffic for your QA projects. With a few clicks, record requests from DevTools, organize them by steps and export to Postman or CSV to document and reuse scenarios quickly.",descripcion2:"Additionally, it incorporates dynamic filters and exclusion list to isolate own services and omit unauthorized third parties, along with history and repetition count that provide precision and accelerate tests (including stress tests). Free and ready to use in Chrome/Edge."},$me={titulo:"Haka Path is a valuable extension",descripcion1:"Specifically designed for web browsers that revolutionizes the way you generate XPaths for your test automation projects. With just two clicks, this tool allows you to create XPaths efficiently and effectively, significantly accelerating your workflow.",descripcion2:"One of the standout features of Haka Path is generating multiple XPath options and showing how many elements match in real time, providing greater precision, flexibility and time savings in creating locators for your automated tests."},Wme={hero:{descripcion:"The Revolution in Test Automation with Artificial Intelligence",exclusivo:"Exclusive to Haka Lab",cta:"Request Access"},presentacion:{titulo:"We transform how software testing is automated",subtitulo:"We apply Artificial Intelligence strategically to reduce test creation times and optimize processes",etapas:{automatizacion:{titulo:"Automation",descripcion:"Generates robust scripts automatically."},seguridad:{titulo:"Security",descripcion:"Information sent to AI is minimal and obfuscated to align with security and data governance laws."},ia:{titulo:"AI",descripcion:"AI handles the most costly processes of developing automated tests."},talento:{titulo:"Human Talent",descripcion:"Our Engineers supervise what AI creates, adjust and ensure security and functionality."},impacto:{titulo:"Real Impact",descripcion:"Between 70 and 80% reduction in automated test creation times."}}},potencia:{titulo:"Key Features",subtitulo:"Powered by Gemini AI to take your automation to the next level",grabacion:{titulo:"Smart Recording",descripcion:"Capture your interactions in real-time with two modes: Playwright (modern semantic selectors) and Selenium (optimized XPath with uniqueness validation)."},generacion:{titulo:"AI Generation",descripcion:"Gemini AI analyzes your recordings and generates Gherkin test cases, complete Python implementations, optimized Page Objects, and custom steps."},busqueda:{titulo:"Intelligent Vector Search",descripcion:"Embedding system that detects reusable steps, avoids code duplication, suggests best practices, and learns from your testing patterns."}
17956,chat:{titulo:"Interactive Chat with Kai",descripcion:"Integrated AI assistant that answers testing questions, helps refine test cases, suggests improvements, and explains generated code."},analisis:{titulo:"Reusability Analysis",descripcion:"Automatically detects repetitive step sequences, refactoring opportunities, common patterns, and duplicate code."},velocidad:{titulo:"Extreme Speed",descripcion:"Reduces test creation time by 70%. What took 2-4 hours now takes 15-30 minutes."}},queHace:{titulo:"Key Benefits",subtitulo:"Real impact on your automation process",reduccion:"Reduction in automated test creation time",beneficios:["Generates high-quality code","Reuses pre-existing steps","Progressive vectorization for real-time knowledge","Uses a high-quality standard","Frees QA Engineer for other quality tasks","Accelerates project launch","Reduces technical onboarding",'Thanks to its integrated AI chat "KAI" it solves scripting issues quickly']},comparativa:{titulo:"Traditional Automation vs Haka AI Studio",subtitulo:"Discover the difference AI makes in your workflow",aspecto:"Aspect",sinHaka:"Without Haka AI Studio",conHaka:"With Haka AI Studio",tabla:{tiempo:{aspecto:"Creation time",sin:"1 hour per test",con:"12-18 minutes"},seguridad:{aspecto:"Security",sin:"No control over what is sent to AI",con:"Automatic and customizable obfuscation of URLs, emails, domains"},selectores:{aspecto:"Selectors",sin:"Manually written, error-prone",con:"Automatically generated and validated"},reutilizacion:{aspecto:"Code reusability",sin:"Manual, requires search and analysis",con:"Automatic with vector search"},formato:{aspecto:"Test format",sin:"Direct Python code",con:"Readable Gherkin + implementation"},mantenimiento:{aspecto:"Maintenance",sin:"High - fragile selectors",con:"Low - optimized selectors"}},destacado:{titulo:"What used to take 1 hour, now takes 12-18 minutes",descripcion:"Between 70% and 80% reduction in test creation time"}},casosUso:{titulo:"Lean Mindset Applied to Processes",subtitulo:"Haka AI Studio joins Haka Lab's Power Ups to optimize processes and maximize ROI",frontEnd:{titulo:"Front End Testing",descripcion:"Allows building tests for any type of web application, no specifications required on how it was built."},backend:{titulo:"Backend Testing",descripcion:"Thanks to being optimized to work with Haka Automation Engines, it's possible to easily integrate backend tests or steps into created tests."},regresion:{titulo:"Regression Testing",descripcion:"Makes regression tests available in complete suites in an accelerated manner."},ayudante:{titulo:"QA Assistant",descripcion:"The internal KAI chat allows quality engineers to diagnose problems in their tests, make corrections and improve their robustness in seconds."},talento:{titulo:"AI at the Service of Talent",descripcion:"Haka AI Studio uses AI strategically, instead of asking it to build everything, we use its generative layer for intelligent orchestration, which keeps security at maximum."}},faq:{titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about Haka AI Studio",items:[{question:"What is Haka AI Studio?",answer:"Haka AI Studio is an exclusive Visual Studio Code extension that combines the power of artificial intelligence with test automation best practices. Record your browser interactions and automatically generate complete test cases in Gherkin/BDD format with ready-to-run implementations."},{question:"What frameworks does it support?",answer:"Haka AI Studio supports Playwright and Selenium, the two most popular web automation frameworks. You can record with one framework and generate code for the other."},{question:"Do I need advanced programming knowledge?",answer:"No. Haka AI Studio is designed so that anyone with basic knowledge can create quality automated tests. AI guides the entire process and generates code following best practices."},{question:"How does vector search work?",answer:"The vector search system analyzes your existing framework and automatically detects reusable steps. This avoids code duplication and ensures you follow established patterns in your project."},{question:"Can I customize the generated code?",answer:"Yes, completely. You can use Kai's chat to refine tests, add additional validations, or adjust any aspect of the generated code."},{question:"Is Haka AI Studio publicly available?",answer:"No, Haka AI Studio is an exclusive Haka Lab tool for our QA services. Contact your project leader to get access."},{question:"What do I need to use Haka AI Studio?",answer:"You need Visual Studio Code 1.85.0 or higher, Node.js 20.x or higher, a Gemini API Key (provided by Haka Lab), and Python 3.8+ to run the tests."},{question:"How much time do I really save?",answer:"On average, our clients report a 70% reduction in test creation time. What used to take 2-4 hours now takes 15-30 minutes."}]}},Gme={titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about HakaPath",items:[{question:"What should I do after installing HakaPath?",answer:"After installing the add-on, you need to pin the add-on to your browser from the add-ons menu in Google Chrome, then restart your browser. No additional actions are required beyond these two steps."},{question:"How to generate an xpath?",answer:'To generate an xpath, simply identify the web element you want to get the xpath from, right-click on it and select "Get Hakapath"'},{question:"What localization strategy does HakaPath use?",answer:"HakaPath uses a localization strategy based on xpath best practices. HakaPath automatically constructs the xpath according to the main components available in the clicked web element; id, name, class, etc."},{question:"How many xpaths can be generated?",answer:"HakaPath allows you to generate xpath unlimited. Each time you generate an xpath, up to 4 possible localization options are delivered (in the registered version of the add-on)."},{question:"What are the differences in the generated xpath results?",answer:"HakaPath generates up to 4 xpaths automatically (in the registered version) whose difference lies in the specialization of the localization strategy, thus offering different strategies such as: General localization using wildcard (*), Specific localization using web component tag, Second-order specific localization, adding the parent of the selected element, Third-order specific localization, trying to access the parent web element from a child."},{question:"What languages can generated xpaths be automatically converted to?",answer:"HakaPath allows you to convert generated xpaths to Selenium code to get a webElement, up to 4 languages are available in the configuration options; Python (default), Java, Javascript and C#."},{question:'HakaPath does not deliver xpaths, it stays in "waiting..." What should I do?',answer:'If you are using Google Chrome in mobile device view (size scaling) verify that the "Device toolbar" option is not active, as this option overlays a layer on the web to display mobile device tools which interferes with HakaPath.'},{question:"In what situations can HakaPath fail to deliver a correct result?",answer:"While in the vast majority of cases HakaPath will deliver exact locators, there may be cases where it is difficult to do so, this can originate from the way the website or application is designed, particularly in those where layers of components overlap one another."},{question:"How are XPath matches identified?",answer:"Hakapath automatically searches the HTML DOM for matches for each generated xpath just as it does when you manually enter an xpath in the browser inspector. Occasionally it may happen that no matches are found, this means that the xpath does not match any element in the DOM. We show it anyway in the list of generated Xpaths in case it is useful to use it as a basis to generate a much more specialized locator."},{question:"What is the purpose of identifying and counting elements that match the xpath?",answer:"This will allow you to know with certainty which is the most accurate xpath, plus knowing the number of matches will allow you to identify the type of strategy to use with your xpath when creating a particular web element or a list of them from selenium."}]},Kme={hero:{title:"We are specialists in",title2:"Software Quality",subtitle:"Experts in automated QA and testing who transform quality into a competitive advantage for your business.",cta:"Success stories",scheduleCall:"Let's talk about quality"},services:[{title:"Salesforce QA and Continuous Testing",description:"Our methodology and experience in testing allows us to ensure the quality of your Salesforce developments in multiple layers, accelerating time to market and saving costs in continuous quality assurance through automated regressions."},{title:"SAP QA and Functional Testing",description:"From the planning stage to final product implementation, we help our partners build with quality, reducing errors, improving product reliability and resilience, saving costs, and promoting continuous assurance through automated testing."},{title:"Continuous Performance",description:"Through different scalable strategies we prepare your ecosystem to successfully face high-demand events, delivering valuable information on the actual use of infrastru
17956cture and capabilities, allowing you to save costs in cloud infrastructure while guaranteeing a return on investment."},{title:"Continuous Data Testing",description:"We work on the specific challenges of data infrastructure, analysis and evaluation of the integrity, security and efficiency of data systems."}],methodology:{title:"Methodology",subtitle:"Our DNA: Quality + Innovation + Value Delivery.",description:"An agile, scalable methodology focused on measurable results.",bottomText:"We ensure software quality through different testing approaches, to guarantee the stability, reliability and operability of your products",steps:[{title:"Risk Detection",description:"We identify critical points"},{title:"Prioritization",description:"We focus efforts strategically"},{title:"Agile and automated execution",description:"We implement with speed"},{title:"Continuous feedback and scalability",description:"We improve constantly"}]},errorCost:{title:{before:'"The cost of an error after deployment is ',highlight:"10 times higher",after:' than preventing it."'},description:"Ignoring testing in early stages directly impacts the ROI of your investment, degrades the user experience, and breaks trust in your brand.",risks:["Critical errors discovered in production.","Loss of budget on reactive corrections.","Erosion of reputation and user loyalty."],impactTitle:"Business Impact",impacts:[{label:"Loss of Productivity",percentage:"+55%"},{label:"Accumulated Technical Debt",percentage:"+75%"}],disclaimer:"*Data based on health audits of Salesforce ecosystems pre-Haka Lab."},testimonials:{title:"Testimonials",subtitle:"What do our clients say?",items:[{text:`I especially highlight: 17957 17958The company's great commitment to supporting the organization in the challenges they have faced. A high level of technical and professional expertise in their teams delivering very good quality solutions. An incredible service vocation that is reflected in the quality of the services they provide. They really put the customer at the center.`,author:"Jesus Rodriguez",position:"CTO",company:"Sodimac"},{text:"Thanks to Haka Lab, we have been able to establish a robust and automated certification process in our Salesforce CRM platform, which has improved the time-to-market of our developments",author:"Francisco Rodriguez",position:"Subgerente CRM",company:"Consorcio"},{text:"The adaptation to the teams and constant support and commitment to the challenges posed stands out. Therefore I can perfectly recommend any service that Haka Lab can provide in the field of test automation.",author:"Humberto Proschle",position:"Technology Manager",company:"Casa Ideas"}]},clients:{title:"Our clients",description:"We work with leading companies in their industries, helping them achieve their technological objectives with innovative and quality solutions."},partners:{title:"Our partners"}},Jme={hero:{title:"Who are we?",subtitle:"At Haka Lab, we drive technological quality. With more than 7 years of experience, we collaborate with companies from various sectors â retail, banking, health and services â to guarantee technological solutions that align with their objectives and organizational culture.",cta:"Contact us"},identidad:{intro:"We believe that quality is born from human commitment, not just code. That's why our identity is also reflected in Koru and Kai, two characters that symbolize what drives us:"},koru:{descripcion:"Koru represents innovation and automation, always looking for new ways to create value."},kai:{descripcion:"Kai embodies collaboration and trust, the force that ensures that every delivery is accompanied by excellence."},haka:{conclusion:"Together, they do the haka: a dance that conveys unity, energy and shared purpose. This is how we work every day at Haka Lab: with passion, in community and always focused on generating Continuous Value Delivery."},caracteristicas:{esencia:{title:"Our Essence",description:"We are dedicated to continuously improving our processes and services, ensuring that each project exceeds expectations in quality and efficiency."},vision:{title:"Vision",description:"We aspire to positively impact our partners and clients, fostering a culture of innovation and continuous improvement."},mision:{title:"Mission",description:"We focus on offering technological solutions that provide sustainable value, backed by excellent service and a solid organizational culture."},compromiso:{title:"Commitment",description:"We are committed to driving the growth and success of our clients through innovative and high-quality technological solutions."}}
17958,redes:{titulo:"Follow Us on Our Social Networks",subtitulo:"Stay updated with our latest news and updates",verMasNoticias:"See more news"}},Qme={titulo:"Our Services",descripcion:"We offer comprehensive testing and quality solutions designed to ensure the excellence of your technological products. From functional testing to data analysis, we cover all stages of your development cycle.",contactanos:"Contact Us",servicesDescription:"Our services are designed to ensure quality, automation and scalability of your technological solutions.",agileCycle:{introText:"We integrate the quality vision in all stages of the software development lifecycle, making the process more efficient and reducing costs.",centerText:{line1:"Software Development",line2:"Lifecycle"},devStages:["Planning","Design","Development","Testing","Deploy","Review","Launch"],qaStages:[{label:"Analysis",fullName:"Analysis, preconditions and risks",description:"Detailed analysis of requirements, risk identification and establishment of preconditions to ensure quality from the start."},{label:"Test Design",fullName:"Test Design",description:"Detailed design of the test plan with strategies, test cases and acceptance criteria."},{label:"Construction",fullName:"Test Construction",description:"Construction and development of automated and manual tests according to the defined plan."},{label:"Execution",fullName:"Test Execution",description:"Execution of tests in different environments and scenarios to validate software quality."},{label:"Regression Verification (CI/CD)",fullName:"Testing in CI/CD",description:"Integration of tests in the CI/CD pipeline for continuous and automated validation."},{label:"Evaluation",fullName:"Results Evaluation",description:"Analysis of results, report generation and decision making based on quality metrics."},{label:"Measurement",fullName:"Production Indicators Measurement",description:"Measurement and analysis of key productivity and efficiency indicators of the testing process for continuous improvement."}]},performance:{title:"Continuous Performance",subtitle:"Our framework expands the traditional approach to performance testing by integrating Observability and continuous monitoring to ensure infrastru
17958cture and ecosystem preparation against any challenge.",cta:"Request a free demo",features:["Testing strategies that adapt to your business requirements.","Continuous improvement through constant test execution.","Focus on customer experience and business objectives.","Personalized and custom reporting.","Actively integrated process."]},continuos:{title:"Continuous Testing",subtitle:"Functional - Salesforce - SAP"},services:[{title:"Salesforce Testing",description:"We ensure product quality thanks to our specially developed and robust testing framework for Salesforce, optimizing certification times by creating parallel execution strategies, multiple combination scenarios, custom object identification, regression, and continuous integration to minimize the impact on business operations.",benefit:"Accelerate the time-to-market of your Salesforce projects by 70% with specialized testing",features:["Reduction of up to 70% in certification time.","Own Automation Framework.","Custom reporting and evidence","Multi-browser executions"]},{title:"Functional Testing",description:"We implement the highest quality standards throughout the entire software development lifecycle. From the planning stage to final product implementation, we provide technical and methodological support to teams in meeting their challenges, with a central focus on test automation and an integrated approach to the entire process.",benefit:"Reduce operational costs by up to 60% through intelligent automation and early error detection",features:["Parallel certification to reduce delivery by up to 80%.","Highly reusable automation.","Continuous quality strategies."]},{title:"SAP Testing",description:"We integrate legacy systems such as databases, OMS, APIs, IMS, and various e-commerce platforms through our test automation framework. We've also incorporated technologies like computer vision, peripheral control, and everything necessary to ensure effective validations that reduce risks and costs while maximizing benefits.",benefit:"Minimize risks in critical SAP implementations, protecting million-dollar investments",features:["Phased automation and short-term value delivery.","Reduction in certification time.","Customized Reporting."]}],data:{title:"Data Testing",subtitle:"We work on the specific challenges of data infrastructure, we delve into the analysis and evaluation of the integrity, security and efficiency of data systems. Additionally, we identify failures early and areas for improvement, ensuring the robustness and reliability of databases and information storage, optimizing information management and guaranteeing its security.",cta:"Request a free demo",features:["Reduction of up to 90% of time related to data testing processes.","Testing, analysis and evaluation.","Constant regressive executions.","Constant data consistency verification."]}},Xme={titulo2:"Discover our testing tools",hero:{title:"Strategic solutions for your",title2:" software quality",subtitle:"Simplify your quality processes with our tools powered by strategic Artificial Intelligence.",cta:"Request a free demo"},titulo:"Boost your QA and development work with our Haka tools",descripcion:"Simplify your daily tasks, reduce time and automate with intelligence.",hakaboost:{descripcion:"Speed up test creation in Jira by up to 97% with AI"},hakabuddy:{descripcion:"Create manual test reports in minutes, not hours"},hakapath:{descripcion:"Generate XPaths automatically with precision and speed"},hakatools:{descripcion:"Complete suite of tools for test automation"},hakartc:{descripcion:"Capture and export REST traffic for your API tests"}
17958,hakainsight:{descripcion:"Analyze your code and create simple explanations with interactive diagrams automatically"},hakaengine:{descripcion:"BDD test automation framework with Playwright, AI self-healing and 1800+ ready-to-use steps"},hakaaistudio:{descripcion:"Companion to accelerate test automation with our engine and artificial intelligence"},hakaistudio:{descripcion:"VS Code extension with AI that transforms recordings into complete automated tests"}},Yme={titulo:"Testing Cycle",descripcion:"Our products directly impact the different stages of the testing cycle, allowing us to accelerate processes and optimize quality assurance.",productoLabel:"Product:",entendido:"Got it",pasos:[`Planning 17959and analysis`,`Test case 17960design`,`Test 17961execution`,`Defect 17962reporting`,`Closure and 17963validation`,`Continuous 17964improvement`],descriptions:["We define clear quality objectives, identify risks and establish acceptance criteria. We analyze functional and non-functional requirements to ensure that every aspect of the software meets quality standards from the start.","We create exhaustive test scenarios that cover main flows, edge cases and exceptional situations. We design testing strategies that ensure complete code coverage and validation of all business requirements.","We implement robust and maintainable automation scripts. We configure test environments that replicate production and establish CI/CD pipelines to integrate testing at each stage of development, detecting defects early.","We execute functional, regression, performance and security tests automatically. We validate that each functionality operates correctly under different conditions and loads, ensuring system stability and reliability.","We analyze quality metrics, identify defect patterns and generate detailed reports. We provide complete visibility of the software quality status, facilitating informed decisions about the release.","We refine testing processes based on lessons learned. We optimize test coverage, reduce execution times and improve early defect detection. We implement feedback loops to continuously raise quality standards."],productDescriptions:{hakaboost:"Planning and analysis, Test case design",hakabuddy:"Test case design, Execution, Reporting, Analysis and visibility",hakapath:"Test execution",hakartc:"Test case design",hakainsight:"Analyze and understand your source code easily",hakaengine:"Functional test automation without coding",hakaaistudio:"Test automation with Artificial Intelligence"}},Zme={hero:{title:"Do your systems fail when you need them most?",subtitle:"At Haka Lab we solve those pains with technology, speed and real quality. See how companies like yours turned their challenges into success stories - with results in hours saved, bugs eliminated and happy customers.",btn:"Request a free evaluation"},desafioLabel:"Challenge:",solucionLabel:"Solution:",testimonioLabel:"Testimonial",qaLabel:"QA",cta:{titulo:"Want to achieve these results?",descripcion:"Schedule your free diagnosis and discover how we adapt our frameworks to your environment.",boton:"Request a free evaluation"},cases:{walmart:{company:"Walmart",title:"100% Uptime during Cyber Day",problem:"Challenge: Omnichannel operations required guaranteeing system stability during critical high-traffic events (such as launches and promotional campaigns), avoiding errors and production outages.",solution:"Solution: We implemented an E2E automation strategy focused on performance, integrating QMS, ecommerce, APIs, synthetic monitoring and computer vision on dynamic infrastructure.",results:[{metric:"100%",description:"We ensured 100% compliance with time to market, with no delays in key releases."},{metric:"65%",description:"We reduced critical incidents related to system performance by 65%."},{metric:"99.98%",description:"We enabled preventive alerts in real time, raising the availability of the digital ecosystem to 99.98%"}],qa:"We transformed QA into a strategic axis to anticipate risks and improve customer experience."},melt:{company:"Melt Pizzas",title:"Synthetic Monitoring",problem:"Melt Pizzas sought to ensure that its infrastru
17964cture could support the accelerated growth of its digital channels, especially in high-demand contexts.",solution:"We performed synthetic monitoring and performance testing to validate whether the current infrastructure could support expected growth. Strategic recommendations were issued based on load analysis and user experience.",results:[{description:"We established a permanent monitoring base that allows scaling without sacrificing quality or availability."},{description:"Customized reporting to present data obtained from tests, with charts to represent relevant KPIs to management."},{description:"Proactive validation of infrastructure response capacity."}]},consorcio:{company:"Consorcio",title:"CRM Salesforce",problem:"Slow manual certification process without traceability.",solution:"100% automation of Salesforce functional tests with execution from CI/CD.",results:[{description:"We reduced time to production by 70%."},{description:"We improved process visibility and eliminated technical debt in weeks."}],testimonial:{text:"Thanks to Haka Lab, we have been able to establish a robust and automated certification process on our Salesforce CRM platform, which has improved the time to market of our developments",author:"Francisco RodrÃguez",position:"Salesforce CRM Sub-Manager",company:"Implementation Leader"}},casaideas:{company:"Casa Ideas",title:"Automation of Ecommerce Flow and SAP and Magento integrations",problem:"Complex E2E flow difficult to certify which had multiple production errors.",solution:"We automated SAP Logon v760 together with the E2E of the purchase in the ecommerce and then validated that the data generated matched and arrived correctly to SAP, Magento, Omnix and Dbnet.",results:[{description:"Automation of comprehensive tests with SAP and legacy systems."},{description:"Test execution on automated virtual machines."}],testimonial:{text:"For the launch of our new e-commerce platform we decided to hire Haka Lab's services as they demonstrated a high degree of technical knowledge in the test automation process. The project achieved its objectives and stands out especially: - Innovation and technology management - Use of Methodologies - Support and accompaniment in the design and development of tests - Constant adaptation to change - Technical support and commitment. Additionally, the adaptation to the teams and constant support and commitment to the challenges posed stands out. Therefore, I can perfectly recommend any service that Haka Lab can provide in the field of test automation.",author:"Casa Ideas Team",position:"",company:"Casa Ideas"}},sodimac:{company:"Sodimac Homecenter",title:"Backoffice closing and reconciliation",problem:"Difficulty in the process and high times for closing and reconciliation of sales points.",solution:"We automated a critical process that previously took 8 hours and reduced it to just 70 minutes, overcoming complex technological barriers with legacy components (UXPOS, SAP, Control-M) and computer vision.",results:[{description:"Reduction of time for the manual Back office Closing and Reconciliation process from 8 hours to 70 minutes automated."},{description:"Automation of UXPOS, SAP and Control-M components"}],testimonial:{text:"The company's great commitment to supporting the organization in the challenges it has faced stands out especially. A high level of technical and professional expertise in its teams delivering very good quality solutions. An incredible vocation for service that is reflected in the quality of the services they provide. They really put the customer at the center.",author:"Jesús RodrÃguez",position:"CTO Sodimac",company:""}},scotiabank:{company:"Scotiabank",title:"Digital Factory",problem:"",solution:"We were pioneers in implementing a Continuous Testing and Delivery strategy in the Digital Factory of one of Chile's leading banking entities. We incorporated practices such as ATDD and BDD to align business with development and ensure quality from the first sprint. We took charge of the complete certification of the factory, integrating quality in all layers.",results:[{description:"Total certification of digital products in parallel with development."},{description:"Successful implementation of ATDD and BDD as the basis for QA maturity."},{description:"Reduction in delivery cycles thanks to Continuous Delivery."},{description:"We established a continuous quality model that remains in place today."}]},parquearauco:{company:"Parque Arauco",title:"SAP Hana to AWS Migration",problem:"Challenge: Parque Arauco faced the challenge of ensuring quality in a complex migration to AWS, involving multiple data layers, cloud services and critical business components.",solution:"Solution: We deployed our specialized automation framework for data certification, applying technologies such as Spark, Glue, Hyde, C3, Lambda and Python. We implemented regressive tests with a focus on traceability and end-to-e
17964nd integrity, actively integrating them with the client's teams with iterative deliveries and continuous feedback.",results:[{description:"Reduction in certification times thanks to constant regressions identifying errors early."},{description:"Own Automation Framework for data certifications with technologies such as Spark, Hyde, Glue, C3, Lambda, Python."}]}}},ehe={titulo:"Blog",titleFront:"HakaLab Blog",descripcion:"Articles about testing, software quality and test automation",leerMas:"Read More",verEnBlog:"View on Blog",articulosRelacionados:"Related Articles",volverAlBlog:"Back to Blog",buscar:"Search articles...",filtrarPorEtiqueta:"Filter by Tag",limpiarFiltros:"Clear Filters",noHayArticulos:"No published articles yet",noEncontrados:"No articles found with the selected filters",mostrando:"Showing",de:"of",articulos:"articles",vistas:"views",autor:"Author",creado:"Created",etiquetas:"Tags",por:"By"},the={title:"Schedule a Call",name:"Name",email:"Email",company:"Company",date:"Date",time:"Time",message:"Message (optional)",schedule:"Schedule",scheduling:"Scheduling...",cancel:"Cancel",success:"Call scheduled successfully!",successMessage:"We will send you a confirmation email",errorRequired:"Please fill in all required fields",noCalendarUrl:"Calendar is not configured",close:"Close",calendlyMessage:"Click the button to open the calendar and schedule your call",openCalendar:"Open Calendar"},ahe={title:"The Cost of Bugs in the Development Cycle",subtitle:"Cost of finding a bug in the software development lifecycle",message:"By integrating ourselves into your team, we accelerate bug detection to early stages",conclusion:"That saves money",ciclos:"Development Cycle",stages:[{label:"Planificación"},{label:"Design"},{label:"Coding"},{label:"Testing"},{label:"Production"}]},nhe={titulo:"Official Partner of",titulo2:"XRAY by Sembi",titulo3:"by Sembi",subtitulo:"We are official implementers of XRAY in Jira Cloud and specialists in its professional use to support software quality for our clients.",conversemos:"Let's talk about quality"},ihe={partners:"Strategic Partners",lideres:"Leaders in Salesforce Quality"},rhe={title:"Impact on ROI",title2:"Efficiency"},ohe={welcome:{title:"Haka Lab Quality Self-Assessment",subtitle:"Answer the following questions to measure the quality level you currently apply to your software development",email:"Email",emailPlaceholder:"[email protected]",company:"Company",companyPlaceholder:"Your company name",industry:"Industry",industryPlaceholder:"Select your industry",developmentType:"Development Type",developmentTypePlaceholder:"Select development type",startButton:"Start Assessment",requiredField:"This field is required",invalidEmail:"Email is not valid"},quiz:{progress:"Progress",question:"Question",of:"of",continueButton:"Continue",previousButton:"Previous",seeResultsButton:"See Results",allQuestionsRequired:"Please answer all questions before continuing"},rating:{never:"Never",rarely:"Rarely",sometimes:"Sometimes",frequently:"Frequently",always:"Always"},results:{title:"Your Results",yourScore:"Your Score",outOf:"out of",points:"points",maturityLevel:"Maturity Level",analysis:"Personalized Analysis",redFlags:"Identified Red Flags",noRedFlags:"Excellent! No critical red flags identified.",recommendations:"How can we help you?",recommendationsSubtitle:"Recommended services based on your assessment",contactButton:"Contact HakaLab",learnMore:"Learn more",highScoreMessage:"Congratulations! Your team has an established quality culture. We can help you optimize your processes even further.",savingResults:"Saving results...",resultsSaved:"Results saved successfully"},maturityLevels:{reactive:{name:"Reactive Quality",label:"Critical Level",diagnosis:"The team is firefighting. QA is a bottleneck at the end of the process with little visibility into production."},transition:{name:"Quality in Transition",label:"Medium Level",diagnosis:"Efforts exist (perhaps some unit tests or QA environments), but consistency and metrics for improvement are lacking."},advanced:{name:"Advanced Quality",label:"Pro Level",diagnosis:"The team has a quality culture. QA is integrated and there are metrics."}},redFlags:{silos:{title:"Silos Alert",message:"Your QA team is isolated; this generates rework and high correction costs."},production_risk:{title:"Production Risk Alert",message:"You are flying blind; you are not learning from your production errors."},technical_debt:{title:"Technical Debt Alert",message:"Your manual regression will become unsustainable soon. Automation is your next step."}},services:{qa_assessment:{name:"QA Assessment & Strategy",description:"We define processes from scratch, establish DOR/DOD and shift QA left."},test_automation:{name:"Test Automation",description:"We automate smoke and regression tests to free up time and improve c
17964onfidence."},continuous_testing:{name:"Continuous Testing",description:"We integrate tests into your CI/CD pipeline to detect problems early."},performance_testing:{name:"Performance Testing",description:"We optimize system load and ensure your application scales."},data_testing:{name:"Data Testing",description:"We validate the quality and accuracy of your data in pipelines and reports."},resource_optimization:{name:"Resource Optimization",description:"We optimize your existing QA processes to maximize efficiency and reduce costs."}},errors:{loadingQuestions:"Error loading questions",savingResults:"Error saving results",generic:"An error occurred. Please try again."}},she={hero:{badge:"Automation Engine",title:"Haka Automation Engine",titleHighlight:"Intelligence applied to quality",subtitle:"Our specialized automation engine integrates the best testing technologies to build automated tests up to 40% faster, reducing costs and ensuring continuous quality.",ctaContact:"Request Demo"},diagram:{title:"Engine Architecture",subtitle:"Based on our experience, we created a complete layered solution that optimizes every stage of the testing process.",layer1:{title:"Technology Base",description:"Selenium, Playwright, and Behave (Gherkin) for modern, stable, parallel-run testing"},layer2:{title:"Powered by Experience and AI",description:"It allows you to build tests for front-end, REST API, databases, and Gene AI at high speed."},layer3:{title:"Native Integrations",description:"Direct connection with Jira, Xray, Zephyr, and Grafana for real-time results"},layer4:{title:"Automatic Reports",description:"Automatically generated HTML/Video reports along with tests to facilitate monitoring, indicator review, and complete traceability"},layer5:{title:"CI/CD Ready",description:"Prepared for continuous integration and deployment pipelines"},note:"Our products drive the engine to streamline the process, maximize quality, and reduce the costs of building and running tests."},aiTesting:{badge:"Testing Innovation",title:"AI-Powered Engine",subtitle:"Our engine is prepared to test applications using Generative AI, through advanced semantic analysis and RAG (Retrieval-Augmented Generation) strategies.",innovationBadge:"Innovation",features:{genAI:{title:"Generative AI Testing",description:"Specialized validation for applications that use GEN AI to generate interactions or responses to their users"},semantic:{title:"Semantic Analysis",description:"Intelligent evaluation of the meaning and context of AI-generated responses, saving costs associated with external validators"},rag:{title:"RAG Strategies",description:"Testing systems that combine information retrieval with content generation using different validation strategies and quantitative analysis of results"},validation:{title:"Quality Validation",description:"Verification of accuracy, consistency, and relevance in AI responses in alignment with the client's technological and business expectations"}},stat:{label:"Ready for the future",value:"Gen AI",description:"Specialized testing for the new era of intelligent applications"},diagram:{input:{title:"User Input",description:"Query or prompt"}
17964,genAI:{title:"Generative AI",description:"Processing + RAG"},output:{title:"Generated Response",description:"AI Content"},testing:{title:"Haka Automation Engine",description:"Semantic Validation"}}},comparison:{title:"Efficiency Comparison",subtitle:"Discover how Haka Automation Engine accelerates your testing process, optimizes resources, maximizes efficiency, and saves costs.",traditional:{badge:"Traditional Method",title:"Without Specialized Engine",description:"Manual construction of each test component",point1:"Development from scratch",point2:"Longer implementation time",point3:"High resource costs"},hakalab:{badge:"With Hakalab",title:"Haka Automation Engine",description:"Pre-built and optimized components",point1:"1500+ ready-to-use steps",point2:"Accelerated implementation",point3:"Significant cost reduction"},savings:"Less development time"},benefits:{title:"Key Benefits",subtitle:"Why Haka Automation Engine makes the difference",speed:{title:"Optimized Speed",description:"Reduce test construction time by up to 40% with pre-built components"},coverage:{title:"Maximized Coverage",description:"Tests across all layers: front-end, API REST, databases and Gen AI"},continuous:{title:"Continuous Quality",description:"CI/CD integration for automatic regressions and immediate feedback"},reports:{title:"Robust Reports",description:"Automatic documentation with evidence, metrics and complete traceability"},integrations:{title:"Native Integrations",description:"Direct connection with Jira, Xray, Zephyr and Grafana without complex configuration"},cost:{title:"Cost Savings",description:"Resource optimization and time reduction translates into real savings"}},technologies:{title:"Integrated Technologies",subtitle:"A complete ecosystem of industry-leading tools",products:{title:"Hakalab Products Included",description:"All our products are designed to work with the engine and accelerate your testing"}},cta:{badge:"Start Now",demoTitle:"Automated Execution Demo",demoSubtitle:"Watch how Haka Automation Engine executes automated tests in real-time",videoLoading:"Loading video...",videoLoadingSubtitle:"Please wait a few seconds",title:"Ready to accelerate your testing?",description:"Schedule a personalized demo and discover how Haka Automation Engine can transform your QA process",scheduleDemo:"Schedule Demo",contact:"Contact",stat1:"Less time",stat2:"Pre-built steps",stat3:"Automatable"}},lhe={hero:{badge:"Comprehensive Framework",title:"HakaLab Framework",titleHighlight:"People + Methodology + Technologies",subtitle:"Working together to ensure the quality of your products",ctaContact:"Request Demo"},pillars:{title:"HakaLab Framework",subtitle:"Our solution focuses on three fundamental pillars that work in synergy, learning and continuous improvement",people:{title:"People",description:"We drive operational efficiency through a comprehensive quality strategy. We apply Shift-Left Testing to anticipate defects and reduce technical debt from the beginning of the project to production deployment."},methodology:{title:"Methodological Framework",description:"We implement quality practices throughout the software development lifecycle using industry best practices."},technology:{title:"Technological Framework",description:"We use our own technological solution built on the most robust testing and automation tools available today, powered by AI and our experience."}},methodology:{title:"Methodological Framework",subtitle:"We implement quality practices throughout the development cycle through agile methodologies and continuous improvement",quote:"We integrate the Haka Lab methodological framework according to the client's needs and capabilities in an evolutionary model of continuous improvement, value and constant return on investment.",author:"MatÃas Carrasco",authorRole:"CEO Haka Lab"},technology:{subtitle:"Robust technologies powered by our engineers' expertise",techTitle:"Technology Stack",aiPowered:"AI Powered",differentiator:{title:"What sets us apart?",description:"It's not just about using the best tools, it's how our engineers master them to accelerate processes, reduce costs and maximize quality. We power every project with our Haka products."},powerups:{title:"Haka Power-Ups",description:"Our proprietary products that multiply the efficiency of the technology framework:"},cta:"Learn about Haka Automation Engine",tools:{selenium:"Web browser automation",playwright:"Modern web application testing",cucumber:"BDD framework with Gherkin",python:"Language for testing scripts",jenkins:"CI/CD automation",docker:"Containers for consistent environments",github:"Version control and collaboration",jira:"Project management and tracking",xray:"Test case management in Jira",grafana:"Metrics visualization and dashboards",html:"Automated HTML reports",apirest:"REST API testing",bbdd:"Database testing",front:"Frontend interface testing",chrome:"Browser for automated testing",appium:"Mobile app automation"}}},che={titulo:"Terms and Conditions of Use",ultimaActualizacion:"Last updated",definiciones:{titulo:"Definitions"},aceptacion:{titulo:"Acceptance of Terms"},licencia:{titulo:"License to Use"},restricciones:{titulo:"Usage Restrictions"},actualizaciones:{titulo:"Updates and Changes to Services"},privacidad:{titulo:"Privacy and Data Protection"},limitacion:{titulo:"Limitation of Liability"},terminacion:{titulo:"Termination"},legislacion:{titulo:"Applicable Law"},modificaciones:{titulo:"Modifications to Terms"},politicaPrivacidad:{titulo:"Haka Lab Privacy Policy",informacion:{titulo:"Information We Collect"},finalidades:{titulo:"Processing Purposes"},baseLegal:{titulo:"Legal Basis and Consent"},transferencia:{titulo:"Data Transfer and Sharing"},seguridad:{titulo:"Information Security"},derechos:{titulo:"Your Rights"},cambios:{titulo:"Changes to this Policy"},contacto:{titulo:"Contact"}}},dhe={titulo:"Frequently Asked Questions about QA and Testing",subt
17964itulo:"Get answers about Quality Assurance services, test automation, and how we can help your business.",items:[{question:"What is QA and why is it important for my company?",answer:"QA (Quality Assurance) is the process that ensures your software works correctly before it reaches your customers.",details:["Without QA, production bugs generate direct financial losses and damage your brand reputation.","Investing in quality from the start reduces operational costs and accelerates delivery timelines.","At HakaLab we have over 10 years of experience helping companies in Chile turn quality into a competitive advantage."],highlight:"over 10 years"},{question:"What QA services does HakaLab offer?",answer:"We offer a comprehensive quality assurance model covering the entire software lifecycle:",details:["Test automation to accelerate releases and reduce delivery times.","Performance testing to ensure availability during critical high-demand moments.","Quality certification for Salesforce and SAP implementations.","Strategic consulting to optimize testing processes and mature teams.","Data validation to ensure the integrity of your information."],highlight:"entire software lifecycle"},{question:"What sets HakaLab apart from other QA companies in Chile?",answer:"Three pillars differentiate us:",details:["Adaptive capability: we integrate into the client's ecosystem without imposing technologies, adapting processes to their business context.","Over 7 proprietary AI-powered products that accelerate quality processes and generate unique efficiencies in the market.","A methodology proven over 10+ years + highly specialized talent = measurable results that directly impact ROI."],highlight:"70% acceleration in delivery cycles"},{question:"How can test automation reduce costs?",answer:"A bug detected in production costs up to 10 times more than preventing it in early stages.",details:["Reduces validation time by up to 80% per delivery.","Frees your team for higher strategic value tasks.","Accelerates time-to-market for new features.","Ensures continuous quality without repetitive manual effort."],highlight:"80% validation time"},{question:"What is HakaLab's technological capability?",answer:"We have a broad and flexible technology ecosystem that adapts to each client:",details:["Industry-leading tools for automation, performance, and continuous integration.","Over 7 proprietary AI products: automation engines, quality copilot, smart reports, and code analysis.","We integrate with the client's existing ecosystems to enhance team capacity without friction."],highlight:"over 7 proprietary products"},{question:"Do you work with companies of any size?",answer:"Yes. Our model adapts to the size and maturity of each organization:",details:["Early-stage startups that need to build a quality strategy from scratch.","Growing mid-size companies looking to scale and professionalize their testing processes.","Fortune 500 corporations that need to optimize and automate QA operations at scale."],highlight:"Fortune 500"},{question:"How long does it take to see results with HakaLab?",answer:"Initial results are visible within the first 2-4 weeks:",details:["Our proprietary automation engine implements solutions up to 40% faster than traditional approaches.","From the first sprint, incremental value deliveries are generated.","Our engine is prepared to test AI-powered applications, positioning us as long-term partners for your tech evolution."],highlight:"40% faster"}]},uhe={header:Ame,nav:Eme,contactModal:Cme,trabajaModal:jme,relatedProducts:Tme,hakaboost:Nme,hakabuddy:Ime,descargaExitoModal:Pme,common:Rme,footer:Lme,cargando:Ome,hakapath:Mme,hakartc:Dme,ctaNewsletter:qme,faq:zme,hakabuddy_queHace:Vme,hakabuddy_faq:Hme,hakapath_queHace:Fme,hakartc_queHace:Bme,potencia_hakartc:Ume,potencia_hakapath:$me,hakaistudio:Wme,hakapath_faq:Gme,home:Kme,nosotros:Jme,servicios:Qme,productos:Xme,cicloTesting:Yme,casosExito:Zme,blog:ehe,scheduleModal:the,bugCostCycle:ahe,partners:nhe,badges:ihe,roibox:rhe,quickAnalysis:ohe,hakaAutomationEngine:she,frameworkHakalab:lhe,terminos:che,faqServicios:dhe},phe={es:{translation:_me},en:{translation:uhe}};wa.use(yH).init({resources:phe,lng:localStorage.getItem("language")||"es",fallbackLng:"es",interpolation:{escapeValue:!1}});xx.createRoot(document.getElementById("root")).render(s.jsx(Re.StrictMode,{children:s.jsx(fP,{children:s.jsx(Dpe,{})})}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.