{"version":3,"mappings":"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","names":["piniaInstance","createPinia","subscribedEvents","broadcastUnsubscribeAllEvents","meetingHub","sEvent","broadcastEmitEvent","eventName","data","FIMenuPaymentAmount","init","window","factory","module","this","jStat","Math","undefined","concat","slice","toString","calcRdx","n","m","val","isArray","arg","isFunction","isNumber","num","toVector","arr","args","i","fn","obj","j","index","submat","ind","column","a","nrow","res","row","objArr","rows","cols","func","toAlter","ncol","col","retZero","retOne","retIdent","size","min","max","length","hival","step","current","cnt","start","end","rl","_slice","list","rcSlice","colSlice","rowSlice","A","B","nl","ml","diagArray","mat","t","jProto","funcs","passfunc","self","results","ascNum","b","clip","sum","mean","tmp","prod","low","high","hash","_arr","logs","meanOfLogs","arrlen","diffs","arrLen","distinctNumbers","numberCounts","number","sortedDistinctNumbers","numberRanks","currentRank","count","first","last","rank","maxCount","numMaxCount","mode_arr","flag","sumsqerr","samples","dev","median","quantilesArray","alphap","betap","sortedArray","quantileVals","p","aleph","k","gamma","exclusive","realIndex","frac","score","kind","counter","len","strict","value","binCnt","binWidth","bins","arr1","arr2","u","v","arr1Len","sq_dev","mu","sigma","skewSum","fullbool","tmpthis","callbackFunction","argsToPass","curriedFunction","vector","x","cof","ser","xx","y","x0","x2","xp","gl","gl0","q","fact","xden","xnum","z","yi","aln","ap","del","ITMAX","an","fpmin","qab","qap","qam","c","d","m2","aa","h","a1","EPS","gln","err","pp","lna1","afac","isneg","dd","ty","b1","lna","lnb","al","w","bt","shape","oalph","a2","f","newthis","vals","fnfunc","alpha","beta","df1","df2","x1","local","scale","dof","rate","ncp","tol","min_iterations","flip","prob","lastvalue","std","dof2","betinc","eps","a0","b0","m9","c9","betacdf","s","N","scaledPDF","samplesDone","scaledCDF","factor","l","sumarr","L","lam","U","V","slam","loglam","invalpha","vr","us","laplaceSign","tukeyWprob","rr","cc","nleg","ihalf","C1","C2","C3","bb","wlar","wincr1","wincr2","xleg","aleg","qsqz","pr_w","wincr","blb","binc","bub","einsum","cc1","wi","elsum","jj","ac","qexpo","pplus","pminus","rinsum","tukeyQinv","p0","q0","p1","q1","p2","q2","p3","q3","p4","q4","c1","c2","c3","c4","c5","vmax","ps","nmeans","df","nlegq","ihalfq","eps1","eps2","dhaf","dquar","deigh","dlarg","ulen1","ulen2","ulen3","ulen4","xlegq","alegq","f2","f2lf","f21","ff4","ulen","ans","otsum","twa1","t1","wprb","rotsum","maxiter","valx0","valx1","iter","xabs","push","isUsable","nrescols","rescols","left","right","nnorm","newarr","result","det","determinant","submatrix","sign","maug","pivot","temp","y2","maxrow","parts","matrix_mode","R","T","r","xv","xk","range","qr2","R_I","I","Aj","cAi","Ij","cIi","qr_solve","array_mode","QR","Q","attrs","Q1","R1","RI","Q2","condition","e","ev","maxim","theta","t_j","u_j","order","k1","k2","u_j1","k3","k4","h1","g","X","pos","h_min","y1","F","dF","dl","temp1","D","temp2","Y","Bt","Vt","sides","zscore","tscore","expVar","sample","sampMean","sampSampMean","tmpargs","unexpVar","anovafscore","fscore","mean1","mean2","n1","n2","sd","qscore","arrays","means","change","pvalue","differenceOfProportions","pooled","se","sub_regress","exog","var_count","modelList","endog_index","exog_index","ols","endog","nobs","df_model","df_resid","coef","predict","resid","ybar","SSE","SSR","SST","R2","t_test","model","subModelList","sigmaHat","seBetaHat","mod","tStatistic","pValue","leftppf","interval95","F_test","F_statistic","fcdf","ols_wrap","ttest","ftest","adjust_R2","matrixRows","array","jMat","pass","jMatX","jMatY","innerinv","xtransp","next","compile","jMatYBar","yAverage","covar","sds","ts","inner","yBar","ssr","sse","sst","exports","BESSEL","M","_horner","_bessel_iter","f0","f1","tdx","o","_bessel_wrap","bessel0","bessel1","name","nonzero","besselj","W","b0_a1a","b0_a2a","b0_a1b","b0_a2b","b1_a1a","b1_a2a","b1_a1b","b1_a2b","ret","jsum","bjp","bj","bjm","tox","bessely","besseli","b0_a","b0_b","b1_a","b1_b","bip","bi","bim","besselk","div0","na","argsToArray","arrayEach","iteratee","flatten","argument","isArrayLike","isFlat","flattenShallow","aIsArray","bIsArray","anyError","anyIsError","parseNumber","string","parseNumberArray","parsed","BINOM","number_s","trials","probability_s","cumulative","number_s2","COMBIN","CHISQ","deg_freedom","probability","actual_range","expected_range","xsqr","Pi","ChiSq","deg_freedom1","deg_freedom2","array1","array2","sumOfSquares","values","SUM","sum1","sum2","NORM","standard_dev","mean_x","mean_y","s_x","s_y","CEILING","significance","mode","anyError$1","precision","ROUND","number_chosen","FACT","MEMOIZED_FACT","num_digits","inner_result","PMT","nper","pv","fv","type","term","PERIODS_YEARS","financials","amount","residualPercent","residualDollars","util","floatAmount","floatPercent","adjCap","residual","pvRes","mf","lenderCode","apr","moneyFactor","msrp","payment","intTerm","floatResidual","floatMsrp","floatMoneyFactor","capCost","residualValue","oddDays","monthlyPayment","floatApr","floatPrincipal","intOdd","balloonAmount","rateAsPercentage","termWithoutFinalPayment","presentValueResidual","state","preDocsStamps","newTotal","postDocStamps","decimalPoints","multiplier","baseAmount","tax","dp","FIMenuLeaseTerm","cttf","dealType","otd","stateTaxRate","countyTaxRate","baseLeasePayment","stateTax","countyTax","buyrateBaseLeasePayment","stateTaxAtBuyRate","countyTaxAtBuyRate","adjustedCapCost","vehicleValue","sellrate","FIMenuLeaseTerms","fimenu","t1BuyRateMax","t2BuyRateMax","t3BuyRateMax","residualMin","required","minValue","maxValue","FIMenuLoanTerm","selectedDaysToFirstPayment","maxDaysToFirstPayment","isBalloon","financePayment","DealType","financePaymentAtBuyRate","balloonValidationMessage","FIMenuLoanTerms","helpers","requiredIf","currency2","prettyDate","moment","prettyDateTime","prettyNumber","decimals","filters","FIMenuVehicleWarrantyCoverage","vehicleMiles","retVal","warrantyStartDate","inventoryType","valid","overMiles","overTerm","FIMenuVehicleWarranty","vinResponse","carFax","FIMenuForCustomerMeeting","fimenuCustomer","fimenuLender","_sfc_main","$modal","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","$options","$data","_createBlock","_resolveDynamicComponent","_normalizeProps","_mergeProps","$props","_createCommentVNode","Modal","_Fragment","_renderList","_component_Modal","$meetingHub","inject","meetingHelper","MeetingHubBus","EventBus","$route","useRoute","$router","useRouter","userStore","useUserStore","ref","isUserInDev","computed","settings","onMounted","ENUMS","onBeforeUnmount","languageChangedHandler","triggerCustomerActionHandler","registerCustomerViewedHandler","EventBusCore","toastrEmitterHandler","handleBeforeClosePage","notifData","title","duration","text","notify","updatePreferredCoverageHandler","ct","updateLoanDaysToPaymentHandler","days","redirectTo","address","language","action","fimenuStringified","updatedFimenuForCustomerInstance","customerViewedInfo","FIMenuCustomerViewed","_resolveComponent","_normalizeClass","$setup","_createVNode","_component_router_view","_component_notifications","router","createRouter","createWebHistory","__vitePreload","ApplicationsSettingsLoader","to","from","localStorageId","queryId","generatedLink","CustomerHelper","error","SaturnGlobalPlugin","StaticViewsPlugin","Static","app","$static","$global","reactive","$grid","colTemplate","gap","templateValues","columnTemplate","gapOutside","newGapOutside","HttpError","errorMessage","statusCode","trueProto","TimeoutError","AbortError","UnsupportedTransportError","message","transport","DisabledTransportError","FailedToStartTransportError","FailedToNegotiateWithServerError","AggregateErrors","innerErrors","HttpResponse","statusText","content","HttpClient","url","options","LogLevel","NullLogger","_logLevel","_message","VERSION","Arg","Platform","getDataDetail","includeContent","detail","isArrayBuffer","formatArrayBuffer","view","str","pad","sendMessage","logger","transportName","httpClient","headers","getUserAgentHeader","responseType","response","createLogger","ConsoleLogger","SubjectSubscription","subject","observer","_","minimumLogLevel","logLevel","msg","userAgentHeaderName","constructUserAgent","getOsName","getRuntime","getRuntimeVersion","version","os","runtime","runtimeVersion","userAgent","majorAndMinor","getErrorString","getGlobalThis","FetchHttpClient","requireFunc","request","abortController","timeoutId","msTimeout","deserializeContent","payload","cookies","XhrHttpClient","resolve","reject","xhr","header","DefaultHttpClient","TextMessageFormat","output","input","messages","HandshakeProtocol","handshakeRequest","messageData","remainingData","binaryData","separatorIndex","responseLength","textData","MessageType","Subject","item","MessageBuffer","protocol","connection","bufferSize","serializedMessage","backpressurePromise","backpressurePromiseResolver","backpressurePromiseRejector","BufferedItem","ackMessage","newestAckedMessage","element","currentId","sequenceId","id","resolver","rejector","DEFAULT_TIMEOUT_IN_MS","DEFAULT_PING_INTERVAL_IN_MS","DEFAULT_STATEFUL_RECONNECT_BUFFER_SIZE","HubConnectionState","HubConnection","reconnectPolicy","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","statefulReconnectBufferSize","handshakePromise","startPromise","methodName","streams","streamIds","invocationDescriptor","promiseQueue","cancelInvocation","invocationEvent","sendPromise","newMethod","method","handlers","removeIdx","callback","responseMessage","nextPing","invocationMessage","methods","methodsCopy","expectsResponse","exception","completionMessage","prevRes","reconnectStartTime","previousReconnectAttempts","retryError","nextRetryDelay","previousRetryCount","elapsedMilliseconds","retryReason","callbacks","key","nonblocking","invocationId","streamId","DEFAULT_RETRY_DELAYS_IN_MILLISECONDS","DefaultReconnectPolicy","retryDelays","retryContext","HeaderNames","AccessTokenHttpClient","innerClient","accessTokenFactory","allowRetry","HttpTransportType","TransferFormat","AbortController$1","LongPollingTransport","AbortController","transferFormat","pollOptions","pollUrl","deleteOptions","logMessage","ServerSentEventsTransport","accessToken","opened","eventSource","WebSocketTransport","logMessageContent","webSocketConstructor","token","webSocket","_event","event","MAX_REDIRECTS","HttpConnection","webSocketModule","eventSourceModule","TransportSendQueue","negotiateResponse","redirects","negotiateUrl","connectionToken","requestedTransport","requestedTransferFormat","connectUrl","transportExceptions","transports","negotiate","endpoint","transportOrError","ex","callStop","useStatefulReconnect","transportMatches","aTag","searchParams","actualTransport","_transport","PromiseSource","transportResult","arrayBuffers","totalLength","offset","reason","JSON_HUB_PROTOCOL_NAME","JsonHubProtocol","hubMessages","parsedMessage","LogLevelNameMapping","parseLogLevel","mapping","HubConnectionBuilder","logging","isLogger","transportTypeOrOptions","retryDelaysOrReconnectPolicy","milliseconds","httpConnectionOptions","MeetingHub","connectionId","myConnectionId","role","isInStoreConnection","meetingRoomCode","currentMeetingDetails","viewedType","viewedDateTime","videosSeen","sellRate","buyRate","updatedMeetingParticipants","doc","newSecureRoom","document","customerScreenData","metadata","time","volumeLevel","path","signatureInfo","pdfIndex","isOpen","userId","accessKey","signal","playerConnectedCode","playerId","cardObject","page","JSONStringPlayer","JSONStringBash","pageThis$router","codes","code","dealNumber","storeCode","dif","tempStoreCode","startedPromise","scrollData","fimenuDealId","firstName","lastName","fullName","meetingUser","oldCode","customerAction","shouldMeetingEnd","videoId","videoData","resendMessageHandler","retries","timeout","waitForRetry","nextDelay","signer","docInfo","LogRocket","missingPdfList","isMuted","who","signature","initials","signatureId","initialsId","docIndex","endTime","latestTimeStamp","blob","groupId","MeetingInfo","MeetingHelper","globalProperties","encodeMeetingCode","decodeMeetingCode","newDealNumber","initiateMeeting","auth","createMeeting","meetingObject","api","startRemoteMeeting","meetingCurrentlyOpen","allowUserIntoMeeting","userToAllow","sendLinkToMeetingRoomParticipant","meetingInvitation","failMessage","sendMethod","participantEmail","participantCell","participantFirstName","participantLastName","participantFullName","dealershipName","fimanagerName","meetingLinkInfo","encodedLinkInfo","sendEmailLinkRequest","sendTextMsgLinkRequest","emailSubject","emailBody","textBody","emailResponse","textResponse","startInStoreMeeting","inStoreConnectionCode","fimanagerConnectToSecureRoom","meetingRoomJoinSuccessHandler","user","CUSTOMER_VIEWS","updateMeetingHubParticipantsHandler","disconnectParticipant","customerDisconnectedHandler","usersLeftInRoom","endMeeting","usersToSendToLobby","userToDisconnect","fimanagerDisconnect","fimanagerResetHelper","customerMoveToSecureRoomHandler","customerConnectToSecureRoom","inStore","requestToBePresenter","userRequestingToPresentHandler","grantRequestToBePresenter","userToGrantRequest","customerMeetingRoomJoinSuccessHandler","customerFinishMeetingHandler","customerResetHelper","reconnectedMeetingHubHandler","dealId","createApp","App","eventBus","mitt","Notifications","route","decryptedId","customerId","subdomain","sb"],"ignoreList":[3,4,5,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"sources":["../../../vue-core/stores/pinia-instance.ts","../../../vue-core/helpers/broadcast-helper.js","../../../vue-core/classes/FIMenuPaymentAmount.ts","../../../node_modules/jstat/dist/jstat.js","../../../node_modules/bessel/bessel.js","../../../node_modules/@formulajs/formulajs/lib/esm/index.mjs","../../../vue-core/services/financials.ts","../../../vue-core/classes/FIMenuLeaseTerm.ts","../../../vue-core/classes/FIMenuLeaseTerms.ts","../../../vue-core/classes/FIMenuLoanTerm.ts","../../../vue-core/classes/FIMenuLoanTerms.ts","../../../vue-core/services/filters.ts","../../../vue-core/classes/FIMenuVehicleWarrantyCoverage.js","../../../vue-core/classes/FIMenuVehicleWarranty.ts","../../../vue-core/classes/FIMenuForCustomerMeeting.ts","../../../vue-core/components/Modal.vue","../../../vue-core/components/ModalManager.vue","../../../customer-app/src/App.vue","../../../customer-app/src/router.ts","../../../vue-core/classes/StaticClasses.ts","../../../vue-core/plugins/static.ts","../../../node_modules/@microsoft/signalr/dist/esm/Errors.js","../../../node_modules/@microsoft/signalr/dist/esm/HttpClient.js","../../../node_modules/@microsoft/signalr/dist/esm/ILogger.js","../../../node_modules/@microsoft/signalr/dist/esm/Loggers.js","../../../node_modules/@microsoft/signalr/dist/esm/Utils.js","../../../node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js","../../../node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js","../../../node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js","../../../node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js","../../../node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js","../../../node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js","../../../node_modules/@microsoft/signalr/dist/esm/Subject.js","../../../node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js","../../../node_modules/@microsoft/signalr/dist/esm/HubConnection.js","../../../node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js","../../../node_modules/@microsoft/signalr/dist/esm/HeaderNames.js","../../../node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js","../../../node_modules/@microsoft/signalr/dist/esm/ITransport.js","../../../node_modules/@microsoft/signalr/dist/esm/AbortController.js","../../../node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js","../../../node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js","../../../node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js","../../../node_modules/@microsoft/signalr/dist/esm/HttpConnection.js","../../../node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js","../../../node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js","../../../vue-core/plugins/meetingHub.js","../../../vue-core/classes/MeetingInfo.js","../../../vue-core/plugins/MeetingHelper.ts","../../../customer-app/src/main.ts"],"sourcesContent":["import { createPinia } from \"pinia\";\r\n\r\nexport const piniaInstance = createPinia();","import $modal from \"@core/services/modal\"\r\nimport modalBroadcastMessages from \"@core/modals/modalBroadcastMessages.vue\"\r\nimport ENUMS from \"@core/classes/Enums\"\r\n\r\nlet subscribedEvents = []\r\n\r\nexport const broadcastSubscribeEvents = (meetingHub, subscribeTo) => {\r\n subscribeTo.map(subscribe => {\r\n meetingHub.subscribeToGroupEvent(subscribe.event, 'Broadcast', subscribe.callback)\r\n subscribedEvents.push(subscribe.event)\r\n })\r\n}\r\n\r\nexport const broadcastUnsubscribeEvents = (meetingHub, subscribeTo) => {\r\n subscribeTo.map(subscribe => {\r\n meetingHub.unsubscribeToGroupEvent(subscribe.event)\r\n\r\n subscribedEvents = subscribedEvents.filter(sEvent => sEvent !== subscribe.event)\r\n })\r\n}\r\n\r\nexport const broadcastUnsubscribeAllEvents = (meetingHub) => {\r\n subscribedEvents.map(sEvent => {\r\n meetingHub.unsubscribeToGroupEvent(sEvent)\r\n })\r\n subscribedEvents = []\r\n}\r\n\r\nexport const broadcastEmitEvent = (meetingHub, eventName, data) => {\r\n meetingHub.broadcastGroupEvent(eventName, 'Broadcast', data)\r\n}\r\n\r\nexport const broadcastCallbacks = {\r\n openModalBroadcastMessages: (data) => {\r\n $modal.open(modalBroadcastMessages, { name: 'modalBroadcastMessages', passedData: { data: JSON.parse(data) }, backdrop: true });\r\n }\r\n}\r\n\r\n","import CoverageTerm from \"./CoverageTerm\";\r\nimport FIMenuLeaseTerm from \"./FIMenuLeaseTerm\";\r\nimport FIMenuLoanTerm from \"./FIMenuLoanTerm\";\r\n\r\nexport interface IFIMenuPaymentAmount {\r\n amountFinanced?: number;\r\n buyRate?: number;\r\n coverageTerm?: number;\r\n dealTerm?: FIMenuLoanTerm | FIMenuLeaseTerm;\r\n paymentAtBuyRate?: number;\r\n paymentAtBuyRateWithTax?: number;\r\n paymentAtSellRate?: number;\r\n paymentAtSellRateWithTax?: number;\r\n reserveProfitFlat?: number;\r\n reserveProfitSplit?: number;\r\n sellRate?: number;\r\n}\r\n\r\nexport default class FIMenuPaymentAmount {\r\n amountFinanced?: number = null;\r\n buyRate?: number = null;\r\n coverageTerm?: number = null;\r\n dealTerm?: FIMenuLoanTerm | FIMenuLeaseTerm = null;\r\n paymentAtBuyRate?: number = null;\r\n paymentAtBuyRateWithTax?: number = null;\r\n paymentAtSellRate?: number = null;\r\n paymentAtSellRateWithTax?: number = null;\r\n reserveProfitFlat?: number = null;\r\n reserveProfitSplit?: number = null;\r\n sellRate?: number = null;\r\n\r\n constructor(init?: IFIMenuPaymentAmount) {\r\n\r\n if (init) {\r\n this.amountFinanced = init.amountFinanced;\r\n this.dealTerm = init.dealTerm;\r\n this.coverageTerm = init.coverageTerm;\r\n this.sellRate = this.isValidRate(init);\r\n this.paymentAtSellRate = init.paymentAtSellRate;\r\n this.paymentAtSellRateWithTax = init.paymentAtSellRateWithTax;\r\n this.buyRate = init.buyRate;\r\n this.paymentAtBuyRate = init.paymentAtBuyRate;\r\n this.paymentAtBuyRateWithTax = init.paymentAtBuyRateWithTax;\r\n this.reserveProfitFlat = init.reserveProfitFlat;\r\n this.reserveProfitSplit = init.reserveProfitSplit;\r\n }\r\n }\r\n /// if rate does not meet validation results in zero for reserve profit\r\n isValidRate(init: IFIMenuPaymentAmount) {\r\n return init.sellRate >= init.buyRate ? init.sellRate : init.buyRate;\r\n }\r\n}","(function (window, factory) {\n if (typeof exports === 'object') {\n module.exports = factory();\n } else if (typeof define === 'function' && define.amd) {\n define(factory);\n } else {\n window.jStat = factory();\n }\n})(this, function () {\nvar jStat = (function(Math, undefined) {\n\n// For quick reference.\nvar concat = Array.prototype.concat;\nvar slice = Array.prototype.slice;\nvar toString = Object.prototype.toString;\n\n// Calculate correction for IEEE error\n// TODO: This calculation can be improved.\nfunction calcRdx(n, m) {\n var val = n > m ? n : m;\n return Math.pow(10,\n 17 - ~~(Math.log(((val > 0) ? val : -val)) * Math.LOG10E));\n}\n\n\nvar isArray = Array.isArray || function isArray(arg) {\n return toString.call(arg) === '[object Array]';\n};\n\n\nfunction isFunction(arg) {\n return toString.call(arg) === '[object Function]';\n}\n\n\nfunction isNumber(num) {\n return (typeof num === 'number') ? num - num === 0 : false;\n}\n\n\n// Converts the jStat matrix to vector.\nfunction toVector(arr) {\n return concat.apply([], arr);\n}\n\n\n// The one and only jStat constructor.\nfunction jStat() {\n return new jStat._init(arguments);\n}\n\n\n// TODO: Remove after all references in src files have been removed.\njStat.fn = jStat.prototype;\n\n\n// By separating the initializer from the constructor it's easier to handle\n// always returning a new instance whether \"new\" was used or not.\njStat._init = function _init(args) {\n // If first argument is an array, must be vector or matrix.\n if (isArray(args[0])) {\n // Check if matrix.\n if (isArray(args[0][0])) {\n // See if a mapping function was also passed.\n if (isFunction(args[1]))\n args[0] = jStat.map(args[0], args[1]);\n // Iterate over each is faster than this.push.apply(this, args[0].\n for (var i = 0; i < args[0].length; i++)\n this[i] = args[0][i];\n this.length = args[0].length;\n\n // Otherwise must be a vector.\n } else {\n this[0] = isFunction(args[1]) ? jStat.map(args[0], args[1]) : args[0];\n this.length = 1;\n }\n\n // If first argument is number, assume creation of sequence.\n } else if (isNumber(args[0])) {\n this[0] = jStat.seq.apply(null, args);\n this.length = 1;\n\n // Handle case when jStat object is passed to jStat.\n } else if (args[0] instanceof jStat) {\n // Duplicate the object and pass it back.\n return jStat(args[0].toArray());\n\n // Unexpected argument value, return empty jStat object.\n // TODO: This is strange behavior. Shouldn't this throw or some such to let\n // the user know they had bad arguments?\n } else {\n this[0] = [];\n this.length = 1;\n }\n\n return this;\n};\njStat._init.prototype = jStat.prototype;\njStat._init.constructor = jStat;\n\n\n// Utility functions.\n// TODO: for internal use only?\njStat.utils = {\n calcRdx: calcRdx,\n isArray: isArray,\n isFunction: isFunction,\n isNumber: isNumber,\n toVector: toVector\n};\n\n\njStat._random_fn = Math.random;\njStat.setRandom = function setRandom(fn) {\n if (typeof fn !== 'function')\n throw new TypeError('fn is not a function');\n jStat._random_fn = fn;\n};\n\n\n// Easily extend the jStat object.\n// TODO: is this seriously necessary?\njStat.extend = function extend(obj) {\n var i, j;\n\n if (arguments.length === 1) {\n for (j in obj)\n jStat[j] = obj[j];\n return this;\n }\n\n for (i = 1; i < arguments.length; i++) {\n for (j in arguments[i])\n obj[j] = arguments[i][j];\n }\n\n return obj;\n};\n\n\n// Returns the number of rows in the matrix.\njStat.rows = function rows(arr) {\n return arr.length || 1;\n};\n\n\n// Returns the number of columns in the matrix.\njStat.cols = function cols(arr) {\n return arr[0].length || 1;\n};\n\n\n// Returns the dimensions of the object { rows: i, cols: j }\njStat.dimensions = function dimensions(arr) {\n return {\n rows: jStat.rows(arr),\n cols: jStat.cols(arr)\n };\n};\n\n\n// Returns a specified row as a vector or return a sub matrix by pick some rows\njStat.row = function row(arr, index) {\n if (isArray(index)) {\n return index.map(function(i) {\n return jStat.row(arr, i);\n })\n }\n return arr[index];\n};\n\n\n// return row as array\n// rowa([[1,2],[3,4]],0) -> [1,2]\njStat.rowa = function rowa(arr, i) {\n return jStat.row(arr, i);\n};\n\n\n// Returns the specified column as a vector or return a sub matrix by pick some\n// columns\njStat.col = function col(arr, index) {\n if (isArray(index)) {\n var submat = jStat.arange(arr.length).map(function() {\n return new Array(index.length);\n });\n index.forEach(function(ind, i){\n jStat.arange(arr.length).forEach(function(j) {\n submat[j][i] = arr[j][ind];\n });\n });\n return submat;\n }\n var column = new Array(arr.length);\n for (var i = 0; i < arr.length; i++)\n column[i] = [arr[i][index]];\n return column;\n};\n\n\n// return column as array\n// cola([[1,2],[3,4]],0) -> [1,3]\njStat.cola = function cola(arr, i) {\n return jStat.col(arr, i).map(function(a){ return a[0] });\n};\n\n\n// Returns the diagonal of the matrix\njStat.diag = function diag(arr) {\n var nrow = jStat.rows(arr);\n var res = new Array(nrow);\n for (var row = 0; row < nrow; row++)\n res[row] = [arr[row][row]];\n return res;\n};\n\n\n// Returns the anti-diagonal of the matrix\njStat.antidiag = function antidiag(arr) {\n var nrow = jStat.rows(arr) - 1;\n var res = new Array(nrow);\n for (var i = 0; nrow >= 0; nrow--, i++)\n res[i] = [arr[i][nrow]];\n return res;\n};\n\n// Transpose a matrix or array.\njStat.transpose = function transpose(arr) {\n var obj = [];\n var objArr, rows, cols, j, i;\n\n // Make sure arr is in matrix format.\n if (!isArray(arr[0]))\n arr = [arr];\n\n rows = arr.length;\n cols = arr[0].length;\n\n for (i = 0; i < cols; i++) {\n objArr = new Array(rows);\n for (j = 0; j < rows; j++)\n objArr[j] = arr[j][i];\n obj.push(objArr);\n }\n\n // If obj is vector, return only single array.\n return obj.length === 1 ? obj[0] : obj;\n};\n\n\n// Map a function to an array or array of arrays.\n// \"toAlter\" is an internal variable.\njStat.map = function map(arr, func, toAlter) {\n var row, nrow, ncol, res, col;\n\n if (!isArray(arr[0]))\n arr = [arr];\n\n nrow = arr.length;\n ncol = arr[0].length;\n res = toAlter ? arr : new Array(nrow);\n\n for (row = 0; row < nrow; row++) {\n // if the row doesn't exist, create it\n if (!res[row])\n res[row] = new Array(ncol);\n for (col = 0; col < ncol; col++)\n res[row][col] = func(arr[row][col], row, col);\n }\n\n return res.length === 1 ? res[0] : res;\n};\n\n\n// Cumulatively combine the elements of an array or array of arrays using a function.\njStat.cumreduce = function cumreduce(arr, func, toAlter) {\n var row, nrow, ncol, res, col;\n\n if (!isArray(arr[0]))\n arr = [arr];\n\n nrow = arr.length;\n ncol = arr[0].length;\n res = toAlter ? arr : new Array(nrow);\n\n for (row = 0; row < nrow; row++) {\n // if the row doesn't exist, create it\n if (!res[row])\n res[row] = new Array(ncol);\n if (ncol > 0)\n res[row][0] = arr[row][0];\n for (col = 1; col < ncol; col++)\n res[row][col] = func(res[row][col-1], arr[row][col]);\n }\n return res.length === 1 ? res[0] : res;\n};\n\n\n// Destructively alter an array.\njStat.alter = function alter(arr, func) {\n return jStat.map(arr, func, true);\n};\n\n\n// Generate a rows x cols matrix according to the supplied function.\njStat.create = function create(rows, cols, func) {\n var res = new Array(rows);\n var i, j;\n\n if (isFunction(cols)) {\n func = cols;\n cols = rows;\n }\n\n for (i = 0; i < rows; i++) {\n res[i] = new Array(cols);\n for (j = 0; j < cols; j++)\n res[i][j] = func(i, j);\n }\n\n return res;\n};\n\n\nfunction retZero() { return 0; }\n\n\n// Generate a rows x cols matrix of zeros.\njStat.zeros = function zeros(rows, cols) {\n if (!isNumber(cols))\n cols = rows;\n return jStat.create(rows, cols, retZero);\n};\n\n\nfunction retOne() { return 1; }\n\n\n// Generate a rows x cols matrix of ones.\njStat.ones = function ones(rows, cols) {\n if (!isNumber(cols))\n cols = rows;\n return jStat.create(rows, cols, retOne);\n};\n\n\n// Generate a rows x cols matrix of uniformly random numbers.\njStat.rand = function rand(rows, cols) {\n if (!isNumber(cols))\n cols = rows;\n return jStat.create(rows, cols, jStat._random_fn);\n};\n\n\nfunction retIdent(i, j) { return i === j ? 1 : 0; }\n\n\n// Generate an identity matrix of size row x cols.\njStat.identity = function identity(rows, cols) {\n if (!isNumber(cols))\n cols = rows;\n return jStat.create(rows, cols, retIdent);\n};\n\n\n// Tests whether a matrix is symmetric\njStat.symmetric = function symmetric(arr) {\n var size = arr.length;\n var row, col;\n\n if (arr.length !== arr[0].length)\n return false;\n\n for (row = 0; row < size; row++) {\n for (col = 0; col < size; col++)\n if (arr[col][row] !== arr[row][col])\n return false;\n }\n\n return true;\n};\n\n\n// Set all values to zero.\njStat.clear = function clear(arr) {\n return jStat.alter(arr, retZero);\n};\n\n\n// Generate sequence.\njStat.seq = function seq(min, max, length, func) {\n if (!isFunction(func))\n func = false;\n\n var arr = [];\n var hival = calcRdx(min, max);\n var step = (max * hival - min * hival) / ((length - 1) * hival);\n var current = min;\n var cnt;\n\n // Current is assigned using a technique to compensate for IEEE error.\n // TODO: Needs better implementation.\n for (cnt = 0;\n current <= max && cnt < length;\n cnt++, current = (min * hival + step * hival * cnt) / hival) {\n arr.push((func ? func(current, cnt) : current));\n }\n\n return arr;\n};\n\n\n// arange(5) -> [0,1,2,3,4]\n// arange(1,5) -> [1,2,3,4]\n// arange(5,1,-1) -> [5,4,3,2]\njStat.arange = function arange(start, end, step) {\n var rl = [];\n var i;\n step = step || 1;\n if (end === undefined) {\n end = start;\n start = 0;\n }\n if (start === end || step === 0) {\n return [];\n }\n if (start < end && step < 0) {\n return [];\n }\n if (start > end && step > 0) {\n return [];\n }\n if (step > 0) {\n for (i = start; i < end; i += step) {\n rl.push(i);\n }\n } else {\n for (i = start; i > end; i += step) {\n rl.push(i);\n }\n }\n return rl;\n};\n\n\n// A=[[1,2,3],[4,5,6],[7,8,9]]\n// slice(A,{row:{end:2},col:{start:1}}) -> [[2,3],[5,6]]\n// slice(A,1,{start:1}) -> [5,6]\n// as numpy code A[:2,1:]\njStat.slice = (function(){\n function _slice(list, start, end, step) {\n // note it's not equal to range.map mode it's a bug\n var i;\n var rl = [];\n var length = list.length;\n if (start === undefined && end === undefined && step === undefined) {\n return jStat.copy(list);\n }\n\n start = start || 0;\n end = end || list.length;\n start = start >= 0 ? start : length + start;\n end = end >= 0 ? end : length + end;\n step = step || 1;\n if (start === end || step === 0) {\n return [];\n }\n if (start < end && step < 0) {\n return [];\n }\n if (start > end && step > 0) {\n return [];\n }\n if (step > 0) {\n for (i = start; i < end; i += step) {\n rl.push(list[i]);\n }\n } else {\n for (i = start; i > end;i += step) {\n rl.push(list[i]);\n }\n }\n return rl;\n }\n\n function slice(list, rcSlice) {\n var colSlice, rowSlice;\n rcSlice = rcSlice || {};\n if (isNumber(rcSlice.row)) {\n if (isNumber(rcSlice.col))\n return list[rcSlice.row][rcSlice.col];\n var row = jStat.rowa(list, rcSlice.row);\n colSlice = rcSlice.col || {};\n return _slice(row, colSlice.start, colSlice.end, colSlice.step);\n }\n\n if (isNumber(rcSlice.col)) {\n var col = jStat.cola(list, rcSlice.col);\n rowSlice = rcSlice.row || {};\n return _slice(col, rowSlice.start, rowSlice.end, rowSlice.step);\n }\n\n rowSlice = rcSlice.row || {};\n colSlice = rcSlice.col || {};\n var rows = _slice(list, rowSlice.start, rowSlice.end, rowSlice.step);\n return rows.map(function(row) {\n return _slice(row, colSlice.start, colSlice.end, colSlice.step);\n });\n }\n\n return slice;\n}());\n\n\n// A=[[1,2,3],[4,5,6],[7,8,9]]\n// sliceAssign(A,{row:{start:1},col:{start:1}},[[0,0],[0,0]])\n// A=[[1,2,3],[4,0,0],[7,0,0]]\njStat.sliceAssign = function sliceAssign(A, rcSlice, B) {\n var nl, ml;\n if (isNumber(rcSlice.row)) {\n if (isNumber(rcSlice.col))\n return A[rcSlice.row][rcSlice.col] = B;\n rcSlice.col = rcSlice.col || {};\n rcSlice.col.start = rcSlice.col.start || 0;\n rcSlice.col.end = rcSlice.col.end || A[0].length;\n rcSlice.col.step = rcSlice.col.step || 1;\n nl = jStat.arange(rcSlice.col.start,\n Math.min(A.length, rcSlice.col.end),\n rcSlice.col.step);\n var m = rcSlice.row;\n nl.forEach(function(n, i) {\n A[m][n] = B[i];\n });\n return A;\n }\n\n if (isNumber(rcSlice.col)) {\n rcSlice.row = rcSlice.row || {};\n rcSlice.row.start = rcSlice.row.start || 0;\n rcSlice.row.end = rcSlice.row.end || A.length;\n rcSlice.row.step = rcSlice.row.step || 1;\n ml = jStat.arange(rcSlice.row.start,\n Math.min(A[0].length, rcSlice.row.end),\n rcSlice.row.step);\n var n = rcSlice.col;\n ml.forEach(function(m, j) {\n A[m][n] = B[j];\n });\n return A;\n }\n\n if (B[0].length === undefined) {\n B = [B];\n }\n rcSlice.row.start = rcSlice.row.start || 0;\n rcSlice.row.end = rcSlice.row.end || A.length;\n rcSlice.row.step = rcSlice.row.step || 1;\n rcSlice.col.start = rcSlice.col.start || 0;\n rcSlice.col.end = rcSlice.col.end || A[0].length;\n rcSlice.col.step = rcSlice.col.step || 1;\n ml = jStat.arange(rcSlice.row.start,\n Math.min(A.length, rcSlice.row.end),\n rcSlice.row.step);\n nl = jStat.arange(rcSlice.col.start,\n Math.min(A[0].length, rcSlice.col.end),\n rcSlice.col.step);\n ml.forEach(function(m, i) {\n nl.forEach(function(n, j) {\n A[m][n] = B[i][j];\n });\n });\n return A;\n};\n\n\n// [1,2,3] ->\n// [[1,0,0],[0,2,0],[0,0,3]]\njStat.diagonal = function diagonal(diagArray) {\n var mat = jStat.zeros(diagArray.length, diagArray.length);\n diagArray.forEach(function(t, i) {\n mat[i][i] = t;\n });\n return mat;\n};\n\n\n// return copy of A\njStat.copy = function copy(A) {\n return A.map(function(row) {\n if (isNumber(row))\n return row;\n return row.map(function(t) {\n return t;\n });\n });\n};\n\n\n// TODO: Go over this entire implementation. Seems a tragic waste of resources\n// doing all this work. Instead, and while ugly, use new Function() to generate\n// a custom function for each static method.\n\n// Quick reference.\nvar jProto = jStat.prototype;\n\n// Default length.\njProto.length = 0;\n\n// For internal use only.\n// TODO: Check if they're actually used, and if they are then rename them\n// to _*\njProto.push = Array.prototype.push;\njProto.sort = Array.prototype.sort;\njProto.splice = Array.prototype.splice;\njProto.slice = Array.prototype.slice;\n\n\n// Return a clean array.\njProto.toArray = function toArray() {\n return this.length > 1 ? slice.call(this) : slice.call(this)[0];\n};\n\n\n// Map a function to a matrix or vector.\njProto.map = function map(func, toAlter) {\n return jStat(jStat.map(this, func, toAlter));\n};\n\n\n// Cumulatively combine the elements of a matrix or vector using a function.\njProto.cumreduce = function cumreduce(func, toAlter) {\n return jStat(jStat.cumreduce(this, func, toAlter));\n};\n\n\n// Destructively alter an array.\njProto.alter = function alter(func) {\n jStat.alter(this, func);\n return this;\n};\n\n\n// Extend prototype with methods that have no argument.\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jProto[passfunc] = function(func) {\n var self = this,\n results;\n // Check for callback.\n if (func) {\n setTimeout(function() {\n func.call(self, jProto[passfunc].call(self));\n });\n return this;\n }\n results = jStat[passfunc](this);\n return isArray(results) ? jStat(results) : results;\n };\n })(funcs[i]);\n})('transpose clear symmetric rows cols dimensions diag antidiag'.split(' '));\n\n\n// Extend prototype with methods that have one argument.\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jProto[passfunc] = function(index, func) {\n var self = this;\n // check for callback\n if (func) {\n setTimeout(function() {\n func.call(self, jProto[passfunc].call(self, index));\n });\n return this;\n }\n return jStat(jStat[passfunc](this, index));\n };\n })(funcs[i]);\n})('row col'.split(' '));\n\n\n// Extend prototype with simple shortcut methods.\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jProto[passfunc] = function() {\n return jStat(jStat[passfunc].apply(null, arguments));\n };\n })(funcs[i]);\n})('create zeros ones rand identity'.split(' '));\n\n\n// Exposing jStat.\nreturn jStat;\n\n}(Math));\n(function(jStat, Math) {\n\nvar isFunction = jStat.utils.isFunction;\n\n// Ascending functions for sort\nfunction ascNum(a, b) { return a - b; }\n\nfunction clip(arg, min, max) {\n return Math.max(min, Math.min(arg, max));\n}\n\n\n// sum of an array\njStat.sum = function sum(arr) {\n var sum = 0;\n var i = arr.length;\n while (--i >= 0)\n sum += arr[i];\n return sum;\n};\n\n\n// sum squared\njStat.sumsqrd = function sumsqrd(arr) {\n var sum = 0;\n var i = arr.length;\n while (--i >= 0)\n sum += arr[i] * arr[i];\n return sum;\n};\n\n\n// sum of squared errors of prediction (SSE)\njStat.sumsqerr = function sumsqerr(arr) {\n var mean = jStat.mean(arr);\n var sum = 0;\n var i = arr.length;\n var tmp;\n while (--i >= 0) {\n tmp = arr[i] - mean;\n sum += tmp * tmp;\n }\n return sum;\n};\n\n// sum of an array in each row\njStat.sumrow = function sumrow(arr) {\n var sum = 0;\n var i = arr.length;\n while (--i >= 0)\n sum += arr[i];\n return sum;\n};\n\n// product of an array\njStat.product = function product(arr) {\n var prod = 1;\n var i = arr.length;\n while (--i >= 0)\n prod *= arr[i];\n return prod;\n};\n\n\n// minimum value of an array\njStat.min = function min(arr) {\n var low = arr[0];\n var i = 0;\n while (++i < arr.length)\n if (arr[i] < low)\n low = arr[i];\n return low;\n};\n\n\n// maximum value of an array\njStat.max = function max(arr) {\n var high = arr[0];\n var i = 0;\n while (++i < arr.length)\n if (arr[i] > high)\n high = arr[i];\n return high;\n};\n\n\n// unique values of an array\njStat.unique = function unique(arr) {\n var hash = {}, _arr = [];\n for(var i = 0; i < arr.length; i++) {\n if (!hash[arr[i]]) {\n hash[arr[i]] = true;\n _arr.push(arr[i]);\n }\n }\n return _arr;\n};\n\n\n// mean value of an array\njStat.mean = function mean(arr) {\n return jStat.sum(arr) / arr.length;\n};\n\n\n// mean squared error (MSE)\njStat.meansqerr = function meansqerr(arr) {\n return jStat.sumsqerr(arr) / arr.length;\n};\n\n\n// geometric mean of an array\njStat.geomean = function geomean(arr) {\n var logs = arr.map(Math.log)\n var meanOfLogs = jStat.mean(logs)\n return Math.exp(meanOfLogs)\n};\n\n\n// median of an array\njStat.median = function median(arr) {\n var arrlen = arr.length;\n var _arr = arr.slice().sort(ascNum);\n // check if array is even or odd, then return the appropriate\n return !(arrlen & 1)\n ? (_arr[(arrlen / 2) - 1 ] + _arr[(arrlen / 2)]) / 2\n : _arr[(arrlen / 2) | 0 ];\n};\n\n\n// cumulative sum of an array\njStat.cumsum = function cumsum(arr) {\n return jStat.cumreduce(arr, function (a, b) { return a + b; });\n};\n\n\n// cumulative product of an array\njStat.cumprod = function cumprod(arr) {\n return jStat.cumreduce(arr, function (a, b) { return a * b; });\n};\n\n\n// successive differences of a sequence\njStat.diff = function diff(arr) {\n var diffs = [];\n var arrLen = arr.length;\n var i;\n for (i = 1; i < arrLen; i++)\n diffs.push(arr[i] - arr[i - 1]);\n return diffs;\n};\n\n\n// ranks of an array\njStat.rank = function (arr) {\n var i;\n var distinctNumbers = [];\n var numberCounts = {};\n for (i = 0; i < arr.length; i++) {\n var number = arr[i];\n if (numberCounts[number]) {\n numberCounts[number]++;\n } else {\n numberCounts[number] = 1;\n distinctNumbers.push(number);\n }\n }\n\n var sortedDistinctNumbers = distinctNumbers.sort(ascNum);\n var numberRanks = {};\n var currentRank = 1;\n for (i = 0; i < sortedDistinctNumbers.length; i++) {\n var number = sortedDistinctNumbers[i];\n var count = numberCounts[number];\n var first = currentRank;\n var last = currentRank + count - 1;\n var rank = (first + last) / 2;\n numberRanks[number] = rank;\n currentRank += count;\n }\n\n return arr.map(function (number) {\n return numberRanks[number];\n });\n};\n\n\n// mode of an array\n// if there are multiple modes of an array, return all of them\n// is this the appropriate way of handling it?\njStat.mode = function mode(arr) {\n var arrLen = arr.length;\n var _arr = arr.slice().sort(ascNum);\n var count = 1;\n var maxCount = 0;\n var numMaxCount = 0;\n var mode_arr = [];\n var i;\n\n for (i = 0; i < arrLen; i++) {\n if (_arr[i] === _arr[i + 1]) {\n count++;\n } else {\n if (count > maxCount) {\n mode_arr = [_arr[i]];\n maxCount = count;\n numMaxCount = 0;\n }\n // are there multiple max counts\n else if (count === maxCount) {\n mode_arr.push(_arr[i]);\n numMaxCount++;\n }\n // resetting count for new value in array\n count = 1;\n }\n }\n\n return numMaxCount === 0 ? mode_arr[0] : mode_arr;\n};\n\n\n// range of an array\njStat.range = function range(arr) {\n return jStat.max(arr) - jStat.min(arr);\n};\n\n// variance of an array\n// flag = true indicates sample instead of population\njStat.variance = function variance(arr, flag) {\n return jStat.sumsqerr(arr) / (arr.length - (flag ? 1 : 0));\n};\n\n// pooled variance of an array of arrays\njStat.pooledvariance = function pooledvariance(arr) {\n var sumsqerr = arr.reduce(function (a, samples) {return a + jStat.sumsqerr(samples);}, 0);\n var count = arr.reduce(function (a, samples) {return a + samples.length;}, 0);\n return sumsqerr / (count - arr.length);\n};\n\n// deviation of an array\njStat.deviation = function (arr) {\n var mean = jStat.mean(arr);\n var arrlen = arr.length;\n var dev = new Array(arrlen);\n for (var i = 0; i < arrlen; i++) {\n dev[i] = arr[i] - mean;\n }\n return dev;\n};\n\n// standard deviation of an array\n// flag = true indicates sample instead of population\njStat.stdev = function stdev(arr, flag) {\n return Math.sqrt(jStat.variance(arr, flag));\n};\n\n// pooled standard deviation of an array of arrays\njStat.pooledstdev = function pooledstdev(arr) {\n return Math.sqrt(jStat.pooledvariance(arr));\n};\n\n// mean deviation (mean absolute deviation) of an array\njStat.meandev = function meandev(arr) {\n var mean = jStat.mean(arr);\n var a = [];\n for (var i = arr.length - 1; i >= 0; i--) {\n a.push(Math.abs(arr[i] - mean));\n }\n return jStat.mean(a);\n};\n\n\n// median deviation (median absolute deviation) of an array\njStat.meddev = function meddev(arr) {\n var median = jStat.median(arr);\n var a = [];\n for (var i = arr.length - 1; i >= 0; i--) {\n a.push(Math.abs(arr[i] - median));\n }\n return jStat.median(a);\n};\n\n\n// coefficient of variation\njStat.coeffvar = function coeffvar(arr) {\n return jStat.stdev(arr) / jStat.mean(arr);\n};\n\n\n// quartiles of an array\njStat.quartiles = function quartiles(arr) {\n var arrlen = arr.length;\n var _arr = arr.slice().sort(ascNum);\n return [\n _arr[ Math.round((arrlen) / 4) - 1 ],\n _arr[ Math.round((arrlen) / 2) - 1 ],\n _arr[ Math.round((arrlen) * 3 / 4) - 1 ]\n ];\n};\n\n\n// Arbitary quantiles of an array. Direct port of the scipy.stats\n// implementation by Pierre GF Gerard-Marchant.\njStat.quantiles = function quantiles(arr, quantilesArray, alphap, betap) {\n var sortedArray = arr.slice().sort(ascNum);\n var quantileVals = [quantilesArray.length];\n var n = arr.length;\n var i, p, m, aleph, k, gamma;\n\n if (typeof alphap === 'undefined')\n alphap = 3 / 8;\n if (typeof betap === 'undefined')\n betap = 3 / 8;\n\n for (i = 0; i < quantilesArray.length; i++) {\n p = quantilesArray[i];\n m = alphap + p * (1 - alphap - betap);\n aleph = n * p + m;\n k = Math.floor(clip(aleph, 1, n - 1));\n gamma = clip(aleph - k, 0, 1);\n quantileVals[i] = (1 - gamma) * sortedArray[k - 1] + gamma * sortedArray[k];\n }\n\n return quantileVals;\n};\n\n// Return the k-th percentile of values in a range, where k is in the range 0..1, inclusive.\n// Passing true for the exclusive parameter excludes both endpoints of the range.\njStat.percentile = function percentile(arr, k, exclusive) {\n var _arr = arr.slice().sort(ascNum);\n var realIndex = k * (_arr.length + (exclusive ? 1 : -1)) + (exclusive ? 0 : 1);\n var index = parseInt(realIndex);\n var frac = realIndex - index;\n if (index + 1 < _arr.length) {\n return _arr[index - 1] + frac * (_arr[index] - _arr[index - 1]);\n } else {\n return _arr[index - 1];\n }\n}\n\n// The percentile rank of score in a given array. Returns the percentage\n// of all values in the input array that are less than (kind='strict') or\n// less or equal than (kind='weak') score. Default is weak.\njStat.percentileOfScore = function percentileOfScore(arr, score, kind) {\n var counter = 0;\n var len = arr.length;\n var strict = false;\n var value, i;\n\n if (kind === 'strict')\n strict = true;\n\n for (i = 0; i < len; i++) {\n value = arr[i];\n if ((strict && value < score) ||\n (!strict && value <= score)) {\n counter++;\n }\n }\n\n return counter / len;\n};\n\n\n// Histogram (bin count) data\njStat.histogram = function histogram(arr, binCnt) {\n binCnt = binCnt || 4;\n var first = jStat.min(arr);\n var binWidth = (jStat.max(arr) - first) / binCnt;\n var len = arr.length;\n var bins = [];\n var i;\n\n for (i = 0; i < binCnt; i++)\n bins[i] = 0;\n for (i = 0; i < len; i++)\n bins[Math.min(Math.floor(((arr[i] - first) / binWidth)), binCnt - 1)] += 1;\n\n return bins;\n};\n\n\n// covariance of two arrays\njStat.covariance = function covariance(arr1, arr2) {\n var u = jStat.mean(arr1);\n var v = jStat.mean(arr2);\n var arr1Len = arr1.length;\n var sq_dev = new Array(arr1Len);\n var i;\n\n for (i = 0; i < arr1Len; i++)\n sq_dev[i] = (arr1[i] - u) * (arr2[i] - v);\n\n return jStat.sum(sq_dev) / (arr1Len - 1);\n};\n\n\n// (pearson's) population correlation coefficient, rho\njStat.corrcoeff = function corrcoeff(arr1, arr2) {\n return jStat.covariance(arr1, arr2) /\n jStat.stdev(arr1, 1) /\n jStat.stdev(arr2, 1);\n};\n\n // (spearman's) rank correlation coefficient, sp\njStat.spearmancoeff = function (arr1, arr2) {\n arr1 = jStat.rank(arr1);\n arr2 = jStat.rank(arr2);\n //return pearson's correlation of the ranks:\n return jStat.corrcoeff(arr1, arr2);\n}\n\n\n// statistical standardized moments (general form of skew/kurt)\njStat.stanMoment = function stanMoment(arr, n) {\n var mu = jStat.mean(arr);\n var sigma = jStat.stdev(arr);\n var len = arr.length;\n var skewSum = 0;\n\n for (var i = 0; i < len; i++)\n skewSum += Math.pow((arr[i] - mu) / sigma, n);\n\n return skewSum / arr.length;\n};\n\n// (pearson's) moment coefficient of skewness\njStat.skewness = function skewness(arr) {\n return jStat.stanMoment(arr, 3);\n};\n\n// (pearson's) (excess) kurtosis\njStat.kurtosis = function kurtosis(arr) {\n return jStat.stanMoment(arr, 4) - 3;\n};\n\n\nvar jProto = jStat.prototype;\n\n\n// Extend jProto with method for calculating cumulative sums and products.\n// This differs from the similar extension below as cumsum and cumprod should\n// not be run again in the case fullbool === true.\n// If a matrix is passed, automatically assume operation should be done on the\n// columns.\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n // If a matrix is passed, automatically assume operation should be done on\n // the columns.\n jProto[passfunc] = function(fullbool, func) {\n var arr = [];\n var i = 0;\n var tmpthis = this;\n // Assignment reassignation depending on how parameters were passed in.\n if (isFunction(fullbool)) {\n func = fullbool;\n fullbool = false;\n }\n // Check if a callback was passed with the function.\n if (func) {\n setTimeout(function() {\n func.call(tmpthis, jProto[passfunc].call(tmpthis, fullbool));\n });\n return this;\n }\n // Check if matrix and run calculations.\n if (this.length > 1) {\n tmpthis = fullbool === true ? this : this.transpose();\n for (; i < tmpthis.length; i++)\n arr[i] = jStat[passfunc](tmpthis[i]);\n return arr;\n }\n // Pass fullbool if only vector, not a matrix. for variance and stdev.\n return jStat[passfunc](this[0], fullbool);\n };\n })(funcs[i]);\n})(('cumsum cumprod').split(' '));\n\n\n// Extend jProto with methods which don't require arguments and work on columns.\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n // If a matrix is passed, automatically assume operation should be done on\n // the columns.\n jProto[passfunc] = function(fullbool, func) {\n var arr = [];\n var i = 0;\n var tmpthis = this;\n // Assignment reassignation depending on how parameters were passed in.\n if (isFunction(fullbool)) {\n func = fullbool;\n fullbool = false;\n }\n // Check if a callback was passed with the function.\n if (func) {\n setTimeout(function() {\n func.call(tmpthis, jProto[passfunc].call(tmpthis, fullbool));\n });\n return this;\n }\n // Check if matrix and run calculations.\n if (this.length > 1) {\n if (passfunc !== 'sumrow')\n tmpthis = fullbool === true ? this : this.transpose();\n for (; i < tmpthis.length; i++)\n arr[i] = jStat[passfunc](tmpthis[i]);\n return fullbool === true\n ? jStat[passfunc](jStat.utils.toVector(arr))\n : arr;\n }\n // Pass fullbool if only vector, not a matrix. for variance and stdev.\n return jStat[passfunc](this[0], fullbool);\n };\n })(funcs[i]);\n})(('sum sumsqrd sumsqerr sumrow product min max unique mean meansqerr ' +\n 'geomean median diff rank mode range variance deviation stdev meandev ' +\n 'meddev coeffvar quartiles histogram skewness kurtosis').split(' '));\n\n\n// Extend jProto with functions that take arguments. Operations on matrices are\n// done on columns.\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jProto[passfunc] = function() {\n var arr = [];\n var i = 0;\n var tmpthis = this;\n var args = Array.prototype.slice.call(arguments);\n var callbackFunction;\n\n // If the last argument is a function, we assume it's a callback; we\n // strip the callback out and call the function again.\n if (isFunction(args[args.length - 1])) {\n callbackFunction = args[args.length - 1];\n var argsToPass = args.slice(0, args.length - 1);\n\n setTimeout(function() {\n callbackFunction.call(tmpthis,\n jProto[passfunc].apply(tmpthis, argsToPass));\n });\n return this;\n\n // Otherwise we curry the function args and call normally.\n } else {\n callbackFunction = undefined;\n var curriedFunction = function curriedFunction(vector) {\n return jStat[passfunc].apply(tmpthis, [vector].concat(args));\n }\n }\n\n // If this is a matrix, run column-by-column.\n if (this.length > 1) {\n tmpthis = tmpthis.transpose();\n for (; i < tmpthis.length; i++)\n arr[i] = curriedFunction(tmpthis[i]);\n return arr;\n }\n\n // Otherwise run on the vector.\n return curriedFunction(this[0]);\n };\n })(funcs[i]);\n})('quantiles percentileOfScore'.split(' '));\n\n}(jStat, Math));\n// Special functions //\n(function(jStat, Math) {\n\n// Log-gamma function\njStat.gammaln = function gammaln(x) {\n var j = 0;\n var cof = [\n 76.18009172947146, -86.50532032941677, 24.01409824083091,\n -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5\n ];\n var ser = 1.000000000190015;\n var xx, y, tmp;\n tmp = (y = xx = x) + 5.5;\n tmp -= (xx + 0.5) * Math.log(tmp);\n for (; j < 6; j++)\n ser += cof[j] / ++y;\n return Math.log(2.5066282746310005 * ser / xx) - tmp;\n};\n\n/*\n * log-gamma function to support poisson distribution sampling. The\n * algorithm comes from SPECFUN by Shanjie Zhang and Jianming Jin and their\n * book \"Computation of Special Functions\", 1996, John Wiley & Sons, Inc.\n */\njStat.loggam = function loggam(x) {\n var x0, x2, xp, gl, gl0;\n var k, n;\n\n var a = [8.333333333333333e-02, -2.777777777777778e-03,\n 7.936507936507937e-04, -5.952380952380952e-04,\n 8.417508417508418e-04, -1.917526917526918e-03,\n 6.410256410256410e-03, -2.955065359477124e-02,\n 1.796443723688307e-01, -1.39243221690590e+00];\n x0 = x;\n n = 0;\n if ((x == 1.0) || (x == 2.0)) {\n return 0.0;\n }\n if (x <= 7.0) {\n n = Math.floor(7 - x);\n x0 = x + n;\n }\n x2 = 1.0 / (x0 * x0);\n xp = 2 * Math.PI;\n gl0 = a[9];\n for (k = 8; k >= 0; k--) {\n gl0 *= x2;\n gl0 += a[k];\n }\n gl = gl0 / x0 + 0.5 * Math.log(xp) + (x0 - 0.5) * Math.log(x0) - x0;\n if (x <= 7.0) {\n for (k = 1; k <= n; k++) {\n gl -= Math.log(x0 - 1.0);\n x0 -= 1.0;\n }\n }\n return gl;\n}\n\n// gamma of x\njStat.gammafn = function gammafn(x) {\n var p = [-1.716185138865495, 24.76565080557592, -379.80425647094563,\n 629.3311553128184, 866.9662027904133, -31451.272968848367,\n -36144.413418691176, 66456.14382024054\n ];\n var q = [-30.8402300119739, 315.35062697960416, -1015.1563674902192,\n -3107.771671572311, 22538.118420980151, 4755.8462775278811,\n -134659.9598649693, -115132.2596755535];\n var fact = false;\n var n = 0;\n var xden = 0;\n var xnum = 0;\n var y = x;\n var i, z, yi, res;\n if (x > 171.6243769536076) {\n return Infinity;\n }\n if (y <= 0) {\n res = y % 1 + 3.6e-16;\n if (res) {\n fact = (!(y & 1) ? 1 : -1) * Math.PI / Math.sin(Math.PI * res);\n y = 1 - y;\n } else {\n return Infinity;\n }\n }\n yi = y;\n if (y < 1) {\n z = y++;\n } else {\n z = (y -= n = (y | 0) - 1) - 1;\n }\n for (i = 0; i < 8; ++i) {\n xnum = (xnum + p[i]) * z;\n xden = xden * z + q[i];\n }\n res = xnum / xden + 1;\n if (yi < y) {\n res /= yi;\n } else if (yi > y) {\n for (i = 0; i < n; ++i) {\n res *= y;\n y++;\n }\n }\n if (fact) {\n res = fact / res;\n }\n return res;\n};\n\n\n// lower incomplete gamma function, which is usually typeset with a\n// lower-case greek gamma as the function symbol\njStat.gammap = function gammap(a, x) {\n return jStat.lowRegGamma(a, x) * jStat.gammafn(a);\n};\n\n\n// The lower regularized incomplete gamma function, usually written P(a,x)\njStat.lowRegGamma = function lowRegGamma(a, x) {\n var aln = jStat.gammaln(a);\n var ap = a;\n var sum = 1 / a;\n var del = sum;\n var b = x + 1 - a;\n var c = 1 / 1.0e-30;\n var d = 1 / b;\n var h = d;\n var i = 1;\n // calculate maximum number of itterations required for a\n var ITMAX = -~(Math.log((a >= 1) ? a : 1 / a) * 8.5 + a * 0.4 + 17);\n var an;\n\n if (x < 0 || a <= 0) {\n return NaN;\n } else if (x < a + 1) {\n for (; i <= ITMAX; i++) {\n sum += del *= x / ++ap;\n }\n return (sum * Math.exp(-x + a * Math.log(x) - (aln)));\n }\n\n for (; i <= ITMAX; i++) {\n an = -i * (i - a);\n b += 2;\n d = an * d + b;\n c = b + an / c;\n d = 1 / d;\n h *= d * c;\n }\n\n return (1 - h * Math.exp(-x + a * Math.log(x) - (aln)));\n};\n\n// natural log factorial of n\njStat.factorialln = function factorialln(n) {\n return n < 0 ? NaN : jStat.gammaln(n + 1);\n};\n\n// factorial of n\njStat.factorial = function factorial(n) {\n return n < 0 ? NaN : jStat.gammafn(n + 1);\n};\n\n// combinations of n, m\njStat.combination = function combination(n, m) {\n // make sure n or m don't exceed the upper limit of usable values\n return (n > 170 || m > 170)\n ? Math.exp(jStat.combinationln(n, m))\n : (jStat.factorial(n) / jStat.factorial(m)) / jStat.factorial(n - m);\n};\n\n\njStat.combinationln = function combinationln(n, m){\n return jStat.factorialln(n) - jStat.factorialln(m) - jStat.factorialln(n - m);\n};\n\n\n// permutations of n, m\njStat.permutation = function permutation(n, m) {\n return jStat.factorial(n) / jStat.factorial(n - m);\n};\n\n\n// beta function\njStat.betafn = function betafn(x, y) {\n // ensure arguments are positive\n if (x <= 0 || y <= 0)\n return undefined;\n // make sure x + y doesn't exceed the upper limit of usable values\n return (x + y > 170)\n ? Math.exp(jStat.betaln(x, y))\n : jStat.gammafn(x) * jStat.gammafn(y) / jStat.gammafn(x + y);\n};\n\n\n// natural logarithm of beta function\njStat.betaln = function betaln(x, y) {\n return jStat.gammaln(x) + jStat.gammaln(y) - jStat.gammaln(x + y);\n};\n\n\n// Evaluates the continued fraction for incomplete beta function by modified\n// Lentz's method.\njStat.betacf = function betacf(x, a, b) {\n var fpmin = 1e-30;\n var m = 1;\n var qab = a + b;\n var qap = a + 1;\n var qam = a - 1;\n var c = 1;\n var d = 1 - qab * x / qap;\n var m2, aa, del, h;\n\n // These q's will be used in factors that occur in the coefficients\n if (Math.abs(d) < fpmin)\n d = fpmin;\n d = 1 / d;\n h = d;\n\n for (; m <= 100; m++) {\n m2 = 2 * m;\n aa = m * (b - m) * x / ((qam + m2) * (a + m2));\n // One step (the even one) of the recurrence\n d = 1 + aa * d;\n if (Math.abs(d) < fpmin)\n d = fpmin;\n c = 1 + aa / c;\n if (Math.abs(c) < fpmin)\n c = fpmin;\n d = 1 / d;\n h *= d * c;\n aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));\n // Next step of the recurrence (the odd one)\n d = 1 + aa * d;\n if (Math.abs(d) < fpmin)\n d = fpmin;\n c = 1 + aa / c;\n if (Math.abs(c) < fpmin)\n c = fpmin;\n d = 1 / d;\n del = d * c;\n h *= del;\n if (Math.abs(del - 1.0) < 3e-7)\n break;\n }\n\n return h;\n};\n\n\n// Returns the inverse of the lower regularized inomplete gamma function\njStat.gammapinv = function gammapinv(p, a) {\n var j = 0;\n var a1 = a - 1;\n var EPS = 1e-8;\n var gln = jStat.gammaln(a);\n var x, err, t, u, pp, lna1, afac;\n\n if (p >= 1)\n return Math.max(100, a + 100 * Math.sqrt(a));\n if (p <= 0)\n return 0;\n if (a > 1) {\n lna1 = Math.log(a1);\n afac = Math.exp(a1 * (lna1 - 1) - gln);\n pp = (p < 0.5) ? p : 1 - p;\n t = Math.sqrt(-2 * Math.log(pp));\n x = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t;\n if (p < 0.5)\n x = -x;\n x = Math.max(1e-3,\n a * Math.pow(1 - 1 / (9 * a) - x / (3 * Math.sqrt(a)), 3));\n } else {\n t = 1 - a * (0.253 + a * 0.12);\n if (p < t)\n x = Math.pow(p / t, 1 / a);\n else\n x = 1 - Math.log(1 - (p - t) / (1 - t));\n }\n\n for(; j < 12; j++) {\n if (x <= 0)\n return 0;\n err = jStat.lowRegGamma(a, x) - p;\n if (a > 1)\n t = afac * Math.exp(-(x - a1) + a1 * (Math.log(x) - lna1));\n else\n t = Math.exp(-x + a1 * Math.log(x) - gln);\n u = err / t;\n x -= (t = u / (1 - 0.5 * Math.min(1, u * ((a - 1) / x - 1))));\n if (x <= 0)\n x = 0.5 * (x + t);\n if (Math.abs(t) < EPS * x)\n break;\n }\n\n return x;\n};\n\n\n// Returns the error function erf(x)\njStat.erf = function erf(x) {\n var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,\n -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,\n 4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,\n 1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,\n 6.529054439e-9, 5.059343495e-9, -9.91364156e-10,\n -2.27365122e-10, 9.6467911e-11, 2.394038e-12,\n -6.886027e-12, 8.94487e-13, 3.13092e-13,\n -1.12708e-13, 3.81e-16, 7.106e-15,\n -1.523e-15, -9.4e-17, 1.21e-16,\n -2.8e-17];\n var j = cof.length - 1;\n var isneg = false;\n var d = 0;\n var dd = 0;\n var t, ty, tmp, res;\n\n if (x < 0) {\n x = -x;\n isneg = true;\n }\n\n t = 2 / (2 + x);\n ty = 4 * t - 2;\n\n for(; j > 0; j--) {\n tmp = d;\n d = ty * d - dd + cof[j];\n dd = tmp;\n }\n\n res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);\n return isneg ? res - 1 : 1 - res;\n};\n\n\n// Returns the complmentary error function erfc(x)\njStat.erfc = function erfc(x) {\n return 1 - jStat.erf(x);\n};\n\n\n// Returns the inverse of the complementary error function\njStat.erfcinv = function erfcinv(p) {\n var j = 0;\n var x, err, t, pp;\n if (p >= 2)\n return -100;\n if (p <= 0)\n return 100;\n pp = (p < 1) ? p : 2 - p;\n t = Math.sqrt(-2 * Math.log(pp / 2));\n x = -0.70711 * ((2.30753 + t * 0.27061) /\n (1 + t * (0.99229 + t * 0.04481)) - t);\n for (; j < 2; j++) {\n err = jStat.erfc(x) - pp;\n x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);\n }\n return (p < 1) ? x : -x;\n};\n\n\n// Returns the inverse of the incomplete beta function\njStat.ibetainv = function ibetainv(p, a, b) {\n var EPS = 1e-8;\n var a1 = a - 1;\n var b1 = b - 1;\n var j = 0;\n var lna, lnb, pp, t, u, err, x, al, h, w, afac;\n if (p <= 0)\n return 0;\n if (p >= 1)\n return 1;\n if (a >= 1 && b >= 1) {\n pp = (p < 0.5) ? p : 1 - p;\n t = Math.sqrt(-2 * Math.log(pp));\n x = (2.30753 + t * 0.27061) / (1 + t* (0.99229 + t * 0.04481)) - t;\n if (p < 0.5)\n x = -x;\n al = (x * x - 3) / 6;\n h = 2 / (1 / (2 * a - 1) + 1 / (2 * b - 1));\n w = (x * Math.sqrt(al + h) / h) - (1 / (2 * b - 1) - 1 / (2 * a - 1)) *\n (al + 5 / 6 - 2 / (3 * h));\n x = a / (a + b * Math.exp(2 * w));\n } else {\n lna = Math.log(a / (a + b));\n lnb = Math.log(b / (a + b));\n t = Math.exp(a * lna) / a;\n u = Math.exp(b * lnb) / b;\n w = t + u;\n if (p < t / w)\n x = Math.pow(a * w * p, 1 / a);\n else\n x = 1 - Math.pow(b * w * (1 - p), 1 / b);\n }\n afac = -jStat.gammaln(a) - jStat.gammaln(b) + jStat.gammaln(a + b);\n for(; j < 10; j++) {\n if (x === 0 || x === 1)\n return x;\n err = jStat.ibeta(x, a, b) - p;\n t = Math.exp(a1 * Math.log(x) + b1 * Math.log(1 - x) + afac);\n u = err / t;\n x -= (t = u / (1 - 0.5 * Math.min(1, u * (a1 / x - b1 / (1 - x)))));\n if (x <= 0)\n x = 0.5 * (x + t);\n if (x >= 1)\n x = 0.5 * (x + t + 1);\n if (Math.abs(t) < EPS * x && j > 0)\n break;\n }\n return x;\n};\n\n\n// Returns the incomplete beta function I_x(a,b)\njStat.ibeta = function ibeta(x, a, b) {\n // Factors in front of the continued fraction.\n var bt = (x === 0 || x === 1) ? 0 :\n Math.exp(jStat.gammaln(a + b) - jStat.gammaln(a) -\n jStat.gammaln(b) + a * Math.log(x) + b *\n Math.log(1 - x));\n if (x < 0 || x > 1)\n return false;\n if (x < (a + 1) / (a + b + 2))\n // Use continued fraction directly.\n return bt * jStat.betacf(x, a, b) / a;\n // else use continued fraction after making the symmetry transformation.\n return 1 - bt * jStat.betacf(1 - x, b, a) / b;\n};\n\n\n// Returns a normal deviate (mu=0, sigma=1).\n// If n and m are specified it returns a object of normal deviates.\njStat.randn = function randn(n, m) {\n var u, v, x, y, q;\n if (!m)\n m = n;\n if (n)\n return jStat.create(n, m, function() { return jStat.randn(); });\n do {\n u = jStat._random_fn();\n v = 1.7156 * (jStat._random_fn() - 0.5);\n x = u - 0.449871;\n y = Math.abs(v) + 0.386595;\n q = x * x + y * (0.19600 * y - 0.25472 * x);\n } while (q > 0.27597 && (q > 0.27846 || v * v > -4 * Math.log(u) * u * u));\n return v / u;\n};\n\n\n// Returns a gamma deviate by the method of Marsaglia and Tsang.\njStat.randg = function randg(shape, n, m) {\n var oalph = shape;\n var a1, a2, u, v, x, mat;\n if (!m)\n m = n;\n if (!shape)\n shape = 1;\n if (n) {\n mat = jStat.zeros(n,m);\n mat.alter(function() { return jStat.randg(shape); });\n return mat;\n }\n if (shape < 1)\n shape += 1;\n a1 = shape - 1 / 3;\n a2 = 1 / Math.sqrt(9 * a1);\n do {\n do {\n x = jStat.randn();\n v = 1 + a2 * x;\n } while(v <= 0);\n v = v * v * v;\n u = jStat._random_fn();\n } while(u > 1 - 0.331 * Math.pow(x, 4) &&\n Math.log(u) > 0.5 * x*x + a1 * (1 - v + Math.log(v)));\n // alpha > 1\n if (shape == oalph)\n return a1 * v;\n // alpha < 1\n do {\n u = jStat._random_fn();\n } while(u === 0);\n return Math.pow(u, 1 / oalph) * a1 * v;\n};\n\n\n// making use of static methods on the instance\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jStat.fn[passfunc] = function() {\n return jStat(\n jStat.map(this, function(value) { return jStat[passfunc](value); }));\n }\n })(funcs[i]);\n})('gammaln gammafn factorial factorialln'.split(' '));\n\n\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jStat.fn[passfunc] = function() {\n return jStat(jStat[passfunc].apply(null, arguments));\n };\n })(funcs[i]);\n})('randn'.split(' '));\n\n}(jStat, Math));\n(function(jStat, Math) {\n\n// generate all distribution instance methods\n(function(list) {\n for (var i = 0; i < list.length; i++) (function(func) {\n // distribution instance method\n jStat[func] = function f(a, b, c) {\n if (!(this instanceof f))\n return new f(a, b, c);\n this._a = a;\n this._b = b;\n this._c = c;\n return this;\n };\n // distribution method to be used on a jStat instance\n jStat.fn[func] = function(a, b, c) {\n var newthis = jStat[func](a, b, c);\n newthis.data = this;\n return newthis;\n };\n // sample instance method\n jStat[func].prototype.sample = function(arr) {\n var a = this._a;\n var b = this._b;\n var c = this._c;\n if (arr)\n return jStat.alter(arr, function() {\n return jStat[func].sample(a, b, c);\n });\n else\n return jStat[func].sample(a, b, c);\n };\n // generate the pdf, cdf and inv instance methods\n (function(vals) {\n for (var i = 0; i < vals.length; i++) (function(fnfunc) {\n jStat[func].prototype[fnfunc] = function(x) {\n var a = this._a;\n var b = this._b;\n var c = this._c;\n if (!x && x !== 0)\n x = this.data;\n if (typeof x !== 'number') {\n return jStat.fn.map.call(x, function(x) {\n return jStat[func][fnfunc](x, a, b, c);\n });\n }\n return jStat[func][fnfunc](x, a, b, c);\n };\n })(vals[i]);\n })('pdf cdf inv'.split(' '));\n // generate the mean, median, mode and variance instance methods\n (function(vals) {\n for (var i = 0; i < vals.length; i++) (function(fnfunc) {\n jStat[func].prototype[fnfunc] = function() {\n return jStat[func][fnfunc](this._a, this._b, this._c);\n };\n })(vals[i]);\n })('mean median mode variance'.split(' '));\n })(list[i]);\n})((\n 'beta centralF cauchy chisquare exponential gamma invgamma kumaraswamy ' +\n 'laplace lognormal noncentralt normal pareto studentt weibull uniform ' +\n 'binomial negbin hypgeom poisson triangular tukey arcsine'\n).split(' '));\n\n\n\n// extend beta function with static methods\njStat.extend(jStat.beta, {\n pdf: function pdf(x, alpha, beta) {\n // PDF is zero outside the support\n if (x > 1 || x < 0)\n return 0;\n // PDF is one for the uniform case\n if (alpha == 1 && beta == 1)\n return 1;\n\n if (alpha < 512 && beta < 512) {\n return (Math.pow(x, alpha - 1) * Math.pow(1 - x, beta - 1)) /\n jStat.betafn(alpha, beta);\n } else {\n return Math.exp((alpha - 1) * Math.log(x) +\n (beta - 1) * Math.log(1 - x) -\n jStat.betaln(alpha, beta));\n }\n },\n\n cdf: function cdf(x, alpha, beta) {\n return (x > 1 || x < 0) ? (x > 1) * 1 : jStat.ibeta(x, alpha, beta);\n },\n\n inv: function inv(x, alpha, beta) {\n return jStat.ibetainv(x, alpha, beta);\n },\n\n mean: function mean(alpha, beta) {\n return alpha / (alpha + beta);\n },\n\n median: function median(alpha, beta) {\n return jStat.ibetainv(0.5, alpha, beta);\n },\n\n mode: function mode(alpha, beta) {\n return (alpha - 1 ) / ( alpha + beta - 2);\n },\n\n // return a random sample\n sample: function sample(alpha, beta) {\n var u = jStat.randg(alpha);\n return u / (u + jStat.randg(beta));\n },\n\n variance: function variance(alpha, beta) {\n return (alpha * beta) / (Math.pow(alpha + beta, 2) * (alpha + beta + 1));\n }\n});\n\n// extend F function with static methods\njStat.extend(jStat.centralF, {\n // This implementation of the pdf function avoids float overflow\n // See the way that R calculates this value:\n // https://svn.r-project.org/R/trunk/src/nmath/df.c\n pdf: function pdf(x, df1, df2) {\n var p, q, f;\n\n if (x < 0)\n return 0;\n\n if (df1 <= 2) {\n if (x === 0 && df1 < 2) {\n return Infinity;\n }\n if (x === 0 && df1 === 2) {\n return 1;\n }\n return (1 / jStat.betafn(df1 / 2, df2 / 2)) *\n Math.pow(df1 / df2, df1 / 2) *\n Math.pow(x, (df1/2) - 1) *\n Math.pow((1 + (df1 / df2) * x), -(df1 + df2) / 2);\n }\n\n p = (df1 * x) / (df2 + x * df1);\n q = df2 / (df2 + x * df1);\n f = df1 * q / 2.0;\n return f * jStat.binomial.pdf((df1 - 2) / 2, (df1 + df2 - 2) / 2, p);\n },\n\n cdf: function cdf(x, df1, df2) {\n if (x < 0)\n return 0;\n return jStat.ibeta((df1 * x) / (df1 * x + df2), df1 / 2, df2 / 2);\n },\n\n inv: function inv(x, df1, df2) {\n return df2 / (df1 * (1 / jStat.ibetainv(x, df1 / 2, df2 / 2) - 1));\n },\n\n mean: function mean(df1, df2) {\n return (df2 > 2) ? df2 / (df2 - 2) : undefined;\n },\n\n mode: function mode(df1, df2) {\n return (df1 > 2) ? (df2 * (df1 - 2)) / (df1 * (df2 + 2)) : undefined;\n },\n\n // return a random sample\n sample: function sample(df1, df2) {\n var x1 = jStat.randg(df1 / 2) * 2;\n var x2 = jStat.randg(df2 / 2) * 2;\n return (x1 / df1) / (x2 / df2);\n },\n\n variance: function variance(df1, df2) {\n if (df2 <= 4)\n return undefined;\n return 2 * df2 * df2 * (df1 + df2 - 2) /\n (df1 * (df2 - 2) * (df2 - 2) * (df2 - 4));\n }\n});\n\n\n// extend cauchy function with static methods\njStat.extend(jStat.cauchy, {\n pdf: function pdf(x, local, scale) {\n if (scale < 0) { return 0; }\n\n return (scale / (Math.pow(x - local, 2) + Math.pow(scale, 2))) / Math.PI;\n },\n\n cdf: function cdf(x, local, scale) {\n return Math.atan((x - local) / scale) / Math.PI + 0.5;\n },\n\n inv: function(p, local, scale) {\n return local + scale * Math.tan(Math.PI * (p - 0.5));\n },\n\n median: function median(local/*, scale*/) {\n return local;\n },\n\n mode: function mode(local/*, scale*/) {\n return local;\n },\n\n sample: function sample(local, scale) {\n return jStat.randn() *\n Math.sqrt(1 / (2 * jStat.randg(0.5))) * scale + local;\n }\n});\n\n\n\n// extend chisquare function with static methods\njStat.extend(jStat.chisquare, {\n pdf: function pdf(x, dof) {\n if (x < 0)\n return 0;\n return (x === 0 && dof === 2) ? 0.5 :\n Math.exp((dof / 2 - 1) * Math.log(x) - x / 2 - (dof / 2) *\n Math.log(2) - jStat.gammaln(dof / 2));\n },\n\n cdf: function cdf(x, dof) {\n if (x < 0)\n return 0;\n return jStat.lowRegGamma(dof / 2, x / 2);\n },\n\n inv: function(p, dof) {\n return 2 * jStat.gammapinv(p, 0.5 * dof);\n },\n\n mean : function(dof) {\n return dof;\n },\n\n // TODO: this is an approximation (is there a better way?)\n median: function median(dof) {\n return dof * Math.pow(1 - (2 / (9 * dof)), 3);\n },\n\n mode: function mode(dof) {\n return (dof - 2 > 0) ? dof - 2 : 0;\n },\n\n sample: function sample(dof) {\n return jStat.randg(dof / 2) * 2;\n },\n\n variance: function variance(dof) {\n return 2 * dof;\n }\n});\n\n\n\n// extend exponential function with static methods\njStat.extend(jStat.exponential, {\n pdf: function pdf(x, rate) {\n return x < 0 ? 0 : rate * Math.exp(-rate * x);\n },\n\n cdf: function cdf(x, rate) {\n return x < 0 ? 0 : 1 - Math.exp(-rate * x);\n },\n\n inv: function(p, rate) {\n return -Math.log(1 - p) / rate;\n },\n\n mean : function(rate) {\n return 1 / rate;\n },\n\n median: function (rate) {\n return (1 / rate) * Math.log(2);\n },\n\n mode: function mode(/*rate*/) {\n return 0;\n },\n\n sample: function sample(rate) {\n return -1 / rate * Math.log(jStat._random_fn());\n },\n\n variance : function(rate) {\n return Math.pow(rate, -2);\n }\n});\n\n\n\n// extend gamma function with static methods\njStat.extend(jStat.gamma, {\n pdf: function pdf(x, shape, scale) {\n if (x < 0)\n return 0;\n return (x === 0 && shape === 1) ? 1 / scale :\n Math.exp((shape - 1) * Math.log(x) - x / scale -\n jStat.gammaln(shape) - shape * Math.log(scale));\n },\n\n cdf: function cdf(x, shape, scale) {\n if (x < 0)\n return 0;\n return jStat.lowRegGamma(shape, x / scale);\n },\n\n inv: function(p, shape, scale) {\n return jStat.gammapinv(p, shape) * scale;\n },\n\n mean : function(shape, scale) {\n return shape * scale;\n },\n\n mode: function mode(shape, scale) {\n if(shape > 1) return (shape - 1) * scale;\n return undefined;\n },\n\n sample: function sample(shape, scale) {\n return jStat.randg(shape) * scale;\n },\n\n variance: function variance(shape, scale) {\n return shape * scale * scale;\n }\n});\n\n// extend inverse gamma function with static methods\njStat.extend(jStat.invgamma, {\n pdf: function pdf(x, shape, scale) {\n if (x <= 0)\n return 0;\n return Math.exp(-(shape + 1) * Math.log(x) - scale / x -\n jStat.gammaln(shape) + shape * Math.log(scale));\n },\n\n cdf: function cdf(x, shape, scale) {\n if (x <= 0)\n return 0;\n return 1 - jStat.lowRegGamma(shape, scale / x);\n },\n\n inv: function(p, shape, scale) {\n return scale / jStat.gammapinv(1 - p, shape);\n },\n\n mean : function(shape, scale) {\n return (shape > 1) ? scale / (shape - 1) : undefined;\n },\n\n mode: function mode(shape, scale) {\n return scale / (shape + 1);\n },\n\n sample: function sample(shape, scale) {\n return scale / jStat.randg(shape);\n },\n\n variance: function variance(shape, scale) {\n if (shape <= 2)\n return undefined;\n return scale * scale / ((shape - 1) * (shape - 1) * (shape - 2));\n }\n});\n\n\n// extend kumaraswamy function with static methods\njStat.extend(jStat.kumaraswamy, {\n pdf: function pdf(x, alpha, beta) {\n if (x === 0 && alpha === 1)\n return beta;\n else if (x === 1 && beta === 1)\n return alpha;\n return Math.exp(Math.log(alpha) + Math.log(beta) + (alpha - 1) *\n Math.log(x) + (beta - 1) *\n Math.log(1 - Math.pow(x, alpha)));\n },\n\n cdf: function cdf(x, alpha, beta) {\n if (x < 0)\n return 0;\n else if (x > 1)\n return 1;\n return (1 - Math.pow(1 - Math.pow(x, alpha), beta));\n },\n\n inv: function inv(p, alpha, beta) {\n return Math.pow(1 - Math.pow(1 - p, 1 / beta), 1 / alpha);\n },\n\n mean : function(alpha, beta) {\n return (beta * jStat.gammafn(1 + 1 / alpha) *\n jStat.gammafn(beta)) / (jStat.gammafn(1 + 1 / alpha + beta));\n },\n\n median: function median(alpha, beta) {\n return Math.pow(1 - Math.pow(2, -1 / beta), 1 / alpha);\n },\n\n mode: function mode(alpha, beta) {\n if (!(alpha >= 1 && beta >= 1 && (alpha !== 1 && beta !== 1)))\n return undefined;\n return Math.pow((alpha - 1) / (alpha * beta - 1), 1 / alpha);\n },\n\n variance: function variance(/*alpha, beta*/) {\n throw new Error('variance not yet implemented');\n // TODO: complete this\n }\n});\n\n\n\n// extend lognormal function with static methods\njStat.extend(jStat.lognormal, {\n pdf: function pdf(x, mu, sigma) {\n if (x <= 0)\n return 0;\n return Math.exp(-Math.log(x) - 0.5 * Math.log(2 * Math.PI) -\n Math.log(sigma) - Math.pow(Math.log(x) - mu, 2) /\n (2 * sigma * sigma));\n },\n\n cdf: function cdf(x, mu, sigma) {\n if (x < 0)\n return 0;\n return 0.5 +\n (0.5 * jStat.erf((Math.log(x) - mu) / Math.sqrt(2 * sigma * sigma)));\n },\n\n inv: function(p, mu, sigma) {\n return Math.exp(-1.41421356237309505 * sigma * jStat.erfcinv(2 * p) + mu);\n },\n\n mean: function mean(mu, sigma) {\n return Math.exp(mu + sigma * sigma / 2);\n },\n\n median: function median(mu/*, sigma*/) {\n return Math.exp(mu);\n },\n\n mode: function mode(mu, sigma) {\n return Math.exp(mu - sigma * sigma);\n },\n\n sample: function sample(mu, sigma) {\n return Math.exp(jStat.randn() * sigma + mu);\n },\n\n variance: function variance(mu, sigma) {\n return (Math.exp(sigma * sigma) - 1) * Math.exp(2 * mu + sigma * sigma);\n }\n});\n\n\n\n// extend noncentralt function with static methods\njStat.extend(jStat.noncentralt, {\n pdf: function pdf(x, dof, ncp) {\n var tol = 1e-14;\n if (Math.abs(ncp) < tol) // ncp approx 0; use student-t\n return jStat.studentt.pdf(x, dof)\n\n if (Math.abs(x) < tol) { // different formula for x == 0\n return Math.exp(jStat.gammaln((dof + 1) / 2) - ncp * ncp / 2 -\n 0.5 * Math.log(Math.PI * dof) - jStat.gammaln(dof / 2));\n }\n\n // formula for x != 0\n return dof / x *\n (jStat.noncentralt.cdf(x * Math.sqrt(1 + 2 / dof), dof+2, ncp) -\n jStat.noncentralt.cdf(x, dof, ncp));\n },\n\n cdf: function cdf(x, dof, ncp) {\n var tol = 1e-14;\n var min_iterations = 200;\n\n if (Math.abs(ncp) < tol) // ncp approx 0; use student-t\n return jStat.studentt.cdf(x, dof);\n\n // turn negative x into positive and flip result afterwards\n var flip = false;\n if (x < 0) {\n flip = true;\n ncp = -ncp;\n }\n\n var prob = jStat.normal.cdf(-ncp, 0, 1);\n var value = tol + 1;\n // use value at last two steps to determine convergence\n var lastvalue = value;\n var y = x * x / (x * x + dof);\n var j = 0;\n var p = Math.exp(-ncp * ncp / 2);\n var q = Math.exp(-ncp * ncp / 2 - 0.5 * Math.log(2) -\n jStat.gammaln(3 / 2)) * ncp;\n while (j < min_iterations || lastvalue > tol || value > tol) {\n lastvalue = value;\n if (j > 0) {\n p *= (ncp * ncp) / (2 * j);\n q *= (ncp * ncp) / (2 * (j + 1 / 2));\n }\n value = p * jStat.beta.cdf(y, j + 0.5, dof / 2) +\n q * jStat.beta.cdf(y, j+1, dof/2);\n prob += 0.5 * value;\n j++;\n }\n\n return flip ? (1 - prob) : prob;\n }\n});\n\n\n// extend normal function with static methods\njStat.extend(jStat.normal, {\n pdf: function pdf(x, mean, std) {\n return Math.exp(-0.5 * Math.log(2 * Math.PI) -\n Math.log(std) - Math.pow(x - mean, 2) / (2 * std * std));\n },\n\n cdf: function cdf(x, mean, std) {\n return 0.5 * (1 + jStat.erf((x - mean) / Math.sqrt(2 * std * std)));\n },\n\n inv: function(p, mean, std) {\n return -1.41421356237309505 * std * jStat.erfcinv(2 * p) + mean;\n },\n\n mean : function(mean/*, std*/) {\n return mean;\n },\n\n median: function median(mean/*, std*/) {\n return mean;\n },\n\n mode: function (mean/*, std*/) {\n return mean;\n },\n\n sample: function sample(mean, std) {\n return jStat.randn() * std + mean;\n },\n\n variance : function(mean, std) {\n return std * std;\n }\n});\n\n\n\n// extend pareto function with static methods\njStat.extend(jStat.pareto, {\n pdf: function pdf(x, scale, shape) {\n if (x < scale)\n return 0;\n return (shape * Math.pow(scale, shape)) / Math.pow(x, shape + 1);\n },\n\n cdf: function cdf(x, scale, shape) {\n if (x < scale)\n return 0;\n return 1 - Math.pow(scale / x, shape);\n },\n\n inv: function inv(p, scale, shape) {\n return scale / Math.pow(1 - p, 1 / shape);\n },\n\n mean: function mean(scale, shape) {\n if (shape <= 1)\n return undefined;\n return (shape * Math.pow(scale, shape)) / (shape - 1);\n },\n\n median: function median(scale, shape) {\n return scale * (shape * Math.SQRT2);\n },\n\n mode: function mode(scale/*, shape*/) {\n return scale;\n },\n\n variance : function(scale, shape) {\n if (shape <= 2)\n return undefined;\n return (scale*scale * shape) / (Math.pow(shape - 1, 2) * (shape - 2));\n }\n});\n\n\n\n// extend studentt function with static methods\njStat.extend(jStat.studentt, {\n pdf: function pdf(x, dof) {\n dof = dof > 1e100 ? 1e100 : dof;\n return (1/(Math.sqrt(dof) * jStat.betafn(0.5, dof/2))) *\n Math.pow(1 + ((x * x) / dof), -((dof + 1) / 2));\n },\n\n cdf: function cdf(x, dof) {\n var dof2 = dof / 2;\n return jStat.ibeta((x + Math.sqrt(x * x + dof)) /\n (2 * Math.sqrt(x * x + dof)), dof2, dof2);\n },\n\n inv: function(p, dof) {\n var x = jStat.ibetainv(2 * Math.min(p, 1 - p), 0.5 * dof, 0.5);\n x = Math.sqrt(dof * (1 - x) / x);\n return (p > 0.5) ? x : -x;\n },\n\n mean: function mean(dof) {\n return (dof > 1) ? 0 : undefined;\n },\n\n median: function median(/*dof*/) {\n return 0;\n },\n\n mode: function mode(/*dof*/) {\n return 0;\n },\n\n sample: function sample(dof) {\n return jStat.randn() * Math.sqrt(dof / (2 * jStat.randg(dof / 2)));\n },\n\n variance: function variance(dof) {\n return (dof > 2) ? dof / (dof - 2) : (dof > 1) ? Infinity : undefined;\n }\n});\n\n\n\n// extend weibull function with static methods\njStat.extend(jStat.weibull, {\n pdf: function pdf(x, scale, shape) {\n if (x < 0 || scale < 0 || shape < 0)\n return 0;\n return (shape / scale) * Math.pow((x / scale), (shape - 1)) *\n Math.exp(-(Math.pow((x / scale), shape)));\n },\n\n cdf: function cdf(x, scale, shape) {\n return x < 0 ? 0 : 1 - Math.exp(-Math.pow((x / scale), shape));\n },\n\n inv: function(p, scale, shape) {\n return scale * Math.pow(-Math.log(1 - p), 1 / shape);\n },\n\n mean : function(scale, shape) {\n return scale * jStat.gammafn(1 + 1 / shape);\n },\n\n median: function median(scale, shape) {\n return scale * Math.pow(Math.log(2), 1 / shape);\n },\n\n mode: function mode(scale, shape) {\n if (shape <= 1)\n return 0;\n return scale * Math.pow((shape - 1) / shape, 1 / shape);\n },\n\n sample: function sample(scale, shape) {\n return scale * Math.pow(-Math.log(jStat._random_fn()), 1 / shape);\n },\n\n variance: function variance(scale, shape) {\n return scale * scale * jStat.gammafn(1 + 2 / shape) -\n Math.pow(jStat.weibull.mean(scale, shape), 2);\n }\n});\n\n\n\n// extend uniform function with static methods\njStat.extend(jStat.uniform, {\n pdf: function pdf(x, a, b) {\n return (x < a || x > b) ? 0 : 1 / (b - a);\n },\n\n cdf: function cdf(x, a, b) {\n if (x < a)\n return 0;\n else if (x < b)\n return (x - a) / (b - a);\n return 1;\n },\n\n inv: function(p, a, b) {\n return a + (p * (b - a));\n },\n\n mean: function mean(a, b) {\n return 0.5 * (a + b);\n },\n\n median: function median(a, b) {\n return jStat.mean(a, b);\n },\n\n mode: function mode(/*a, b*/) {\n throw new Error('mode is not yet implemented');\n },\n\n sample: function sample(a, b) {\n return (a / 2 + b / 2) + (b / 2 - a / 2) * (2 * jStat._random_fn() - 1);\n },\n\n variance: function variance(a, b) {\n return Math.pow(b - a, 2) / 12;\n }\n});\n\n\n// Got this from http://www.math.ucla.edu/~tom/distributions/binomial.html\nfunction betinc(x, a, b, eps) {\n var a0 = 0;\n var b0 = 1;\n var a1 = 1;\n var b1 = 1;\n var m9 = 0;\n var a2 = 0;\n var c9;\n\n while (Math.abs((a1 - a2) / a1) > eps) {\n a2 = a1;\n c9 = -(a + m9) * (a + b + m9) * x / (a + 2 * m9) / (a + 2 * m9 + 1);\n a0 = a1 + c9 * a0;\n b0 = b1 + c9 * b0;\n m9 = m9 + 1;\n c9 = m9 * (b - m9) * x / (a + 2 * m9 - 1) / (a + 2 * m9);\n a1 = a0 + c9 * a1;\n b1 = b0 + c9 * b1;\n a0 = a0 / b1;\n b0 = b0 / b1;\n a1 = a1 / b1;\n b1 = 1;\n }\n\n return a1 / a;\n}\n\n\n// extend uniform function with static methods\njStat.extend(jStat.binomial, {\n pdf: function pdf(k, n, p) {\n return (p === 0 || p === 1) ?\n ((n * p) === k ? 1 : 0) :\n jStat.combination(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);\n },\n\n cdf: function cdf(x, n, p) {\n var betacdf;\n var eps = 1e-10;\n\n if (x < 0)\n return 0;\n if (x >= n)\n return 1;\n if (p < 0 || p > 1 || n <= 0)\n return NaN;\n\n x = Math.floor(x);\n var z = p;\n var a = x + 1;\n var b = n - x;\n var s = a + b;\n var bt = Math.exp(jStat.gammaln(s) - jStat.gammaln(b) -\n jStat.gammaln(a) + a * Math.log(z) + b * Math.log(1 - z));\n\n if (z < (a + 1) / (s + 2))\n betacdf = bt * betinc(z, a, b, eps);\n else\n betacdf = 1 - bt * betinc(1 - z, b, a, eps);\n\n return Math.round((1 - betacdf) * (1 / eps)) / (1 / eps);\n }\n});\n\n\n\n// extend uniform function with static methods\njStat.extend(jStat.negbin, {\n pdf: function pdf(k, r, p) {\n if (k !== k >>> 0)\n return false;\n if (k < 0)\n return 0;\n return jStat.combination(k + r - 1, r - 1) *\n Math.pow(1 - p, k) * Math.pow(p, r);\n },\n\n cdf: function cdf(x, r, p) {\n var sum = 0,\n k = 0;\n if (x < 0) return 0;\n for (; k <= x; k++) {\n sum += jStat.negbin.pdf(k, r, p);\n }\n return sum;\n }\n});\n\n\n\n// extend uniform function with static methods\njStat.extend(jStat.hypgeom, {\n pdf: function pdf(k, N, m, n) {\n // Hypergeometric PDF.\n\n // A simplification of the CDF algorithm below.\n\n // k = number of successes drawn\n // N = population size\n // m = number of successes in population\n // n = number of items drawn from population\n\n if(k !== k | 0) {\n return false;\n } else if(k < 0 || k < m - (N - n)) {\n // It's impossible to have this few successes drawn.\n return 0;\n } else if(k > n || k > m) {\n // It's impossible to have this many successes drawn.\n return 0;\n } else if (m * 2 > N) {\n // More than half the population is successes.\n\n if(n * 2 > N) {\n // More than half the population is sampled.\n\n return jStat.hypgeom.pdf(N - m - n + k, N, N - m, N - n)\n } else {\n // Half or less of the population is sampled.\n\n return jStat.hypgeom.pdf(n - k, N, N - m, n);\n }\n\n } else if(n * 2 > N) {\n // Half or less is successes.\n\n return jStat.hypgeom.pdf(m - k, N, m, N - n);\n\n } else if(m < n) {\n // We want to have the number of things sampled to be less than the\n // successes available. So swap the definitions of successful and sampled.\n return jStat.hypgeom.pdf(k, N, n, m);\n } else {\n // If we get here, half or less of the population was sampled, half or\n // less of it was successes, and we had fewer sampled things than\n // successes. Now we can do this complicated iterative algorithm in an\n // efficient way.\n\n // The basic premise of the algorithm is that we partially normalize our\n // intermediate product to keep it in a numerically good region, and then\n // finish the normalization at the end.\n\n // This variable holds the scaled probability of the current number of\n // successes.\n var scaledPDF = 1;\n\n // This keeps track of how much we have normalized.\n var samplesDone = 0;\n\n for(var i = 0; i < k; i++) {\n // For every possible number of successes up to that observed...\n\n while(scaledPDF > 1 && samplesDone < n) {\n // Intermediate result is growing too big. Apply some of the\n // normalization to shrink everything.\n\n scaledPDF *= 1 - (m / (N - samplesDone));\n\n // Say we've normalized by this sample already.\n samplesDone++;\n }\n\n // Work out the partially-normalized hypergeometric PDF for the next\n // number of successes\n scaledPDF *= (n - i) * (m - i) / ((i + 1) * (N - m - n + i + 1));\n }\n\n for(; samplesDone < n; samplesDone++) {\n // Apply all the rest of the normalization\n scaledPDF *= 1 - (m / (N - samplesDone));\n }\n\n // Bound answer sanely before returning.\n return Math.min(1, Math.max(0, scaledPDF));\n }\n },\n\n cdf: function cdf(x, N, m, n) {\n // Hypergeometric CDF.\n\n // This algorithm is due to Prof. Thomas S. Ferguson, ,\n // and comes from his hypergeometric test calculator at\n // .\n\n // x = number of successes drawn\n // N = population size\n // m = number of successes in population\n // n = number of items drawn from population\n\n if(x < 0 || x < m - (N - n)) {\n // It's impossible to have this few successes drawn or fewer.\n return 0;\n } else if(x >= n || x >= m) {\n // We will always have this many successes or fewer.\n return 1;\n } else if (m * 2 > N) {\n // More than half the population is successes.\n\n if(n * 2 > N) {\n // More than half the population is sampled.\n\n return jStat.hypgeom.cdf(N - m - n + x, N, N - m, N - n)\n } else {\n // Half or less of the population is sampled.\n\n return 1 - jStat.hypgeom.cdf(n - x - 1, N, N - m, n);\n }\n\n } else if(n * 2 > N) {\n // Half or less is successes.\n\n return 1 - jStat.hypgeom.cdf(m - x - 1, N, m, N - n);\n\n } else if(m < n) {\n // We want to have the number of things sampled to be less than the\n // successes available. So swap the definitions of successful and sampled.\n return jStat.hypgeom.cdf(x, N, n, m);\n } else {\n // If we get here, half or less of the population was sampled, half or\n // less of it was successes, and we had fewer sampled things than\n // successes. Now we can do this complicated iterative algorithm in an\n // efficient way.\n\n // The basic premise of the algorithm is that we partially normalize our\n // intermediate sum to keep it in a numerically good region, and then\n // finish the normalization at the end.\n\n // Holds the intermediate, scaled total CDF.\n var scaledCDF = 1;\n\n // This variable holds the scaled probability of the current number of\n // successes.\n var scaledPDF = 1;\n\n // This keeps track of how much we have normalized.\n var samplesDone = 0;\n\n for(var i = 0; i < x; i++) {\n // For every possible number of successes up to that observed...\n\n while(scaledCDF > 1 && samplesDone < n) {\n // Intermediate result is growing too big. Apply some of the\n // normalization to shrink everything.\n\n var factor = 1 - (m / (N - samplesDone));\n\n scaledPDF *= factor;\n scaledCDF *= factor;\n\n // Say we've normalized by this sample already.\n samplesDone++;\n }\n\n // Work out the partially-normalized hypergeometric PDF for the next\n // number of successes\n scaledPDF *= (n - i) * (m - i) / ((i + 1) * (N - m - n + i + 1));\n\n // Add to the CDF answer.\n scaledCDF += scaledPDF;\n }\n\n for(; samplesDone < n; samplesDone++) {\n // Apply all the rest of the normalization\n scaledCDF *= 1 - (m / (N - samplesDone));\n }\n\n // Bound answer sanely before returning.\n return Math.min(1, Math.max(0, scaledCDF));\n }\n }\n});\n\n\n\n// extend uniform function with static methods\njStat.extend(jStat.poisson, {\n pdf: function pdf(k, l) {\n if (l < 0 || (k % 1) !== 0 || k < 0) {\n return 0;\n }\n\n return Math.pow(l, k) * Math.exp(-l) / jStat.factorial(k);\n },\n\n cdf: function cdf(x, l) {\n var sumarr = [],\n k = 0;\n if (x < 0) return 0;\n for (; k <= x; k++) {\n sumarr.push(jStat.poisson.pdf(k, l));\n }\n return jStat.sum(sumarr);\n },\n\n mean : function(l) {\n return l;\n },\n\n variance : function(l) {\n return l;\n },\n\n sampleSmall: function sampleSmall(l) {\n var p = 1, k = 0, L = Math.exp(-l);\n do {\n k++;\n p *= jStat._random_fn();\n } while (p > L);\n return k - 1;\n },\n\n sampleLarge: function sampleLarge(l) {\n var lam = l;\n var k;\n var U, V, slam, loglam, a, b, invalpha, vr, us;\n\n slam = Math.sqrt(lam);\n loglam = Math.log(lam);\n b = 0.931 + 2.53 * slam;\n a = -0.059 + 0.02483 * b;\n invalpha = 1.1239 + 1.1328 / (b - 3.4);\n vr = 0.9277 - 3.6224 / (b - 2);\n\n while (1) {\n U = Math.random() - 0.5;\n V = Math.random();\n us = 0.5 - Math.abs(U);\n k = Math.floor((2 * a / us + b) * U + lam + 0.43);\n if ((us >= 0.07) && (V <= vr)) {\n return k;\n }\n if ((k < 0) || ((us < 0.013) && (V > us))) {\n continue;\n }\n /* log(V) == log(0.0) ok here */\n /* if U==0.0 so that us==0.0, log is ok since always returns */\n if ((Math.log(V) + Math.log(invalpha) - Math.log(a / (us * us) + b)) <= (-lam + k * loglam - jStat.loggam(k + 1))) {\n return k;\n }\n }\n },\n\n sample: function sample(l) {\n if (l < 10)\n return this.sampleSmall(l);\n else\n return this.sampleLarge(l);\n }\n});\n\n// extend triangular function with static methods\njStat.extend(jStat.triangular, {\n pdf: function pdf(x, a, b, c) {\n if (b <= a || c < a || c > b) {\n return NaN;\n } else {\n if (x < a || x > b) {\n return 0;\n } else if (x < c) {\n return (2 * (x - a)) / ((b - a) * (c - a));\n } else if (x === c) {\n return (2 / (b - a));\n } else { // x > c\n return (2 * (b - x)) / ((b - a) * (b - c));\n }\n }\n },\n\n cdf: function cdf(x, a, b, c) {\n if (b <= a || c < a || c > b)\n return NaN;\n if (x <= a)\n return 0;\n else if (x >= b)\n return 1;\n if (x <= c)\n return Math.pow(x - a, 2) / ((b - a) * (c - a));\n else // x > c\n return 1 - Math.pow(b - x, 2) / ((b - a) * (b - c));\n },\n\n inv: function inv(p, a, b, c) {\n if (b <= a || c < a || c > b) {\n return NaN;\n } else {\n if (p <= ((c - a) / (b - a))) {\n return a + (b - a) * Math.sqrt(p * ((c - a) / (b - a)));\n } else { // p > ((c - a) / (b - a))\n return a + (b - a) * (1 - Math.sqrt((1 - p) * (1 - ((c - a) / (b - a)))));\n }\n }\n },\n\n mean: function mean(a, b, c) {\n return (a + b + c) / 3;\n },\n\n median: function median(a, b, c) {\n if (c <= (a + b) / 2) {\n return b - Math.sqrt((b - a) * (b - c)) / Math.sqrt(2);\n } else if (c > (a + b) / 2) {\n return a + Math.sqrt((b - a) * (c - a)) / Math.sqrt(2);\n }\n },\n\n mode: function mode(a, b, c) {\n return c;\n },\n\n sample: function sample(a, b, c) {\n var u = jStat._random_fn();\n if (u < ((c - a) / (b - a)))\n return a + Math.sqrt(u * (b - a) * (c - a))\n return b - Math.sqrt((1 - u) * (b - a) * (b - c));\n },\n\n variance: function variance(a, b, c) {\n return (a * a + b * b + c * c - a * b - a * c - b * c) / 18;\n }\n});\n\n\n// extend arcsine function with static methods\njStat.extend(jStat.arcsine, {\n pdf: function pdf(x, a, b) {\n if (b <= a) return NaN;\n\n return (x <= a || x >= b) ? 0 :\n (2 / Math.PI) *\n Math.pow(Math.pow(b - a, 2) -\n Math.pow(2 * x - a - b, 2), -0.5);\n },\n\n cdf: function cdf(x, a, b) {\n if (x < a)\n return 0;\n else if (x < b)\n return (2 / Math.PI) * Math.asin(Math.sqrt((x - a)/(b - a)));\n return 1;\n },\n\n inv: function(p, a, b) {\n return a + (0.5 - 0.5 * Math.cos(Math.PI * p)) * (b - a);\n },\n\n mean: function mean(a, b) {\n if (b <= a) return NaN;\n return (a + b) / 2;\n },\n\n median: function median(a, b) {\n if (b <= a) return NaN;\n return (a + b) / 2;\n },\n\n mode: function mode(/*a, b*/) {\n throw new Error('mode is not yet implemented');\n },\n\n sample: function sample(a, b) {\n return ((a + b) / 2) + ((b - a) / 2) *\n Math.sin(2 * Math.PI * jStat.uniform.sample(0, 1));\n },\n\n variance: function variance(a, b) {\n if (b <= a) return NaN;\n return Math.pow(b - a, 2) / 8;\n }\n});\n\n\nfunction laplaceSign(x) { return x / Math.abs(x); }\n\njStat.extend(jStat.laplace, {\n pdf: function pdf(x, mu, b) {\n return (b <= 0) ? 0 : (Math.exp(-Math.abs(x - mu) / b)) / (2 * b);\n },\n\n cdf: function cdf(x, mu, b) {\n if (b <= 0) { return 0; }\n\n if(x < mu) {\n return 0.5 * Math.exp((x - mu) / b);\n } else {\n return 1 - 0.5 * Math.exp(- (x - mu) / b);\n }\n },\n\n mean: function(mu/*, b*/) {\n return mu;\n },\n\n median: function(mu/*, b*/) {\n return mu;\n },\n\n mode: function(mu/*, b*/) {\n return mu;\n },\n\n variance: function(mu, b) {\n return 2 * b * b;\n },\n\n sample: function sample(mu, b) {\n var u = jStat._random_fn() - 0.5;\n\n return mu - (b * laplaceSign(u) * Math.log(1 - (2 * Math.abs(u))));\n }\n});\n\nfunction tukeyWprob(w, rr, cc) {\n var nleg = 12;\n var ihalf = 6;\n\n var C1 = -30;\n var C2 = -50;\n var C3 = 60;\n var bb = 8;\n var wlar = 3;\n var wincr1 = 2;\n var wincr2 = 3;\n var xleg = [\n 0.981560634246719250690549090149,\n 0.904117256370474856678465866119,\n 0.769902674194304687036893833213,\n 0.587317954286617447296702418941,\n 0.367831498998180193752691536644,\n 0.125233408511468915472441369464\n ];\n var aleg = [\n 0.047175336386511827194615961485,\n 0.106939325995318430960254718194,\n 0.160078328543346226334652529543,\n 0.203167426723065921749064455810,\n 0.233492536538354808760849898925,\n 0.249147045813402785000562436043\n ];\n\n var qsqz = w * 0.5;\n\n // if w >= 16 then the integral lower bound (occurs for c=20)\n // is 0.99999999999995 so return a value of 1.\n\n if (qsqz >= bb)\n return 1.0;\n\n // find (f(w/2) - 1) ^ cc\n // (first term in integral of hartley's form).\n\n var pr_w = 2 * jStat.normal.cdf(qsqz, 0, 1, 1, 0) - 1; // erf(qsqz / M_SQRT2)\n // if pr_w ^ cc < 2e-22 then set pr_w = 0\n if (pr_w >= Math.exp(C2 / cc))\n pr_w = Math.pow(pr_w, cc);\n else\n pr_w = 0.0;\n\n // if w is large then the second component of the\n // integral is small, so fewer intervals are needed.\n\n var wincr;\n if (w > wlar)\n wincr = wincr1;\n else\n wincr = wincr2;\n\n // find the integral of second term of hartley's form\n // for the integral of the range for equal-length\n // intervals using legendre quadrature. limits of\n // integration are from (w/2, 8). two or three\n // equal-length intervals are used.\n\n // blb and bub are lower and upper limits of integration.\n\n var blb = qsqz;\n var binc = (bb - qsqz) / wincr;\n var bub = blb + binc;\n var einsum = 0.0;\n\n // integrate over each interval\n\n var cc1 = cc - 1.0;\n for (var wi = 1; wi <= wincr; wi++) {\n var elsum = 0.0;\n var a = 0.5 * (bub + blb);\n\n // legendre quadrature with order = nleg\n\n var b = 0.5 * (bub - blb);\n\n for (var jj = 1; jj <= nleg; jj++) {\n var j, xx;\n if (ihalf < jj) {\n j = (nleg - jj) + 1;\n xx = xleg[j-1];\n } else {\n j = jj;\n xx = -xleg[j-1];\n }\n var c = b * xx;\n var ac = a + c;\n\n // if exp(-qexpo/2) < 9e-14,\n // then doesn't contribute to integral\n\n var qexpo = ac * ac;\n if (qexpo > C3)\n break;\n\n var pplus = 2 * jStat.normal.cdf(ac, 0, 1, 1, 0);\n var pminus= 2 * jStat.normal.cdf(ac, w, 1, 1, 0);\n\n // if rinsum ^ (cc-1) < 9e-14,\n // then doesn't contribute to integral\n\n var rinsum = (pplus * 0.5) - (pminus * 0.5);\n if (rinsum >= Math.exp(C1 / cc1)) {\n rinsum = (aleg[j-1] * Math.exp(-(0.5 * qexpo))) * Math.pow(rinsum, cc1);\n elsum += rinsum;\n }\n }\n elsum *= (((2.0 * b) * cc) / Math.sqrt(2 * Math.PI));\n einsum += elsum;\n blb = bub;\n bub += binc;\n }\n\n // if pr_w ^ rr < 9e-14, then return 0\n pr_w += einsum;\n if (pr_w <= Math.exp(C1 / rr))\n return 0;\n\n pr_w = Math.pow(pr_w, rr);\n if (pr_w >= 1) // 1 was iMax was eps\n return 1;\n return pr_w;\n}\n\nfunction tukeyQinv(p, c, v) {\n var p0 = 0.322232421088;\n var q0 = 0.993484626060e-01;\n var p1 = -1.0;\n var q1 = 0.588581570495;\n var p2 = -0.342242088547;\n var q2 = 0.531103462366;\n var p3 = -0.204231210125;\n var q3 = 0.103537752850;\n var p4 = -0.453642210148e-04;\n var q4 = 0.38560700634e-02;\n var c1 = 0.8832;\n var c2 = 0.2368;\n var c3 = 1.214;\n var c4 = 1.208;\n var c5 = 1.4142;\n var vmax = 120.0;\n\n var ps = 0.5 - 0.5 * p;\n var yi = Math.sqrt(Math.log(1.0 / (ps * ps)));\n var t = yi + (((( yi * p4 + p3) * yi + p2) * yi + p1) * yi + p0)\n / (((( yi * q4 + q3) * yi + q2) * yi + q1) * yi + q0);\n if (v < vmax) t += (t * t * t + t) / v / 4.0;\n var q = c1 - c2 * t;\n if (v < vmax) q += -c3 / v + c4 * t / v;\n return t * (q * Math.log(c - 1.0) + c5);\n}\n\njStat.extend(jStat.tukey, {\n cdf: function cdf(q, nmeans, df) {\n // Identical implementation as the R ptukey() function as of commit 68947\n var rr = 1;\n var cc = nmeans;\n\n var nlegq = 16;\n var ihalfq = 8;\n\n var eps1 = -30.0;\n var eps2 = 1.0e-14;\n var dhaf = 100.0;\n var dquar = 800.0;\n var deigh = 5000.0;\n var dlarg = 25000.0;\n var ulen1 = 1.0;\n var ulen2 = 0.5;\n var ulen3 = 0.25;\n var ulen4 = 0.125;\n var xlegq = [\n 0.989400934991649932596154173450,\n 0.944575023073232576077988415535,\n 0.865631202387831743880467897712,\n 0.755404408355003033895101194847,\n 0.617876244402643748446671764049,\n 0.458016777657227386342419442984,\n 0.281603550779258913230460501460,\n 0.950125098376374401853193354250e-1\n ];\n var alegq = [\n 0.271524594117540948517805724560e-1,\n 0.622535239386478928628438369944e-1,\n 0.951585116824927848099251076022e-1,\n 0.124628971255533872052476282192,\n 0.149595988816576732081501730547,\n 0.169156519395002538189312079030,\n 0.182603415044923588866763667969,\n 0.189450610455068496285396723208\n ];\n\n if (q <= 0)\n return 0;\n\n // df must be > 1\n // there must be at least two values\n\n if (df < 2 || rr < 1 || cc < 2) return NaN;\n\n if (!Number.isFinite(q))\n return 1;\n\n if (df > dlarg)\n return tukeyWprob(q, rr, cc);\n\n // calculate leading constant\n\n var f2 = df * 0.5;\n var f2lf = ((f2 * Math.log(df)) - (df * Math.log(2))) - jStat.gammaln(f2);\n var f21 = f2 - 1.0;\n\n // integral is divided into unit, half-unit, quarter-unit, or\n // eighth-unit length intervals depending on the value of the\n // degrees of freedom.\n\n var ff4 = df * 0.25;\n var ulen;\n if (df <= dhaf) ulen = ulen1;\n else if (df <= dquar) ulen = ulen2;\n else if (df <= deigh) ulen = ulen3;\n else ulen = ulen4;\n\n f2lf += Math.log(ulen);\n\n // integrate over each subinterval\n\n var ans = 0.0;\n\n for (var i = 1; i <= 50; i++) {\n var otsum = 0.0;\n\n // legendre quadrature with order = nlegq\n // nodes (stored in xlegq) are symmetric around zero.\n\n var twa1 = (2 * i - 1) * ulen;\n\n for (var jj = 1; jj <= nlegq; jj++) {\n var j, t1;\n if (ihalfq < jj) {\n j = jj - ihalfq - 1;\n t1 = (f2lf + (f21 * Math.log(twa1 + (xlegq[j] * ulen))))\n - (((xlegq[j] * ulen) + twa1) * ff4);\n } else {\n j = jj - 1;\n t1 = (f2lf + (f21 * Math.log(twa1 - (xlegq[j] * ulen))))\n + (((xlegq[j] * ulen) - twa1) * ff4);\n }\n\n // if exp(t1) < 9e-14, then doesn't contribute to integral\n var qsqz;\n if (t1 >= eps1) {\n if (ihalfq < jj) {\n qsqz = q * Math.sqrt(((xlegq[j] * ulen) + twa1) * 0.5);\n } else {\n qsqz = q * Math.sqrt(((-(xlegq[j] * ulen)) + twa1) * 0.5);\n }\n\n // call wprob to find integral of range portion\n\n var wprb = tukeyWprob(qsqz, rr, cc);\n var rotsum = (wprb * alegq[j]) * Math.exp(t1);\n otsum += rotsum;\n }\n // end legendre integral for interval i\n // L200:\n }\n\n // if integral for interval i < 1e-14, then stop.\n // However, in order to avoid small area under left tail,\n // at least 1 / ulen intervals are calculated.\n if (i * ulen >= 1.0 && otsum <= eps2)\n break;\n\n // end of interval i\n // L330:\n\n ans += otsum;\n }\n\n if (otsum > eps2) { // not converged\n throw new Error('tukey.cdf failed to converge');\n }\n if (ans > 1)\n ans = 1;\n return ans;\n },\n\n inv: function(p, nmeans, df) {\n // Identical implementation as the R qtukey() function as of commit 68947\n var rr = 1;\n var cc = nmeans;\n\n var eps = 0.0001;\n var maxiter = 50;\n\n // df must be > 1 ; there must be at least two values\n if (df < 2 || rr < 1 || cc < 2) return NaN;\n\n if (p < 0 || p > 1) return NaN;\n if (p === 0) return 0;\n if (p === 1) return Infinity;\n\n // Initial value\n\n var x0 = tukeyQinv(p, cc, df);\n\n // Find prob(value < x0)\n\n var valx0 = jStat.tukey.cdf(x0, nmeans, df) - p;\n\n // Find the second iterate and prob(value < x1).\n // If the first iterate has probability value\n // exceeding p then second iterate is 1 less than\n // first iterate; otherwise it is 1 greater.\n\n var x1;\n if (valx0 > 0.0)\n x1 = Math.max(0.0, x0 - 1.0);\n else\n x1 = x0 + 1.0;\n var valx1 = jStat.tukey.cdf(x1, nmeans, df) - p;\n\n // Find new iterate\n\n var ans;\n for(var iter = 1; iter < maxiter; iter++) {\n ans = x1 - ((valx1 * (x1 - x0)) / (valx1 - valx0));\n valx0 = valx1;\n\n // New iterate must be >= 0\n\n x0 = x1;\n if (ans < 0.0) {\n ans = 0.0;\n valx1 = -p;\n }\n // Find prob(value < new iterate)\n\n valx1 = jStat.tukey.cdf(ans, nmeans, df) - p;\n x1 = ans;\n\n // If the difference between two successive\n // iterates is less than eps, stop\n\n var xabs = Math.abs(x1 - x0);\n if (xabs < eps)\n return ans;\n }\n\n throw new Error('tukey.inv failed to converge');\n }\n});\n\n}(jStat, Math));\n/* Provides functions for the solution of linear system of equations, integration, extrapolation,\n * interpolation, eigenvalue problems, differential equations and PCA analysis. */\n\n(function(jStat, Math) {\n\nvar push = Array.prototype.push;\nvar isArray = jStat.utils.isArray;\n\nfunction isUsable(arg) {\n return isArray(arg) || arg instanceof jStat;\n}\n\njStat.extend({\n\n // add a vector/matrix to a vector/matrix or scalar\n add: function add(arr, arg) {\n // check if arg is a vector or scalar\n if (isUsable(arg)) {\n if (!isUsable(arg[0])) arg = [ arg ];\n return jStat.map(arr, function(value, row, col) {\n return value + arg[row][col];\n });\n }\n return jStat.map(arr, function(value) { return value + arg; });\n },\n\n // subtract a vector or scalar from the vector\n subtract: function subtract(arr, arg) {\n // check if arg is a vector or scalar\n if (isUsable(arg)) {\n if (!isUsable(arg[0])) arg = [ arg ];\n return jStat.map(arr, function(value, row, col) {\n return value - arg[row][col] || 0;\n });\n }\n return jStat.map(arr, function(value) { return value - arg; });\n },\n\n // matrix division\n divide: function divide(arr, arg) {\n if (isUsable(arg)) {\n if (!isUsable(arg[0])) arg = [ arg ];\n return jStat.multiply(arr, jStat.inv(arg));\n }\n return jStat.map(arr, function(value) { return value / arg; });\n },\n\n // matrix multiplication\n multiply: function multiply(arr, arg) {\n var row, col, nrescols, sum, nrow, ncol, res, rescols;\n // eg: arr = 2 arg = 3 -> 6 for res[0][0] statement closure\n if (arr.length === undefined && arg.length === undefined) {\n return arr * arg;\n }\n nrow = arr.length,\n ncol = arr[0].length,\n res = jStat.zeros(nrow, nrescols = (isUsable(arg)) ? arg[0].length : ncol),\n rescols = 0;\n if (isUsable(arg)) {\n for (; rescols < nrescols; rescols++) {\n for (row = 0; row < nrow; row++) {\n sum = 0;\n for (col = 0; col < ncol; col++)\n sum += arr[row][col] * arg[col][rescols];\n res[row][rescols] = sum;\n }\n }\n return (nrow === 1 && rescols === 1) ? res[0][0] : res;\n }\n return jStat.map(arr, function(value) { return value * arg; });\n },\n\n // outer([1,2,3],[4,5,6])\n // ===\n // [[1],[2],[3]] times [[4,5,6]]\n // ->\n // [[4,5,6],[8,10,12],[12,15,18]]\n outer:function outer(A, B) {\n return jStat.multiply(A.map(function(t){ return [t] }), [B]);\n },\n\n\n // Returns the dot product of two matricies\n dot: function dot(arr, arg) {\n if (!isUsable(arr[0])) arr = [ arr ];\n if (!isUsable(arg[0])) arg = [ arg ];\n // convert column to row vector\n var left = (arr[0].length === 1 && arr.length !== 1) ? jStat.transpose(arr) : arr,\n right = (arg[0].length === 1 && arg.length !== 1) ? jStat.transpose(arg) : arg,\n res = [],\n row = 0,\n nrow = left.length,\n ncol = left[0].length,\n sum, col;\n for (; row < nrow; row++) {\n res[row] = [];\n sum = 0;\n for (col = 0; col < ncol; col++)\n sum += left[row][col] * right[row][col];\n res[row] = sum;\n }\n return (res.length === 1) ? res[0] : res;\n },\n\n // raise every element by a scalar\n pow: function pow(arr, arg) {\n return jStat.map(arr, function(value) { return Math.pow(value, arg); });\n },\n\n // exponentiate every element\n exp: function exp(arr) {\n return jStat.map(arr, function(value) { return Math.exp(value); });\n },\n\n // generate the natural log of every element\n log: function exp(arr) {\n return jStat.map(arr, function(value) { return Math.log(value); });\n },\n\n // generate the absolute values of the vector\n abs: function abs(arr) {\n return jStat.map(arr, function(value) { return Math.abs(value); });\n },\n\n // computes the p-norm of the vector\n // In the case that a matrix is passed, uses the first row as the vector\n norm: function norm(arr, p) {\n var nnorm = 0,\n i = 0;\n // check the p-value of the norm, and set for most common case\n if (isNaN(p)) p = 2;\n // check if multi-dimensional array, and make vector correction\n if (isUsable(arr[0])) arr = arr[0];\n // vector norm\n for (; i < arr.length; i++) {\n nnorm += Math.pow(Math.abs(arr[i]), p);\n }\n return Math.pow(nnorm, 1 / p);\n },\n\n // computes the angle between two vectors in rads\n // In case a matrix is passed, this uses the first row as the vector\n angle: function angle(arr, arg) {\n return Math.acos(jStat.dot(arr, arg) / (jStat.norm(arr) * jStat.norm(arg)));\n },\n\n // augment one matrix by another\n // Note: this function returns a matrix, not a jStat object\n aug: function aug(a, b) {\n var newarr = [];\n var i;\n for (i = 0; i < a.length; i++) {\n newarr.push(a[i].slice());\n }\n for (i = 0; i < newarr.length; i++) {\n push.apply(newarr[i], b[i]);\n }\n return newarr;\n },\n\n // The inv() function calculates the inverse of a matrix\n // Create the inverse by augmenting the matrix by the identity matrix of the\n // appropriate size, and then use G-J elimination on the augmented matrix.\n inv: function inv(a) {\n var rows = a.length;\n var cols = a[0].length;\n var b = jStat.identity(rows, cols);\n var c = jStat.gauss_jordan(a, b);\n var result = [];\n var i = 0;\n var j;\n\n //We need to copy the inverse portion to a new matrix to rid G-J artifacts\n for (; i < rows; i++) {\n result[i] = [];\n for (j = cols; j < c[0].length; j++)\n result[i][j - cols] = c[i][j];\n }\n return result;\n },\n\n // calculate the determinant of a matrix\n det: function det(a) {\n if (a.length === 2) {\n return a[0][0] * a[1][1] - a[0][1] * a[1][0];\n }\n\n var determinant = 0;\n for (var i = 0; i < a.length; i++) {\n // build a sub matrix without column `i`\n var submatrix = [];\n for (var row = 1; row < a.length; row++) {\n submatrix[row - 1] = [];\n for (var col = 0; col < a.length; col++) {\n if (col < i) {\n submatrix[row - 1][col] = a[row][col];\n } else if (col > i) {\n submatrix[row - 1][col - 1] = a[row][col];\n }\n }\n }\n\n // alternate between + and - between determinants\n var sign = i % 2 ? -1 : 1;\n determinant += det(submatrix) * a[0][i] * sign;\n }\n\n return determinant\n },\n\n gauss_elimination: function gauss_elimination(a, b) {\n var i = 0,\n j = 0,\n n = a.length,\n m = a[0].length,\n factor = 1,\n sum = 0,\n x = [],\n maug, pivot, temp, k;\n a = jStat.aug(a, b);\n maug = a[0].length;\n for(i = 0; i < n; i++) {\n pivot = a[i][i];\n j = i;\n for (k = i + 1; k < m; k++) {\n if (pivot < Math.abs(a[k][i])) {\n pivot = a[k][i];\n j = k;\n }\n }\n if (j != i) {\n for(k = 0; k < maug; k++) {\n temp = a[i][k];\n a[i][k] = a[j][k];\n a[j][k] = temp;\n }\n }\n for (j = i + 1; j < n; j++) {\n factor = a[j][i] / a[i][i];\n for(k = i; k < maug; k++) {\n a[j][k] = a[j][k] - factor * a[i][k];\n }\n }\n }\n for (i = n - 1; i >= 0; i--) {\n sum = 0;\n for (j = i + 1; j<= n - 1; j++) {\n sum = sum + x[j] * a[i][j];\n }\n x[i] =(a[i][maug - 1] - sum) / a[i][i];\n }\n return x;\n },\n\n gauss_jordan: function gauss_jordan(a, b) {\n var m = jStat.aug(a, b);\n var h = m.length;\n var w = m[0].length;\n var c = 0;\n var x, y, y2;\n // find max pivot\n for (y = 0; y < h; y++) {\n var maxrow = y;\n for (y2 = y+1; y2 < h; y2++) {\n if (Math.abs(m[y2][y]) > Math.abs(m[maxrow][y]))\n maxrow = y2;\n }\n var tmp = m[y];\n m[y] = m[maxrow];\n m[maxrow] = tmp\n for (y2 = y+1; y2 < h; y2++) {\n c = m[y2][y] / m[y][y];\n for (x = y; x < w; x++) {\n m[y2][x] -= m[y][x] * c;\n }\n }\n }\n // backsubstitute\n for (y = h-1; y >= 0; y--) {\n c = m[y][y];\n for (y2 = 0; y2 < y; y2++) {\n for (x = w-1; x > y-1; x--) {\n m[y2][x] -= m[y][x] * m[y2][y] / c;\n }\n }\n m[y][y] /= c;\n for (x = h; x < w; x++) {\n m[y][x] /= c;\n }\n }\n return m;\n },\n\n // solve equation\n // Ax=b\n // A is upper triangular matrix\n // A=[[1,2,3],[0,4,5],[0,6,7]]\n // b=[1,2,3]\n // triaUpSolve(A,b) // -> [2.666,0.1666,1.666]\n // if you use matrix style\n // A=[[1,2,3],[0,4,5],[0,6,7]]\n // b=[[1],[2],[3]]\n // will return [[2.666],[0.1666],[1.666]]\n triaUpSolve: function triaUpSolve(A, b) {\n var size = A[0].length;\n var x = jStat.zeros(1, size)[0];\n var parts;\n var matrix_mode = false;\n\n if (b[0].length != undefined) {\n b = b.map(function(i){ return i[0] });\n matrix_mode = true;\n }\n\n jStat.arange(size - 1, -1, -1).forEach(function(i) {\n parts = jStat.arange(i + 1, size).map(function(j) {\n return x[j] * A[i][j];\n });\n x[i] = (b[i] - jStat.sum(parts)) / A[i][i];\n });\n\n if (matrix_mode)\n return x.map(function(i){ return [i] });\n return x;\n },\n\n triaLowSolve: function triaLowSolve(A, b) {\n // like to triaUpSolve but A is lower triangular matrix\n var size = A[0].length;\n var x = jStat.zeros(1, size)[0];\n var parts;\n\n var matrix_mode=false;\n if (b[0].length != undefined) {\n b = b.map(function(i){ return i[0] });\n matrix_mode = true;\n }\n\n jStat.arange(size).forEach(function(i) {\n parts = jStat.arange(i).map(function(j) {\n return A[i][j] * x[j];\n });\n x[i] = (b[i] - jStat.sum(parts)) / A[i][i];\n })\n\n if (matrix_mode)\n return x.map(function(i){ return [i] });\n return x;\n },\n\n\n // A -> [L,U]\n // A=LU\n // L is lower triangular matrix\n // U is upper triangular matrix\n lu: function lu(A) {\n var size = A.length;\n //var L=jStat.diagonal(jStat.ones(1,size)[0]);\n var L = jStat.identity(size);\n var R = jStat.zeros(A.length, A[0].length);\n var parts;\n jStat.arange(size).forEach(function(t) {\n R[0][t] = A[0][t];\n });\n jStat.arange(1, size).forEach(function(l) {\n jStat.arange(l).forEach(function(i) {\n parts = jStat.arange(i).map(function(jj) {\n return L[l][jj] * R[jj][i];\n });\n L[l][i] = (A[l][i] - jStat.sum(parts)) / R[i][i];\n });\n jStat.arange(l, size).forEach(function(j) {\n parts = jStat.arange(l).map(function(jj) {\n return L[l][jj] * R[jj][j];\n });\n R[l][j] = A[parts.length][j] - jStat.sum(parts);\n });\n });\n return [L, R];\n },\n\n // A -> T\n // A=TT'\n // T is lower triangular matrix\n cholesky: function cholesky(A) {\n var size = A.length;\n var T = jStat.zeros(A.length, A[0].length);\n var parts;\n jStat.arange(size).forEach(function(i) {\n parts = jStat.arange(i).map(function(t) {\n return Math.pow(T[i][t],2);\n });\n T[i][i] = Math.sqrt(A[i][i] - jStat.sum(parts));\n jStat.arange(i + 1, size).forEach(function(j) {\n parts = jStat.arange(i).map(function(t) {\n return T[i][t] * T[j][t];\n });\n T[j][i] = (A[i][j] - jStat.sum(parts)) / T[i][i];\n });\n });\n return T;\n },\n\n\n gauss_jacobi: function gauss_jacobi(a, b, x, r) {\n var i = 0;\n var j = 0;\n var n = a.length;\n var l = [];\n var u = [];\n var d = [];\n var xv, c, h, xk;\n for (; i < n; i++) {\n l[i] = [];\n u[i] = [];\n d[i] = [];\n for (j = 0; j < n; j++) {\n if (i > j) {\n l[i][j] = a[i][j];\n u[i][j] = d[i][j] = 0;\n } else if (i < j) {\n u[i][j] = a[i][j];\n l[i][j] = d[i][j] = 0;\n } else {\n d[i][j] = a[i][j];\n l[i][j] = u[i][j] = 0;\n }\n }\n }\n h = jStat.multiply(jStat.multiply(jStat.inv(d), jStat.add(l, u)), -1);\n c = jStat.multiply(jStat.inv(d), b);\n xv = x;\n xk = jStat.add(jStat.multiply(h, x), c);\n i = 2;\n while (Math.abs(jStat.norm(jStat.subtract(xk,xv))) > r) {\n xv = xk;\n xk = jStat.add(jStat.multiply(h, xv), c);\n i++;\n }\n return xk;\n },\n\n gauss_seidel: function gauss_seidel(a, b, x, r) {\n var i = 0;\n var n = a.length;\n var l = [];\n var u = [];\n var d = [];\n var j, xv, c, h, xk;\n for (; i < n; i++) {\n l[i] = [];\n u[i] = [];\n d[i] = [];\n for (j = 0; j < n; j++) {\n if (i > j) {\n l[i][j] = a[i][j];\n u[i][j] = d[i][j] = 0;\n } else if (i < j) {\n u[i][j] = a[i][j];\n l[i][j] = d[i][j] = 0;\n } else {\n d[i][j] = a[i][j];\n l[i][j] = u[i][j] = 0;\n }\n }\n }\n h = jStat.multiply(jStat.multiply(jStat.inv(jStat.add(d, l)), u), -1);\n c = jStat.multiply(jStat.inv(jStat.add(d, l)), b);\n xv = x;\n xk = jStat.add(jStat.multiply(h, x), c);\n i = 2;\n while (Math.abs(jStat.norm(jStat.subtract(xk, xv))) > r) {\n xv = xk;\n xk = jStat.add(jStat.multiply(h, xv), c);\n i = i + 1;\n }\n return xk;\n },\n\n SOR: function SOR(a, b, x, r, w) {\n var i = 0;\n var n = a.length;\n var l = [];\n var u = [];\n var d = [];\n var j, xv, c, h, xk;\n for (; i < n; i++) {\n l[i] = [];\n u[i] = [];\n d[i] = [];\n for (j = 0; j < n; j++) {\n if (i > j) {\n l[i][j] = a[i][j];\n u[i][j] = d[i][j] = 0;\n } else if (i < j) {\n u[i][j] = a[i][j];\n l[i][j] = d[i][j] = 0;\n } else {\n d[i][j] = a[i][j];\n l[i][j] = u[i][j] = 0;\n }\n }\n }\n h = jStat.multiply(jStat.inv(jStat.add(d, jStat.multiply(l, w))),\n jStat.subtract(jStat.multiply(d, 1 - w),\n jStat.multiply(u, w)));\n c = jStat.multiply(jStat.multiply(jStat.inv(jStat.add(d,\n jStat.multiply(l, w))), b), w);\n xv = x;\n xk = jStat.add(jStat.multiply(h, x), c);\n i = 2;\n while (Math.abs(jStat.norm(jStat.subtract(xk, xv))) > r) {\n xv = xk;\n xk = jStat.add(jStat.multiply(h, xv), c);\n i++;\n }\n return xk;\n },\n\n householder: function householder(a) {\n var m = a.length;\n var n = a[0].length;\n var i = 0;\n var w = [];\n var p = [];\n var alpha, r, k, j, factor;\n for (; i < m - 1; i++) {\n alpha = 0;\n for (j = i + 1; j < n; j++)\n alpha += (a[j][i] * a[j][i]);\n factor = (a[i + 1][i] > 0) ? -1 : 1;\n alpha = factor * Math.sqrt(alpha);\n r = Math.sqrt((((alpha * alpha) - a[i + 1][i] * alpha) / 2));\n w = jStat.zeros(m, 1);\n w[i + 1][0] = (a[i + 1][i] - alpha) / (2 * r);\n for (k = i + 2; k < m; k++) w[k][0] = a[k][i] / (2 * r);\n p = jStat.subtract(jStat.identity(m, n),\n jStat.multiply(jStat.multiply(w, jStat.transpose(w)), 2));\n a = jStat.multiply(p, jStat.multiply(a, p));\n }\n return a;\n },\n\n // A -> [Q,R]\n // Q is orthogonal matrix\n // R is upper triangular\n QR: (function() {\n // x -> Q\n // find a orthogonal matrix Q st.\n // Qx=y\n // y is [||x||,0,0,...]\n\n // quick ref\n var sum = jStat.sum;\n var range = jStat.arange;\n\n function qr2(x) {\n // quick impletation\n // https://www.stat.wisc.edu/~larget/math496/qr.html\n\n var n = x.length;\n var p = x[0].length;\n\n var r = jStat.zeros(p, p);\n x = jStat.copy(x);\n\n var i,j,k;\n for(j = 0; j < p; j++){\n r[j][j] = Math.sqrt(sum(range(n).map(function(i){\n return x[i][j] * x[i][j];\n })));\n for(i = 0; i < n; i++){\n x[i][j] = x[i][j] / r[j][j];\n }\n for(k = j+1; k < p; k++){\n r[j][k] = sum(range(n).map(function(i){\n return x[i][j] * x[i][k];\n }));\n for(i = 0; i < n; i++){\n x[i][k] = x[i][k] - x[i][j]*r[j][k];\n }\n }\n }\n return [x, r];\n }\n\n return qr2;\n }()),\n\n lstsq: (function() {\n // solve least squard problem for Ax=b as QR decomposition way if b is\n // [[b1],[b2],[b3]] form will return [[x1],[x2],[x3]] array form solution\n // else b is [b1,b2,b3] form will return [x1,x2,x3] array form solution\n function R_I(A) {\n A = jStat.copy(A);\n var size = A.length;\n var I = jStat.identity(size);\n jStat.arange(size - 1, -1, -1).forEach(function(i) {\n jStat.sliceAssign(\n I, { row: i }, jStat.divide(jStat.slice(I, { row: i }), A[i][i]));\n jStat.sliceAssign(\n A, { row: i }, jStat.divide(jStat.slice(A, { row: i }), A[i][i]));\n jStat.arange(i).forEach(function(j) {\n var c = jStat.multiply(A[j][i], -1);\n var Aj = jStat.slice(A, { row: j });\n var cAi = jStat.multiply(jStat.slice(A, { row: i }), c);\n jStat.sliceAssign(A, { row: j }, jStat.add(Aj, cAi));\n var Ij = jStat.slice(I, { row: j });\n var cIi = jStat.multiply(jStat.slice(I, { row: i }), c);\n jStat.sliceAssign(I, { row: j }, jStat.add(Ij, cIi));\n })\n });\n return I;\n }\n\n function qr_solve(A, b){\n var array_mode = false;\n if (b[0].length === undefined) {\n // [c1,c2,c3] mode\n b = b.map(function(x){ return [x] });\n array_mode = true;\n }\n var QR = jStat.QR(A);\n var Q = QR[0];\n var R = QR[1];\n var attrs = A[0].length;\n var Q1 = jStat.slice(Q,{col:{end:attrs}});\n var R1 = jStat.slice(R,{row:{end:attrs}});\n var RI = R_I(R1);\n var Q2 = jStat.transpose(Q1);\n\n if(Q2[0].length === undefined){\n Q2 = [Q2]; // The confusing jStat.multifly implementation threat nature process again.\n }\n\n var x = jStat.multiply(jStat.multiply(RI, Q2), b);\n\n if(x.length === undefined){\n x = [[x]]; // The confusing jStat.multifly implementation threat nature process again.\n }\n\n\n if (array_mode)\n return x.map(function(i){ return i[0] });\n return x;\n }\n\n return qr_solve;\n }()),\n\n jacobi: function jacobi(a) {\n var condition = 1;\n var n = a.length;\n var e = jStat.identity(n, n);\n var ev = [];\n var b, i, j, p, q, maxim, theta, s;\n // condition === 1 only if tolerance is not reached\n while (condition === 1) {\n maxim = a[0][1];\n p = 0;\n q = 1;\n for (i = 0; i < n; i++) {\n for (j = 0; j < n; j++) {\n if (i != j) {\n if (maxim < Math.abs(a[i][j])) {\n maxim = Math.abs(a[i][j]);\n p = i;\n q = j;\n }\n }\n }\n }\n if (a[p][p] === a[q][q])\n theta = (a[p][q] > 0) ? Math.PI / 4 : -Math.PI / 4;\n else\n theta = Math.atan(2 * a[p][q] / (a[p][p] - a[q][q])) / 2;\n s = jStat.identity(n, n);\n s[p][p] = Math.cos(theta);\n s[p][q] = -Math.sin(theta);\n s[q][p] = Math.sin(theta);\n s[q][q] = Math.cos(theta);\n // eigen vector matrix\n e = jStat.multiply(e, s);\n b = jStat.multiply(jStat.multiply(jStat.inv(s), a), s);\n a = b;\n condition = 0;\n for (i = 1; i < n; i++) {\n for (j = 1; j < n; j++) {\n if (i != j && Math.abs(a[i][j]) > 0.001) {\n condition = 1;\n }\n }\n }\n }\n for (i = 0; i < n; i++) ev.push(a[i][i]);\n //returns both the eigenvalue and eigenmatrix\n return [e, ev];\n },\n\n rungekutta: function rungekutta(f, h, p, t_j, u_j, order) {\n var k1, k2, u_j1, k3, k4;\n if (order === 2) {\n while (t_j <= p) {\n k1 = h * f(t_j, u_j);\n k2 = h * f(t_j + h, u_j + k1);\n u_j1 = u_j + (k1 + k2) / 2;\n u_j = u_j1;\n t_j = t_j + h;\n }\n }\n if (order === 4) {\n while (t_j <= p) {\n k1 = h * f(t_j, u_j);\n k2 = h * f(t_j + h / 2, u_j + k1 / 2);\n k3 = h * f(t_j + h / 2, u_j + k2 / 2);\n k4 = h * f(t_j +h, u_j + k3);\n u_j1 = u_j + (k1 + 2 * k2 + 2 * k3 + k4) / 6;\n u_j = u_j1;\n t_j = t_j + h;\n }\n }\n return u_j;\n },\n\n romberg: function romberg(f, a, b, order) {\n var i = 0;\n var h = (b - a) / 2;\n var x = [];\n var h1 = [];\n var g = [];\n var m, a1, j, k, I;\n while (i < order / 2) {\n I = f(a);\n for (j = a, k = 0; j <= b; j = j + h, k++) x[k] = j;\n m = x.length;\n for (j = 1; j < m - 1; j++) {\n I += (((j % 2) !== 0) ? 4 : 2) * f(x[j]);\n }\n I = (h / 3) * (I + f(b));\n g[i] = I;\n h /= 2;\n i++;\n }\n a1 = g.length;\n m = 1;\n while (a1 !== 1) {\n for (j = 0; j < a1 - 1; j++)\n h1[j] = ((Math.pow(4, m)) * g[j + 1] - g[j]) / (Math.pow(4, m) - 1);\n a1 = h1.length;\n g = h1;\n h1 = [];\n m++;\n }\n return g;\n },\n\n richardson: function richardson(X, f, x, h) {\n function pos(X, x) {\n var i = 0;\n var n = X.length;\n var p;\n for (; i < n; i++)\n if (X[i] === x) p = i;\n return p;\n }\n var h_min = Math.abs(x - X[pos(X, x) + 1]);\n var i = 0;\n var g = [];\n var h1 = [];\n var y1, y2, m, a, j;\n while (h >= h_min) {\n y1 = pos(X, x + h);\n y2 = pos(X, x);\n g[i] = (f[y1] - 2 * f[y2] + f[2 * y2 - y1]) / (h * h);\n h /= 2;\n i++;\n }\n a = g.length;\n m = 1;\n while (a != 1) {\n for (j = 0; j < a - 1; j++)\n h1[j] = ((Math.pow(4, m)) * g[j + 1] - g[j]) / (Math.pow(4, m) - 1);\n a = h1.length;\n g = h1;\n h1 = [];\n m++;\n }\n return g;\n },\n\n simpson: function simpson(f, a, b, n) {\n var h = (b - a) / n;\n var I = f(a);\n var x = [];\n var j = a;\n var k = 0;\n var i = 1;\n var m;\n for (; j <= b; j = j + h, k++)\n x[k] = j;\n m = x.length;\n for (; i < m - 1; i++) {\n I += ((i % 2 !== 0) ? 4 : 2) * f(x[i]);\n }\n return (h / 3) * (I + f(b));\n },\n\n hermite: function hermite(X, F, dF, value) {\n var n = X.length;\n var p = 0;\n var i = 0;\n var l = [];\n var dl = [];\n var A = [];\n var B = [];\n var j;\n for (; i < n; i++) {\n l[i] = 1;\n for (j = 0; j < n; j++) {\n if (i != j) l[i] *= (value - X[j]) / (X[i] - X[j]);\n }\n dl[i] = 0;\n for (j = 0; j < n; j++) {\n if (i != j) dl[i] += 1 / (X [i] - X[j]);\n }\n A[i] = (1 - 2 * (value - X[i]) * dl[i]) * (l[i] * l[i]);\n B[i] = (value - X[i]) * (l[i] * l[i]);\n p += (A[i] * F[i] + B[i] * dF[i]);\n }\n return p;\n },\n\n lagrange: function lagrange(X, F, value) {\n var p = 0;\n var i = 0;\n var j, l;\n var n = X.length;\n for (; i < n; i++) {\n l = F[i];\n for (j = 0; j < n; j++) {\n // calculating the lagrange polynomial L_i\n if (i != j) l *= (value - X[j]) / (X[i] - X[j]);\n }\n // adding the lagrange polynomials found above\n p += l;\n }\n return p;\n },\n\n cubic_spline: function cubic_spline(X, F, value) {\n var n = X.length;\n var i = 0, j;\n var A = [];\n var B = [];\n var alpha = [];\n var c = [];\n var h = [];\n var b = [];\n var d = [];\n for (; i < n - 1; i++)\n h[i] = X[i + 1] - X[i];\n alpha[0] = 0;\n for (i = 1; i < n - 1; i++) {\n alpha[i] = (3 / h[i]) * (F[i + 1] - F[i]) -\n (3 / h[i-1]) * (F[i] - F[i-1]);\n }\n for (i = 1; i < n - 1; i++) {\n A[i] = [];\n B[i] = [];\n A[i][i-1] = h[i-1];\n A[i][i] = 2 * (h[i - 1] + h[i]);\n A[i][i+1] = h[i];\n B[i][0] = alpha[i];\n }\n c = jStat.multiply(jStat.inv(A), B);\n for (j = 0; j < n - 1; j++) {\n b[j] = (F[j + 1] - F[j]) / h[j] - h[j] * (c[j + 1][0] + 2 * c[j][0]) / 3;\n d[j] = (c[j + 1][0] - c[j][0]) / (3 * h[j]);\n }\n for (j = 0; j < n; j++) {\n if (X[j] > value) break;\n }\n j -= 1;\n return F[j] + (value - X[j]) * b[j] + jStat.sq(value-X[j]) *\n c[j] + (value - X[j]) * jStat.sq(value - X[j]) * d[j];\n },\n\n gauss_quadrature: function gauss_quadrature() {\n throw new Error('gauss_quadrature not yet implemented');\n },\n\n PCA: function PCA(X) {\n var m = X.length;\n var n = X[0].length;\n var i = 0;\n var j, temp1;\n var u = [];\n var D = [];\n var result = [];\n var temp2 = [];\n var Y = [];\n var Bt = [];\n var B = [];\n var C = [];\n var V = [];\n var Vt = [];\n for (i = 0; i < m; i++) {\n u[i] = jStat.sum(X[i]) / n;\n }\n for (i = 0; i < n; i++) {\n B[i] = [];\n for(j = 0; j < m; j++) {\n B[i][j] = X[j][i] - u[j];\n }\n }\n B = jStat.transpose(B);\n for (i = 0; i < m; i++) {\n C[i] = [];\n for (j = 0; j < m; j++) {\n C[i][j] = (jStat.dot([B[i]], [B[j]])) / (n - 1);\n }\n }\n result = jStat.jacobi(C);\n V = result[0];\n D = result[1];\n Vt = jStat.transpose(V);\n for (i = 0; i < D.length; i++) {\n for (j = i; j < D.length; j++) {\n if(D[i] < D[j]) {\n temp1 = D[i];\n D[i] = D[j];\n D[j] = temp1;\n temp2 = Vt[i];\n Vt[i] = Vt[j];\n Vt[j] = temp2;\n }\n }\n }\n Bt = jStat.transpose(B);\n for (i = 0; i < m; i++) {\n Y[i] = [];\n for (j = 0; j < Bt.length; j++) {\n Y[i][j] = jStat.dot([Vt[i]], [Bt[j]]);\n }\n }\n return [X, D, Vt, Y];\n }\n});\n\n// extend jStat.fn with methods that require one argument\n(function(funcs) {\n for (var i = 0; i < funcs.length; i++) (function(passfunc) {\n jStat.fn[passfunc] = function(arg, func) {\n var tmpthis = this;\n // check for callback\n if (func) {\n setTimeout(function() {\n func.call(tmpthis, jStat.fn[passfunc].call(tmpthis, arg));\n }, 15);\n return this;\n }\n if (typeof jStat[passfunc](this, arg) === 'number')\n return jStat[passfunc](this, arg);\n else\n return jStat(jStat[passfunc](this, arg));\n };\n }(funcs[i]));\n}('add divide multiply subtract dot pow exp log abs norm angle'.split(' ')));\n\n}(jStat, Math));\n(function(jStat, Math) {\n\nvar slice = [].slice;\nvar isNumber = jStat.utils.isNumber;\nvar isArray = jStat.utils.isArray;\n\n// flag==true denotes use of sample standard deviation\n// Z Statistics\njStat.extend({\n // 2 different parameter lists:\n // (value, mean, sd)\n // (value, array, flag)\n zscore: function zscore() {\n var args = slice.call(arguments);\n if (isNumber(args[1])) {\n return (args[0] - args[1]) / args[2];\n }\n return (args[0] - jStat.mean(args[1])) / jStat.stdev(args[1], args[2]);\n },\n\n // 3 different paramter lists:\n // (value, mean, sd, sides)\n // (zscore, sides)\n // (value, array, sides, flag)\n ztest: function ztest() {\n var args = slice.call(arguments);\n var z;\n if (isArray(args[1])) {\n // (value, array, sides, flag)\n z = jStat.zscore(args[0],args[1],args[3]);\n return (args[2] === 1) ?\n (jStat.normal.cdf(-Math.abs(z), 0, 1)) :\n (jStat.normal.cdf(-Math.abs(z), 0, 1)*2);\n } else {\n if (args.length > 2) {\n // (value, mean, sd, sides)\n z = jStat.zscore(args[0],args[1],args[2]);\n return (args[3] === 1) ?\n (jStat.normal.cdf(-Math.abs(z),0,1)) :\n (jStat.normal.cdf(-Math.abs(z),0,1)* 2);\n } else {\n // (zscore, sides)\n z = args[0];\n return (args[1] === 1) ?\n (jStat.normal.cdf(-Math.abs(z),0,1)) :\n (jStat.normal.cdf(-Math.abs(z),0,1)*2);\n }\n }\n }\n});\n\njStat.extend(jStat.fn, {\n zscore: function zscore(value, flag) {\n return (value - this.mean()) / this.stdev(flag);\n },\n\n ztest: function ztest(value, sides, flag) {\n var zscore = Math.abs(this.zscore(value, flag));\n return (sides === 1) ?\n (jStat.normal.cdf(-zscore, 0, 1)) :\n (jStat.normal.cdf(-zscore, 0, 1) * 2);\n }\n});\n\n// T Statistics\njStat.extend({\n // 2 parameter lists\n // (value, mean, sd, n)\n // (value, array)\n tscore: function tscore() {\n var args = slice.call(arguments);\n return (args.length === 4) ?\n ((args[0] - args[1]) / (args[2] / Math.sqrt(args[3]))) :\n ((args[0] - jStat.mean(args[1])) /\n (jStat.stdev(args[1], true) / Math.sqrt(args[1].length)));\n },\n\n // 3 different paramter lists:\n // (value, mean, sd, n, sides)\n // (tscore, n, sides)\n // (value, array, sides)\n ttest: function ttest() {\n var args = slice.call(arguments);\n var tscore;\n if (args.length === 5) {\n tscore = Math.abs(jStat.tscore(args[0], args[1], args[2], args[3]));\n return (args[4] === 1) ?\n (jStat.studentt.cdf(-tscore, args[3]-1)) :\n (jStat.studentt.cdf(-tscore, args[3]-1)*2);\n }\n if (isNumber(args[1])) {\n tscore = Math.abs(args[0])\n return (args[2] == 1) ?\n (jStat.studentt.cdf(-tscore, args[1]-1)) :\n (jStat.studentt.cdf(-tscore, args[1]-1) * 2);\n }\n tscore = Math.abs(jStat.tscore(args[0], args[1]))\n return (args[2] == 1) ?\n (jStat.studentt.cdf(-tscore, args[1].length-1)) :\n (jStat.studentt.cdf(-tscore, args[1].length-1) * 2);\n }\n});\n\njStat.extend(jStat.fn, {\n tscore: function tscore(value) {\n return (value - this.mean()) / (this.stdev(true) / Math.sqrt(this.cols()));\n },\n\n ttest: function ttest(value, sides) {\n return (sides === 1) ?\n (1 - jStat.studentt.cdf(Math.abs(this.tscore(value)), this.cols()-1)) :\n (jStat.studentt.cdf(-Math.abs(this.tscore(value)), this.cols()-1)*2);\n }\n});\n\n// F Statistics\njStat.extend({\n // Paramter list is as follows:\n // (array1, array2, array3, ...)\n // or it is an array of arrays\n // array of arrays conversion\n anovafscore: function anovafscore() {\n var args = slice.call(arguments),\n expVar, sample, sampMean, sampSampMean, tmpargs, unexpVar, i, j;\n if (args.length === 1) {\n tmpargs = new Array(args[0].length);\n for (i = 0; i < args[0].length; i++) {\n tmpargs[i] = args[0][i];\n }\n args = tmpargs;\n }\n // Builds sample array\n sample = new Array();\n for (i = 0; i < args.length; i++) {\n sample = sample.concat(args[i]);\n }\n sampMean = jStat.mean(sample);\n // Computes the explained variance\n expVar = 0;\n for (i = 0; i < args.length; i++) {\n expVar = expVar + args[i].length * Math.pow(jStat.mean(args[i]) - sampMean, 2);\n }\n expVar /= (args.length - 1);\n // Computes unexplained variance\n unexpVar = 0;\n for (i = 0; i < args.length; i++) {\n sampSampMean = jStat.mean(args[i]);\n for (j = 0; j < args[i].length; j++) {\n unexpVar += Math.pow(args[i][j] - sampSampMean, 2);\n }\n }\n unexpVar /= (sample.length - args.length);\n return expVar / unexpVar;\n },\n\n // 2 different paramter setups\n // (array1, array2, array3, ...)\n // (anovafscore, df1, df2)\n anovaftest: function anovaftest() {\n var args = slice.call(arguments),\n df1, df2, n, i;\n if (isNumber(args[0])) {\n return 1 - jStat.centralF.cdf(args[0], args[1], args[2]);\n }\n var anovafscore = jStat.anovafscore(args);\n df1 = args.length - 1;\n n = 0;\n for (i = 0; i < args.length; i++) {\n n = n + args[i].length;\n }\n df2 = n - df1 - 1;\n return 1 - jStat.centralF.cdf(anovafscore, df1, df2);\n },\n\n ftest: function ftest(fscore, df1, df2) {\n return 1 - jStat.centralF.cdf(fscore, df1, df2);\n }\n});\n\njStat.extend(jStat.fn, {\n anovafscore: function anovafscore() {\n return jStat.anovafscore(this.toArray());\n },\n\n anovaftes: function anovaftes() {\n var n = 0;\n var i;\n for (i = 0; i < this.length; i++) {\n n = n + this[i].length;\n }\n return jStat.ftest(this.anovafscore(), this.length - 1, n - this.length);\n }\n});\n\n// Tukey's range test\njStat.extend({\n // 2 parameter lists\n // (mean1, mean2, n1, n2, sd)\n // (array1, array2, sd)\n qscore: function qscore() {\n var args = slice.call(arguments);\n var mean1, mean2, n1, n2, sd;\n if (isNumber(args[0])) {\n mean1 = args[0];\n mean2 = args[1];\n n1 = args[2];\n n2 = args[3];\n sd = args[4];\n } else {\n mean1 = jStat.mean(args[0]);\n mean2 = jStat.mean(args[1]);\n n1 = args[0].length;\n n2 = args[1].length;\n sd = args[2];\n }\n return Math.abs(mean1 - mean2) / (sd * Math.sqrt((1 / n1 + 1 / n2) / 2));\n },\n\n // 3 different parameter lists:\n // (qscore, n, k)\n // (mean1, mean2, n1, n2, sd, n, k)\n // (array1, array2, sd, n, k)\n qtest: function qtest() {\n var args = slice.call(arguments);\n\n var qscore;\n if (args.length === 3) {\n qscore = args[0];\n args = args.slice(1);\n } else if (args.length === 7) {\n qscore = jStat.qscore(args[0], args[1], args[2], args[3], args[4]);\n args = args.slice(5);\n } else {\n qscore = jStat.qscore(args[0], args[1], args[2]);\n args = args.slice(3);\n }\n\n var n = args[0];\n var k = args[1];\n\n return 1 - jStat.tukey.cdf(qscore, k, n - k);\n },\n\n tukeyhsd: function tukeyhsd(arrays) {\n var sd = jStat.pooledstdev(arrays);\n var means = arrays.map(function (arr) {return jStat.mean(arr);});\n var n = arrays.reduce(function (n, arr) {return n + arr.length;}, 0);\n\n var results = [];\n for (var i = 0; i < arrays.length; ++i) {\n for (var j = i + 1; j < arrays.length; ++j) {\n var p = jStat.qtest(means[i], means[j], arrays[i].length, arrays[j].length, sd, n, arrays.length);\n results.push([[i, j], p]);\n }\n }\n\n return results;\n }\n});\n\n// Error Bounds\njStat.extend({\n // 2 different parameter setups\n // (value, alpha, sd, n)\n // (value, alpha, array)\n normalci: function normalci() {\n var args = slice.call(arguments),\n ans = new Array(2),\n change;\n if (args.length === 4) {\n change = Math.abs(jStat.normal.inv(args[1] / 2, 0, 1) *\n args[2] / Math.sqrt(args[3]));\n } else {\n change = Math.abs(jStat.normal.inv(args[1] / 2, 0, 1) *\n jStat.stdev(args[2]) / Math.sqrt(args[2].length));\n }\n ans[0] = args[0] - change;\n ans[1] = args[0] + change;\n return ans;\n },\n\n // 2 different parameter setups\n // (value, alpha, sd, n)\n // (value, alpha, array)\n tci: function tci() {\n var args = slice.call(arguments),\n ans = new Array(2),\n change;\n if (args.length === 4) {\n change = Math.abs(jStat.studentt.inv(args[1] / 2, args[3] - 1) *\n args[2] / Math.sqrt(args[3]));\n } else {\n change = Math.abs(jStat.studentt.inv(args[1] / 2, args[2].length - 1) *\n jStat.stdev(args[2], true) / Math.sqrt(args[2].length));\n }\n ans[0] = args[0] - change;\n ans[1] = args[0] + change;\n return ans;\n },\n\n significant: function significant(pvalue, alpha) {\n return pvalue < alpha;\n }\n});\n\njStat.extend(jStat.fn, {\n normalci: function normalci(value, alpha) {\n return jStat.normalci(value, alpha, this.toArray());\n },\n\n tci: function tci(value, alpha) {\n return jStat.tci(value, alpha, this.toArray());\n }\n});\n\n// internal method for calculating the z-score for a difference of proportions test\nfunction differenceOfProportions(p1, n1, p2, n2) {\n if (p1 > 1 || p2 > 1 || p1 <= 0 || p2 <= 0) {\n throw new Error(\"Proportions should be greater than 0 and less than 1\")\n }\n var pooled = (p1 * n1 + p2 * n2) / (n1 + n2);\n var se = Math.sqrt(pooled * (1 - pooled) * ((1/n1) + (1/n2)));\n return (p1 - p2) / se;\n}\n\n// Difference of Proportions\njStat.extend(jStat.fn, {\n oneSidedDifferenceOfProportions: function oneSidedDifferenceOfProportions(p1, n1, p2, n2) {\n var z = differenceOfProportions(p1, n1, p2, n2);\n return jStat.ztest(z, 1);\n },\n\n twoSidedDifferenceOfProportions: function twoSidedDifferenceOfProportions(p1, n1, p2, n2) {\n var z = differenceOfProportions(p1, n1, p2, n2);\n return jStat.ztest(z, 2);\n }\n});\n\n}(jStat, Math));\njStat.models = (function(){\n function sub_regress(exog) {\n var var_count = exog[0].length;\n var modelList = jStat.arange(var_count).map(function(endog_index) {\n var exog_index =\n jStat.arange(var_count).filter(function(i){return i!==endog_index});\n return ols(jStat.col(exog, endog_index).map(function(x){ return x[0] }),\n jStat.col(exog, exog_index))\n });\n return modelList;\n }\n\n // do OLS model regress\n // exog have include const columns ,it will not generate it .In fact, exog is\n // \"design matrix\" look at\n //https://en.wikipedia.org/wiki/Design_matrix\n function ols(endog, exog) {\n var nobs = endog.length;\n var df_model = exog[0].length - 1;\n var df_resid = nobs-df_model - 1;\n var coef = jStat.lstsq(exog, endog);\n var predict =\n jStat.multiply(exog, coef.map(function(x) { return [x] }))\n .map(function(p) { return p[0] });\n var resid = jStat.subtract(endog, predict);\n var ybar = jStat.mean(endog);\n // constant cause problem\n // var SST = jStat.sum(endog.map(function(y) {\n // return Math.pow(y-ybar,2);\n // }));\n var SSE = jStat.sum(predict.map(function(f) {\n return Math.pow(f - ybar, 2);\n }));\n var SSR = jStat.sum(endog.map(function(y, i) {\n return Math.pow(y - predict[i], 2);\n }));\n var SST = SSE + SSR;\n var R2 = (SSE / SST);\n return {\n exog:exog,\n endog:endog,\n nobs:nobs,\n df_model:df_model,\n df_resid:df_resid,\n coef:coef,\n predict:predict,\n resid:resid,\n ybar:ybar,\n SST:SST,\n SSE:SSE,\n SSR:SSR,\n R2:R2\n };\n }\n\n // H0: b_I=0\n // H1: b_I!=0\n function t_test(model) {\n var subModelList = sub_regress(model.exog);\n //var sigmaHat=jStat.stdev(model.resid);\n var sigmaHat = Math.sqrt(model.SSR / (model.df_resid));\n var seBetaHat = subModelList.map(function(mod) {\n var SST = mod.SST;\n var R2 = mod.R2;\n return sigmaHat / Math.sqrt(SST * (1 - R2));\n });\n var tStatistic = model.coef.map(function(coef, i) {\n return (coef - 0) / seBetaHat[i];\n });\n var pValue = tStatistic.map(function(t) {\n var leftppf = jStat.studentt.cdf(t, model.df_resid);\n return (leftppf > 0.5 ? 1 - leftppf : leftppf) * 2;\n });\n var c = jStat.studentt.inv(0.975, model.df_resid);\n var interval95 = model.coef.map(function(coef, i) {\n var d = c * seBetaHat[i];\n return [coef - d, coef + d];\n })\n return {\n se: seBetaHat,\n t: tStatistic,\n p: pValue,\n sigmaHat: sigmaHat,\n interval95: interval95\n };\n }\n\n function F_test(model) {\n var F_statistic =\n (model.R2 / model.df_model) / ((1 - model.R2) / model.df_resid);\n var fcdf = function(x, n1, n2) {\n return jStat.beta.cdf(x / (n2 / n1 + x), n1 / 2, n2 / 2)\n }\n var pvalue = 1 - fcdf(F_statistic, model.df_model, model.df_resid);\n return { F_statistic: F_statistic, pvalue: pvalue };\n }\n\n function ols_wrap(endog, exog) {\n var model = ols(endog,exog);\n var ttest = t_test(model);\n var ftest = F_test(model);\n // Provide the Wherry / Ezekiel / McNemar / Cohen Adjusted R^2\n // Which matches the 'adjusted R^2' provided by R's lm package\n var adjust_R2 =\n 1 - (1 - model.R2) * ((model.nobs - 1) / (model.df_resid));\n model.t = ttest;\n model.f = ftest;\n model.adjust_R2 = adjust_R2;\n return model;\n }\n\n return { ols: ols_wrap };\n})();\n//To regress, simply build X matrix\n//(append column of 1's) using\n//buildxmatrix and build the Y\n//matrix using buildymatrix\n//(simply the transpose)\n//and run regress.\n\n\n\n//Regressions\n\njStat.extend({\n buildxmatrix: function buildxmatrix(){\n //Parameters will be passed in as such\n //(array1,array2,array3,...)\n //as (x1,x2,x3,...)\n //needs to be (1,x1,x2,x3,...)\n var matrixRows = new Array(arguments.length);\n for(var i=0;i1){\n result = [];\n for (i = 0; i < A.rows(); i++) {\n result[i] = [];\n for (j = 0; j < B.cols(); j++) {\n sum = 0;\n for (k = 0; k < A.cols(); k++) {\n sum += A.toArray()[i][k] * B.toArray()[k][j];\n }\n result[i][j] = sum;\n }\n }\n return jStat(result);\n }\n result = [];\n for (i = 0; i < A.rows(); i++) {\n result[i] = [];\n for (j = 0; j < B.cols(); j++) {\n sum = 0;\n for (k = 0; k < A.cols(); k++) {\n sum += A.toArray()[i][k] * B.toArray()[j];\n }\n result[i][j] = sum;\n }\n }\n return jStat(result);\n }\n },\n\n //regress and regresst to be fixed\n\n regress: function regress(jMatX,jMatY){\n //print(\"regressin!\");\n //print(jMatX.toArray());\n var innerinv = jStat.xtranspxinv(jMatX);\n //print(innerinv);\n var xtransp = jMatX.transpose();\n var next = jStat.matrixmult(jStat(innerinv),xtransp);\n return jStat.matrixmult(next,jMatY);\n\n },\n\n regresst: function regresst(jMatX,jMatY,sides){\n var beta = jStat.regress(jMatX,jMatY);\n\n var compile = {};\n compile.anova = {};\n var jMatYBar = jStat.jMatYBar(jMatX, beta);\n compile.yBar = jMatYBar;\n var yAverage = jMatY.mean();\n compile.anova.residuals = jStat.residuals(jMatY, jMatYBar);\n\n compile.anova.ssr = jStat.ssr(jMatYBar, yAverage);\n compile.anova.msr = compile.anova.ssr / (jMatX[0].length - 1);\n\n compile.anova.sse = jStat.sse(jMatY, jMatYBar);\n compile.anova.mse =\n compile.anova.sse / (jMatY.length - (jMatX[0].length - 1) - 1);\n\n compile.anova.sst = jStat.sst(jMatY, yAverage);\n compile.anova.mst = compile.anova.sst / (jMatY.length - 1);\n\n compile.anova.r2 = 1 - (compile.anova.sse / compile.anova.sst);\n if (compile.anova.r2 < 0) compile.anova.r2 = 0;\n\n compile.anova.fratio = compile.anova.msr / compile.anova.mse;\n compile.anova.pvalue =\n jStat.anovaftest(compile.anova.fratio,\n jMatX[0].length - 1,\n jMatY.length - (jMatX[0].length - 1) - 1);\n\n compile.anova.rmse = Math.sqrt(compile.anova.mse);\n\n compile.anova.r2adj = 1 - (compile.anova.mse / compile.anova.mst);\n if (compile.anova.r2adj < 0) compile.anova.r2adj = 0;\n\n compile.stats = new Array(jMatX[0].length);\n var covar = jStat.xtranspxinv(jMatX);\n var sds, ts, ps;\n\n for(var i=0; i n) {\n ret = _bessel_iter(x, n, bessel0(x), bessel1(x),-1);\n } else {\n var m=2*M.floor((n+M.floor(M.sqrt(40*n)))/2);\n var jsum=false;\n var bjp=0.0, sum=0.0;\n var bj=1.0, bjm = 0.0;\n var tox = 2 / x;\n for (var j=m;j>0;j--) {\n bjm=j*tox*bj-bjp;\n bjp=bj;\n bj=bjm;\n if (M.abs(bj) > 1E10) {\n bj *= 1E-10;\n bjp *= 1E-10;\n ret *= 1E-10;\n sum *= 1E-10;\n }\n if (jsum) sum += bj;\n jsum=!jsum;\n if (j == n) ret=bjp;\n }\n sum=2.0*sum-bj;\n ret /= sum;\n }\n return ret;\n };\n})();\nvar bessely = (function() {\n var W = 0.636619772;\n\n var b0_a1a = [-2957821389.0, 7062834065.0, -512359803.6, 10879881.29, -86327.92757, 228.4622733].reverse();\n var b0_a2a = [40076544269.0, 745249964.8, 7189466.438, 47447.26470, 226.1030244, 1.0].reverse();\n var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse();\n var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934945152e-7].reverse();\n\n function bessel0(x) {\n var a=0, a1=0, a2=0, y = x * x, xx = x - 0.785398164;\n if(x < 8) {\n a1 = _horner(b0_a1a, y);\n a2 = _horner(b0_a2a, y);\n a = a1/a2 + W * besselj(x,0) * M.log(x);\n } else {\n y = 64 / y;\n a1 = _horner(b0_a1b, y);\n a2 = _horner(b0_a2b, y);\n a = M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x);\n }\n return a;\n }\n\n var b1_a1a = [-0.4900604943e13, 0.1275274390e13, -0.5153438139e11, 0.7349264551e9, -0.4237922726e7, 0.8511937935e4].reverse();\n var b1_a2a = [0.2499580570e14, 0.4244419664e12, 0.3733650367e10, 0.2245904002e8, 0.1020426050e6, 0.3549632885e3, 1].reverse();\n var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse();\n var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse();\n\n function bessel1(x) {\n var a=0, a1=0, a2=0, y = x*x, xx = x - 2.356194491;\n if(x < 8) {\n a1 = x*_horner(b1_a1a, y);\n a2 = _horner(b1_a2a, y);\n a = a1/a2 + W * (besselj(x,1) * M.log(x) - 1 / x);\n } else {\n y = 64 / y;\n a1=_horner(b1_a1b, y);\n a2=_horner(b1_a2b, y);\n a=M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x);\n }\n return a;\n }\n\n return _bessel_wrap(bessel0, bessel1, 'BESSELY', 1, -1);\n})();\nvar besseli = (function() {\n var b0_a = [1.0, 3.5156229, 3.0899424, 1.2067492, 0.2659732, 0.360768e-1, 0.45813e-2].reverse();\n var b0_b = [0.39894228, 0.1328592e-1, 0.225319e-2, -0.157565e-2, 0.916281e-2, -0.2057706e-1, 0.2635537e-1, -0.1647633e-1, 0.392377e-2].reverse();\n\n function bessel0(x) {\n if(x <= 3.75) return _horner(b0_a, x*x/(3.75*3.75));\n return M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b0_b, 3.75/M.abs(x));\n }\n\n var b1_a = [0.5, 0.87890594, 0.51498869, 0.15084934, 0.2658733e-1, 0.301532e-2, 0.32411e-3].reverse();\n var b1_b = [0.39894228, -0.3988024e-1, -0.362018e-2, 0.163801e-2, -0.1031555e-1, 0.2282967e-1, -0.2895312e-1, 0.1787654e-1, -0.420059e-2].reverse();\n\n function bessel1(x) {\n if(x < 3.75) return x * _horner(b1_a, x*x/(3.75*3.75));\n return (x < 0 ? -1 : 1) * M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b1_b, 3.75/M.abs(x));\n }\n\n return function besseli(x, n) {\n n = Math.round(n);\n if(n === 0) return bessel0(x);\n if(n === 1) return bessel1(x);\n if(n < 0) return NaN;\n if(M.abs(x) === 0) return 0;\n if(x == Infinity) return Infinity;\n\n var ret = 0.0, j, tox = 2 / M.abs(x), bip = 0.0, bi=1.0, bim=0.0;\n var m=2*M.round((n+M.round(M.sqrt(40*n)))/2);\n for (j=m;j>0;j--) {\n bim=j*tox*bi + bip;\n bip=bi; bi=bim;\n if (M.abs(bi) > 1E10) {\n bi *= 1E-10;\n bip *= 1E-10;\n ret *= 1E-10;\n }\n if(j == n) ret = bip;\n }\n ret *= besseli(x, 0) / bi;\n return x < 0 && (n%2) ? -ret : ret;\n };\n\n})();\n\nvar besselk = (function() {\n var b0_a = [-0.57721566, 0.42278420, 0.23069756, 0.3488590e-1, 0.262698e-2, 0.10750e-3, 0.74e-5].reverse();\n var b0_b = [1.25331414, -0.7832358e-1, 0.2189568e-1, -0.1062446e-1, 0.587872e-2, -0.251540e-2, 0.53208e-3].reverse();\n\n function bessel0(x) {\n if(x <= 2) return -M.log(x/2) * besseli(x,0) + _horner(b0_a, x*x/4);\n return M.exp(-x) / M.sqrt(x) * _horner(b0_b, 2/x);\n }\n\n var b1_a = [1.0, 0.15443144, -0.67278579, -0.18156897, -0.1919402e-1, -0.110404e-2, -0.4686e-4].reverse();\n var b1_b = [1.25331414, 0.23498619, -0.3655620e-1, 0.1504268e-1, -0.780353e-2, 0.325614e-2, -0.68245e-3].reverse();\n\n function bessel1(x) {\n if(x <= 2) return M.log(x/2) * besseli(x,1) + (1/x) * _horner(b1_a, x*x/4);\n return M.exp(-x)/M.sqrt(x)*_horner(b1_b, 2/x);\n }\n\n return _bessel_wrap(bessel0, bessel1, 'BESSELK', 2, 1);\n})();\nBESSEL.besselj = besselj;\nBESSEL.bessely = bessely;\nBESSEL.besseli = besseli;\nBESSEL.besselk = besselk;\n}));\n","import jStat from 'jstat';\nimport bessel from 'bessel';\n\nconst nil = new Error('#NULL!');\nconst div0 = new Error('#DIV/0!');\nconst value = new Error('#VALUE!');\nconst ref = new Error('#REF!');\nconst name = new Error('#NAME?');\nconst num = new Error('#NUM!');\nconst na = new Error('#N/A');\nconst error = new Error('#ERROR!');\nconst data = new Error('#GETTING_DATA');\n\nvar errors = /*#__PURE__*/Object.freeze({\n __proto__: null,\n data: data,\n div0: div0,\n error: error,\n na: na,\n name: name,\n nil: nil,\n num: num,\n ref: ref,\n value: value\n});\n\nconst defaultOperator = '=';\nconst validSymbols = ['>', '>=', '<', '<=', '=', '<>'];\nconst _TOKEN_TYPE_OPERATOR = 'operator';\nconst _TOKEN_TYPE_LITERAL = 'literal';\nconst SUPPORTED_TOKENS = [_TOKEN_TYPE_OPERATOR, _TOKEN_TYPE_LITERAL];\n\nconst TOKEN_TYPE_OPERATOR = _TOKEN_TYPE_OPERATOR;\nconst TOKEN_TYPE_LITERAL = _TOKEN_TYPE_LITERAL;\n\n/**\n * Create token which describe passed symbol/value.\n *\n * @param {String} value Value/Symbol to describe.\n * @param {String} type Type of the token 'operator' or 'literal'.\n * @return {Object}\n */\nfunction createToken(value, type) {\n if (SUPPORTED_TOKENS.indexOf(type) === -1) {\n throw new Error('Unsupported token type: ' + type)\n }\n\n return {\n value: value,\n type: type\n }\n}\n\n/**\n * Tries to cast numeric values to their type passed as a string.\n *\n * @param {*} value\n * @return {*}\n */\nfunction castValueToCorrectType(value) {\n if (typeof value !== 'string') {\n return value\n }\n\n if (/^\\d+(\\.\\d+)?$/.test(value)) {\n value = value.indexOf('.') === -1 ? parseInt(value, 10) : parseFloat(value);\n }\n\n return value\n}\n\n/**\n * Generate stream of tokens from passed expression.\n *\n * @param {String} expression\n * @return {String[]}\n */\nfunction tokenizeExpression(expression) {\n const expressionLength = expression.length;\n const tokens = [];\n let cursorIndex = 0;\n let processedValue = '';\n let processedSymbol = '';\n\n while (cursorIndex < expressionLength) {\n const char = expression.charAt(cursorIndex);\n\n switch (char) {\n case '>':\n case '<':\n case '=':\n processedSymbol = processedSymbol + char;\n\n if (processedValue.length > 0) {\n tokens.push(processedValue);\n processedValue = '';\n }\n\n break\n default:\n if (processedSymbol.length > 0) {\n tokens.push(processedSymbol);\n processedSymbol = '';\n }\n\n processedValue = processedValue + char;\n break\n }\n\n cursorIndex++;\n }\n\n if (processedValue.length > 0) {\n tokens.push(processedValue);\n }\n\n if (processedSymbol.length > 0) {\n tokens.push(processedSymbol);\n }\n\n return tokens\n}\n\n/**\n * Analyze and convert tokens to an object which describes their meaning.\n *\n * @param {String[]} tokens\n * @return {Object[]}\n */\nfunction analyzeTokens(tokens) {\n let literalValue = '';\n const analyzedTokens = [];\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n if (i === 0 && validSymbols.indexOf(token) >= 0) {\n analyzedTokens.push(createToken(token, TOKEN_TYPE_OPERATOR));\n } else {\n literalValue += token;\n }\n }\n\n if (literalValue.length > 0) {\n analyzedTokens.push(createToken(castValueToCorrectType(literalValue), TOKEN_TYPE_LITERAL));\n }\n\n if (analyzedTokens.length > 0 && analyzedTokens[0].type !== TOKEN_TYPE_OPERATOR) {\n analyzedTokens.unshift(createToken(defaultOperator, TOKEN_TYPE_OPERATOR));\n }\n\n return analyzedTokens\n}\n\n/**\n * Compute/Evaluate an expression passed as an array of tokens.\n *\n * @param {Object[]} tokens\n * @return {Boolean}\n */\nfunction computeExpression(tokens) {\n const values = [];\n let operator;\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n switch (token.type) {\n case TOKEN_TYPE_OPERATOR:\n operator = token.value;\n break\n case TOKEN_TYPE_LITERAL:\n values.push(token.value);\n break\n }\n }\n\n return evaluate(values, operator)\n}\n\n/**\n * Evaluate values based on passed math operator.\n *\n * @param {*} values\n * @param {String} operator\n * @return {Boolean}\n */\nfunction evaluate(values, operator) {\n let result = false;\n\n switch (operator) {\n case '>':\n result = values[0] > values[1];\n break\n case '>=':\n result = values[0] >= values[1];\n break\n case '<':\n result = values[0] < values[1];\n break\n case '<=':\n result = values[0] <= values[1];\n break\n case '=':\n result = values[0] == values[1];\n break\n case '<>':\n result = values[0] != values[1];\n break\n }\n\n return result\n}\n\nfunction parse(expression) {\n return analyzeTokens(tokenizeExpression(expression))\n}\n\nconst compute = computeExpression;\n\n// Arrays\nfunction argsToArray(args) {\n const result = [];\n\n arrayEach(args, (value) => {\n result.push(value);\n });\n\n return result\n}\n\nfunction arrayEach(array, iteratee) {\n let index = -1;\n const length = array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break\n }\n }\n\n return array\n}\n\nfunction arrayValuesToNumbers(arr) {\n let n = arr.length;\n let el;\n\n while (n--) {\n el = arr[n];\n\n if (typeof el === 'number') {\n continue\n }\n\n if (el === true) {\n arr[n] = 1;\n continue\n }\n\n if (el === false) {\n arr[n] = 0;\n continue\n }\n\n if (typeof el === 'string') {\n const number = parseNumber(el);\n\n arr[n] = number instanceof Error ? 0 : number;\n }\n }\n\n return arr\n}\n\nfunction fillMatrix(matrix, fill_value) {\n if (!matrix) {\n return value\n }\n\n if (!matrix.every((el) => Array.isArray(el)) || matrix.length === 0) {\n matrix = [[...matrix]];\n }\n\n matrix.map((arr, i) => {\n arr.map((a, j) => {\n if (!a) {\n matrix[i][j] = 0;\n }\n });\n });\n\n const longestArrayIndex = matrix.reduce((acc, arr, i) => (arr.length > matrix[acc].length ? i : acc), 0);\n const longestArrayLength = matrix[longestArrayIndex].length;\n\n return matrix.map((el) => [...el, ...Array(longestArrayLength - el.length).fill(0)])\n}\n\nfunction flatten() {\n let result;\n\n if (arguments.length === 1) {\n const argument = arguments[0];\n result = isArrayLike(argument) ? argsToArray.apply(null, arguments) : [argument];\n } else {\n result = Array.from(arguments);\n }\n\n while (!isFlat(result)) {\n result = flattenShallow(result);\n }\n\n return result\n}\n\nfunction flattenShallow(array) {\n if (!array || !array.reduce) {\n return [array]\n }\n\n return array.reduce((a, b) => {\n const aIsArray = Array.isArray(a);\n const bIsArray = Array.isArray(b);\n\n if (aIsArray && bIsArray) {\n return a.concat(b)\n }\n\n if (aIsArray) {\n a.push(b);\n\n return a\n }\n\n if (bIsArray) {\n return [a].concat(b)\n }\n\n return [a, b]\n })\n}\n\nfunction initial(array, idx) {\n idx = idx || 1;\n\n if (!array || typeof array.slice !== 'function') {\n return array\n }\n\n return array.slice(0, array.length - idx)\n}\n\nfunction isArrayLike(a) {\n return a != null && typeof a.length === 'number' && typeof a !== 'string'\n}\n\nfunction isFlat(array) {\n if (!array) {\n return false\n }\n\n for (let i = 0; i < array.length; ++i) {\n if (Array.isArray(array[i])) {\n return false\n }\n }\n\n return true\n}\n\nfunction rest(array, idx) {\n idx = idx || 1;\n\n if (!array || typeof array.slice !== 'function') {\n return array\n }\n\n return array.slice(idx)\n}\n\nfunction transpose(matrix) {\n if (!matrix) {\n return value\n }\n\n return matrix[0].map((col, i) => matrix.map((row) => row[i]))\n}\n\n// Databases\nfunction findField(database, title) {\n let index = null;\n\n arrayEach(database, (value, i) => {\n if (value[0] === title) {\n index = i;\n\n return false\n }\n });\n\n // Return error if the input field title is incorrect\n if (index == null) {\n return value\n }\n\n return index\n}\n\n// Errors\nfunction anyError() {\n for (let n = 0; n < arguments.length; n++) {\n if (arguments[n] instanceof Error) {\n return arguments[n]\n }\n }\n\n return undefined\n}\n\nfunction anyIsError() {\n let n = arguments.length;\n\n while (n--) {\n if (arguments[n] instanceof Error) {\n return true\n }\n }\n\n return false\n}\n\n// Numbers\nfunction cleanFloat(number) {\n const power = 1e14;\n\n return Math.round(number * power) / power\n}\n\nfunction numbers() {\n const possibleNumbers = flatten.apply(null, arguments);\n\n return possibleNumbers.filter((el) => typeof el === 'number')\n}\n\nfunction serialNumberToDate(serial) {\n if (serial < 60) {\n serial += 1;\n }\n\n const utc_days = Math.floor(serial - 25569);\n const utc_value = utc_days * 86400;\n const date_info = new Date(utc_value * 1000);\n const fractional_day = serial - Math.floor(serial) + 0.0000001;\n\n let total_seconds = Math.floor(86400 * fractional_day);\n\n const seconds = total_seconds % 60;\n\n total_seconds -= seconds;\n\n const hours = Math.floor(total_seconds / (60 * 60));\n const minutes = Math.floor(total_seconds / 60) % 60;\n let days = date_info.getUTCDate();\n let month = date_info.getUTCMonth();\n\n if (serial >= 60 && serial < 61) {\n days = 29;\n month = 1;\n }\n\n return new Date(date_info.getUTCFullYear(), month, days, hours, minutes, seconds)\n}\n\n// Parsers\nfunction parseBool(bool) {\n if (typeof bool === 'boolean') {\n return bool\n }\n\n if (bool instanceof Error) {\n return bool\n }\n\n if (typeof bool === 'number') {\n return bool !== 0\n }\n\n if (typeof bool === 'string') {\n const up = bool.toUpperCase();\n\n if (up === 'TRUE') {\n return true\n }\n\n if (up === 'FALSE') {\n return false\n }\n }\n\n if (bool instanceof Date && !isNaN(bool)) {\n return true\n }\n\n return value\n}\n\nfunction parseDate(date) {\n if (!isNaN(date)) {\n if (date instanceof Date) {\n return new Date(date)\n }\n\n const d = parseFloat(date);\n\n if (d < 0 || d >= 2958466) {\n return num\n }\n\n return serialNumberToDate(d)\n }\n\n if (typeof date === 'string') {\n date = /(\\d{4})-(\\d\\d?)-(\\d\\d?)$/.test(date) ? new Date(date + 'T00:00:00.000') : new Date(date);\n\n if (!isNaN(date)) {\n return date\n }\n }\n\n return value\n}\n\nfunction parseDateArray(arr) {\n let len = arr.length;\n let parsed;\n\n while (len--) {\n parsed = parseDate(arr[len]);\n\n if (parsed === value) {\n return parsed\n }\n\n arr[len] = parsed;\n }\n\n return arr\n}\n\nfunction parseNumber(string) {\n if (string instanceof Error) {\n return string\n }\n\n if (string === undefined || string === null) {\n return 0\n }\n\n if (typeof string === 'boolean') {\n string = +string;\n }\n\n if (!isNaN(string) && string !== '') {\n return parseFloat(string)\n }\n\n return value\n}\n\nfunction parseNumberArray(arr) {\n let len;\n\n if (!arr || (len = arr.length) === 0) {\n return value\n }\n\n let parsed;\n\n while (len--) {\n if (arr[len] instanceof Error) {\n return arr[len]\n }\n\n parsed = parseNumber(arr[len]);\n\n if (parsed instanceof Error) {\n return parsed\n }\n\n arr[len] = parsed;\n }\n\n return arr\n}\n\nfunction parseString(string) {\n if (string instanceof Error) {\n return string\n }\n\n if (string === undefined || string === null) {\n return ''\n }\n\n return string.toString()\n}\n\n// Strings\nfunction anyIsString() {\n let n = arguments.length;\n\n while (n--) {\n if (typeof arguments[n] === 'string') {\n return true\n }\n }\n\n return false\n}\n\n// Misc\n//Filters values from a given range based on multiple criteria.\n//Returns an array containing the values that satisfy all the specified criteria.\nfunction applyCriteria() {\n const args = argsToArray(arguments);\n const range = parseNumberArray(flatten(args.shift()));\n if (range instanceof Error) {\n return range\n }\n\n const criterias = args;\n const criteriaLength = criterias.length / 2;\n\n for (let i = 0; i < criteriaLength; i++) {\n criterias[i * 2] = flatten(criterias[i * 2]);\n }\n\n let values = [];\n\n for (let i = 0; i < range.length; i++) {\n let isMetCondition = false;\n\n for (let j = 0; j < criteriaLength; j++) {\n const valueToTest = criterias[j * 2][i];\n const criteria = criterias[j * 2 + 1];\n const isWildcard = criteria === void 0 || criteria === '*';\n let computedResult = false;\n\n if (isWildcard) {\n computedResult = true;\n } else {\n const tokenizedCriteria = parse(criteria + '');\n const tokens = [createToken(valueToTest, TOKEN_TYPE_LITERAL)].concat(\n tokenizedCriteria\n );\n\n computedResult = compute(tokens);\n }\n\n // Criterias are calculated as AND so any `false` breaks the loop as unmeet condition\n if (!computedResult) {\n isMetCondition = false;\n break\n }\n\n isMetCondition = true;\n }\n\n if (isMetCondition) {\n values.push(range[i]);\n }\n }\n return values\n}\n\nfunction isDefined(arg) {\n return arg !== undefined && arg !== null\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns information about the formatting, location, or contents of a value.\n *\n * Category: Information\n *\n * @returns\n */\nfunction CELL() {\n throw new Error('CELL is not implemented')\n}\n\nconst ERROR = {};\n\nERROR.TYPE = (error_val) => {\n switch (error_val) {\n case nil:\n return 1\n case div0:\n return 2\n case value:\n return 3\n case ref:\n return 4\n case name:\n return 5\n case num:\n return 6\n case na:\n return 7\n case data:\n return 8\n }\n\n return na\n};\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns information about the current operating environment.\n *\n * Category: Information\n *\n * @returns\n */\nfunction INFO() {\n throw new Error('INFO is not implemented')\n}\n\n/**\n * Returns TRUE if the value is blank.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISBLANK(value) {\n return value === null\n}\n\n/**\n * Returns TRUE if the value is any error value except #N/A.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISERR(value$1) {\n return (\n [value, ref, div0, num, name, nil].indexOf(value$1) >= 0 ||\n (typeof value$1 === 'number' && (isNaN(value$1) || !isFinite(value$1)))\n )\n}\n\n/**\n * Returns TRUE if the value is any error value.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISERROR(value) {\n return ISERR(value) || value === na\n}\n\n/**\n * Returns TRUE if the number is even.\n *\n * Category: Information\n *\n * @param {*} number The value to test. If number is not an integer, it is truncated.\n * @returns\n */\nfunction ISEVEN(number) {\n return !(Math.floor(Math.abs(number)) & 1)\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns TRUE if there is a reference to a value that contains a formula.\n *\n * Category: Information\n *\n * @param {*} reference Reference is a reference to the value you want to test. Reference can be a value reference, a formula, or a name that refers to a value.\n * @returns\n */\nfunction ISFORMULA() {\n throw new Error('ISFORMULA is not implemented')\n}\n\n/**\n * Returns TRUE if the value is a logical value.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISLOGICAL(value) {\n return value === true || value === false\n}\n\n/**\n * Returns TRUE if the value is the #N/A error value.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISNA(value) {\n return value === na\n}\n\n/**\n * Returns TRUE if the value is not text.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISNONTEXT(value) {\n return typeof value !== 'string'\n}\n\n/**\n * Returns TRUE if the value is a number.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISNUMBER(value) {\n return typeof value === 'number' && !isNaN(value) && isFinite(value)\n}\n\n/**\n * Returns TRUE if the number is odd.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISODD(value) {\n return !!(Math.floor(Math.abs(value)) & 1)\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns TRUE if the value is a reference.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISREF() {\n throw new Error('ISREF is not implemented')\n}\n\n/**\n * Returns TRUE if the value is text.\n *\n * Category: Information\n *\n * @param {*} value The value that you want tested. The value argument can be a blank (empty value), error, logical value, text, number, or reference value, or a name referring to any of these.\n * @returns\n */\nfunction ISTEXT(value) {\n return typeof value === 'string'\n}\n\n/**\n * Returns a value converted to a number.\n *\n * Category: Information\n *\n * @param {*} value The value you want converted. N converts values listed in the following table.\n * @returns\n */\nfunction N(value) {\n if (ISNUMBER(value)) {\n return value\n }\n\n if (value instanceof Date) {\n return value.getTime()\n }\n\n if (value === true) {\n return 1\n }\n\n if (value === false) {\n return 0\n }\n\n if (ISERROR(value)) {\n return value\n }\n\n return 0\n}\n\n/**\n * Returns the error value #N/A.\n *\n * Category: Information\n *\n * @returns\n */\nfunction NA() {\n return na\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the sheet number of the referenced sheet.\n *\n * Category: Information\n *\n * @param {*} value Optional. Value is the name of a sheet or a reference for which you want the sheet number. If value is omitted, SHEET returns the number of the sheet that contains the function.\n * @returns\n */\nfunction SHEET() {\n throw new Error('SHEET is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the number of sheets in a reference.\n *\n * Category: Information\n *\n * @param {*} reference Optional. Reference is a reference for which you want to know the number of sheets it contains. If Reference is omitted, SHEETS returns the number of sheets in the workbook that contains the function.\n * @returns\n */\nfunction SHEETS() {\n throw new Error('SHEETS is not implemented')\n}\n\n/**\n * Returns a number indicating the data type of a value.\n *\n * Category: Information\n *\n * @param {*} value Can be any Microsoft Excel value, such as a number, text, logical value, and so on.\n * @returns\n */\nfunction TYPE(value) {\n if (ISNUMBER(value)) {\n return 1\n }\n\n if (ISTEXT(value)) {\n return 2\n }\n\n if (ISLOGICAL(value)) {\n return 4\n }\n\n if (ISERROR(value)) {\n return 16\n }\n\n if (Array.isArray(value)) {\n return 64\n }\n}\n\n/**\n * Chooses a value from a list of values.\n *\n * Category: Lookup and reference\n *\n * @param {*} index_num Specifies which value argument is selected. Index_num must be a number between 1 and 254, or a formula or reference to a value containing a number between 1 and 254. If index_num is 1, CHOOSE returns value1; if it is 2, CHOOSE returns value2; and so on. If index_num is less than 1 or greater than the number of the last value in the list, CHOOSE returns the #VALUE! error value. If index_num is a fraction, it is truncated to the lowest integer before being used.\n - If index_num is 1, CHOOSE returns value1; if it is 2, CHOOSE returns value2; and so on.\n - If index_num is less than 1 or greater than the number of the last value in the list, CHOOSE returns the #VALUE! error value.\n - If index_num is a fraction, it is truncated to the lowest integer before being used.\n * @param {*} args value1, value2, ... Value 1 is required, subsequent values are optional. 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on index_num. The arguments can be numbers, value references, defined names, formulas, functions, or text.\n * @returns\n */\nfunction CHOOSE() {\n if (arguments.length < 2) {\n return na\n }\n\n const index = arguments[0];\n\n if (index < 1 || index > 254) {\n return value\n }\n\n if (arguments.length < index + 1) {\n return value\n }\n\n return arguments[index]\n}\n\n/**\n * Returns the column number of a reference.\n *\n * Category: Lookup and reference\n *\n * @param {*} reference the value or range of values for which you want to return the column number.\n * @param {*} index\n * @returns\n */\nfunction COLUMN(reference, index) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (index < 0) {\n return num\n }\n\n if (!(reference instanceof Array) || typeof index !== 'number') {\n return value\n }\n\n if (reference.length === 0) {\n return undefined\n }\n\n return jStat.col(reference, index)\n}\n\n/**\n * Returns the number of columns in a reference.\n *\n * Category: Lookup and reference\n *\n * @param {*} array An array or array formula, or a reference to a range of values for which you want the number of columns.\n * @returns\n */\nfunction COLUMNS(array) {\n if (arguments.length !== 1) {\n return na\n }\n\n if (!(array instanceof Array)) {\n return value\n }\n\n if (array.length === 0) {\n return 0\n }\n\n return jStat.cols(array)\n}\n\n/**\n * Looks in the top row of an array and returns the value of the indicated value.\n *\n * Category: Lookup and reference\n *\n * @param {*} lookup_value The value to be found in the first row of the table. Lookup_value can be a value, a reference, or a text string.\n * @param {*} table_array A table of information in which data is looked up. Use a reference to a range or a range name.\n * @param {*} row_index_num The row number in table_array from which the matching value will be returned. A row_index_num of 1 returns the first row value in table_array, a row_index_num of 2 returns the second row value in table_array, and so on. If row_index_num is less than 1, HLOOKUP returns the #VALUE! error value; if row_index_num is greater than the number of rows on table_array, HLOOKUP returns the #REF! error value.\n * @param {*} range_lookup Optional. A logical value that specifies whether you want HLOOKUP to find an exact match or an approximate match. If TRUE or omitted, an approximate match is returned. In other words, if an exact match is not found, the next largest value that is less than lookup_value is returned. If FALSE, HLOOKUP will find an exact match. If one is not found, the error value #N/A is returned.\n * @returns\n */\nfunction HLOOKUP(lookup_value, table_array, row_index_num, range_lookup) {\n return VLOOKUP(lookup_value, transpose(table_array), row_index_num, range_lookup)\n}\n\n/**\n * Uses an index to choose a value from a reference or array.\n *\n * Category: Lookup and reference\n *\n * @param {*} array A range of values or an array constant.\n - If array contains only one row or column, the corresponding row_num or column_num argument is optional.\n - If array has more than one row and more than one column, and only row_num or column_num is used, INDEX returns an array of the entire row or column in array.\n * @param {*} row_num Required, unless column_num is present. Selects the row in array from which to return a value. If row_num is omitted, column_num is required.\n * @param {*} column_num Optional. Selects the column in array from which to return a value. If column_num is omitted, row_num is required.\n * @returns\n */\nfunction INDEX(array, row_num, column_num) {\n const someError = anyError(array, row_num, column_num);\n\n if (someError) {\n return someError\n }\n\n if (!Array.isArray(array)) {\n return value\n }\n\n const isOneDimensionRange = array.length > 0 && !Array.isArray(array[0]);\n\n if (isOneDimensionRange && !column_num) {\n column_num = row_num;\n row_num = 1;\n } else {\n column_num = column_num || 1;\n row_num = row_num || 1;\n }\n\n if (column_num < 0 || row_num < 0) {\n return value\n }\n\n if (isOneDimensionRange && row_num === 1 && column_num <= array.length) {\n return array[column_num - 1]\n } else if (row_num <= array.length && column_num <= array[row_num - 1].length) {\n return array[row_num - 1][column_num - 1]\n }\n\n return ref\n}\n\n/**\n * Looks up values in a vector or array.\n *\n * Category: Lookup and reference\n *\n * @param {*} lookup_value A value that LOOKUP searches for in an array. The lookup_value argument can be a number, text, a logical value, or a name or reference that refers to a value.\n - If LOOKUP can't find the value of lookup_value, it uses the largest value in the array that is less than or equal to lookup_value.\n - If the value of lookup_value is smaller than the smallest value in the first row or column (depending on the array dimensions), LOOKUP returns the #N/A error value.\n * @param {*} array A range of values that contains text, numbers, or logical values that you want to compare with lookup_value. The array form of LOOKUP is very similar to the HLOOKUP and VLOOKUP functions. The difference is that HLOOKUP searches for the value of lookup_value in the first row, VLOOKUP searches in the first column, and LOOKUP searches according to the dimensions of array.\n* @param {*} result_array Optional. A range that contains only one row or column. The result_array argument must be the same size as lookup_value. It has to be the same size.\n * @returns\n */\nfunction LOOKUP(lookup_value, array, result_array) {\n array = flatten(array);\n result_array = result_array ? flatten(result_array) : array;\n\n const isNumberLookup = typeof lookup_value === 'number';\n let result = na;\n\n for (let i = 0; i < array.length; i++) {\n if (array[i] === lookup_value) {\n return result_array[i]\n } else if (\n (isNumberLookup && array[i] <= lookup_value) ||\n (typeof array[i] === 'string' && array[i].localeCompare(lookup_value) < 0)\n ) {\n result = result_array[i];\n } else if (isNumberLookup && array[i] > lookup_value) {\n return result\n }\n }\n\n return result\n}\n\n/**\n * Looks up values in a reference or array.\n *\n * Category: Lookup and reference\n *\n * @param {*} lookup_value The value that you want to match in lookup_array. For example, when you look up someone's number in a telephone book, you are using the person's name as the lookup value, but the telephone number is the value you want.The lookup_value argument can be a value (number, text, or logical value) or a value reference to a number, text, or logical value.\n * @param {*} lookup_array The range of values being searched.\n * @param {*} match_type Optional. The number -1, 0, or 1. The match_type argument specifies how Excel matches lookup_value with values in lookup_array. The default value for this argument is 1.\n * @returns\n */\nfunction MATCH(lookup_value, lookup_array, match_type) {\n if ((!lookup_value && lookup_value !== 0) || !lookup_array) {\n return na\n }\n\n if (arguments.length === 2) {\n match_type = 1;\n }\n\n lookup_array = flatten(lookup_array);\n\n if (!(lookup_array instanceof Array)) {\n return na\n }\n\n if (match_type !== -1 && match_type !== 0 && match_type !== 1) {\n return na\n }\n\n let index;\n let indexValue;\n\n for (let idx = 0; idx < lookup_array.length; idx++) {\n if (match_type === 1) {\n if (lookup_array[idx] === lookup_value) {\n return idx + 1\n } else if (lookup_array[idx] < lookup_value) {\n if (!indexValue) {\n index = idx + 1;\n indexValue = lookup_array[idx];\n } else if (lookup_array[idx] > indexValue) {\n index = idx + 1;\n indexValue = lookup_array[idx];\n }\n }\n } else if (match_type === 0) {\n if (typeof lookup_value === 'string' && typeof lookup_array[idx] === 'string') {\n const lookupValueStr = lookup_value\n .toLowerCase()\n .replace(/\\?/g, '.')\n .replace(/\\*/g, '.*')\n .replace(/~/g, '\\\\')\n .replace(/\\+/g, '\\\\+')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]');\n\n const regex = new RegExp('^' + lookupValueStr + '$');\n\n if (regex.test(lookup_array[idx].toLowerCase())) {\n return idx + 1\n }\n } else {\n if (lookup_array[idx] === lookup_value) {\n return idx + 1\n }\n }\n } else if (match_type === -1) {\n if (lookup_array[idx] === lookup_value) {\n return idx + 1\n } else if (lookup_array[idx] > lookup_value) {\n if (!indexValue) {\n index = idx + 1;\n indexValue = lookup_array[idx];\n } else if (lookup_array[idx] < indexValue) {\n index = idx + 1;\n indexValue = lookup_array[idx];\n }\n }\n }\n }\n\n return index || na\n}\n\n/**\n * Returns the number of rows in a reference.\n *\n * Category: Lookup and reference\n *\n * @param {*} array An array, an array formula, or a reference to a range of values for which you want the number of rows.\n * @returns\n */\nfunction ROWS(array) {\n if (arguments.length !== 1) {\n return na\n }\n\n if (!(array instanceof Array)) {\n return value\n }\n\n if (array.length === 0) {\n return 0\n }\n\n return jStat.rows(array)\n}\n/**\n * Returns a sorted array of the elements in an array. The returned array is the same shape as the provided array argument.\n *\n * Category: Lookup and reference\n *\n * @param {*} array Array to sort\n * @param {*} sort_index Optional. A number indicating the row or column to sort by\n * @param {*} sort_order Optional. A number indicating the desired sort order; 1 for ascending order (default), -1 for descending order\n * @param {*} by_col Optional. A logical value indicating the desired sort direction; FALSE to sort by row (default), TRUE to sort by column\n * @returns\n */\nfunction SORT(array, sort_index = 1, sort_order = 1, by_col = false) {\n if (!array || !Array.isArray(array)) {\n return na\n }\n\n if (array.length === 0) {\n return 0\n }\n\n sort_index = parseNumber(sort_index);\n if (!sort_index || sort_index < 1) {\n return value\n }\n\n sort_order = parseNumber(sort_order);\n if (sort_order !== 1 && sort_order !== -1) {\n return value\n }\n\n by_col = parseBool(by_col);\n if (typeof by_col !== 'boolean') {\n return name\n }\n\n const sortArray = (arr) =>\n arr.sort((a, b) => {\n a = parseString(a[sort_index - 1]);\n b = parseString(b[sort_index - 1]);\n\n return sort_order === 1 ? (a < b ? sort_order * -1 : sort_order) : a > b ? sort_order : sort_order * -1\n });\n\n const matrix = fillMatrix(array);\n const result = by_col ? transpose(matrix) : matrix;\n\n return sort_index >= 1 && sort_index <= result[0].length\n ? by_col\n ? transpose(sortArray(result))\n : sortArray(result)\n : value\n}\n\n/**\n * Returns the transpose of an array.\n *\n * Category: Lookup and reference\n *\n * @param {*} array An array or range of values on a worksheet that you want to transpose. The transpose of an array is created by using the first row of the array as the first column of the new array, the second row of the array as the second column of the new array, and so on. If you're not sure of how to enter an array formula, see Create an array formula.\n * @returns\n */\nfunction TRANSPOSE(array) {\n if (!array) {\n return na\n }\n\n const matrix = fillMatrix(array);\n\n return transpose(matrix)\n}\n\n/**\n * Returns a list of unique values in a list or range.\n *\n * Category: Lookup and reference\n *\n * @returns\n */\nfunction UNIQUE() {\n const result = [];\n\n for (let i = 0; i < arguments.length; ++i) {\n let hasElement = false;\n const element = arguments[i];\n\n // Check if we've already seen this element.\n\n for (let j = 0; j < result.length; ++j) {\n hasElement = result[j] === element;\n\n if (hasElement) {\n break\n }\n }\n\n // If we did not find it, add it to the result.\n if (!hasElement) {\n result.push(element);\n }\n }\n\n return result\n}\n\n/**\n * Looks in the first column of an array and moves across the row to return the value of a value.\n *\n * Category: Lookup and reference\n *\n * @param {*} lookup_value The value to be found in the first row of the table. Lookup_value can be a value, a reference, or a text string.\n * @param {*} table_array A table of information in which data is looked up. Use a reference to a range or a range name.\n * @param {*} col_index_num The row number in table_array from which the matching value will be returned. A row_index_num of 1 returns the first row value in table_array, a row_index_num of 2 returns the second row value in table_array, and so on. If row_index_num is less than 1, HLOOKUP returns the #VALUE! error value; if row_index_num is greater than the number of rows on table_array, HLOOKUP returns the #REF! error value.\n * @param {*} range_lookup Optional. A logical value that specifies whether you want HLOOKUP to find an exact match or an approximate match. If TRUE or omitted, an approximate match is returned. In other words, if an exact match is not found, the next largest value that is less than lookup_value is returned. If FALSE, HLOOKUP will find an exact match. If one is not found, the error value #N/A is returned.\n * @returns\n */\nfunction VLOOKUP(lookup_value, table_array, col_index_num, range_lookup) {\n if (!table_array || !col_index_num) {\n return na\n }\n\n range_lookup = !(range_lookup === 0 || range_lookup === false);\n\n let result = na;\n let exactMatchOnly = false;\n\n const isNumberLookup = typeof lookup_value === 'number';\n const lookupValue = typeof lookup_value === 'string' ? lookup_value.toLowerCase() : lookup_value;\n\n for (let i = 0; i < table_array.length; i++) {\n const row = table_array[i];\n const rowValue = typeof row[0] === 'string' ? row[0].toLowerCase() : row[0];\n\n if (rowValue === lookupValue) {\n result = col_index_num < row.length + 1 ? row[col_index_num - 1] : ref;\n break\n } else if (\n !exactMatchOnly &&\n ((isNumberLookup && range_lookup && rowValue <= lookup_value) ||\n (range_lookup && typeof rowValue === 'string' && rowValue.localeCompare(lookup_value) < 0))\n ) {\n result = col_index_num < row.length + 1 ? row[col_index_num - 1] : ref;\n }\n\n if (isNumberLookup && rowValue > lookup_value) {\n exactMatchOnly = true;\n }\n }\n\n return result\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Changes full-width (double-byte) English letters or katakana within a character string to half-width (single-byte) characters.\n *\n * Category: Text\n *\n * @param {*} text The text or a reference to a value that contains the text you want to change. If text does not contain any full-width letters, text is not changed.\n * @returns\n */\nfunction ASC() {\n throw new Error('ASC is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Converts a number to text, using the ß (baht) currency format.\n *\n * Category: Text\n *\n * @param {*} number A number you want to convert to text, or a reference to a value containing a number, or a formula that evaluates to a number.\n * @returns\n */\nfunction BAHTTEXT() {\n throw new Error('BAHTTEXT is not implemented')\n}\n\n/**\n * Returns the character specified by the code number.\n *\n * Category: Text\n *\n * @param {*} number A number between 1 and 255 specifying which character you want. The character is from the character set used by your computer. Note: Excel for the web supports only CHAR(9), CHAR(10), CHAR(13), and CHAR(32) and above.\n * @returns\n */\nfunction CHAR(number) {\n number = parseNumber(number);\n\n if (number === 0) {\n return value\n }\n\n if (number instanceof Error) {\n return number\n }\n\n return String.fromCharCode(number)\n}\n\n/**\n * Removes all nonprintable characters from text.\n *\n * Category: Text\n *\n * @param {*} text Any worksheet information from which you want to remove nonprintable characters.\n * @returns\n */\nfunction CLEAN(text) {\n if (anyIsError(text)) {\n return text\n }\n\n text = text || '';\n const re = /[\\0-\\x1F]/g;\n\n return text.replace(re, '')\n}\n\n/**\n * Returns a numeric code for the first character in a text string.\n *\n * Category: Text\n *\n * @param {*} text The text for which you want the code of the first character.\n * @returns\n */\nfunction CODE(text) {\n if (anyIsError(text)) {\n return text\n }\n\n text = text || '';\n let result = text.charCodeAt(0);\n\n if (isNaN(result)) {\n result = value;\n }\n\n return result\n}\n\n/**\n * Joins several text items into one text item.\n *\n * Category: Text\n *\n * @returns\n */\nfunction CONCATENATE() {\n const args = flatten(arguments);\n const someError = anyError.apply(undefined, args);\n\n if (someError) {\n return someError\n }\n\n let trueFound = 0;\n\n while ((trueFound = args.indexOf(true)) > -1) {\n args[trueFound] = 'TRUE';\n }\n\n let falseFound = 0;\n\n while ((falseFound = args.indexOf(false)) > -1) {\n args[falseFound] = 'FALSE';\n }\n\n return args.join('')\n}\n\nconst CONCAT = CONCATENATE;\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Changes half-width (single-byte) English letters or katakana within a character string to full-width (double-byte) characters.\n *\n * Category: Text\n *\n * @param {*} text The text or a reference to a value that contains the text you want to change. If text does not contain any half-width English letters or katakana, text is not changed.\n * @returns\n */\nfunction DBCS() {\n throw new Error('DBCS is not implemented')\n}\n\n/**\n * Converts a number to text, using the $ (dollar) currency format.\n *\n * Category: Text\n *\n * @param {*} number A number, a reference to a value containing a number, or a formula that evaluates to a number.\n * @param {*} decimals Optional. The number of digits to the right of the decimal point. If this is negative, the number is rounded to the left of the decimal point. If you omit decimals, it is assumed to be 2.\n * @returns\n */\nfunction DOLLAR(number, decimals = 2) {\n number = parseNumber(number);\n if (isNaN(number)) {\n return value\n }\n\n number = ROUND(number, decimals);\n\n const options = {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: decimals >= 0 ? decimals : 0,\n maximumFractionDigits: decimals >= 0 ? decimals : 0\n };\n\n const formattedNumber = number.toLocaleString('en-US', options);\n\n if (number < 0) {\n return '$(' + formattedNumber.slice(2) + ')'\n }\n\n return formattedNumber\n}\n\n/**\n * Checks to see if two text values are identical.\n *\n * Category: Text\n *\n * @param {*} text1 The first text string.\n * @param {*} text2 The second text string.\n * @returns\n */\nfunction EXACT(text1, text2) {\n if (arguments.length !== 2) {\n return na\n }\n\n const someError = anyError(text1, text2);\n\n if (someError) {\n return someError\n }\n\n text1 = parseString(text1);\n text2 = parseString(text2);\n\n return text1 === text2\n}\n\n/**\n * Locate one text string within a second text string, and return the number of the starting position of the first text string from the first character of the second text string.\n *\n * Category: Text\n *\n * @param {*} find_text The text you want to find.\n * @param {*} within_text The text containing the text you want to find.\n * @param {*} start_num Optional. Specifies the character at which to start the search. The first character in within_text is character number 1. If you omit start_num, it is assumed to be 1.\n * @returns\n */\nfunction FIND(find_text, within_text, start_num) {\n if (arguments.length < 2) {\n return na\n }\n\n find_text = parseString(find_text);\n within_text = parseString(within_text);\n start_num = start_num === undefined ? 0 : start_num;\n const found_index = within_text.indexOf(find_text, start_num - 1);\n\n if (found_index === -1) {\n return value\n }\n\n return found_index + 1\n}\n\n/**\n * Formats a number as text with a fixed number of decimals.\n *\n * Category: Text\n *\n * @param {*} number The number you want to round and convert to text.\n * @param {*} decimals Optional. The number of digits to the right of the decimal point.\n * @param {*} no_commas Optional. A logical value that, if TRUE, prevents FIXED from including commas in the returned text.\n * @returns\n */\nfunction FIXED(number, decimals = 2, no_commas = false) {\n number = parseNumber(number);\n if (isNaN(number)) {\n return value\n }\n\n decimals = parseNumber(decimals);\n if (isNaN(decimals)) {\n return value\n }\n\n if (decimals < 0) {\n const factor = Math.pow(10, -decimals);\n number = Math.round(number / factor) * factor;\n } else {\n number = number.toFixed(decimals);\n }\n\n if (no_commas) {\n number = number.toString().replace(/,/g, '');\n } else {\n const parts = number.toString().split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+$)/g, ',');\n number = parts.join('.');\n }\n\n return number\n}\n\n/**\n * Returns the leftmost characters from a text value.\n *\n * Category: Text\n *\n * @param {*} text The text string that contains the characters you want to extract.\n * @param {*} num_chars Optional. Specifies the number of characters you want LEFT to extract.\n * @returns\n */\nfunction LEFT(text, num_chars) {\n const someError = anyError(text, num_chars);\n\n if (someError) {\n return someError\n }\n\n text = parseString(text);\n num_chars = num_chars === undefined ? 1 : num_chars;\n num_chars = parseNumber(num_chars);\n\n if (num_chars instanceof Error || typeof text !== 'string') {\n return value\n }\n\n return text.substring(0, num_chars)\n}\n\n/**\n * Returns the number of characters in a text string\n *\n * Category: Text\n *\n * @param {*} text The text whose length you want to find. Spaces count as characters.\n * @returns\n */\nfunction LEN(text) {\n if (arguments.length === 0) {\n return error\n }\n\n if (text instanceof Error) {\n return text\n }\n\n if (Array.isArray(text)) {\n return value\n }\n\n const textAsString = parseString(text);\n\n return textAsString.length\n}\n\n/**\n * Converts text to lowercase.\n *\n * Category: Text\n *\n * @param {*} text The text you want to convert to lowercase. LOWER does not change characters in text that are not letters.\n * @returns\n */\nfunction LOWER(text) {\n if (arguments.length !== 1) {\n return value\n }\n\n text = parseString(text);\n\n if (anyIsError(text)) {\n return text\n }\n\n return text.toLowerCase()\n}\n\n/**\n * Returns a specific number of characters from a text string starting at the position you specify\n *\n * Category: Text\n *\n * @param {*} text The text string containing the characters you want to extract.\n * @param {*} start_num The position of the first character you want to extract in text. The first character in text has start_num 1, and so on.\n * @param {*} num_chars Specifies the number of characters you want MID to return from text.\n * @returns\n */\nfunction MID(text, start_num, num_chars) {\n if (start_num === undefined || start_num === null) {\n return value\n }\n\n start_num = parseNumber(start_num);\n num_chars = parseNumber(num_chars);\n\n if (anyIsError(start_num, num_chars) || typeof text !== 'string') {\n return num_chars\n }\n\n const begin = start_num - 1;\n const end = begin + num_chars;\n\n return text.substring(begin, end)\n}\n\n// TODO\n/**\n * Converts text to number in a locale-independent manner.\n *\n * Category: Text\n *\n * @param {*} text The text to convert to a number.\n * @param {*} decimal_separator Optional. The character used to separate the integer and fractional part of the result.\n * @param {*} group_separator Optional. The character used to separate groupings of numbers, such as thousands from hundreds and millions from thousands.\n * @returns\n */\nfunction NUMBERVALUE(text, decimal_separator, group_separator) {\n text = isDefined(text) ? text : '';\n\n if (typeof text === 'number') {\n return text\n }\n\n if (typeof text !== 'string') {\n return na\n }\n\n decimal_separator = typeof decimal_separator === 'undefined' ? '.' : decimal_separator;\n group_separator = typeof group_separator === 'undefined' ? ',' : group_separator;\n\n return Number(text.replace(decimal_separator, '.').replace(group_separator, ''))\n}\n\n// TODO\n/**\n * -- Not implemented --\n */\nfunction PRONETIC() {\n throw new Error('PRONETIC is not implemented')\n}\n\n/**\n * Capitalizes the first letter in each word of a text value.\n *\n * Category: Text\n *\n * @param {*} text Text enclosed in quotation marks, a formula that returns text, or a reference to a value containing the text you want to partially capitalize.\n * @returns\n */\nfunction PROPER(text) {\n if (anyIsError(text)) {\n return text\n }\n\n if (isNaN(text) && typeof text === 'number') {\n return value\n }\n\n text = parseString(text);\n\n return text.replace(/\\w\\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())\n}\n\n/**\n * Replaces characters within text\n *\n * Category: Text\n *\n * @param {*} old_text Text in which you want to replace some characters.\n * @param {*} num_chars The number of characters in old_text that you want REPLACE to replace with new_text.\n * @param {*} length he number of characters in old_text that you want REPLACEB to replace with new_text.\n * @param {*} new_text he text that will replace characters in old_text.\n * @returns\n */\nfunction REPLACE(old_text, num_chars, length, new_text) {\n num_chars = parseNumber(num_chars);\n length = parseNumber(length);\n\n if (anyIsError(num_chars, length) || typeof old_text !== 'string' || typeof new_text !== 'string') {\n return value\n }\n\n return old_text.substr(0, num_chars - 1) + new_text + old_text.substr(num_chars - 1 + length)\n}\n\n/**\n * Repeats text a given number of times.\n *\n * Category: Text\n *\n * @param {*} text The text you want to repeat.\n * @param {*} number_times A positive number specifying the number of times to repeat text.\n * @returns\n */\nfunction REPT(text, number_times) {\n const someError = anyError(text, number_times);\n\n if (someError) {\n return someError\n }\n\n text = parseString(text);\n number_times = parseNumber(number_times);\n\n if (number_times instanceof Error) {\n return number_times\n }\n\n return new Array(number_times + 1).join(text)\n}\n\n/**\n * Returns the rightmost characters from a text value\n *\n * Category: Text\n *\n * @param {*} text The text string containing the characters you want to extract.\n * @param {*} num_chars Optional. Specifies the number of characters you want RIGHT to extract.\n * @returns\n */\nfunction RIGHT(text, num_chars) {\n const someError = anyError(text, num_chars);\n\n if (someError) {\n return someError\n }\n\n text = parseString(text);\n num_chars = num_chars === undefined ? 1 : num_chars;\n num_chars = parseNumber(num_chars);\n\n if (num_chars instanceof Error) {\n return num_chars\n }\n\n return text.substring(text.length - num_chars)\n}\n\n/**\n * Finds one text value within another (not case-sensitive)\n *\n * Category: Text\n *\n * @param {*} find_text The text that you want to find.\n * @param {*} within_text The text in which you want to search for the value of the find_text argument.\n * @param {*} start_num Optional. The character number in the within_text argument at which you want to start searching.\n * @returns\n */\nfunction SEARCH(find_text, within_text, start_num) {\n let foundAt;\n\n if (typeof find_text !== 'string' || typeof within_text !== 'string') {\n return value\n }\n\n start_num = start_num === undefined ? 0 : start_num;\n foundAt = within_text.toLowerCase().indexOf(find_text.toLowerCase(), start_num - 1) + 1;\n\n return foundAt === 0 ? value : foundAt\n}\n\n/**\n * Substitutes new text for old text in a text string.\n *\n * Category: Text\n *\n * @param {*} text The text or the reference to a value containing text for which you want to substitute characters.\n * @param {*} old_text The text you want to replace.\n * @param {*} new_text The text you want to replace old_text with.\n * @param {*} instance_num Optional. Specifies which occurrence of old_text you want to replace with new_text. If you specify instance_num, only that instance of old_text is replaced. Otherwise, every occurrence of old_text in text is changed to new_text.\n * @returns\n */\nfunction SUBSTITUTE(text, old_text, new_text, instance_num) {\n if (arguments.length < 3) {\n return na\n }\n\n if (!text || !old_text) {\n return text\n } else if (instance_num === undefined) {\n return text.split(old_text).join(new_text)\n } else {\n instance_num = Math.floor(Number(instance_num));\n\n if (Number.isNaN(instance_num) || instance_num <= 0) {\n return value\n }\n\n let index = 0;\n let i = 0;\n\n while (index > -1 && text.indexOf(old_text, index) > -1) {\n index = text.indexOf(old_text, index + 1);\n i++;\n\n if (index > -1 && i === instance_num) {\n return text.substring(0, index) + new_text + text.substring(index + old_text.length)\n }\n }\n\n return text\n }\n}\n\n/**\n * Converts its arguments to text.\n *\n * Category: Text\n *\n * @param {*} value The value you want to test.\n * @returns\n */\nfunction T(value) {\n if (value instanceof Error) {\n return value\n }\n\n return typeof value === 'string' ? value : ''\n}\n\n/**\n * Formats a number and converts it to text.\n *\n * Category: Text\n *\n * @param {*} value A numeric value that you want to be converted into text.\n * @param {*} format_text A text string that defines the formatting that you want to be applied to the supplied value.\n * @returns\n */\nfunction TEXT(value$1, format_text) {\n if (value$1 === undefined || value$1 instanceof Error || format_text instanceof Error) {\n return na\n }\n\n if (value$1 instanceof Date) {\n return value$1.toISOString().slice(0, 10)\n }\n\n if (format_text === undefined || format_text === null) {\n return ''\n }\n\n if (typeof format_text === 'number') {\n return String(format_text)\n }\n\n if (typeof format_text !== 'string') {\n return value\n }\n\n const currencySymbol = format_text.startsWith('$') ? '$' : '';\n const isPercent = format_text.endsWith('%');\n format_text = format_text.replace(/%/g, '').replace(/\\$/g, '');\n\n // count all 0s after the decimal point\n const decimalPlaces = format_text.includes('.') ? format_text.split('.')[1].match(/0/g).length : 0;\n\n const noCommas = !format_text.includes(',');\n\n if (isPercent) {\n value$1 = value$1 * 100;\n }\n\n value$1 = FIXED(value$1, decimalPlaces, noCommas);\n\n if (value$1.startsWith('-')) {\n value$1 = value$1.replace('-', '');\n value$1 = '-' + currencySymbol + value$1;\n } else {\n value$1 = currencySymbol + value$1;\n }\n\n if (isPercent) {\n value$1 = value$1 + '%';\n }\n\n return value$1\n}\n\n/**\n * Combines the text from multiple ranges and/or strings.\n *\n * Category: Text\n * @param {*} delimiter A text string, either empty, or one or more characters enclosed by double quotes, or a reference to a valid text string. If a number is supplied, it will be treated as text.\n * @param {*} ignore_empty If TRUE, ignores empty values.\n * @param {*} args Text item to be joined. A text string, or array of strings, such as a range of values.\n * @returns\n */\nfunction TEXTJOIN(delimiter, ignore_empty, ...args) {\n if (typeof ignore_empty !== 'boolean') {\n ignore_empty = parseBool(ignore_empty);\n }\n\n if (arguments.length < 3) {\n return na\n }\n\n delimiter = delimiter !== null && delimiter !== undefined ? delimiter : '';\n\n let flatArgs = flatten(args);\n let textToJoin = ignore_empty ? flatArgs.filter((text) => text) : flatArgs;\n\n if (Array.isArray(delimiter)) {\n delimiter = flatten(delimiter);\n\n let chunks = textToJoin.map((item) => [item]);\n let index = 0;\n\n for (let i = 0; i < chunks.length - 1; i++) {\n chunks[i].push(delimiter[index]);\n index++;\n\n if (index === delimiter.length) {\n index = 0;\n }\n }\n\n textToJoin = flatten(chunks);\n\n return textToJoin.join('')\n }\n\n return textToJoin.join(delimiter)\n}\n\n/**\n * Removes spaces from text.\n *\n * Category: Text\n *\n * @param {*} text The text from which you want spaces removed.\n * @returns\n */\nfunction TRIM(text) {\n text = parseString(text);\n\n if (text instanceof Error) {\n return text\n }\n\n return text.replace(/\\s+/g, ' ').trim()\n}\n\nconst UNICHAR = CHAR;\n\nconst UNICODE = CODE;\n\n/**\n * Converts text to uppercase.\n *\n * Category: Text\n *\n * @param {*} text The text you want converted to uppercase. Text can be a reference or text string.\n * @returns\n */\nfunction UPPER(text) {\n text = parseString(text);\n\n if (text instanceof Error) {\n return text\n }\n\n return text.toUpperCase()\n}\n\n/**\n * Converts a text argument to a number.\n *\n * Category: Text\n *\n * @param {*} text The text enclosed in quotation marks or a reference to a value containing the text you want to convert.\n * @returns\n */\nfunction VALUE(text) {\n const anyError$1 = anyError(text);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (typeof text === 'number') {\n return text\n }\n\n if (!isDefined(text)) {\n text = '';\n }\n\n if (typeof text !== 'string') {\n return value\n }\n\n const isPercent = /(%)$/.test(text) || /^(%)/.test(text);\n text = text.replace(/^[^0-9-]{0,3}/, '');\n text = text.replace(/[^0-9]{0,3}$/, '');\n text = text.replace(/[ ,]/g, '');\n\n if (text === '') {\n return 0\n }\n\n let output = Number(text);\n\n if (isNaN(output)) {\n return value\n }\n\n output = output || 0;\n\n if (isPercent) {\n output = output * 0.01;\n }\n\n return output\n}\n\nconst SQRT2PI = 2.5066282746310002;\n\n/**\n * Returns the average of the absolute deviations of data points from their mean.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want the average of the absolute deviations. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction AVEDEV() {\n const flatArguments = flatten(arguments);\n const flatArgumentsDefined = flatArguments.filter(isDefined);\n\n if (flatArgumentsDefined.length === 0) {\n return num\n }\n\n const range = parseNumberArray(flatArgumentsDefined);\n\n if (range instanceof Error) {\n return range\n }\n\n return jStat.sum(jStat(range).subtract(jStat.mean(range)).abs()[0]) / range.length\n}\n\n/**\n * Returns the average of its arguments.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ...Numbers, value references or ranges for which you want the average.\n * @returns\n */\nfunction AVERAGE() {\n const flatArguments = flatten(arguments);\n const flatArgumentsDefined = flatArguments.filter(isDefined);\n\n if (flatArgumentsDefined.length === 0) {\n return div0\n }\n\n const someError = anyError.apply(undefined, flatArgumentsDefined);\n\n if (someError) {\n return someError\n }\n\n const range = numbers(flatArgumentsDefined);\n const n = range.length;\n\n let sum = 0;\n let count = 0;\n let result;\n\n for (let i = 0; i < n; i++) {\n sum += range[i];\n count += 1;\n }\n\n result = sum / count;\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the average of its arguments, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 255 values, ranges of values, or values for which you want the average.\n * @returns\n */\nfunction AVERAGEA() {\n const flatArguments = flatten(arguments);\n const flatArgumentsDefined = flatArguments.filter(isDefined);\n\n if (flatArgumentsDefined.length === 0) {\n return div0\n }\n\n const someError = anyError.apply(undefined, flatArgumentsDefined);\n\n if (someError) {\n return someError\n }\n\n const range = flatArgumentsDefined;\n const n = range.length;\n\n let sum = 0;\n let count = 0;\n let result;\n\n for (let i = 0; i < n; i++) {\n const el = range[i];\n\n if (typeof el === 'number') {\n sum += el;\n }\n\n if (el === true) {\n sum++;\n }\n\n if (el !== null) {\n count++;\n }\n }\n\n result = sum / count;\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the average (arithmetic mean) of all the values in a range that meet a given criteria.\n *\n * Category: Statistical\n *\n * @param {*} range One or more values to average, including numbers or names, arrays, or references that contain numbers.\n * @param {*} criteria The criteria in the form of a number, expression, value reference, or text that defines which values are averaged.\n * @param {*} average_range Optional. The actual set of values to average. If omitted, range is used.\n * @returns\n */\nfunction AVERAGEIF(range, criteria, average_range) {\n if (arguments.length <= 1) {\n return na\n }\n\n average_range = average_range || range;\n\n const flatAverageRange = flatten(average_range);\n const flatAverageRangeDefined = flatAverageRange.filter(isDefined);\n\n average_range = parseNumberArray(flatAverageRangeDefined);\n range = flatten(range);\n\n if (average_range instanceof Error) {\n return average_range\n }\n\n let average_count = 0;\n let result = 0;\n\n const isWildcard = criteria === void 0 || criteria === '*';\n const tokenizedCriteria = isWildcard ? null : parse(criteria + '');\n\n for (let i = 0; i < range.length; i++) {\n const value = range[i];\n\n if (isWildcard) {\n result += average_range[i];\n average_count++;\n } else {\n const tokens = [createToken(value, TOKEN_TYPE_LITERAL)].concat(tokenizedCriteria);\n\n if (compute(tokens)) {\n result += average_range[i];\n average_count++;\n }\n }\n }\n\n return result / average_count\n}\n\n/**\n * Returns the average (arithmetic mean) of all values that meet multiple criteria.\n *\n * Category: Statistical\n *\n * @param {*} args One or more values to average, including numbers or names, arrays, or references that contain numbers.\n * @returns\n */\nfunction AVERAGEIFS() {\n // Does not work with multi dimensional ranges yet!\n // http://office.microsoft.com/en-001/excel-help/averageifs-function-HA010047493.aspx\n const values = applyCriteria(...arguments);\n const result = values.reduce((acc, value) => acc + value, 0);\n const average = result / values.length;\n\n return isNaN(average) ? 0 : average\n}\n\nconst BETA = {};\n\n/**\n * Returns the beta cumulative distribution function.\n *\n * Category: Statistical\n *\n * @param {*} x The value between A and B at which to evaluate the function\n * @param {*} alpha A parameter of the distribution.\n * @param {*} beta A parameter of the distribution.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, BETA.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @param {*} a Optional. A lower bound to the interval of x.\n * @param {*} b Optional. An upper bound to the interval of x.\n * @returns\n */\nBETA.DIST = function (x, alpha, beta, cumulative, a, b) {\n if (arguments.length < 4) {\n return value\n }\n\n a = a === undefined ? 0 : a;\n b = b === undefined ? 1 : b;\n\n x = parseNumber(x);\n alpha = parseNumber(alpha);\n beta = parseNumber(beta);\n a = parseNumber(a);\n b = parseNumber(b);\n\n if (anyIsError(x, alpha, beta, a, b)) {\n return value\n }\n\n x = (x - a) / (b - a);\n\n return cumulative ? jStat.beta.cdf(x, alpha, beta) : jStat.beta.pdf(x, alpha, beta)\n};\n\n/**\n * Returns the inverse of the cumulative distribution function for a specified beta distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability associated with the beta distribution.\n * @param {*} alpha A parameter of the distribution.\n * @param {*} beta A parameter the distribution.\n * @param {*} a Optional. A lower bound to the interval of x.\n * @param {*} b Optional. An upper bound to the interval of x.\n * @returns\n */\nBETA.INV = (probability, alpha, beta, a, b) => {\n a = a === undefined ? 0 : a;\n b = b === undefined ? 1 : b;\n probability = parseNumber(probability);\n alpha = parseNumber(alpha);\n beta = parseNumber(beta);\n a = parseNumber(a);\n b = parseNumber(b);\n\n if (anyIsError(probability, alpha, beta, a, b)) {\n return value\n }\n\n return jStat.beta.inv(probability, alpha, beta) * (b - a) + a\n};\n\nconst BINOM = {};\n\n/**\n * Returns the individual term binomial distribution probability.\n *\n * Category: Statistical\n *\n * @param {*} number_s The number of successes in trials.\n * @param {*} trials The number of independent trials.\n * @param {*} probability_s The probability of success on each trial.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, then BINOM.DIST returns the cumulative distribution function, which is the probability that there are at most number_s successes; if FALSE, it returns the probability mass function, which is the probability that there are number_s successes.\n * @returns\n */\nBINOM.DIST = (number_s, trials, probability_s, cumulative) => {\n number_s = parseNumber(number_s);\n trials = parseNumber(trials);\n probability_s = parseNumber(probability_s);\n cumulative = parseNumber(cumulative);\n\n if (anyIsError(number_s, trials, probability_s, cumulative)) {\n return value\n }\n\n return cumulative\n ? jStat.binomial.cdf(number_s, trials, probability_s)\n : jStat.binomial.pdf(number_s, trials, probability_s)\n};\n\n/**\n * Returns the probability of a trial result using a binomial distribution.\n *\n * Category: Statistical\n *\n * @param {*} trials The number of independent trials. Must be greater than or equal to 0.\n * @param {*} probability_s The probability of success in each trial. Must be greater than or equal to 0 and less than or equal to 1.\n * @param {*} number_s The number of successes in trials. Must be greater than or equal to 0 and less than or equal to Trials.\n * @param {*} number_s2 Optional. If provided, returns the probability that the number of successful trials will fall between Number_s and number_s2. Must be greater than or equal to Number_s and less than or equal to Trials.\n * @returns\n */\nBINOM.DIST.RANGE = (trials, probability_s, number_s, number_s2) => {\n number_s2 = number_s2 === undefined ? number_s : number_s2;\n\n trials = parseNumber(trials);\n probability_s = parseNumber(probability_s);\n number_s = parseNumber(number_s);\n number_s2 = parseNumber(number_s2);\n\n if (anyIsError(trials, probability_s, number_s, number_s2)) {\n return value\n }\n\n let result = 0;\n\n for (let i = number_s; i <= number_s2; i++) {\n result += COMBIN(trials, i) * Math.pow(probability_s, i) * Math.pow(1 - probability_s, trials - i);\n }\n\n return result\n};\n\n/**\n * Returns the smallest value for which the cumulative binomial distribution is less than or equal to a criterion value.\n *\n * Category: Statistical\n *\n * @param {*} trials The number of Bernoulli trials.\n * @param {*} probability_s The probability of a success on each trial.\n * @param {*} alpha The criterion value.\n * @returns\n */\nBINOM.INV = (trials, probability_s, alpha) => {\n trials = parseNumber(trials);\n probability_s = parseNumber(probability_s);\n alpha = parseNumber(alpha);\n\n if (anyIsError(trials, probability_s, alpha)) {\n return value\n }\n\n let x = 0;\n\n while (x <= trials) {\n if (jStat.binomial.cdf(x, trials, probability_s) >= alpha) {\n return x\n }\n\n x++;\n }\n};\n\nconst CHISQ = {};\n\n/**\n * Returns the cumulative beta probability density function.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which you want to evaluate the distribution.\n * @param {*} deg_freedom The number of degrees of freedom.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, CHISQ.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nCHISQ.DIST = (x, deg_freedom, cumulative) => {\n x = parseNumber(x);\n deg_freedom = parseNumber(deg_freedom);\n\n if (anyIsError(x, deg_freedom)) {\n return value\n }\n\n return cumulative ? jStat.chisquare.cdf(x, deg_freedom) : jStat.chisquare.pdf(x, deg_freedom)\n};\n\n/**\n * Returns the one-tailed probability of the chi-squared distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which you want to evaluate the distribution.\n * @param {*} deg_freedom The number of degrees of freedom.\n * @returns\n */\nCHISQ.DIST.RT = (x, deg_freedom) => {\n if (!x | !deg_freedom) {\n return na\n }\n\n if (x < 1 || deg_freedom > Math.pow(10, 10)) {\n return num\n }\n\n if (typeof x !== 'number' || typeof deg_freedom !== 'number') {\n return value\n }\n\n return 1 - jStat.chisquare.cdf(x, deg_freedom)\n};\n\n/**\n * Returns the cumulative beta probability density function.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability associated with the chi-squared distribution.\n * @param {*} deg_freedom The number of degrees of freedom.\n * @returns\n */\nCHISQ.INV = (probability, deg_freedom) => {\n probability = parseNumber(probability);\n deg_freedom = parseNumber(deg_freedom);\n\n if (anyIsError(probability, deg_freedom)) {\n return value\n }\n\n return jStat.chisquare.inv(probability, deg_freedom)\n};\n\n/**\n * Returns the inverse of the one-tailed probability of the chi-squared distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability associated with the chi-squared distribution.\n * @param {*} deg_freedom The number of degrees of freedom.\n * @returns\n */\nCHISQ.INV.RT = (probability, deg_freedom) => {\n if (!probability | !deg_freedom) {\n return na\n }\n\n if (probability < 0 || probability > 1 || deg_freedom < 1 || deg_freedom > Math.pow(10, 10)) {\n return num\n }\n\n if (typeof probability !== 'number' || typeof deg_freedom !== 'number') {\n return value\n }\n\n return jStat.chisquare.inv(1.0 - probability, deg_freedom)\n};\n\n/**\n * Returns the test for independence.\n *\n * Category: Statistical\n *\n * @param {*} actual_range The range of data that contains observations to test against expected values.\n * @param {*} expected_range The range of data that contains the ratio of the product of row totals and column totals to the grand total.\n * @returns\n */\nCHISQ.TEST = function (actual_range, expected_range) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (!(actual_range instanceof Array) || !(expected_range instanceof Array)) {\n return value\n }\n\n if (actual_range.length !== expected_range.length) {\n return value\n }\n\n if (actual_range[0] && expected_range[0] && actual_range[0].length !== expected_range[0].length) {\n return value\n }\n\n const row = actual_range.length;\n\n let tmp, i, j;\n\n // Convert single-dimension array into two-dimension array\n\n for (i = 0; i < row; i++) {\n if (!(actual_range[i] instanceof Array)) {\n tmp = actual_range[i];\n\n actual_range[i] = [];\n actual_range[i].push(tmp);\n }\n\n if (!(expected_range[i] instanceof Array)) {\n tmp = expected_range[i];\n\n expected_range[i] = [];\n expected_range[i].push(tmp);\n }\n }\n\n const col = actual_range[0].length;\n const dof = col === 1 ? row - 1 : (row - 1) * (col - 1);\n\n let xsqr = 0;\n\n const Pi = Math.PI;\n\n for (i = 0; i < row; i++) {\n for (j = 0; j < col; j++) {\n xsqr += Math.pow(actual_range[i][j] - expected_range[i][j], 2) / expected_range[i][j];\n }\n }\n\n // Get independency by X square and its degree of freedom\n function ChiSq(xsqr, dof) {\n let p = Math.exp(-0.5 * xsqr);\n\n if (dof % 2 === 1) {\n p = p * Math.sqrt((2 * xsqr) / Pi);\n }\n\n let k = dof;\n\n while (k >= 2) {\n p = (p * xsqr) / k;\n k = k - 2;\n }\n\n let t = p;\n let a = dof;\n\n while (t > 0.0000000001 * p) {\n a = a + 2;\n t = (t * xsqr) / a;\n p = p + t;\n }\n\n return 1 - p\n }\n\n return Math.round(ChiSq(xsqr, dof) * 1000000) / 1000000\n};\n\nconst CONFIDENCE = {};\n\n/**\n * Returns the confidence interval for a population mean.\n *\n * Category: Statistical\n *\n * @param {*} alpha The significance level used to compute the confidence level. The confidence level equals 100*(1 - alpha)%, or in other words, an alpha of 0.05 indicates a 95 percent confidence level.\n * @param {*} standard_dev The population standard deviation for the data range and is assumed to be known.\n * @param {*} size The sample size.\n * @returns\n */\nCONFIDENCE.NORM = (alpha, standard_dev, size) => {\n alpha = parseNumber(alpha);\n standard_dev = parseNumber(standard_dev);\n size = parseNumber(size);\n\n if (anyIsError(alpha, standard_dev, size)) {\n return value\n }\n\n return jStat.normalci(1, alpha, standard_dev, size)[1] - 1\n};\n\n/**\n * Returns the confidence interval for a population mean, using a Student's t distribution.\n *\n * Category: Statistical\n *\n * @param {*} alpha The significance level used to compute the confidence level. The confidence level equals 100*(1 - alpha)%, or in other words, an alpha of 0.05 indicates a 95 percent confidence level.\n * @param {*} standard_dev The population standard deviation for the data range and is assumed to be known.\n * @param {*} size The sample size.\n * @returns\n */\nCONFIDENCE.T = (alpha, standard_dev, size) => {\n alpha = parseNumber(alpha);\n standard_dev = parseNumber(standard_dev);\n size = parseNumber(size);\n\n if (anyIsError(alpha, standard_dev, size)) {\n return value\n }\n\n return jStat.tci(1, alpha, standard_dev, size)[1] - 1\n};\n\n/**\n * Returns the correlation coefficient between two data sets.\n *\n * Category: Statistical\n *\n * @param {*} array1 A range of value values.\n * @param {*} array2 A second range of value values.\n * @returns\n */\nfunction CORREL(array1, array2) {\n array1 = parseNumberArray(flatten(array1));\n array2 = parseNumberArray(flatten(array2));\n\n if (anyIsError(array1, array2)) {\n return value\n }\n\n return jStat.corrcoeff(array1, array2)\n}\n\n/**\n * Counts how many numbers are in the list of arguments.\n *\n * Category: Statistical\n *\n * @param {*} args Cell reference, or range within which you want to count numbers.count numbers.\n * @returns\n */\nfunction COUNT() {\n const flatArguments = flatten(arguments);\n\n return numbers(flatArguments).length\n}\n\n/**\n * Counts how many values are in the list of arguments.\n *\n * Category: Statistical\n *\n * @param {*} args Arguments representing the values that you want to count.\n * @returns\n */\nfunction COUNTA() {\n const flatArguments = flatten(arguments);\n\n return flatArguments.length - COUNTBLANK(flatArguments)\n}\n\n/**\n * Counts the number of blank values within a range.\n *\n * Category: Statistical\n *\n * @param {*} args The range from which you want to count the blank values.\n * @returns\n */\nfunction COUNTBLANK() {\n const range = flatten(arguments);\n\n let blanks = 0;\n let element;\n\n for (let i = 0; i < range.length; i++) {\n element = range[i];\n\n if (element === undefined || element === null || element === '') {\n blanks++;\n }\n }\n\n return blanks\n}\n\n/**\n * Counts the number of values within a range that meet the given criteria.\n *\n * Category: Statistical\n *\n * @returns\n */\nfunction COUNTIF(range, criteria) {\n range = flatten(range);\n\n const isWildcard = criteria === void 0 || criteria === '*';\n\n if (isWildcard) {\n return range.length\n }\n\n let matches = 0;\n\n const tokenizedCriteria = parse(criteria + '');\n\n for (let i = 0; i < range.length; i++) {\n const value = range[i];\n const tokens = [createToken(value, TOKEN_TYPE_LITERAL)].concat(tokenizedCriteria);\n\n if (compute(tokens)) {\n matches++;\n }\n }\n\n return matches\n}\n\n/**\n * Counts the number of values within a range that meet multiple criteria.\n *\n * Category: Statistical\n *\n * @param {*} args Range in which to evaluate the associated criteria.\n * @returns\n */\nfunction COUNTIFS() {\n const args = argsToArray(arguments);\n const results = new Array(flatten(args[0]).length);\n\n for (let i = 0; i < results.length; i++) {\n results[i] = true;\n }\n\n for (let i = 0; i < args.length; i += 2) {\n const range = flatten(args[i]);\n const criteria = args[i + 1];\n const isWildcard = criteria === void 0 || criteria === '*';\n\n if (!isWildcard) {\n const tokenizedCriteria = parse(criteria + '');\n\n for (let j = 0; j < range.length; j++) {\n const value = range[j];\n const tokens = [createToken(value, TOKEN_TYPE_LITERAL)].concat(tokenizedCriteria);\n\n results[j] = results[j] && compute(tokens);\n }\n }\n }\n\n let result = 0;\n\n for (let i = 0; i < results.length; i++) {\n if (results[i]) {\n result++;\n }\n }\n\n return result\n}\n\nconst COVARIANCE = {};\n\n/**\n * Returns covariance, the average of the products of paired deviations.\n *\n * Category: Statistical\n *\n * @param {*} array1 The first value range of integers.\n * @param {*} array2 The second value range of integers.\n * @returns\n */\nCOVARIANCE.P = (array1, array2) => {\n array1 = parseNumberArray(flatten(array1));\n array2 = parseNumberArray(flatten(array2));\n\n if (anyIsError(array1, array2)) {\n return value\n }\n\n const mean1 = jStat.mean(array1);\n const mean2 = jStat.mean(array2);\n\n let result = 0;\n\n const n = array1.length;\n\n for (let i = 0; i < n; i++) {\n result += (array1[i] - mean1) * (array2[i] - mean2);\n }\n\n return result / n\n};\n\n/**\n * Returns the sample covariance, the average of the products deviations for each data point pair in two data sets.\n *\n * Category: Statistical\n *\n * @param {*} array1 The first value range of integers.\n * @param {*} array2 The second value range of integers.\n * @returns\n */\nCOVARIANCE.S = (array1, array2) => {\n array1 = parseNumberArray(flatten(array1));\n array2 = parseNumberArray(flatten(array2));\n\n if (anyIsError(array1, array2)) {\n return value\n }\n\n return jStat.covariance(array1, array2)\n};\n\n/**\n * Returns the sum of squares of deviations.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want to calculate the sum of squared deviations. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction DEVSQ() {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const mean = jStat.mean(range);\n\n let result = 0;\n\n for (let i = 0; i < range.length; i++) {\n result += Math.pow(range[i] - mean, 2);\n }\n\n return result\n}\n\nconst EXPON = {};\n\n/**\n * Returns the exponential distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value of the function.\n * @param {*} lambda The parameter value.\n * @param {*} cumulative A logical value that indicates which form of the exponential function to provide. If cumulative is TRUE, EXPON.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nEXPON.DIST = (x, lambda, cumulative) => {\n x = parseNumber(x);\n lambda = parseNumber(lambda);\n\n if (anyIsError(x, lambda)) {\n return value\n }\n\n return cumulative ? jStat.exponential.cdf(x, lambda) : jStat.exponential.pdf(x, lambda)\n};\n\nconst F = {};\n\n/**\n * Returns the F probability distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} deg_freedom1 The numerator degrees of freedom.\n * @param {*} deg_freedom2 The denominator degrees of freedom.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, F.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nF.DIST = (x, deg_freedom1, deg_freedom2, cumulative) => {\n x = parseNumber(x);\n deg_freedom1 = parseNumber(deg_freedom1);\n deg_freedom2 = parseNumber(deg_freedom2);\n\n if (anyIsError(x, deg_freedom1, deg_freedom2)) {\n return value\n }\n\n return cumulative\n ? jStat.centralF.cdf(x, deg_freedom1, deg_freedom2)\n : jStat.centralF.pdf(x, deg_freedom1, deg_freedom2)\n};\n\n/**\n * Returns the F probability distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} deg_freedom1 The numerator degrees of freedom.\n * @param {*} deg_freedom2 The denominator degrees of freedom.\n * @returns\n */\nF.DIST.RT = function (x, deg_freedom1, deg_freedom2) {\n if (arguments.length !== 3) {\n return na\n }\n\n if (x < 0 || deg_freedom1 < 1 || deg_freedom2 < 1) {\n return num\n }\n\n if (typeof x !== 'number' || typeof deg_freedom1 !== 'number' || typeof deg_freedom2 !== 'number') {\n return value\n }\n\n return 1 - jStat.centralF.cdf(x, deg_freedom1, deg_freedom2)\n};\n\n/**\n * Returns the inverse of the F probability distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability associated with the F cumulative distribution.\n * @param {*} deg_freedom1 The numerator degrees of freedom.\n * @param {*} deg_freedom2 The denominator degrees of freedom.\n * @returns\n */\nF.INV = (probability, deg_freedom1, deg_freedom2) => {\n probability = parseNumber(probability);\n deg_freedom1 = parseNumber(deg_freedom1);\n deg_freedom2 = parseNumber(deg_freedom2);\n\n if (anyIsError(probability, deg_freedom1, deg_freedom2)) {\n return value\n }\n\n if (probability <= 0.0 || probability > 1.0) {\n return num\n }\n\n return jStat.centralF.inv(probability, deg_freedom1, deg_freedom2)\n};\n\n/**\n * Returns the inverse of the F probability distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability associated with the F cumulative distribution.\n * @param {*} deg_freedom1 The numerator degrees of freedom.\n * @param {*} deg_freedom2 The denominator degrees of freedom.\n * @returns\n */\nF.INV.RT = function (probability, deg_freedom1, deg_freedom2) {\n if (arguments.length !== 3) {\n return na\n }\n\n if (\n probability < 0 ||\n probability > 1 ||\n deg_freedom1 < 1 ||\n deg_freedom1 > Math.pow(10, 10) ||\n deg_freedom2 < 1 ||\n deg_freedom2 > Math.pow(10, 10)\n ) {\n return num\n }\n\n if (typeof probability !== 'number' || typeof deg_freedom1 !== 'number' || typeof deg_freedom2 !== 'number') {\n return value\n }\n\n return jStat.centralF.inv(1.0 - probability, deg_freedom1, deg_freedom2)\n};\n\n/**\n * Returns the result of an F-test.\n *\n * Category: Statistical\n *\n * @param {*} array1 The first array or range of data.\n * @param {*} array2 The second array or range of data.\n * @returns\n */\nF.TEST = (array1, array2) => {\n if (!array1 || !array2) {\n return na\n }\n\n if (!(array1 instanceof Array) || !(array2 instanceof Array)) {\n return na\n }\n\n if (array1.length < 2 || array2.length < 2) {\n return div0\n }\n\n const sumOfSquares = (values, x1) => {\n let sum = 0;\n\n for (let i = 0; i < values.length; i++) {\n sum += Math.pow(values[i] - x1, 2);\n }\n\n return sum\n };\n\n const x1 = SUM(array1) / array1.length;\n const x2 = SUM(array2) / array2.length;\n const sum1 = sumOfSquares(array1, x1) / (array1.length - 1);\n const sum2 = sumOfSquares(array2, x2) / (array2.length - 1);\n\n return sum1 / sum2\n};\n\n/**\n * Returns the Fisher transformation.\n *\n * Category: Statistical\n *\n * @param {*} x A numeric value for which you want the transformation.\n * @returns\n */\nfunction FISHER(x) {\n x = parseNumber(x);\n\n if (x instanceof Error) {\n return x\n }\n\n return Math.log((1 + x) / (1 - x)) / 2\n}\n\n/**\n * Returns the inverse of the Fisher transformation.\n *\n * Category: Statistical\n *\n * @param {*} y The value for which you want to perform the inverse of the transformation.\n * @returns\n */\nfunction FISHERINV(y) {\n y = parseNumber(y);\n\n if (y instanceof Error) {\n return y\n }\n\n const e2y = Math.exp(2 * y);\n\n return (e2y - 1) / (e2y + 1)\n}\n\n/**\n * Returns a value along a linear trend.\n *\n * Category: Statistical\n *\n * @param {*} x The data point for which you want to predict a value.\n * @param {*} known_ys The dependent array or range of data.\n * @param {*} known_xs The independent array or range of data.\n * @returns\n */\nfunction FORECAST(x, known_ys, known_xs) {\n x = parseNumber(x);\n known_ys = parseNumberArray(flatten(known_ys));\n known_xs = parseNumberArray(flatten(known_xs));\n\n if (anyIsError(x, known_ys, known_xs)) {\n return value\n }\n\n const xmean = jStat.mean(known_xs);\n const ymean = jStat.mean(known_ys);\n\n const n = known_xs.length;\n\n let num = 0;\n let den = 0;\n\n for (let i = 0; i < n; i++) {\n num += (known_xs[i] - xmean) * (known_ys[i] - ymean);\n den += Math.pow(known_xs[i] - xmean, 2);\n }\n\n const b = num / den;\n const a = ymean - b * xmean;\n\n return a + b * x\n}\n\n/**\n * Returns a frequency distribution as a vertical array.\n *\n * Category: Statistical\n *\n * @param {*} data_array An array of or reference to a set of values for which you want to count frequencies. If data_array contains no values, FREQUENCY returns an array of zeros.\n * @param {*} bins_array An array of or reference to intervals into which you want to group the values in data_array. If bins_array contains no values, FREQUENCY returns the number of elements in data_array.\n * @returns\n */\nfunction FREQUENCY(data_array, bins_array) {\n data_array = parseNumberArray(flatten(data_array));\n bins_array = parseNumberArray(flatten(bins_array));\n\n if (anyIsError(data_array, bins_array)) {\n return value\n }\n\n const n = data_array.length;\n const b = bins_array.length;\n const r = [];\n\n for (let i = 0; i <= b; i++) {\n r[i] = 0;\n\n for (let j = 0; j < n; j++) {\n if (i === 0) {\n if (data_array[j] <= bins_array[0]) {\n r[0] += 1;\n }\n } else if (i < b) {\n if (data_array[j] > bins_array[i - 1] && data_array[j] <= bins_array[i]) {\n r[i] += 1;\n }\n } else if (i === b) {\n if (data_array[j] > bins_array[b - 1]) {\n r[b] += 1;\n }\n }\n }\n }\n\n return r\n}\n\n/**\n * Returns the Gamma function value.\n *\n * Category: Statistical\n *\n * @param {*} number Returns a number.\n * @returns\n */\nfunction GAMMA(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return num\n }\n\n if (parseInt(number, 10) === number && number < 0) {\n return num\n }\n\n return jStat.gammafn(number)\n}\n\n/**\n * Returns the gamma distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which you want to evaluate the distribution.\n * @param {*} alpha A parameter to the distribution.\n * @param {*} beta A parameter to the distribution. If beta = 1, GAMMA.DIST returns the standard gamma distribution.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, GAMMA.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nGAMMA.DIST = function (value$1, alpha, beta, cumulative) {\n if (arguments.length !== 4) {\n return na\n }\n\n if (value$1 < 0 || alpha <= 0 || beta <= 0) {\n return value\n }\n\n if (typeof value$1 !== 'number' || typeof alpha !== 'number' || typeof beta !== 'number') {\n return value\n }\n\n return cumulative ? jStat.gamma.cdf(value$1, alpha, beta, true) : jStat.gamma.pdf(value$1, alpha, beta, false)\n};\n\n/**\n * Returns the inverse of the gamma cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability The probability associated with the gamma distribution.\n * @param {*} alpha A parameter to the distribution.\n * @param {*} beta A parameter to the distribution. If beta = 1, GAMMA.INV returns the standard gamma distribution.\n * @returns\n */\nGAMMA.INV = function (probability, alpha, beta) {\n if (arguments.length !== 3) {\n return na\n }\n\n if (probability < 0 || probability > 1 || alpha <= 0 || beta <= 0) {\n return num\n }\n\n if (typeof probability !== 'number' || typeof alpha !== 'number' || typeof beta !== 'number') {\n return value\n }\n\n return jStat.gamma.inv(probability, alpha, beta)\n};\n\n/**\n * Returns the natural logarithm of the gamma function, Γ(x).\n *\n * Category: Statistical\n *\n * @param {*} x The value for which you want to calculate GAMMALN.\n * @returns\n */\nfunction GAMMALN(x) {\n x = parseNumber(x);\n\n if (x instanceof Error) {\n return x\n }\n\n return jStat.gammaln(x)\n}\n\n/**\n * Returns the natural logarithm of the gamma function, Γ(x).\n *\n * Category: Statistical\n *\n * @param {*} x The value for which you want to calculate GAMMALN.PRECISE.\n * @returns\n */\nGAMMALN.PRECISE = function (x) {\n if (arguments.length !== 1) {\n return na\n }\n\n if (x <= 0) {\n return num\n }\n\n if (typeof x !== 'number') {\n return value\n }\n\n return jStat.gammaln(x)\n};\n\n/**\n * Returns 0.5 less than the standard normal cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} z Returns a number.\n * @returns\n */\nfunction GAUSS(z) {\n z = parseNumber(z);\n\n if (z instanceof Error) {\n return z\n }\n\n return jStat.normal.cdf(z, 0, 1) - 0.5\n}\n\n/**\n * Returns the geometric mean.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want to calculate the mean. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction GEOMEAN() {\n const args = parseNumberArray(flatten(arguments));\n\n if (args instanceof Error) {\n return args\n }\n\n return jStat.geomean(args)\n}\n\n/**\n * Returns values along an exponential trend.\n *\n * Category: Statistical\n *\n * @param {*} known_y The set of y-values you already know in the relationship y = b*m^x.\n - If the array known_y's is in a single column, then each column of known_x's is interpreted as a separate variable.\n - If the array known_y's is in a single row, then each row of known_x's is interpreted as a separate variable.\n - If any of the numbers in known_y's is 0 or negative, GROWTH returns the #NUM! error value.\n * @param {*} known_x Optional. An optional set of x-values that you may already know in the relationship y = b*m^x.\n - The array known_x's can include one or more sets of variables. If only one variable is used, known_y's and known_x's can be ranges of any shape, as long as they have equal dimensions. If more than one variable is used, known_y's must be a vector (that is, a range with a height of one row or a width of one column).\n - If known_x's is omitted, it is assumed to be the array {1,2,3,...} that is the same size as known_y's.\n * @param {*} new_x Optional. Are new x-values for which you want GROWTH to return corresponding y-values.\n - new_x's must include a column (or row) for each independent variable, just as known_x's does. So, if known_y's is in a single column, known_x's and new_x's must have the same number of columns. If known_y's is in a single row, known_x's and new_x's must have the same number of rows.\n - If new_x's is omitted, it is assumed to be the same as known_x's.\n - If both known_x's and new_x's are omitted, they are assumed to be the array {1,2,3,...} that is the same size as known_y's.\n * @param {*} use_const Optional. A logical value specifying whether to force the constant b to equal 1. If const is TRUE or omitted, b is calculated normally. If const is FALSE, b is set equal to 1 and the m-values are adjusted so that y = m^x.\n - If const is TRUE or omitted, b is calculated normally.\n - If const is FALSE, b is set equal to 1 and the m-values are adjusted so that y = m^x.\n * @returns\n */\nfunction GROWTH(known_y, known_x, new_x, use_const) {\n // Credits: Ilmari Karonen (http://stackoverflow.com/questions/14161990/how-to-implement-growth-function-in-javascript)\n known_y = parseNumberArray(flatten(known_y));\n\n if (known_y instanceof Error) {\n return known_y\n }\n\n // Default values for optional parameters:\n let i;\n\n if (known_x === undefined) {\n known_x = [];\n\n for (i = 1; i <= known_y.length; i++) {\n known_x.push(i);\n }\n }\n\n if (new_x === undefined) {\n new_x = known_x;\n }\n\n known_x = parseNumberArray(flatten(known_x));\n new_x = parseNumberArray(flatten(new_x));\n\n if (anyIsError(known_x, new_x)) {\n return value\n }\n\n if (use_const === undefined) {\n use_const = true;\n }\n\n // Calculate sums over the data:\n const n = known_y.length;\n\n let avg_x = 0;\n let avg_y = 0;\n let avg_xy = 0;\n let avg_xx = 0;\n\n for (i = 0; i < n; i++) {\n const x = known_x[i];\n const y = Math.log(known_y[i]);\n\n avg_x += x;\n avg_y += y;\n avg_xy += x * y;\n avg_xx += x * x;\n }\n\n avg_x /= n;\n avg_y /= n;\n avg_xy /= n;\n avg_xx /= n;\n\n // Compute linear regression coefficients:\n let beta;\n let alpha;\n\n if (use_const) {\n beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x);\n alpha = avg_y - beta * avg_x;\n } else {\n beta = avg_xy / avg_xx;\n alpha = 0;\n }\n\n // Compute and return result array:\n const new_y = [];\n\n for (i = 0; i < new_x.length; i++) {\n new_y.push(Math.exp(alpha + beta * new_x[i]));\n }\n\n return new_y\n}\n\n/**\n * Returns the harmonic mean.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want to calculate the mean. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction HARMEAN() {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const n = range.length;\n\n let den = 0;\n\n for (let i = 0; i < n; i++) {\n den += 1 / range[i];\n }\n\n return n / den\n}\n\nconst HYPGEOM = {};\n\n/**\n * Returns the hypergeometric distribution.\n *\n * Category: Statistical\n *\n * @param {*} sample_s The number of successes in the sample.\n * @param {*} number_sample The size of the sample.\n * @param {*} population_s The number of successes in the population.\n * @param {*} number_pop The population size.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, then HYPGEOM.DIST returns the cumulative distribution function; if FALSE, it returns the probability mass function.\n * @returns\n */\nHYPGEOM.DIST = (sample_s, number_sample, population_s, number_pop, cumulative) => {\n sample_s = parseNumber(sample_s);\n number_sample = parseNumber(number_sample);\n population_s = parseNumber(population_s);\n number_pop = parseNumber(number_pop);\n\n if (anyIsError(sample_s, number_sample, population_s, number_pop)) {\n return value\n }\n\n function pdf(x, n, M, N) {\n return (COMBIN(M, x) * COMBIN(N - M, n - x)) / COMBIN(N, n)\n }\n\n function cdf(x, n, M, N) {\n let result = 0;\n\n for (let i = 0; i <= x; i++) {\n result += pdf(i, n, M, N);\n }\n\n return result\n }\n\n return cumulative\n ? cdf(sample_s, number_sample, population_s, number_pop)\n : pdf(sample_s, number_sample, population_s, number_pop)\n};\n\n/**\n * Returns the intercept of the linear regression line.\n *\n * Category: Statistical\n *\n * @param {*} known_y The dependent set of observations or data.\n * @param {*} known_x The independent set of observations or data.\n * @returns\n */\nfunction INTERCEPT(known_y, known_x) {\n known_y = parseNumberArray(known_y);\n known_x = parseNumberArray(known_x);\n\n if (anyIsError(known_y, known_x)) {\n return value\n }\n\n if (known_y.length !== known_x.length) {\n return na\n }\n\n return FORECAST(0, known_y, known_x)\n}\n\n/**\n * Returns the kurtosis of a data set.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want to calculate kurtosis. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction KURT() {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const mean = jStat.mean(range);\n const n = range.length;\n\n let sigma = 0;\n\n for (let i = 0; i < n; i++) {\n sigma += Math.pow(range[i] - mean, 4);\n }\n\n sigma = sigma / Math.pow(jStat.stdev(range, true), 4);\n\n return ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sigma - (3 * (n - 1) * (n - 1)) / ((n - 2) * (n - 3))\n}\n\n/**\n * Returns the k-th largest value in a data set.\n *\n * Category: Statistical\n *\n * @param {*} array The array or range of data for which you want to determine the k-th largest value.\n * @param {*} k The position (from the largest) in the array or value range of data to return.\n * @returns\n */\nfunction LARGE(array, k) {\n const someError = anyError.apply(undefined, array);\n\n if (someError) {\n return someError\n }\n\n if (anyIsError(k)) {\n return k\n }\n\n array = numbers(flatten(array));\n k = parseNumber(k);\n\n if (k < 0 || array.length < k) {\n return value\n }\n\n return array.sort((a, b) => b - a)[k - 1]\n}\n\n/**\n * Returns the parameters of a linear trend.\n *\n * Category: Statistical\n *\n * @param {*} known_y The set of y-values that you already know in the relationship y = mx + b.\n - If the range of known_y's is in a single column, each column of known_x's is interpreted as a separate variable.\n - If the range of known_y's is contained in a single row, each row of known_x's is interpreted as a separate variable.\n * @param {*} known_x Optional. A set of x-values that you may already know in the relationship y = mx + b.\n - The range of known_x's can include one or more sets of variables. If only one variable is used, known_y's and known_x's can be ranges of any shape, as long as they have equal dimensions. If more than one variable is used, known_y's must be a vector (that is, a range with a height of one row or a width of one column).\n - If known_x's is omitted, it is assumed to be the array {1,2,3,...} that is the same size as known_y's.\n * @returns\n */\nfunction LINEST(known_y, known_x) {\n known_y = parseNumberArray(flatten(known_y));\n known_x = parseNumberArray(flatten(known_x));\n\n if (anyIsError(known_y, known_x)) {\n return value\n }\n\n const ymean = jStat.mean(known_y);\n const xmean = jStat.mean(known_x);\n const n = known_x.length;\n\n let num = 0;\n let den = 0;\n\n for (let i = 0; i < n; i++) {\n num += (known_x[i] - xmean) * (known_y[i] - ymean);\n den += Math.pow(known_x[i] - xmean, 2);\n }\n\n const m = num / den;\n const b = ymean - m * xmean;\n\n return [m, b]\n}\n\n// According to Microsoft:\n// http://office.microsoft.com/en-us/starter-help/logest-function-HP010342665.aspx\n// LOGEST returns are based on the following linear model:\n// ln y = x1 ln m1 + ... + xn ln mn + ln b\n/**\n * Returns the parameters of an exponential trend.\n *\n * Category: Statistical\n *\n * @param {*} known_y The set of y-values you already know in the relationship y = b*m^x.\n - If the array known_y's is in a single column, then each column of known_x's is interpreted as a separate variable.\n - If the array known_y's is in a single row, then each row of known_x's is interpreted as a separate variable.\n * @param {*} known_x Optional. An optional set of x-values that you may already know in the relationship y = b*m^x.\n - The array known_x's can include one or more sets of variables. If only one variable is used, known_y's and known_x's can be ranges of any shape, as long as they have equal dimensions. If more than one variable is used, known_y's must be a range of values with a height of one row or a width of one column (which is also known as a vector).\n - If known_x's is omitted, it is assumed to be the array {1,2,3,...} that is the same size as known_y's.\n * @returns\n */\nfunction LOGEST(known_y, known_x) {\n known_y = parseNumberArray(flatten(known_y));\n known_x = parseNumberArray(flatten(known_x));\n\n if (anyIsError(known_y, known_x)) {\n return value\n }\n\n if (known_y.length !== known_x.length) {\n return value\n }\n\n for (let i = 0; i < known_y.length; i++) {\n known_y[i] = Math.log(known_y[i]);\n }\n\n const result = LINEST(known_y, known_x);\n\n result[0] = Math.round(Math.exp(result[0]) * 1000000) / 1000000;\n result[1] = Math.round(Math.exp(result[1]) * 1000000) / 1000000;\n\n return result\n}\n\nconst LOGNORM = {};\n\n/**\n * Returns the cumulative lognormal distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} mean The mean of ln(x).\n * @param {*} standard_dev The standard deviation of ln(x).\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, LOGNORM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nLOGNORM.DIST = (x, mean, standard_dev, cumulative) => {\n x = parseNumber(x);\n mean = parseNumber(mean);\n standard_dev = parseNumber(standard_dev);\n\n if (anyIsError(x, mean, standard_dev)) {\n return value\n }\n\n return cumulative ? jStat.lognormal.cdf(x, mean, standard_dev) : jStat.lognormal.pdf(x, mean, standard_dev)\n};\n\n/**\n * Returns the inverse of the lognormal cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability associated with the lognormal distribution.\n * @param {*} mean The mean of ln(x).\n * @param {*} standard_dev The standard deviation of ln(x).\n * @returns\n */\nLOGNORM.INV = (probability, mean, standard_dev) => {\n probability = parseNumber(probability);\n mean = parseNumber(mean);\n standard_dev = parseNumber(standard_dev);\n\n if (anyIsError(probability, mean, standard_dev)) {\n return value\n }\n\n return jStat.lognormal.inv(probability, mean, standard_dev)\n};\n\n/**\n * Returns the maximum value in a list of arguments.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 numbers for which you want to find the maximum value.\n * @returns\n */\nfunction MAX() {\n const flatArguments = flatten(arguments);\n const someError = anyError.apply(undefined, flatArguments);\n\n if (someError) {\n return someError\n }\n\n const range = numbers(flatArguments);\n\n return range.length === 0 ? 0 : Math.max.apply(Math, range)\n}\n\n/**\n * Returns the maximum value in a list of arguments, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2,... Number arguments 2 to 255 for which you want to find the largest value.\n * @returns\n */\nfunction MAXA() {\n const flatArguments = flatten(arguments);\n const someError = anyError.apply(undefined, flatArguments);\n\n if (someError) {\n return someError\n }\n\n let range = arrayValuesToNumbers(flatArguments);\n\n range = range.map((value) => (value === undefined || value === null ? 0 : value));\n\n return range.length === 0 ? 0 : Math.max.apply(Math, range)\n}\n\n/**\n * Returns the maximum of all values in a range that meet multiple criteria.\n *\n * Category: Statistical\n *\n * @returns\n */\nfunction MAXIFS() {\n const values = applyCriteria(...arguments);\n\n return values.length === 0 ? 0 : Math.max.apply(Math, values)\n}\n\n/**\n * Returns the median of the given numbers.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 numbers for which you want the median.\n * @returns\n */\nfunction MEDIAN() {\n const flatArguments = flatten(arguments);\n const someError = anyError.apply(undefined, flatArguments);\n\n if (someError) {\n return someError\n }\n\n const range = arrayValuesToNumbers(flatArguments);\n\n let result = jStat.median(range);\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the minimum value in a list of arguments.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is optional, subsequent numbers are optional. 1 to 255 numbers for which you want to find the minimum value.\n * @returns\n */\nfunction MIN() {\n const flatArguments = flatten(arguments);\n const someError = anyError.apply(undefined, flatArguments);\n\n if (someError) {\n return someError\n }\n\n const range = numbers(flatArguments);\n\n return range.length === 0 ? 0 : Math.min.apply(Math, range)\n}\n\n/**\n * Returns the smallest value in a list of arguments, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 255 values for which you want to find the smallest value.\n * @returns\n */\nfunction MINA() {\n const flatArguments = flatten(arguments);\n const someError = anyError.apply(undefined, flatArguments);\n\n if (someError) {\n return someError\n }\n\n let range = arrayValuesToNumbers(flatArguments);\n\n range = range.map((value) => (value === undefined || value === null ? 0 : value));\n\n return range.length === 0 ? 0 : Math.min.apply(Math, range)\n}\n\n/**\n * Returns the minimum of all values in a range that meet multiple criteria.\n *\n * Category: Statistical\n *\n * @returns\n */\nfunction MINIFS() {\n const values = applyCriteria(...arguments);\n\n return values.length === 0 ? 0 : Math.min.apply(Math, values)\n}\n\nconst MODE = {};\n\n/**\n * Returns a vertical array of the most frequently occurring, or repetitive values in an array or range of data.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number arguments 2 to 254 for which you want to calculate the mode. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nMODE.MULT = function () {\n // Credits: Roönaän\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const n = range.length;\n const count = {};\n\n let maxItems = [];\n let max = 0;\n let currentItem;\n\n for (let i = 0; i < n; i++) {\n currentItem = range[i];\n count[currentItem] = count[currentItem] ? count[currentItem] + 1 : 1;\n\n if (count[currentItem] > max) {\n max = count[currentItem];\n maxItems = [];\n }\n\n if (count[currentItem] === max) {\n maxItems[maxItems.length] = currentItem;\n }\n }\n\n return maxItems\n};\n\n/**\n * Returns the most common value in a data set.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Arguments 2 to 254 for which you want to calculate the mode. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nMODE.SNGL = function () {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n return MODE.MULT(range).sort((a, b) => a - b)[0]\n};\n\nconst NEGBINOM = {};\n\n/**\n * Returns the negative binomial distribution.\n *\n * Category: Statistical\n *\n * @param {*} number_f The number of failures.\n * @param {*} number_s The threshold number of successes.\n * @param {*} probability_s The probability of a success.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, NEGBINOM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nNEGBINOM.DIST = (number_f, number_s, probability_s, cumulative) => {\n number_f = parseNumber(number_f);\n number_s = parseNumber(number_s);\n probability_s = parseNumber(probability_s);\n\n if (anyIsError(number_f, number_s, probability_s)) {\n return value\n }\n\n return cumulative\n ? jStat.negbin.cdf(number_f, number_s, probability_s)\n : jStat.negbin.pdf(number_f, number_s, probability_s)\n};\n\nconst NORM = {};\n\n/**\n * Returns the normal cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value for which you want the distribution.\n * @param {*} mean The arithmetic mean of the distribution.\n * @param {*} standard_dev The standard deviation of the distribution.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, NORM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nNORM.DIST = (x, mean, standard_dev, cumulative) => {\n x = parseNumber(x);\n mean = parseNumber(mean);\n standard_dev = parseNumber(standard_dev);\n\n if (anyIsError(x, mean, standard_dev)) {\n return value\n }\n\n if (standard_dev <= 0) {\n return num\n }\n\n // Return normal distribution computed by jStat [http://jstat.org]\n return cumulative ? jStat.normal.cdf(x, mean, standard_dev) : jStat.normal.pdf(x, mean, standard_dev)\n};\n\n/**\n * Returns the inverse of the normal cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability corresponding to the normal distribution.\n * @param {*} mean The arithmetic mean of the distribution.\n * @param {*} standard_dev The standard deviation of the distribution.\n * @returns\n */\nNORM.INV = (probability, mean, standard_dev) => {\n probability = parseNumber(probability);\n mean = parseNumber(mean);\n standard_dev = parseNumber(standard_dev);\n\n if (anyIsError(probability, mean, standard_dev)) {\n return value\n }\n\n return jStat.normal.inv(probability, mean, standard_dev)\n};\n\nNORM.S = {};\n\n/**\n * Returns the standard normal cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} z The value for which you want the distribution.\n * @param {*} cumulative Cumulative is a logical value that determines the form of the function. If cumulative is TRUE, NORMS.DIST returns the cumulative distribution function; if FALSE, it returns the probability mass function.\n * @returns\n */\nNORM.S.DIST = (z, cumulative) => {\n z = parseNumber(z);\n\n if (z instanceof Error) {\n return value\n }\n\n return cumulative ? jStat.normal.cdf(z, 0, 1) : jStat.normal.pdf(z, 0, 1)\n};\n\n/**\n * Returns the inverse of the standard normal cumulative distribution.\n *\n * Category: Statistical\n *\n * @param {*} probability A probability corresponding to the normal distribution.\n * @returns\n */\nNORM.S.INV = (probability) => {\n probability = parseNumber(probability);\n\n if (probability instanceof Error) {\n return value\n }\n\n return jStat.normal.inv(probability, 0, 1)\n};\n\n/**\n * Returns the Pearson product moment correlation coefficient.\n *\n * Category: Statistical\n *\n * @param {*} array1 A set of independent values.\n * @param {*} array2 A set of dependent values.\n * @returns\n */\nfunction PEARSON(array1, array2) {\n array2 = parseNumberArray(flatten(array2));\n array1 = parseNumberArray(flatten(array1));\n\n if (anyIsError(array2, array1)) {\n return value\n }\n\n const xmean = jStat.mean(array1);\n const ymean = jStat.mean(array2);\n const n = array1.length;\n\n let num = 0;\n let den1 = 0;\n let den2 = 0;\n\n for (let i = 0; i < n; i++) {\n num += (array1[i] - xmean) * (array2[i] - ymean);\n den1 += Math.pow(array1[i] - xmean, 2);\n den2 += Math.pow(array2[i] - ymean, 2);\n }\n\n return num / Math.sqrt(den1 * den2)\n}\n\nconst PERCENTILE = {};\n\n/**\n * Returns the k-th percentile of values in a range, where k is in the range 0..1, exclusive.\n *\n * Category: Statistical\n *\n * @returns\n */\nPERCENTILE.EXC = (array, k) => {\n array = parseNumberArray(flatten(array));\n k = parseNumber(k);\n\n if (anyIsError(array, k)) {\n return value\n }\n\n array = array.sort((a, b) => a - b);\n\n const n = array.length;\n\n if (k < 1 / (n + 1) || k > 1 - 1 / (n + 1)) {\n return num\n }\n\n const l = k * (n + 1) - 1;\n const fl = Math.floor(l);\n\n return cleanFloat(l === fl ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl]))\n};\n\n/**\n * Returns the k-th percentile of values in a range.\n *\n * Category: Statistical\n *\n * @param {*} array The array or range of data that defines relative standing.\n * @param {*} k The percentile value in the range 0..1, inclusive.\n * @returns\n */\nPERCENTILE.INC = (array, k) => {\n array = parseNumberArray(flatten(array));\n k = parseNumber(k);\n\n if (anyIsError(array, k)) {\n return value\n }\n\n array = array.sort((a, b) => a - b);\n\n const n = array.length;\n const l = k * (n - 1);\n const fl = Math.floor(l);\n\n return cleanFloat(l === fl ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl]))\n};\n\nconst PERCENTRANK = {};\n\n/**\n * Returns the rank of a value in a data set as a percentage (0..1, exclusive) of the data set.\n *\n * Category: Statistical\n *\n * @param {*} array The array or range of data with numeric values that defines relative standing\n * @param {*} x The value for which you want to know the rank.\n * @param {*} significance Optional. A value that identifies the number of significant digits for the returned percentage value. If omitted, PERCENTRANK.EXC uses three digits (0.xxx).\n * @returns\n */\nPERCENTRANK.EXC = (array, x, significance) => {\n significance = significance === undefined ? 3 : significance;\n array = parseNumberArray(flatten(array));\n x = parseNumber(x);\n significance = parseNumber(significance);\n\n if (anyIsError(array, x, significance)) {\n return value\n }\n\n array = array.sort((a, b) => a - b);\n\n const uniques = UNIQUE.apply(null, array);\n const n = array.length;\n const m = uniques.length;\n const power = Math.pow(10, significance);\n\n let result = 0;\n let match = false;\n let i = 0;\n\n while (!match && i < m) {\n if (x === uniques[i]) {\n result = (array.indexOf(uniques[i]) + 1) / (n + 1);\n match = true;\n } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) {\n result = (array.indexOf(uniques[i]) + 1 + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n + 1);\n match = true;\n }\n\n i++;\n }\n\n return Math.floor(result * power) / power\n};\n\n/**\n * Returns the percentage rank of a value in a data set.\n *\n * Category: Statistical\n *\n * @param {*} array The array or range of data with numeric values that defines relative standing.\n * @param {*} x The value for which you want to know the rank.\n * @param {*} significance Optional. A value that identifies the number of significant digits for the returned percentage value. If omitted, PERCENTRANK.INC uses three digits (0.xxx).\n * @returns\n */\nPERCENTRANK.INC = (array, x, significance) => {\n significance = significance === undefined ? 3 : significance;\n array = parseNumberArray(flatten(array));\n x = parseNumber(x);\n significance = parseNumber(significance);\n\n if (anyIsError(array, x, significance)) {\n return value\n }\n\n array = array.sort((a, b) => a - b);\n\n const uniques = UNIQUE.apply(null, array);\n const n = array.length;\n const m = uniques.length;\n const power = Math.pow(10, significance);\n\n let result = 0;\n let match = false;\n let i = 0;\n\n while (!match && i < m) {\n if (x === uniques[i]) {\n result = array.indexOf(uniques[i]) / (n - 1);\n match = true;\n } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) {\n result = (array.indexOf(uniques[i]) + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n - 1);\n match = true;\n }\n\n i++;\n }\n\n return Math.floor(result * power) / power\n};\n\n/**\n * Returns the number of permutations for a given number of objects.\n *\n * Category: Statistical\n *\n * @param {*} number An integer that describes the number of objects.\n * @param {*} number_chosen An integer that describes the number of objects in each permutation.\n * @returns\n */\nfunction PERMUT(number, number_chosen) {\n number = parseNumber(number);\n number_chosen = parseNumber(number_chosen);\n\n if (anyIsError(number, number_chosen)) {\n return value\n }\n\n return FACT(number) / FACT(number - number_chosen)\n}\n\n/**\n * Returns the number of permutations for a given number of objects (with repetitions) that can be selected from the total objects.\n *\n * Category: Statistical\n *\n * @param {*} number An integer that describes the total number of objects.\n * @param {*} number_chosen An integer that describes the number of objects in each permutation.\n * @returns\n */\nfunction PERMUTATIONA(number, number_chosen) {\n number = parseNumber(number);\n number_chosen = parseNumber(number_chosen);\n\n if (anyIsError(number, number_chosen)) {\n return value\n }\n\n return Math.pow(number, number_chosen)\n}\n\n/**\n * Returns the value of the density function for a standard normal distribution.\n *\n * Category: Statistical\n *\n * @param {*} x X is the number for which you want the density of the standard normal distribution.\n * @returns\n */\nfunction PHI(x) {\n x = parseNumber(x);\n\n if (x instanceof Error) {\n return value\n }\n\n return Math.exp(-0.5 * x * x) / SQRT2PI\n}\n\nconst POISSON = {};\n\n/**\n * Returns the Poisson distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The number of events.\n * @param {*} mean The expected numeric value.\n * @param {*} cumulative A logical value that determines the form of the probability distribution returned. If cumulative is TRUE, POISSON.DIST returns the cumulative Poisson probability that the number of random events occurring will be between zero and x inclusive; if FALSE, it returns the Poisson probability mass function that the number of events occurring will be exactly x.\n * @returns\n */\nPOISSON.DIST = (x, mean, cumulative) => {\n x = parseNumber(x);\n mean = parseNumber(mean);\n\n if (anyIsError(x, mean)) {\n return value\n }\n\n return cumulative ? jStat.poisson.cdf(x, mean) : jStat.poisson.pdf(x, mean)\n};\n\n/**\n * Returns the probability that values in a range are between two limits.\n *\n * Category: Statistical\n *\n * @param {*} x_range The range of numeric values of x with which there are associated probabilities.\n * @param {*} prob_range A set of probabilities associated with values in x_range.\n * @param {*} lower_limit Optional. The lower bound on the value for which you want a probability.\n * @param {*} upper_limit Optional. The optional upper bound on the value for which you want a probability.\n * @returns\n */\nfunction PROB(x_range, prob_range, lower_limit, upper_limit) {\n if (lower_limit === undefined) {\n return 0\n }\n\n upper_limit = upper_limit === undefined ? lower_limit : upper_limit;\n\n x_range = parseNumberArray(flatten(x_range));\n prob_range = parseNumberArray(flatten(prob_range));\n lower_limit = parseNumber(lower_limit);\n upper_limit = parseNumber(upper_limit);\n\n if (anyIsError(x_range, prob_range, lower_limit, upper_limit)) {\n return value\n }\n\n if (lower_limit === upper_limit) {\n return x_range.indexOf(lower_limit) >= 0 ? prob_range[x_range.indexOf(lower_limit)] : 0\n }\n\n const sorted = x_range.sort((a, b) => a - b);\n const n = sorted.length;\n\n let result = 0;\n\n for (let i = 0; i < n; i++) {\n if (sorted[i] >= lower_limit && sorted[i] <= upper_limit) {\n result += prob_range[x_range.indexOf(sorted[i])];\n }\n }\n\n return result\n}\n\nconst QUARTILE = {};\n\n/**\n * Returns the quartile of the data set, based on percentile values from 0..1, exclusive.\n *\n * Category: Statistical\n *\n * @param {*} array The array or value range of numeric values for which you want the quartile value.\n * @param {*} quart Indicates which value to return.\n * @returns\n */\nQUARTILE.EXC = (range, quart) => {\n range = parseNumberArray(numbers(flatten(range)));\n quart = parseNumber(quart);\n\n if (anyIsError(range, quart)) {\n return value\n }\n\n switch (quart) {\n case 1:\n return PERCENTILE.EXC(range, 0.25)\n case 2:\n return PERCENTILE.EXC(range, 0.5)\n case 3:\n return PERCENTILE.EXC(range, 0.75)\n default:\n return num\n }\n};\n\n/**\n * Returns the quartile of a data set.\n *\n * Category: Statistical\n *\n * @param {*} array The array or value range of numeric values for which you want the quartile value.\n * @param {*} quart Indicates which value to return.\n * @returns\n */\nQUARTILE.INC = (range, quart) => {\n range = parseNumberArray(numbers(flatten(range)));\n quart = parseNumber(quart);\n\n if (anyIsError(range, quart)) {\n return value\n }\n\n switch (quart) {\n case 1:\n return PERCENTILE.INC(range, 0.25)\n case 2:\n return PERCENTILE.INC(range, 0.5)\n case 3:\n return PERCENTILE.INC(range, 0.75)\n default:\n return num\n }\n};\n\nconst RANK = {};\n\n/**\n * Returns the rank of a number in a list of numbers.\n *\n * Category: Statistical\n *\n * @param {*} number The number whose rank you want to find.\n * @param {*} ref An array of, or a reference to, a list of numbers. Nonnumeric values in Ref are ignored.\n * @param {*} order Optional. A number specifying how to rank number.\n * @returns\n */\nRANK.AVG = (number, ref, order) => {\n number = parseNumber(number);\n ref = parseNumberArray(flatten(ref));\n\n if (anyIsError(number, ref)) {\n return value\n }\n\n ref = flatten(ref);\n order = order || false;\n\n const sort = order ? (a, b) => a - b : (a, b) => b - a;\n\n ref = ref.sort(sort);\n\n const length = ref.length;\n\n let count = 0;\n\n for (let i = 0; i < length; i++) {\n if (ref[i] === number) {\n count++;\n }\n }\n\n return count > 1 ? (2 * ref.indexOf(number) + count + 1) / 2 : ref.indexOf(number) + 1\n};\n\n/**\n * Returns the rank of a number in a list of numbers.\n *\n * Category: Statistical\n *\n * @param {*} number The number whose rank you want to find.\n * @param {*} ref An array of, or a reference to, a list of numbers. Non-numeric values in Ref are ignored.\n * @param {*} order Optional. A number specifying how to rank number.\n * @returns\n */\nRANK.EQ = (number, ref, order) => {\n number = parseNumber(number);\n ref = parseNumberArray(flatten(ref));\n\n if (anyIsError(number, ref)) {\n return value\n }\n\n order = order || false;\n\n const sort = order ? (a, b) => a - b : (a, b) => b - a;\n\n ref = ref.sort(sort);\n\n return ref.indexOf(number) + 1\n};\n\n/**\n * Returns the row number of a reference.\n *\n * Category: Lookup and reference\n *\n * @param {*} reference the value or range of values for which you want the row number.\n * @param {*} index\n * @returns\n */\nfunction ROW(reference, index) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (index < 0) {\n return num\n }\n\n if (!(reference instanceof Array) || typeof index !== 'number') {\n return value\n }\n\n if (reference.length === 0) {\n return undefined\n }\n\n return jStat.row(reference, index)\n}\n\n/**\n * Returns the square of the Pearson product moment correlation coefficient.\n *\n * Category: Statistical\n *\n * @param {*} known_y An array or range of data points.\n * @param {*} known_x An array or range of data points.\n * @returns\n */\nfunction RSQ(known_y, known_x) {\n // no need to flatten here, PEARSON will take care of that\n known_y = parseNumberArray(flatten(known_y));\n known_x = parseNumberArray(flatten(known_x));\n\n if (anyIsError(known_y, known_x)) {\n return value\n }\n\n return Math.pow(PEARSON(known_y, known_x), 2)\n}\n\n/**\n * Returns the skewness of a distribution.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want to calculate skewness. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction SKEW() {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const mean = jStat.mean(range);\n const n = range.length;\n\n let sigma = 0;\n\n for (let i = 0; i < n; i++) {\n sigma += Math.pow(range[i] - mean, 3);\n }\n\n return (n * sigma) / ((n - 1) * (n - 2) * Math.pow(jStat.stdev(range, true), 3))\n}\n\n/**\n * Returns the skewness of a distribution based on a population.\n *\n * Category: Statistical\n *\n * @returns\n */\nSKEW.P = function () {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const mean = jStat.mean(range);\n const n = range.length;\n\n let m2 = 0;\n let m3 = 0;\n\n for (let i = 0; i < n; i++) {\n m3 += Math.pow(range[i] - mean, 3);\n m2 += Math.pow(range[i] - mean, 2);\n }\n\n m3 = m3 / n;\n m2 = m2 / n;\n\n return m3 / Math.pow(m2, 3 / 2)\n};\n\n/**\n * Returns the slope of the linear regression line.\n *\n * Category: Statistical\n *\n * @param {*} known_y An array or value range of numeric dependent data points.\n * @param {*} known_x The set of independent data points.\n * @returns\n */\nfunction SLOPE(known_y, known_x) {\n known_y = parseNumberArray(flatten(known_y));\n known_x = parseNumberArray(flatten(known_x));\n\n if (anyIsError(known_y, known_x)) {\n return value\n }\n\n const xmean = jStat.mean(known_x);\n const ymean = jStat.mean(known_y);\n const n = known_x.length;\n\n let num = 0;\n let den = 0;\n\n for (let i = 0; i < n; i++) {\n num += (known_x[i] - xmean) * (known_y[i] - ymean);\n den += Math.pow(known_x[i] - xmean, 2);\n }\n\n return num / den\n}\n\n/**\n * Returns the k-th smallest value in a data set.\n *\n * Category: Statistical\n *\n * @param {*} array An array or range of numerical data for which you want to determine the k-th smallest value.\n * @param {*} k The position (from the smallest) in the array or range of data to return.\n * @returns\n */\nfunction SMALL(array, k) {\n array = parseNumberArray(flatten(array));\n k = parseNumber(k);\n\n if (anyIsError(array, k)) {\n return array\n }\n\n return array.sort((a, b) => a - b)[k - 1]\n}\n\n/**\n * Returns a normalized value.\n *\n * Category: Statistical\n *\n * @param {*} x The value you want to normalize.\n * @param {*} mean The arithmetic mean of the distribution.\n * @param {*} standard_dev The standard deviation of the distribution.\n * @returns\n */\nfunction STANDARDIZE(x, mean, standard_dev) {\n x = parseNumber(x);\n mean = parseNumber(mean);\n standard_dev = parseNumber(standard_dev);\n\n if (anyIsError(x, mean, standard_dev)) {\n return value\n }\n\n return (x - mean) / standard_dev\n}\n\nconst STDEV = {};\n\n/**\n * Calculates standard deviation based on the entire population.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number arguments 2 to 254 corresponding to a population. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nSTDEV.P = function () {\n const v = VAR.P.apply(this, arguments);\n\n let result = Math.sqrt(v);\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n};\n\n/**\n * Estimates standard deviation based on a sample.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number arguments 2 to 254 corresponding to a sample of a population. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nSTDEV.S = function () {\n const v = VAR.S.apply(this, arguments);\n const result = Math.sqrt(v);\n\n return result\n};\n\n/**\n * Estimates standard deviation based on a sample, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 255 values corresponding to a sample of a population. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction STDEVA() {\n const v = VARA.apply(this, arguments);\n const result = Math.sqrt(v);\n\n return result\n}\n\n/**\n * Calculates standard deviation based on the entire population, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 255 values corresponding to a population. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction STDEVPA() {\n const v = VARPA.apply(this, arguments);\n\n let result = Math.sqrt(v);\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the standard error of the predicted y-value for each x in the regression.\n *\n * Category: Statistical\n *\n * @param {*} known_y An array or range of dependent data points.\n * @param {*} known_x An array or range of independent data points.\n * @returns\n */\nfunction STEYX(known_y, known_x) {\n known_y = parseNumberArray(flatten(known_y));\n known_x = parseNumberArray(flatten(known_x));\n\n if (anyIsError(known_y, known_x)) {\n return value\n }\n\n const xmean = jStat.mean(known_x);\n const ymean = jStat.mean(known_y);\n const n = known_x.length;\n\n let lft = 0;\n let num = 0;\n let den = 0;\n\n for (let i = 0; i < n; i++) {\n lft += Math.pow(known_y[i] - ymean, 2);\n num += (known_x[i] - xmean) * (known_y[i] - ymean);\n den += Math.pow(known_x[i] - xmean, 2);\n }\n\n return Math.sqrt((lft - (num * num) / den) / (n - 2))\n}\n\n/**\n * Returns the Percentage Points (probability) for the Student t-distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The numeric value at which to evaluate the distribution\n * @param {*} deg_freedom An integer indicating the number of degrees of freedom.\n * @param {*} cumulative A logical value that determines the form of the function. If cumulative is TRUE, T.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\n * @returns\n */\nT.DIST = (x, deg_freedom, cumulative) => {\n if (cumulative !== 1 && cumulative !== 2) {\n return num\n }\n\n return cumulative === 1 ? T.DIST.RT(x, deg_freedom) : T.DIST['2T'](x, deg_freedom)\n};\n\n/**\n * Returns the Percentage Points (probability) for the Student t-distribution\n *\n * Category: Statistical\n *\n * @param {*} x The numeric value at which to evaluate the distribution.\n * @param {*} deg_freedom An integer indicating the number of degrees of freedom.\n * @returns\n */\nT.DIST['2T'] = function (x, deg_freedom) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (x < 0 || deg_freedom < 1) {\n return num\n }\n\n if (typeof x !== 'number' || typeof deg_freedom !== 'number') {\n return value\n }\n\n return (1 - jStat.studentt.cdf(x, deg_freedom)) * 2\n};\n\n/**\n * Returns the Student's t-distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The numeric value at which to evaluate the distribution.\n * @param {*} deg_freedom An integer indicating the number of degrees of freedom.\n * @returns\n */\nT.DIST.RT = function (x, deg_freedom) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (x < 0 || deg_freedom < 1) {\n return num\n }\n\n if (typeof x !== 'number' || typeof deg_freedom !== 'number') {\n return value\n }\n\n return 1 - jStat.studentt.cdf(x, deg_freedom)\n};\n\n/**\n * Returns the t-value of the Student's t-distribution as a function of the probability and the degrees of freedom.\n *\n * Category: Statistical\n *\n * @param {*} probability The probability associated with the Student's t-distribution.\n * @param {*} deg_freedom The number of degrees of freedom with which to characterize the distribution.\n * @returns\n */\nT.INV = (probability, deg_freedom) => {\n probability = parseNumber(probability);\n deg_freedom = parseNumber(deg_freedom);\n\n if (anyIsError(probability, deg_freedom)) {\n return value\n }\n\n return jStat.studentt.inv(probability, deg_freedom)\n};\n\n/**\n * Returns the inverse of the Student's t-distribution\n *\n * Category: Statistical\n *\n * @param {*} probability The probability associated with the Student's t-distribution.\n * @param {*} deg_freedom The number of degrees of freedom with which to characterize the distribution.\n * @returns\n */\nT.INV['2T'] = (probability, deg_freedom) => {\n probability = parseNumber(probability);\n deg_freedom = parseNumber(deg_freedom);\n\n if (probability <= 0 || probability > 1 || deg_freedom < 1) {\n return num\n }\n\n if (anyIsError(probability, deg_freedom)) {\n return value\n }\n\n return Math.abs(jStat.studentt.inv(probability / 2, deg_freedom))\n};\n\n// The algorithm can be found here:\n// http://www.chem.uoa.gr/applets/AppletTtest/Appl_Ttest2.html\n/**\n * Returns the probability associated with a Student's t-test.\n *\n * Category: Statistical\n *\n * @param {*} array1 The first data set.\n * @param {*} array2 The second data set.\n * @returns\n */\nT.TEST = (array1, array2) => {\n array1 = parseNumberArray(flatten(array1));\n array2 = parseNumberArray(flatten(array2));\n\n if (anyIsError(array1, array2)) {\n return value\n }\n\n const mean_x = jStat.mean(array1);\n const mean_y = jStat.mean(array2);\n\n let s_x = 0;\n let s_y = 0;\n let i;\n\n for (i = 0; i < array1.length; i++) {\n s_x += Math.pow(array1[i] - mean_x, 2);\n }\n\n for (i = 0; i < array2.length; i++) {\n s_y += Math.pow(array2[i] - mean_y, 2);\n }\n\n s_x = s_x / (array1.length - 1);\n s_y = s_y / (array2.length - 1);\n\n const t = Math.abs(mean_x - mean_y) / Math.sqrt(s_x / array1.length + s_y / array2.length);\n\n return T.DIST['2T'](t, array1.length + array2.length - 2)\n};\n\n/**\n * Returns values along a linear trend.\n *\n * Category: Statistical\n *\n * @param {*} known_ys The set of y-values you already know in the relationship y = mx + b\n * @param {*} known_xs An optional set of x-values that you may already know in the relationship y = mx + b\n * @param {*} new_xs Optional. New x-values for which you want TREND to return corresponding y-values.\n * @returns\n */\nfunction TREND(known_ys, known_xs, new_xs) {\n known_ys = parseNumberArray(flatten(known_ys));\n known_xs = parseNumberArray(flatten(known_xs));\n new_xs = parseNumberArray(flatten(new_xs));\n\n if (anyIsError(known_ys, known_xs, new_xs)) {\n return value\n }\n\n const linest = LINEST(known_ys, known_xs);\n const m = linest[0];\n const b = linest[1];\n const result = [];\n\n new_xs.forEach((x) => {\n result.push(m * x + b);\n });\n\n return result\n}\n\n/**\n * Returns the mean of the interior of a data set.\n *\n * Category: Statistical\n *\n * @param {*} array The array or range of values to trim and average.\n * @param {*} percent The fractional number of data points to exclude from the calculation. For example, if percent = 0.2, 4 points are trimmed from a data set of 20 points (20 x 0.2): 2 from the top and 2 from the bottom of the set.\n * @returns\n */\nfunction TRIMMEAN(range, percent) {\n range = parseNumberArray(flatten(range));\n percent = parseNumber(percent);\n\n if (anyIsError(range, percent)) {\n return value\n }\n\n const trim = FLOOR(range.length * percent, 2) / 2;\n\n return jStat.mean(\n initial(\n rest(\n range.sort((a, b) => a - b),\n trim\n ),\n trim\n )\n )\n}\n\nconst VAR = {};\n\n/**\n * Calculates variance based on the entire population.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number arguments 2 to 254 corresponding to a population.\n * @returns\n */\nVAR.P = function () {\n const range = numbers(flatten(arguments));\n const n = range.length;\n\n let sigma = 0;\n\n const mean = AVERAGE(range);\n\n let result;\n\n for (let i = 0; i < n; i++) {\n sigma += Math.pow(range[i] - mean, 2);\n }\n\n result = sigma / n;\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n};\n\n/**\n * Estimates variance based on a sample.\n *\n * Category: Statistical\n *\n * @param {*} args number1, number2, ... Number arguments 2 to 254 corresponding to a sample of a population.\n * @returns\n */\nVAR.S = function () {\n const range = numbers(flatten(arguments));\n const n = range.length;\n\n let sigma = 0;\n\n const mean = AVERAGE(range);\n\n for (let i = 0; i < n; i++) {\n sigma += Math.pow(range[i] - mean, 2);\n }\n\n return sigma / (n - 1)\n};\n\n/**\n * Estimates variance based on a sample, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 255 value arguments corresponding to a sample of a population.\n * @returns\n */\nfunction VARA() {\n const range = flatten(arguments);\n const n = range.length;\n\n let sigma = 0;\n let count = 0;\n\n const mean = AVERAGEA(range);\n\n for (let i = 0; i < n; i++) {\n const el = range[i];\n\n if (typeof el === 'number') {\n sigma += Math.pow(el - mean, 2);\n } else if (el === true) {\n sigma += Math.pow(1 - mean, 2);\n } else {\n sigma += Math.pow(0 - mean, 2);\n }\n\n if (el !== null) {\n count++;\n }\n }\n\n return sigma / (count - 1)\n}\n\n/**\n * Calculates variance based on the entire population, including numbers, text, and logical values.\n *\n * Category: Statistical\n *\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 255 value arguments corresponding to a population.\n * @returns\n */\nfunction VARPA() {\n const range = flatten(arguments);\n const n = range.length;\n\n let sigma = 0;\n let count = 0;\n\n const mean = AVERAGEA(range);\n\n let result;\n\n for (let i = 0; i < n; i++) {\n const el = range[i];\n\n if (typeof el === 'number') {\n sigma += Math.pow(el - mean, 2);\n } else if (el === true) {\n sigma += Math.pow(1 - mean, 2);\n } else {\n sigma += Math.pow(0 - mean, 2);\n }\n\n if (el !== null) {\n count++;\n }\n }\n\n result = sigma / count;\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\nconst WEIBULL = {};\n\n/**\n * Returns the Weibull distribution.\n *\n * Category: Statistical\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} alpha A parameter to the distribution.\n * @param {*} beta A parameter to the distribution.\n * @param {*} cumulative Determines the form of the function.\n * @returns\n */\nWEIBULL.DIST = (x, alpha, beta, cumulative) => {\n x = parseNumber(x);\n alpha = parseNumber(alpha);\n beta = parseNumber(beta);\n\n if (anyIsError(x, alpha, beta)) {\n return value\n }\n\n return cumulative\n ? 1 - Math.exp(-Math.pow(x / beta, alpha))\n : (Math.pow(x, alpha - 1) * Math.exp(-Math.pow(x / beta, alpha)) * alpha) / Math.pow(beta, alpha)\n};\n\nconst Z = {};\n\n/**\n * Returns the one-tailed probability-value of a z-test.\n *\n * Category: Statistical\n *\n * @param {*} array The array or range of data against which to test x.\n * @param {*} x The value to test.\n * @param {*} sigma Optional. The population (known) standard deviation. If omitted, the sample standard deviation is used.\n * @returns\n */\nZ.TEST = (array, x, sigma) => {\n array = parseNumberArray(flatten(array));\n x = parseNumber(x);\n\n if (anyIsError(array, x)) {\n return value\n }\n\n sigma = sigma || STDEV.S(array);\n\n const n = array.length;\n\n return 1 - NORM.S.DIST((AVERAGE(array) - x) / (sigma / Math.sqrt(n)), true)\n};\n\n/**\n * Returns the absolute value of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The real number of which you want the absolute value.\n * @returns\n */\nfunction ABS(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n const result = Math.abs(number);\n\n return result\n}\n\n/**\n * Returns the arccosine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The cosine of the angle you want and must be from -1 to 1.\n * @returns\n */\nfunction ACOS(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n let result = Math.acos(number);\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the inverse hyperbolic cosine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number equal to or greater than 1.\n * @returns\n */\nfunction ACOSH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n let result = Math.log(number + Math.sqrt(number * number - 1));\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the arccotangent of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Number is the cotangent of the angle you want. This must be a real number.\n * @returns\n */\nfunction ACOT(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n const result = Math.atan(1 / number);\n\n return result\n}\n\n/**\n * Returns the hyperbolic arccotangent of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The absolute value of Number must be greater than 1.\n * @returns\n */\nfunction ACOTH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n let result = 0.5 * Math.log((number + 1) / (number - 1));\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n// TODO: use options\n/**\n * Returns an aggregate in a list or database.\n *\n * Category: Math and trigonometry\n *\n * @param {*} function_num A number 1 to 19 that specifies which function to use.\n * @param {*} options A numerical value that determines which values to ignore in the evaluation range for the function. Note: The function will not ignore hidden rows, nested subtotals or nested aggregates if the array argument includes a calculation, for example: =AGGREGATE(14,3,A1:A100*(A1:A100>0),1)\n * @param {*} ref1 The first numeric argument for functions that take multiple numeric arguments for which you want the aggregate value.\n * @param {*} ref2 Optional. Numeric arguments 2 to 253 for which you want the aggregate value. For functions that take an array, ref1 is an array, an array formula, or a reference to a range of values for which you want the aggregate value. Ref2 is a second argument that is required for certain functions.\n * @returns\n */\nfunction AGGREGATE(function_num, options, ref1, ref2) {\n function_num = parseNumber(function_num);\n options = parseNumber(function_num);\n\n if (anyIsError(function_num, options)) {\n return value\n }\n\n switch (function_num) {\n case 1:\n return AVERAGE(ref1)\n case 2:\n return COUNT(ref1)\n case 3:\n return COUNTA(ref1)\n case 4:\n return MAX(ref1)\n case 5:\n return MIN(ref1)\n case 6:\n return PRODUCT(ref1)\n case 7:\n return STDEV.S(ref1)\n case 8:\n return STDEV.P(ref1)\n case 9:\n return SUM(ref1)\n case 10:\n return VAR.S(ref1)\n case 11:\n return VAR.P(ref1)\n case 12:\n return MEDIAN(ref1)\n case 13:\n return MODE.SNGL(ref1)\n case 14:\n return LARGE(ref1, ref2)\n case 15:\n return SMALL(ref1, ref2)\n case 16:\n return PERCENTILE.INC(ref1, ref2)\n case 17:\n return QUARTILE.INC(ref1, ref2)\n case 18:\n return PERCENTILE.EXC(ref1, ref2)\n case 19:\n return QUARTILE.EXC(ref1, ref2)\n }\n}\n\n/**\n * Converts a Roman number to Arabic, as a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} text A string enclosed in quotation marks, an empty string (\"\"), or a reference to a value containing text.\n * @returns\n */\nfunction ARABIC(text) {\n if (text === undefined || text === null) {\n return 0\n }\n\n if (text instanceof Error) {\n return text\n }\n\n // Credits: Rafa? Kukawski\n if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(text)) {\n return value\n }\n\n let r = 0;\n text.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, (i) => {\n r += {\n M: 1000,\n CM: 900,\n D: 500,\n CD: 400,\n C: 100,\n XC: 90,\n L: 50,\n XL: 40,\n X: 10,\n IX: 9,\n V: 5,\n IV: 4,\n I: 1\n }[i];\n });\n\n return r\n}\n\n/**\n * Returns the arcsine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The sine of the angle you want and must be from -1 to 1.\n * @returns\n */\nfunction ASIN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n let result = Math.asin(number);\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Returns the inverse hyperbolic sine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number.\n * @returns\n */\nfunction ASINH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.log(number + Math.sqrt(number * number + 1))\n}\n\n/**\n * Returns the arctangent of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The tangent of the angle you want.\n * @returns\n */\nfunction ATAN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.atan(number)\n}\n\n/**\n * Returns the arctangent from x- and y-coordinates.\n *\n * Category: Math and trigonometry\n *\n * @param {*} x_num The x-coordinate of the point.\n * @param {*} y_num The y-coordinate of the point.\n * @returns\n */\nfunction ATAN2(x_num, y_num) {\n x_num = parseNumber(x_num);\n y_num = parseNumber(y_num);\n const anyError$1 = anyError(x_num, y_num);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return Math.atan2(x_num, y_num)\n}\n\n/**\n * Returns the inverse hyperbolic tangent of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number between 1 and -1.\n * @returns\n */\nfunction ATANH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n let result = Math.log((1 + number) / (1 - number)) / 2;\n\n if (isNaN(result)) {\n result = num;\n }\n\n return result\n}\n\n/**\n * Converts a number into a text representation with the given radix (base).\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number that you want to convert. Must be an integer greater than or equal to 0 and less than 2^53.\n * @param {*} radix The base radix that you want to convert the number into. Must be an integer greater than or equal to 2 and less than or equal to 36.\n * @param {*} min_length Optional. The minimum length of the returned string. Must be an integer greater than or equal to 0.\n * @returns\n */\nfunction BASE(number, radix, min_length) {\n number = parseNumber(number);\n radix = parseNumber(radix);\n min_length = parseNumber(min_length);\n const anyError$1 = anyError(number, radix, min_length);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (radix === 0) {\n return num\n }\n\n const result = number.toString(radix);\n\n return new Array(Math.max(min_length + 1 - result.length, 0)).join('0') + result\n}\n\n/**\n * Rounds a number to the nearest integer or to the nearest multiple of significance.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The value you want to round.\n * @param {*} significance The multiple to which you want to round.\n * @param {*} mode Optional. For negative numbers, controls whether Number is rounded toward or away from zero.\n * @returns\n */\nfunction CEILING(number, significance, mode) {\n number = parseNumber(number);\n significance = parseNumber(significance);\n mode = parseNumber(mode);\n const anyError$1 = anyError(number, significance, mode);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (significance === 0) {\n return 0\n }\n\n significance = Math.abs(significance);\n const precision = -Math.floor(Math.log(significance) / Math.log(10));\n\n if (number >= 0) {\n return ROUND(Math.ceil(number / significance) * significance, precision)\n } else {\n if (mode === 0) {\n return -ROUND(Math.floor(Math.abs(number) / significance) * significance, precision)\n } else {\n return -ROUND(Math.ceil(Math.abs(number) / significance) * significance, precision)\n }\n }\n}\n\nCEILING.MATH = CEILING;\n\nCEILING.PRECISE = CEILING;\n\n/**\n * Returns the number of combinations for a given number of objects.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number of items.\n * @param {*} number_chosen The number of items in each combination.\n * @returns\n */\nfunction COMBIN(number, number_chosen) {\n number = parseNumber(number);\n number_chosen = parseNumber(number_chosen);\n const anyError$1 = anyError(number, number_chosen);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (number < number_chosen) {\n return num\n }\n\n return FACT(number) / (FACT(number_chosen) * FACT(number - number_chosen))\n}\n\n/**\n * Returns the number of combinations with repetitions for a given number of items.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Must be greater than or equal to 0, and greater than or equal to Number_chosen. Non-integer values are truncated.\n * @param {*} number_chosen Must be greater than or equal to 0. Non-integer values are truncated.\n * @returns\n */\nfunction COMBINA(number, number_chosen) {\n number = parseNumber(number);\n number_chosen = parseNumber(number_chosen);\n const anyError$1 = anyError(number, number_chosen);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (number < number_chosen) {\n return num\n }\n\n return number === 0 && number_chosen === 0 ? 1 : COMBIN(number + number_chosen - 1, number - 1)\n}\n\n/**\n * Returns the cosine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The angle in radians for which you want the cosine.\n * @returns\n */\nfunction COS(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.cos(number)\n}\n\n/**\n * Returns the hyperbolic cosine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number for which you want to find the hyperbolic cosine.\n * @returns\n */\nfunction COSH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return (Math.exp(number) + Math.exp(-number)) / 2\n}\n\n/**\n * Returns the hyperbolic cosine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The angle in radians for which you want the cotangent.\n * @returns\n */\nfunction COT(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return div0\n }\n\n return 1 / Math.tan(number)\n}\n\n/**\n * Returns the cotangent of an angle.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number\n * @returns\n */\nfunction COTH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return div0\n }\n\n const e2 = Math.exp(2 * number);\n\n return (e2 + 1) / (e2 - 1)\n}\n\n/**\n * Returns the cosecant of an angle.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number\n * @returns\n */\nfunction CSC(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return div0\n }\n\n return 1 / Math.sin(number)\n}\n\n/**\n * Returns the hyperbolic cosecant of an angle.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number\n * @returns\n */\nfunction CSCH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return div0\n }\n\n return 2 / (Math.exp(number) - Math.exp(-number))\n}\n\n/**\n * Converts a text representation of a number in a given base into a decimal number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} text\n * @param {*} radix Radix must be an integer.\n * @returns\n */\nfunction DECIMAL(text, radix) {\n if (arguments.length < 2) {\n return na\n }\n\n text = text || '0';\n radix = parseNumber(radix);\n const anyError$1 = anyError(text, radix);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (radix === 0) {\n return num\n }\n\n const result = parseInt(text, radix);\n\n if (isNaN(result)) {\n return num\n }\n\n return result\n}\n\n/**\n * Converts radians to degrees.\n *\n * Category: Math and trigonometry\n *\n * @param {*} angle The angle in radians that you want to convert.\n * @returns\n */\nfunction DEGREES(angle) {\n angle = parseNumber(angle);\n\n if (angle instanceof Error) {\n return angle\n }\n\n return (angle * 180) / Math.PI\n}\n\n/**\n * Rounds a number up to the nearest even integer.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The value to round.\n * @returns\n */\nfunction EVEN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return CEILING(number, -2, -1)\n}\n\n/**\n * Returns e raised to the power of a given number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The exponent applied to the base e.\n * @returns\n */\nfunction EXP(number) {\n if (arguments.length < 1) {\n return na\n }\n\n if (arguments.length > 1) {\n return error\n }\n\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n number = Math.exp(number);\n\n return number\n}\n\nconst MEMOIZED_FACT = [];\n/**\n * Returns the factorial of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The nonnegative number for which you want the factorial. If number is not an integer, it is truncated.\n * @returns\n */\nfunction FACT(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n const n = Math.floor(number);\n\n if (n === 0 || n === 1) {\n return 1\n } else if (MEMOIZED_FACT[n] > 0) {\n return MEMOIZED_FACT[n]\n } else {\n MEMOIZED_FACT[n] = FACT(n - 1) * n;\n\n return MEMOIZED_FACT[n]\n }\n}\n\n/**\n * Returns the double factorial of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The value for which to return the double factorial. If number is not an integer, it is truncated.\n * @returns\n */\nfunction FACTDOUBLE(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n const n = Math.floor(number);\n\n return n <= 0 ? 1 : n * FACTDOUBLE(n - 2)\n}\n\n/**\n * Rounds a number down, toward zero.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The numeric value you want to round.\n * @param {*} significance The multiple to which you want to round.\n * @returns\n */\nfunction FLOOR(number, significance) {\n number = parseNumber(number);\n significance = parseNumber(significance);\n const anyError$1 = anyError(number, significance);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (significance === 0) {\n return 0\n }\n\n if (!(number >= 0 && significance > 0) && !(number <= 0 && significance < 0)) {\n return num\n }\n\n significance = Math.abs(significance);\n const precision = -Math.floor(Math.log(significance) / Math.log(10));\n\n return number >= 0\n ? ROUND(Math.floor(number / significance) * significance, precision)\n : -ROUND(Math.ceil(Math.abs(number) / significance), precision)\n}\n\n// TODO: Verify\n\n/**\n * Rounds a number down, to the nearest integer or to the nearest multiple of significance.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number to be rounded down.\n * @param {*} significance Optional. The multiple to which you want to round.\n * @param {*} mode Optional. The direction (toward or away from 0) to round negative numbers.\n * @returns\n */\nFLOOR.MATH = (number, significance, mode) => {\n if (significance instanceof Error) {\n return significance\n }\n\n significance = significance === undefined ? 0 : significance;\n\n number = parseNumber(number);\n significance = parseNumber(significance);\n mode = parseNumber(mode);\n const anyError$1 = anyError(number, significance, mode);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (significance === 0) {\n return 0\n }\n\n significance = significance ? Math.abs(significance) : 1;\n const precision = -Math.floor(Math.log(significance) / Math.log(10));\n\n if (number >= 0) {\n return ROUND(Math.floor(number / significance) * significance, precision)\n } else if (mode === 0 || mode === undefined) {\n return -ROUND(Math.ceil(Math.abs(number) / significance) * significance, precision)\n }\n\n return -ROUND(Math.floor(Math.abs(number) / significance) * significance, precision)\n};\n\n// Deprecated\n\n/**\n * Rounds a number the nearest integer or to the nearest multiple of significance. Regardless of the sign of the number, the number is rounded up.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The value to be rounded.\n * @param {*} significance Optional. The multiple to which number is to be rounded. If significance is omitted, its default value is 1.\n * @returns\n */\nFLOOR.PRECISE = FLOOR['MATH'];\n\n// adapted http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript\n/**\n * Returns the greatest common divisor.\n *\n * Category: Math and trigonometry\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 values. If any value is not an integer, it is truncated.\n * @returns\n */\nfunction GCD() {\n const range = parseNumberArray(flatten(arguments));\n\n if (range instanceof Error) {\n return range\n }\n\n const n = range.length;\n const r0 = range[0];\n let x = r0 < 0 ? -r0 : r0;\n\n for (let i = 1; i < n; i++) {\n const ri = range[i];\n let y = ri < 0 ? -ri : ri;\n\n while (x && y) {\n if (x > y) {\n x %= y;\n } else {\n y %= x;\n }\n }\n\n x += y;\n }\n\n return x\n}\n\n/**\n * Rounds a number down to the nearest integer.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The real number you want to round down to an integer.\n * @returns\n */\nfunction INT(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.floor(number)\n}\n\n// TODO: verify\nconst ISO = {\n CEILING: CEILING\n};\n\n/**\n * Returns the least common multiple.\n *\n * Category: Math and trigonometry\n *\n * @param {*} args number1, number2,... Number1 is required, subsequent numbers are optional. 1 to 255 values for which you want the least common multiple. If value is not an integer, it is truncated.\n * @returns\n */\nfunction LCM() {\n // Credits: Jonas Raoni Soares Silva\n const o = parseNumberArray(flatten(arguments));\n\n if (o instanceof Error) {\n return o\n }\n\n for (var i, j, n, d, r = 1; (n = o.pop()) !== undefined; ) {\n if (n === 0) {\n return 0\n }\n\n while (n > 1) {\n if (n % 2) {\n for (i = 3, j = Math.floor(Math.sqrt(n)); i <= j && n % i; i += 2) {\n // empty\n }\n\n d = i <= j ? i : n;\n } else {\n d = 2;\n }\n\n for (n /= d, r *= d, i = o.length; i; o[--i] % d === 0 && (o[i] /= d) === 1 && o.splice(i, 1)) {\n // empty\n }\n }\n }\n\n return r\n}\n\n/**\n * Returns the natural logarithm of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The positive real number for which you want the natural logarithm.\n * @returns\n */\nfunction LN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return num\n }\n\n return Math.log(number)\n}\n\n/**\n * Returns the logarithm of a number to a specified base.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The positive real number for which you want the logarithm.\n * @param {*} base Optional. The base of the logarithm. If base is omitted, it is assumed to be 10.\n * @returns\n */\nfunction LOG(number, base) {\n number = parseNumber(number);\n base = base ? parseNumber(base) : 10;\n const anyError$1 = anyError(number, base);\n if (anyError$1) {\n return anyError$1\n }\n\n if (number === 0 || base === 0) {\n return num\n }\n\n return Math.log(number) / Math.log(base)\n}\n\n/**\n * Returns the base-10 logarithm of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The positive real number for which you want the base-10 logarithm.\n * @returns\n */\nfunction LOG10(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number === 0) {\n return num\n }\n\n return Math.log(number) / Math.log(10)\n}\n\n/**\n * Returns the matrix product of two arrays. The result is an array with the same number of rows as array1 and the same number of columns as array2.\n *\n * Category: Math and trigonometry\n *\n * @param {*} array1 Required. 1st array you want to multiply.\n * @param {*} array2 Required. 2nd array you want to multiply.\n * @returns\n */\nfunction MMULT(array1, array2) {\n if (\n //Arguments are not arrays\n !Array.isArray(array1) ||\n !Array.isArray(array2) ||\n // There are empty arrays\n array1.some((el) => !el.length) ||\n array2.some((el) => !el.length) ||\n // Not all array elements are numbers\n flattenShallow(array1).some((el) => typeof el !== 'number') ||\n flattenShallow(array2).some((el) => typeof el !== 'number') ||\n // Number of columns in array1 is different from the number of rows in array2\n array1[0].length !== array2.length\n ) {\n return value\n }\n\n const matrix = Array(array1.length)\n .fill(0)\n .map(() => Array(array2[0].length).fill(0));\n\n return matrix.map((row, i) => row.map((_, j) => array1[i].reduce((sum, el, k) => sum + el * array2[k][j], 0)))\n}\n\n/**\n * Returns the remainder from division.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number for which you want to find the remainder.\n * @param {*} divisor The number by which you want to divide number.\n * @returns\n */\nfunction MOD(number, divisor) {\n number = parseNumber(number);\n divisor = parseNumber(divisor);\n const anyError$1 = anyError(number, divisor);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (divisor === 0) {\n return div0\n }\n\n let modulus = Math.abs(number % divisor);\n modulus = number < 0 ? divisor - modulus : modulus;\n\n return divisor > 0 ? modulus : -modulus\n}\n\n/**\n * Returns a number rounded to the desired multiple.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The value to round.\n * @param {*} multiple The multiple to which you want to round number.\n * @returns\n */\nfunction MROUND(number, multiple) {\n number = parseNumber(number);\n multiple = parseNumber(multiple);\n const anyError$1 = anyError(number, multiple);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (number * multiple === 0) {\n return 0\n }\n\n if (number * multiple < 0) {\n return num\n }\n\n return Math.round(number / multiple) * multiple\n}\n\n/**\n * Returns the multinomial of a set of numbers.\n *\n * Category: Math and trigonometry\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 values for which you want the multinomial.\n * @returns\n */\nfunction MULTINOMIAL() {\n const args = parseNumberArray(flatten(arguments));\n\n if (args instanceof Error) {\n return args\n }\n\n let sum = 0;\n let divisor = 1;\n\n for (let i = 0; i < args.length; i++) {\n sum += args[i];\n divisor *= FACT(args[i]);\n }\n\n return FACT(sum) / divisor\n}\n\n/**\n * Returns the unit matrix for the specified dimension.\n *\n * Category: Math and trigonometry\n *\n * @param {*} dimension Required. Dimension is an integer specifying the dimension of the unit matrix that you want to return. It returns an array. The dimension has to be greater than zero.\n * @returns\n */\nfunction MUNIT(dimension) {\n if (arguments.length > 1) {\n return na\n }\n\n dimension = parseInt(dimension);\n\n if (!dimension || dimension <= 0) {\n return value\n }\n\n return Array(dimension)\n .fill(0)\n .map(() => Array(dimension).fill(0))\n .map((el, i) => {\n el[i] = 1;\n return el\n })\n}\n\n/**\n * Rounds a number up to the nearest odd integer.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number: The value to round.\n * @returns\n */\nfunction ODD(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n let temp = Math.ceil(Math.abs(number));\n temp = temp & 1 ? temp : temp + 1;\n\n return number >= 0 ? temp : -temp\n}\n\n/**\n * Returns the value of pi.\n *\n * Category: Math and trigonometry\n *\n * @returns\n */\nfunction PI() {\n return Math.PI\n}\n\n/**\n * Returns the result of a number raised to a power.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The base number. It can be any real number.\n * @param {*} power The exponent to which the base number is raised.\n * @returns\n */\nfunction POWER(number, power) {\n number = parseNumber(number);\n power = parseNumber(power);\n const anyError$1 = anyError(number, power);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (number === 0 && power === 0) {\n return num\n }\n\n const result = Math.pow(number, power);\n\n if (isNaN(result)) {\n return num\n }\n\n return result\n}\n\n/**\n * Multiplies its arguments.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number1 The first number or range that you want to multiply.\n * @param {*} args number2, ... Optional. Additional numbers or ranges that you want to multiply, up to a maximum of 255 arguments.\n * @returns\n */\nfunction PRODUCT() {\n const flatArguments = flatten(arguments);\n const flatArgumentsDefined = flatArguments.filter((arg) => arg !== undefined && arg !== null);\n\n if (flatArgumentsDefined.length === 0) {\n return 0\n }\n\n const args = parseNumberArray(flatArgumentsDefined);\n\n if (args instanceof Error) {\n return args\n }\n\n let result = 1;\n\n for (let i = 0; i < args.length; i++) {\n result *= args[i];\n }\n\n return result\n}\n\n/**\n * Returns the integer portion of a division.\n *\n * Category: Math and trigonometry\n *\n * @param {*} numerator The dividend.\n * @param {*} denominator The divisor.\n * @returns\n */\nfunction QUOTIENT(numerator, denominator) {\n numerator = parseNumber(numerator);\n denominator = parseNumber(denominator);\n const anyError$1 = anyError(numerator, denominator);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return parseInt(numerator / denominator, 10)\n}\n\n/**\n * Converts degrees to radians.\n *\n * Category: Math and trigonometry\n *\n * @param {*} angle An angle in degrees that you want to convert.\n * @returns\n */\nfunction RADIANS(angle) {\n angle = parseNumber(angle);\n\n if (angle instanceof Error) {\n return angle\n }\n\n return (angle * Math.PI) / 180\n}\n\n/**\n * Returns a random number between 0 and 1.\n *\n * Category: Math and trigonometry\n *\n * @returns\n */\nfunction RAND() {\n return Math.random()\n}\n\n/**\n * Returns a random number between the numbers you specify.\n *\n * Category: Math and trigonometry\n *\n * @param {*} bottom The smallest integer RANDBETWEEN will return.\n * @param {*} top The largest integer RANDBETWEEN will return.\n * @returns\n */\nfunction RANDBETWEEN(bottom, top) {\n bottom = parseNumber(bottom);\n top = parseNumber(top);\n const anyError$1 = anyError(bottom, top);\n\n if (anyError$1) {\n return anyError$1\n }\n // Creative Commons Attribution 3.0 License\n // Copyright (c) 2012 eqcode\n\n return bottom + Math.ceil((top - bottom + 1) * Math.random()) - 1\n}\n\n// TODO\n/**\n * Converts an arabic numeral to roman, as text.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The Arabic numeral you want converted.\n * @returns\n */\nfunction ROMAN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n // The MIT License\n // Copyright (c) 2008 Steven Levithan\n const digits = String(number).split('');\n const key = [\n '',\n 'C',\n 'CC',\n 'CCC',\n 'CD',\n 'D',\n 'DC',\n 'DCC',\n 'DCCC',\n 'CM',\n '',\n 'X',\n 'XX',\n 'XXX',\n 'XL',\n 'L',\n 'LX',\n 'LXX',\n 'LXXX',\n 'XC',\n '',\n 'I',\n 'II',\n 'III',\n 'IV',\n 'V',\n 'VI',\n 'VII',\n 'VIII',\n 'IX'\n ];\n let roman = '';\n let i = 3;\n\n while (i--) {\n roman = (key[+digits.pop() + i * 10] || '') + roman;\n }\n\n return new Array(+digits.join('') + 1).join('M') + roman\n}\n\n/**\n * Rounds a number to a specified number of digits.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number that you want to round.\n * @param {*} num_digits The number of digits to which you want to round the number argument.\n * @returns\n */\nfunction ROUND(number, num_digits) {\n number = parseNumber(number);\n num_digits = parseNumber(num_digits);\n const anyError$1 = anyError(number, num_digits);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return Number(Math.round(Number(number + 'e' + num_digits)) + 'e' + num_digits * -1)\n}\n\n/**\n * Rounds a number down, toward zero.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number that you want rounded down.\n * @param {*} num_digits The number of digits to which you want to round number.\n * @returns\n */\nfunction ROUNDDOWN(number, num_digits) {\n number = parseNumber(number);\n num_digits = parseNumber(num_digits);\n const anyError$1 = anyError(number, num_digits);\n\n if (anyError$1) {\n return anyError$1\n }\n\n const sign = number > 0 ? 1 : -1;\n\n return (sign * Math.floor(Math.abs(number) * Math.pow(10, num_digits))) / Math.pow(10, num_digits)\n}\n\n/**\n * Rounds a number up, away from zero.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number that you want rounded up.\n * @param {*} num_digits The number of digits to which you want to round number.\n * @returns\n */\nfunction ROUNDUP(number, num_digits) {\n number = parseNumber(number);\n num_digits = parseNumber(num_digits);\n const anyError$1 = anyError(number, num_digits);\n\n if (anyError$1) {\n return anyError$1\n }\n\n const sign = number > 0 ? 1 : -1;\n\n return (sign * Math.ceil(Math.abs(number) * Math.pow(10, num_digits))) / Math.pow(10, num_digits)\n}\n\n/**\n * Returns the secant of an angle.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The angle in radians for which you want the secant.\n * @returns\n */\nfunction SEC(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return 1 / Math.cos(number)\n}\n\n/**\n * Returns the hyperbolic secant of an angle.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The angle in radians for which you want the hyperbolic secant.\n * @returns\n */\nfunction SECH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return 2 / (Math.exp(number) + Math.exp(-number))\n}\n\n/**\n * Returns the sum of a power series based on the formula.\n *\n * Category: Math and trigonometry\n *\n * @param {*} x The input value to the power series.\n * @param {*} n The initial power to which you want to raise x.\n * @param {*} m The step by which to increase n for each term in the series.\n * @param {*} coefficients A set of coefficients by which each successive power of x is multiplied. The number of values in coefficients determines the number of terms in the power series. For example, if there are three values in coefficients, then there will be three terms in the power series.\n * @returns\n */\nfunction SERIESSUM(x, n, m, coefficients) {\n x = parseNumber(x);\n n = parseNumber(n);\n m = parseNumber(m);\n coefficients = parseNumberArray(coefficients);\n\n if (anyIsError(x, n, m, coefficients)) {\n return value\n }\n\n let result = coefficients[0] * Math.pow(x, n);\n\n for (let i = 1; i < coefficients.length; i++) {\n result += coefficients[i] * Math.pow(x, n + i * m);\n }\n\n return result\n}\n\n/**\n * Returns the sign of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number.\n * @returns\n */\nfunction SIGN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number < 0) {\n return -1\n } else if (number === 0) {\n return 0\n } else {\n return 1\n }\n}\n\n/**\n * Returns the sine of the given angle.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The angle in radians for which you want the sine.\n * @returns\n */\nfunction SIN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.sin(number)\n}\n\n/**\n * Returns the hyperbolic sine of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number.\n * @returns\n */\nfunction SINH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return (Math.exp(number) - Math.exp(-number)) / 2\n}\n\n/**\n * Returns a positive square root.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number for which you want the square root.\n * @returns\n */\nfunction SQRT(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n if (number < 0) {\n return num\n }\n\n return Math.sqrt(number)\n}\n\n/**\n * Returns the square root of (number * pi).\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number by which pi is multiplied.\n * @returns\n */\nfunction SQRTPI(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.sqrt(number * Math.PI)\n}\n\n/**\n * Returns a subtotal in a list or database.\n *\n * Category: Math and trigonometry\n *\n * @param {*} function_num The number 1-11 or 101-111 that specifies the function to use for the subtotal. 1-11 includes manually-hidden rows, while 101-111 excludes them; filtered-out values are always excluded.\n * @param {*} ref1 The first named range or reference for which you want the subtotal.\n * @returns\n */\nfunction SUBTOTAL(function_num, ref1) {\n function_num = parseNumber(function_num);\n\n if (function_num instanceof Error) {\n return function_num\n }\n\n switch (function_num) {\n case 1:\n return AVERAGE(ref1)\n case 2:\n return COUNT(ref1)\n case 3:\n return COUNTA(ref1)\n case 4:\n return MAX(ref1)\n case 5:\n return MIN(ref1)\n case 6:\n return PRODUCT(ref1)\n case 7:\n return STDEV.S(ref1)\n case 8:\n return STDEV.P(ref1)\n case 9:\n return SUM(ref1)\n case 10:\n return VAR.S(ref1)\n case 11:\n return VAR.P(ref1)\n // no hidden values for us\n case 101:\n return AVERAGE(ref1)\n case 102:\n return COUNT(ref1)\n case 103:\n return COUNTA(ref1)\n case 104:\n return MAX(ref1)\n case 105:\n return MIN(ref1)\n case 106:\n return PRODUCT(ref1)\n case 107:\n return STDEV.S(ref1)\n case 108:\n return STDEV.P(ref1)\n case 109:\n return SUM(ref1)\n case 110:\n return VAR.S(ref1)\n case 111:\n return VAR.P(ref1)\n }\n}\n\n/**\n * Adds its arguments.\n *\n * Category: Math and trigonometry\n *\n * @returns\n */\nfunction SUM() {\n let result = 0;\n\n arrayEach(argsToArray(arguments), (value) => {\n if (result instanceof Error) {\n return false\n } else if (value instanceof Error) {\n result = value;\n } else if (typeof value === 'number') {\n result += value;\n } else if (typeof value === 'string') {\n const parsed = parseFloat(value);\n\n !isNaN(parsed) && (result += parsed);\n } else if (Array.isArray(value)) {\n const inner_result = SUM.apply(null, value);\n\n if (inner_result instanceof Error) {\n result = inner_result;\n } else {\n result += inner_result;\n }\n }\n });\n\n return result\n}\n\n/**\n * Adds the values specified by a given criteria.\n *\n * Category: Math and trigonometry\n *\n * @param {*} range The range of values that you want evaluated by criteria. Cells in each range must be numbers or names, arrays, or references that contain numbers. Blank and text values are ignored.\n * @param {*} criteria The criteria in the form of a number, expression, a value reference, text, or a function that defines which values will be added.\n * @param {*} sum_range Optional. The actual values to add, if you want to add values other than those specified in the range argument. If the sum_range argument is omitted, Excel adds the values that are specified in the range argument (the same values to which the criteria is applied). Sum_range should be the same size and shape as range. If it isn't, performance may suffer, and the formula will sum a range of values that starts with the first value in sum_range but has the same dimensions as range.\n * @returns\n */\nfunction SUMIF(range, criteria, sum_range) {\n range = flatten(range);\n\n sum_range = sum_range ? flatten(sum_range) : range;\n\n if (range instanceof Error) {\n return range\n }\n\n if (criteria === undefined || criteria === null || criteria instanceof Error) {\n return 0\n }\n\n let result = 0;\n const isWildcard = criteria === '*';\n const tokenizedCriteria = isWildcard ? null : parse(criteria + '');\n\n for (let i = 0; i < range.length; i++) {\n const value = range[i];\n const sumValue = sum_range[i];\n\n if (isWildcard) {\n result += value;\n } else {\n const tokens = [createToken(value, TOKEN_TYPE_LITERAL)].concat(tokenizedCriteria);\n\n result += compute(tokens) ? sumValue : 0;\n }\n }\n\n return result\n}\n\n/**\n * Adds the values in a range that meet multiple criteria.\n *\n * Category: Math and trigonometry\n *\n * @returns\n */\nfunction SUMIFS() {\n const values = applyCriteria(...arguments);\n return SUM(values)\n}\n\n/**\n * Returns the sum of the products of corresponding array components.\n *\n * Category: Math and trigonometry\n *\n * @returns\n */\nfunction SUMPRODUCT() {\n if (!arguments || arguments.length === 0) {\n return value\n }\n\n const arrays = arguments.length + 1;\n let result = 0;\n let product;\n let k;\n let _i;\n let _ij;\n\n for (let i = 0; i < arguments[0].length; i++) {\n if (!(arguments[0][i] instanceof Array)) {\n product = 1;\n\n for (k = 1; k < arrays; k++) {\n const _i_arg = arguments[k - 1][i];\n\n if (_i_arg instanceof Error) {\n return _i_arg\n }\n\n _i = parseNumber(_i_arg);\n\n if (_i instanceof Error) {\n return _i\n }\n\n product *= _i;\n }\n\n result += product;\n } else {\n for (let j = 0; j < arguments[0][i].length; j++) {\n product = 1;\n\n for (k = 1; k < arrays; k++) {\n const _ij_arg = arguments[k - 1][i][j];\n\n if (_ij_arg instanceof Error) {\n return _ij_arg\n }\n\n _ij = parseNumber(_ij_arg);\n\n if (_ij instanceof Error) {\n return _ij\n }\n\n product *= _ij;\n }\n\n result += product;\n }\n }\n }\n\n return result\n}\n\n/**\n * Returns the sum of the squares of the arguments.\n *\n * Category: Math and trigonometry\n *\n * @param {*} args number1, number2, ... Number1 is required, subsequent numbers are optional. 1 to 255 arguments for which you want the sum of the squares. You can also use a single array or a reference to an array instead of arguments separated by commas.\n * @returns\n */\nfunction SUMSQ() {\n const numbers = parseNumberArray(flatten(arguments));\n\n if (numbers instanceof Error) {\n return numbers\n }\n\n let result = 0;\n const length = numbers.length;\n\n for (let i = 0; i < length; i++) {\n result += ISNUMBER(numbers[i]) ? numbers[i] * numbers[i] : 0;\n }\n\n return result\n}\n\n/**\n * Returns the sum of the difference of squares of corresponding values in two arrays.\n *\n * Category: Math and trigonometry\n *\n * @param {*} array_x The first array or range of values.\n * @param {*} array_y The second array or range of values.\n * @returns\n */\nfunction SUMX2MY2(array_x, array_y) {\n array_x = parseNumberArray(flatten(array_x));\n array_y = parseNumberArray(flatten(array_y));\n\n if (anyIsError(array_x, array_y)) {\n return value\n }\n\n let result = 0;\n\n for (let i = 0; i < array_x.length; i++) {\n result += array_x[i] * array_x[i] - array_y[i] * array_y[i];\n }\n\n return result\n}\n\n/**\n * Returns the sum of the sum of squares of corresponding values in two arrays.\n *\n * Category: Math and trigonometry\n *\n * @param {*} array_x The first array or range of values.\n * @param {*} array_y The second array or range of values.\n * @returns\n */\nfunction SUMX2PY2(array_x, array_y) {\n array_x = parseNumberArray(flatten(array_x));\n array_y = parseNumberArray(flatten(array_y));\n\n if (anyIsError(array_x, array_y)) {\n return value\n }\n\n let result = 0;\n array_x = parseNumberArray(flatten(array_x));\n array_y = parseNumberArray(flatten(array_y));\n\n for (let i = 0; i < array_x.length; i++) {\n result += array_x[i] * array_x[i] + array_y[i] * array_y[i];\n }\n\n return result\n}\n\n/**\n * Returns the sum of squares of differences of corresponding values in two arrays.\n *\n * Category: Math and trigonometry\n *\n * @param {*} array_x The first array or range of values.\n * @param {*} array_y The second array or range of values.\n * @returns\n */\nfunction SUMXMY2(array_x, array_y) {\n array_x = parseNumberArray(flatten(array_x));\n array_y = parseNumberArray(flatten(array_y));\n\n if (anyIsError(array_x, array_y)) {\n return value\n }\n\n let result = 0;\n array_x = flatten(array_x);\n array_y = flatten(array_y);\n\n for (let i = 0; i < array_x.length; i++) {\n result += Math.pow(array_x[i] - array_y[i], 2);\n }\n\n return result\n}\n\n/**\n * Returns the tangent of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The angle in radians for which you want the tangent.\n * @returns\n */\nfunction TAN(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n return Math.tan(number)\n}\n\n/**\n * Returns the hyperbolic tangent of a number.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number Any real number.\n * @returns\n */\nfunction TANH(number) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n const e2 = Math.exp(2 * number);\n\n return (e2 - 1) / (e2 + 1)\n}\n\n/**\n * Truncates a number to an integer.\n *\n * Category: Math and trigonometry\n *\n * @param {*} number The number you want to truncate.\n * @param {*} num_digits Optional. A number specifying the precision of the truncation. The default value for num_digits is 0 (zero).\n * @returns\n */\nfunction TRUNC(number, num_digits) {\n number = parseNumber(number);\n num_digits = parseNumber(num_digits);\n const anyError$1 = anyError(number, num_digits);\n\n if (anyError$1) {\n return anyError$1\n }\n\n const sign = number > 0 ? 1 : -1;\n\n return (sign * Math.floor(Math.abs(number) * Math.pow(10, num_digits))) / Math.pow(10, num_digits)\n}\n\n/**\n * Following functions are part of Formula.js only and not found in Excel.\n * Purpose of these functions is to implement an Excel like behaviour for fundamental math symbols such as +, -, /, *, etc.\n */\n\n/**\n * Formula.js only.\n *\n * @param {*} num1\n * @param {*} num2\n * @returns\n */\nfunction ADD(num1, num2) {\n if (arguments.length !== 2) {\n return na\n }\n\n num1 = parseNumber(num1);\n num2 = parseNumber(num2);\n const anyError$1 = anyError(num1, num2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return num1 + num2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} dividend\n * @param {*} divisor\n * @returns\n */\nfunction DIVIDE(dividend, divisor) {\n if (arguments.length !== 2) {\n return na\n }\n\n dividend = parseNumber(dividend);\n divisor = parseNumber(divisor);\n const anyError$1 = anyError(dividend, divisor);\n\n if (anyError$1) {\n return anyError$1\n }\n\n if (divisor === 0) {\n return div0\n }\n\n return dividend / divisor\n}\n\n/**\n * Formula.js only\n *\n * @param {*} value1\n * @param {*} value2\n * @returns\n */\nfunction EQ(value1, value2) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (value1 instanceof Error) {\n return value1\n }\n\n if (value2 instanceof Error) {\n return value2\n }\n\n if (value1 === null) {\n value1 = undefined;\n }\n\n if (value2 === null) {\n value2 = undefined;\n }\n\n return value1 === value2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} num1\n * @param {*} num2\n * @returns\n */\nfunction GT(num1, num2) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (num1 instanceof Error) {\n return num1\n }\n\n if (num2 instanceof Error) {\n return num2\n }\n\n if (anyIsString(num1, num2)) {\n num1 = parseString(num1);\n num2 = parseString(num2);\n } else {\n num1 = parseNumber(num1);\n num2 = parseNumber(num2);\n }\n\n const anyError$1 = anyError(num1, num2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return num1 > num2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} num1\n * @param {*} num2\n * @returns\n */\nfunction GTE(num1, num2) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (anyIsString(num1, num2)) {\n num1 = parseString(num1);\n num2 = parseString(num2);\n } else {\n num1 = parseNumber(num1);\n num2 = parseNumber(num2);\n }\n\n const anyError$1 = anyError(num1, num2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return num1 >= num2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} num1\n * @param {*} num2\n * @returns\n */\nfunction LT(num1, num2) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (anyIsString(num1, num2)) {\n num1 = parseString(num1);\n num2 = parseString(num2);\n } else {\n num1 = parseNumber(num1);\n num2 = parseNumber(num2);\n }\n\n const anyError$1 = anyError(num1, num2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return num1 < num2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} num1\n * @param {*} num2\n * @returns\n */\nfunction LTE(num1, num2) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (anyIsString(num1, num2)) {\n num1 = parseString(num1);\n num2 = parseString(num2);\n } else {\n num1 = parseNumber(num1);\n num2 = parseNumber(num2);\n }\n\n const anyError$1 = anyError(num1, num2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return num1 <= num2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} num1\n * @param {*} num2\n * @returns\n */\nfunction MINUS(num1, num2) {\n if (arguments.length !== 2) {\n return na\n }\n\n num1 = parseNumber(num1);\n num2 = parseNumber(num2);\n const anyError$1 = anyError(num1, num2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return num1 - num2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} factor1\n * @param {*} factor2\n * @returns\n */\nfunction MULTIPLY(factor1, factor2) {\n if (arguments.length !== 2) {\n return na\n }\n\n factor1 = parseNumber(factor1);\n factor2 = parseNumber(factor2);\n const anyError$1 = anyError(factor1, factor2);\n\n if (anyError$1) {\n return anyError$1\n }\n\n return factor1 * factor2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} value1\n * @param {*} value2\n * @returns\n */\nfunction NE(value1, value2) {\n if (arguments.length !== 2) {\n return na\n }\n\n if (value1 instanceof Error) {\n return value1\n }\n\n if (value2 instanceof Error) {\n return value2\n }\n\n if (value1 === null) {\n value1 = undefined;\n }\n\n if (value2 === null) {\n value2 = undefined;\n }\n\n return value1 !== value2\n}\n\n/**\n * Formula.js only\n *\n * @param {*} base\n * @param {*} exponent\n * @returns\n */\nfunction POW(base, exponent) {\n if (arguments.length !== 2) {\n return na\n }\n\n return POWER(base, exponent)\n}\n\nvar symbols = /*#__PURE__*/Object.freeze({\n __proto__: null,\n ADD: ADD,\n DIVIDE: DIVIDE,\n EQ: EQ,\n GT: GT,\n GTE: GTE,\n LT: LT,\n LTE: LTE,\n MINUS: MINUS,\n MULTIPLY: MULTIPLY,\n NE: NE,\n POW: POW\n});\n\nconst d1900 = new Date(Date.UTC(1900, 0, 1));\nconst WEEK_STARTS = [\n undefined,\n 0,\n 1,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 0\n];\nconst WEEK_TYPES = [\n [],\n [1, 2, 3, 4, 5, 6, 7],\n [7, 1, 2, 3, 4, 5, 6],\n [6, 0, 1, 2, 3, 4, 5],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [7, 1, 2, 3, 4, 5, 6],\n [6, 7, 1, 2, 3, 4, 5],\n [5, 6, 7, 1, 2, 3, 4],\n [4, 5, 6, 7, 1, 2, 3],\n [3, 4, 5, 6, 7, 1, 2],\n [2, 3, 4, 5, 6, 7, 1],\n [1, 2, 3, 4, 5, 6, 7]\n];\nconst WEEKEND_TYPES = [\n [],\n [6, 0],\n [0, 1],\n [1, 2],\n [2, 3],\n [3, 4],\n [4, 5],\n [5, 6],\n undefined,\n undefined,\n undefined,\n [0, 0],\n [1, 1],\n [2, 2],\n [3, 3],\n [4, 4],\n [5, 5],\n [6, 6]\n];\n\n/**\n * Returns the serial number of a particular date.\n *\n * Category: Date and time\n *\n * @param {*} year Year\n * @param {*} month Month\n * @param {*} day Day\n * @returns\n */\nfunction DATE(year, month, day) {\n let result;\n\n year = parseNumber(year);\n month = parseNumber(month);\n day = parseNumber(day);\n\n if (anyIsError(year, month, day)) {\n result = value;\n } else {\n result = new Date(year, month - 1, day);\n\n if (result.getFullYear() < 0) {\n result = num;\n }\n }\n\n return result\n}\n\n/**\n * Calculates the number of days, months, or years between two dates. This function is useful in formulas where you need to calculate an age.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the first, or starting date of a given period.\n * @param {*} end_date A date that represents the last, or ending, date of the period.\n * @param {*} unit The type of information that you want returned, where:\n - \"Y\": The number of complete years in the period.\n - \"M\": The number of complete months in the period.\n - \"D\": The number of days in the period.\n - \"MD\": The difference between the days in start_date and end_date. The months and years of the dates are ignored.\n - \"YM\": The difference between the months in start_date and end_date. The days and years of the dates are ignored\n - \"YD\": The difference between the days of start_date and end_date. The years of the dates are ignored.\n * @returns\n */\nfunction DATEDIF(start_date, end_date, unit) {\n unit = unit.toUpperCase();\n start_date = parseDate(start_date);\n end_date = parseDate(end_date);\n\n const start_date_year = start_date.getFullYear();\n const start_date_month = start_date.getMonth();\n const start_date_day = start_date.getDate();\n const end_date_year = end_date.getFullYear();\n const end_date_month = end_date.getMonth();\n const end_date_day = end_date.getDate();\n\n let result;\n\n switch (unit) {\n case 'Y':\n result = Math.floor(YEARFRAC(start_date, end_date));\n break\n case 'D':\n result = DAYS(end_date, start_date);\n break\n case 'M':\n result = end_date_month - start_date_month + 12 * (end_date_year - start_date_year);\n\n if (end_date_day < start_date_day) {\n result--;\n }\n\n break\n case 'MD':\n if (start_date_day <= end_date_day) {\n result = end_date_day - start_date_day;\n } else {\n if (end_date_month === 0) {\n start_date.setFullYear(end_date_year - 1);\n start_date.setMonth(12);\n } else {\n start_date.setFullYear(end_date_year);\n start_date.setMonth(end_date_month - 1);\n }\n\n result = DAYS(end_date, start_date);\n }\n\n break\n case 'YM':\n result = end_date_month - start_date_month + 12 * (end_date_year - start_date_year);\n\n if (end_date_day < start_date_day) {\n result--;\n }\n\n result = result % 12;\n break\n case 'YD':\n if (end_date_month > start_date_month || (end_date_month === start_date_month && end_date_day < start_date_day)) {\n start_date.setFullYear(end_date_year);\n } else {\n start_date.setFullYear(end_date_year - 1);\n }\n\n result = DAYS(end_date, start_date);\n break\n }\n\n return result\n}\n\n/**\n * Converts a date in the form of text to a serial number.\n *\n * Category: Date and time\n *\n * @param {*} date_text Text that represents a date in an Excel date format, or a reference to a value that contains text that represents a date in an Excel date format.\n * @returns\n */\nfunction DATEVALUE(date_text) {\n if (typeof date_text !== 'string') {\n return value\n }\n\n const date = Date.parse(date_text);\n\n if (isNaN(date)) {\n return value\n }\n\n return new Date(date_text)\n}\n\n/**\n * Converts a serial number to a day of the month.\n *\n * Category: Date and time\n *\n * @param {*} serial_number The date of the day you are trying to find.\n * @returns\n */\nfunction DAY(serial_number) {\n const date = parseDate(serial_number);\n\n if (date instanceof Error) {\n return date\n }\n\n return date.getDate()\n}\n\nfunction startOfDay(date) {\n const newDate = new Date(date);\n newDate.setHours(0, 0, 0, 0);\n\n return newDate\n}\n\n/**\n * Returns the number of days between two dates.\n *\n * Category: Date and time\n *\n * @param {*} end_date Start_date and End_date are the two dates between which you want to know the number of days.\n * @param {*} start_date Start_date and End_date are the two dates between which you want to know the number of days.\n * @returns\n */\nfunction DAYS(end_date, start_date) {\n end_date = parseDate(end_date);\n start_date = parseDate(start_date);\n\n if (end_date instanceof Error) {\n return end_date\n }\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n return serial(startOfDay(end_date)) - serial(startOfDay(start_date))\n}\n\n/**\n * Calculates the number of days between two dates based on a 360-day year.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the start date. If start_date occurs after end_date, the DAYS360 function returns a negative number.\n * @param {*} end_date A date that represents the end date.\n * @param {*} method Optional. A logical value that specifies whether to use the U.S. or European method in the calculation.\n * @returns\n */\nfunction DAYS360(start_date, end_date, method) {\n method = parseBool(method || 'false');\n start_date = parseDate(start_date);\n end_date = parseDate(end_date);\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n if (end_date instanceof Error) {\n return end_date\n }\n\n if (method instanceof Error) {\n return method\n }\n\n const sm = start_date.getMonth();\n let em = end_date.getMonth();\n let sd, ed;\n\n if (method) {\n sd = start_date.getDate() === 31 ? 30 : start_date.getDate();\n ed = end_date.getDate() === 31 ? 30 : end_date.getDate();\n } else {\n const smd = new Date(start_date.getFullYear(), sm + 1, 0).getDate();\n const emd = new Date(end_date.getFullYear(), em + 1, 0).getDate();\n sd = start_date.getDate() === smd ? 30 : start_date.getDate();\n\n if (end_date.getDate() === emd) {\n if (sd < 30) {\n em++;\n ed = 1;\n } else {\n ed = 30;\n }\n } else {\n ed = end_date.getDate();\n }\n }\n\n return 360 * (end_date.getFullYear() - start_date.getFullYear()) + 30 * (em - sm) + (ed - sd)\n}\n\n/**\n * Returns the serial number of the date that is the indicated number of months before or after the start date.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the start date.\n * @param {*} months The number of months before or after start_date. A positive value for months yields a future date; a negative value yields a past date.\n * @returns\n */\nfunction EDATE(start_date, months) {\n start_date = parseDate(start_date);\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n if (isNaN(months)) {\n return value\n }\n\n // store the day and temporarily set to 1, which is safe\n let storedDay = start_date.getDate();\n start_date.setDate(1);\n\n months = parseInt(months, 10);\n start_date.setMonth(start_date.getMonth() + months);\n\n let targetMonth = start_date.getMonth();\n\n // if storedDay > 28 then we need to check end-of-month scenarios\n if (storedDay > 28) {\n let daysInTargetMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][targetMonth];\n\n // if target month is February, check for a leap year\n let targetYear = start_date.getFullYear();\n if (targetMonth === 1 && ((targetYear % 4 === 0 && targetYear % 100 !== 0) || targetYear % 400 === 0)) {\n daysInTargetMonth = 29;\n }\n storedDay = Math.min(storedDay, daysInTargetMonth);\n }\n\n start_date.setDate(storedDay);\n\n return start_date\n}\n\n/**\n * Returns the serial number of the last day of the month before or after a specified number of months.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the starting date.\n * @param {*} months The number of months before or after start_date. A positive value for months yields a future date; a negative value yields a past date.\n * @returns\n */\nfunction EOMONTH(start_date, months) {\n start_date = parseDate(start_date);\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n if (isNaN(months)) {\n return value\n }\n\n months = parseInt(months, 10);\n\n return new Date(start_date.getFullYear(), start_date.getMonth() + months + 1, 0)\n}\n\n/**\n * Converts a serial number to an hour.\n *\n * Category: Date and time\n *\n * @param {*} serial_number The time that contains the hour you want to find. Times may be entered as text strings within quotation marks (for example, \"6:45 PM\"), as decimal numbers (for example, 0.78125, which represents 6:45 PM), or as results of other formulas or functions (for example, TIMEVALUE(\"6:45 PM\")).\n * @returns\n */\nfunction HOUR(serial_number) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n return serial_number.getHours()\n}\n\n/**\n * Returns the number of the ISO week number of the year for a given date.\n *\n * Category: Date and time\n *\n * @param {*} date Date is the date-time code used by Excel for date and time calculation.\n * @returns\n */\nfunction ISOWEEKNUM(date) {\n date = parseDate(date);\n\n if (date instanceof Error) {\n return date\n }\n\n date = startOfDay(date);\n date.setDate(date.getDate() + 4 - (date.getDay() || 7));\n const yearStart = new Date(date.getFullYear(), 0, 1);\n\n return Math.ceil(((date - yearStart) / 86400000 + 1) / 7)\n}\n\n/**\n * Converts a serial number to a minute.\n *\n * Category: Date and time\n *\n * @param {*} serial_number The time that contains the minute you want to find. Times may be entered as text strings within quotation marks (for example, \"6:45 PM\"), as decimal numbers (for example, 0.78125, which represents 6:45 PM), or as results of other formulas or functions (for example, TIMEVALUE(\"6:45 PM\")).\n * @returns\n */\nfunction MINUTE(serial_number) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n return serial_number.getMinutes()\n}\n\n/**\n * Converts a serial number to a month.\n *\n * Category: Date and time\n *\n * @param {*} serial_number The date of the month you are trying to find.\n * @returns\n */\nfunction MONTH(serial_number) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n return serial_number.getMonth() + 1\n}\n\n/**\n * Returns the number of whole workdays between two dates.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the start date.\n * @param {*} end_date A date that represents the end date.\n * @param {*} holidays Optional. An optional range of one or more dates to exclude from the working calendar, such as state and federal holidays and floating holidays. The list can be either a range of values that contains the dates or an array constant of the serial numbers that represent the dates.\n * @returns\n */\nfunction NETWORKDAYS(start_date, end_date, holidays) {\n return NETWORKDAYS.INTL(start_date, end_date, 1, holidays)\n}\n\n/**\n * Returns the number of whole workdays between two dates using parameters to indicate which and how many days are weekend days.\n *\n * Category: Date and time\n *\n * @param {*} start_date The date for from which the difference is to be computed. The start_date can be earlier than, the same as, or later than the end_date.\n * @param {*} end_date The date for to which the difference is to be computed.\n * @param {*} weekend Optional. Indicates the days of the week that are weekend days and are not included in the number of whole working days between start_date and end_date. Weekend is a weekend number or string that specifies when weekends occur. Weekend number values indicate the following weekend days:\n * @param {*} holidays Optional. An optional set of one or more dates that are to be excluded from the working day calendar. holidays shall be a range of values that contain the dates, or an array constant of the serial values that represent those dates. The ordering of dates or serial values in holidays can be arbitrary.\n * @returns\n */\nNETWORKDAYS.INTL = (start_date, end_date, weekend, holidays) => {\n start_date = parseDate(start_date);\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n end_date = parseDate(end_date);\n\n if (end_date instanceof Error) {\n return end_date\n }\n\n let isMask = false;\n const maskDays = [];\n const maskIndex = [1, 2, 3, 4, 5, 6, 0];\n const maskRegex = new RegExp('^[0|1]{7}$');\n\n if (weekend === undefined) {\n weekend = WEEKEND_TYPES[1];\n } else if (typeof weekend === 'string' && maskRegex.test(weekend)) {\n isMask = true;\n weekend = weekend.split('');\n\n for (let i = 0; i < weekend.length; i++) {\n if (weekend[i] === '1') {\n maskDays.push(maskIndex[i]);\n }\n }\n } else {\n weekend = WEEKEND_TYPES[weekend];\n }\n\n if (!(weekend instanceof Array)) {\n return value\n }\n\n if (holidays === undefined) {\n holidays = [];\n } else if (!(holidays instanceof Array)) {\n holidays = [holidays];\n }\n\n for (let i = 0; i < holidays.length; i++) {\n const h = parseDate(holidays[i]);\n\n if (h instanceof Error) {\n return h\n }\n\n holidays[i] = h;\n }\n\n const days = Math.round((end_date - start_date) / (1000 * 60 * 60 * 24)) + 1;\n let total = days;\n const day = start_date;\n\n for (let i = 0; i < days; i++) {\n const d = new Date().getTimezoneOffset() > 0 ? day.getUTCDay() : day.getDay();\n let dec = isMask ? maskDays.includes(d) : d === weekend[0] || d === weekend[1];\n\n for (let j = 0; j < holidays.length; j++) {\n const holiday = holidays[j];\n\n if (\n holiday.getDate() === day.getDate() &&\n holiday.getMonth() === day.getMonth() &&\n holiday.getFullYear() === day.getFullYear()\n ) {\n dec = true;\n break\n }\n }\n\n if (dec) {\n total--;\n }\n\n day.setDate(day.getDate() + 1);\n }\n\n return total\n};\n\n/**\n * Returns the serial number of the current date and time.\n *\n * Category: Date and time\n *\n * @returns\n */\nfunction NOW() {\n return new Date()\n}\n\n/**\n * Converts a serial number to a second.\n *\n * Category: Date and time\n *\n * @param {*} serial_number The time that contains the seconds you want to find. Times may be entered as text strings within quotation marks (for example, \"6:45 PM\"), as decimal numbers (for example, 0.78125, which represents 6:45 PM), or as results of other formulas or functions (for example, TIMEVALUE(\"6:45 PM\")).\n * @returns\n */\nfunction SECOND(serial_number) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n return serial_number.getSeconds()\n}\n\n/**\n * Returns the serial number of a particular time.\n *\n * Category: Date and time\n *\n * @param {*} hour A number from 0 (zero) to 32767 representing the hour. Any value greater than 23 will be divided by 24 and the remainder will be treated as the hour value. For example, TIME(27,0,0) = TIME(3,0,0) = .125 or 3:00 AM.\n * @param {*} minute A number from 0 to 32767 representing the minute. Any value greater than 59 will be converted to hours and minutes. For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM.\n * @param {*} second A number from 0 to 32767 representing the second. Any value greater than 59 will be converted to hours, minutes, and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 or 12:33:20 AM\n * @returns\n */\nfunction TIME(hour, minute, second) {\n hour = parseNumber(hour);\n minute = parseNumber(minute);\n second = parseNumber(second);\n\n if (anyIsError(hour, minute, second)) {\n return value\n }\n\n if (hour < 0 || minute < 0 || second < 0) {\n return num\n }\n\n return (3600 * hour + 60 * minute + second) / 86400\n}\n\n/**\n * Converts a time in the form of text to a serial number.\n *\n * Category: Date and time\n *\n * @param {*} time_text A text string that represents a time in any one of the Microsoft Excel time formats; for example, \"6:45 PM\" and \"18:45\" text strings within quotation marks that represent time.\n * @returns\n */\nfunction TIMEVALUE(time_text) {\n time_text = parseDate(time_text);\n\n if (time_text instanceof Error) {\n return time_text\n }\n\n return (3600 * time_text.getHours() + 60 * time_text.getMinutes() + time_text.getSeconds()) / 86400\n}\n\n/**\n * Returns the serial number of today's date.\n *\n * Category: Date and time\n *\n * @returns\n */\nfunction TODAY() {\n return startOfDay(new Date())\n}\n\n/**\n * Converts a serial number to a day of the week.\n *\n * Category: Date and time\n *\n * @param {*} serial_number A sequential number that represents the date of the day you are trying to find.\n * @param {*} return_type Optional. A number that determines the type of return value.\n * @returns\n */\nfunction WEEKDAY(serial_number, return_type) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n if (return_type === undefined) {\n return_type = 1;\n }\n\n const day = serial_number.getDay();\n\n return WEEK_TYPES[return_type][day]\n}\n\n/**\n * Converts a serial number to a number representing where the week falls numerically with a year.\n *\n * Category: Date and time\n *\n * @param {*} serial_number A date within the week.\n * @param {*} return_type Optional. A number that determines on which day the week begins. The default is 1.\n * @returns\n */\nfunction WEEKNUM(serial_number, return_type) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n if (return_type === undefined) {\n return_type = 1;\n }\n\n if (return_type === 21) {\n return ISOWEEKNUM(serial_number)\n }\n\n const week_start = WEEK_STARTS[return_type];\n let jan = new Date(serial_number.getFullYear(), 0, 1);\n const inc = jan.getDay() < week_start ? 1 : 0;\n jan -= Math.abs(jan.getDay() - week_start) * 24 * 60 * 60 * 1000;\n\n return Math.floor((serial_number - jan) / (1000 * 60 * 60 * 24) / 7 + 1) + inc\n}\n\n/**\n * Returns the serial number of the date before or after a specified number of workdays.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the start date.\n * @param {*} days The number of nonweekend and nonholiday days before or after start_date. A positive value for days yields a future date; a negative value yields a past date.\n * @param {*} holidays Optional. An optional list of one or more dates to exclude from the working calendar, such as state and federal holidays and floating holidays. The list can be either a range of values that contain the dates or an array constant of the serial numbers that represent the dates.\n * @returns\n */\nfunction WORKDAY(start_date, days, holidays) {\n return WORKDAY.INTL(start_date, days, 1, holidays)\n}\n\n/**\n * Returns the serial number of the date before or after a specified number of workdays using parameters to indicate which and how many days are weekend days.\n *\n * Category: Date and time\n *\n * @param {*} start_date The start date, truncated to integer.\n * @param {*} days The number of workdays before or after the start_date. A positive value yields a future date; a negative value yields a past date; a zero value yields the start_date. Day-offset is truncated to an integer.\n * @param {*} weekend Optional. Indicates the days of the week that are weekend days and are not considered working days. Weekend is a weekend number or string that specifies when weekends occur. Weekend number values indicate the following weekend days:\n * @param {*} holidays Optional. An optional set of one or more dates that are to be excluded from the working day calendar. Holidays shall be a range of values that contain the dates, or an array constant of the serial values that represent those dates. The ordering of dates or serial values in holidays can be arbitrary.\n * @returns\n */\nWORKDAY.INTL = (start_date, days, weekend, holidays) => {\n start_date = parseDate(start_date);\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n days = parseNumber(days);\n\n if (days instanceof Error) {\n return days\n }\n\n if (weekend === undefined) {\n weekend = WEEKEND_TYPES[1];\n } else {\n weekend = WEEKEND_TYPES[weekend];\n }\n\n if (!(weekend instanceof Array)) {\n return value\n }\n\n if (holidays === undefined) {\n holidays = [];\n } else if (!(holidays instanceof Array)) {\n holidays = [holidays];\n }\n\n for (let i = 0; i < holidays.length; i++) {\n const h = parseDate(holidays[i]);\n\n if (h instanceof Error) {\n return h\n }\n\n holidays[i] = h;\n }\n\n let d = 0;\n\n const sign = Math.sign(days);\n\n while (d < days * sign) {\n start_date.setDate(start_date.getDate() + sign);\n\n const day = start_date.getDay();\n\n if (day === weekend[0] || day === weekend[1]) {\n continue\n }\n\n for (let j = 0; j < holidays.length; j++) {\n const holiday = holidays[j];\n\n if (\n holiday.getDate() === start_date.getDate() &&\n holiday.getMonth() === start_date.getMonth() &&\n holiday.getFullYear() === start_date.getFullYear()\n ) {\n d--;\n break\n }\n }\n\n d++;\n }\n\n // EXCEL does not recognize dates before 1900.\n if (start_date.getFullYear() < 1900) {\n return value\n }\n\n return start_date\n};\n\n/**\n * Converts a serial number to a year.\n *\n * Category: Date and time\n *\n * @param {*} serial_number The date of the year you want to find.\n * @returns\n */\nfunction YEAR(serial_number) {\n serial_number = parseDate(serial_number);\n\n if (serial_number instanceof Error) {\n return serial_number\n }\n\n return serial_number.getFullYear()\n}\n\nfunction isLeapYear(year) {\n return new Date(year, 1, 29).getMonth() === 1\n}\n\n// TODO : Use DAYS ?\nfunction daysBetween(start_date, end_date) {\n return Math.ceil((end_date - start_date) / 1000 / 60 / 60 / 24)\n}\n\n/**\n * Returns the year fraction representing the number of whole days between start_date and end_date.\n *\n * Category: Date and time\n *\n * @param {*} start_date A date that represents the start date.\n * @param {*} end_date A date that represents the end date.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction YEARFRAC(start_date, end_date, basis) {\n start_date = parseDate(start_date);\n\n if (start_date instanceof Error) {\n return start_date\n }\n\n end_date = parseDate(end_date);\n\n if (end_date instanceof Error) {\n return end_date\n }\n\n basis = basis || 0;\n let sd = start_date.getDate();\n const sm = start_date.getMonth() + 1;\n const sy = start_date.getFullYear();\n let ed = end_date.getDate();\n const em = end_date.getMonth() + 1;\n const ey = end_date.getFullYear();\n\n switch (basis) {\n case 0:\n // US (NASD) 30/360\n if (sd === 31 && ed === 31) {\n sd = 30;\n ed = 30;\n } else if (sd === 31) {\n sd = 30;\n } else if (sd === 30 && ed === 31) {\n ed = 30;\n }\n\n return (ed + em * 30 + ey * 360 - (sd + sm * 30 + sy * 360)) / 360\n case 1: {\n // Actual/actual\n const feb29Between = (date1, date2) => {\n const year1 = date1.getFullYear();\n const mar1year1 = new Date(year1, 2, 1);\n\n if (isLeapYear(year1) && date1 < mar1year1 && date2 >= mar1year1) {\n return true\n }\n\n const year2 = date2.getFullYear();\n const mar1year2 = new Date(year2, 2, 1);\n\n return isLeapYear(year2) && date2 >= mar1year2 && date1 < mar1year2\n };\n\n let ylength = 365;\n\n if (sy === ey || (sy + 1 === ey && (sm > em || (sm === em && sd >= ed)))) {\n if ((sy === ey && isLeapYear(sy)) || feb29Between(start_date, end_date) || (em === 1 && ed === 29)) {\n ylength = 366;\n }\n\n return daysBetween(start_date, end_date) / ylength\n }\n\n const years = ey - sy + 1;\n const days = (new Date(ey + 1, 0, 1) - new Date(sy, 0, 1)) / 1000 / 60 / 60 / 24;\n const average = days / years;\n\n return daysBetween(start_date, end_date) / average\n }\n\n case 2:\n // Actual/360\n\n return daysBetween(start_date, end_date) / 360\n case 3:\n // Actual/365\n\n return daysBetween(start_date, end_date) / 365\n case 4:\n // European 30/360\n\n return (ed + em * 30 + ey * 360 - (sd + sm * 30 + sy * 360)) / 360\n }\n}\n\nfunction serial(date) {\n const addOn = date > -2203891200000 ? 2 : 1;\n\n return Math.ceil((date - d1900) / 86400000) + addOn\n}\n\nfunction isValidBinaryNumber(number) {\n return /^[01]{1,10}$/.test(number)\n}\n\n/**\n * Returns the modified Bessel function In(x).\n *\n * Category: Engineering\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} n The order of the Bessel function. If n is not an integer, it is truncated.\n * @returns\n */\nfunction BESSELI(x, n) {\n x = parseNumber(x);\n n = parseNumber(n);\n\n if (anyIsError(x, n)) {\n return value\n }\n\n return bessel.besseli(x, n)\n}\n\n/**\n * Returns the Bessel function Jn(x).\n *\n * Category: Engineering\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} n The order of the Bessel function. If n is not an integer, it is truncated.\n * @returns\n */\nfunction BESSELJ(x, n) {\n x = parseNumber(x);\n n = parseNumber(n);\n\n if (anyIsError(x, n)) {\n return value\n }\n\n return bessel.besselj(x, n)\n}\n\n/**\n * Returns the modified Bessel function Kn(x).\n *\n * Category: Engineering\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} n The order of the function. If n is not an integer, it is truncated.\n * @returns\n */\nfunction BESSELK(x, n) {\n x = parseNumber(x);\n n = parseNumber(n);\n\n if (anyIsError(x, n)) {\n return value\n }\n\n return bessel.besselk(x, n)\n}\n\n/**\n * Returns the Bessel function Yn(x).\n *\n * Category: Engineering\n *\n * @param {*} x The value at which to evaluate the function.\n * @param {*} n The order of the function. If n is not an integer, it is truncated.\n * @returns\n */\nfunction BESSELY(x, n) {\n x = parseNumber(x);\n n = parseNumber(n);\n\n if (anyIsError(x, n)) {\n return value\n }\n\n return bessel.bessely(x, n)\n}\n\n/**\n * Converts a binary number to decimal.\n *\n * Category: Engineering\n *\n * @param {*} number The binary number you want to convert. Number cannot contain more than 10 characters (10 bits). The most significant bit of number is the sign bit. The remaining 9 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @returns\n */\nfunction BIN2DEC(number) {\n // Return error if number is not binary or contains more than 10 characters (10 digits)\n if (!isValidBinaryNumber(number)) {\n return num\n }\n\n // Convert binary number to decimal\n const result = parseInt(number, 2);\n\n // Handle negative numbers\n const stringified = number.toString();\n\n if (stringified.length === 10 && stringified.substring(0, 1) === '1') {\n return parseInt(stringified.substring(1), 2) - 512\n } else {\n return result\n }\n}\n\n/**\n * Converts a binary number to hexadecimal.\n *\n * Category: Engineering\n *\n * @param {*} number The binary number you want to convert. Number cannot contain more than 10 characters (10 bits). The most significant bit of number is the sign bit. The remaining 9 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, BIN2HEX uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction BIN2HEX(number, places) {\n // Return error if number is not binary or contains more than 10 characters (10 digits)\n if (!isValidBinaryNumber(number)) {\n return num\n }\n\n // Ignore places and return a 10-character hexadecimal number if number is negative\n const stringified = number.toString();\n\n if (stringified.length === 10 && stringified.substring(0, 1) === '1') {\n return (1099511627264 + parseInt(stringified.substring(1), 2)).toString(16)\n }\n\n // Convert binary number to hexadecimal\n const result = parseInt(number, 2).toString(16);\n\n // Return hexadecimal number using the minimum number of characters necessary if places is undefined\n if (places === undefined) {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Converts a binary number to octal.\n *\n * Category: Engineering\n *\n * @param {*} number The binary number you want to convert. Number cannot contain more than 10 characters (10 bits). The most significant bit of number is the sign bit. The remaining 9 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, BIN2OCT uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction BIN2OCT(number, places) {\n // Return error if number is not binary or contains more than 10 characters (10 digits)\n if (!isValidBinaryNumber(number)) {\n return num\n }\n\n // Ignore places and return a 10-character octal number if number is negative\n const stringified = number.toString();\n\n if (stringified.length === 10 && stringified.substring(0, 1) === '1') {\n return (1073741312 + parseInt(stringified.substring(1), 2)).toString(8)\n }\n\n // Convert binary number to octal\n const result = parseInt(number, 2).toString(8);\n\n // Return octal number using the minimum number of characters necessary if places is undefined\n if (places === undefined) {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Returns a 'Bitwise And' of two numbers.\n *\n * Category: Engineering\n *\n * @param {*} number1 Must be in decimal form and greater than or equal to 0.\n * @param {*} number2 Must be in decimal form and greater than or equal to 0.\n * @returns\n */\nfunction BITAND(number1, number2) {\n // Return error if either number is a non-numeric value\n number1 = parseNumber(number1);\n number2 = parseNumber(number2);\n\n if (anyIsError(number1, number2)) {\n return value\n }\n\n // Return error if either number is less than 0\n if (number1 < 0 || number2 < 0) {\n return num\n }\n\n // Return error if either number is a non-integer\n if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) {\n return num\n }\n\n // Return error if either number is greater than (2^48)-1\n if (number1 > 281474976710655 || number2 > 281474976710655) {\n return num\n }\n\n // Return bitwise AND of two numbers\n return number1 & number2\n}\n\n/**\n * Returns a value number shifted left by shift_amount bits.\n *\n * Category: Engineering\n *\n * @param {*} number Number must be an integer greater than or equal to 0.\n * @param {*} shift_amount Shift_amount must be an integer.\n * @returns\n */\nfunction BITLSHIFT(number, shift_amount) {\n number = parseNumber(number);\n shift_amount = parseNumber(shift_amount);\n\n if (anyIsError(number, shift_amount)) {\n return value\n }\n\n // Return error if number is less than 0\n if (number < 0) {\n return num\n }\n\n // Return error if number is a non-integer\n if (Math.floor(number) !== number) {\n return num\n }\n\n // Return error if number is greater than (2^48)-1\n if (number > 281474976710655) {\n return num\n }\n\n // Return error if the absolute value of shift is greater than 53\n if (Math.abs(shift_amount) > 53) {\n return num\n }\n\n // Return number shifted by shift bits to the left or to the right if shift is negative\n return shift_amount >= 0 ? number << shift_amount : number >> -shift_amount\n}\n\n/**\n * Returns a bitwise OR of 2 numbers.\n *\n * Category: Engineering\n *\n * @param {*} number1 Must be in decimal form and greater than or equal to 0.\n * @param {*} number2 Must be in decimal form and greater than or equal to 0.\n * @returns\n */\nfunction BITOR(number1, number2) {\n number1 = parseNumber(number1);\n number2 = parseNumber(number2);\n\n if (anyIsError(number1, number2)) {\n return value\n }\n\n // Return error if either number is less than 0\n if (number1 < 0 || number2 < 0) {\n return num\n }\n\n // Return error if either number is a non-integer\n if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) {\n return num\n }\n\n // Return error if either number is greater than (2^48)-1\n if (number1 > 281474976710655 || number2 > 281474976710655) {\n return num\n }\n\n // Return bitwise OR of two numbers\n return number1 | number2\n}\n\n/**\n * Returns a value number shifted right by shift_amount bits.\n *\n * Category: Engineering\n *\n * @param {*} number Must be an integer greater than or equal to 0.\n * @param {*} shift_amount Must be an integer.\n * @returns\n */\nfunction BITRSHIFT(number, shift_amount) {\n number = parseNumber(number);\n shift_amount = parseNumber(shift_amount);\n\n if (anyIsError(number, shift_amount)) {\n return value\n }\n\n // Return error if number is less than 0\n if (number < 0) {\n return num\n }\n\n // Return error if number is a non-integer\n if (Math.floor(number) !== number) {\n return num\n }\n\n // Return error if number is greater than (2^48)-1\n if (number > 281474976710655) {\n return num\n }\n\n // Return error if the absolute value of shift is greater than 53\n if (Math.abs(shift_amount) > 53) {\n return num\n }\n\n // Return number shifted by shift bits to the right or to the left if shift is negative\n return shift_amount >= 0 ? number >> shift_amount : number << -shift_amount\n}\n\n/**\n * Returns a bitwise 'Exclusive Or' of two numbers.\n *\n * Category: Engineering\n *\n * @param {*} number1 Must be greater than or equal to 0.\n * @param {*} number2 Must be greater than or equal to 0.\n * @returns\n */\nfunction BITXOR(number1, number2) {\n number1 = parseNumber(number1);\n number2 = parseNumber(number2);\n\n if (anyIsError(number1, number2)) {\n return value\n }\n\n // Return error if either number is less than 0\n if (number1 < 0 || number2 < 0) {\n return num\n }\n\n // Return error if either number is a non-integer\n if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) {\n return num\n }\n\n // Return error if either number is greater than (2^48)-1\n if (number1 > 281474976710655 || number2 > 281474976710655) {\n return num\n }\n\n // Return bitwise XOR of two numbers\n return number1 ^ number2\n}\n\n/**\n * Converts real and imaginary coefficients into a complex number.\n *\n * Category: Engineering\n *\n * @param {*} real_num The real coefficient of the complex number.\n * @param {*} i_num The imaginary coefficient of the complex number.\n * @param {*} suffix Optional. The suffix for the imaginary component of the complex number. If omitted, suffix is assumed to be \"i\".\n * @returns\n */\nfunction COMPLEX(real_num, i_num, suffix) {\n real_num = parseNumber(real_num);\n i_num = parseNumber(i_num);\n\n if (anyIsError(real_num, i_num)) {\n return real_num\n }\n\n // Set suffix\n suffix = suffix === undefined ? 'i' : suffix;\n\n // Return error if suffix is neither \"i\" nor \"j\"\n if (suffix !== 'i' && suffix !== 'j') {\n return value\n }\n\n // Return complex number\n if (real_num === 0 && i_num === 0) {\n return 0\n } else if (real_num === 0) {\n return i_num === 1 ? suffix : i_num.toString() + suffix\n } else if (i_num === 0) {\n return real_num.toString()\n } else {\n const sign = i_num > 0 ? '+' : '';\n return real_num.toString() + sign + (i_num === 1 ? suffix : i_num.toString() + suffix)\n }\n}\n\n/**\n * Converts a number from one measurement system to another.\n *\n * Category: Engineering\n *\n * @param {*} number is the value in from_units to convert.\n * @param {*} from_unit is the units for number.\n * @param {*} to_unit is the units for the result. CONVERT accepts the following text values (in quotation marks) for from_unit and to_unit.\n * @returns\n */\nfunction CONVERT(number, from_unit, to_unit) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n // List of units supported by CONVERT and units defined by the International System of Units\n // [Name, Symbol, Alternate symbols, Quantity, ISU, CONVERT, Conversion ratio]\n const units = [\n ['a.u. of action', '?', null, 'action', false, false, 1.05457168181818e-34],\n ['a.u. of charge', 'e', null, 'electric_charge', false, false, 1.60217653141414e-19],\n ['a.u. of energy', 'Eh', null, 'energy', false, false, 4.35974417757576e-18],\n ['a.u. of length', 'a?', null, 'length', false, false, 5.29177210818182e-11],\n ['a.u. of mass', 'm?', null, 'mass', false, false, 9.10938261616162e-31],\n ['a.u. of time', '?/Eh', null, 'time', false, false, 2.41888432650516e-17],\n ['admiralty knot', 'admkn', null, 'speed', false, true, 0.514773333],\n ['ampere', 'A', null, 'electric_current', true, false, 1],\n ['ampere per meter', 'A/m', null, 'magnetic_field_intensity', true, false, 1],\n ['ångström', 'Å', ['ang'], 'length', false, true, 1e-10],\n ['are', 'ar', null, 'area', false, true, 100],\n ['astronomical unit', 'ua', null, 'length', false, false, 1.49597870691667e-11],\n ['bar', 'bar', null, 'pressure', false, false, 100000],\n ['barn', 'b', null, 'area', false, false, 1e-28],\n ['becquerel', 'Bq', null, 'radioactivity', true, false, 1],\n ['bit', 'bit', ['b'], 'information', false, true, 1],\n ['btu', 'BTU', ['btu'], 'energy', false, true, 1055.05585262],\n ['byte', 'byte', null, 'information', false, true, 8],\n ['candela', 'cd', null, 'luminous_intensity', true, false, 1],\n ['candela per square metre', 'cd/m?', null, 'luminance', true, false, 1],\n ['coulomb', 'C', null, 'electric_charge', true, false, 1],\n ['cubic ångström', 'ang3', ['ang^3'], 'volume', false, true, 1e-30],\n ['cubic foot', 'ft3', ['ft^3'], 'volume', false, true, 0.028316846592],\n ['cubic inch', 'in3', ['in^3'], 'volume', false, true, 0.000016387064],\n ['cubic light-year', 'ly3', ['ly^3'], 'volume', false, true, 8.46786664623715e-47],\n ['cubic metre', 'm3', ['m^3'], 'volume', true, true, 1],\n ['cubic mile', 'mi3', ['mi^3'], 'volume', false, true, 4168181825.44058],\n ['cubic nautical mile', 'Nmi3', ['Nmi^3'], 'volume', false, true, 6352182208],\n ['cubic Pica', 'Pica3', ['Picapt3', 'Pica^3', 'Picapt^3'], 'volume', false, true, 7.58660370370369e-8],\n ['cubic yard', 'yd3', ['yd^3'], 'volume', false, true, 0.764554857984],\n ['cup', 'cup', null, 'volume', false, true, 0.0002365882365],\n ['dalton', 'Da', ['u'], 'mass', false, false, 1.66053886282828e-27],\n ['day', 'd', ['day'], 'time', false, true, 86400],\n ['degree', '°', null, 'angle', false, false, 0.0174532925199433],\n ['degrees Rankine', 'Rank', null, 'temperature', false, true, 0.555555555555556],\n ['dyne', 'dyn', ['dy'], 'force', false, true, 0.00001],\n ['electronvolt', 'eV', ['ev'], 'energy', false, true, 1.60217656514141],\n ['ell', 'ell', null, 'length', false, true, 1.143],\n ['erg', 'erg', ['e'], 'energy', false, true, 1e-7],\n ['farad', 'F', null, 'electric_capacitance', true, false, 1],\n ['fluid ounce', 'oz', null, 'volume', false, true, 0.0000295735295625],\n ['foot', 'ft', null, 'length', false, true, 0.3048],\n ['foot-pound', 'flb', null, 'energy', false, true, 1.3558179483314],\n ['gal', 'Gal', null, 'acceleration', false, false, 0.01],\n ['gallon', 'gal', null, 'volume', false, true, 0.003785411784],\n ['gauss', 'G', ['ga'], 'magnetic_flux_density', false, true, 1],\n ['grain', 'grain', null, 'mass', false, true, 0.0000647989],\n ['gram', 'g', null, 'mass', false, true, 0.001],\n ['gray', 'Gy', null, 'absorbed_dose', true, false, 1],\n ['gross registered ton', 'GRT', ['regton'], 'volume', false, true, 2.8316846592],\n ['hectare', 'ha', null, 'area', false, true, 10000],\n ['henry', 'H', null, 'inductance', true, false, 1],\n ['hertz', 'Hz', null, 'frequency', true, false, 1],\n ['horsepower', 'HP', ['h'], 'power', false, true, 745.69987158227],\n ['horsepower-hour', 'HPh', ['hh', 'hph'], 'energy', false, true, 2684519.538],\n ['hour', 'h', ['hr'], 'time', false, true, 3600],\n ['imperial gallon (U.K.)', 'uk_gal', null, 'volume', false, true, 0.00454609],\n ['imperial hundredweight', 'lcwt', ['uk_cwt', 'hweight'], 'mass', false, true, 50.802345],\n ['imperial quart (U.K)', 'uk_qt', null, 'volume', false, true, 0.0011365225],\n ['imperial ton', 'brton', ['uk_ton', 'LTON'], 'mass', false, true, 1016.046909],\n ['inch', 'in', null, 'length', false, true, 0.0254],\n ['international acre', 'uk_acre', null, 'area', false, true, 4046.8564224],\n ['IT calorie', 'cal', null, 'energy', false, true, 4.1868],\n ['joule', 'J', null, 'energy', true, true, 1],\n ['katal', 'kat', null, 'catalytic_activity', true, false, 1],\n ['kelvin', 'K', ['kel'], 'temperature', true, true, 1],\n ['kilogram', 'kg', null, 'mass', true, true, 1],\n ['knot', 'kn', null, 'speed', false, true, 0.514444444444444],\n ['light-year', 'ly', null, 'length', false, true, 9460730472580800],\n ['litre', 'L', ['l', 'lt'], 'volume', false, true, 0.001],\n ['lumen', 'lm', null, 'luminous_flux', true, false, 1],\n ['lux', 'lx', null, 'illuminance', true, false, 1],\n ['maxwell', 'Mx', null, 'magnetic_flux', false, false, 1e-18],\n ['measurement ton', 'MTON', null, 'volume', false, true, 1.13267386368],\n ['meter per hour', 'm/h', ['m/hr'], 'speed', false, true, 0.00027777777777778],\n ['meter per second', 'm/s', ['m/sec'], 'speed', true, true, 1],\n ['meter per second squared', 'm?s??', null, 'acceleration', true, false, 1],\n ['parsec', 'pc', ['parsec'], 'length', false, true, 30856775814671900],\n ['meter squared per second', 'm?/s', null, 'kinematic_viscosity', true, false, 1],\n ['metre', 'm', null, 'length', true, true, 1],\n ['miles per hour', 'mph', null, 'speed', false, true, 0.44704],\n ['millimetre of mercury', 'mmHg', null, 'pressure', false, false, 133.322],\n ['minute', '?', null, 'angle', false, false, 0.000290888208665722],\n ['minute', 'min', ['mn'], 'time', false, true, 60],\n ['modern teaspoon', 'tspm', null, 'volume', false, true, 0.000005],\n ['mole', 'mol', null, 'amount_of_substance', true, false, 1],\n ['morgen', 'Morgen', null, 'area', false, true, 2500],\n ['n.u. of action', '?', null, 'action', false, false, 1.05457168181818e-34],\n ['n.u. of mass', 'm?', null, 'mass', false, false, 9.10938261616162e-31],\n ['n.u. of speed', 'c?', null, 'speed', false, false, 299792458],\n ['n.u. of time', '?/(me?c??)', null, 'time', false, false, 1.28808866778687e-21],\n ['nautical mile', 'M', ['Nmi'], 'length', false, true, 1852],\n ['newton', 'N', null, 'force', true, true, 1],\n ['œrsted', 'Oe ', null, 'magnetic_field_intensity', false, false, 79.5774715459477],\n ['ohm', 'Ω', null, 'electric_resistance', true, false, 1],\n ['ounce mass', 'ozm', null, 'mass', false, true, 0.028349523125],\n ['pascal', 'Pa', null, 'pressure', true, false, 1],\n ['pascal second', 'Pa?s', null, 'dynamic_viscosity', true, false, 1],\n ['pferdestärke', 'PS', null, 'power', false, true, 735.49875],\n ['phot', 'ph', null, 'illuminance', false, false, 0.0001],\n ['pica (1/6 inch)', 'pica', null, 'length', false, true, 0.00035277777777778],\n ['pica (1/72 inch)', 'Pica', ['Picapt'], 'length', false, true, 0.00423333333333333],\n ['poise', 'P', null, 'dynamic_viscosity', false, false, 0.1],\n ['pond', 'pond', null, 'force', false, true, 0.00980665],\n ['pound force', 'lbf', null, 'force', false, true, 4.4482216152605],\n ['pound mass', 'lbm', null, 'mass', false, true, 0.45359237],\n ['quart', 'qt', null, 'volume', false, true, 0.000946352946],\n ['radian', 'rad', null, 'angle', true, false, 1],\n ['second', '?', null, 'angle', false, false, 0.00000484813681109536],\n ['second', 's', ['sec'], 'time', true, true, 1],\n ['short hundredweight', 'cwt', ['shweight'], 'mass', false, true, 45.359237],\n ['siemens', 'S', null, 'electrical_conductance', true, false, 1],\n ['sievert', 'Sv', null, 'equivalent_dose', true, false, 1],\n ['slug', 'sg', null, 'mass', false, true, 14.59390294],\n ['square ångström', 'ang2', ['ang^2'], 'area', false, true, 1e-20],\n ['square foot', 'ft2', ['ft^2'], 'area', false, true, 0.09290304],\n ['square inch', 'in2', ['in^2'], 'area', false, true, 0.00064516],\n ['square light-year', 'ly2', ['ly^2'], 'area', false, true, 8.95054210748189e31],\n ['square meter', 'm?', null, 'area', true, true, 1],\n ['square mile', 'mi2', ['mi^2'], 'area', false, true, 2589988.110336],\n ['square nautical mile', 'Nmi2', ['Nmi^2'], 'area', false, true, 3429904],\n ['square Pica', 'Pica2', ['Picapt2', 'Pica^2', 'Picapt^2'], 'area', false, true, 0.00001792111111111],\n ['square yard', 'yd2', ['yd^2'], 'area', false, true, 0.83612736],\n ['statute mile', 'mi', null, 'length', false, true, 1609.344],\n ['steradian', 'sr', null, 'solid_angle', true, false, 1],\n ['stilb', 'sb', null, 'luminance', false, false, 0.0001],\n ['stokes', 'St', null, 'kinematic_viscosity', false, false, 0.0001],\n ['stone', 'stone', null, 'mass', false, true, 6.35029318],\n ['tablespoon', 'tbs', null, 'volume', false, true, 0.0000147868],\n ['teaspoon', 'tsp', null, 'volume', false, true, 0.00000492892],\n ['tesla', 'T', null, 'magnetic_flux_density', true, true, 1],\n ['thermodynamic calorie', 'c', null, 'energy', false, true, 4.184],\n ['ton', 'ton', null, 'mass', false, true, 907.18474],\n ['tonne', 't', null, 'mass', false, false, 1000],\n ['U.K. pint', 'uk_pt', null, 'volume', false, true, 0.00056826125],\n ['U.S. bushel', 'bushel', null, 'volume', false, true, 0.03523907],\n ['U.S. oil barrel', 'barrel', null, 'volume', false, true, 0.158987295],\n ['U.S. pint', 'pt', ['us_pt'], 'volume', false, true, 0.000473176473],\n ['U.S. survey mile', 'survey_mi', null, 'length', false, true, 1609.347219],\n ['U.S. survey/statute acre', 'us_acre', null, 'area', false, true, 4046.87261],\n ['volt', 'V', null, 'voltage', true, false, 1],\n ['watt', 'W', null, 'power', true, true, 1],\n ['watt-hour', 'Wh', ['wh'], 'energy', false, true, 3600],\n ['weber', 'Wb', null, 'magnetic_flux', true, false, 1],\n ['yard', 'yd', null, 'length', false, true, 0.9144],\n ['year', 'yr', null, 'time', false, true, 31557600]\n ];\n\n // Binary prefixes\n // [Name, Prefix power of 2 value, Previx value, Abbreviation, Derived from]\n const binary_prefixes = {\n Yi: ['yobi', 80, 1208925819614629174706176, 'Yi', 'yotta'],\n Zi: ['zebi', 70, 1180591620717411303424, 'Zi', 'zetta'],\n Ei: ['exbi', 60, 1152921504606846976, 'Ei', 'exa'],\n Pi: ['pebi', 50, 1125899906842624, 'Pi', 'peta'],\n Ti: ['tebi', 40, 1099511627776, 'Ti', 'tera'],\n Gi: ['gibi', 30, 1073741824, 'Gi', 'giga'],\n Mi: ['mebi', 20, 1048576, 'Mi', 'mega'],\n ki: ['kibi', 10, 1024, 'ki', 'kilo']\n };\n\n // Unit prefixes\n // [Name, Multiplier, Abbreviation]\n const unit_prefixes = {\n Y: ['yotta', 1e24, 'Y'],\n Z: ['zetta', 1e21, 'Z'],\n E: ['exa', 1e18, 'E'],\n P: ['peta', 1e15, 'P'],\n T: ['tera', 1e12, 'T'],\n G: ['giga', 1e9, 'G'],\n M: ['mega', 1e6, 'M'],\n k: ['kilo', 1e3, 'k'],\n h: ['hecto', 1e2, 'h'],\n e: ['dekao', 1e1, 'e'],\n d: ['deci', 1e-1, 'd'],\n c: ['centi', 1e-2, 'c'],\n m: ['milli', 1e-3, 'm'],\n u: ['micro', 1e-6, 'u'],\n n: ['nano', 1e-9, 'n'],\n p: ['pico', 1e-12, 'p'],\n f: ['femto', 1e-15, 'f'],\n a: ['atto', 1e-18, 'a'],\n z: ['zepto', 1e-21, 'z'],\n y: ['yocto', 1e-24, 'y']\n };\n\n // Initialize units and multipliers\n let from = null;\n let to = null;\n let base_from_unit = from_unit;\n let base_to_unit = to_unit;\n let from_multiplier = 1;\n let to_multiplier = 1;\n let alt;\n\n // Lookup from and to units\n for (let i = 0; i < units.length; i++) {\n alt = units[i][2] === null ? [] : units[i][2];\n\n if (units[i][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) {\n from = units[i];\n }\n\n if (units[i][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) {\n to = units[i];\n }\n }\n\n // Lookup from prefix\n if (from === null) {\n const from_binary_prefix = binary_prefixes[from_unit.substring(0, 2)];\n let from_unit_prefix = unit_prefixes[from_unit.substring(0, 1)];\n\n // Handle dekao unit prefix (only unit prefix with two characters)\n if (from_unit.substring(0, 2) === 'da') {\n from_unit_prefix = ['dekao', 1e1, 'da'];\n }\n\n // Handle binary prefixes first (so that 'Yi' is processed before 'Y')\n if (from_binary_prefix) {\n from_multiplier = from_binary_prefix[2];\n base_from_unit = from_unit.substring(2);\n } else if (from_unit_prefix) {\n from_multiplier = from_unit_prefix[1];\n base_from_unit = from_unit.substring(from_unit_prefix[2].length);\n }\n\n // Lookup from unit\n for (let j = 0; j < units.length; j++) {\n alt = units[j][2] === null ? [] : units[j][2];\n\n if (units[j][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) {\n from = units[j];\n }\n }\n }\n\n // Lookup to prefix\n if (to === null) {\n const to_binary_prefix = binary_prefixes[to_unit.substring(0, 2)];\n let to_unit_prefix = unit_prefixes[to_unit.substring(0, 1)];\n\n // Handle dekao unit prefix (only unit prefix with two characters)\n if (to_unit.substring(0, 2) === 'da') {\n to_unit_prefix = ['dekao', 1e1, 'da'];\n }\n\n // Handle binary prefixes first (so that 'Yi' is processed before 'Y')\n if (to_binary_prefix) {\n to_multiplier = to_binary_prefix[2];\n base_to_unit = to_unit.substring(2);\n } else if (to_unit_prefix) {\n to_multiplier = to_unit_prefix[1];\n base_to_unit = to_unit.substring(to_unit_prefix[2].length);\n }\n\n // Lookup to unit\n for (let k = 0; k < units.length; k++) {\n alt = units[k][2] === null ? [] : units[k][2];\n\n if (units[k][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) {\n to = units[k];\n }\n }\n }\n\n // Return error if a unit does not exist\n if (from === null || to === null) {\n return na\n }\n\n // Return error if units represent different quantities\n if (from[3] !== to[3]) {\n return na\n }\n\n // Return converted number\n return (number * from[6] * from_multiplier) / (to[6] * to_multiplier)\n}\n\n/**\n * Converts a decimal number to binary.\n *\n * Category: Engineering\n *\n * @param {*} number The decimal integer you want to convert. If number is negative, valid place values are ignored and DEC2BIN returns a 10-character (10-bit) binary number in which the most significant bit is the sign bit. The remaining 9 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, DEC2BIN uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction DEC2BIN(number, places) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n // Return error if number is not decimal, is lower than -512, or is greater than 511\n if (!/^-?[0-9]{1,3}$/.test(number) || number < -512 || number > 511) {\n return num\n }\n\n // Ignore places and return a 10-character binary number if number is negative\n if (number < 0) {\n return '1' + REPT('0', 9 - (512 + number).toString(2).length) + (512 + number).toString(2)\n }\n\n // Convert decimal number to binary\n const result = parseInt(number, 10).toString(2);\n\n // Return binary number using the minimum number of characters necessary if places is undefined\n if (typeof places === 'undefined') {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Converts a decimal number to hexadecimal.\n *\n * Category: Engineering\n *\n * @param {*} number The decimal integer you want to convert. If number is negative, places is ignored and DEC2HEX returns a 10-character (40-bit) hexadecimal number in which the most significant bit is the sign bit. The remaining 39 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, DEC2HEX uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction DEC2HEX(number, places) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887\n if (!/^-?[0-9]{1,12}$/.test(number) || number < -549755813888 || number > 549755813887) {\n return num\n }\n\n // Ignore places and return a 10-character hexadecimal number if number is negative\n if (number < 0) {\n return (1099511627776 + number).toString(16)\n }\n\n // Convert decimal number to hexadecimal\n const result = parseInt(number, 10).toString(16);\n\n // Return hexadecimal number using the minimum number of characters necessary if places is undefined\n if (typeof places === 'undefined') {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Converts a decimal number to octal.\n *\n * Category: Engineering\n *\n * @param {*} number The decimal integer you want to convert. If number is negative, places is ignored and DEC2OCT returns a 10-character (30-bit) octal number in which the most significant bit is the sign bit. The remaining 29 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, DEC2OCT uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction DEC2OCT(number, places) {\n number = parseNumber(number);\n\n if (number instanceof Error) {\n return number\n }\n\n // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887\n if (!/^-?[0-9]{1,9}$/.test(number) || number < -536870912 || number > 536870911) {\n return num\n }\n\n // Ignore places and return a 10-character octal number if number is negative\n if (number < 0) {\n return (1073741824 + number).toString(8)\n }\n\n // Convert decimal number to octal\n const result = parseInt(number, 10).toString(8);\n\n // Return octal number using the minimum number of characters necessary if places is undefined\n if (typeof places === 'undefined') {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Tests whether two values are equal.\n *\n * Category: Engineering\n *\n * @param {*} number1 The first number.\n * @param {*} number2 Optional. The second number. If omitted, number2 is assumed to be zero.\n * @returns\n */\nfunction DELTA(number1, number2) {\n // Set number2 to zero if undefined\n number2 = number2 === undefined ? 0 : number2;\n number1 = parseNumber(number1);\n number2 = parseNumber(number2);\n\n if (anyIsError(number1, number2)) {\n return value\n }\n\n // Return delta\n return number1 === number2 ? 1 : 0\n}\n\n// TODO: why is upper_bound not used ? The excel documentation has no examples with upper_bound\n/**\n * Returns the error function.\n *\n * Category: Engineering\n *\n * @param {*} lower_limit The lower bound for integrating ERF.\n * @param {*} upper_limit Optional. The upper bound for integrating ERF. If omitted, ERF integrates between zero and lower_limit.\n * @returns\n */\nfunction ERF(lower_limit, upper_limit) {\n // Set number2 to zero if undefined\n upper_limit = upper_limit === undefined ? 0 : upper_limit;\n\n lower_limit = parseNumber(lower_limit);\n upper_limit = parseNumber(upper_limit);\n\n if (anyIsError(lower_limit, upper_limit)) {\n return value\n }\n\n return jStat.erf(lower_limit)\n}\n\n// TODO\n\n/**\n * -- Not implemented --\n *\n * Returns the error function.\n *\n * Category: Engineering\n *\n * @param {*} x The lower bound for integrating ERF.PRECISE.\n * @returns\n */\nERF.PRECISE = () => {\n throw new Error('ERF.PRECISE is not implemented')\n};\n\n/**\n * Returns the complementary error function.\n *\n * Category: Engineering\n *\n * @param {*} x The lower bound for integrating ERFC.\n * @returns\n */\nfunction ERFC(x) {\n // Return error if x is not a number\n if (isNaN(x)) {\n return value\n }\n\n return jStat.erfc(x)\n}\n\n// TODO\n\n/**\n * -- Not implemented --\n *\n * Returns the complementary ERF function integrated between x and infinity.\n *\n * Category: Engineering\n *\n * @param {*} x The lower bound for integrating ERFC.PRECISE.\n * @returns\n */\nERFC.PRECISE = () => {\n throw new Error('ERFC.PRECISE is not implemented')\n};\n\n/**\n * Tests whether a number is greater than a threshold value.\n *\n * Category: Engineering\n *\n * @param {*} number The value to test against step.\n * @param {*} step Optional. The threshold value. If you omit a value for step, GESTEP uses zero.\n * @returns\n */\nfunction GESTEP(number, step) {\n step = step || 0;\n number = parseNumber(number);\n\n if (anyIsError(step, number)) {\n return number\n }\n\n // Return delta\n return number >= step ? 1 : 0\n}\n\n/**\n * Converts a hexadecimal number to binary.\n *\n * Category: Engineering\n *\n * @param {*} number The hexadecimal number you want to convert. Number cannot contain more than 10 characters. The most significant bit of number is the sign bit (40th bit from the right). The remaining 9 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, HEX2BIN uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction HEX2BIN(number, places) {\n // Return error if number is not hexadecimal or contains more than ten characters (10 digits)\n if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) {\n return num\n }\n\n // Check if number is negative\n const negative = !!(number.length === 10 && number.substring(0, 1).toLowerCase() === 'f');\n\n // Convert hexadecimal number to decimal\n const decimal = negative ? parseInt(number, 16) - 1099511627776 : parseInt(number, 16);\n\n // Return error if number is lower than -512 or greater than 511\n if (decimal < -512 || decimal > 511) {\n return num\n }\n\n // Ignore places and return a 10-character binary number if number is negative\n if (negative) {\n return '1' + REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2)\n }\n\n // Convert decimal number to binary\n const result = decimal.toString(2);\n\n // Return binary number using the minimum number of characters necessary if places is undefined\n if (places === undefined) {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Converts a hexadecimal number to decimal.\n *\n * Category: Engineering\n *\n * @param {*} number The hexadecimal number you want to convert. Number cannot contain more than 10 characters (40 bits). The most significant bit of number is the sign bit. The remaining 39 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @returns\n */\nfunction HEX2DEC(number) {\n // Return error if number is not hexadecimal or contains more than ten characters (10 digits)\n if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) {\n return num\n }\n\n // Convert hexadecimal number to decimal\n const decimal = parseInt(number, 16);\n\n // Return decimal number\n return decimal >= 549755813888 ? decimal - 1099511627776 : decimal\n}\n\n/**\n * Converts a hexadecimal number to octal.\n *\n * Category: Engineering\n *\n * @param {*} number The hexadecimal number you want to convert. Number cannot contain more than 10 characters. The most significant bit of number is the sign bit. The remaining 39 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, HEX2OCT uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction HEX2OCT(number, places) {\n // Return error if number is not hexadecimal or contains more than ten characters (10 digits)\n if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) {\n return num\n }\n\n // Convert hexadecimal number to decimal\n const decimal = parseInt(number, 16);\n\n // Return error if number is positive and greater than 0x1fffffff (536870911)\n if (decimal > 536870911 && decimal < 1098974756864) {\n return num\n }\n\n // Ignore places and return a 10-character octal number if number is negative\n if (decimal >= 1098974756864) {\n return (decimal - 1098437885952).toString(8)\n }\n\n // Convert decimal number to octal\n const result = decimal.toString(8);\n\n // Return octal number using the minimum number of characters necessary if places is undefined\n if (places === undefined) {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Returns the absolute value (modulus) of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the absolute value.\n * @returns\n */\nfunction IMABS(inumber) {\n // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n // Return error if either coefficient is not a number\n if (anyIsError(x, y)) {\n return value\n }\n\n // Return absolute value of complex number\n return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))\n}\n\n/**\n * Returns the imaginary coefficient of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the imaginary coefficient.\n * @returns\n */\nfunction IMAGINARY(inumber) {\n if (inumber === undefined || inumber === true || inumber === false) {\n return value\n }\n\n // Return 0 if inumber is equal to 0\n if (inumber === 0 || inumber === '0') {\n return 0\n }\n\n // Handle special cases\n if (['i', 'j'].indexOf(inumber) >= 0) {\n return 1\n }\n\n // Force string type\n inumber = inumber + '';\n\n // Normalize imaginary coefficient\n inumber = inumber.replace('+i', '+1i').replace('-i', '-1i').replace('+j', '+1j').replace('-j', '-1j');\n\n // Lookup sign\n let plus = inumber.indexOf('+');\n let minus = inumber.indexOf('-');\n\n if (plus === 0) {\n plus = inumber.indexOf('+', 1);\n }\n\n if (minus === 0) {\n minus = inumber.indexOf('-', 1);\n }\n\n // Lookup imaginary unit\n const last = inumber.substring(inumber.length - 1, inumber.length);\n const unit = last === 'i' || last === 'j';\n\n if (plus >= 0 || minus >= 0) {\n // Return error if imaginary unit is neither i nor j\n if (!unit) {\n return num\n }\n\n // Return imaginary coefficient of complex number\n if (plus >= 0) {\n return isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))\n ? num\n : Number(inumber.substring(plus + 1, inumber.length - 1))\n } else {\n return isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))\n ? num\n : -Number(inumber.substring(minus + 1, inumber.length - 1))\n }\n } else {\n if (unit) {\n return isNaN(inumber.substring(0, inumber.length - 1)) ? num : inumber.substring(0, inumber.length - 1)\n } else {\n return isNaN(inumber) ? num : 0\n }\n }\n}\n\n/**\n * Returns the argument theta, an angle expressed in radians.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the argument .\n * @returns\n */\nfunction IMARGUMENT(inumber) {\n // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n // Return error if either coefficient is not a number\n if (anyIsError(x, y)) {\n return value\n }\n\n // Return error if inumber is equal to zero\n if (x === 0 && y === 0) {\n return div0\n }\n\n // Return PI/2 if x is equal to zero and y is positive\n if (x === 0 && y > 0) {\n return Math.PI / 2\n }\n\n // Return -PI/2 if x is equal to zero and y is negative\n if (x === 0 && y < 0) {\n return -Math.PI / 2\n }\n\n // Return zero if x is negative and y is equal to zero\n if (y === 0 && x > 0) {\n return 0\n }\n\n // Return zero if x is negative and y is equal to zero\n if (y === 0 && x < 0) {\n return -Math.PI\n }\n\n // Return argument of complex number\n if (x > 0) {\n return Math.atan(y / x)\n } else if (x < 0 && y >= 0) {\n return Math.atan(y / x) + Math.PI\n } else {\n return Math.atan(y / x) - Math.PI\n }\n}\n\n/**\n * Returns the complex conjugate of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the conjugate.\n * @returns\n */\nfunction IMCONJUGATE(inumber) {\n // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return conjugate of complex number\n return y !== 0 ? COMPLEX(x, -y, unit) : inumber\n}\n\n/**\n * Returns the cosine of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the cosine.\n * @returns\n */\nfunction IMCOS(inumber) {\n // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return cosine of complex number\n return COMPLEX(\n (Math.cos(x) * (Math.exp(y) + Math.exp(-y))) / 2,\n (-Math.sin(x) * (Math.exp(y) - Math.exp(-y))) / 2,\n unit\n )\n}\n\n/**\n * Returns the hyperbolic cosine of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the hyperbolic cosine.\n * @returns\n */\nfunction IMCOSH(inumber) {\n // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return hyperbolic cosine of complex number\n return COMPLEX(\n (Math.cos(y) * (Math.exp(x) + Math.exp(-x))) / 2,\n (Math.sin(y) * (Math.exp(x) - Math.exp(-x))) / 2,\n unit\n )\n}\n\n/**\n * Returns the cotangent of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the cotangent.\n * @returns\n */\nfunction IMCOT(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Return cotangent of complex number\n return IMDIV(IMCOS(inumber), IMSIN(inumber))\n}\n\n/**\n * Returns the quotient of two complex numbers.\n *\n * Category: Engineering\n *\n * @param {*} inumber1 The complex numerator or dividend.\n * @param {*} inumber2 The complex denominator or divisor.\n * @returns\n */\nfunction IMDIV(inumber1, inumber2) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const a = IMREAL(inumber1);\n const b = IMAGINARY(inumber1);\n const c = IMREAL(inumber2);\n const d = IMAGINARY(inumber2);\n\n if (anyIsError(a, b, c, d)) {\n return value\n }\n\n // Lookup imaginary unit\n const unit1 = inumber1.substring(inumber1.length - 1);\n const unit2 = inumber2.substring(inumber2.length - 1);\n let unit = 'i';\n\n if (unit1 === 'j') {\n unit = 'j';\n } else if (unit2 === 'j') {\n unit = 'j';\n }\n\n // Return error if inumber2 is null\n if (c === 0 && d === 0) {\n return num\n }\n\n // Return exponential of complex number\n const den = c * c + d * d;\n return COMPLEX((a * c + b * d) / den, (b * c - a * d) / den, unit)\n}\n\n/**\n * Returns the exponential of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the exponential.\n * @returns\n */\nfunction IMEXP(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return exponential of complex number\n const e = Math.exp(x);\n return COMPLEX(e * Math.cos(y), e * Math.sin(y), unit)\n}\n\n/**\n * Returns the natural logarithm of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the natural logarithm.\n * @returns\n */\nfunction IMLN(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return exponential of complex number\n return COMPLEX(Math.log(Math.sqrt(x * x + y * y)), Math.atan(y / x), unit)\n}\n\n/**\n * Returns the base-10 logarithm of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the common logarithm.\n * @returns\n */\nfunction IMLOG10(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return exponential of complex number\n return COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(10), Math.atan(y / x) / Math.log(10), unit)\n}\n\n/**\n * Returns the base-2 logarithm of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the base-2 logarithm.\n * @returns\n */\nfunction IMLOG2(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return exponential of complex number\n return COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(2), Math.atan(y / x) / Math.log(2), unit)\n}\n\n/**\n * Returns a complex number raised to an integer power.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number you want to raise to a power.\n * @param {*} number The power to which you want to raise the complex number.\n * @returns\n */\nfunction IMPOWER(inumber, number) {\n number = parseNumber(number);\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(number, x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Calculate power of modulus\n const p = Math.pow(IMABS(inumber), number);\n\n // Calculate argument\n const t = IMARGUMENT(inumber);\n\n // Return exponential of complex number\n return COMPLEX(p * Math.cos(number * t), p * Math.sin(number * t), unit)\n}\n\n/**\n * Returns the product of complex numbers.\n *\n * Category: Engineering\n *\n * @param {*} args inumber1, [inumber2], … Inumber1 is required, subsequent inumbers are not. 1 to 255 complex numbers to multiply.\n * @returns\n */\nfunction IMPRODUCT() {\n // Initialize result\n let result = arguments[0];\n\n if (!arguments.length) {\n return value\n }\n\n // Loop on all numbers\n for (let i = 1; i < arguments.length; i++) {\n // Lookup coefficients of two complex numbers\n const a = IMREAL(result);\n const b = IMAGINARY(result);\n const c = IMREAL(arguments[i]);\n const d = IMAGINARY(arguments[i]);\n\n if (anyIsError(a, b, c, d)) {\n return value\n }\n\n // Complute product of two complex numbers\n result = COMPLEX(a * c - b * d, a * d + b * c);\n }\n\n // Return product of complex numbers\n return result\n}\n\n/**\n * Returns the real coefficient of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the real coefficient.\n * @returns\n */\nfunction IMREAL(inumber) {\n if (inumber === undefined || inumber === true || inumber === false) {\n return value\n }\n\n // Return 0 if inumber is equal to 0\n if (inumber === 0 || inumber === '0') {\n return 0\n }\n\n // Handle special cases\n if (['i', '+i', '1i', '+1i', '-i', '-1i', 'j', '+j', '1j', '+1j', '-j', '-1j'].indexOf(inumber) >= 0) {\n return 0\n }\n\n // Force String type\n inumber = inumber + '';\n\n // Lookup sign\n let plus = inumber.indexOf('+');\n let minus = inumber.indexOf('-');\n\n if (plus === 0) {\n plus = inumber.indexOf('+', 1);\n }\n\n if (minus === 0) {\n minus = inumber.indexOf('-', 1);\n }\n\n // Lookup imaginary unit\n const last = inumber.substring(inumber.length - 1, inumber.length);\n const unit = last === 'i' || last === 'j';\n\n if (plus >= 0 || minus >= 0) {\n // Return error if imaginary unit is neither i nor j\n if (!unit) {\n return num\n }\n\n // Return real coefficient of complex number\n if (plus >= 0) {\n return isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))\n ? num\n : Number(inumber.substring(0, plus))\n } else {\n return isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))\n ? num\n : Number(inumber.substring(0, minus))\n }\n } else {\n if (unit) {\n return isNaN(inumber.substring(0, inumber.length - 1)) ? num : 0\n } else {\n return isNaN(inumber) ? num : inumber\n }\n }\n}\n\n/**\n * Returns the secant of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the secant.\n * @returns\n */\nfunction IMSEC(inumber) {\n // Return error if inumber is a logical value\n if (inumber === true || inumber === false) {\n return value\n }\n\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Return secant of complex number\n return IMDIV('1', IMCOS(inumber))\n}\n\n/**\n * Returns the hyperbolic secant of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the hyperbolic secant.\n * @returns\n */\nfunction IMSECH(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Return hyperbolic secant of complex number\n return IMDIV('1', IMCOSH(inumber))\n}\n\n/**\n * Returns the sine of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the sine.\n * @returns\n */\nfunction IMSIN(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return sine of complex number\n return COMPLEX(\n (Math.sin(x) * (Math.exp(y) + Math.exp(-y))) / 2,\n (Math.cos(x) * (Math.exp(y) - Math.exp(-y))) / 2,\n unit\n )\n}\n\n/**\n * Returns the hyperbolic sine of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the hyperbolic sine.\n * @returns\n */\nfunction IMSINH(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Return hyperbolic sine of complex number\n return COMPLEX(\n (Math.cos(y) * (Math.exp(x) - Math.exp(-x))) / 2,\n (Math.sin(y) * (Math.exp(x) + Math.exp(-x))) / 2,\n unit\n )\n}\n\n/**\n * Returns the square root of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the square root.\n * @returns\n */\nfunction IMSQRT(inumber) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Lookup imaginary unit\n let unit = inumber.substring(inumber.length - 1);\n unit = unit === 'i' || unit === 'j' ? unit : 'i';\n\n // Calculate power of modulus\n const s = Math.sqrt(IMABS(inumber));\n\n // Calculate argument\n const t = IMARGUMENT(inumber);\n\n // Return exponential of complex number\n return COMPLEX(s * Math.cos(t / 2), s * Math.sin(t / 2), unit)\n}\n\n/**\n * Returns the cosecant of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the cosecant.\n * @returns\n */\nfunction IMCSC(inumber) {\n // Return error if inumber is a logical value\n if (inumber === true || inumber === false) {\n return value\n }\n\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n // Return error if either coefficient is not a number\n if (anyIsError(x, y)) {\n return num\n }\n\n // Return cosecant of complex number\n return IMDIV('1', IMSIN(inumber))\n}\n\n/**\n * Returns the hyperbolic cosecant of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the hyperbolic cosecant.\n * @returns\n */\nfunction IMCSCH(inumber) {\n // Return error if inumber is a logical value\n if (inumber === true || inumber === false) {\n return value\n }\n\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n // Return error if either coefficient is not a number\n if (anyIsError(x, y)) {\n return num\n }\n\n // Return hyperbolic cosecant of complex number\n return IMDIV('1', IMSINH(inumber))\n}\n\n/**\n * Returns the difference between two complex numbers.\n *\n * Category: Engineering\n *\n * @param {*} inumber1 The complex number from which to subtract inumber2.\n * @param {*} inumber2 The complex number to subtract from inumber1.\n * @returns\n */\nfunction IMSUB(inumber1, inumber2) {\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const a = IMREAL(inumber1);\n const b = IMAGINARY(inumber1);\n const c = IMREAL(inumber2);\n const d = IMAGINARY(inumber2);\n\n if (anyIsError(a, b, c, d)) {\n return value\n }\n\n // Lookup imaginary unit\n const unit1 = inumber1.substring(inumber1.length - 1);\n const unit2 = inumber2.substring(inumber2.length - 1);\n let unit = 'i';\n\n if (unit1 === 'j') {\n unit = 'j';\n } else if (unit2 === 'j') {\n unit = 'j';\n }\n\n // Return _ of two complex numbers\n return COMPLEX(a - c, b - d, unit)\n}\n\n/**\n * Returns the sum of complex numbers.\n *\n * Category: Engineering\n *\n * @param {*} args inumber1, [inumber2], ... Inumber1 is required, subsequent numbers are not. 1 to 255 complex numbers to add.\n * @returns\n */\nfunction IMSUM() {\n if (!arguments.length) {\n return value\n }\n\n const args = flatten(arguments);\n\n // Initialize result\n let result = args[0];\n\n // Loop on all numbers\n for (let i = 1; i < args.length; i++) {\n // Lookup coefficients of two complex numbers\n const a = IMREAL(result);\n const b = IMAGINARY(result);\n const c = IMREAL(args[i]);\n const d = IMAGINARY(args[i]);\n\n if (anyIsError(a, b, c, d)) {\n return value\n }\n\n // Complute product of two complex numbers\n result = COMPLEX(a + c, b + d);\n }\n\n // Return sum of complex numbers\n return result\n}\n\n/**\n * Returns the tangent of a complex number.\n *\n * Category: Engineering\n *\n * @param {*} inumber A complex number for which you want the tangent.\n * @returns\n */\nfunction IMTAN(inumber) {\n // Return error if inumber is a logical value\n if (inumber === true || inumber === false) {\n return value\n }\n\n // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]\n const x = IMREAL(inumber);\n const y = IMAGINARY(inumber);\n\n if (anyIsError(x, y)) {\n return value\n }\n\n // Return tangent of complex number\n return IMDIV(IMSIN(inumber), IMCOS(inumber))\n}\n\n/**\n * Converts an octal number to binary.\n *\n * Category: Engineering\n *\n * @param {*} number The octal number you want to convert. Number may not contain more than 10 characters. The most significant bit of number is the sign bit. The remaining 29 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, OCT2BIN uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction OCT2BIN(number, places) {\n // Return error if number is not hexadecimal or contains more than ten characters (10 digits)\n if (!/^[0-7]{1,10}$/.test(number)) {\n return num\n }\n\n // Check if number is negative\n const negative = !!(number.length === 10 && number.substring(0, 1) === '7');\n\n // Convert octal number to decimal\n const decimal = negative ? parseInt(number, 8) - 1073741824 : parseInt(number, 8);\n\n // Return error if number is lower than -512 or greater than 511\n if (decimal < -512 || decimal > 511) {\n return num\n }\n\n // Ignore places and return a 10-character binary number if number is negative\n if (negative) {\n return '1' + REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2)\n }\n\n // Convert decimal number to binary\n const result = decimal.toString(2);\n\n // Return binary number using the minimum number of characters necessary if places is undefined\n if (typeof places === 'undefined') {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\n/**\n * Converts an octal number to decimal.\n *\n * Category: Engineering\n *\n * @param {*} number The octal number you want to convert. Number may not contain more than 10 octal characters (30 bits). The most significant bit of number is the sign bit. The remaining 29 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @returns\n */\nfunction OCT2DEC(number) {\n // Return error if number is not octal or contains more than ten characters (10 digits)\n if (!/^[0-7]{1,10}$/.test(number)) {\n return num\n }\n\n // Convert octal number to decimal\n const decimal = parseInt(number, 8);\n\n // Return decimal number\n return decimal >= 536870912 ? decimal - 1073741824 : decimal\n}\n\n/**\n * Converts an octal number to hexadecimal.\n *\n * Category: Engineering\n *\n * @param {*} number The octal number you want to convert. Number may not contain more than 10 octal characters (30 bits). The most significant bit of number is the sign bit. The remaining 29 bits are magnitude bits. Negative numbers are represented using two's-complement notation.\n * @param {*} places Optional. The number of characters to use. If places is omitted, OCT2HEX uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).\n * @returns\n */\nfunction OCT2HEX(number, places) {\n // Return error if number is not octal or contains more than ten characters (10 digits)\n if (!/^[0-7]{1,10}$/.test(number)) {\n return num\n }\n\n // Convert octal number to decimal\n const decimal = parseInt(number, 8);\n\n // Ignore places and return a 10-character octal number if number is negative\n if (decimal >= 536870912) {\n return 'ff' + (decimal + 3221225472).toString(16)\n }\n\n // Convert decimal number to hexadecimal\n const result = decimal.toString(16);\n\n // Return hexadecimal number using the minimum number of characters necessary if places is undefined\n if (places === undefined) {\n return result\n } else {\n // Return error if places is nonnumeric\n if (isNaN(places)) {\n return value\n }\n\n // Return error if places is negative\n if (places < 0) {\n return num\n }\n\n // Truncate places in case it is not an integer\n places = Math.floor(places);\n\n // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)\n return places >= result.length ? REPT('0', places - result.length) + result : num\n }\n}\n\nconst BETADIST = BETA.DIST;\nconst BETAINV = BETA.INV;\nconst BINOMDIST = BINOM.DIST;\nconst CEILINGMATH = CEILING.MATH;\nconst CEILINGPRECISE = CEILING.PRECISE;\nconst CHIDIST = CHISQ.DIST;\nconst CHIDISTRT = CHISQ.DIST.RT;\nconst CHIINV = CHISQ.INV;\nconst CHIINVRT = CHISQ.INV.RT;\nconst CHITEST = CHISQ.TEST;\nconst COVAR = COVARIANCE.P;\nconst COVARIANCEP = COVARIANCE.P;\nconst COVARIANCES = COVARIANCE.S;\nconst CRITBINOM = BINOM.INV;\nconst ERFCPRECISE = ERFC.PRECISE;\nconst ERFPRECISE = ERF.PRECISE;\nconst EXPONDIST = EXPON.DIST;\nconst FDIST = F.DIST;\nconst FDISTRT = F.DIST.RT;\nconst FINV = F.INV;\nconst FINVRT = F.INV.RT;\nconst FLOORMATH = FLOOR.MATH;\nconst FLOORPRECISE = FLOOR.PRECISE;\nconst FTEST = F.TEST;\nconst GAMMADIST = GAMMA.DIST;\nconst GAMMAINV = GAMMA.INV;\nconst GAMMALNPRECISE = GAMMALN.PRECISE;\nconst HYPGEOMDIST = HYPGEOM.DIST;\nconst LOGINV = LOGNORM.INV;\nconst LOGNORMDIST = LOGNORM.DIST;\nconst LOGNORMINV = LOGNORM.INV;\nconst MODEMULT = MODE.MULT;\nconst MODESNGL = MODE.SNGL;\nconst NEGBINOMDIST = NEGBINOM.DIST;\nconst NETWORKDAYSINTL = NETWORKDAYS.INTL;\nconst NORMDIST = NORM.DIST;\nconst NORMINV = NORM.INV;\nconst NORMSDIST = NORM.S.DIST;\nconst NORMSINV = NORM.S.INV;\nconst PERCENTILEEXC = PERCENTILE.EXC;\nconst PERCENTILEINC = PERCENTILE.INC;\nconst PERCENTRANKEXC = PERCENTRANK.EXC;\nconst PERCENTRANKINC = PERCENTRANK.INC;\nconst POISSONDIST = POISSON.DIST;\nconst QUARTILEEXC = QUARTILE.EXC;\nconst QUARTILEINC = QUARTILE.INC;\nconst RANKAVG = RANK.AVG;\nconst RANKEQ = RANK.EQ;\nconst SKEWP = SKEW.P;\nconst STDEVP = STDEV.P;\nconst STDEVS = STDEV.S;\nconst TDIST = T.DIST;\nconst TDISTRT = T.DIST.RT;\nconst TINV = T.INV;\nconst TTEST = T.TEST;\nconst VARP = VAR.P;\nconst VARS = VAR.S;\nconst WEIBULLDIST = WEIBULL.DIST;\nconst WORKDAYINTL = WORKDAY.INTL;\nconst ZTEST = Z.TEST;\n\nfunction compact(array) {\n const result = [];\n\n arrayEach(array, (value) => {\n if (value) {\n result.push(value);\n }\n });\n\n return result\n}\n\nfunction findResultIndex(database, criterias) {\n const matches = {};\n\n for (let i = 1; i < database[0].length; ++i) {\n matches[i] = true;\n }\n\n let maxCriteriaLength = criterias[0].length;\n\n for (let i = 1; i < criterias.length; ++i) {\n if (criterias[i].length > maxCriteriaLength) {\n maxCriteriaLength = criterias[i].length;\n }\n }\n\n for (let k = 1; k < database.length; ++k) {\n for (let l = 1; l < database[k].length; ++l) {\n let currentCriteriaResult = false;\n let hasMatchingCriteria = false;\n\n for (let j = 0; j < criterias.length; ++j) {\n const criteria = criterias[j];\n\n if (criteria.length < maxCriteriaLength) {\n continue\n }\n\n const criteriaField = criteria[0];\n\n if (database[k][0] !== criteriaField) {\n continue\n }\n\n hasMatchingCriteria = true;\n\n for (let p = 1; p < criteria.length; ++p) {\n if (!currentCriteriaResult) {\n const isWildcard = criteria[p] === void 0 || criteria[p] === '*';\n\n if (isWildcard) {\n currentCriteriaResult = true;\n } else {\n const tokenizedCriteria = parse(criteria[p] + '');\n const tokens = [createToken(database[k][l], TOKEN_TYPE_LITERAL)].concat(\n tokenizedCriteria\n );\n\n currentCriteriaResult = compute(tokens);\n }\n }\n }\n }\n\n if (hasMatchingCriteria) {\n matches[l] = matches[l] && currentCriteriaResult;\n }\n }\n }\n\n const result = [];\n\n for (let n = 0; n < database[0].length; ++n) {\n if (matches[n]) {\n result.push(n - 1);\n }\n }\n\n return result\n}\n\n// Database functions\n/**\n * Returns the average of selected database entries.\n *\n * Category: Database\n *\n * @param {*} database Range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria Range of values that contains the conditions you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DAVERAGE(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n let sum = 0;\n\n arrayEach(resultIndexes, (value) => {\n sum += targetFields[value];\n });\n\n return resultIndexes.length === 0 ? div0 : sum / resultIndexes.length\n}\n\n/**\n * Counts the values that contain numbers in a database.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as the argument includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DCOUNT(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n const targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n return COUNT(targetValues)\n}\n\n/**\n * Counts nonblank values in a database.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Optional. Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DCOUNTA(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n const targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n return COUNTA(targetValues)\n}\n\n/**\n * Extracts from a database a single record that matches the specified criteria.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DGET(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n // Return error if no record meets the criteria\n if (resultIndexes.length === 0) {\n return value\n }\n // Returns the #NUM! error value because more than one record meets the\n // criteria\n if (resultIndexes.length > 1) {\n return num\n }\n\n return targetFields[resultIndexes[0]]\n}\n\n/**\n * Returns the maximum value from selected database entries.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DMAX(database, field, criteria) {\n // Return error if field is not a number and not a string\n\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n let maxValue = targetFields[resultIndexes[0]];\n\n arrayEach(resultIndexes, (value) => {\n if (maxValue < targetFields[value]) {\n maxValue = targetFields[value];\n }\n });\n\n return maxValue\n}\n\n/**\n * Returns the minimum value from selected database entries.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DMIN(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n let minValue = targetFields[resultIndexes[0]];\n\n arrayEach(resultIndexes, (value) => {\n if (minValue > targetFields[value]) {\n minValue = targetFields[value];\n }\n });\n\n return minValue\n}\n\n/**\n * Multiplies the values in a particular field of records that match the criteria in a database.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DPRODUCT(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n let targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n targetValues = compact(targetValues);\n\n let result = 1;\n\n arrayEach(targetValues, (value) => {\n result *= value;\n });\n\n return result\n}\n\n/**\n * Estimates the standard deviation based on a sample of selected database entries.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DSTDEV(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n let targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n targetValues = compact(targetValues);\n\n return STDEV.S(targetValues)\n}\n\n/**\n * Calculates the standard deviation based on the entire population of selected database entries.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DSTDEVP(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n let targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n targetValues = compact(targetValues);\n\n return STDEV.P(targetValues)\n}\n\n/**\n * Adds the numbers in the field column of records in the database that match the criteria.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria Is the range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DSUM(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n const targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n return SUM(targetValues)\n}\n\n/**\n * Estimates variance based on a sample from selected database entries.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DVAR(database, field, criteria) {\n // Return error if field is not a number and not a string\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n const targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n return VAR.S(targetValues)\n}\n\n/**\n * Calculates variance based on the entire population of selected database entries.\n *\n * Category: Database\n *\n * @param {*} database The range of values that makes up the list or database. A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column.\n * @param {*} field Indicates which column is used in the function. Enter the column label enclosed between double quotation marks, such as \"Age\" or \"Yield,\" or a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on.\n * @param {*} criteria The range of values that contains the conditions that you specify. You can use any range for the criteria argument, as long as it includes at least one column label and at least one value below the column label in which you specify a condition for the column.\n * @returns\n */\nfunction DVARP(database, field, criteria) {\n // Return error if field is not a number and not a string\n\n if (isNaN(field) && typeof field !== 'string') {\n return value\n }\n\n const resultIndexes = findResultIndex(database, criteria);\n let targetFields = [];\n\n if (typeof field === 'string') {\n const index = findField(database, field);\n targetFields = rest(database[index]);\n } else {\n targetFields = rest(database[field]);\n }\n\n const targetValues = [];\n\n arrayEach(resultIndexes, (value) => {\n targetValues.push(targetFields[value]);\n });\n\n return VAR.P(targetValues)\n}\n\nfunction validDate(d) {\n return d && d.getTime && !isNaN(d.getTime())\n}\n\nfunction ensureDate(d) {\n return d instanceof Date ? d : new Date(d)\n}\n\n// Calculate last coupon date before settlement\nfunction lastCoupDateBeforeSettlement(settlement, maturity, frequency) {\n let date = parseDate(maturity);\n date.setFullYear(settlement.getFullYear());\n\n if (date < settlement) {\n date.setFullYear(date.getFullYear() + 1);\n }\n\n // Adjust the date based on the coupon frequency until date is later than settlement\n while (date > settlement) {\n date.setMonth(date.getMonth() + -12 / frequency);\n }\n\n return date\n}\n\nfunction validateFrequency(frequency) {\n frequency = parseNumber(frequency);\n\n // Return error if frequency is neither 1, 2, or 4\n if ([1, 2, 4].indexOf(frequency) === -1) {\n return num\n }\n\n return frequency\n}\n\nfunction validateBasis(basis) {\n basis = parseNumber(basis);\n\n // Return error if basis is neither 0, 1, 2, 3, or 4\n if ([0, 1, 2, 3, 4].indexOf(basis) === -1) {\n return num\n }\n\n return basis\n}\n\n/**\n * Returns the accrued interest for a security that pays periodic interest.\n *\n * Category: Financial\n *\n * @param {*} issue The security's issue date.\n * @param {*} first_interest The security's first interest date.\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} rate The security's annual coupon rate.\n * @param {*} par The security's par value. If you omit par, ACCRINT uses $1,000.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @param {*} calc_method Optional. Not implemented in formulajs. A logical value that specifies the way to calculate the total accrued interest when the date of settlement is later than the date of first_interest. A value of TRUE (1) returns the total accrued interest from issue to settlement. A value of FALSE (0) returns the accrued interest from first_interest to settlement. If you do not enter the argument, it defaults to TRUE.\n * @returns\n */\nfunction ACCRINT(issue, first_interest, settlement, rate, par, frequency, basis) {\n // Return error if either date is invalid\n issue = ensureDate(issue);\n first_interest = ensureDate(first_interest);\n settlement = ensureDate(settlement);\n frequency = validateFrequency(frequency);\n basis = validateBasis(basis);\n\n if (anyError(frequency, basis)) {\n return num\n }\n\n if (!validDate(issue) || !validDate(first_interest) || !validDate(settlement)) {\n return value\n }\n\n // Return error if either rate or par are lower than or equal to zero\n if (rate <= 0 || par <= 0) {\n return num\n }\n\n // Return error if settlement is before or equal to issue\n if (settlement <= issue) {\n return num\n }\n\n // Set default values\n par = par || 0;\n basis = basis || 0;\n\n // Compute accrued interest\n return par * rate * YEARFRAC(issue, settlement, basis)\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the accrued interest for a security that pays interest at maturity.\n *\n * Category: Financial\n *\n * @param {*} issue The security's issue date.\n * @param {*} settlement The security's maturity date.\n * @param {*} rate The security's annual coupon rate.\n * @param {*} par The security's par value. If you omit par, ACCRINTM uses $1,000.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction ACCRINTM() {\n throw new Error('ACCRINTM is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the depreciation for each accounting period by using a depreciation coefficient.\n *\n * Category: Financial\n *\n * @param {*} cost The cost of the asset.\n * @param {*} date_purchased The date of the purchase of the asset.\n * @param {*} first_period The date of the end of the first period.\n * @param {*} salvage The salvage value at the end of the life of the asset.\n * @param {*} period The period.\n * @param {*} rate The rate of depreciation.\n * @param {*} basis Optional. The year basis to be used.\n * @returns\n */\nfunction AMORDEGRC() {\n throw new Error('AMORDEGRC is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the depreciation for each accounting period.\n *\n * Category: Financial\n *\n * @param {*} cost The cost of the asset.\n * @param {*} date_purchased The date of the purchase of the asset.\n * @param {*} first_period The date of the end of the first period.\n * @param {*} salvage The salvage value at the end of the life of the asset.\n * @param {*} period The period.\n * @param {*} rate The rate of depreciation.\n * @param {*} basis Optional. The year basis to be used.\n * @returns\n */\nfunction AMORLINC() {\n throw new Error('AMORLINC is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the number of days from the beginning of the coupon period to the settlement date.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction COUPDAYBS() {\n throw new Error('COUPDAYBS is not implemented')\n}\n\n/**\n *\n * Returns the number of days in the coupon period that contains the settlement date.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction COUPDAYS(settlement, maturity, frequency, basis) {\n basis = validateBasis(basis);\n frequency = validateFrequency(frequency);\n settlement = parseDate(settlement);\n maturity = parseDate(maturity);\n\n if (anyError(settlement, maturity)) {\n return value\n }\n\n if (anyError(frequency, basis) || settlement >= maturity) {\n return num\n }\n\n if (basis === 1) {\n let date = lastCoupDateBeforeSettlement(settlement, maturity, frequency);\n let nextDate = parseDate(date);\n\n // Set month of the nextDate to the next coupon month\n nextDate.setMonth(nextDate.getMonth() + 12 / frequency);\n\n return DATEDIF(date, nextDate, 'D')\n }\n\n let numOfDays;\n\n switch (basis) {\n case 0:\n case 2:\n case 4:\n numOfDays = 360;\n break\n case 3:\n numOfDays = 365;\n break\n default:\n return num\n }\n\n return numOfDays / frequency\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the number of days from the settlement date to the next coupon date.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction COUPDAYSNC() {\n throw new Error('COUPDAYSNC is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the next coupon date after the settlement date.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction COUPNCD() {\n throw new Error('COUPNCD is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the number of coupons payable between the settlement date and maturity date.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction COUPNUM() {\n throw new Error('COUPNUM is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the previous coupon date before the settlement date.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction COUPPCD() {\n throw new Error('COUPPCD is not implemented')\n}\n\n/**\n * Returns the cumulative interest paid between two periods.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate.\n * @param {*} nper The total number of payment periods.\n * @param {*} pv The present value.\n * @param {*} start_period The first period in the calculation. Payment periods are numbered beginning with 1.\n * @param {*} end_period The last period in the calculation.\n * @param {*} type The timing of the payment.\n * @returns\n */\nfunction CUMIPMT(rate, nper, pv, start_period, end_period, type) {\n rate = parseNumber(rate);\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n\n if (anyIsError(rate, nper, pv)) {\n return value\n }\n\n if (rate <= 0 || nper <= 0 || pv <= 0) {\n return num\n }\n\n if (start_period < 1 || end_period < 1 || start_period > end_period) {\n return num\n }\n\n if (type !== 0 && type !== 1) {\n return num\n }\n\n const payment = PMT(rate, nper, pv, 0, type);\n let interest = 0;\n\n if (start_period === 1) {\n if (type === 0) {\n interest = -pv;\n }\n\n start_period++;\n }\n\n for (let i = start_period; i <= end_period; i++) {\n interest += type === 1 ? FV(rate, i - 2, payment, pv, 1) - payment : FV(rate, i - 1, payment, pv, 0);\n }\n\n interest *= rate;\n\n return interest\n}\n\n/**\n * Returns the cumulative principal paid on a loan between two periods.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate.\n * @param {*} nper The total number of payment periods.\n * @param {*} pv The present value.\n * @param {*} start_period The first period in the calculation. Payment periods are numbered beginning with 1.\n * @param {*} end_period The last period in the calculation.\n * @param {*} type The timing of the payment.\n * @returns\n */\nfunction CUMPRINC(rate, nper, pv, start_period, end, type) {\n // Credits: algorithm inspired by Apache OpenOffice\n // Credits: Hannes Stiebitzhofer for the translations of function and variable names\n rate = parseNumber(rate);\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n\n if (anyIsError(rate, nper, pv)) {\n return value\n }\n\n // Return error if either rate, nper, or value are lower than or equal to zero\n if (rate <= 0 || nper <= 0 || pv <= 0) {\n return num\n }\n\n // Return error if start < 1, end < 1, or start > end\n if (start_period < 1 || end < 1 || start_period > end) {\n return num\n }\n\n // Return error if type is neither 0 nor 1\n if (type !== 0 && type !== 1) {\n return num\n }\n\n // Compute cumulative principal\n const payment = PMT(rate, nper, pv, 0, type);\n let principal = 0;\n\n if (start_period === 1) {\n principal = type === 0 ? payment + pv * rate : payment;\n\n start_period++;\n }\n\n for (let i = start_period; i <= end; i++) {\n principal +=\n type > 0\n ? payment - (FV(rate, i - 2, payment, pv, 1) - payment) * rate\n : payment - FV(rate, i - 1, payment, pv, 0) * rate;\n }\n\n // Return cumulative principal\n return principal\n}\n\n/**\n * Returns the depreciation of an asset for a specified period by using the fixed-declining balance method.\n *\n * Category: Financial\n *\n * @param {*} cost The initial cost of the asset.\n * @param {*} salvage The value at the end of the depreciation (sometimes called the salvage value of the asset).\n * @param {*} life The number of periods over which the asset is being depreciated (sometimes called the useful life of the asset).\n * @param {*} period The period for which you want to calculate the depreciation. Period must use the same units as life.\n * @param {*} month Optional. The number of months in the first year. If month is omitted, it is assumed to be 12.\n * @returns\n */\nfunction DB(cost, salvage, life, period, month) {\n // Initialize month\n month = month === undefined ? 12 : month;\n\n cost = parseNumber(cost);\n salvage = parseNumber(salvage);\n life = parseNumber(life);\n period = parseNumber(period);\n month = parseNumber(month);\n\n if (anyIsError(cost, salvage, life, period, month)) {\n return value\n }\n\n // Return error if any of the parameters is negative\n if (cost < 0 || salvage < 0 || life < 0 || period < 0) {\n return num\n }\n\n // Return error if month is not an integer between 1 and 12\n if ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].indexOf(month) === -1) {\n return num\n }\n\n // Return error if period is greater than life\n if (period > life) {\n return num\n }\n\n // Return 0 (zero) if salvage is greater than or equal to cost\n if (salvage >= cost) {\n return 0\n }\n\n // Rate is rounded to three decimals places\n const rate = (1 - Math.pow(salvage / cost, 1 / life)).toFixed(3);\n\n // Compute initial depreciation\n const initial = (cost * rate * month) / 12;\n\n // Compute total depreciation\n let total = initial;\n let current = 0;\n const ceiling = period === life ? life - 1 : period;\n\n for (let i = 2; i <= ceiling; i++) {\n current = (cost - total) * rate;\n total += current;\n }\n\n // Depreciation for the first and last periods are special cases\n if (period === 1) {\n // First period\n return initial\n } else if (period === life) {\n // Last period\n\n return (cost - total) * rate\n } else {\n return current\n }\n}\n\n/**\n * Returns the depreciation of an asset for a specified period by using the double-declining balance method or some other method that you specify.\n *\n * Category: Financial\n *\n * @param {*} cost The initial cost of the asset.\n * @param {*} salvage The value at the end of the depreciation (sometimes called the salvage value of the asset). This value can be 0.\n * @param {*} life The number of periods over which the asset is being depreciated (sometimes called the useful life of the asset).\n * @param {*} period The period for which you want to calculate the depreciation. Period must use the same units as life.\n * @param {*} factor Optional. The rate at which the balance declines. If factor is omitted, it is assumed to be 2 (the double-declining balance method).\n * @returns\n */\nfunction DDB(cost, salvage, life, period, factor) {\n // Initialize factor\n factor = factor === undefined ? 2 : factor;\n\n cost = parseNumber(cost);\n salvage = parseNumber(salvage);\n life = parseNumber(life);\n period = parseNumber(period);\n factor = parseNumber(factor);\n\n if (anyIsError(cost, salvage, life, period, factor)) {\n return value\n }\n\n // Return error if any of the parameters is negative or if factor is null\n if (cost < 0 || salvage < 0 || life < 0 || period < 0 || factor <= 0) {\n return num\n }\n\n // Return error if period is greater than life\n if (period > life) {\n return num\n }\n\n // Return 0 (zero) if salvage is greater than or equal to cost\n if (salvage >= cost) {\n return 0\n }\n\n // Compute depreciation\n let total = 0;\n let current = 0;\n\n for (let i = 1; i <= period; i++) {\n current = Math.min((cost - total) * (factor / life), cost - salvage - total);\n total += current;\n }\n\n // Return depreciation\n return current\n}\n\n/**\n * Returns the discount rate for a security.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} pr The security's price per $100 face value.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction DISC(settlement, maturity, pr, redemption, basis) {\n settlement = parseDate(settlement);\n maturity = parseDate(maturity);\n pr = parseNumber(pr);\n redemption = parseNumber(redemption);\n basis = parseNumber(basis);\n\n basis = basis || 0;\n\n if (anyIsError(settlement, maturity, pr, redemption, basis)) {\n return value\n }\n\n if (pr <= 0 || redemption <= 0) {\n return num\n }\n\n if (settlement >= maturity) {\n return value\n }\n\n let basisVal, diff;\n switch (basis) {\n case 0:\n basisVal = 360;\n diff = DAYS360(settlement, maturity, false);\n break\n case 1:\n basisVal = 365;\n diff = DATEDIF(settlement, maturity, 'D');\n break\n case 2:\n basisVal = 360;\n diff = DATEDIF(settlement, maturity, 'D');\n break\n case 3:\n basisVal = 365;\n diff = DATEDIF(settlement, maturity, 'D');\n break\n case 4:\n basisVal = 360;\n diff = DAYS360(settlement, maturity, true);\n break\n default:\n return num\n }\n\n return (((redemption - pr) / redemption) * basisVal) / diff\n}\n\n/**\n * Converts a dollar price, expressed as a fraction, into a dollar price, expressed as a decimal number.\n *\n * Category: Financial\n *\n * @param {*} fractional_dollar A number expressed as an integer part and a fraction part, separated by a decimal symbol.\n * @param {*} fraction The integer to use in the denominator of the fraction.\n * @returns\n */\nfunction DOLLARDE(fractional_dollar, fraction) {\n // Credits: algorithm inspired by Apache OpenOffice\n fractional_dollar = parseNumber(fractional_dollar);\n fraction = parseNumber(fraction);\n\n if (anyIsError(fractional_dollar, fraction)) {\n return value\n }\n\n // Return error if fraction is negative\n if (fraction < 0) {\n return num\n }\n\n // Return error if fraction is greater than or equal to 0 and less than 1\n if (fraction >= 0 && fraction < 1) {\n return div0\n }\n\n // Truncate fraction if it is not an integer\n fraction = parseInt(fraction, 10);\n\n // Compute integer part\n let result = parseInt(fractional_dollar, 10);\n\n // Add decimal part\n result += ((fractional_dollar % 1) * Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN10))) / fraction;\n\n // Round result\n const power = Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN2) + 1);\n result = Math.round(result * power) / power;\n\n // Return converted dollar price\n return result\n}\n\n/**\n * Converts a dollar price, expressed as a decimal number, into a dollar price, expressed as a fraction.\n *\n * Category: Financial\n *\n * @param {*} decimal_dollar A decimal number.\n * @param {*} fraction The integer to use in the denominator of a fraction.\n * @returns\n */\nfunction DOLLARFR(decimal_dollar, fraction) {\n // Credits: algorithm inspired by Apache OpenOffice\n decimal_dollar = parseNumber(decimal_dollar);\n fraction = parseNumber(fraction);\n\n if (anyIsError(decimal_dollar, fraction)) {\n return value\n }\n\n // Return error if fraction is negative\n if (fraction < 0) {\n return num\n }\n\n // Return error if fraction is greater than or equal to 0 and less than 1\n if (fraction >= 0 && fraction < 1) {\n return div0\n }\n\n // Truncate fraction if it is not an integer\n fraction = parseInt(fraction, 10);\n\n // Compute integer part\n let result = parseInt(decimal_dollar, 10);\n\n // Add decimal part\n result += (decimal_dollar % 1) * Math.pow(10, -Math.ceil(Math.log(fraction) / Math.LN10)) * fraction;\n\n // Return converted dollar price\n return result\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the annual duration of a security with periodic interest payments.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} coupon The security's annual coupon rate.\n * @param {*} yld The security's annual yield.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction DURATION() {\n throw new Error('DURATION is not implemented')\n}\n\n/**\n * Returns the effective annual interest rate.\n *\n * Category: Financial\n *\n * @param {*} nominal_rate The nominal interest rate.\n * @param {*} npery The number of compounding periods per year.\n * @returns\n */\nfunction EFFECT(nominal_rate, npery) {\n nominal_rate = parseNumber(nominal_rate);\n npery = parseNumber(npery);\n\n if (anyIsError(nominal_rate, npery)) {\n return value\n }\n\n // Return error if rate <=0 or periods < 1\n if (nominal_rate <= 0 || npery < 1) {\n return num\n }\n\n // Truncate periods if it is not an integer\n npery = parseInt(npery, 10);\n\n // Return effective annual interest rate\n return Math.pow(1 + nominal_rate / npery, npery) - 1\n}\n\n/**\n * Returns the future value of an investment.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate per period.\n * @param {*} nper The total number of payment periods in an annuity.\n * @param {*} pmt The payment made each period; it cannot change over the life of the annuity. Typically, pmt contains principal and interest but no other fees or taxes. If pmt is omitted, you must include the pv argument.\n * @param {*} pv Optional. The present value, or the lump-sum amount that a series of future payments is worth right now. If pv is omitted, it is assumed to be 0 (zero), and you must include the pmt argument.\n * @param {*} type Optional. The number 0 or 1 and indicates when payments are due. If type is omitted, it is assumed to be 0.\n * @returns\n */\nfunction FV(rate, nper, payment, value$1, type) {\n // Credits: algorithm inspired by Apache OpenOffice\n value$1 = value$1 || 0;\n type = type || 0;\n\n rate = parseNumber(rate);\n nper = parseNumber(nper);\n payment = parseNumber(payment);\n value$1 = parseNumber(value$1);\n type = parseNumber(type);\n\n if (anyIsError(rate, nper, payment, value$1, type)) {\n return value\n }\n\n // Return future value\n let result;\n\n if (rate === 0) {\n result = value$1 + payment * nper;\n } else {\n const term = Math.pow(1 + rate, nper);\n\n result =\n type === 1\n ? value$1 * term + (payment * (1 + rate) * (term - 1)) / rate\n : value$1 * term + (payment * (term - 1)) / rate;\n }\n\n return -result\n}\n\n/**\n * Returns the future value of an initial principal after applying a series of compound interest rates.\n *\n * Category: Financial\n *\n * @param {*} principal The present value.\n * @param {*} schedule An array of interest rates to apply.\n * @returns\n */\nfunction FVSCHEDULE(principal, schedule) {\n principal = parseNumber(principal);\n schedule = parseNumberArray(flatten(schedule));\n\n if (anyIsError(principal, schedule)) {\n return value\n }\n\n const n = schedule.length;\n let future = principal;\n\n // Apply all interests in schedule\n\n for (let i = 0; i < n; i++) {\n // Apply scheduled interest\n future *= 1 + schedule[i];\n }\n\n // Return future value\n return future\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the interest rate for a fully invested security.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} investment The amount invested in the security.\n * @param {*} redemption The amount to be received at maturity.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction INTRATE() {\n throw new Error('INTRATE is not implemented')\n}\n\n/**\n * Returns the interest payment for an investment for a given period.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate per period.\n * @param {*} per The period for which you want to find the interest and must be in the range 1 to nper.\n * @param {*} nper The total number of payment periods in an annuity.\n * @param {*} pv The present value, or the lump-sum amount that a series of future payments is worth right now.\n * @param {*} fv Optional. The future value, or a cash balance you want to attain after the last payment is made. If fv is omitted, it is assumed to be 0 (the future value of a loan, for example, is 0).\n * @param {*} type Optional. The number 0 or 1 and indicates when payments are due. If type is omitted, it is assumed to be 0.\n * @returns\n */\nfunction IPMT(rate, per, nper, pv, fv, type) {\n // Credits: algorithm inspired by Apache OpenOffice\n fv = fv || 0;\n type = type || 0;\n\n rate = parseNumber(rate);\n per = parseNumber(per);\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n type = parseNumber(type);\n\n if (anyIsError(rate, per, nper, pv, fv, type)) {\n return value\n }\n\n // Compute payment\n const payment = PMT(rate, nper, pv, fv, type);\n\n // Compute interest\n let interest =\n per === 1\n ? type === 1\n ? 0\n : -pv\n : type === 1\n ? FV(rate, per - 2, payment, pv, 1) - payment\n : FV(rate, per - 1, payment, pv, 0);\n\n // Return interest\n return interest * rate\n}\n\n/**\n * Returns the internal rate of return for a series of cash flows.\n *\n * Category: Financial\n *\n * @param {*} values An array or a reference to values that contain numbers for which you want to calculate the internal rate of return.\n - Values must contain at least one positive value and one negative value to calculate the internal rate of return.\n - IRR uses the order of values to interpret the order of cash flows. Be sure to enter your payment and income values in the sequence you want.\n - If an array or reference argument contains text, logical values, or empty values, those values are ignored.\n * @param {*} guess Optional. A number that you guess is close to the result of IRR.\n - Microsoft Excel uses an iterative technique for calculating IRR. Starting with guess, IRR cycles through the calculation until the result is accurate within 0.00001 percent. If IRR can't find a result that works after 20 tries, the #NUM! error value is returned.\n - In most cases you do not need to provide guess for the IRR calculation. If guess is omitted, it is assumed to be 0.1 (10 percent).\n - If IRR gives the #NUM! error value, or if the result is not close to what you expected, try again with a different value for guess.\n * @returns\n */\nfunction IRR(values, guess) {\n // Credits: algorithm inspired by Apache OpenOffice\n guess = guess || 0;\n\n values = parseNumberArray(flatten(values));\n guess = parseNumber(guess);\n\n if (anyIsError(values, guess)) {\n return value\n }\n\n // Calculates the resulting amount\n const irrResult = (values, dates, rate) => {\n const r = rate + 1;\n let result = values[0];\n\n for (let i = 1; i < values.length; i++) {\n result += values[i] / Math.pow(r, (dates[i] - dates[0]) / 365);\n }\n\n return result\n };\n\n // Calculates the first derivation\n const irrResultDeriv = (values, dates, rate) => {\n const r = rate + 1;\n let result = 0;\n\n for (let i = 1; i < values.length; i++) {\n const frac = (dates[i] - dates[0]) / 365;\n result -= (frac * values[i]) / Math.pow(r, frac + 1);\n }\n\n return result\n };\n\n // Initialize dates and check that values contains at least one positive value and one negative value\n const dates = [];\n let positive = false;\n let negative = false;\n\n for (let i = 0; i < values.length; i++) {\n dates[i] = i === 0 ? 0 : dates[i - 1] + 365;\n\n if (values[i] > 0) {\n positive = true;\n }\n\n if (values[i] < 0) {\n negative = true;\n }\n }\n\n // Return error if values does not contain at least one positive value and one negative value\n if (!positive || !negative) {\n return num\n }\n\n // Initialize guess and resultRate\n guess = guess === undefined ? 0.1 : guess;\n let resultRate = guess;\n\n // Set maximum epsilon for end of iteration\n const epsMax = 1e-10;\n\n // Implement Newton's method\n let newRate, epsRate, resultValue;\n let contLoop = true;\n do {\n resultValue = irrResult(values, dates, resultRate);\n newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate);\n epsRate = Math.abs(newRate - resultRate);\n resultRate = newRate;\n contLoop = epsRate > epsMax && Math.abs(resultValue) > epsMax;\n } while (contLoop)\n\n // Return internal rate of return\n return resultRate\n}\n\n/**\n * Calculates the interest paid during a specific period of an investment.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate for the investment.\n * @param {*} per The period for which you want to find the interest, and must be between 1 and Nper.\n * @param {*} nper The total number of payment periods for the investment.\n * @param {*} pv The present value of the investment. For a loan, Pv is the loan amount.\n *\n * @returns\n */\nfunction ISPMT(rate, per, nper, pv) {\n rate = parseNumber(rate);\n per = parseNumber(per);\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n\n if (anyIsError(rate, per, nper, pv)) {\n return value\n }\n\n // Return interest\n return pv * rate * (per / nper - 1)\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the Macauley modified duration for a security with an assumed par value of $100.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} coupon The security's annual coupon rate.\n * @param {*} yld The security's annual yield.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction MDURATION() {\n throw new Error('MDURATION is not implemented')\n}\n\n/**\n * Returns the internal rate of return where positive and negative cash flows are financed at different rates.\n *\n * Category: Financial\n *\n * @param {*} values An array or a reference to values that contain numbers. These numbers represent a series of payments (negative values) and income (positive values) occurring at regular periods.\n - Values must contain at least one positive value and one negative value to calculate the modified internal rate of return. Otherwise, MIRR returns the #DIV/0! error value.\n - If an array or reference argument contains text, logical values, or empty values, those values are ignored; however, values with the value zero are included.\n * @param {*} finance_rate The interest rate you pay on the money used in the cash flows.\n * @param {*} reinvest_rate The interest rate you receive on the cash flows as you reinvest them.\n * @returns\n */\nfunction MIRR(values, finance_rate, reinvest_rate) {\n values = parseNumberArray(flatten(values));\n finance_rate = parseNumber(finance_rate);\n reinvest_rate = parseNumber(reinvest_rate);\n\n if (anyIsError(values, finance_rate, reinvest_rate)) {\n return value\n }\n\n // Initialize number of values\n const n = values.length;\n\n // Lookup payments (negative values) and incomes (positive values)\n const payments = [];\n const incomes = [];\n\n for (let i = 0; i < n; i++) {\n if (values[i] < 0) {\n payments.push(values[i]);\n } else {\n incomes.push(values[i]);\n }\n }\n\n // Return modified internal rate of return\n const num = -NPV(reinvest_rate, incomes) * Math.pow(1 + reinvest_rate, n - 1);\n const den = NPV(finance_rate, payments) * (1 + finance_rate);\n\n return Math.pow(num / den, 1 / (n - 1)) - 1\n}\n\n/**\n * Returns the annual nominal interest rate.\n *\n * Category: Financial\n *\n * @param {*} effect_rate The effective interest rate.\n * @param {*} npery The number of compounding periods per year.\n * @returns\n */\nfunction NOMINAL(effect_rate, npery) {\n effect_rate = parseNumber(effect_rate);\n npery = parseNumber(npery);\n\n if (anyIsError(effect_rate, npery)) {\n return value\n }\n\n // Return error if rate <=0 or periods < 1\n if (effect_rate <= 0 || npery < 1) {\n return num\n }\n\n // Truncate periods if it is not an integer\n npery = parseInt(npery, 10);\n\n // Return nominal annual interest rate\n return (Math.pow(effect_rate + 1, 1 / npery) - 1) * npery\n}\n\n/**\n * Returns the number of periods for an investment.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate per period.\n * @param {*} pmt The payment made each period; it cannot change over the life of the annuity. Typically, pmt contains principal and interest but no other fees or taxes.\n * @param {*} pv The present value, or the lump-sum amount that a series of future payments is worth right now.\n * @param {*} fv Optional. The future value, or a cash balance you want to attain after the last payment is made. If fv is omitted, it is assumed to be 0 (the future value of a loan, for example, is 0).\n * @param {*} type Optional. The number 0 or 1 and indicates when payments are due.\n * @returns\n */\nfunction NPER(rate, pmt, pv, fv, type) {\n type = type === undefined ? 0 : type;\n fv = fv === undefined ? 0 : fv;\n\n rate = parseNumber(rate);\n pmt = parseNumber(pmt);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n type = parseNumber(type);\n\n if (anyIsError(rate, pmt, pv, fv, type)) {\n return value\n }\n\n if (rate === 0) {\n return -(pv + fv) / pmt\n } else {\n const num = pmt * (1 + rate * type) - fv * rate;\n const den = pv * rate + pmt * (1 + rate * type);\n\n return Math.log(num / den) / Math.log(1 + rate)\n }\n}\n\n/**\n * Returns the net present value of an investment based on a series of periodic cash flows and a discount rate.\n *\n * Category: Financial\n *\n * @param {*} rate The rate of discount over the length of one period.\n * @param {*} args value1, value2, ... Value1 is required, subsequent values are optional. 1 to 254 arguments representing the payments and income.\n - value1, value2, ... must be equally spaced in time and occur at the end of each period.\n - NPV uses the order of value1, value2, ... to interpret the order of cash flows. Be sure to enter your payment and income values in the correct sequence.\n - Arguments that are empty values, logical values, or text representations of numbers, error values, or text that cannot be translated into numbers are ignored.\n - If an argument is an array or reference, only numbers in that array or reference are counted. Empty values, logical values, text, or error values in the array or reference are ignored.\n * @returns\n */\nfunction NPV() {\n const args = parseNumberArray(flatten(arguments));\n\n if (args instanceof Error) {\n return args\n }\n\n // Lookup rate\n const rate = args[0];\n\n // Initialize net present value\n let value = 0;\n\n // Loop on all values\n for (let j = 1; j < args.length; j++) {\n value += args[j] / Math.pow(1 + rate, j);\n }\n\n // Return net present value\n return value\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the price per $100 face value of a security with an odd first period.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} issue The security's issue date.\n * @param {*} first_coupon The security's first coupon date.\n * @param {*} rate The security's interest rate.\n * @param {*} yld The security's annual yield.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction ODDFPRICE() {\n throw new Error('ODDFPRICE is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the yield of a security with an odd first period.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} issue The security's issue date.\n * @param {*} first_coupon The security's first coupon date.\n * @param {*} rate The security's interest rate.\n * @param {*} pr The security's price.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction ODDFYIELD() {\n throw new Error('ODDFYIELD is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the price per $100 face value of a security with an odd last period.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} last_interest The security's last coupon date.\n * @param {*} rate The security's interest rate.\n * @param {*} yld The security's annual yield.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction ODDLPRICE() {\n throw new Error('ODDLPRICE is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the yield of a security with an odd last period.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} last_interest The security's last coupon date.\n * @param {*} rate The security's interest rate\n * @param {*} pr The security's price.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction ODDLYIELD() {\n throw new Error('ODDLYIELD is not implemented')\n}\n\n/**\n * Returns the number of periods required by an investment to reach a specified value.\n *\n * Category: Financial\n *\n * @param {*} rate Rate is the interest rate per period.\n * @param {*} pv Pv is the present value of the investment.\n * @param {*} fv Fv is the desired future value of the investment.\n * @returns\n */\nfunction PDURATION(rate, pv, fv) {\n rate = parseNumber(rate);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n\n if (anyIsError(rate, pv, fv)) {\n return value\n }\n\n // Return error if rate <=0\n if (rate <= 0) {\n return num\n }\n\n // Return number of periods\n return (Math.log(fv) - Math.log(pv)) / Math.log(1 + rate)\n}\n\n/**\n * Returns the periodic payment for an annuity.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate for the loan.\n * @param {*} nper The total number of payments for the loan.\n * @param {*} pv The present value, or the total amount that a series of future payments is worth now; also known as the principal.\n * @param {*} fv Optional. The future value, or a cash balance you want to attain after the last payment is made. If fv is omitted, it is assumed to be 0 (zero), that is, the future value of a loan is 0.\n * @param {*} type Optional. The number 0 (zero) or 1 and indicates when payments are due.\n * @returns\n */\nfunction PMT(rate, nper, pv, fv, type) {\n // Credits: algorithm inspired by Apache OpenOffice\n fv = fv || 0;\n type = type || 0;\n\n rate = parseNumber(rate);\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n type = parseNumber(type);\n\n if (anyIsError(rate, nper, pv, fv, type)) {\n return value\n }\n\n // Return payment\n let result;\n\n if (rate === 0) {\n result = (pv + fv) / nper;\n } else {\n const term = Math.pow(1 + rate, nper);\n\n result =\n type === 1\n ? ((fv * rate) / (term - 1) + (pv * rate) / (1 - 1 / term)) / (1 + rate)\n : (fv * rate) / (term - 1) + (pv * rate) / (1 - 1 / term);\n }\n\n return -result\n}\n\n/**\n * Returns the payment on the principal for an investment for a given period.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate per period.\n * @param {*} per Specifies the period and must be in the range 1 to nper.\n * @param {*} nper The total number of payment periods in an annuity.\n * @param {*} pv The present value — the total amount that a series of future payments is worth now.\n * @param {*} fv Optional. The future value, or a cash balance you want to attain after the last payment is made. If fv is omitted, it is assumed to be 0 (zero), that is, the future value of a loan is 0.\n * @param {*} type Optional. The number 0 or 1 and indicates when payments are due.\n * @returns\n */\nfunction PPMT(rate, per, nper, pv, fv, type) {\n fv = fv || 0;\n type = type || 0;\n\n rate = parseNumber(rate);\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n type = parseNumber(type);\n\n if (anyIsError(rate, nper, pv, fv, type)) {\n return value\n }\n\n return PMT(rate, nper, pv, fv, type) - IPMT(rate, per, nper, pv, fv, type)\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the price per $100 face value of a security that pays periodic interest.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} rate The security's annual coupon rate.\n * @param {*} yld The security's annual yield.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction PRICE() {\n throw new Error('PRICE is not implemented')\n}\n\n/**\n * Returns the price per $100 face value of a discounted security.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} discount The security's discount rate.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction PRICEDISC(settlement, maturity, discount, redemption, basis) {\n settlement = parseDate(settlement);\n maturity = parseDate(maturity);\n discount = parseNumber(discount);\n redemption = parseNumber(redemption);\n basis = parseNumber(basis);\n\n basis = basis || 0;\n\n if (anyIsError(settlement, maturity, discount, redemption, basis)) {\n return value\n }\n\n if (discount <= 0 || redemption <= 0) {\n return num\n }\n\n if (settlement >= maturity) {\n return value\n }\n\n let basisVal, diff;\n switch (basis) {\n case 0:\n basisVal = 360;\n diff = DAYS360(settlement, maturity, false);\n break\n case 1:\n basisVal = 365;\n diff = DATEDIF(settlement, maturity, 'D');\n break\n case 2:\n basisVal = 360;\n diff = DATEDIF(settlement, maturity, 'D');\n break\n case 3:\n basisVal = 365;\n diff = DATEDIF(settlement, maturity, 'D');\n break\n case 4:\n basisVal = 360;\n diff = DAYS360(settlement, maturity, true);\n break\n default:\n return num\n }\n\n return redemption - (discount * redemption * diff) / basisVal\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the price per $100 face value of a security that pays interest at maturity.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} issue The security's issue date, expressed as a serial date number.\n * @param {*} rate The security's interest rate at date of issue.\n * @param {*} yld The security's annual yield.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction PRICEMAT() {\n throw new Error('PRICEMAT is not implemented')\n}\n\n/**\n * Returns the present value of an investment.\n *\n * Category: Financial\n *\n * @param {*} rate The interest rate per period. For example, if you obtain an automobile loan at a 10 percent annual interest rate and make monthly payments, your interest rate per month is 10%/12, or 0.83%. You would enter 10%/12, or 0.83%, or 0.0083, into the formula as the rate.\n * @param {*} nper The total number of payment periods in an annuity. For example, if you get a four-year car loan and make monthly payments, your loan has 4*12 (or 48) periods. You would enter 48 into the formula for nper.\n * @param {*} pmt The payment made each period and cannot change over the life of the annuity. Typically, pmt includes principal and interest but no other fees or taxes. For example, the monthly payments on a $10,000, four-year car loan at 12 percent are $263.33. You would enter -263.33 into the formula as the pmt. If pmt is omitted, you must include the fv argument.\n * @param {*} fv Optional. The future value, or a cash balance you want to attain after the last payment is made. If fv is omitted, it is assumed to be 0 (the future value of a loan, for example, is 0). For example, if you want to save $50,000 to pay for a special project in 18 years, then $50,000 is the future value. You could then make a conservative guess at an interest rate and determine how much you must save each month. If fv is omitted, you must include the pmt argument.\n * @param {*} type Optional. The number 0 or 1 and indicates when payments are due.\n * @returns\n */\nfunction PV(rate, per, pmt, fv, type) {\n fv = fv || 0;\n type = type || 0;\n\n rate = parseNumber(rate);\n per = parseNumber(per);\n pmt = parseNumber(pmt);\n fv = parseNumber(fv);\n type = parseNumber(type);\n\n if (anyIsError(rate, per, pmt, fv, type)) {\n return value\n }\n\n // Return present value\n return rate === 0\n ? -pmt * per - fv\n : (((1 - Math.pow(1 + rate, per)) / rate) * pmt * (1 + rate * type) - fv) / Math.pow(1 + rate, per)\n}\n\n/**\n * Returns the interest rate per period of an annuity.\n *\n * Category: Financial\n *\n * @param {*} nper The total number of payment periods in an annuity.\n * @param {*} pmt The payment made each period and cannot change over the life of the annuity. Typically, pmt includes principal and interest but no other fees or taxes. If pmt is omitted, you must include the fv argument.\n * @param {*} pv The present value — the total amount that a series of future payments is worth now.\n * @param {*} fv Optional. The future value, or a cash balance you want to attain after the last payment is made. If fv is omitted, it is assumed to be 0 (the future value of a loan, for example, is 0). If fv is omitted, you must include the pmt argument.\n * @param {*} type Optional. The number 0 or 1 and indicates when payments are due.\n * @param {*} guess Optional. Your guess for what the rate will be. If you omit guess, it is assumed to be 10 percent. If RATE does not converge, try different values for guess. RATE usually converges if guess is between 0 and 1.\n - If you omit guess, it is assumed to be 10 percent.\n - If RATE does not converge, try different values for guess. RATE usually converges if guess is between 0 and 1.\n * @returns\n */\nfunction RATE(nper, pmt, pv, fv, type, guess) {\n guess = guess === undefined ? 0.1 : guess;\n fv = fv === undefined ? 0 : fv;\n type = type === undefined ? 0 : type;\n\n nper = parseNumber(nper);\n pmt = parseNumber(pmt);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n type = parseNumber(type);\n guess = parseNumber(guess);\n\n if (anyIsError(nper, pmt, pv, fv, type, guess)) {\n return value\n }\n\n const epsMax = 1e-10;\n const iterMax = 100;\n let rate = guess;\n\n type = type ? 1 : 0;\n\n for (let i = 0; i < iterMax; i++) {\n if (rate <= -1) {\n return num\n }\n\n let y, f;\n\n if (Math.abs(rate) < epsMax) {\n y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv;\n } else {\n f = Math.pow(1 + rate, nper);\n y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;\n }\n\n if (Math.abs(y) < epsMax) {\n return rate\n }\n\n let dy;\n\n if (Math.abs(rate) < epsMax) {\n dy = pv * nper + pmt * type * nper;\n } else {\n f = Math.pow(1 + rate, nper);\n const df = nper * Math.pow(1 + rate, nper - 1);\n dy = pv * df + pmt * (1 / rate + type) * df + pmt * (-1 / (rate * rate)) * (f - 1);\n }\n\n rate -= y / dy;\n }\n\n return rate\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the amount received at maturity for a fully invested security.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} investment The amount invested in the security.\n * @param {*} discount The security's discount rate.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction RECEIVED() {\n throw new Error('RECEIVED is not implemented')\n}\n\n/**\n * Returns an equivalent interest rate for the growth of an investment.\n *\n * Category: Financial\n *\n * @param {*} nper Nper is the number of periods for the investment.\n * @param {*} pv Pv is the present value of the investment.\n * @param {*} fv Fv is the future value of the investment.\n * @returns\n */\nfunction RRI(nper, pv, fv) {\n nper = parseNumber(nper);\n pv = parseNumber(pv);\n fv = parseNumber(fv);\n\n if (anyIsError(nper, pv, fv)) {\n return value\n }\n\n // Return error if nper or present is equal to 0 (zero)\n if (nper === 0 || pv === 0) {\n return num\n }\n\n // Return equivalent interest rate\n return Math.pow(fv / pv, 1 / nper) - 1\n}\n\n/**\n * Returns the straight-line depreciation of an asset for one period.\n *\n * Category: Financial\n *\n * @param {*} cost The initial cost of the asset.\n * @param {*} salvage The value at the end of the depreciation (sometimes called the salvage value of the asset).\n * @param {*} life The number of periods over which the asset is depreciated (sometimes called the useful life of the asset).\n * @returns\n */\nfunction SLN(cost, salvage, life) {\n cost = parseNumber(cost);\n salvage = parseNumber(salvage);\n life = parseNumber(life);\n\n if (anyIsError(cost, salvage, life)) {\n return value\n }\n\n // Return error if life equal to 0 (zero)\n if (life === 0) {\n return num\n }\n\n // Return straight-line depreciation\n return (cost - salvage) / life\n}\n\n/**\n * Returns the sum-of-years' digits depreciation of an asset for a specified period.\n *\n * Category: Financial\n *\n * @param {*} cost The initial cost of the asset.\n * @param {*} salvage The value at the end of the depreciation (sometimes called the salvage value of the asset).\n * @param {*} life The number of periods over which the asset is depreciated (sometimes called the useful life of the asset).\n * @param {*} per The period and must use the same units as life.\n * @returns\n */\nfunction SYD(cost, salvage, life, per) {\n // Return error if any of the parameters is not a number\n cost = parseNumber(cost);\n salvage = parseNumber(salvage);\n life = parseNumber(life);\n per = parseNumber(per);\n\n if (anyIsError(cost, salvage, life, per)) {\n return value\n }\n\n // Return error if life equal to 0 (zero)\n if (life === 0) {\n return num\n }\n\n // Return error if period is lower than 1 or greater than life\n if (per < 1 || per > life) {\n return num\n }\n\n // Truncate period if it is not an integer\n per = parseInt(per, 10);\n\n // Return straight-line depreciation\n return ((cost - salvage) * (life - per + 1) * 2) / (life * (life + 1))\n}\n\n/**\n * Returns the bond-equivalent yield for a Treasury bill.\n *\n * Category: Financial\n *\n * @param {*} settlement The Treasury bill's settlement date. The security settlement date is the date after the issue date when the Treasury bill is traded to the buyer.\n * @param {*} maturity The Treasury bill's maturity date. The maturity date is the date when the Treasury bill expires.\n * @param {*} discount The Treasury bill's discount rate.\n * @returns\n */\nfunction TBILLEQ(settlement, maturity, discount) {\n settlement = parseDate(settlement);\n maturity = parseDate(maturity);\n discount = parseNumber(discount);\n\n if (anyIsError(settlement, maturity, discount)) {\n return value\n }\n\n // Return error if discount is lower than or equal to zero\n if (discount <= 0) {\n return num\n }\n\n // Return error if settlement is greater than maturity\n if (settlement > maturity) {\n return num\n }\n\n // Return error if maturity is more than one year after settlement\n if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) {\n return num\n }\n\n // Return bond-equivalent yield\n return (365 * discount) / (360 - discount * DAYS360(settlement, maturity, false))\n}\n\n/**\n * Returns the price per $100 face value for a Treasury bill.\n *\n * Category: Financial\n *\n * @param {*} settlement The Treasury bill's settlement date. The security settlement date is the date after the issue date when the Treasury bill is traded to the buyer.\n * @param {*} maturity The Treasury bill's maturity date. The maturity date is the date when the Treasury bill expires.\n * @param {*} discount The Treasury bill's discount rate.\n * @returns\n */\nfunction TBILLPRICE(settlement, maturity, discount) {\n settlement = parseDate(settlement);\n maturity = parseDate(maturity);\n discount = parseNumber(discount);\n\n if (anyIsError(settlement, maturity, discount)) {\n return value\n }\n\n // Return error if discount is lower than or equal to zero\n if (discount <= 0) {\n return num\n }\n\n // Return error if settlement is greater than maturity\n if (settlement > maturity) {\n return num\n }\n\n // Return error if maturity is more than one year after settlement\n if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) {\n return num\n }\n\n // Return bond-equivalent yield\n return 100 * (1 - (discount * DAYS360(settlement, maturity, false)) / 360)\n}\n\n/**\n * Returns the yield for a Treasury bill.\n *\n * Category: Financial\n *\n * @param {*} settlement The Treasury bill's settlement date. The security settlement date is the date after the issue date when the Treasury bill is traded to the buyer.\n * @param {*} maturity The Treasury bill's maturity date. The maturity date is the date when the Treasury bill expires.\n * @param {*} pr The Treasury bill's price per $100 face value.\n * @returns\n */\nfunction TBILLYIELD(settlement, maturity, pr) {\n settlement = parseDate(settlement);\n maturity = parseDate(maturity);\n pr = parseNumber(pr);\n\n if (anyIsError(settlement, maturity, pr)) {\n return value\n }\n\n // Return error if price is lower than or equal to zero\n if (pr <= 0) {\n return num\n }\n\n // Return error if settlement is greater than maturity\n if (settlement > maturity) {\n return num\n }\n\n // Return error if maturity is more than one year after settlement\n if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) {\n return num\n }\n\n // Return bond-equivalent yield\n return ((100 - pr) * 360) / (pr * DAYS360(settlement, maturity, false))\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the depreciation of an asset for a specified or partial period by using a declining balance method.\n *\n * Category: Financial\n *\n * @param {*} cost The initial cost of the asset.\n * @param {*} salvage The value at the end of the depreciation (sometimes called the salvage value of the asset). This value can be 0.\n * @param {*} life The number of periods over which the asset is depreciated (sometimes called the useful life of the asset).\n * @param {*} start_period The starting period for which you want to calculate the depreciation. Start_period must use the same units as life.\n * @param {*} end_period The ending period for which you want to calculate the depreciation. End_period must use the same units as life.\n * @param {*} factor Optional. The rate at which the balance declines. If factor is omitted, it is assumed to be 2 (the double-declining balance method). Change factor if you do not want to use the double-declining balance method. For a description of the double-declining balance method, see DDB.\n * @param {*} no_switch Optional. A logical value specifying whether to switch to straight-line depreciation when depreciation is greater than the declining balance calculation.\n - If no_switch is TRUE, Microsoft Excel does not switch to straight-line depreciation even when the depreciation is greater than the declining balance calculation.\n - If no_switch is FALSE or omitted, Excel switches to straight-line depreciation when depreciation is greater than the declining balance calculation.\n * @returns\n */\nfunction VDB() {\n throw new Error('VDB is not implemented')\n}\n\n/**\n * Returns the internal rate of return for a schedule of cash flows that is not necessarily periodic.\n *\n * Category: Financial\n *\n * @param {*} values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive and one negative value.\n * @param {*} dates A schedule of payment dates that corresponds to the cash flow payments. Dates may occur in any order. Dates should be entered by using the DATE function, or as results of other formulas or functions. For example, use DATE(2008,5,23) for the 23rd day of May, 2008. Problems can occur if dates are entered as text. .\n * @param {*} guess Optional. A number that you guess is close to the result of XIRR.\n * @returns\n */\nfunction XIRR(values, dates, guess) {\n // Credits: algorithm inspired by Apache OpenOffice\n values = parseNumberArray(flatten(values));\n dates = parseDateArray(flatten(dates));\n guess = parseNumber(guess);\n\n if (anyIsError(values, dates, guess)) {\n return value\n }\n\n // Calculates the resulting amount\n const irrResult = (values, dates, rate) => {\n const r = rate + 1;\n let result = values[0];\n\n for (let i = 1; i < values.length; i++) {\n result += values[i] / Math.pow(r, DAYS(dates[i], dates[0]) / 365);\n }\n\n return result\n };\n\n // Calculates the first derivation\n const irrResultDeriv = (values, dates, rate) => {\n const r = rate + 1;\n let result = 0;\n\n for (let i = 1; i < values.length; i++) {\n const frac = DAYS(dates[i], dates[0]) / 365;\n result -= (frac * values[i]) / Math.pow(r, frac + 1);\n }\n\n return result\n };\n\n // Check that values contains at least one positive value and one negative value\n let positive = false;\n let negative = false;\n\n for (let i = 0; i < values.length; i++) {\n if (values[i] > 0) {\n positive = true;\n }\n\n if (values[i] < 0) {\n negative = true;\n }\n }\n\n // Return error if values does not contain at least one positive value and one negative value\n if (!positive || !negative) {\n return num\n }\n\n // Initialize guess and resultRate\n guess = guess || 0.1;\n let resultRate = guess;\n\n // Set maximum epsilon for end of iteration\n const epsMax = 1e-10;\n\n // Implement Newton's method\n let newRate, epsRate, resultValue;\n let contLoop = true;\n\n do {\n resultValue = irrResult(values, dates, resultRate);\n newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate);\n epsRate = Math.abs(newRate - resultRate);\n resultRate = newRate;\n contLoop = epsRate > epsMax && Math.abs(resultValue) > epsMax;\n } while (contLoop)\n\n // Return internal rate of return\n return resultRate\n}\n\n/**\n * Returns the net present value for a schedule of cash flows that is not necessarily periodic.\n *\n * Category: Financial\n *\n * @param {*} rate The discount rate to apply to the cash flows.\n * @param {*} values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value.\n * @param {*} dates A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order.\n * @returns\n */\nfunction XNPV(rate, values, dates) {\n rate = parseNumber(rate);\n values = parseNumberArray(flatten(values));\n dates = parseDateArray(flatten(dates));\n\n if (anyIsError(rate, values, dates)) {\n return value\n }\n\n let result = 0;\n\n for (let i = 0; i < values.length; i++) {\n result += values[i] / Math.pow(1 + rate, DAYS(dates[i], dates[0]) / 365);\n }\n\n return result\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the yield on a security that pays periodic interest.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} rate The security's annual coupon rate.\n * @param {*} pr The security's price per $100 face value.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} frequency The number of coupon payments per year. For annual payments, frequency = 1; for semiannual, frequency = 2; for quarterly, frequency = 4.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction YIELD() {\n throw new Error('YIELD is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the annual yield for a discounted security; for example, a Treasury bill.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} pr The security's price per $100 face value.\n * @param {*} redemption The security's redemption value per $100 face value.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction YIELDDISC() {\n throw new Error('YIELDDISC is not implemented')\n}\n\n// TODO\n/**\n * -- Not implemented --\n *\n * Returns the annual yield of a security that pays interest at maturity.\n *\n * Category: Financial\n *\n * @param {*} settlement The security's settlement date. The security settlement date is the date after the issue date when the security is traded to the buyer.\n * @param {*} maturity The security's maturity date. The maturity date is the date when the security expires.\n * @param {*} issue The security's issue date, expressed as a serial date number.\n * @param {*} rate The security's interest rate at date of issue.\n * @param {*} pr The security's price per $100 face value.\n * @param {*} basis Optional. The type of day count basis to use.\n * @returns\n */\nfunction YIELDMAT() {\n throw new Error('YIELDMAT is not implemented')\n}\n\n/**\n * Returns TRUE if all of its arguments are TRUE.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction AND() {\n const args = flatten(arguments);\n let result = value;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] instanceof Error) {\n return args[i]\n }\n\n if (args[i] === undefined || args[i] === null || typeof args[i] === 'string') {\n continue\n }\n\n if (result === value) {\n result = true;\n }\n\n if (!args[i]) {\n result = false;\n }\n }\n\n return result\n}\n\n/**\n * Returns the logical value FALSE.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction FALSE() {\n return false\n}\n\n/**\n * Specifies a logical test to perform.\n *\n * Category: Logical\n *\n * @param {*} logical_test\n * @param {*} value_if_true\n * @param {*} value_if_false\n *\n * @returns\n */\nfunction IF(logical_test, value_if_true, value_if_false) {\n if (logical_test instanceof Error) {\n return logical_test\n }\n\n value_if_true = arguments.length >= 2 ? value_if_true : true;\n\n if (value_if_true === undefined || value_if_true === null) {\n value_if_true = 0;\n }\n\n value_if_false = arguments.length === 3 ? value_if_false : false;\n\n if (value_if_false === undefined || value_if_false === null) {\n value_if_false = 0;\n }\n\n return logical_test ? value_if_true : value_if_false\n}\n\n/**\n * Checks whether one or more conditions are met and returns a value that corresponds to the first TRUE condition.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction IFS() {\n for (let i = 0; i < arguments.length / 2; i++) {\n if (arguments[i * 2]) {\n return arguments[i * 2 + 1]\n }\n }\n\n return na\n}\n\n/**\n * Returns a value you specify if a formula evaluates to an error; otherwise, returns the result of the formula.\n *\n * Category: Logical\n *\n * @param {*} value The argument that is checked for an error.\n * @param {*} value_if_error The value to return if the formula evaluates to an error. The following error types are evaluated: #N/A, #VALUE!, #REF!, #DIV/0!, #NUM!, #NAME?, or #NULL!.\n * @returns\n */\nfunction IFERROR(value, value_if_error) {\n if (ISERROR(value)) {\n return value_if_error\n }\n\n return value\n}\n\n/**\n * Returns the value you specify if the expression resolves to #N/A, otherwise returns the result of the expression.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction IFNA(value, value_if_na) {\n return value === na ? value_if_na : value\n}\n\n/**\n * Reverses the logic of its argument.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction NOT(logical) {\n if (typeof logical === 'string') {\n return value\n }\n\n if (logical instanceof Error) {\n return logical\n }\n\n return !logical\n}\n\n/**\n * Returns TRUE if any argument is TRUE.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction OR() {\n const args = flatten(arguments);\n let result = value;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] instanceof Error) {\n return args[i]\n }\n\n if (args[i] === undefined || args[i] === null || typeof args[i] === 'string') {\n continue\n }\n\n if (result === value) {\n result = false;\n }\n\n if (args[i]) {\n result = true;\n }\n }\n\n return result\n}\n\n/**\n * Returns the logical value TRUE.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction TRUE() {\n return true\n}\n\n/**\n * Returns a logical exclusive OR of all arguments.\n *\n * Category: Logical\n *\n * @param {*} args logical1, logical2,… Logical 1 is required, subsequent logical values are optional. 1 to 254 conditions you want to test that can be either TRUE or FALSE, and can be logical values, arrays, or references.\n * @returns\n */\nfunction XOR() {\n const args = flatten(arguments);\n let result = value;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] instanceof Error) {\n return args[i]\n }\n\n if (args[i] === undefined || args[i] === null || typeof args[i] === 'string') {\n continue\n }\n\n if (result === value) {\n result = 0;\n }\n\n if (args[i]) {\n result++;\n }\n }\n\n if (result === value) {\n return result\n }\n\n return !!(Math.floor(Math.abs(result)) & 1)\n}\n\n/**\n * Evaluates an expression against a list of values and returns the result corresponding to the first matching value. If there is no match, an optional default value may be returned.\n *\n * Category: Logical\n *\n * @returns\n */\nfunction SWITCH() {\n let result;\n\n if (arguments.length > 0) {\n const targetValue = arguments[0];\n const argc = arguments.length - 1;\n const switchCount = Math.floor(argc / 2);\n let switchSatisfied = false;\n const hasDefaultClause = argc % 2 !== 0;\n const defaultClause = argc % 2 === 0 ? null : arguments[arguments.length - 1];\n\n if (switchCount) {\n for (let index = 0; index < switchCount; index++) {\n if (targetValue === arguments[index * 2 + 1]) {\n result = arguments[index * 2 + 2];\n switchSatisfied = true;\n break\n }\n }\n }\n\n if (!switchSatisfied) {\n result = hasDefaultClause ? defaultClause : na;\n }\n } else {\n result = value;\n }\n\n return result\n}\n\nconst utils = { errors, symbols };\n\nexport { ABS, ACCRINT, ACCRINTM, ACOS, ACOSH, ACOT, ACOTH, AGGREGATE, AMORDEGRC, AMORLINC, AND, ARABIC, ASC, ASIN, ASINH, ATAN, ATAN2, ATANH, AVEDEV, AVERAGE, AVERAGEA, AVERAGEIF, AVERAGEIFS, BAHTTEXT, BASE, BESSELI, BESSELJ, BESSELK, BESSELY, BETA, BETADIST, BETAINV, BIN2DEC, BIN2HEX, BIN2OCT, BINOM, BINOMDIST, BITAND, BITLSHIFT, BITOR, BITRSHIFT, BITXOR, CEILING, CEILINGMATH, CEILINGPRECISE, CELL, CHAR, CHIDIST, CHIDISTRT, CHIINV, CHIINVRT, CHISQ, CHITEST, CHOOSE, CLEAN, CODE, COLUMN, COLUMNS, COMBIN, COMBINA, COMPLEX, CONCAT, CONCATENATE, CONFIDENCE, CONVERT, CORREL, COS, COSH, COT, COTH, COUNT, COUNTA, COUNTBLANK, COUNTIF, COUNTIFS, COUPDAYBS, COUPDAYS, COUPDAYSNC, COUPNCD, COUPNUM, COUPPCD, COVAR, COVARIANCE, COVARIANCEP, COVARIANCES, CRITBINOM, CSC, CSCH, CUMIPMT, CUMPRINC, DATE, DATEDIF, DATEVALUE, DAVERAGE, DAY, DAYS, DAYS360, DB, DBCS, DCOUNT, DCOUNTA, DDB, DEC2BIN, DEC2HEX, DEC2OCT, DECIMAL, DEGREES, DELTA, DEVSQ, DGET, DISC, DMAX, DMIN, DOLLAR, DOLLARDE, DOLLARFR, DPRODUCT, DSTDEV, DSTDEVP, DSUM, DURATION, DVAR, DVARP, EDATE, EFFECT, EOMONTH, ERF, ERFC, ERFCPRECISE, ERFPRECISE, ERROR, EVEN, EXACT, EXP, EXPON, EXPONDIST, F, FACT, FACTDOUBLE, FALSE, FDIST, FDISTRT, FIND, FINV, FINVRT, FISHER, FISHERINV, FIXED, FLOOR, FLOORMATH, FLOORPRECISE, FORECAST, FREQUENCY, FTEST, FV, FVSCHEDULE, GAMMA, GAMMADIST, GAMMAINV, GAMMALN, GAMMALNPRECISE, GAUSS, GCD, GEOMEAN, GESTEP, GROWTH, HARMEAN, HEX2BIN, HEX2DEC, HEX2OCT, HLOOKUP, HOUR, HYPGEOM, HYPGEOMDIST, IF, IFERROR, IFNA, IFS, IMABS, IMAGINARY, IMARGUMENT, IMCONJUGATE, IMCOS, IMCOSH, IMCOT, IMCSC, IMCSCH, IMDIV, IMEXP, IMLN, IMLOG10, IMLOG2, IMPOWER, IMPRODUCT, IMREAL, IMSEC, IMSECH, IMSIN, IMSINH, IMSQRT, IMSUB, IMSUM, IMTAN, INDEX, INFO, INT, INTERCEPT, INTRATE, IPMT, IRR, ISBLANK, ISERR, ISERROR, ISEVEN, ISFORMULA, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISO, ISODD, ISOWEEKNUM, ISPMT, ISREF, ISTEXT, KURT, LARGE, LCM, LEFT, LEN, LINEST, LN, LOG, LOG10, LOGEST, LOGINV, LOGNORM, LOGNORMDIST, LOGNORMINV, LOOKUP, LOWER, MATCH, MAX, MAXA, MAXIFS, MDURATION, MEDIAN, MID, MIN, MINA, MINIFS, MINUTE, MIRR, MMULT, MOD, MODE, MODEMULT, MODESNGL, MONTH, MROUND, MULTINOMIAL, MUNIT, N, NA, NEGBINOM, NEGBINOMDIST, NETWORKDAYS, NETWORKDAYSINTL, NOMINAL, NORM, NORMDIST, NORMINV, NORMSDIST, NORMSINV, NOT, NOW, NPER, NPV, NUMBERVALUE, OCT2BIN, OCT2DEC, OCT2HEX, ODD, ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD, OR, PDURATION, PEARSON, PERCENTILE, PERCENTILEEXC, PERCENTILEINC, PERCENTRANK, PERCENTRANKEXC, PERCENTRANKINC, PERMUT, PERMUTATIONA, PHI, PI, PMT, POISSON, POISSONDIST, POWER, PPMT, PRICE, PRICEDISC, PRICEMAT, PROB, PRODUCT, PRONETIC, PROPER, PV, QUARTILE, QUARTILEEXC, QUARTILEINC, QUOTIENT, RADIANS, RAND, RANDBETWEEN, RANK, RANKAVG, RANKEQ, RATE, RECEIVED, REPLACE, REPT, RIGHT, ROMAN, ROUND, ROUNDDOWN, ROUNDUP, ROW, ROWS, RRI, RSQ, SEARCH, SEC, SECH, SECOND, SERIESSUM, SHEET, SHEETS, SIGN, SIN, SINH, SKEW, SKEWP, SLN, SLOPE, SMALL, SORT, SQRT, SQRTPI, STANDARDIZE, STDEV, STDEVA, STDEVP, STDEVPA, STDEVS, STEYX, SUBSTITUTE, SUBTOTAL, SUM, SUMIF, SUMIFS, SUMPRODUCT, SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2, SWITCH, SYD, T, TAN, TANH, TBILLEQ, TBILLPRICE, TBILLYIELD, TDIST, TDISTRT, TEXT, TEXTJOIN, TIME, TIMEVALUE, TINV, TODAY, TRANSPOSE, TREND, TRIM, TRIMMEAN, TRUE, TRUNC, TTEST, TYPE, UNICHAR, UNICODE, UNIQUE, UPPER, VALUE, VAR, VARA, VARP, VARPA, VARS, VDB, VLOOKUP, WEEKDAY, WEEKNUM, WEIBULL, WEIBULLDIST, WORKDAY, WORKDAYINTL, XIRR, XNPV, XOR, YEAR, YEARFRAC, YIELD, YIELDDISC, YIELDMAT, Z, ZTEST, utils };\n","import { PMT, ROUND } from \"@formulajs/formulajs\"\r\nimport util from '@core/services/util';\r\n\r\nconst PERIODS_YEARS = 12;\r\nenum BalloonPeriodStart {\r\n End = 0,\r\n BEGINNING = 1\r\n}\r\n\r\n\r\nconst financials = {\r\n calculateResidualDollars(amount: any, residualPercent: any) {\r\n //params\r\n //amount - this is the MSRP to use to calculate the residual value\r\n //residualPercent - this is the percentage to use to calculate the residual value - (represented as the full number, in other words, 65% would be 65, not .65)\r\n let residualDollars = 0;\r\n //console.log('in calculateResidualDollars', arguments);\r\n if (!util.anyNull(amount, residualPercent)) {\r\n const floatAmount = amount;\r\n const floatPercent = residualPercent;\r\n residualDollars = ((floatPercent * .01) * floatAmount);\r\n }\r\n return residualDollars;\r\n },\r\n\r\n calculateResidualDollarsOld(amount: any, residualPercent: any) {\r\n //params\r\n //amount - this is the MSRP to use to calculate the residual value\r\n //residualPercent - this is the percentage to use to calculate the residual value - (represented as the full number, in other words, 65% would be 65, not .65)\r\n let residualDollars = 0;\r\n //console.log('in calculateResidualDollars', arguments);\r\n if (!util.anyNull(amount, residualPercent)) {\r\n const floatAmount = Number.parseFloat(amount);\r\n const floatPercent = Number.parseFloat(residualPercent);\r\n if (Number.isNaN(floatAmount) || Number.isNaN(floatPercent)) return residualDollars;\r\n residualDollars = ((floatPercent * .01) * floatAmount);\r\n }\r\n return parseFloat(residualDollars.toFixed(2));\r\n },\r\n\r\n calculateLeastPaymentAlly(term: number, adjCap: number, residual: number, rate: number) {\r\n const i = rate / 1200;\r\n // 1. Calculate PV of Residual\r\n const pvRes = residual * Math.pow(1 + i, -(term + 1)); //PV__Res = Res x (1 + i) –( N + 1 ) || 19,242.31 = 29,664.25 x (1 + 12.14 )-(42+1)\r\n\r\n // 2. Calculate A (AdjCap - PV_Res)\r\n const a = adjCap - pvRes; // A = AdjCap – PV__Res || 23,561.58= 42,803.89 – 19,242.31\r\n\r\n // 3. Calculate Payment\r\n const payment = a * ((i / (1 + i)) / (1 - Math.pow(1 + i, -term))); \r\n return payment;\r\n },\r\n\r\n convertMFtoAPR(mf: number, lenderCode: string) {\r\n return mf * 2400;\r\n },\r\n convertAPRtoMF(apr: number, lenderCode: string) {\r\n return apr / 2400;\r\n },\r\n\r\n ConvertAPRtoMF_ALLY(rate: number) {\r\n return Number((rate / (1200 * 24)).toFixed(8));\r\n },\r\n ConvertMFtoAPR_ALLY(mf: number) {\r\n return Number((mf * 24 * 1200).toFixed(3));\r\n },\r\n\r\n calculateLeasePayment(term: any, amount: any, residualPercent: any, moneyFactor: any, msrp: any) {\r\n\r\n //params\r\n //term - number of months\r\n //amount - the capitalized cost amount\r\n //residualPercent - this is the percentage to use to calculate the residual value - (represented as the full number, in other words, 65% would be 65, not .65)\r\n //moneyFactor - this is the money factor to use - (represented as .00##))\r\n //msrp - the MSRP to use to calculate the residual\r\n let payment = 0;\r\n //console.log('in calculateLeasePayment', arguments);\r\n if (!util.anyNull(term, amount, residualPercent, moneyFactor, msrp)) {\r\n //console.log('in calculateLeasePayment', arguments);\r\n const intTerm = term;\r\n const floatAmount = amount;\r\n const floatResidual = residualPercent;\r\n const floatMsrp = msrp;\r\n const floatMoneyFactor = moneyFactor;\r\n const residualDollars = financials.calculateResidualDollars(floatMsrp, floatResidual);\r\n //console.log('in lease calc', intTerm, floatAmount, floatResidual, floatMsrp, floatMoneyFactor, residualDollars);\r\n //if (Number.isNaN(intTerm) || Number.isNaN(floatAmount) || Number.isNaN(floatMoneyFactor)) return payment;\r\n payment = ((((floatAmount + residualDollars) * intTerm * floatMoneyFactor) + (floatAmount - residualDollars)) / intTerm);\r\n }\r\n //console.log(payment, payment.toFixed(2))\r\n return payment;\r\n //return parseFloat(payment.toFixed(2));\r\n },\r\n\r\n calculateLeasePaymentOld(term: any, amount: any, residualPercent: any, moneyFactor: any, msrp: any) {\r\n\r\n //params\r\n //term - number of months\r\n //amount - the capitalized cost amount\r\n //residualPercent - this is the percentage to use to calculate the residual value - (represented as the full number, in other words, 65% would be 65, not .65)\r\n //moneyFactor - this is the money factor to use - (represented as .00##))\r\n //msrp - the MSRP to use to calculate the residual\r\n let payment = 0;\r\n //console.log('in calculateLeasePayment', arguments);\r\n if (!util.anyNull(term, amount, residualPercent, moneyFactor, msrp)) {\r\n //console.log('in calculateLeasePayment', arguments);\r\n const intTerm = Number.parseInt(term);\r\n const floatAmount = Number.parseFloat(amount);\r\n const floatResidual = Number.parseFloat(residualPercent);\r\n const floatMsrp = Number.parseFloat(msrp);\r\n const floatMoneyFactor = Number.parseFloat(moneyFactor);\r\n const residualDollars = Number.parseFloat(financials.calculateResidualDollars(floatMsrp, floatResidual)?.toString());\r\n //console.log('in lease calc', intTerm, floatAmount, floatResidual, floatMsrp, floatMoneyFactor, residualDollars);\r\n if (Number.isNaN(intTerm) || Number.isNaN(floatAmount) || Number.isNaN(floatMoneyFactor)) return payment;\r\n payment = ((((floatAmount + residualDollars) * intTerm * floatMoneyFactor) + (floatAmount - residualDollars)) / intTerm);\r\n }\r\n //console.log(payment, payment.toFixed(2))\r\n //return payment;\r\n return parseFloat(payment.toFixed(2));\r\n },\r\n\r\n calculateLeasePaymentWithApr(capCost: any, apr: any, residualValue: any, term: any, oddDays: any) {\r\n apr = apr * 0.01; // APR is a percent\r\n const d = apr / 12;\r\n const pow = Math.pow(1 + d, 37);\r\n const p1 = capCost - (residualValue / pow);\r\n const monthlyPayment = (capCost - (residualValue / Math.pow((1 + (apr / 12)), (term + 1)))) * (apr / 12) * (1 + (apr * oddDays / 365)) / (1 - Math.pow((1 + (apr / 12)), -term));\r\n\r\n const roundedMonthlyPayment = Math.round(monthlyPayment * 100) / 100;\r\n\r\n return roundedMonthlyPayment;\r\n },\r\n\r\n //calculateLeasePaymentWithApr(capCost, apr, residualValue, term) {\r\n // // Calculate depreciation\r\n // const depreciation = (capCost - residualValue) / term;\r\n //\r\n // // Calculate interest\r\n // const interest = ((capCost + residualValue) * (apr / 100)) / 12;\r\n //\r\n // // Monthly payment is the sum of depreciation and interest\r\n // const monthlyPayment = depreciation + interest;\r\n //\r\n // return monthlyPayment;\r\n //},\r\n\r\n calculateFinancePayment(term: any, amount: any, rate: any, oddDays: any) {\r\n //params\r\n //term - number of months\r\n //amount - the principal amount\r\n //rate - the APR to use (represented as the full number, in other words, 6.5% would be 6.5, not .065)\r\n //oddDays - this is a whole number of odd days (the difference in number of days until the first payment)\r\n\r\n let payment = 0;\r\n if (!util.anyNull(term, amount, rate, oddDays)) {\r\n\r\n const floatApr = Number.parseFloat(rate) * .01;\r\n const floatPrincipal = Number.parseFloat(amount);\r\n const intOdd = Number.parseInt(oddDays);\r\n const intTerm = Number.parseInt(term);\r\n\r\n if (floatApr == 0 && floatPrincipal > 0 && intTerm > 0) {\r\n payment = floatPrincipal / intTerm\r\n } else if (Number.isNaN(intTerm) || Number.isNaN(floatPrincipal) || Number.isNaN(floatApr) || Number.isNaN(intOdd)) {\r\n payment = 0\r\n } else {\r\n payment = (Number(floatPrincipal) * (floatApr / 12) * (1 + ((floatApr * intOdd) / 360))) / (1 - (Math.pow(1 + (floatApr / 12), -intTerm)));\r\n }\r\n\r\n }\r\n return payment.toFixed(2);\r\n },\r\n\r\n\r\n /**\r\n * @param {number} term Number of months\r\n * @param {number} amount The principal amount\r\n * @param {number} rate The APR to use (represented as the full number, in other words, 6.5% would be 6.5, not .065)\r\n * @param {*} oddDays This is a whole number of odd days (the difference in number of days until the first payment)\r\n * @param {number} balloonAmount\r\n * @return {*} The monthly finance amount\r\n */\r\n calculateBalloonPayment(term: number, amount: number, rate: number, oddDays: any, balloonAmount: number) {\r\n let payment: number | Error = 0.0;\r\n\r\n const rateAsPercentage = rate * 0.01;\r\n const termWithoutFinalPayment = term -1;\r\n const presentValueResidual = balloonAmount * ((1 + (rateAsPercentage/PERIODS_YEARS)) ** -term);\r\n\r\n payment = Number(ROUND(PMT(rateAsPercentage/PERIODS_YEARS, termWithoutFinalPayment, amount - presentValueResidual, null, BalloonPeriodStart.End), 2));\r\n if (typeof payment == \"number\") payment = payment * -1;\r\n\r\n // console.log(\"balloon amounts\", balloonAmount, amount, rateAsPercentage, -term, presentValueResidual)\r\n // console.log(\"final payment\", payment, interestPaid, amount - balloonAmount, termWithoutFinalPayment)\r\n\r\n return payment;\r\n },\r\n\r\n calculateDocStamps(amount: any, state: string) {\r\n\r\n switch (state) {\r\n case \"FL\":\r\n //PROVIDED BY AVIDAN 12/9/2020 - this is how CDK calculates it\r\n return Number((financials.roundUpToNearestHundreds(amount) * 0.0035).toFixed(2));\r\n //return Number((financials.roundUpToNearestHundreds(amount) / 0.9965 - financials.roundUpToNearestHundreds(amount)).toFixed(2));\r\n default:\r\n return 0.00;\r\n }\r\n },\r\n\r\n calculateCDKDocStamps(amount: any, state: string) {\r\n\r\n let preDocsStamps = 0.0\r\n let newTotal = 0.0\r\n let postDocStamps = 0.0\r\n switch (state) {\r\n case \"FL\":\r\n //PROVIDED BY AVIDAN 12/9/2020 - this is how CDK calculates it\r\n preDocsStamps = Number((financials.roundUpToNearestHundreds(amount) * 0.0035).toFixed(2));\r\n newTotal = amount + preDocsStamps;\r\n postDocStamps = Number((financials.roundUpToNearestHundreds(newTotal) * 0.0035).toFixed(2));\r\n return postDocStamps;\r\n default:\r\n return 0.00;\r\n }\r\n },\r\n\r\n round(num: number, decimalPoints = 2) {\r\n const multiplier = Math.pow(10, decimalPoints);\r\n return Math.round((num + Number.EPSILON) * multiplier) / multiplier;\r\n },\r\n\r\n roundUpToNearestHundreds(amount: number) {\r\n return Math.ceil(amount / 100.00) * 100.00;\r\n },\r\n\r\n calculateStateSalesTax(baseAmount: number, rate: number, state?: string) {\r\n //params\r\n //baseAmount - the amount to base the tax on\r\n //rate - the tax percentage to use (represented as the full number, in other words, 6.5% would be 6.5, not .065)\r\n //state - the state to use (some states will have different calculations for taxes)\r\n let tax: any = 0.0;\r\n if (baseAmount > 0 && rate > 0 && state != null && state != \"\") {\r\n switch (state) {\r\n default:\r\n tax = financials.roundFloatNumberWithoutTrailingZeroes(baseAmount * (rate / 100), 2);\r\n break;\r\n }\r\n }\r\n return tax;\r\n },\r\n\r\n calculateCountySalesTax(baseAmount: number, rate: number, state: string) {\r\n //params\r\n //baseAmount - the amount to base the tax on\r\n //rate - the tax percentage to use (represented as the full number, in other words, 6.5% would be 6.5, not .065)\r\n //state - the state to use (some states will have different calculations for taxes)\r\n let tax: any = 0.0;\r\n if (baseAmount > 0 && rate > 0 && state != null && state != \"\") {\r\n switch (state) {\r\n case \"FL\":\r\n tax = financials.roundFloatNumberWithoutTrailingZeroes(Math.min(5000, baseAmount) * (rate / 100), 2);\r\n break;\r\n default:\r\n tax = financials.roundFloatNumberWithoutTrailingZeroes(baseAmount * (rate / 100), 2);\r\n break;\r\n }\r\n }\r\n return tax;\r\n },\r\n\r\n roundFloatNumberWithoutTrailingZeroes(num: any, dp: any) {\r\n //params\r\n //num - the number to round\r\n //dp - the number of characters to use (typically 2 for a currency)\r\n //console.log('in roundFloatNumberWithoutTrailingZeroes',num,dp);\r\n const numToFixedDp = Number(num).toFixed(dp);\r\n return numToFixedDp;\r\n }\r\n}\r\n\r\nexport default financials;","import { DealType } from './SharedEnums';\r\nimport FIMenuPaymentAmount from './FIMenuPaymentAmount'\r\nimport financials from '@core/services/financials'\r\nimport util from '@core/services/util'\r\n\r\nexport interface IFIMenuLeaseTerm {\r\n buyrate?: number;\r\n buyRateMoneyFactor?: number;\r\n finalNumbersPerCoverageTerm?: any[];\r\n moneyfactor?: number;\r\n paymentAmounts?: FIMenuPaymentAmount[];\r\n residual?: number;\r\n residualAmount?: number;\r\n sellrate?: number;\r\n show?: boolean;\r\n term?: number;\r\n}\r\n\r\n\r\nexport default class FIMenuLeaseTerm implements IFIMenuLeaseTerm{\r\n buyrate?: number;\r\n buyRateMoneyFactor?: number;\r\n finalNumbersPerCoverageTerm?: any[];\r\n moneyfactor?: number;\r\n paymentAmounts?: FIMenuPaymentAmount[];\r\n residual?: number;\r\n residualAmount?: number;\r\n sellrate?: number;\r\n show?: boolean;\r\n term?: number;\r\n\r\n constructor(init?: IFIMenuLeaseTerm) {\r\n if(init){\r\n this.term = init.term;\r\n this.residual = init.residual;\r\n this.moneyfactor = init.moneyfactor;\r\n this.buyrate = init.buyrate;\r\n this.show = init.show;\r\n this.paymentAmounts = init.paymentAmounts?.map(cttf => new FIMenuPaymentAmount(cttf)) ?? [];\r\n\r\n //front end properties only\r\n this.residualAmount = init.residualAmount ?? null;\r\n this.sellrate = init.sellrate ?? init?.moneyfactor ? init.moneyfactor * 2400 : null;\r\n this.buyRateMoneyFactor = init.buyRateMoneyFactor ?? init.buyrate ? init.buyrate / 2400 : null;\r\n this.finalNumbersPerCoverageTerm = [];\r\n }\r\n }\r\n\r\n isAvailable() {\r\n return this.term && this.show && util.hasValue(this.residual) && util.hasValue(this.moneyfactor);\r\n }\r\n\r\n paymentCalculationWithoutCoverage(dealType: DealType, otd: number, msrp: number, stateTaxRate: number, countyTaxRate: number, state: string, lenderCode: string) {\r\n //params\r\n //dealType - should always be 'lease'\r\n //otd - should be the Out the Door price\r\n //msrp - MSRP which is what is used to calculate residual amount\r\n //stateTaxRate - only include this if the payment gets taxed. this should be the state's tax rate (represented as the full number, in other words, 6.5% would be 6.5, not .065)\r\n //countyTaxRate - only include this if the payment gets taxed. this should be the county's tax rate (represented as the full number, in other words, 1.0% would be 1.0, not .01)\r\n //state - only need to include this if the payment gets taxed. gets passed in to the sales tax calculations\r\n if (dealType.toLowerCase() === 'lease' && this.term) {\r\n\r\n if (stateTaxRate) {\r\n let baseLeasePayment = this.baseCalculateLeasePayment(this.term, otd, this.residual, this.moneyfactor, msrp, lenderCode, this.sellrate);;\r\n let stateTax = financials.calculateStateSalesTax(baseLeasePayment, stateTaxRate, state);\r\n let countyTax = financials.calculateCountySalesTax(baseLeasePayment, countyTaxRate, state);\r\n //console.log('baseLeasePayment', baseLeasePayment);\r\n //console.log('stateTaxRate', stateTaxRate);\r\n //console.log('countyTaxRate', countyTaxRate);\r\n //console.log('state', state);\r\n //console.log('stateTax', stateTax);\r\n //console.log('countyTax', countyTax);\r\n return financials.roundFloatNumberWithoutTrailingZeroes(Number(baseLeasePayment) + Number(stateTax) + Number(countyTax), 2);\r\n }\r\n else {\r\n return this.baseCalculateLeasePayment(this.term, otd, this.residual, this.moneyfactor, msrp,lenderCode, this.sellrate);\r\n }\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n\r\n paymentCalculation(dealType: DealType, otd: number, msrp: number, stateTaxRate: number, countyTaxRate: number, state?: string, lenderCode?: string) {\r\n //params\r\n //dealType - should always be 'lease'\r\n //otd - should be the Out the Door price\r\n //coverage - should be the coverage total - depending on what state you're in, it needs to not include tax, since we're taxing the monthly payment\r\n //msrp - MSRP which is what is used to calculate residual amount\r\n //stateTaxRate - only include this if the payment gets taxed. this should be the state's tax rate (represented as the full number, in other words, 6.5% would be 6.5, not .065)\r\n //countyTaxRate - only include this if the payment gets taxed. this should be the county's tax rate (represented as the full number, in other words, 1.0% would be 1.0, not .01)\r\n //state - only need to include this if the payment gets taxed. gets passed in to the sales tax calculations\r\n if (dealType.toLowerCase() === 'lease' && this.term)\r\n if (stateTaxRate) {\r\n let baseLeasePayment = this.baseCalculateLeasePayment(this.term, otd, this.residual, this.moneyfactor, msrp, lenderCode, this.sellrate);\r\n let stateTax = financials.calculateStateSalesTax(baseLeasePayment, stateTaxRate, state);\r\n let countyTax = financials.calculateCountySalesTax(baseLeasePayment, countyTaxRate, state);\r\n\r\n let buyrateBaseLeasePayment = this.baseCalculateLeasePayment(this.term, otd, this.residual, this.buyRateMoneyFactor, msrp, lenderCode, this.sellrate);\r\n let stateTaxAtBuyRate = financials.calculateStateSalesTax(buyrateBaseLeasePayment, stateTaxRate, state);\r\n let countyTaxAtBuyRate = financials.calculateCountySalesTax(buyrateBaseLeasePayment, countyTaxRate, state);\r\n return {\r\n payment: financials.roundFloatNumberWithoutTrailingZeroes(Number(baseLeasePayment) + Number(stateTax) + Number(countyTax), 2),\r\n paymentAtBuyRate: financials.roundFloatNumberWithoutTrailingZeroes(Number(buyrateBaseLeasePayment) + Number(stateTaxAtBuyRate) + Number(countyTaxAtBuyRate), 2),\r\n };\r\n }\r\n else {\r\n return {\r\n payment: this.baseCalculateLeasePayment(this.term, otd, this.residual, this.moneyfactor, msrp, lenderCode, this.sellrate),\r\n paymentAtBuyRate: this.baseCalculateLeasePayment(this.term, otd, this.residual, this.buyRateMoneyFactor, msrp, lenderCode, this.sellrate)\r\n }\r\n }\r\n else\r\n return {\r\n payment: null,\r\n paymentAtBuyRate: null\r\n };\r\n }\r\n\r\n baseCalculateLeasePayment(term: number, adjustedCapCost: number, residual: number, moneyFactor: number, vehicleValue: number, lenderCode: string, sellrate: number) { \r\n switch(lenderCode) {\r\n case \"ALLY\":\r\n return financials.calculateLeastPaymentAlly(term, adjustedCapCost, residual, sellrate);\r\n default: \r\n return financials.calculateLeasePayment(term, adjustedCapCost, residual, moneyFactor, vehicleValue);\r\n }\r\n }\r\n\r\n\r\n}","import { required, between, minValue, maxValue, minLength, maxLength, numeric } from '@vuelidate/validators'\r\nimport FIMenuLeaseTerm from './FIMenuLeaseTerm';\r\nimport FIMenu from './FIMenu';\r\n\r\nexport interface IFIMenuLeaseTerms {\r\n acceptedTerm?: any;\r\n firstpayment?: any;\r\n finalMonthlyPayment?: any;\r\n term1?: FIMenuLeaseTerm;\r\n term2?: FIMenuLeaseTerm;\r\n term3?: FIMenuLeaseTerm;\r\n}\r\n\r\n\r\nexport default class FIMenuLeaseTerms implements IFIMenuLeaseTerms{\r\n\r\n acceptedTerm?: any = null;\r\n firstpayment?: any = null;\r\n finalMonthlyPayment?: any = null;\r\n term1?: FIMenuLeaseTerm = new FIMenuLeaseTerm();\r\n term2?: FIMenuLeaseTerm = new FIMenuLeaseTerm();\r\n term3?: FIMenuLeaseTerm = new FIMenuLeaseTerm();\r\n\r\n\r\n static validationTypes = {\r\n TERMS: 'TERMS',\r\n DEFAULT: 'DEFAULT'\r\n }\r\n\r\n constructor(init?: IFIMenuLeaseTerms) {\r\n if (init){\r\n this.acceptedTerm = init?.acceptedTerm;\r\n this.firstpayment = init?.firstpayment;\r\n this.finalMonthlyPayment = init?.finalMonthlyPayment;\r\n this.term1 = new FIMenuLeaseTerm(init?.term1);\r\n this.term2 = new FIMenuLeaseTerm(init?.term2);\r\n this.term3 = new FIMenuLeaseTerm(init?.term3);\r\n }\r\n }\r\n\r\n getAcceptedTerm() {\r\n if (this.acceptedTerm) {\r\n if (this.acceptedTerm === 1 && this.term1) return this.term1;\r\n if (this.acceptedTerm === 2 && this.term2) return this.term2;\r\n if (this.acceptedTerm === 3 && this.term3) return this.term3;\r\n return null;\r\n }\r\n else\r\n return null\r\n }\r\n\r\n availableTerms() {\r\n return [this.term1, this.term2, this.term3].filter(term => term.isAvailable());\r\n }\r\n\r\n allTerms() {\r\n return [this.term1, this.term2, this.term3];\r\n }\r\n\r\n validation(fimenu: FIMenu, type: string = FIMenuLeaseTerms.validationTypes.DEFAULT) {\r\n const data = {\r\n finalMonthlyPayment: {},\r\n term1: {\r\n term: {},\r\n residual: {},\r\n moneyfactor: {},\r\n buyrate: {},\r\n },\r\n term2: {\r\n term: {},\r\n residual: {},\r\n moneyfactor: {},\r\n buyrate: {},\r\n },\r\n term3: {\r\n term: {},\r\n residual: {},\r\n moneyfactor: {},\r\n buyrate: {}\r\n }\r\n }\r\n\r\n switch (type) {\r\n case FIMenuLeaseTerms.validationTypes.DEFAULT:\r\n return data\r\n case FIMenuLeaseTerms.validationTypes.TERMS:\r\n if (fimenu.isLease()) {\r\n const t1BuyRateMax = fimenu.leaseTerms.term1.sellrate ?? 0;\r\n const t2BuyRateMax = fimenu.leaseTerms.term2.sellrate ?? 0;\r\n const t3BuyRateMax = fimenu.leaseTerms.term3.sellrate ?? 0;\r\n\r\n let residualMin = fimenu.lender.lenderCode === 'DA' ? 0 : 10;\r\n\r\n data.term1 = {\r\n term: { required, minValue: minValue(1) },\r\n residual: { required, minValue: minValue(residualMin), maxValue: maxValue(100) },\r\n moneyfactor: { required },\r\n buyrate: { required, minValue: minValue(t1BuyRateMax - 3), maxValue: maxValue(t1BuyRateMax) },\r\n }\r\n\r\n if (fimenu.leaseTerms.term2.term) {\r\n data.term2.residual = { required, minValue: minValue(residualMin), maxValue: maxValue(100) }\r\n data.term2.moneyfactor = { required }\r\n data.term2.buyrate = { required, minValue: minValue(t2BuyRateMax - 3), maxValue: maxValue(t2BuyRateMax) }\r\n }\r\n if (fimenu.leaseTerms.term3.term) {\r\n data.term3.residual = { required, minValue: minValue(residualMin), maxValue: maxValue(100) }\r\n data.term3.moneyfactor = { required }\r\n data.term3.buyrate = { required, minValue: minValue(t3BuyRateMax - 3), maxValue: maxValue(t3BuyRateMax) }\r\n }\r\n }\r\n return data\r\n default:\r\n return data\r\n }\r\n }\r\n}","import { DealType } from './SharedEnums';\r\nimport FIMenuPaymentAmount from './FIMenuPaymentAmount'\r\nimport financials from '@core/services/financials'\r\nimport util from '@core/services/util'\r\n\r\nexport default class FIMenuLoanTerm {\r\n /**\r\n * The amount for the balloon payment.\r\n * Setting this to 0 for all deal terms prevents the deal from being treated as balloon.\r\n */\r\n balloonAmount?: number = null;\r\n buyrate?: any = null;\r\n finalNumbersPerCoverageTerm: any[] = [];\r\n paymentAmounts?: FIMenuPaymentAmount[] = [];\r\n sellrate?: any = null;\r\n show?: boolean = false;\r\n term?: any = null;\r\n\r\n constructor(init?: Partial) {\r\n if(init){\r\n this.term = init?.term;\r\n this.buyrate = init?.buyrate;\r\n this.sellrate = init?.sellrate;\r\n this.show = init?.show;\r\n this.paymentAmounts = init?.paymentAmounts?.map(cttf => new FIMenuPaymentAmount(cttf)) ?? []\r\n this.balloonAmount = init?.balloonAmount;\r\n this.finalNumbersPerCoverageTerm = [];\r\n }\r\n }\r\n\r\n isAvailable() {\r\n return this.term && this.show && util.hasValue(this.buyrate) && util.hasValue(this.sellrate);\r\n }\r\n\r\n isChoice() {\r\n return this.term;\r\n }\r\n\r\n paymentCalculation(dealType: DealType, otd: number, selectedDaysToFirstPayment: number, maxDaysToFirstPayment: number, isBalloon = false) {\r\n let financePayment: any = 0.0;\r\n if (dealType === DealType.Retail && this.term) {\r\n if (isBalloon) {\r\n financePayment = financials.calculateBalloonPayment(this.term, otd, this.sellrate, (selectedDaysToFirstPayment ?? maxDaysToFirstPayment) - 30, this.balloonAmount)\r\n }else {\r\n financePayment = financials.calculateFinancePayment(this.term, otd, this.sellrate, (selectedDaysToFirstPayment ?? maxDaysToFirstPayment) - 30);\r\n }\r\n const financePaymentAtBuyRate = financials.calculateFinancePayment(this.term, otd, this.buyrate, (selectedDaysToFirstPayment ?? maxDaysToFirstPayment) - 30);\r\n return {\r\n financePayment,\r\n paymentAtBuyRate: financePaymentAtBuyRate\r\n }\r\n }\r\n else\r\n return {\r\n financePayment: null,\r\n paymentAtBuyRate: null\r\n };\r\n }\r\n\r\n}","import { required, minValue, maxValue, helpers, requiredIf } from '@vuelidate/validators';\r\nimport FIMenu from './FIMenu';\r\nimport FIMenuLoanTerm from './FIMenuLoanTerm';\r\n\r\nexport const balloonValidationMessage = 'Balloon amount is required. \\nSet this to 0 if not in use.';\r\n\r\nexport default class FIMenuLoanTerms {\r\n acceptedTerm?: number = null;\r\n line5limit?: any = null;\r\n additionalDownPayment?: boolean = null;\r\n /** Determines if the deal has a lender that allows balloon payments */\r\n isBalloon: boolean = false;\r\n maxDaysToFirstPayment?: any = null;\r\n selectedDaysToFirstPayment?: any = null;\r\n finalMonthlyPayment?: any = null;\r\n term1?: FIMenuLoanTerm = new FIMenuLoanTerm();\r\n term2?: FIMenuLoanTerm = new FIMenuLoanTerm();\r\n term3?: FIMenuLoanTerm = new FIMenuLoanTerm();\r\n\r\n static validationTypes = {\r\n TERMS: 'TERMS',\r\n DEFAULT: 'DEFAULT',\r\n };\r\n\r\n constructor(init?: Partial) {\r\n if (init) {\r\n this.acceptedTerm = init?.acceptedTerm;\r\n this.line5limit = init?.line5limit;\r\n this.additionalDownPayment = init?.additionalDownPayment;\r\n this.isBalloon = init?.isBalloon ?? false;\r\n this.maxDaysToFirstPayment = init?.maxDaysToFirstPayment;\r\n this.selectedDaysToFirstPayment = init?.selectedDaysToFirstPayment;\r\n this.finalMonthlyPayment = init?.finalMonthlyPayment;\r\n this.term1 = new FIMenuLoanTerm(init?.term1);\r\n this.term2 = new FIMenuLoanTerm(init?.term2);\r\n this.term3 = new FIMenuLoanTerm(init?.term3);\r\n }\r\n }\r\n getAcceptedTerm() {\r\n if (this.acceptedTerm) {\r\n if (this.acceptedTerm === 1 && this.term1) return this.term1;\r\n if (this.acceptedTerm === 2 && this.term2) return this.term2;\r\n if (this.acceptedTerm === 3 && this.term3) return this.term3;\r\n }\r\n return null;\r\n }\r\n allTerms() {\r\n return [this.term1, this.term2, this.term3].filter(term => term.isChoice());\r\n }\r\n availableTerms() {\r\n return [this.term1, this.term2, this.term3].filter(term => term.isAvailable());\r\n }\r\n\r\n atLeastOneBalloonAmount() {\r\n return (\r\n (this.term1.balloonAmount != null && this.term1.balloonAmount > 0)\r\n || (this.term2.balloonAmount != null && this.term2.balloonAmount > 0)\r\n || (this.term3.balloonAmount != null && this.term3.balloonAmount > 0)\r\n );\r\n }\r\n\r\n resetBalloonAmounts() {\r\n this.term1.balloonAmount = null;\r\n this.term2.balloonAmount = null;\r\n this.term3.balloonAmount = null;\r\n }\r\n\r\n validation(fimenu: FIMenu, type = FIMenuLoanTerms.validationTypes.DEFAULT) {\r\n const data = {\r\n maxDaysToFirstPayment: {},\r\n finalMonthlyPayment: {},\r\n term1: {\r\n term: {},\r\n buyrate: {},\r\n sellrate: {},\r\n balloonAmount: {},\r\n },\r\n term2: {\r\n term: {},\r\n buyrate: {},\r\n sellrate: {},\r\n balloonAmount: {},\r\n },\r\n term3: {\r\n term: {},\r\n buyrate: {},\r\n sellrate: {},\r\n balloonAmount: {},\r\n },\r\n };\r\n\r\n switch (type) {\r\n case FIMenuLoanTerms.validationTypes.DEFAULT:\r\n return data;\r\n case FIMenuLoanTerms.validationTypes.TERMS:\r\n if (fimenu.isFinance()) {\r\n const t1BuyRateMax = fimenu.loanTerms.term1.sellrate ?? 0;\r\n const t2BuyRateMax = fimenu.loanTerms.term2.sellrate ?? 0;\r\n const t3BuyRateMax = fimenu.loanTerms.term3.sellrate ?? 0;\r\n\r\n data.maxDaysToFirstPayment = { required, minValue: minValue(30) };\r\n data.term1 = {\r\n term: { required, minValue: minValue(1) },\r\n buyrate: { required, minValue: minValue(t1BuyRateMax - 3), maxValue: maxValue(t1BuyRateMax) },\r\n sellrate: { required, minValue: minValue(fimenu.loanTerms.term1.buyrate) },\r\n balloonAmount: {\r\n required: helpers.withMessage(\r\n balloonValidationMessage,\r\n requiredIf(() => fimenu.loanTerms.isBalloon),\r\n ),\r\n },\r\n };\r\n\r\n if (fimenu.loanTerms.term2.term) {\r\n data.term2.buyrate = { minValue: minValue(t2BuyRateMax - 3), maxValue: maxValue(t2BuyRateMax) };\r\n data.term2.sellrate = { required, minValue: minValue(fimenu.loanTerms.term2.buyrate) };\r\n data.term2.balloonAmount = {\r\n required: helpers.withMessage(\r\n balloonValidationMessage,\r\n requiredIf(() => fimenu.loanTerms.isBalloon),\r\n ),\r\n };\r\n }\r\n\r\n if (fimenu.loanTerms.term3.term) {\r\n data.term3.buyrate = { minValue: minValue(t3BuyRateMax - 3), maxValue: maxValue(t3BuyRateMax) };\r\n data.term3.sellrate = { required, minValue: minValue(fimenu.loanTerms.term3.buyrate) };\r\n data.term3.balloonAmount = {\r\n required: helpers.withMessage(\r\n balloonValidationMessage,\r\n requiredIf(() => fimenu.loanTerms.isBalloon),\r\n ),\r\n };\r\n }\r\n } else if (fimenu.isDraft()) {\r\n if (fimenu.loanTerms.term1.term) {\r\n data.term1.term = { minValue: minValue(0) };\r\n data.term1.sellrate = { minValue: minValue(0) };\r\n data.term1.buyrate = { minValue: minValue(0) };\r\n }\r\n\r\n if (fimenu.loanTerms.term2.term) {\r\n data.term2.term = { minValue: minValue(0) };\r\n data.term2.sellrate = { minValue: minValue(0) };\r\n data.term2.buyrate = { minValue: minValue(0) };\r\n }\r\n\r\n if (fimenu.loanTerms.term3.term) {\r\n data.term3.term = { minValue: minValue(0) };\r\n data.term3.sellrate = { minValue: minValue(0) };\r\n data.term3.buyrate = { minValue: minValue(0) };\r\n }\r\n }\r\n return data;\r\n default:\r\n return data;\r\n }\r\n }\r\n}\r\n","import moment from 'moment';\r\n\r\nconst currency2 = (value: number) => {\r\n //console.log('in currency2',value)\r\n if (value != null && value >= 0) {\r\n //console.log('in return')\r\n return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });\r\n }\r\n return null;\r\n};\r\n\r\nconst prettyDate = (value: any) => {\r\n return moment(value, ['MM/DD/YYYY', 'YYYY-MM-DDTHH:mm:ss.SSSZ']).format('MM/DD/YYYY');\r\n};\r\n\r\nconst prettyDateTime = (value: any) => {\r\n return moment(value, ['MM/DD/YYYY', 'YYYY-MM-DDTHH:mm:ss.SSSZ']).format('MM/DD/YYYY hh:mm ');\r\n};\r\n\r\nconst prettyNumber = (value: any, decimals?: any) => {\r\n return value.toLocaleString(undefined, { maximumFractionDigits: decimals });\r\n};\r\n\r\nconst filters = {\r\n currency2,\r\n prettyDate,\r\n prettyDateTime,\r\n prettyNumber,\r\n};\r\n\r\nexport type FiltersPlugin = typeof filters;\r\n\r\nexport default filters;\r\n","import moment from 'moment';\r\nimport util from '@core/services/util'\r\nimport filters from '@core/services/filters'\r\n\r\nconst { prettyNumber } = filters;\r\n\r\nexport default class FIMenuVehicleWarrantyCoverage {\r\n constructor(init) {\r\n if (init) {\r\n this.months = init.months;\r\n this.miles = init.miles;\r\n } else {\r\n this.months = null;\r\n this.miles = null;\r\n }\r\n }\r\n\r\n milesLeft(vehicleMiles) {\r\n let retVal = null;\r\n if (this.miles && (vehicleMiles || vehicleMiles === 0)) {\r\n retVal = this.miles - vehicleMiles;\r\n }\r\n return retVal;\r\n }\r\n\r\n monthsLeft(warrantyStartDate) {\r\n if (this.months && warrantyStartDate) {\r\n return util.toMoment(warrantyStartDate).add(this.months, 'month').diff(moment(), 'months', true);\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n\r\n monthsDisplay(inventoryType, warrantyStartDate) {\r\n //console.log('monthsDisplay', inventoryType, warrantyStartDate, this.months);\r\n if (inventoryType) {\r\n if (inventoryType.toLowerCase() == 'new' && this.months)\r\n return prettyNumber(this.months, 0);\r\n else if (this.monthsLeft(warrantyStartDate))\r\n return prettyNumber(this.monthsLeft(warrantyStartDate), 0);\r\n else\r\n return '';\r\n } else\r\n return '';\r\n }\r\n\r\n milesDisplay(inventoryType, vehicleMiles) {\r\n //console.log('milesDisplay', inventoryType, vehicleMiles, this.miles);\r\n if (inventoryType) {\r\n if (inventoryType.toLowerCase() == 'new' && this.miles)\r\n return prettyNumber(this.miles, 0)\r\n else if (this.milesLeft(vehicleMiles))\r\n return prettyNumber(this.milesLeft(vehicleMiles), 0)\r\n else\r\n return '';\r\n } else\r\n return '';\r\n }\r\n\r\n valid(vehicleMiles, warrantyStartDate) {\r\n\r\n let valid = false;\r\n let overMiles = false;\r\n let overTerm = false;\r\n\r\n if (this.miles || this.months) {\r\n valid = true;\r\n\r\n if (vehicleMiles > this.miles)\r\n overMiles = true;\r\n\r\n if (this.months)\r\n overTerm = moment() > util.toMoment(warrantyStartDate).add(this.months, 'month');\r\n\r\n if (overMiles || overTerm)\r\n valid = false;\r\n }\r\n\r\n return valid;\r\n }\r\n\r\n\r\n}","import FIMenuVehicleWarrantyCoverage from './FIMenuVehicleWarrantyCoverage'\r\nimport moment from 'moment'\r\nimport util from '@core/services/util'\r\nimport { VINInfo } from './VINInfo';\r\nimport FIMenuCarFax from './FIMenuCarFax';\r\n\r\ntype WarrantyCoverages = {\r\n basic: FIMenuVehicleWarrantyCoverage;\r\n drivetrain: FIMenuVehicleWarrantyCoverage;\r\n roadside: FIMenuVehicleWarrantyCoverage;\r\n maintenance: FIMenuVehicleWarrantyCoverage;\r\n}\r\n\r\n\r\nexport default class FIMenuVehicleWarranty {\r\n warrantyStartDate: any;\r\n isLoanerIncluded: any;\r\n isCertified: any;\r\n warranties: WarrantyCoverages\r\n\r\n constructor(init?: Partial) {\r\n if (init) {\r\n this.warrantyStartDate = init.warrantyStartDate;\r\n this.isLoanerIncluded = init.isLoanerIncluded;\r\n this.isCertified = init.isCertified;\r\n this.warranties =\r\n {\r\n basic: new FIMenuVehicleWarrantyCoverage(init.warranties?.basic),\r\n drivetrain: new FIMenuVehicleWarrantyCoverage(init.warranties?.drivetrain),\r\n roadside: new FIMenuVehicleWarrantyCoverage(init.warranties?.roadside),\r\n maintenance: new FIMenuVehicleWarrantyCoverage(init.warranties?.maintenance)\r\n\r\n }\r\n } else {\r\n this.warrantyStartDate = null;\r\n this.isLoanerIncluded = false;\r\n this.isCertified = false;\r\n this.warranties =\r\n {\r\n basic: new FIMenuVehicleWarrantyCoverage(),\r\n drivetrain: new FIMenuVehicleWarrantyCoverage(),\r\n roadside: new FIMenuVehicleWarrantyCoverage(),\r\n maintenance: new FIMenuVehicleWarrantyCoverage()\r\n\r\n }\r\n }\r\n\r\n }\r\n\r\n updateUsingVINLookupResponse(vinResponse: VINInfo, carFax?: FIMenuCarFax) {\r\n this.warranties.basic.miles = null\r\n this.warranties.basic.months = null\r\n this.warranties.drivetrain.miles = null\r\n this.warranties.drivetrain.months = null\r\n this.warranties.roadside.miles = null\r\n this.warranties.roadside.months = null\r\n this.warranties.maintenance.miles = null\r\n this.warranties.maintenance.months = null\r\n\r\n if (vinResponse && vinResponse.warrantyInfo) {\r\n this.warranties.basic.miles = vinResponse.warrantyInfo.basicMiles;\r\n this.warranties.basic.months = vinResponse.warrantyInfo.basicMonths;\r\n this.warranties.drivetrain.miles = vinResponse.warrantyInfo.drivetrainMiles;\r\n this.warranties.drivetrain.months = vinResponse.warrantyInfo.drivetrainMonths;\r\n this.warranties.roadside.miles = vinResponse.warrantyInfo.roadsideMiles;\r\n this.warranties.roadside.months = vinResponse.warrantyInfo.roadsideMonths;\r\n this.warranties.maintenance.miles = vinResponse.warrantyInfo.maintenanceMiles;\r\n this.warranties.maintenance.months = vinResponse.warrantyInfo.maintenanceMonths;\r\n }\r\n }\r\n\r\n updateUsingVINCarFaxLookup(vinResponse: VINInfo, carFax: FIMenuCarFax) {\r\n const maximunAllowedDifferenceInYears = 1;\r\n\r\n //Auto-populating WarrantyStartDate\r\n if (carFax?.warrantyStartDateTime) {\r\n this.warrantyStartDate = carFax.warrantyStartDateTime;\r\n }\r\n //Populating missing warranty info from VinDecoder with CarFax info if available\r\n if (carFax && vinResponse?.warrantyInfo &&\r\n (!vinResponse.warrantyInfo.basicMiles || !vinResponse.warrantyInfo.basicMonths ||\r\n !vinResponse.warrantyInfo.drivetrainMiles || !vinResponse.warrantyInfo.drivetrainMonths ||\r\n !vinResponse.warrantyInfo.roadsideMiles || !vinResponse.warrantyInfo.roadsideMonths)) {\r\n\r\n if (!vinResponse.warrantyInfo.basicMiles && carFax.originalBasicMiles) {\r\n this.warranties.basic.miles = carFax.originalBasicMiles;\r\n }\r\n if (!vinResponse.warrantyInfo.basicMonths && carFax.originalBasicMonths) {\r\n this.warranties.basic.months = carFax.originalBasicMonths;\r\n }\r\n\r\n if (!vinResponse.warrantyInfo.drivetrainMiles && carFax.originalDrivetrainMiles) {\r\n this.warranties.drivetrain.miles = carFax.originalDrivetrainMiles;\r\n }\r\n if (!vinResponse.warrantyInfo.drivetrainMonths && carFax.originalDrivetrainMonths) {\r\n this.warranties.drivetrain.months = carFax.originalDrivetrainMonths;\r\n }\r\n\r\n if (!vinResponse.warrantyInfo.roadsideMiles && carFax.originalRoadsideMiles) {\r\n this.warranties.roadside.miles = carFax.originalRoadsideMiles;\r\n }\r\n if (!vinResponse.warrantyInfo.roadsideMonths && carFax.originalRoadsideMonths) {\r\n this.warranties.roadside.months = carFax.originalRoadsideMonths;\r\n }\r\n }\r\n }\r\n}","import CoverageTerm from './CoverageTerm';\r\nimport FIMenuCustomer from './FIMenuCustomer';\r\nimport FIMenuCustomerViewed from './FIMenuCustomerViewed';\r\nimport FIMenuLeaseTerms from './FIMenuLeaseTerms';\r\nimport FIMenuLender from './FIMenuLender';\r\nimport FIMenuLoanTerms from './FIMenuLoanTerms';\r\nimport FIMenuVehicleWarranty from './FIMenuVehicleWarranty';\r\n\r\nexport default class FIMenuForCustomerMeeting {\r\n language: string = null;\r\n storeInfo: any = {}; // storeInfo is used in customer application\r\n storeCode: string = null;\r\n storeState: string = null;\r\n coverageTerms: CoverageTerm[] = [];\r\n customerViewed: FIMenuCustomerViewed[] = [];\r\n customer:CustomerLite = null;\r\n coCustomer:CustomerLite = null;\r\n hasCoSigner: boolean = null;\r\n googleReviewsURL: string = '';\r\n\r\n dealType: string = null;\r\n dealDate: string = null;\r\n otd: number = null;\r\n\r\n lender: LenderLite = null;\r\n leaseTerms: FIMenuLeaseTerms = new FIMenuLeaseTerms();\r\n loanTerms: FIMenuLoanTerms = new FIMenuLoanTerms();\r\n isDraft: boolean = null;\r\n pricesReady: boolean = null;\r\n calculatedFinalNumbers: ICalculatedFinalNumbers = null;\r\n disclaimerPayment: IDisclaimerPayment = null;\r\n\r\n vin: string = null;\r\n inventoryType: string = null;\r\n vehicle: any = null;\r\n vehicleMiles: number = null;\r\n vehicleWarranty = new FIMenuVehicleWarranty();\r\n currentPacket: any = null;\r\n fimanagerSignature: string = null;\r\n\r\n constructor(init?: any) {\r\n if (init) {\r\n this.language = init.language ?? null;\r\n this.storeInfo = init.storeInfo ?? {};\r\n this.storeCode = init.storeCode ?? null;\r\n this.storeState = init.storeState ?? null;\r\n this.coverageTerms = init.coverageTerms ? [...init.coverageTerms] : [];\r\n this.customerViewed = init.customerViewed ? [...init.customerViewed] : [];\r\n this.customer = init.customer ? this.getFilteredCustomerData(init.customer) : null;\r\n this.coCustomer = init.coCustomer ? this.getFilteredCustomerData(init.coCustomer) : null;\r\n this.hasCoSigner = init.hasCoSigner ?? null;\r\n this.googleReviewsURL = init.googleReviewsURL ?? '';\r\n\r\n this.dealType = init.dealType ?? null;\r\n this.dealDate = init.dealDate ?? null;\r\n this.otd = init.otd ?? null;\r\n\r\n this.lender = init.lender ? this.getFilteredLenderData(init.lender) : null;\r\n this.leaseTerms = init.leaseTerms ? new FIMenuLeaseTerms(init.leaseTerms) : new FIMenuLeaseTerms();\r\n this.loanTerms = init.loanTerms ? new FIMenuLoanTerms(init.loanTerms) : new FIMenuLoanTerms();\r\n this.isDraft = init.isDraft ?? null;\r\n this.pricesReady = init.pricesReady ?? null;\r\n this.calculatedFinalNumbers = init.calculatedFinalNumbers ?? ({} as ICalculatedFinalNumbers);\r\n this.disclaimerPayment = init.disclaimerPayment ?? ({} as IDisclaimerPayment);\r\n\r\n this.vin = init.vin ?? null;\r\n this.inventoryType = init.inventoryType ?? null;\r\n this.vehicle = init.vehicle ? { ...init.vehicle } : null;\r\n this.vehicleMiles = init.vehicleMiles ?? null;\r\n this.vehicleWarranty = init.vehicleWarranty ? new FIMenuVehicleWarranty(init.vehicleWarranty) : new FIMenuVehicleWarranty();\r\n \r\n this.currentPacket = init.currentPacket ? init.currentPacket : null;\r\n }\r\n\r\n }\r\n\r\n getFilteredCustomerData(fimenuCustomer: FIMenuCustomer): CustomerLite {\r\n return {\r\n fullName: fimenuCustomer.fullName,\r\n currentSignatureId: fimenuCustomer.currentSignatureId,\r\n currentInitialsId: fimenuCustomer.currentInitialsId,\r\n }\r\n }\r\n\r\n getFilteredLenderData(fimenuLender: FIMenuLender): LenderLite {\r\n return {\r\n lenderName: fimenuLender.lenderName,\r\n lenderCode: fimenuLender.lenderCode,\r\n }\r\n }\r\n}\r\ninterface CustomerLite {\r\n fullName: string;\r\n currentSignatureId: string;\r\n currentInitialsId: string;\r\n}\r\n\r\ninterface LenderLite {\r\n lenderName: string;\r\n lenderCode: string;\r\n}\r\n\r\ninterface IDisclaimerPayment {\r\n basePayment: number;\r\n}\r\n\r\ninterface ICalculatedFinalNumbers {\r\n termNumbers: any;\r\n [key: number]: any;\r\n}\r\n\r\n\r\n// interface IDealTerm {\r\n// term: number,\r\n// numbers: IDealTermDetails\r\n// }\r\n\r\n// interface IDealTermDetails {\r\n// baseAmount: number,\r\n// basePayment: number,\r\n// dealType: string,\r\n// finalAmount: number,\r\n// finalPayment: number,\r\n// finalPaymentAtBuyRate: number,\r\n// }\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n\r\n","import { createRouter, createWebHistory } from \"vue-router\";\r\n//import Presentation from 'views/Presentation'\r\n//import StandBy from 'views/StandBy'\r\n//import MeetingRoom from 'views/MeetingRoom'\r\n//import InStoreConnection from 'views/InStoreConnection'\r\n//import RemoteConnection from 'views/RemoteConnection'\r\n//import PaperworkSigning from 'views/PaperworkSigning'\r\n//import CoverageSelection from 'views/CoverageSelection'\r\n//import CreditAppLogin from 'views/CreditAppLogin'\r\n//import CreditAppMain from 'views/CreditAppMain'\r\n//import CashbashDisplay from 'views/CashbashDisplay'\r\n//import CreditAppCreateApplication from 'views/CreditAppCreateApplication'\r\n//import CustomerChecklist from 'views/CustomerChecklist'\r\n//import PrivacyPolicy from 'views/PrivacyPolicy'\r\n//import Redirect from 'views/Redirect'\r\n//import PlaidLinkPortal from 'views/PlaidLinkPortal'\r\n//import ESignMobile from 'views/ESignMobile'\r\nimport ApplicationsSettingsLoader from \"@core/classes/Applications/ApplicationsSettingsLoader\";\r\nimport CustomerHelper from \"@core/helpers/Customer/customer-helper\";\r\n\r\nconst router = createRouter({\r\n history: createWebHistory(),\r\n routes: [\r\n {\r\n path: \"/redirect\",\r\n name: \"redirect\",\r\n component: () => import(`@/views/Redirect.vue`),\r\n //component: Redirect\r\n },\r\n {\r\n path: \"/privacy-policy\",\r\n name: \"PrivacyPolicy\",\r\n component: () => import(`@/views/PrivacyPolicy.vue`),\r\n //component: PrivacyPolicy\r\n },\r\n {\r\n path: \"/help\",\r\n name: \"help\",\r\n component: () => import(`@/views/Help.vue`),\r\n //component: Help\r\n },\r\n {\r\n path: \"/meetingroom/\",\r\n component: () => import(`@/views/MeetingRoomWrapper.vue`),\r\n name: \"meetingroomWrapper\",\r\n children: [\r\n //{\r\n // path: '', // default child route, could redirect or render something else if needed\r\n // redirect: 'inStoreConnection'\r\n //},\r\n {\r\n path: \"inStoreConnection\",\r\n name: \"inStoreConnection\",\r\n component: () => import(`@/views/InStoreConnection.vue`),\r\n },\r\n {\r\n path: \"disconnected\",\r\n name: \"meetingRoomDisconnected\",\r\n component: () => import(`@/views/MeetingRoomDisconnected.vue`),\r\n },\r\n {\r\n path: \":code\",\r\n name: \"meetingroomCode\",\r\n component: () => import(`@/views/MeetingRoom.vue`),\r\n children: [\r\n {\r\n path: \"stand-by\",\r\n name: \"stand-by\",\r\n component: () => import(`@/views/StandBy.vue`),\r\n },\r\n {\r\n path: \"presentation\",\r\n name: \"presentation\",\r\n component: () => import(`@/views/Presentation.vue`),\r\n },\r\n {\r\n path: \"coverage-selection\",\r\n name: \"coverage-selection\",\r\n component: () => import(`@/views/CoverageSelection.vue`),\r\n },\r\n {\r\n path: \"paperwork-signing\",\r\n name: \"paperwork-signing\",\r\n component: () => import(`@/views/PaperworkSigning.vue`),\r\n },\r\n ],\r\n },\r\n ],\r\n },\r\n {\r\n path: \"/cashbashdisplay/\",\r\n name: \"cashbashdisplay\",\r\n component: () => import(`@/views/CashbashDisplay.vue`),\r\n //component: CashbashDisplay\r\n },\r\n {\r\n path: \"/customer-checklist\",\r\n name: \"CustomerChecklist\",\r\n component: () => import(`@/views/CustomerChecklist.vue`),\r\n //component: CustomerChecklist\r\n },\r\n {\r\n path: '/plaid',\r\n name: 'PlaidLinkPortal',\r\n component: () => import(`@/views/PlaidLinkPortal.vue`)\r\n },\r\n {\r\n path: '/plaid/income-verification',\r\n name: 'PlaidProofOfIncome',\r\n component: () => import(`@/views/PlaidProofOfIncome.vue`)\r\n },\r\n {\r\n path: \"/e-sign\",\r\n name: \"ESign\",\r\n component: () => import(`@/views/ESignMobile.vue`),\r\n //component: ESignMobile\r\n },\r\n {\r\n path: \"/service-lookup\",\r\n name: \"ServiceLookup\",\r\n component: () => import(`@/views/ServiceLookup.vue`),\r\n },\r\n {\r\n path: \"/insurance\",\r\n name: \"InsurancePortal\",\r\n component: () => import(`@/views/InsurancePortal.vue`),\r\n },\r\n //NOTE: This is the first page after the OTP for customer app\r\n {\r\n path: \"/creditapp/creditappQuestionnaire\",\r\n name: \"creditappQuestionnaire\",\r\n component: () => import(`@/views/CreditAppMain.vue`),\r\n beforeEnter: ApplicationsSettingsLoader.beforeEnter,\r\n },\r\n //NOTE: This is the prefilled data page.\r\n {\r\n path: \"/creditapp/\",\r\n name: \"creditappLogin\",\r\n component: () => import(`@/views/CreditAppCreateApplication.vue`),\r\n beforeEnter: ApplicationsSettingsLoader.beforeEnter,\r\n },\r\n //NOTE: The OTP page for the customer portal AND the customer application\r\n {\r\n path: \"/customer-portal/phoneVerification\",\r\n name: \"OTPPage\",\r\n component: () => import(`@/views/OTPPage.vue`),\r\n beforeEnter: ApplicationsSettingsLoader.beforeEnter,\r\n },\r\n {\r\n //NOTE: After the OTP is entered to get into the customer portal, the customer then gets to this page that chooses where to send them based on logic. This does not have a view at all, its just for pushing/redirecting.\r\n path: \"/customer-portal/redirect-page\",\r\n name: \"CustomerPortal\",\r\n component: () => import(`@/views/customerPortal/CustomerPortal.vue`),\r\n beforeEnter: ApplicationsSettingsLoader.beforeEnter,\r\n },\r\n {\r\n path: \"/customer-portal/no-access\",\r\n name: \"no-access\",\r\n component: () => import(`@/views/customerPortal/NotFoundPage.vue`),\r\n beforeEnter: ApplicationsSettingsLoader.beforeEnter,\r\n },\r\n {\r\n path: \"/customer-portal/:id?\",\r\n name: \"customer-portal\",\r\n beforeEnter: async (to, from, next) => {\r\n const localStorageId = localStorage.getItem('customerId') ?? null;\r\n const queryId = to.query.id as string;\r\n const hasIdInLocalStorage = localStorageId === queryId;\r\n\r\n if (!hasIdInLocalStorage) {\r\n try {\r\n const generatedLink = await CustomerHelper.getCustomerAndGenerateLink(queryId)\r\n window.location.href = generatedLink;\r\n\r\n } catch (error) {\r\n console.error(\"error\", error)\r\n next({ name: 'no-access' });\r\n } \r\n } else {\r\n await ApplicationsSettingsLoader.loadApplicationSettings()\r\n next();\r\n }\r\n },\r\n component: () => import(`@/views/customerPortal/Layout.vue`),\r\n meta: { requiresCustomerData: true },\r\n children: [\r\n {\r\n path: \"\",\r\n name: \"home\",\r\n component: () => import(`@/views/customerPortal/HomePage.vue`),\r\n },\r\n {\r\n path: \"profile\",\r\n name: \"profile\",\r\n component: () => import(`@/views/customerPortal/ProfilePage.vue`),\r\n },\r\n {\r\n path: \"garage\",\r\n name: \"garage\",\r\n component: () => import(`@/views/customerPortal/GaragePage.vue`),\r\n },\r\n {\r\n path: \"identity-verification\",\r\n name: \"identity-verification\",\r\n component: () => import(`@/views/customerPortal/IdentityVerificationPage.vue`),\r\n },\r\n {\r\n path: \"business\",\r\n name: \"business\",\r\n component: () => import(`@/views/customerPortal/BusinessPage.vue`),\r\n },\r\n {\r\n path: \"add-business\",\r\n name: \"add-business\",\r\n component: () => import(`@/views/customerPortal/AddBusinessPage.vue`),\r\n },\r\n {\r\n path: \"add-vehicle\",\r\n name: \"add-vehicle\",\r\n component: () => import(`@/views/customerPortal/AddVehiclePage.vue`),\r\n },\r\n {\r\n path: \"*\",\r\n name: \"not-found\",\r\n component: () => import(`@/views/customerPortal/NotFoundPage.vue`),\r\n },\r\n ],\r\n },\r\n ],\r\n});\r\n\r\n//Preventing navigation to the previous route only if the route does not contain customer portal\r\nrouter.afterEach((to, from, next) => {\r\n if (!to.path.includes(\"/customer-portal\")) {\r\n history.pushState(null, null, location.href);\r\n // This event always fires when history is changed, does not matter about the if stmt above. \r\n window.onpopstate = function () {\r\n if(!window.location.pathname.includes(\"/customer-portal\")) {\r\n history.go(1);\r\n }\r\n };\r\n }\r\n});\r\nexport default router;\r\n","import { IPanelMenuSection } from \"@core/_interfaces/ComponentProps\";\r\n\r\nexport class SaturnGlobalPlugin {\r\n selectedStore: any;\r\n dealNumber: string = null;\r\n isAdminView: boolean = false;\r\n isManageOverridesEnabled: boolean = false;\r\n customerWindow: any = null;\r\n maxMilesToBeConsideredNewCar: any = null;\r\n Lenders: any[];\r\n r1CreditAppField: any = null;\r\n stores: any = null\r\n\r\n constructor(init?: SaturnGlobalPlugin) {\r\n if (init) {\r\n Object.assign(this, init);\r\n }\r\n }\r\n}\r\n\r\nexport class StaticViewsPlugin {\r\n adminPages: IPanelMenuSection[];\r\n utilitiesPages: IPanelMenuSection[];\r\n reportPages: IPanelMenuSection[];\r\n\r\n constructor(init?: StaticViewsPlugin) {\r\n if (init) {\r\n this.adminPages = init.adminPages;\r\n this.utilitiesPages = init.utilitiesPages;\r\n this.reportPages = init.reportPages;\r\n }\r\n }\r\n}\r\n","import { App, CSSProperties, reactive, ref } from 'vue';\r\nimport { SaturnGlobalPlugin, StaticViewsPlugin } from '@core/classes/StaticClasses';\r\nimport settings from 'settings'\r\n\r\nexport type $gridType = (colTemplate: any, gap?: string) => CSSProperties\r\n\r\n\r\nexport default {\r\n\r\n install(app: any) {\r\n\r\n const $static = new StaticViewsPlugin({\r\n adminPages: [\r\n { isActive: false, isAdmin: true, name: 'Global Settings', stateName: 'admin-global-settings' },\r\n { isActive: false, isAdmin: false, name: 'Users', stateName: 'admin-users' },\r\n { isActive: false, isAdmin: true, name: 'Stores', stateName: 'admin-stores' },\r\n { isActive: false, isAdmin: true, name: 'Products', stateName: 'admin-products' },\r\n { isActive: false, isAdmin: true, name: 'Lenders', stateName: 'admin-lenders' },\r\n { isActive: false, isAdmin: true, name: 'Reserve Profit Calculations', stateName: 'admin-reserve-profit-calculations' },\r\n { isActive: false, isAdmin: true, name: 'Surcharges', stateName: 'admin-surcharges' },\r\n { isActive: false, isAdmin: true, name: 'Providers', stateName: 'admin-providers' },\r\n { isActive: false, isAdmin: true, name: 'Warranty Expiration Rules', stateName: 'admin-warranty-expiration-rules' },\r\n { isActive: false, isAdmin: true, name: 'Deal Checklist Items', stateName: 'admin-deal-checklist-items' },\r\n { isActive: false, isAdmin: true, name: 'Term Spreads', stateName: 'admin-term-spreads' },\r\n { isActive: false, isAdmin: true, name: 'Deviation Reasons', stateName: 'admin-deviation-reasons' },\r\n { isActive: false, isAdmin: true, name: 'Contract In Transit Statuses', stateName: 'admin-contract-in-transit-statuses' },\r\n { isActive: false, isAdmin: true, name: 'Deal Flow Statuses', stateName: 'admin-deal-flow-statuses' },\r\n { isActive: false, isAdmin: true, name: 'Positions', stateName: 'admin-positions' },\r\n { isActive: false, isAdmin: true, name: 'Sale Types', stateName: 'admin-sale-types' },\r\n { isActive: false, isAdmin: true, name: 'Deal Types', stateName: 'admin-deal-types' },\r\n { isActive: false, isAdmin: true, name: 'Vehicle Types', stateName: 'admin-vehicle-types' },\r\n { isActive: false, isAdmin: true, name: 'Document Types', stateName: 'admin-document-types' },\r\n { isActive: false, isAdmin: true, name: 'Advertisement Types', stateName: 'admin-advertisement-types' },\r\n { isActive: false, isAdmin: true, name: 'Advertisement Sources', stateName: 'admin-advertisement-sources' },\r\n { isActive: false, isAdmin: true, name: 'Manage CashBash', stateName: 'admin-manage-cashbash' },\r\n { isActive: false, isAdmin: true, name: 'General Mappings', stateName: 'admin-general-mapping' },\r\n { isActive: false, isAdmin: true, name: 'Legal Terms', stateName: 'admin-legal-terms' },\r\n { isActive: false, isAdmin: false, name: 'Saturn Applications', stateName: 'admin-saturn-applications' },\r\n { isActive: false, isAdmin: true, name: 'Credit Bureaus', stateName: 'admin-credit-bureaus' },\r\n { isActive: false, isAdmin: true, name: 'CarFax Credentials', stateName: 'admin-carfax-credentials' },\r\n { isActive: false, isAdmin: true, name: 'OAuth Users', stateName: 'admin-oauth' },\r\n ],\r\n utilitiesPages:\r\n settings.environmentName != 'PRODUCTION' ?\r\n [\r\n { isActive: false, name: 'Active Deals', stateName: 'utilities-active-deals' },\r\n { isActive: false, name: 'Copy From Production', stateName: 'utilities-copy-from-prod' },\r\n { isActive: false, name: 'Error Logs', stateName: 'utilities-error-logs' },\r\n { isActive: false, name: 'Custom Variables', stateName: 'custom-variables' },\r\n { isActive: false, name: 'Saturn Expressions', stateName: 'utilities-saturn-expressions' },\r\n { isActive: false, name: 'Manage Base Paperwork', stateName: 'utilities-manage-base-paperwork' },\r\n { isActive: false, name: 'Code Editor Themes', stateName: 'utilities-code-editor-themes' },\r\n { isActive: false, name: 'Vehicle Records', stateName: 'utilities-vehicle-records' },\r\n { isActive: false, name: 'Data Definitions', stateName: 'utilities-data-definitions-page'},\r\n { isActive: false, name: 'Broadcast System', stateName: 'utilities-broadcast-system-page'},\r\n { isActive: false, name: 'Plaid Lookup', stateName: 'utilities-plaid-lookup' },\r\n\r\n ] : [\r\n { isActive: false, name: 'Active Deals', stateName: 'utilities-active-deals' },\r\n { isActive: false, name: 'Error Logs', stateName: 'utilities-error-logs' },\r\n { isActive: false, name: 'Vehicle Records', stateName: 'utilities-vehicle-records' },\r\n { isActive: false, name: 'Data Definitions', stateName: 'utilities-data-definitions-page'},\r\n { isActive: false, name: 'Plaid Lookup', stateName: 'utilities-plaid-lookup' },\r\n ],\r\n reportPages: [\r\n { isActive: false, name: 'Products', stateName: 'products-report' },\r\n //{ isActive: false, name: 'My-First-Report', displayName: 'My First Report', stateName: 'report1' },\r\n ]\r\n });\r\n app.config.globalProperties.$static = $static\r\n app.provide(\"$static\", $static);\r\n\r\n const $global = reactive(new SaturnGlobalPlugin({\r\n selectedStore: settings.userStores?.[0],\r\n dealNumber: null,\r\n isAdminView: false,\r\n isManageOverridesEnabled: false,\r\n customerWindow: null,\r\n maxMilesToBeConsideredNewCar: null,\r\n Lenders: [],\r\n r1CreditAppField: null,\r\n stores: settings.userStores,\r\n }));\r\n\r\n app.config.globalProperties.$global = $global;\r\n app.provide(\"$global\", $global);\r\n\r\n const $grid = (colTemplate: any, gap = \"10px\"): CSSProperties => {\r\n const templateValues: string[] = colTemplate.toString().split('-');\r\n let columnTemplate = \"\"\r\n templateValues.forEach(value => {\r\n columnTemplate += ' '\r\n if (value.includes('px') ||\r\n value.includes('%') ||\r\n value.includes('cm') ||\r\n value.includes('mm') ||\r\n value.includes('in') ||\r\n value.includes('pt') ||\r\n value.includes('pc') ||\r\n value.includes('em') ||\r\n value.includes('ex') ||\r\n value.includes('ch') ||\r\n value.includes('rem') ||\r\n value.includes('vw') ||\r\n value.includes('vh') ||\r\n value.includes('vmin') ||\r\n value.includes('vmax')) {\r\n\r\n columnTemplate += value\r\n } else {\r\n columnTemplate += value + 'fr'\r\n }\r\n })\r\n\r\n const gapOutside = gap.split(' ');\r\n const newGapOutside = parseInt(gapOutside[0])\r\n\r\n return {\r\n width: '100%',\r\n display: 'grid',\r\n gridTemplateColumns: columnTemplate,\r\n gridGap: gap,\r\n marginBottom: newGapOutside + 'px',\r\n }\r\n };\r\n app.config.globalProperties.$grid = $grid;\r\n app.provide(\"$grid\", $grid)\r\n\r\n app.config.globalProperties.$sandbox = {\r\n someValue: 1\r\n };\r\n\r\n settings.globalProperties = app.config.globalProperties\r\n }\r\n\r\n}","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n/** Error thrown when an HTTP request fails. */\r\nexport class HttpError extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n * @param {number} statusCode The HTTP status code represented by this error.\r\n */\r\n constructor(errorMessage, statusCode) {\r\n const trueProto = new.target.prototype;\r\n super(`${errorMessage}: Status code '${statusCode}'`);\r\n this.statusCode = statusCode;\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when a timeout elapses. */\r\nexport class TimeoutError extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.TimeoutError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n */\r\n constructor(errorMessage = \"A timeout occurred.\") {\r\n const trueProto = new.target.prototype;\r\n super(errorMessage);\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when an action is aborted. */\r\nexport class AbortError extends Error {\r\n /** Constructs a new instance of {@link AbortError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n */\r\n constructor(errorMessage = \"An abort occurred.\") {\r\n const trueProto = new.target.prototype;\r\n super(errorMessage);\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when the selected transport is unsupported by the browser. */\r\n/** @private */\r\nexport class UnsupportedTransportError extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.UnsupportedTransportError}.\r\n *\r\n * @param {string} message A descriptive error message.\r\n * @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occurred on.\r\n */\r\n constructor(message, transport) {\r\n const trueProto = new.target.prototype;\r\n super(message);\r\n this.transport = transport;\r\n this.errorType = 'UnsupportedTransportError';\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when the selected transport is disabled by the browser. */\r\n/** @private */\r\nexport class DisabledTransportError extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.DisabledTransportError}.\r\n *\r\n * @param {string} message A descriptive error message.\r\n * @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occurred on.\r\n */\r\n constructor(message, transport) {\r\n const trueProto = new.target.prototype;\r\n super(message);\r\n this.transport = transport;\r\n this.errorType = 'DisabledTransportError';\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when the selected transport cannot be started. */\r\n/** @private */\r\nexport class FailedToStartTransportError extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.FailedToStartTransportError}.\r\n *\r\n * @param {string} message A descriptive error message.\r\n * @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occurred on.\r\n */\r\n constructor(message, transport) {\r\n const trueProto = new.target.prototype;\r\n super(message);\r\n this.transport = transport;\r\n this.errorType = 'FailedToStartTransportError';\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when the negotiation with the server failed to complete. */\r\n/** @private */\r\nexport class FailedToNegotiateWithServerError extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.FailedToNegotiateWithServerError}.\r\n *\r\n * @param {string} message A descriptive error message.\r\n */\r\n constructor(message) {\r\n const trueProto = new.target.prototype;\r\n super(message);\r\n this.errorType = 'FailedToNegotiateWithServerError';\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n/** Error thrown when multiple errors have occurred. */\r\n/** @private */\r\nexport class AggregateErrors extends Error {\r\n /** Constructs a new instance of {@link @microsoft/signalr.AggregateErrors}.\r\n *\r\n * @param {string} message A descriptive error message.\r\n * @param {Error[]} innerErrors The collection of errors this error is aggregating.\r\n */\r\n constructor(message, innerErrors) {\r\n const trueProto = new.target.prototype;\r\n super(message);\r\n this.innerErrors = innerErrors;\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n//# sourceMappingURL=Errors.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n/** Represents an HTTP response. */\r\nexport class HttpResponse {\r\n constructor(statusCode, statusText, content) {\r\n this.statusCode = statusCode;\r\n this.statusText = statusText;\r\n this.content = content;\r\n }\r\n}\r\n/** Abstraction over an HTTP client.\r\n *\r\n * This class provides an abstraction over an HTTP client so that a different implementation can be provided on different platforms.\r\n */\r\nexport class HttpClient {\r\n get(url, options) {\r\n return this.send({\r\n ...options,\r\n method: \"GET\",\r\n url,\r\n });\r\n }\r\n post(url, options) {\r\n return this.send({\r\n ...options,\r\n method: \"POST\",\r\n url,\r\n });\r\n }\r\n delete(url, options) {\r\n return this.send({\r\n ...options,\r\n method: \"DELETE\",\r\n url,\r\n });\r\n }\r\n /** Gets all cookies that apply to the specified URL.\r\n *\r\n * @param url The URL that the cookies are valid for.\r\n * @returns {string} A string containing all the key-value cookie pairs for the specified URL.\r\n */\r\n // @ts-ignore\r\n getCookieString(url) {\r\n return \"\";\r\n }\r\n}\r\n//# sourceMappingURL=HttpClient.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n// These values are designed to match the ASP.NET Log Levels since that's the pattern we're emulating here.\r\n/** Indicates the severity of a log message.\r\n *\r\n * Log Levels are ordered in increasing severity. So `Debug` is more severe than `Trace`, etc.\r\n */\r\nexport var LogLevel;\r\n(function (LogLevel) {\r\n /** Log level for very low severity diagnostic messages. */\r\n LogLevel[LogLevel[\"Trace\"] = 0] = \"Trace\";\r\n /** Log level for low severity diagnostic messages. */\r\n LogLevel[LogLevel[\"Debug\"] = 1] = \"Debug\";\r\n /** Log level for informational diagnostic messages. */\r\n LogLevel[LogLevel[\"Information\"] = 2] = \"Information\";\r\n /** Log level for diagnostic messages that indicate a non-fatal problem. */\r\n LogLevel[LogLevel[\"Warning\"] = 3] = \"Warning\";\r\n /** Log level for diagnostic messages that indicate a failure in the current operation. */\r\n LogLevel[LogLevel[\"Error\"] = 4] = \"Error\";\r\n /** Log level for diagnostic messages that indicate a failure that will terminate the entire application. */\r\n LogLevel[LogLevel[\"Critical\"] = 5] = \"Critical\";\r\n /** The highest possible log level. Used when configuring logging to indicate that no log messages should be emitted. */\r\n LogLevel[LogLevel[\"None\"] = 6] = \"None\";\r\n})(LogLevel || (LogLevel = {}));\r\n//# sourceMappingURL=ILogger.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n/** A logger that does nothing when log messages are sent to it. */\r\nexport class NullLogger {\r\n constructor() { }\r\n /** @inheritDoc */\r\n // eslint-disable-next-line\r\n log(_logLevel, _message) {\r\n }\r\n}\r\n/** The singleton instance of the {@link @microsoft/signalr.NullLogger}. */\r\nNullLogger.instance = new NullLogger();\r\n//# sourceMappingURL=Loggers.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { NullLogger } from \"./Loggers\";\r\n// Version token that will be replaced by the prepack command\r\n/** The version of the SignalR client. */\r\nexport const VERSION = \"8.0.7\";\r\n/** @private */\r\nexport class Arg {\r\n static isRequired(val, name) {\r\n if (val === null || val === undefined) {\r\n throw new Error(`The '${name}' argument is required.`);\r\n }\r\n }\r\n static isNotEmpty(val, name) {\r\n if (!val || val.match(/^\\s*$/)) {\r\n throw new Error(`The '${name}' argument should not be empty.`);\r\n }\r\n }\r\n static isIn(val, values, name) {\r\n // TypeScript enums have keys for **both** the name and the value of each enum member on the type itself.\r\n if (!(val in values)) {\r\n throw new Error(`Unknown ${name} value: ${val}.`);\r\n }\r\n }\r\n}\r\n/** @private */\r\nexport class Platform {\r\n // react-native has a window but no document so we should check both\r\n static get isBrowser() {\r\n return !Platform.isNode && typeof window === \"object\" && typeof window.document === \"object\";\r\n }\r\n // WebWorkers don't have a window object so the isBrowser check would fail\r\n static get isWebWorker() {\r\n return !Platform.isNode && typeof self === \"object\" && \"importScripts\" in self;\r\n }\r\n // react-native has a window but no document\r\n static get isReactNative() {\r\n return !Platform.isNode && typeof window === \"object\" && typeof window.document === \"undefined\";\r\n }\r\n // Node apps shouldn't have a window object, but WebWorkers don't either\r\n // so we need to check for both WebWorker and window\r\n static get isNode() {\r\n return typeof process !== \"undefined\" && process.release && process.release.name === \"node\";\r\n }\r\n}\r\n/** @private */\r\nexport function getDataDetail(data, includeContent) {\r\n let detail = \"\";\r\n if (isArrayBuffer(data)) {\r\n detail = `Binary data of length ${data.byteLength}`;\r\n if (includeContent) {\r\n detail += `. Content: '${formatArrayBuffer(data)}'`;\r\n }\r\n }\r\n else if (typeof data === \"string\") {\r\n detail = `String data of length ${data.length}`;\r\n if (includeContent) {\r\n detail += `. Content: '${data}'`;\r\n }\r\n }\r\n return detail;\r\n}\r\n/** @private */\r\nexport function formatArrayBuffer(data) {\r\n const view = new Uint8Array(data);\r\n // Uint8Array.map only supports returning another Uint8Array?\r\n let str = \"\";\r\n view.forEach((num) => {\r\n const pad = num < 16 ? \"0\" : \"\";\r\n str += `0x${pad}${num.toString(16)} `;\r\n });\r\n // Trim of trailing space.\r\n return str.substr(0, str.length - 1);\r\n}\r\n// Also in signalr-protocol-msgpack/Utils.ts\r\n/** @private */\r\nexport function isArrayBuffer(val) {\r\n return val && typeof ArrayBuffer !== \"undefined\" &&\r\n (val instanceof ArrayBuffer ||\r\n // Sometimes we get an ArrayBuffer that doesn't satisfy instanceof\r\n (val.constructor && val.constructor.name === \"ArrayBuffer\"));\r\n}\r\n/** @private */\r\nexport async function sendMessage(logger, transportName, httpClient, url, content, options) {\r\n const headers = {};\r\n const [name, value] = getUserAgentHeader();\r\n headers[name] = value;\r\n logger.log(LogLevel.Trace, `(${transportName} transport) sending data. ${getDataDetail(content, options.logMessageContent)}.`);\r\n const responseType = isArrayBuffer(content) ? \"arraybuffer\" : \"text\";\r\n const response = await httpClient.post(url, {\r\n content,\r\n headers: { ...headers, ...options.headers },\r\n responseType,\r\n timeout: options.timeout,\r\n withCredentials: options.withCredentials,\r\n });\r\n logger.log(LogLevel.Trace, `(${transportName} transport) request complete. Response status: ${response.statusCode}.`);\r\n}\r\n/** @private */\r\nexport function createLogger(logger) {\r\n if (logger === undefined) {\r\n return new ConsoleLogger(LogLevel.Information);\r\n }\r\n if (logger === null) {\r\n return NullLogger.instance;\r\n }\r\n if (logger.log !== undefined) {\r\n return logger;\r\n }\r\n return new ConsoleLogger(logger);\r\n}\r\n/** @private */\r\nexport class SubjectSubscription {\r\n constructor(subject, observer) {\r\n this._subject = subject;\r\n this._observer = observer;\r\n }\r\n dispose() {\r\n const index = this._subject.observers.indexOf(this._observer);\r\n if (index > -1) {\r\n this._subject.observers.splice(index, 1);\r\n }\r\n if (this._subject.observers.length === 0 && this._subject.cancelCallback) {\r\n this._subject.cancelCallback().catch((_) => { });\r\n }\r\n }\r\n}\r\n/** @private */\r\nexport class ConsoleLogger {\r\n constructor(minimumLogLevel) {\r\n this._minLevel = minimumLogLevel;\r\n this.out = console;\r\n }\r\n log(logLevel, message) {\r\n if (logLevel >= this._minLevel) {\r\n const msg = `[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`;\r\n switch (logLevel) {\r\n case LogLevel.Critical:\r\n case LogLevel.Error:\r\n this.out.error(msg);\r\n break;\r\n case LogLevel.Warning:\r\n this.out.warn(msg);\r\n break;\r\n case LogLevel.Information:\r\n this.out.info(msg);\r\n break;\r\n default:\r\n // console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug\r\n this.out.log(msg);\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n/** @private */\r\nexport function getUserAgentHeader() {\r\n let userAgentHeaderName = \"X-SignalR-User-Agent\";\r\n if (Platform.isNode) {\r\n userAgentHeaderName = \"User-Agent\";\r\n }\r\n return [userAgentHeaderName, constructUserAgent(VERSION, getOsName(), getRuntime(), getRuntimeVersion())];\r\n}\r\n/** @private */\r\nexport function constructUserAgent(version, os, runtime, runtimeVersion) {\r\n // Microsoft SignalR/[Version] ([Detailed Version]; [Operating System]; [Runtime]; [Runtime Version])\r\n let userAgent = \"Microsoft SignalR/\";\r\n const majorAndMinor = version.split(\".\");\r\n userAgent += `${majorAndMinor[0]}.${majorAndMinor[1]}`;\r\n userAgent += ` (${version}; `;\r\n if (os && os !== \"\") {\r\n userAgent += `${os}; `;\r\n }\r\n else {\r\n userAgent += \"Unknown OS; \";\r\n }\r\n userAgent += `${runtime}`;\r\n if (runtimeVersion) {\r\n userAgent += `; ${runtimeVersion}`;\r\n }\r\n else {\r\n userAgent += \"; Unknown Runtime Version\";\r\n }\r\n userAgent += \")\";\r\n return userAgent;\r\n}\r\n// eslint-disable-next-line spaced-comment\r\n/*#__PURE__*/ function getOsName() {\r\n if (Platform.isNode) {\r\n switch (process.platform) {\r\n case \"win32\":\r\n return \"Windows NT\";\r\n case \"darwin\":\r\n return \"macOS\";\r\n case \"linux\":\r\n return \"Linux\";\r\n default:\r\n return process.platform;\r\n }\r\n }\r\n else {\r\n return \"\";\r\n }\r\n}\r\n// eslint-disable-next-line spaced-comment\r\n/*#__PURE__*/ function getRuntimeVersion() {\r\n if (Platform.isNode) {\r\n return process.versions.node;\r\n }\r\n return undefined;\r\n}\r\nfunction getRuntime() {\r\n if (Platform.isNode) {\r\n return \"NodeJS\";\r\n }\r\n else {\r\n return \"Browser\";\r\n }\r\n}\r\n/** @private */\r\nexport function getErrorString(e) {\r\n if (e.stack) {\r\n return e.stack;\r\n }\r\n else if (e.message) {\r\n return e.message;\r\n }\r\n return `${e}`;\r\n}\r\n/** @private */\r\nexport function getGlobalThis() {\r\n // globalThis is semi-new and not available in Node until v12\r\n if (typeof globalThis !== \"undefined\") {\r\n return globalThis;\r\n }\r\n if (typeof self !== \"undefined\") {\r\n return self;\r\n }\r\n if (typeof window !== \"undefined\") {\r\n return window;\r\n }\r\n if (typeof global !== \"undefined\") {\r\n return global;\r\n }\r\n throw new Error(\"could not find global\");\r\n}\r\n//# sourceMappingURL=Utils.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { AbortError, HttpError, TimeoutError } from \"./Errors\";\r\nimport { HttpClient, HttpResponse } from \"./HttpClient\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { Platform, getGlobalThis, isArrayBuffer } from \"./Utils\";\r\nexport class FetchHttpClient extends HttpClient {\r\n constructor(logger) {\r\n super();\r\n this._logger = logger;\r\n // Node added a fetch implementation to the global scope starting in v18.\r\n // We need to add a cookie jar in node to be able to share cookies with WebSocket\r\n if (typeof fetch === \"undefined\" || Platform.isNode) {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n const requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n // Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests\r\n this._jar = new (requireFunc(\"tough-cookie\")).CookieJar();\r\n if (typeof fetch === \"undefined\") {\r\n this._fetchType = requireFunc(\"node-fetch\");\r\n }\r\n else {\r\n // Use fetch from Node if available\r\n this._fetchType = fetch;\r\n }\r\n // node-fetch doesn't have a nice API for getting and setting cookies\r\n // fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one\r\n this._fetchType = requireFunc(\"fetch-cookie\")(this._fetchType, this._jar);\r\n }\r\n else {\r\n this._fetchType = fetch.bind(getGlobalThis());\r\n }\r\n if (typeof AbortController === \"undefined\") {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n const requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n // Node needs EventListener methods on AbortController which our custom polyfill doesn't provide\r\n this._abortControllerType = requireFunc(\"abort-controller\");\r\n }\r\n else {\r\n this._abortControllerType = AbortController;\r\n }\r\n }\r\n /** @inheritDoc */\r\n async send(request) {\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n throw new AbortError();\r\n }\r\n if (!request.method) {\r\n throw new Error(\"No method defined.\");\r\n }\r\n if (!request.url) {\r\n throw new Error(\"No url defined.\");\r\n }\r\n const abortController = new this._abortControllerType();\r\n let error;\r\n // Hook our abortSignal into the abort controller\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = () => {\r\n abortController.abort();\r\n error = new AbortError();\r\n };\r\n }\r\n // If a timeout has been passed in, setup a timeout to call abort\r\n // Type needs to be any to fit window.setTimeout and NodeJS.setTimeout\r\n let timeoutId = null;\r\n if (request.timeout) {\r\n const msTimeout = request.timeout;\r\n timeoutId = setTimeout(() => {\r\n abortController.abort();\r\n this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);\r\n error = new TimeoutError();\r\n }, msTimeout);\r\n }\r\n if (request.content === \"\") {\r\n request.content = undefined;\r\n }\r\n if (request.content) {\r\n // Explicitly setting the Content-Type header for React Native on Android platform.\r\n request.headers = request.headers || {};\r\n if (isArrayBuffer(request.content)) {\r\n request.headers[\"Content-Type\"] = \"application/octet-stream\";\r\n }\r\n else {\r\n request.headers[\"Content-Type\"] = \"text/plain;charset=UTF-8\";\r\n }\r\n }\r\n let response;\r\n try {\r\n response = await this._fetchType(request.url, {\r\n body: request.content,\r\n cache: \"no-cache\",\r\n credentials: request.withCredentials === true ? \"include\" : \"same-origin\",\r\n headers: {\r\n \"X-Requested-With\": \"XMLHttpRequest\",\r\n ...request.headers,\r\n },\r\n method: request.method,\r\n mode: \"cors\",\r\n redirect: \"follow\",\r\n signal: abortController.signal,\r\n });\r\n }\r\n catch (e) {\r\n if (error) {\r\n throw error;\r\n }\r\n this._logger.log(LogLevel.Warning, `Error from HTTP request. ${e}.`);\r\n throw e;\r\n }\r\n finally {\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = null;\r\n }\r\n }\r\n if (!response.ok) {\r\n const errorMessage = await deserializeContent(response, \"text\");\r\n throw new HttpError(errorMessage || response.statusText, response.status);\r\n }\r\n const content = deserializeContent(response, request.responseType);\r\n const payload = await content;\r\n return new HttpResponse(response.status, response.statusText, payload);\r\n }\r\n getCookieString(url) {\r\n let cookies = \"\";\r\n if (Platform.isNode && this._jar) {\r\n // @ts-ignore: unused variable\r\n this._jar.getCookies(url, (e, c) => cookies = c.join(\"; \"));\r\n }\r\n return cookies;\r\n }\r\n}\r\nfunction deserializeContent(response, responseType) {\r\n let content;\r\n switch (responseType) {\r\n case \"arraybuffer\":\r\n content = response.arrayBuffer();\r\n break;\r\n case \"text\":\r\n content = response.text();\r\n break;\r\n case \"blob\":\r\n case \"document\":\r\n case \"json\":\r\n throw new Error(`${responseType} is not supported.`);\r\n default:\r\n content = response.text();\r\n break;\r\n }\r\n return content;\r\n}\r\n//# sourceMappingURL=FetchHttpClient.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { AbortError, HttpError, TimeoutError } from \"./Errors\";\r\nimport { HttpClient, HttpResponse } from \"./HttpClient\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { isArrayBuffer } from \"./Utils\";\r\nexport class XhrHttpClient extends HttpClient {\r\n constructor(logger) {\r\n super();\r\n this._logger = logger;\r\n }\r\n /** @inheritDoc */\r\n send(request) {\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n return Promise.reject(new AbortError());\r\n }\r\n if (!request.method) {\r\n return Promise.reject(new Error(\"No method defined.\"));\r\n }\r\n if (!request.url) {\r\n return Promise.reject(new Error(\"No url defined.\"));\r\n }\r\n return new Promise((resolve, reject) => {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open(request.method, request.url, true);\r\n xhr.withCredentials = request.withCredentials === undefined ? true : request.withCredentials;\r\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\r\n if (request.content === \"\") {\r\n request.content = undefined;\r\n }\r\n if (request.content) {\r\n // Explicitly setting the Content-Type header for React Native on Android platform.\r\n if (isArrayBuffer(request.content)) {\r\n xhr.setRequestHeader(\"Content-Type\", \"application/octet-stream\");\r\n }\r\n else {\r\n xhr.setRequestHeader(\"Content-Type\", \"text/plain;charset=UTF-8\");\r\n }\r\n }\r\n const headers = request.headers;\r\n if (headers) {\r\n Object.keys(headers)\r\n .forEach((header) => {\r\n xhr.setRequestHeader(header, headers[header]);\r\n });\r\n }\r\n if (request.responseType) {\r\n xhr.responseType = request.responseType;\r\n }\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = () => {\r\n xhr.abort();\r\n reject(new AbortError());\r\n };\r\n }\r\n if (request.timeout) {\r\n xhr.timeout = request.timeout;\r\n }\r\n xhr.onload = () => {\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = null;\r\n }\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));\r\n }\r\n else {\r\n reject(new HttpError(xhr.response || xhr.responseText || xhr.statusText, xhr.status));\r\n }\r\n };\r\n xhr.onerror = () => {\r\n this._logger.log(LogLevel.Warning, `Error from HTTP request. ${xhr.status}: ${xhr.statusText}.`);\r\n reject(new HttpError(xhr.statusText, xhr.status));\r\n };\r\n xhr.ontimeout = () => {\r\n this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);\r\n reject(new TimeoutError());\r\n };\r\n xhr.send(request.content);\r\n });\r\n }\r\n}\r\n//# sourceMappingURL=XhrHttpClient.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { AbortError } from \"./Errors\";\r\nimport { FetchHttpClient } from \"./FetchHttpClient\";\r\nimport { HttpClient } from \"./HttpClient\";\r\nimport { Platform } from \"./Utils\";\r\nimport { XhrHttpClient } from \"./XhrHttpClient\";\r\n/** Default implementation of {@link @microsoft/signalr.HttpClient}. */\r\nexport class DefaultHttpClient extends HttpClient {\r\n /** Creates a new instance of the {@link @microsoft/signalr.DefaultHttpClient}, using the provided {@link @microsoft/signalr.ILogger} to log messages. */\r\n constructor(logger) {\r\n super();\r\n if (typeof fetch !== \"undefined\" || Platform.isNode) {\r\n this._httpClient = new FetchHttpClient(logger);\r\n }\r\n else if (typeof XMLHttpRequest !== \"undefined\") {\r\n this._httpClient = new XhrHttpClient(logger);\r\n }\r\n else {\r\n throw new Error(\"No usable HttpClient found.\");\r\n }\r\n }\r\n /** @inheritDoc */\r\n send(request) {\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n return Promise.reject(new AbortError());\r\n }\r\n if (!request.method) {\r\n return Promise.reject(new Error(\"No method defined.\"));\r\n }\r\n if (!request.url) {\r\n return Promise.reject(new Error(\"No url defined.\"));\r\n }\r\n return this._httpClient.send(request);\r\n }\r\n getCookieString(url) {\r\n return this._httpClient.getCookieString(url);\r\n }\r\n}\r\n//# sourceMappingURL=DefaultHttpClient.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n// Not exported from index\r\n/** @private */\r\nexport class TextMessageFormat {\r\n static write(output) {\r\n return `${output}${TextMessageFormat.RecordSeparator}`;\r\n }\r\n static parse(input) {\r\n if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n const messages = input.split(TextMessageFormat.RecordSeparator);\r\n messages.pop();\r\n return messages;\r\n }\r\n}\r\nTextMessageFormat.RecordSeparatorCode = 0x1e;\r\nTextMessageFormat.RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode);\r\n//# sourceMappingURL=TextMessageFormat.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { TextMessageFormat } from \"./TextMessageFormat\";\r\nimport { isArrayBuffer } from \"./Utils\";\r\n/** @private */\r\nexport class HandshakeProtocol {\r\n // Handshake request is always JSON\r\n writeHandshakeRequest(handshakeRequest) {\r\n return TextMessageFormat.write(JSON.stringify(handshakeRequest));\r\n }\r\n parseHandshakeResponse(data) {\r\n let messageData;\r\n let remainingData;\r\n if (isArrayBuffer(data)) {\r\n // Format is binary but still need to read JSON text from handshake response\r\n const binaryData = new Uint8Array(data);\r\n const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);\r\n if (separatorIndex === -1) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n // content before separator is handshake response\r\n // optional content after is additional messages\r\n const responseLength = separatorIndex + 1;\r\n messageData = String.fromCharCode.apply(null, Array.prototype.slice.call(binaryData.slice(0, responseLength)));\r\n remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;\r\n }\r\n else {\r\n const textData = data;\r\n const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);\r\n if (separatorIndex === -1) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n // content before separator is handshake response\r\n // optional content after is additional messages\r\n const responseLength = separatorIndex + 1;\r\n messageData = textData.substring(0, responseLength);\r\n remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;\r\n }\r\n // At this point we should have just the single handshake message\r\n const messages = TextMessageFormat.parse(messageData);\r\n const response = JSON.parse(messages[0]);\r\n if (response.type) {\r\n throw new Error(\"Expected a handshake response from the server.\");\r\n }\r\n const responseMessage = response;\r\n // multiple messages could have arrived with handshake\r\n // return additional data to be parsed as usual, or null if all parsed\r\n return [remainingData, responseMessage];\r\n }\r\n}\r\n//# sourceMappingURL=HandshakeProtocol.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n/** Defines the type of a Hub Message. */\r\nexport var MessageType;\r\n(function (MessageType) {\r\n /** Indicates the message is an Invocation message and implements the {@link @microsoft/signalr.InvocationMessage} interface. */\r\n MessageType[MessageType[\"Invocation\"] = 1] = \"Invocation\";\r\n /** Indicates the message is a StreamItem message and implements the {@link @microsoft/signalr.StreamItemMessage} interface. */\r\n MessageType[MessageType[\"StreamItem\"] = 2] = \"StreamItem\";\r\n /** Indicates the message is a Completion message and implements the {@link @microsoft/signalr.CompletionMessage} interface. */\r\n MessageType[MessageType[\"Completion\"] = 3] = \"Completion\";\r\n /** Indicates the message is a Stream Invocation message and implements the {@link @microsoft/signalr.StreamInvocationMessage} interface. */\r\n MessageType[MessageType[\"StreamInvocation\"] = 4] = \"StreamInvocation\";\r\n /** Indicates the message is a Cancel Invocation message and implements the {@link @microsoft/signalr.CancelInvocationMessage} interface. */\r\n MessageType[MessageType[\"CancelInvocation\"] = 5] = \"CancelInvocation\";\r\n /** Indicates the message is a Ping message and implements the {@link @microsoft/signalr.PingMessage} interface. */\r\n MessageType[MessageType[\"Ping\"] = 6] = \"Ping\";\r\n /** Indicates the message is a Close message and implements the {@link @microsoft/signalr.CloseMessage} interface. */\r\n MessageType[MessageType[\"Close\"] = 7] = \"Close\";\r\n MessageType[MessageType[\"Ack\"] = 8] = \"Ack\";\r\n MessageType[MessageType[\"Sequence\"] = 9] = \"Sequence\";\r\n})(MessageType || (MessageType = {}));\r\n//# sourceMappingURL=IHubProtocol.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { SubjectSubscription } from \"./Utils\";\r\n/** Stream implementation to stream items to the server. */\r\nexport class Subject {\r\n constructor() {\r\n this.observers = [];\r\n }\r\n next(item) {\r\n for (const observer of this.observers) {\r\n observer.next(item);\r\n }\r\n }\r\n error(err) {\r\n for (const observer of this.observers) {\r\n if (observer.error) {\r\n observer.error(err);\r\n }\r\n }\r\n }\r\n complete() {\r\n for (const observer of this.observers) {\r\n if (observer.complete) {\r\n observer.complete();\r\n }\r\n }\r\n }\r\n subscribe(observer) {\r\n this.observers.push(observer);\r\n return new SubjectSubscription(this, observer);\r\n }\r\n}\r\n//# sourceMappingURL=Subject.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { MessageType } from \"./IHubProtocol\";\r\nimport { isArrayBuffer } from \"./Utils\";\r\n/** @private */\r\nexport class MessageBuffer {\r\n constructor(protocol, connection, bufferSize) {\r\n this._bufferSize = 100000;\r\n this._messages = [];\r\n this._totalMessageCount = 0;\r\n this._waitForSequenceMessage = false;\r\n // Message IDs start at 1 and always increment by 1\r\n this._nextReceivingSequenceId = 1;\r\n this._latestReceivedSequenceId = 0;\r\n this._bufferedByteCount = 0;\r\n this._reconnectInProgress = false;\r\n this._protocol = protocol;\r\n this._connection = connection;\r\n this._bufferSize = bufferSize;\r\n }\r\n async _send(message) {\r\n const serializedMessage = this._protocol.writeMessage(message);\r\n let backpressurePromise = Promise.resolve();\r\n // Only count invocation messages. Acks, pings, etc. don't need to be resent on reconnect\r\n if (this._isInvocationMessage(message)) {\r\n this._totalMessageCount++;\r\n let backpressurePromiseResolver = () => { };\r\n let backpressurePromiseRejector = () => { };\r\n if (isArrayBuffer(serializedMessage)) {\r\n this._bufferedByteCount += serializedMessage.byteLength;\r\n }\r\n else {\r\n this._bufferedByteCount += serializedMessage.length;\r\n }\r\n if (this._bufferedByteCount >= this._bufferSize) {\r\n backpressurePromise = new Promise((resolve, reject) => {\r\n backpressurePromiseResolver = resolve;\r\n backpressurePromiseRejector = reject;\r\n });\r\n }\r\n this._messages.push(new BufferedItem(serializedMessage, this._totalMessageCount, backpressurePromiseResolver, backpressurePromiseRejector));\r\n }\r\n try {\r\n // If this is set it means we are reconnecting or resending\r\n // We don't want to send on a disconnected connection\r\n // And we don't want to send if resend is running since that would mean sending\r\n // this message twice\r\n if (!this._reconnectInProgress) {\r\n await this._connection.send(serializedMessage);\r\n }\r\n }\r\n catch {\r\n this._disconnected();\r\n }\r\n await backpressurePromise;\r\n }\r\n _ack(ackMessage) {\r\n let newestAckedMessage = -1;\r\n // Find index of newest message being acked\r\n for (let index = 0; index < this._messages.length; index++) {\r\n const element = this._messages[index];\r\n if (element._id <= ackMessage.sequenceId) {\r\n newestAckedMessage = index;\r\n if (isArrayBuffer(element._message)) {\r\n this._bufferedByteCount -= element._message.byteLength;\r\n }\r\n else {\r\n this._bufferedByteCount -= element._message.length;\r\n }\r\n // resolve items that have already been sent and acked\r\n element._resolver();\r\n }\r\n else if (this._bufferedByteCount < this._bufferSize) {\r\n // resolve items that now fall under the buffer limit but haven't been acked\r\n element._resolver();\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n if (newestAckedMessage !== -1) {\r\n // We're removing everything including the message pointed to, so add 1\r\n this._messages = this._messages.slice(newestAckedMessage + 1);\r\n }\r\n }\r\n _shouldProcessMessage(message) {\r\n if (this._waitForSequenceMessage) {\r\n if (message.type !== MessageType.Sequence) {\r\n return false;\r\n }\r\n else {\r\n this._waitForSequenceMessage = false;\r\n return true;\r\n }\r\n }\r\n // No special processing for acks, pings, etc.\r\n if (!this._isInvocationMessage(message)) {\r\n return true;\r\n }\r\n const currentId = this._nextReceivingSequenceId;\r\n this._nextReceivingSequenceId++;\r\n if (currentId <= this._latestReceivedSequenceId) {\r\n if (currentId === this._latestReceivedSequenceId) {\r\n // Should only hit this if we just reconnected and the server is sending\r\n // Messages it has buffered, which would mean it hasn't seen an Ack for these messages\r\n this._ackTimer();\r\n }\r\n // Ignore, this is a duplicate message\r\n return false;\r\n }\r\n this._latestReceivedSequenceId = currentId;\r\n // Only start the timer for sending an Ack message when we have a message to ack. This also conveniently solves\r\n // timer throttling by not having a recursive timer, and by starting the timer via a network call (recv)\r\n this._ackTimer();\r\n return true;\r\n }\r\n _resetSequence(message) {\r\n if (message.sequenceId > this._nextReceivingSequenceId) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this._connection.stop(new Error(\"Sequence ID greater than amount of messages we've received.\"));\r\n return;\r\n }\r\n this._nextReceivingSequenceId = message.sequenceId;\r\n }\r\n _disconnected() {\r\n this._reconnectInProgress = true;\r\n this._waitForSequenceMessage = true;\r\n }\r\n async _resend() {\r\n const sequenceId = this._messages.length !== 0\r\n ? this._messages[0]._id\r\n : this._totalMessageCount + 1;\r\n await this._connection.send(this._protocol.writeMessage({ type: MessageType.Sequence, sequenceId }));\r\n // Get a local variable to the _messages, just in case messages are acked while resending\r\n // Which would slice the _messages array (which creates a new copy)\r\n const messages = this._messages;\r\n for (const element of messages) {\r\n await this._connection.send(element._message);\r\n }\r\n this._reconnectInProgress = false;\r\n }\r\n _dispose(error) {\r\n error !== null && error !== void 0 ? error : (error = new Error(\"Unable to reconnect to server.\"));\r\n // Unblock backpressure if any\r\n for (const element of this._messages) {\r\n element._rejector(error);\r\n }\r\n }\r\n _isInvocationMessage(message) {\r\n // There is no way to check if something implements an interface.\r\n // So we individually check the messages in a switch statement.\r\n // To make sure we don't miss any message types we rely on the compiler\r\n // seeing the function returns a value and it will do the\r\n // exhaustive check for us on the switch statement, since we don't use 'case default'\r\n switch (message.type) {\r\n case MessageType.Invocation:\r\n case MessageType.StreamItem:\r\n case MessageType.Completion:\r\n case MessageType.StreamInvocation:\r\n case MessageType.CancelInvocation:\r\n return true;\r\n case MessageType.Close:\r\n case MessageType.Sequence:\r\n case MessageType.Ping:\r\n case MessageType.Ack:\r\n return false;\r\n }\r\n }\r\n _ackTimer() {\r\n if (this._ackTimerHandle === undefined) {\r\n this._ackTimerHandle = setTimeout(async () => {\r\n try {\r\n if (!this._reconnectInProgress) {\r\n await this._connection.send(this._protocol.writeMessage({ type: MessageType.Ack, sequenceId: this._latestReceivedSequenceId }));\r\n }\r\n // Ignore errors, that means the connection is closed and we don't care about the Ack message anymore.\r\n }\r\n catch { }\r\n clearTimeout(this._ackTimerHandle);\r\n this._ackTimerHandle = undefined;\r\n // 1 second delay so we don't spam Ack messages if there are many messages being received at once.\r\n }, 1000);\r\n }\r\n }\r\n}\r\nclass BufferedItem {\r\n constructor(message, id, resolver, rejector) {\r\n this._message = message;\r\n this._id = id;\r\n this._resolver = resolver;\r\n this._rejector = rejector;\r\n }\r\n}\r\n//# sourceMappingURL=MessageBuffer.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { HandshakeProtocol } from \"./HandshakeProtocol\";\r\nimport { AbortError } from \"./Errors\";\r\nimport { MessageType } from \"./IHubProtocol\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { Subject } from \"./Subject\";\r\nimport { Arg, getErrorString, Platform } from \"./Utils\";\r\nimport { MessageBuffer } from \"./MessageBuffer\";\r\nconst DEFAULT_TIMEOUT_IN_MS = 30 * 1000;\r\nconst DEFAULT_PING_INTERVAL_IN_MS = 15 * 1000;\r\nconst DEFAULT_STATEFUL_RECONNECT_BUFFER_SIZE = 100000;\r\n/** Describes the current state of the {@link HubConnection} to the server. */\r\nexport var HubConnectionState;\r\n(function (HubConnectionState) {\r\n /** The hub connection is disconnected. */\r\n HubConnectionState[\"Disconnected\"] = \"Disconnected\";\r\n /** The hub connection is connecting. */\r\n HubConnectionState[\"Connecting\"] = \"Connecting\";\r\n /** The hub connection is connected. */\r\n HubConnectionState[\"Connected\"] = \"Connected\";\r\n /** The hub connection is disconnecting. */\r\n HubConnectionState[\"Disconnecting\"] = \"Disconnecting\";\r\n /** The hub connection is reconnecting. */\r\n HubConnectionState[\"Reconnecting\"] = \"Reconnecting\";\r\n})(HubConnectionState || (HubConnectionState = {}));\r\n/** Represents a connection to a SignalR Hub. */\r\nexport class HubConnection {\r\n /** @internal */\r\n // Using a public static factory method means we can have a private constructor and an _internal_\r\n // create method that can be used by HubConnectionBuilder. An \"internal\" constructor would just\r\n // be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a\r\n // public parameter-less constructor.\r\n static create(connection, logger, protocol, reconnectPolicy, serverTimeoutInMilliseconds, keepAliveIntervalInMilliseconds, statefulReconnectBufferSize) {\r\n return new HubConnection(connection, logger, protocol, reconnectPolicy, serverTimeoutInMilliseconds, keepAliveIntervalInMilliseconds, statefulReconnectBufferSize);\r\n }\r\n constructor(connection, logger, protocol, reconnectPolicy, serverTimeoutInMilliseconds, keepAliveIntervalInMilliseconds, statefulReconnectBufferSize) {\r\n this._nextKeepAlive = 0;\r\n this._freezeEventListener = () => {\r\n this._logger.log(LogLevel.Warning, \"The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://learn.microsoft.com/aspnet/core/signalr/javascript-client#bsleep\");\r\n };\r\n Arg.isRequired(connection, \"connection\");\r\n Arg.isRequired(logger, \"logger\");\r\n Arg.isRequired(protocol, \"protocol\");\r\n this.serverTimeoutInMilliseconds = serverTimeoutInMilliseconds !== null && serverTimeoutInMilliseconds !== void 0 ? serverTimeoutInMilliseconds : DEFAULT_TIMEOUT_IN_MS;\r\n this.keepAliveIntervalInMilliseconds = keepAliveIntervalInMilliseconds !== null && keepAliveIntervalInMilliseconds !== void 0 ? keepAliveIntervalInMilliseconds : DEFAULT_PING_INTERVAL_IN_MS;\r\n this._statefulReconnectBufferSize = statefulReconnectBufferSize !== null && statefulReconnectBufferSize !== void 0 ? statefulReconnectBufferSize : DEFAULT_STATEFUL_RECONNECT_BUFFER_SIZE;\r\n this._logger = logger;\r\n this._protocol = protocol;\r\n this.connection = connection;\r\n this._reconnectPolicy = reconnectPolicy;\r\n this._handshakeProtocol = new HandshakeProtocol();\r\n this.connection.onreceive = (data) => this._processIncomingData(data);\r\n this.connection.onclose = (error) => this._connectionClosed(error);\r\n this._callbacks = {};\r\n this._methods = {};\r\n this._closedCallbacks = [];\r\n this._reconnectingCallbacks = [];\r\n this._reconnectedCallbacks = [];\r\n this._invocationId = 0;\r\n this._receivedHandshakeResponse = false;\r\n this._connectionState = HubConnectionState.Disconnected;\r\n this._connectionStarted = false;\r\n this._cachedPingMessage = this._protocol.writeMessage({ type: MessageType.Ping });\r\n }\r\n /** Indicates the state of the {@link HubConnection} to the server. */\r\n get state() {\r\n return this._connectionState;\r\n }\r\n /** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either\r\n * in the disconnected state or if the negotiation step was skipped.\r\n */\r\n get connectionId() {\r\n return this.connection ? (this.connection.connectionId || null) : null;\r\n }\r\n /** Indicates the url of the {@link HubConnection} to the server. */\r\n get baseUrl() {\r\n return this.connection.baseUrl || \"\";\r\n }\r\n /**\r\n * Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or\r\n * Reconnecting states.\r\n * @param {string} url The url to connect to.\r\n */\r\n set baseUrl(url) {\r\n if (this._connectionState !== HubConnectionState.Disconnected && this._connectionState !== HubConnectionState.Reconnecting) {\r\n throw new Error(\"The HubConnection must be in the Disconnected or Reconnecting state to change the url.\");\r\n }\r\n if (!url) {\r\n throw new Error(\"The HubConnection url must be a valid url.\");\r\n }\r\n this.connection.baseUrl = url;\r\n }\r\n /** Starts the connection.\r\n *\r\n * @returns {Promise} A Promise that resolves when the connection has been successfully established, or rejects with an error.\r\n */\r\n start() {\r\n this._startPromise = this._startWithStateTransitions();\r\n return this._startPromise;\r\n }\r\n async _startWithStateTransitions() {\r\n if (this._connectionState !== HubConnectionState.Disconnected) {\r\n return Promise.reject(new Error(\"Cannot start a HubConnection that is not in the 'Disconnected' state.\"));\r\n }\r\n this._connectionState = HubConnectionState.Connecting;\r\n this._logger.log(LogLevel.Debug, \"Starting HubConnection.\");\r\n try {\r\n await this._startInternal();\r\n if (Platform.isBrowser) {\r\n // Log when the browser freezes the tab so users know why their connection unexpectedly stopped working\r\n window.document.addEventListener(\"freeze\", this._freezeEventListener);\r\n }\r\n this._connectionState = HubConnectionState.Connected;\r\n this._connectionStarted = true;\r\n this._logger.log(LogLevel.Debug, \"HubConnection connected successfully.\");\r\n }\r\n catch (e) {\r\n this._connectionState = HubConnectionState.Disconnected;\r\n this._logger.log(LogLevel.Debug, `HubConnection failed to start successfully because of error '${e}'.`);\r\n return Promise.reject(e);\r\n }\r\n }\r\n async _startInternal() {\r\n this._stopDuringStartError = undefined;\r\n this._receivedHandshakeResponse = false;\r\n // Set up the promise before any connection is (re)started otherwise it could race with received messages\r\n const handshakePromise = new Promise((resolve, reject) => {\r\n this._handshakeResolver = resolve;\r\n this._handshakeRejecter = reject;\r\n });\r\n await this.connection.start(this._protocol.transferFormat);\r\n try {\r\n let version = this._protocol.version;\r\n if (!this.connection.features.reconnect) {\r\n // Stateful Reconnect starts with HubProtocol version 2, newer clients connecting to older servers will fail to connect due to\r\n // the handshake only supporting version 1, so we will try to send version 1 during the handshake to keep old servers working.\r\n version = 1;\r\n }\r\n const handshakeRequest = {\r\n protocol: this._protocol.name,\r\n version,\r\n };\r\n this._logger.log(LogLevel.Debug, \"Sending handshake request.\");\r\n await this._sendMessage(this._handshakeProtocol.writeHandshakeRequest(handshakeRequest));\r\n this._logger.log(LogLevel.Information, `Using HubProtocol '${this._protocol.name}'.`);\r\n // defensively cleanup timeout in case we receive a message from the server before we finish start\r\n this._cleanupTimeout();\r\n this._resetTimeoutPeriod();\r\n this._resetKeepAliveInterval();\r\n await handshakePromise;\r\n // It's important to check the stopDuringStartError instead of just relying on the handshakePromise\r\n // being rejected on close, because this continuation can run after both the handshake completed successfully\r\n // and the connection was closed.\r\n if (this._stopDuringStartError) {\r\n // It's important to throw instead of returning a rejected promise, because we don't want to allow any state\r\n // transitions to occur between now and the calling code observing the exceptions. Returning a rejected promise\r\n // will cause the calling continuation to get scheduled to run later.\r\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\r\n throw this._stopDuringStartError;\r\n }\r\n const useStatefulReconnect = this.connection.features.reconnect || false;\r\n if (useStatefulReconnect) {\r\n this._messageBuffer = new MessageBuffer(this._protocol, this.connection, this._statefulReconnectBufferSize);\r\n this.connection.features.disconnected = this._messageBuffer._disconnected.bind(this._messageBuffer);\r\n this.connection.features.resend = () => {\r\n if (this._messageBuffer) {\r\n return this._messageBuffer._resend();\r\n }\r\n };\r\n }\r\n if (!this.connection.features.inherentKeepAlive) {\r\n await this._sendMessage(this._cachedPingMessage);\r\n }\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Debug, `Hub handshake failed with error '${e}' during start(). Stopping HubConnection.`);\r\n this._cleanupTimeout();\r\n this._cleanupPingTimer();\r\n // HttpConnection.stop() should not complete until after the onclose callback is invoked.\r\n // This will transition the HubConnection to the disconnected state before HttpConnection.stop() completes.\r\n await this.connection.stop(e);\r\n throw e;\r\n }\r\n }\r\n /** Stops the connection.\r\n *\r\n * @returns {Promise} A Promise that resolves when the connection has been successfully terminated, or rejects with an error.\r\n */\r\n async stop() {\r\n // Capture the start promise before the connection might be restarted in an onclose callback.\r\n const startPromise = this._startPromise;\r\n this.connection.features.reconnect = false;\r\n this._stopPromise = this._stopInternal();\r\n await this._stopPromise;\r\n try {\r\n // Awaiting undefined continues immediately\r\n await startPromise;\r\n }\r\n catch (e) {\r\n // This exception is returned to the user as a rejected Promise from the start method.\r\n }\r\n }\r\n _stopInternal(error) {\r\n if (this._connectionState === HubConnectionState.Disconnected) {\r\n this._logger.log(LogLevel.Debug, `Call to HubConnection.stop(${error}) ignored because it is already in the disconnected state.`);\r\n return Promise.resolve();\r\n }\r\n if (this._connectionState === HubConnectionState.Disconnecting) {\r\n this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);\r\n return this._stopPromise;\r\n }\r\n const state = this._connectionState;\r\n this._connectionState = HubConnectionState.Disconnecting;\r\n this._logger.log(LogLevel.Debug, \"Stopping HubConnection.\");\r\n if (this._reconnectDelayHandle) {\r\n // We're in a reconnect delay which means the underlying connection is currently already stopped.\r\n // Just clear the handle to stop the reconnect loop (which no one is waiting on thankfully) and\r\n // fire the onclose callbacks.\r\n this._logger.log(LogLevel.Debug, \"Connection stopped during reconnect delay. Done reconnecting.\");\r\n clearTimeout(this._reconnectDelayHandle);\r\n this._reconnectDelayHandle = undefined;\r\n this._completeClose();\r\n return Promise.resolve();\r\n }\r\n if (state === HubConnectionState.Connected) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this._sendCloseMessage();\r\n }\r\n this._cleanupTimeout();\r\n this._cleanupPingTimer();\r\n this._stopDuringStartError = error || new AbortError(\"The connection was stopped before the hub handshake could complete.\");\r\n // HttpConnection.stop() should not complete until after either HttpConnection.start() fails\r\n // or the onclose callback is invoked. The onclose callback will transition the HubConnection\r\n // to the disconnected state if need be before HttpConnection.stop() completes.\r\n return this.connection.stop(error);\r\n }\r\n async _sendCloseMessage() {\r\n try {\r\n await this._sendWithProtocol(this._createCloseMessage());\r\n }\r\n catch {\r\n // Ignore, this is a best effort attempt to let the server know the client closed gracefully.\r\n }\r\n }\r\n /** Invokes a streaming hub method on the server using the specified name and arguments.\r\n *\r\n * @typeparam T The type of the items returned by the server.\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {IStreamResult} An object that yields results from the server as they are received.\r\n */\r\n stream(methodName, ...args) {\r\n const [streams, streamIds] = this._replaceStreamingParams(args);\r\n const invocationDescriptor = this._createStreamInvocation(methodName, args, streamIds);\r\n // eslint-disable-next-line prefer-const\r\n let promiseQueue;\r\n const subject = new Subject();\r\n subject.cancelCallback = () => {\r\n const cancelInvocation = this._createCancelInvocation(invocationDescriptor.invocationId);\r\n delete this._callbacks[invocationDescriptor.invocationId];\r\n return promiseQueue.then(() => {\r\n return this._sendWithProtocol(cancelInvocation);\r\n });\r\n };\r\n this._callbacks[invocationDescriptor.invocationId] = (invocationEvent, error) => {\r\n if (error) {\r\n subject.error(error);\r\n return;\r\n }\r\n else if (invocationEvent) {\r\n // invocationEvent will not be null when an error is not passed to the callback\r\n if (invocationEvent.type === MessageType.Completion) {\r\n if (invocationEvent.error) {\r\n subject.error(new Error(invocationEvent.error));\r\n }\r\n else {\r\n subject.complete();\r\n }\r\n }\r\n else {\r\n subject.next((invocationEvent.item));\r\n }\r\n }\r\n };\r\n promiseQueue = this._sendWithProtocol(invocationDescriptor)\r\n .catch((e) => {\r\n subject.error(e);\r\n delete this._callbacks[invocationDescriptor.invocationId];\r\n });\r\n this._launchStreams(streams, promiseQueue);\r\n return subject;\r\n }\r\n _sendMessage(message) {\r\n this._resetKeepAliveInterval();\r\n return this.connection.send(message);\r\n }\r\n /**\r\n * Sends a js object to the server.\r\n * @param message The js object to serialize and send.\r\n */\r\n _sendWithProtocol(message) {\r\n if (this._messageBuffer) {\r\n return this._messageBuffer._send(message);\r\n }\r\n else {\r\n return this._sendMessage(this._protocol.writeMessage(message));\r\n }\r\n }\r\n /** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver.\r\n *\r\n * The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still\r\n * be processing the invocation.\r\n *\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {Promise} A Promise that resolves when the invocation has been successfully sent, or rejects with an error.\r\n */\r\n send(methodName, ...args) {\r\n const [streams, streamIds] = this._replaceStreamingParams(args);\r\n const sendPromise = this._sendWithProtocol(this._createInvocation(methodName, args, true, streamIds));\r\n this._launchStreams(streams, sendPromise);\r\n return sendPromise;\r\n }\r\n /** Invokes a hub method on the server using the specified name and arguments.\r\n *\r\n * The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise\r\n * resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of\r\n * resolving the Promise.\r\n *\r\n * @typeparam T The expected return type.\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {Promise} A Promise that resolves with the result of the server method (if any), or rejects with an error.\r\n */\r\n invoke(methodName, ...args) {\r\n const [streams, streamIds] = this._replaceStreamingParams(args);\r\n const invocationDescriptor = this._createInvocation(methodName, args, false, streamIds);\r\n const p = new Promise((resolve, reject) => {\r\n // invocationId will always have a value for a non-blocking invocation\r\n this._callbacks[invocationDescriptor.invocationId] = (invocationEvent, error) => {\r\n if (error) {\r\n reject(error);\r\n return;\r\n }\r\n else if (invocationEvent) {\r\n // invocationEvent will not be null when an error is not passed to the callback\r\n if (invocationEvent.type === MessageType.Completion) {\r\n if (invocationEvent.error) {\r\n reject(new Error(invocationEvent.error));\r\n }\r\n else {\r\n resolve(invocationEvent.result);\r\n }\r\n }\r\n else {\r\n reject(new Error(`Unexpected message type: ${invocationEvent.type}`));\r\n }\r\n }\r\n };\r\n const promiseQueue = this._sendWithProtocol(invocationDescriptor)\r\n .catch((e) => {\r\n reject(e);\r\n // invocationId will always have a value for a non-blocking invocation\r\n delete this._callbacks[invocationDescriptor.invocationId];\r\n });\r\n this._launchStreams(streams, promiseQueue);\r\n });\r\n return p;\r\n }\r\n on(methodName, newMethod) {\r\n if (!methodName || !newMethod) {\r\n return;\r\n }\r\n methodName = methodName.toLowerCase();\r\n if (!this._methods[methodName]) {\r\n this._methods[methodName] = [];\r\n }\r\n // Preventing adding the same handler multiple times.\r\n if (this._methods[methodName].indexOf(newMethod) !== -1) {\r\n return;\r\n }\r\n this._methods[methodName].push(newMethod);\r\n }\r\n off(methodName, method) {\r\n if (!methodName) {\r\n return;\r\n }\r\n methodName = methodName.toLowerCase();\r\n const handlers = this._methods[methodName];\r\n if (!handlers) {\r\n return;\r\n }\r\n if (method) {\r\n const removeIdx = handlers.indexOf(method);\r\n if (removeIdx !== -1) {\r\n handlers.splice(removeIdx, 1);\r\n if (handlers.length === 0) {\r\n delete this._methods[methodName];\r\n }\r\n }\r\n }\r\n else {\r\n delete this._methods[methodName];\r\n }\r\n }\r\n /** Registers a handler that will be invoked when the connection is closed.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any).\r\n */\r\n onclose(callback) {\r\n if (callback) {\r\n this._closedCallbacks.push(callback);\r\n }\r\n }\r\n /** Registers a handler that will be invoked when the connection starts reconnecting.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection starts reconnecting. Optionally receives a single argument containing the error that caused the connection to start reconnecting (if any).\r\n */\r\n onreconnecting(callback) {\r\n if (callback) {\r\n this._reconnectingCallbacks.push(callback);\r\n }\r\n }\r\n /** Registers a handler that will be invoked when the connection successfully reconnects.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection successfully reconnects.\r\n */\r\n onreconnected(callback) {\r\n if (callback) {\r\n this._reconnectedCallbacks.push(callback);\r\n }\r\n }\r\n _processIncomingData(data) {\r\n this._cleanupTimeout();\r\n if (!this._receivedHandshakeResponse) {\r\n data = this._processHandshakeResponse(data);\r\n this._receivedHandshakeResponse = true;\r\n }\r\n // Data may have all been read when processing handshake response\r\n if (data) {\r\n // Parse the messages\r\n const messages = this._protocol.parseMessages(data, this._logger);\r\n for (const message of messages) {\r\n if (this._messageBuffer && !this._messageBuffer._shouldProcessMessage(message)) {\r\n // Don't process the message, we are either waiting for a SequenceMessage or received a duplicate message\r\n continue;\r\n }\r\n switch (message.type) {\r\n case MessageType.Invocation:\r\n this._invokeClientMethod(message)\r\n .catch((e) => {\r\n this._logger.log(LogLevel.Error, `Invoke client method threw error: ${getErrorString(e)}`);\r\n });\r\n break;\r\n case MessageType.StreamItem:\r\n case MessageType.Completion: {\r\n const callback = this._callbacks[message.invocationId];\r\n if (callback) {\r\n if (message.type === MessageType.Completion) {\r\n delete this._callbacks[message.invocationId];\r\n }\r\n try {\r\n callback(message);\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `Stream callback threw error: ${getErrorString(e)}`);\r\n }\r\n }\r\n break;\r\n }\r\n case MessageType.Ping:\r\n // Don't care about pings\r\n break;\r\n case MessageType.Close: {\r\n this._logger.log(LogLevel.Information, \"Close message received from server.\");\r\n const error = message.error ? new Error(\"Server returned an error on close: \" + message.error) : undefined;\r\n if (message.allowReconnect === true) {\r\n // It feels wrong not to await connection.stop() here, but processIncomingData is called as part of an onreceive callback which is not async,\r\n // this is already the behavior for serverTimeout(), and HttpConnection.Stop() should catch and log all possible exceptions.\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.connection.stop(error);\r\n }\r\n else {\r\n // We cannot await stopInternal() here, but subsequent calls to stop() will await this if stopInternal() is still ongoing.\r\n this._stopPromise = this._stopInternal(error);\r\n }\r\n break;\r\n }\r\n case MessageType.Ack:\r\n if (this._messageBuffer) {\r\n this._messageBuffer._ack(message);\r\n }\r\n break;\r\n case MessageType.Sequence:\r\n if (this._messageBuffer) {\r\n this._messageBuffer._resetSequence(message);\r\n }\r\n break;\r\n default:\r\n this._logger.log(LogLevel.Warning, `Invalid message type: ${message.type}.`);\r\n break;\r\n }\r\n }\r\n }\r\n this._resetTimeoutPeriod();\r\n }\r\n _processHandshakeResponse(data) {\r\n let responseMessage;\r\n let remainingData;\r\n try {\r\n [remainingData, responseMessage] = this._handshakeProtocol.parseHandshakeResponse(data);\r\n }\r\n catch (e) {\r\n const message = \"Error parsing handshake response: \" + e;\r\n this._logger.log(LogLevel.Error, message);\r\n const error = new Error(message);\r\n this._handshakeRejecter(error);\r\n throw error;\r\n }\r\n if (responseMessage.error) {\r\n const message = \"Server returned handshake error: \" + responseMessage.error;\r\n this._logger.log(LogLevel.Error, message);\r\n const error = new Error(message);\r\n this._handshakeRejecter(error);\r\n throw error;\r\n }\r\n else {\r\n this._logger.log(LogLevel.Debug, \"Server handshake complete.\");\r\n }\r\n this._handshakeResolver();\r\n return remainingData;\r\n }\r\n _resetKeepAliveInterval() {\r\n if (this.connection.features.inherentKeepAlive) {\r\n return;\r\n }\r\n // Set the time we want the next keep alive to be sent\r\n // Timer will be setup on next message receive\r\n this._nextKeepAlive = new Date().getTime() + this.keepAliveIntervalInMilliseconds;\r\n this._cleanupPingTimer();\r\n }\r\n _resetTimeoutPeriod() {\r\n if (!this.connection.features || !this.connection.features.inherentKeepAlive) {\r\n // Set the timeout timer\r\n this._timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);\r\n // Set keepAlive timer if there isn't one\r\n if (this._pingServerHandle === undefined) {\r\n let nextPing = this._nextKeepAlive - new Date().getTime();\r\n if (nextPing < 0) {\r\n nextPing = 0;\r\n }\r\n // The timer needs to be set from a networking callback to avoid Chrome timer throttling from causing timers to run once a minute\r\n this._pingServerHandle = setTimeout(async () => {\r\n if (this._connectionState === HubConnectionState.Connected) {\r\n try {\r\n await this._sendMessage(this._cachedPingMessage);\r\n }\r\n catch {\r\n // We don't care about the error. It should be seen elsewhere in the client.\r\n // The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering\r\n this._cleanupPingTimer();\r\n }\r\n }\r\n }, nextPing);\r\n }\r\n }\r\n }\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n serverTimeout() {\r\n // The server hasn't talked to us in a while. It doesn't like us anymore ... :(\r\n // Terminate the connection, but we don't need to wait on the promise. This could trigger reconnecting.\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.connection.stop(new Error(\"Server timeout elapsed without receiving a message from the server.\"));\r\n }\r\n async _invokeClientMethod(invocationMessage) {\r\n const methodName = invocationMessage.target.toLowerCase();\r\n const methods = this._methods[methodName];\r\n if (!methods) {\r\n this._logger.log(LogLevel.Warning, `No client method with the name '${methodName}' found.`);\r\n // No handlers provided by client but the server is expecting a response still, so we send an error\r\n if (invocationMessage.invocationId) {\r\n this._logger.log(LogLevel.Warning, `No result given for '${methodName}' method and invocation ID '${invocationMessage.invocationId}'.`);\r\n await this._sendWithProtocol(this._createCompletionMessage(invocationMessage.invocationId, \"Client didn't provide a result.\", null));\r\n }\r\n return;\r\n }\r\n // Avoid issues with handlers removing themselves thus modifying the list while iterating through it\r\n const methodsCopy = methods.slice();\r\n // Server expects a response\r\n const expectsResponse = invocationMessage.invocationId ? true : false;\r\n // We preserve the last result or exception but still call all handlers\r\n let res;\r\n let exception;\r\n let completionMessage;\r\n for (const m of methodsCopy) {\r\n try {\r\n const prevRes = res;\r\n res = await m.apply(this, invocationMessage.arguments);\r\n if (expectsResponse && res && prevRes) {\r\n this._logger.log(LogLevel.Error, `Multiple results provided for '${methodName}'. Sending error to server.`);\r\n completionMessage = this._createCompletionMessage(invocationMessage.invocationId, `Client provided multiple results.`, null);\r\n }\r\n // Ignore exception if we got a result after, the exception will be logged\r\n exception = undefined;\r\n }\r\n catch (e) {\r\n exception = e;\r\n this._logger.log(LogLevel.Error, `A callback for the method '${methodName}' threw error '${e}'.`);\r\n }\r\n }\r\n if (completionMessage) {\r\n await this._sendWithProtocol(completionMessage);\r\n }\r\n else if (expectsResponse) {\r\n // If there is an exception that means either no result was given or a handler after a result threw\r\n if (exception) {\r\n completionMessage = this._createCompletionMessage(invocationMessage.invocationId, `${exception}`, null);\r\n }\r\n else if (res !== undefined) {\r\n completionMessage = this._createCompletionMessage(invocationMessage.invocationId, null, res);\r\n }\r\n else {\r\n this._logger.log(LogLevel.Warning, `No result given for '${methodName}' method and invocation ID '${invocationMessage.invocationId}'.`);\r\n // Client didn't provide a result or throw from a handler, server expects a response so we send an error\r\n completionMessage = this._createCompletionMessage(invocationMessage.invocationId, \"Client didn't provide a result.\", null);\r\n }\r\n await this._sendWithProtocol(completionMessage);\r\n }\r\n else {\r\n if (res) {\r\n this._logger.log(LogLevel.Error, `Result given for '${methodName}' method but server is not expecting a result.`);\r\n }\r\n }\r\n }\r\n _connectionClosed(error) {\r\n this._logger.log(LogLevel.Debug, `HubConnection.connectionClosed(${error}) called while in state ${this._connectionState}.`);\r\n // Triggering this.handshakeRejecter is insufficient because it could already be resolved without the continuation having run yet.\r\n this._stopDuringStartError = this._stopDuringStartError || error || new AbortError(\"The underlying connection was closed before the hub handshake could complete.\");\r\n // If the handshake is in progress, start will be waiting for the handshake promise, so we complete it.\r\n // If it has already completed, this should just noop.\r\n if (this._handshakeResolver) {\r\n this._handshakeResolver();\r\n }\r\n this._cancelCallbacksWithError(error || new Error(\"Invocation canceled due to the underlying connection being closed.\"));\r\n this._cleanupTimeout();\r\n this._cleanupPingTimer();\r\n if (this._connectionState === HubConnectionState.Disconnecting) {\r\n this._completeClose(error);\r\n }\r\n else if (this._connectionState === HubConnectionState.Connected && this._reconnectPolicy) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this._reconnect(error);\r\n }\r\n else if (this._connectionState === HubConnectionState.Connected) {\r\n this._completeClose(error);\r\n }\r\n // If none of the above if conditions were true were called the HubConnection must be in either:\r\n // 1. The Connecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail it.\r\n // 2. The Reconnecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail the current reconnect attempt\r\n // and potentially continue the reconnect() loop.\r\n // 3. The Disconnected state in which case we're already done.\r\n }\r\n _completeClose(error) {\r\n if (this._connectionStarted) {\r\n this._connectionState = HubConnectionState.Disconnected;\r\n this._connectionStarted = false;\r\n if (this._messageBuffer) {\r\n this._messageBuffer._dispose(error !== null && error !== void 0 ? error : new Error(\"Connection closed.\"));\r\n this._messageBuffer = undefined;\r\n }\r\n if (Platform.isBrowser) {\r\n window.document.removeEventListener(\"freeze\", this._freezeEventListener);\r\n }\r\n try {\r\n this._closedCallbacks.forEach((c) => c.apply(this, [error]));\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `An onclose callback called with error '${error}' threw error '${e}'.`);\r\n }\r\n }\r\n }\r\n async _reconnect(error) {\r\n const reconnectStartTime = Date.now();\r\n let previousReconnectAttempts = 0;\r\n let retryError = error !== undefined ? error : new Error(\"Attempting to reconnect due to a unknown error.\");\r\n let nextRetryDelay = this._getNextRetryDelay(previousReconnectAttempts++, 0, retryError);\r\n if (nextRetryDelay === null) {\r\n this._logger.log(LogLevel.Debug, \"Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.\");\r\n this._completeClose(error);\r\n return;\r\n }\r\n this._connectionState = HubConnectionState.Reconnecting;\r\n if (error) {\r\n this._logger.log(LogLevel.Information, `Connection reconnecting because of error '${error}'.`);\r\n }\r\n else {\r\n this._logger.log(LogLevel.Information, \"Connection reconnecting.\");\r\n }\r\n if (this._reconnectingCallbacks.length !== 0) {\r\n try {\r\n this._reconnectingCallbacks.forEach((c) => c.apply(this, [error]));\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `An onreconnecting callback called with error '${error}' threw error '${e}'.`);\r\n }\r\n // Exit early if an onreconnecting callback called connection.stop().\r\n if (this._connectionState !== HubConnectionState.Reconnecting) {\r\n this._logger.log(LogLevel.Debug, \"Connection left the reconnecting state in onreconnecting callback. Done reconnecting.\");\r\n return;\r\n }\r\n }\r\n while (nextRetryDelay !== null) {\r\n this._logger.log(LogLevel.Information, `Reconnect attempt number ${previousReconnectAttempts} will start in ${nextRetryDelay} ms.`);\r\n await new Promise((resolve) => {\r\n this._reconnectDelayHandle = setTimeout(resolve, nextRetryDelay);\r\n });\r\n this._reconnectDelayHandle = undefined;\r\n if (this._connectionState !== HubConnectionState.Reconnecting) {\r\n this._logger.log(LogLevel.Debug, \"Connection left the reconnecting state during reconnect delay. Done reconnecting.\");\r\n return;\r\n }\r\n try {\r\n await this._startInternal();\r\n this._connectionState = HubConnectionState.Connected;\r\n this._logger.log(LogLevel.Information, \"HubConnection reconnected successfully.\");\r\n if (this._reconnectedCallbacks.length !== 0) {\r\n try {\r\n this._reconnectedCallbacks.forEach((c) => c.apply(this, [this.connection.connectionId]));\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${e}'.`);\r\n }\r\n }\r\n return;\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Information, `Reconnect attempt failed because of error '${e}'.`);\r\n if (this._connectionState !== HubConnectionState.Reconnecting) {\r\n this._logger.log(LogLevel.Debug, `Connection moved to the '${this._connectionState}' from the reconnecting state during reconnect attempt. Done reconnecting.`);\r\n // The TypeScript compiler thinks that connectionState must be Connected here. The TypeScript compiler is wrong.\r\n if (this._connectionState === HubConnectionState.Disconnecting) {\r\n this._completeClose();\r\n }\r\n return;\r\n }\r\n retryError = e instanceof Error ? e : new Error(e.toString());\r\n nextRetryDelay = this._getNextRetryDelay(previousReconnectAttempts++, Date.now() - reconnectStartTime, retryError);\r\n }\r\n }\r\n this._logger.log(LogLevel.Information, `Reconnect retries have been exhausted after ${Date.now() - reconnectStartTime} ms and ${previousReconnectAttempts} failed attempts. Connection disconnecting.`);\r\n this._completeClose();\r\n }\r\n _getNextRetryDelay(previousRetryCount, elapsedMilliseconds, retryReason) {\r\n try {\r\n return this._reconnectPolicy.nextRetryDelayInMilliseconds({\r\n elapsedMilliseconds,\r\n previousRetryCount,\r\n retryReason,\r\n });\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `IRetryPolicy.nextRetryDelayInMilliseconds(${previousRetryCount}, ${elapsedMilliseconds}) threw error '${e}'.`);\r\n return null;\r\n }\r\n }\r\n _cancelCallbacksWithError(error) {\r\n const callbacks = this._callbacks;\r\n this._callbacks = {};\r\n Object.keys(callbacks)\r\n .forEach((key) => {\r\n const callback = callbacks[key];\r\n try {\r\n callback(null, error);\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `Stream 'error' callback called with '${error}' threw error: ${getErrorString(e)}`);\r\n }\r\n });\r\n }\r\n _cleanupPingTimer() {\r\n if (this._pingServerHandle) {\r\n clearTimeout(this._pingServerHandle);\r\n this._pingServerHandle = undefined;\r\n }\r\n }\r\n _cleanupTimeout() {\r\n if (this._timeoutHandle) {\r\n clearTimeout(this._timeoutHandle);\r\n }\r\n }\r\n _createInvocation(methodName, args, nonblocking, streamIds) {\r\n if (nonblocking) {\r\n if (streamIds.length !== 0) {\r\n return {\r\n arguments: args,\r\n streamIds,\r\n target: methodName,\r\n type: MessageType.Invocation,\r\n };\r\n }\r\n else {\r\n return {\r\n arguments: args,\r\n target: methodName,\r\n type: MessageType.Invocation,\r\n };\r\n }\r\n }\r\n else {\r\n const invocationId = this._invocationId;\r\n this._invocationId++;\r\n if (streamIds.length !== 0) {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n streamIds,\r\n target: methodName,\r\n type: MessageType.Invocation,\r\n };\r\n }\r\n else {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n target: methodName,\r\n type: MessageType.Invocation,\r\n };\r\n }\r\n }\r\n }\r\n _launchStreams(streams, promiseQueue) {\r\n if (streams.length === 0) {\r\n return;\r\n }\r\n // Synchronize stream data so they arrive in-order on the server\r\n if (!promiseQueue) {\r\n promiseQueue = Promise.resolve();\r\n }\r\n // We want to iterate over the keys, since the keys are the stream ids\r\n // eslint-disable-next-line guard-for-in\r\n for (const streamId in streams) {\r\n streams[streamId].subscribe({\r\n complete: () => {\r\n promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createCompletionMessage(streamId)));\r\n },\r\n error: (err) => {\r\n let message;\r\n if (err instanceof Error) {\r\n message = err.message;\r\n }\r\n else if (err && err.toString) {\r\n message = err.toString();\r\n }\r\n else {\r\n message = \"Unknown error\";\r\n }\r\n promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createCompletionMessage(streamId, message)));\r\n },\r\n next: (item) => {\r\n promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createStreamItemMessage(streamId, item)));\r\n },\r\n });\r\n }\r\n }\r\n _replaceStreamingParams(args) {\r\n const streams = [];\r\n const streamIds = [];\r\n for (let i = 0; i < args.length; i++) {\r\n const argument = args[i];\r\n if (this._isObservable(argument)) {\r\n const streamId = this._invocationId;\r\n this._invocationId++;\r\n // Store the stream for later use\r\n streams[streamId] = argument;\r\n streamIds.push(streamId.toString());\r\n // remove stream from args\r\n args.splice(i, 1);\r\n }\r\n }\r\n return [streams, streamIds];\r\n }\r\n _isObservable(arg) {\r\n // This allows other stream implementations to just work (like rxjs)\r\n return arg && arg.subscribe && typeof arg.subscribe === \"function\";\r\n }\r\n _createStreamInvocation(methodName, args, streamIds) {\r\n const invocationId = this._invocationId;\r\n this._invocationId++;\r\n if (streamIds.length !== 0) {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n streamIds,\r\n target: methodName,\r\n type: MessageType.StreamInvocation,\r\n };\r\n }\r\n else {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n target: methodName,\r\n type: MessageType.StreamInvocation,\r\n };\r\n }\r\n }\r\n _createCancelInvocation(id) {\r\n return {\r\n invocationId: id,\r\n type: MessageType.CancelInvocation,\r\n };\r\n }\r\n _createStreamItemMessage(id, item) {\r\n return {\r\n invocationId: id,\r\n item,\r\n type: MessageType.StreamItem,\r\n };\r\n }\r\n _createCompletionMessage(id, error, result) {\r\n if (error) {\r\n return {\r\n error,\r\n invocationId: id,\r\n type: MessageType.Completion,\r\n };\r\n }\r\n return {\r\n invocationId: id,\r\n result,\r\n type: MessageType.Completion,\r\n };\r\n }\r\n _createCloseMessage() {\r\n return { type: MessageType.Close };\r\n }\r\n}\r\n//# sourceMappingURL=HubConnection.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n// 0, 2, 10, 30 second delays before reconnect attempts.\r\nconst DEFAULT_RETRY_DELAYS_IN_MILLISECONDS = [0, 2000, 10000, 30000, null];\r\n/** @private */\r\nexport class DefaultReconnectPolicy {\r\n constructor(retryDelays) {\r\n this._retryDelays = retryDelays !== undefined ? [...retryDelays, null] : DEFAULT_RETRY_DELAYS_IN_MILLISECONDS;\r\n }\r\n nextRetryDelayInMilliseconds(retryContext) {\r\n return this._retryDelays[retryContext.previousRetryCount];\r\n }\r\n}\r\n//# sourceMappingURL=DefaultReconnectPolicy.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nexport class HeaderNames {\r\n}\r\nHeaderNames.Authorization = \"Authorization\";\r\nHeaderNames.Cookie = \"Cookie\";\r\n//# sourceMappingURL=HeaderNames.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { HeaderNames } from \"./HeaderNames\";\r\nimport { HttpClient } from \"./HttpClient\";\r\n/** @private */\r\nexport class AccessTokenHttpClient extends HttpClient {\r\n constructor(innerClient, accessTokenFactory) {\r\n super();\r\n this._innerClient = innerClient;\r\n this._accessTokenFactory = accessTokenFactory;\r\n }\r\n async send(request) {\r\n let allowRetry = true;\r\n if (this._accessTokenFactory && (!this._accessToken || (request.url && request.url.indexOf(\"/negotiate?\") > 0))) {\r\n // don't retry if the request is a negotiate or if we just got a potentially new token from the access token factory\r\n allowRetry = false;\r\n this._accessToken = await this._accessTokenFactory();\r\n }\r\n this._setAuthorizationHeader(request);\r\n const response = await this._innerClient.send(request);\r\n if (allowRetry && response.statusCode === 401 && this._accessTokenFactory) {\r\n this._accessToken = await this._accessTokenFactory();\r\n this._setAuthorizationHeader(request);\r\n return await this._innerClient.send(request);\r\n }\r\n return response;\r\n }\r\n _setAuthorizationHeader(request) {\r\n if (!request.headers) {\r\n request.headers = {};\r\n }\r\n if (this._accessToken) {\r\n request.headers[HeaderNames.Authorization] = `Bearer ${this._accessToken}`;\r\n }\r\n // don't remove the header if there isn't an access token factory, the user manually added the header in this case\r\n else if (this._accessTokenFactory) {\r\n if (request.headers[HeaderNames.Authorization]) {\r\n delete request.headers[HeaderNames.Authorization];\r\n }\r\n }\r\n }\r\n getCookieString(url) {\r\n return this._innerClient.getCookieString(url);\r\n }\r\n}\r\n//# sourceMappingURL=AccessTokenHttpClient.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n// This will be treated as a bit flag in the future, so we keep it using power-of-two values.\r\n/** Specifies a specific HTTP transport type. */\r\nexport var HttpTransportType;\r\n(function (HttpTransportType) {\r\n /** Specifies no transport preference. */\r\n HttpTransportType[HttpTransportType[\"None\"] = 0] = \"None\";\r\n /** Specifies the WebSockets transport. */\r\n HttpTransportType[HttpTransportType[\"WebSockets\"] = 1] = \"WebSockets\";\r\n /** Specifies the Server-Sent Events transport. */\r\n HttpTransportType[HttpTransportType[\"ServerSentEvents\"] = 2] = \"ServerSentEvents\";\r\n /** Specifies the Long Polling transport. */\r\n HttpTransportType[HttpTransportType[\"LongPolling\"] = 4] = \"LongPolling\";\r\n})(HttpTransportType || (HttpTransportType = {}));\r\n/** Specifies the transfer format for a connection. */\r\nexport var TransferFormat;\r\n(function (TransferFormat) {\r\n /** Specifies that only text data will be transmitted over the connection. */\r\n TransferFormat[TransferFormat[\"Text\"] = 1] = \"Text\";\r\n /** Specifies that binary data will be transmitted over the connection. */\r\n TransferFormat[TransferFormat[\"Binary\"] = 2] = \"Binary\";\r\n})(TransferFormat || (TransferFormat = {}));\r\n//# sourceMappingURL=ITransport.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\n// Rough polyfill of https://developer.mozilla.org/en-US/docs/Web/API/AbortController\r\n// We don't actually ever use the API being polyfilled, we always use the polyfill because\r\n// it's a very new API right now.\r\n// Not exported from index.\r\n/** @private */\r\nexport class AbortController {\r\n constructor() {\r\n this._isAborted = false;\r\n this.onabort = null;\r\n }\r\n abort() {\r\n if (!this._isAborted) {\r\n this._isAborted = true;\r\n if (this.onabort) {\r\n this.onabort();\r\n }\r\n }\r\n }\r\n get signal() {\r\n return this;\r\n }\r\n get aborted() {\r\n return this._isAborted;\r\n }\r\n}\r\n//# sourceMappingURL=AbortController.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { AbortController } from \"./AbortController\";\r\nimport { HttpError, TimeoutError } from \"./Errors\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { TransferFormat } from \"./ITransport\";\r\nimport { Arg, getDataDetail, getUserAgentHeader, sendMessage } from \"./Utils\";\r\n// Not exported from 'index', this type is internal.\r\n/** @private */\r\nexport class LongPollingTransport {\r\n // This is an internal type, not exported from 'index' so this is really just internal.\r\n get pollAborted() {\r\n return this._pollAbort.aborted;\r\n }\r\n constructor(httpClient, logger, options) {\r\n this._httpClient = httpClient;\r\n this._logger = logger;\r\n this._pollAbort = new AbortController();\r\n this._options = options;\r\n this._running = false;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n async connect(url, transferFormat) {\r\n Arg.isRequired(url, \"url\");\r\n Arg.isRequired(transferFormat, \"transferFormat\");\r\n Arg.isIn(transferFormat, TransferFormat, \"transferFormat\");\r\n this._url = url;\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) Connecting.\");\r\n // Allow binary format on Node and Browsers that support binary content (indicated by the presence of responseType property)\r\n if (transferFormat === TransferFormat.Binary &&\r\n (typeof XMLHttpRequest !== \"undefined\" && typeof new XMLHttpRequest().responseType !== \"string\")) {\r\n throw new Error(\"Binary protocols over XmlHttpRequest not implementing advanced features are not supported.\");\r\n }\r\n const [name, value] = getUserAgentHeader();\r\n const headers = { [name]: value, ...this._options.headers };\r\n const pollOptions = {\r\n abortSignal: this._pollAbort.signal,\r\n headers,\r\n timeout: 100000,\r\n withCredentials: this._options.withCredentials,\r\n };\r\n if (transferFormat === TransferFormat.Binary) {\r\n pollOptions.responseType = \"arraybuffer\";\r\n }\r\n // Make initial long polling request\r\n // Server uses first long polling request to finish initializing connection and it returns without data\r\n const pollUrl = `${url}&_=${Date.now()}`;\r\n this._logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);\r\n const response = await this._httpClient.get(pollUrl, pollOptions);\r\n if (response.statusCode !== 200) {\r\n this._logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);\r\n // Mark running as false so that the poll immediately ends and runs the close logic\r\n this._closeError = new HttpError(response.statusText || \"\", response.statusCode);\r\n this._running = false;\r\n }\r\n else {\r\n this._running = true;\r\n }\r\n this._receiving = this._poll(this._url, pollOptions);\r\n }\r\n async _poll(url, pollOptions) {\r\n try {\r\n while (this._running) {\r\n try {\r\n const pollUrl = `${url}&_=${Date.now()}`;\r\n this._logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);\r\n const response = await this._httpClient.get(pollUrl, pollOptions);\r\n if (response.statusCode === 204) {\r\n this._logger.log(LogLevel.Information, \"(LongPolling transport) Poll terminated by server.\");\r\n this._running = false;\r\n }\r\n else if (response.statusCode !== 200) {\r\n this._logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);\r\n // Unexpected status code\r\n this._closeError = new HttpError(response.statusText || \"\", response.statusCode);\r\n this._running = false;\r\n }\r\n else {\r\n // Process the response\r\n if (response.content) {\r\n this._logger.log(LogLevel.Trace, `(LongPolling transport) data received. ${getDataDetail(response.content, this._options.logMessageContent)}.`);\r\n if (this.onreceive) {\r\n this.onreceive(response.content);\r\n }\r\n }\r\n else {\r\n // This is another way timeout manifest.\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) Poll timed out, reissuing.\");\r\n }\r\n }\r\n }\r\n catch (e) {\r\n if (!this._running) {\r\n // Log but disregard errors that occur after stopping\r\n this._logger.log(LogLevel.Trace, `(LongPolling transport) Poll errored after shutdown: ${e.message}`);\r\n }\r\n else {\r\n if (e instanceof TimeoutError) {\r\n // Ignore timeouts and reissue the poll.\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) Poll timed out, reissuing.\");\r\n }\r\n else {\r\n // Close the connection with the error as the result.\r\n this._closeError = e;\r\n this._running = false;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n finally {\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) Polling complete.\");\r\n // We will reach here with pollAborted==false when the server returned a response causing the transport to stop.\r\n // If pollAborted==true then client initiated the stop and the stop method will raise the close event after DELETE is sent.\r\n if (!this.pollAborted) {\r\n this._raiseOnClose();\r\n }\r\n }\r\n }\r\n async send(data) {\r\n if (!this._running) {\r\n return Promise.reject(new Error(\"Cannot send until the transport is connected\"));\r\n }\r\n return sendMessage(this._logger, \"LongPolling\", this._httpClient, this._url, data, this._options);\r\n }\r\n async stop() {\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) Stopping polling.\");\r\n // Tell receiving loop to stop, abort any current request, and then wait for it to finish\r\n this._running = false;\r\n this._pollAbort.abort();\r\n try {\r\n await this._receiving;\r\n // Send DELETE to clean up long polling on the server\r\n this._logger.log(LogLevel.Trace, `(LongPolling transport) sending DELETE request to ${this._url}.`);\r\n const headers = {};\r\n const [name, value] = getUserAgentHeader();\r\n headers[name] = value;\r\n const deleteOptions = {\r\n headers: { ...headers, ...this._options.headers },\r\n timeout: this._options.timeout,\r\n withCredentials: this._options.withCredentials,\r\n };\r\n let error;\r\n try {\r\n await this._httpClient.delete(this._url, deleteOptions);\r\n }\r\n catch (err) {\r\n error = err;\r\n }\r\n if (error) {\r\n if (error instanceof HttpError) {\r\n if (error.statusCode === 404) {\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) A 404 response was returned from sending a DELETE request.\");\r\n }\r\n else {\r\n this._logger.log(LogLevel.Trace, `(LongPolling transport) Error sending a DELETE request: ${error}`);\r\n }\r\n }\r\n }\r\n else {\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) DELETE request accepted.\");\r\n }\r\n }\r\n finally {\r\n this._logger.log(LogLevel.Trace, \"(LongPolling transport) Stop finished.\");\r\n // Raise close event here instead of in polling\r\n // It needs to happen after the DELETE request is sent\r\n this._raiseOnClose();\r\n }\r\n }\r\n _raiseOnClose() {\r\n if (this.onclose) {\r\n let logMessage = \"(LongPolling transport) Firing onclose event.\";\r\n if (this._closeError) {\r\n logMessage += \" Error: \" + this._closeError;\r\n }\r\n this._logger.log(LogLevel.Trace, logMessage);\r\n this.onclose(this._closeError);\r\n }\r\n }\r\n}\r\n//# sourceMappingURL=LongPollingTransport.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { TransferFormat } from \"./ITransport\";\r\nimport { Arg, getDataDetail, getUserAgentHeader, Platform, sendMessage } from \"./Utils\";\r\n/** @private */\r\nexport class ServerSentEventsTransport {\r\n constructor(httpClient, accessToken, logger, options) {\r\n this._httpClient = httpClient;\r\n this._accessToken = accessToken;\r\n this._logger = logger;\r\n this._options = options;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n async connect(url, transferFormat) {\r\n Arg.isRequired(url, \"url\");\r\n Arg.isRequired(transferFormat, \"transferFormat\");\r\n Arg.isIn(transferFormat, TransferFormat, \"transferFormat\");\r\n this._logger.log(LogLevel.Trace, \"(SSE transport) Connecting.\");\r\n // set url before accessTokenFactory because this._url is only for send and we set the auth header instead of the query string for send\r\n this._url = url;\r\n if (this._accessToken) {\r\n url += (url.indexOf(\"?\") < 0 ? \"?\" : \"&\") + `access_token=${encodeURIComponent(this._accessToken)}`;\r\n }\r\n return new Promise((resolve, reject) => {\r\n let opened = false;\r\n if (transferFormat !== TransferFormat.Text) {\r\n reject(new Error(\"The Server-Sent Events transport only supports the 'Text' transfer format\"));\r\n return;\r\n }\r\n let eventSource;\r\n if (Platform.isBrowser || Platform.isWebWorker) {\r\n eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials });\r\n }\r\n else {\r\n // Non-browser passes cookies via the dictionary\r\n const cookies = this._httpClient.getCookieString(url);\r\n const headers = {};\r\n headers.Cookie = cookies;\r\n const [name, value] = getUserAgentHeader();\r\n headers[name] = value;\r\n eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials, headers: { ...headers, ...this._options.headers } });\r\n }\r\n try {\r\n eventSource.onmessage = (e) => {\r\n if (this.onreceive) {\r\n try {\r\n this._logger.log(LogLevel.Trace, `(SSE transport) data received. ${getDataDetail(e.data, this._options.logMessageContent)}.`);\r\n this.onreceive(e.data);\r\n }\r\n catch (error) {\r\n this._close(error);\r\n return;\r\n }\r\n }\r\n };\r\n // @ts-ignore: not using event on purpose\r\n eventSource.onerror = (e) => {\r\n // EventSource doesn't give any useful information about server side closes.\r\n if (opened) {\r\n this._close();\r\n }\r\n else {\r\n reject(new Error(\"EventSource failed to connect. The connection could not be found on the server,\"\r\n + \" either the connection ID is not present on the server, or a proxy is refusing/buffering the connection.\"\r\n + \" If you have multiple servers check that sticky sessions are enabled.\"));\r\n }\r\n };\r\n eventSource.onopen = () => {\r\n this._logger.log(LogLevel.Information, `SSE connected to ${this._url}`);\r\n this._eventSource = eventSource;\r\n opened = true;\r\n resolve();\r\n };\r\n }\r\n catch (e) {\r\n reject(e);\r\n return;\r\n }\r\n });\r\n }\r\n async send(data) {\r\n if (!this._eventSource) {\r\n return Promise.reject(new Error(\"Cannot send until the transport is connected\"));\r\n }\r\n return sendMessage(this._logger, \"SSE\", this._httpClient, this._url, data, this._options);\r\n }\r\n stop() {\r\n this._close();\r\n return Promise.resolve();\r\n }\r\n _close(e) {\r\n if (this._eventSource) {\r\n this._eventSource.close();\r\n this._eventSource = undefined;\r\n if (this.onclose) {\r\n this.onclose(e);\r\n }\r\n }\r\n }\r\n}\r\n//# sourceMappingURL=ServerSentEventsTransport.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { HeaderNames } from \"./HeaderNames\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { TransferFormat } from \"./ITransport\";\r\nimport { Arg, getDataDetail, getUserAgentHeader, Platform } from \"./Utils\";\r\n/** @private */\r\nexport class WebSocketTransport {\r\n constructor(httpClient, accessTokenFactory, logger, logMessageContent, webSocketConstructor, headers) {\r\n this._logger = logger;\r\n this._accessTokenFactory = accessTokenFactory;\r\n this._logMessageContent = logMessageContent;\r\n this._webSocketConstructor = webSocketConstructor;\r\n this._httpClient = httpClient;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n this._headers = headers;\r\n }\r\n async connect(url, transferFormat) {\r\n Arg.isRequired(url, \"url\");\r\n Arg.isRequired(transferFormat, \"transferFormat\");\r\n Arg.isIn(transferFormat, TransferFormat, \"transferFormat\");\r\n this._logger.log(LogLevel.Trace, \"(WebSockets transport) Connecting.\");\r\n let token;\r\n if (this._accessTokenFactory) {\r\n token = await this._accessTokenFactory();\r\n }\r\n return new Promise((resolve, reject) => {\r\n url = url.replace(/^http/, \"ws\");\r\n let webSocket;\r\n const cookies = this._httpClient.getCookieString(url);\r\n let opened = false;\r\n if (Platform.isNode || Platform.isReactNative) {\r\n const headers = {};\r\n const [name, value] = getUserAgentHeader();\r\n headers[name] = value;\r\n if (token) {\r\n headers[HeaderNames.Authorization] = `Bearer ${token}`;\r\n }\r\n if (cookies) {\r\n headers[HeaderNames.Cookie] = cookies;\r\n }\r\n // Only pass headers when in non-browser environments\r\n webSocket = new this._webSocketConstructor(url, undefined, {\r\n headers: { ...headers, ...this._headers },\r\n });\r\n }\r\n else {\r\n if (token) {\r\n url += (url.indexOf(\"?\") < 0 ? \"?\" : \"&\") + `access_token=${encodeURIComponent(token)}`;\r\n }\r\n }\r\n if (!webSocket) {\r\n // Chrome is not happy with passing 'undefined' as protocol\r\n webSocket = new this._webSocketConstructor(url);\r\n }\r\n if (transferFormat === TransferFormat.Binary) {\r\n webSocket.binaryType = \"arraybuffer\";\r\n }\r\n webSocket.onopen = (_event) => {\r\n this._logger.log(LogLevel.Information, `WebSocket connected to ${url}.`);\r\n this._webSocket = webSocket;\r\n opened = true;\r\n resolve();\r\n };\r\n webSocket.onerror = (event) => {\r\n let error = null;\r\n // ErrorEvent is a browser only type we need to check if the type exists before using it\r\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent) {\r\n error = event.error;\r\n }\r\n else {\r\n error = \"There was an error with the transport\";\r\n }\r\n this._logger.log(LogLevel.Information, `(WebSockets transport) ${error}.`);\r\n };\r\n webSocket.onmessage = (message) => {\r\n this._logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this._logMessageContent)}.`);\r\n if (this.onreceive) {\r\n try {\r\n this.onreceive(message.data);\r\n }\r\n catch (error) {\r\n this._close(error);\r\n return;\r\n }\r\n }\r\n };\r\n webSocket.onclose = (event) => {\r\n // Don't call close handler if connection was never established\r\n // We'll reject the connect call instead\r\n if (opened) {\r\n this._close(event);\r\n }\r\n else {\r\n let error = null;\r\n // ErrorEvent is a browser only type we need to check if the type exists before using it\r\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent) {\r\n error = event.error;\r\n }\r\n else {\r\n error = \"WebSocket failed to connect. The connection could not be found on the server,\"\r\n + \" either the endpoint may not be a SignalR endpoint,\"\r\n + \" the connection ID is not present on the server, or there is a proxy blocking WebSockets.\"\r\n + \" If you have multiple servers check that sticky sessions are enabled.\";\r\n }\r\n reject(new Error(error));\r\n }\r\n };\r\n });\r\n }\r\n send(data) {\r\n if (this._webSocket && this._webSocket.readyState === this._webSocketConstructor.OPEN) {\r\n this._logger.log(LogLevel.Trace, `(WebSockets transport) sending data. ${getDataDetail(data, this._logMessageContent)}.`);\r\n this._webSocket.send(data);\r\n return Promise.resolve();\r\n }\r\n return Promise.reject(\"WebSocket is not in the OPEN state\");\r\n }\r\n stop() {\r\n if (this._webSocket) {\r\n // Manually invoke onclose callback inline so we know the HttpConnection was closed properly before returning\r\n // This also solves an issue where websocket.onclose could take 18+ seconds to trigger during network disconnects\r\n this._close(undefined);\r\n }\r\n return Promise.resolve();\r\n }\r\n _close(event) {\r\n // webSocket will be null if the transport did not start successfully\r\n if (this._webSocket) {\r\n // Clear websocket handlers because we are considering the socket closed now\r\n this._webSocket.onclose = () => { };\r\n this._webSocket.onmessage = () => { };\r\n this._webSocket.onerror = () => { };\r\n this._webSocket.close();\r\n this._webSocket = undefined;\r\n }\r\n this._logger.log(LogLevel.Trace, \"(WebSockets transport) socket closed.\");\r\n if (this.onclose) {\r\n if (this._isCloseEvent(event) && (event.wasClean === false || event.code !== 1000)) {\r\n this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason || \"no reason given\"}).`));\r\n }\r\n else if (event instanceof Error) {\r\n this.onclose(event);\r\n }\r\n else {\r\n this.onclose();\r\n }\r\n }\r\n }\r\n _isCloseEvent(event) {\r\n return event && typeof event.wasClean === \"boolean\" && typeof event.code === \"number\";\r\n }\r\n}\r\n//# sourceMappingURL=WebSocketTransport.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { AccessTokenHttpClient } from \"./AccessTokenHttpClient\";\r\nimport { DefaultHttpClient } from \"./DefaultHttpClient\";\r\nimport { AggregateErrors, DisabledTransportError, FailedToNegotiateWithServerError, FailedToStartTransportError, HttpError, UnsupportedTransportError, AbortError } from \"./Errors\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { HttpTransportType, TransferFormat } from \"./ITransport\";\r\nimport { LongPollingTransport } from \"./LongPollingTransport\";\r\nimport { ServerSentEventsTransport } from \"./ServerSentEventsTransport\";\r\nimport { Arg, createLogger, getUserAgentHeader, Platform } from \"./Utils\";\r\nimport { WebSocketTransport } from \"./WebSocketTransport\";\r\nconst MAX_REDIRECTS = 100;\r\n/** @private */\r\nexport class HttpConnection {\r\n constructor(url, options = {}) {\r\n this._stopPromiseResolver = () => { };\r\n this.features = {};\r\n this._negotiateVersion = 1;\r\n Arg.isRequired(url, \"url\");\r\n this._logger = createLogger(options.logger);\r\n this.baseUrl = this._resolveUrl(url);\r\n options = options || {};\r\n options.logMessageContent = options.logMessageContent === undefined ? false : options.logMessageContent;\r\n if (typeof options.withCredentials === \"boolean\" || options.withCredentials === undefined) {\r\n options.withCredentials = options.withCredentials === undefined ? true : options.withCredentials;\r\n }\r\n else {\r\n throw new Error(\"withCredentials option was not a 'boolean' or 'undefined' value\");\r\n }\r\n options.timeout = options.timeout === undefined ? 100 * 1000 : options.timeout;\r\n let webSocketModule = null;\r\n let eventSourceModule = null;\r\n if (Platform.isNode && typeof require !== \"undefined\") {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n const requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n webSocketModule = requireFunc(\"ws\");\r\n eventSourceModule = requireFunc(\"eventsource\");\r\n }\r\n if (!Platform.isNode && typeof WebSocket !== \"undefined\" && !options.WebSocket) {\r\n options.WebSocket = WebSocket;\r\n }\r\n else if (Platform.isNode && !options.WebSocket) {\r\n if (webSocketModule) {\r\n options.WebSocket = webSocketModule;\r\n }\r\n }\r\n if (!Platform.isNode && typeof EventSource !== \"undefined\" && !options.EventSource) {\r\n options.EventSource = EventSource;\r\n }\r\n else if (Platform.isNode && !options.EventSource) {\r\n if (typeof eventSourceModule !== \"undefined\") {\r\n options.EventSource = eventSourceModule;\r\n }\r\n }\r\n this._httpClient = new AccessTokenHttpClient(options.httpClient || new DefaultHttpClient(this._logger), options.accessTokenFactory);\r\n this._connectionState = \"Disconnected\" /* ConnectionState.Disconnected */;\r\n this._connectionStarted = false;\r\n this._options = options;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n async start(transferFormat) {\r\n transferFormat = transferFormat || TransferFormat.Binary;\r\n Arg.isIn(transferFormat, TransferFormat, \"transferFormat\");\r\n this._logger.log(LogLevel.Debug, `Starting connection with transfer format '${TransferFormat[transferFormat]}'.`);\r\n if (this._connectionState !== \"Disconnected\" /* ConnectionState.Disconnected */) {\r\n return Promise.reject(new Error(\"Cannot start an HttpConnection that is not in the 'Disconnected' state.\"));\r\n }\r\n this._connectionState = \"Connecting\" /* ConnectionState.Connecting */;\r\n this._startInternalPromise = this._startInternal(transferFormat);\r\n await this._startInternalPromise;\r\n // The TypeScript compiler thinks that connectionState must be Connecting here. The TypeScript compiler is wrong.\r\n if (this._connectionState === \"Disconnecting\" /* ConnectionState.Disconnecting */) {\r\n // stop() was called and transitioned the client into the Disconnecting state.\r\n const message = \"Failed to start the HttpConnection before stop() was called.\";\r\n this._logger.log(LogLevel.Error, message);\r\n // We cannot await stopPromise inside startInternal since stopInternal awaits the startInternalPromise.\r\n await this._stopPromise;\r\n return Promise.reject(new AbortError(message));\r\n }\r\n else if (this._connectionState !== \"Connected\" /* ConnectionState.Connected */) {\r\n // stop() was called and transitioned the client into the Disconnecting state.\r\n const message = \"HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!\";\r\n this._logger.log(LogLevel.Error, message);\r\n return Promise.reject(new AbortError(message));\r\n }\r\n this._connectionStarted = true;\r\n }\r\n send(data) {\r\n if (this._connectionState !== \"Connected\" /* ConnectionState.Connected */) {\r\n return Promise.reject(new Error(\"Cannot send data if the connection is not in the 'Connected' State.\"));\r\n }\r\n if (!this._sendQueue) {\r\n this._sendQueue = new TransportSendQueue(this.transport);\r\n }\r\n // Transport will not be null if state is connected\r\n return this._sendQueue.send(data);\r\n }\r\n async stop(error) {\r\n if (this._connectionState === \"Disconnected\" /* ConnectionState.Disconnected */) {\r\n this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnected state.`);\r\n return Promise.resolve();\r\n }\r\n if (this._connectionState === \"Disconnecting\" /* ConnectionState.Disconnecting */) {\r\n this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);\r\n return this._stopPromise;\r\n }\r\n this._connectionState = \"Disconnecting\" /* ConnectionState.Disconnecting */;\r\n this._stopPromise = new Promise((resolve) => {\r\n // Don't complete stop() until stopConnection() completes.\r\n this._stopPromiseResolver = resolve;\r\n });\r\n // stopInternal should never throw so just observe it.\r\n await this._stopInternal(error);\r\n await this._stopPromise;\r\n }\r\n async _stopInternal(error) {\r\n // Set error as soon as possible otherwise there is a race between\r\n // the transport closing and providing an error and the error from a close message\r\n // We would prefer the close message error.\r\n this._stopError = error;\r\n try {\r\n await this._startInternalPromise;\r\n }\r\n catch (e) {\r\n // This exception is returned to the user as a rejected Promise from the start method.\r\n }\r\n // The transport's onclose will trigger stopConnection which will run our onclose event.\r\n // The transport should always be set if currently connected. If it wasn't set, it's likely because\r\n // stop was called during start() and start() failed.\r\n if (this.transport) {\r\n try {\r\n await this.transport.stop();\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `HttpConnection.transport.stop() threw error '${e}'.`);\r\n this._stopConnection();\r\n }\r\n this.transport = undefined;\r\n }\r\n else {\r\n this._logger.log(LogLevel.Debug, \"HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.\");\r\n }\r\n }\r\n async _startInternal(transferFormat) {\r\n // Store the original base url and the access token factory since they may change\r\n // as part of negotiating\r\n let url = this.baseUrl;\r\n this._accessTokenFactory = this._options.accessTokenFactory;\r\n this._httpClient._accessTokenFactory = this._accessTokenFactory;\r\n try {\r\n if (this._options.skipNegotiation) {\r\n if (this._options.transport === HttpTransportType.WebSockets) {\r\n // No need to add a connection ID in this case\r\n this.transport = this._constructTransport(HttpTransportType.WebSockets);\r\n // We should just call connect directly in this case.\r\n // No fallback or negotiate in this case.\r\n await this._startTransport(url, transferFormat);\r\n }\r\n else {\r\n throw new Error(\"Negotiation can only be skipped when using the WebSocket transport directly.\");\r\n }\r\n }\r\n else {\r\n let negotiateResponse = null;\r\n let redirects = 0;\r\n do {\r\n negotiateResponse = await this._getNegotiationResponse(url);\r\n // the user tries to stop the connection when it is being started\r\n if (this._connectionState === \"Disconnecting\" /* ConnectionState.Disconnecting */ || this._connectionState === \"Disconnected\" /* ConnectionState.Disconnected */) {\r\n throw new AbortError(\"The connection was stopped during negotiation.\");\r\n }\r\n if (negotiateResponse.error) {\r\n throw new Error(negotiateResponse.error);\r\n }\r\n if (negotiateResponse.ProtocolVersion) {\r\n throw new Error(\"Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.\");\r\n }\r\n if (negotiateResponse.url) {\r\n url = negotiateResponse.url;\r\n }\r\n if (negotiateResponse.accessToken) {\r\n // Replace the current access token factory with one that uses\r\n // the returned access token\r\n const accessToken = negotiateResponse.accessToken;\r\n this._accessTokenFactory = () => accessToken;\r\n // set the factory to undefined so the AccessTokenHttpClient won't retry with the same token, since we know it won't change until a connection restart\r\n this._httpClient._accessToken = accessToken;\r\n this._httpClient._accessTokenFactory = undefined;\r\n }\r\n redirects++;\r\n } while (negotiateResponse.url && redirects < MAX_REDIRECTS);\r\n if (redirects === MAX_REDIRECTS && negotiateResponse.url) {\r\n throw new Error(\"Negotiate redirection limit exceeded.\");\r\n }\r\n await this._createTransport(url, this._options.transport, negotiateResponse, transferFormat);\r\n }\r\n if (this.transport instanceof LongPollingTransport) {\r\n this.features.inherentKeepAlive = true;\r\n }\r\n if (this._connectionState === \"Connecting\" /* ConnectionState.Connecting */) {\r\n // Ensure the connection transitions to the connected state prior to completing this.startInternalPromise.\r\n // start() will handle the case when stop was called and startInternal exits still in the disconnecting state.\r\n this._logger.log(LogLevel.Debug, \"The HttpConnection connected successfully.\");\r\n this._connectionState = \"Connected\" /* ConnectionState.Connected */;\r\n }\r\n // stop() is waiting on us via this.startInternalPromise so keep this.transport around so it can clean up.\r\n // This is the only case startInternal can exit in neither the connected nor disconnected state because stopConnection()\r\n // will transition to the disconnected state. start() will wait for the transition using the stopPromise.\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, \"Failed to start the connection: \" + e);\r\n this._connectionState = \"Disconnected\" /* ConnectionState.Disconnected */;\r\n this.transport = undefined;\r\n // if start fails, any active calls to stop assume that start will complete the stop promise\r\n this._stopPromiseResolver();\r\n return Promise.reject(e);\r\n }\r\n }\r\n async _getNegotiationResponse(url) {\r\n const headers = {};\r\n const [name, value] = getUserAgentHeader();\r\n headers[name] = value;\r\n const negotiateUrl = this._resolveNegotiateUrl(url);\r\n this._logger.log(LogLevel.Debug, `Sending negotiation request: ${negotiateUrl}.`);\r\n try {\r\n const response = await this._httpClient.post(negotiateUrl, {\r\n content: \"\",\r\n headers: { ...headers, ...this._options.headers },\r\n timeout: this._options.timeout,\r\n withCredentials: this._options.withCredentials,\r\n });\r\n if (response.statusCode !== 200) {\r\n return Promise.reject(new Error(`Unexpected status code returned from negotiate '${response.statusCode}'`));\r\n }\r\n const negotiateResponse = JSON.parse(response.content);\r\n if (!negotiateResponse.negotiateVersion || negotiateResponse.negotiateVersion < 1) {\r\n // Negotiate version 0 doesn't use connectionToken\r\n // So we set it equal to connectionId so all our logic can use connectionToken without being aware of the negotiate version\r\n negotiateResponse.connectionToken = negotiateResponse.connectionId;\r\n }\r\n if (negotiateResponse.useStatefulReconnect && this._options._useStatefulReconnect !== true) {\r\n return Promise.reject(new FailedToNegotiateWithServerError(\"Client didn't negotiate Stateful Reconnect but the server did.\"));\r\n }\r\n return negotiateResponse;\r\n }\r\n catch (e) {\r\n let errorMessage = \"Failed to complete negotiation with the server: \" + e;\r\n if (e instanceof HttpError) {\r\n if (e.statusCode === 404) {\r\n errorMessage = errorMessage + \" Either this is not a SignalR endpoint or there is a proxy blocking the connection.\";\r\n }\r\n }\r\n this._logger.log(LogLevel.Error, errorMessage);\r\n return Promise.reject(new FailedToNegotiateWithServerError(errorMessage));\r\n }\r\n }\r\n _createConnectUrl(url, connectionToken) {\r\n if (!connectionToken) {\r\n return url;\r\n }\r\n return url + (url.indexOf(\"?\") === -1 ? \"?\" : \"&\") + `id=${connectionToken}`;\r\n }\r\n async _createTransport(url, requestedTransport, negotiateResponse, requestedTransferFormat) {\r\n let connectUrl = this._createConnectUrl(url, negotiateResponse.connectionToken);\r\n if (this._isITransport(requestedTransport)) {\r\n this._logger.log(LogLevel.Debug, \"Connection was provided an instance of ITransport, using that directly.\");\r\n this.transport = requestedTransport;\r\n await this._startTransport(connectUrl, requestedTransferFormat);\r\n this.connectionId = negotiateResponse.connectionId;\r\n return;\r\n }\r\n const transportExceptions = [];\r\n const transports = negotiateResponse.availableTransports || [];\r\n let negotiate = negotiateResponse;\r\n for (const endpoint of transports) {\r\n const transportOrError = this._resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat, (negotiate === null || negotiate === void 0 ? void 0 : negotiate.useStatefulReconnect) === true);\r\n if (transportOrError instanceof Error) {\r\n // Store the error and continue, we don't want to cause a re-negotiate in these cases\r\n transportExceptions.push(`${endpoint.transport} failed:`);\r\n transportExceptions.push(transportOrError);\r\n }\r\n else if (this._isITransport(transportOrError)) {\r\n this.transport = transportOrError;\r\n if (!negotiate) {\r\n try {\r\n negotiate = await this._getNegotiationResponse(url);\r\n }\r\n catch (ex) {\r\n return Promise.reject(ex);\r\n }\r\n connectUrl = this._createConnectUrl(url, negotiate.connectionToken);\r\n }\r\n try {\r\n await this._startTransport(connectUrl, requestedTransferFormat);\r\n this.connectionId = negotiate.connectionId;\r\n return;\r\n }\r\n catch (ex) {\r\n this._logger.log(LogLevel.Error, `Failed to start the transport '${endpoint.transport}': ${ex}`);\r\n negotiate = undefined;\r\n transportExceptions.push(new FailedToStartTransportError(`${endpoint.transport} failed: ${ex}`, HttpTransportType[endpoint.transport]));\r\n if (this._connectionState !== \"Connecting\" /* ConnectionState.Connecting */) {\r\n const message = \"Failed to select transport before stop() was called.\";\r\n this._logger.log(LogLevel.Debug, message);\r\n return Promise.reject(new AbortError(message));\r\n }\r\n }\r\n }\r\n }\r\n if (transportExceptions.length > 0) {\r\n return Promise.reject(new AggregateErrors(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(\" \")}`, transportExceptions));\r\n }\r\n return Promise.reject(new Error(\"None of the transports supported by the client are supported by the server.\"));\r\n }\r\n _constructTransport(transport) {\r\n switch (transport) {\r\n case HttpTransportType.WebSockets:\r\n if (!this._options.WebSocket) {\r\n throw new Error(\"'WebSocket' is not supported in your environment.\");\r\n }\r\n return new WebSocketTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options.logMessageContent, this._options.WebSocket, this._options.headers || {});\r\n case HttpTransportType.ServerSentEvents:\r\n if (!this._options.EventSource) {\r\n throw new Error(\"'EventSource' is not supported in your environment.\");\r\n }\r\n return new ServerSentEventsTransport(this._httpClient, this._httpClient._accessToken, this._logger, this._options);\r\n case HttpTransportType.LongPolling:\r\n return new LongPollingTransport(this._httpClient, this._logger, this._options);\r\n default:\r\n throw new Error(`Unknown transport: ${transport}.`);\r\n }\r\n }\r\n _startTransport(url, transferFormat) {\r\n this.transport.onreceive = this.onreceive;\r\n if (this.features.reconnect) {\r\n this.transport.onclose = async (e) => {\r\n let callStop = false;\r\n if (this.features.reconnect) {\r\n try {\r\n this.features.disconnected();\r\n await this.transport.connect(url, transferFormat);\r\n await this.features.resend();\r\n }\r\n catch {\r\n callStop = true;\r\n }\r\n }\r\n else {\r\n this._stopConnection(e);\r\n return;\r\n }\r\n if (callStop) {\r\n this._stopConnection(e);\r\n }\r\n };\r\n }\r\n else {\r\n this.transport.onclose = (e) => this._stopConnection(e);\r\n }\r\n return this.transport.connect(url, transferFormat);\r\n }\r\n _resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat, useStatefulReconnect) {\r\n const transport = HttpTransportType[endpoint.transport];\r\n if (transport === null || transport === undefined) {\r\n this._logger.log(LogLevel.Debug, `Skipping transport '${endpoint.transport}' because it is not supported by this client.`);\r\n return new Error(`Skipping transport '${endpoint.transport}' because it is not supported by this client.`);\r\n }\r\n else {\r\n if (transportMatches(requestedTransport, transport)) {\r\n const transferFormats = endpoint.transferFormats.map((s) => TransferFormat[s]);\r\n if (transferFormats.indexOf(requestedTransferFormat) >= 0) {\r\n if ((transport === HttpTransportType.WebSockets && !this._options.WebSocket) ||\r\n (transport === HttpTransportType.ServerSentEvents && !this._options.EventSource)) {\r\n this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it is not supported in your environment.'`);\r\n return new UnsupportedTransportError(`'${HttpTransportType[transport]}' is not supported in your environment.`, transport);\r\n }\r\n else {\r\n this._logger.log(LogLevel.Debug, `Selecting transport '${HttpTransportType[transport]}'.`);\r\n try {\r\n this.features.reconnect = transport === HttpTransportType.WebSockets ? useStatefulReconnect : undefined;\r\n return this._constructTransport(transport);\r\n }\r\n catch (ex) {\r\n return ex;\r\n }\r\n }\r\n }\r\n else {\r\n this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it does not support the requested transfer format '${TransferFormat[requestedTransferFormat]}'.`);\r\n return new Error(`'${HttpTransportType[transport]}' does not support ${TransferFormat[requestedTransferFormat]}.`);\r\n }\r\n }\r\n else {\r\n this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it was disabled by the client.`);\r\n return new DisabledTransportError(`'${HttpTransportType[transport]}' is disabled by the client.`, transport);\r\n }\r\n }\r\n }\r\n _isITransport(transport) {\r\n return transport && typeof (transport) === \"object\" && \"connect\" in transport;\r\n }\r\n _stopConnection(error) {\r\n this._logger.log(LogLevel.Debug, `HttpConnection.stopConnection(${error}) called while in state ${this._connectionState}.`);\r\n this.transport = undefined;\r\n // If we have a stopError, it takes precedence over the error from the transport\r\n error = this._stopError || error;\r\n this._stopError = undefined;\r\n if (this._connectionState === \"Disconnected\" /* ConnectionState.Disconnected */) {\r\n this._logger.log(LogLevel.Debug, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is already in the disconnected state.`);\r\n return;\r\n }\r\n if (this._connectionState === \"Connecting\" /* ConnectionState.Connecting */) {\r\n this._logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is still in the connecting state.`);\r\n throw new Error(`HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.`);\r\n }\r\n if (this._connectionState === \"Disconnecting\" /* ConnectionState.Disconnecting */) {\r\n // A call to stop() induced this call to stopConnection and needs to be completed.\r\n // Any stop() awaiters will be scheduled to continue after the onclose callback fires.\r\n this._stopPromiseResolver();\r\n }\r\n if (error) {\r\n this._logger.log(LogLevel.Error, `Connection disconnected with error '${error}'.`);\r\n }\r\n else {\r\n this._logger.log(LogLevel.Information, \"Connection disconnected.\");\r\n }\r\n if (this._sendQueue) {\r\n this._sendQueue.stop().catch((e) => {\r\n this._logger.log(LogLevel.Error, `TransportSendQueue.stop() threw error '${e}'.`);\r\n });\r\n this._sendQueue = undefined;\r\n }\r\n this.connectionId = undefined;\r\n this._connectionState = \"Disconnected\" /* ConnectionState.Disconnected */;\r\n if (this._connectionStarted) {\r\n this._connectionStarted = false;\r\n try {\r\n if (this.onclose) {\r\n this.onclose(error);\r\n }\r\n }\r\n catch (e) {\r\n this._logger.log(LogLevel.Error, `HttpConnection.onclose(${error}) threw error '${e}'.`);\r\n }\r\n }\r\n }\r\n _resolveUrl(url) {\r\n // startsWith is not supported in IE\r\n if (url.lastIndexOf(\"https://\", 0) === 0 || url.lastIndexOf(\"http://\", 0) === 0) {\r\n return url;\r\n }\r\n if (!Platform.isBrowser) {\r\n throw new Error(`Cannot resolve '${url}'.`);\r\n }\r\n // Setting the url to the href propery of an anchor tag handles normalization\r\n // for us. There are 3 main cases.\r\n // 1. Relative path normalization e.g \"b\" -> \"http://localhost:5000/a/b\"\r\n // 2. Absolute path normalization e.g \"/a/b\" -> \"http://localhost:5000/a/b\"\r\n // 3. Networkpath reference normalization e.g \"//localhost:5000/a/b\" -> \"http://localhost:5000/a/b\"\r\n const aTag = window.document.createElement(\"a\");\r\n aTag.href = url;\r\n this._logger.log(LogLevel.Information, `Normalizing '${url}' to '${aTag.href}'.`);\r\n return aTag.href;\r\n }\r\n _resolveNegotiateUrl(url) {\r\n const negotiateUrl = new URL(url);\r\n if (negotiateUrl.pathname.endsWith('/')) {\r\n negotiateUrl.pathname += \"negotiate\";\r\n }\r\n else {\r\n negotiateUrl.pathname += \"/negotiate\";\r\n }\r\n const searchParams = new URLSearchParams(negotiateUrl.searchParams);\r\n if (!searchParams.has(\"negotiateVersion\")) {\r\n searchParams.append(\"negotiateVersion\", this._negotiateVersion.toString());\r\n }\r\n if (searchParams.has(\"useStatefulReconnect\")) {\r\n if (searchParams.get(\"useStatefulReconnect\") === \"true\") {\r\n this._options._useStatefulReconnect = true;\r\n }\r\n }\r\n else if (this._options._useStatefulReconnect === true) {\r\n searchParams.append(\"useStatefulReconnect\", \"true\");\r\n }\r\n negotiateUrl.search = searchParams.toString();\r\n return negotiateUrl.toString();\r\n }\r\n}\r\nfunction transportMatches(requestedTransport, actualTransport) {\r\n return !requestedTransport || ((actualTransport & requestedTransport) !== 0);\r\n}\r\n/** @private */\r\nexport class TransportSendQueue {\r\n constructor(_transport) {\r\n this._transport = _transport;\r\n this._buffer = [];\r\n this._executing = true;\r\n this._sendBufferedData = new PromiseSource();\r\n this._transportResult = new PromiseSource();\r\n this._sendLoopPromise = this._sendLoop();\r\n }\r\n send(data) {\r\n this._bufferData(data);\r\n if (!this._transportResult) {\r\n this._transportResult = new PromiseSource();\r\n }\r\n return this._transportResult.promise;\r\n }\r\n stop() {\r\n this._executing = false;\r\n this._sendBufferedData.resolve();\r\n return this._sendLoopPromise;\r\n }\r\n _bufferData(data) {\r\n if (this._buffer.length && typeof (this._buffer[0]) !== typeof (data)) {\r\n throw new Error(`Expected data to be of type ${typeof (this._buffer)} but was of type ${typeof (data)}`);\r\n }\r\n this._buffer.push(data);\r\n this._sendBufferedData.resolve();\r\n }\r\n async _sendLoop() {\r\n while (true) {\r\n await this._sendBufferedData.promise;\r\n if (!this._executing) {\r\n if (this._transportResult) {\r\n this._transportResult.reject(\"Connection stopped.\");\r\n }\r\n break;\r\n }\r\n this._sendBufferedData = new PromiseSource();\r\n const transportResult = this._transportResult;\r\n this._transportResult = undefined;\r\n const data = typeof (this._buffer[0]) === \"string\" ?\r\n this._buffer.join(\"\") :\r\n TransportSendQueue._concatBuffers(this._buffer);\r\n this._buffer.length = 0;\r\n try {\r\n await this._transport.send(data);\r\n transportResult.resolve();\r\n }\r\n catch (error) {\r\n transportResult.reject(error);\r\n }\r\n }\r\n }\r\n static _concatBuffers(arrayBuffers) {\r\n const totalLength = arrayBuffers.map((b) => b.byteLength).reduce((a, b) => a + b);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const item of arrayBuffers) {\r\n result.set(new Uint8Array(item), offset);\r\n offset += item.byteLength;\r\n }\r\n return result.buffer;\r\n }\r\n}\r\nclass PromiseSource {\r\n constructor() {\r\n this.promise = new Promise((resolve, reject) => [this._resolver, this._rejecter] = [resolve, reject]);\r\n }\r\n resolve() {\r\n this._resolver();\r\n }\r\n reject(reason) {\r\n this._rejecter(reason);\r\n }\r\n}\r\n//# sourceMappingURL=HttpConnection.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { MessageType } from \"./IHubProtocol\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { TransferFormat } from \"./ITransport\";\r\nimport { NullLogger } from \"./Loggers\";\r\nimport { TextMessageFormat } from \"./TextMessageFormat\";\r\nconst JSON_HUB_PROTOCOL_NAME = \"json\";\r\n/** Implements the JSON Hub Protocol. */\r\nexport class JsonHubProtocol {\r\n constructor() {\r\n /** @inheritDoc */\r\n this.name = JSON_HUB_PROTOCOL_NAME;\r\n /** @inheritDoc */\r\n this.version = 2;\r\n /** @inheritDoc */\r\n this.transferFormat = TransferFormat.Text;\r\n }\r\n /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.\r\n *\r\n * @param {string} input A string containing the serialized representation.\r\n * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.\r\n */\r\n parseMessages(input, logger) {\r\n // The interface does allow \"ArrayBuffer\" to be passed in, but this implementation does not. So let's throw a useful error.\r\n if (typeof input !== \"string\") {\r\n throw new Error(\"Invalid input for JSON hub protocol. Expected a string.\");\r\n }\r\n if (!input) {\r\n return [];\r\n }\r\n if (logger === null) {\r\n logger = NullLogger.instance;\r\n }\r\n // Parse the messages\r\n const messages = TextMessageFormat.parse(input);\r\n const hubMessages = [];\r\n for (const message of messages) {\r\n const parsedMessage = JSON.parse(message);\r\n if (typeof parsedMessage.type !== \"number\") {\r\n throw new Error(\"Invalid payload.\");\r\n }\r\n switch (parsedMessage.type) {\r\n case MessageType.Invocation:\r\n this._isInvocationMessage(parsedMessage);\r\n break;\r\n case MessageType.StreamItem:\r\n this._isStreamItemMessage(parsedMessage);\r\n break;\r\n case MessageType.Completion:\r\n this._isCompletionMessage(parsedMessage);\r\n break;\r\n case MessageType.Ping:\r\n // Single value, no need to validate\r\n break;\r\n case MessageType.Close:\r\n // All optional values, no need to validate\r\n break;\r\n case MessageType.Ack:\r\n this._isAckMessage(parsedMessage);\r\n break;\r\n case MessageType.Sequence:\r\n this._isSequenceMessage(parsedMessage);\r\n break;\r\n default:\r\n // Future protocol changes can add message types, old clients can ignore them\r\n logger.log(LogLevel.Information, \"Unknown message type '\" + parsedMessage.type + \"' ignored.\");\r\n continue;\r\n }\r\n hubMessages.push(parsedMessage);\r\n }\r\n return hubMessages;\r\n }\r\n /** Writes the specified {@link @microsoft/signalr.HubMessage} to a string and returns it.\r\n *\r\n * @param {HubMessage} message The message to write.\r\n * @returns {string} A string containing the serialized representation of the message.\r\n */\r\n writeMessage(message) {\r\n return TextMessageFormat.write(JSON.stringify(message));\r\n }\r\n _isInvocationMessage(message) {\r\n this._assertNotEmptyString(message.target, \"Invalid payload for Invocation message.\");\r\n if (message.invocationId !== undefined) {\r\n this._assertNotEmptyString(message.invocationId, \"Invalid payload for Invocation message.\");\r\n }\r\n }\r\n _isStreamItemMessage(message) {\r\n this._assertNotEmptyString(message.invocationId, \"Invalid payload for StreamItem message.\");\r\n if (message.item === undefined) {\r\n throw new Error(\"Invalid payload for StreamItem message.\");\r\n }\r\n }\r\n _isCompletionMessage(message) {\r\n if (message.result && message.error) {\r\n throw new Error(\"Invalid payload for Completion message.\");\r\n }\r\n if (!message.result && message.error) {\r\n this._assertNotEmptyString(message.error, \"Invalid payload for Completion message.\");\r\n }\r\n this._assertNotEmptyString(message.invocationId, \"Invalid payload for Completion message.\");\r\n }\r\n _isAckMessage(message) {\r\n if (typeof message.sequenceId !== 'number') {\r\n throw new Error(\"Invalid SequenceId for Ack message.\");\r\n }\r\n }\r\n _isSequenceMessage(message) {\r\n if (typeof message.sequenceId !== 'number') {\r\n throw new Error(\"Invalid SequenceId for Sequence message.\");\r\n }\r\n }\r\n _assertNotEmptyString(value, errorMessage) {\r\n if (typeof value !== \"string\" || value === \"\") {\r\n throw new Error(errorMessage);\r\n }\r\n }\r\n}\r\n//# sourceMappingURL=JsonHubProtocol.js.map","// Licensed to the .NET Foundation under one or more agreements.\r\n// The .NET Foundation licenses this file to you under the MIT license.\r\nimport { DefaultReconnectPolicy } from \"./DefaultReconnectPolicy\";\r\nimport { HttpConnection } from \"./HttpConnection\";\r\nimport { HubConnection } from \"./HubConnection\";\r\nimport { LogLevel } from \"./ILogger\";\r\nimport { JsonHubProtocol } from \"./JsonHubProtocol\";\r\nimport { NullLogger } from \"./Loggers\";\r\nimport { Arg, ConsoleLogger } from \"./Utils\";\r\nconst LogLevelNameMapping = {\r\n trace: LogLevel.Trace,\r\n debug: LogLevel.Debug,\r\n info: LogLevel.Information,\r\n information: LogLevel.Information,\r\n warn: LogLevel.Warning,\r\n warning: LogLevel.Warning,\r\n error: LogLevel.Error,\r\n critical: LogLevel.Critical,\r\n none: LogLevel.None,\r\n};\r\nfunction parseLogLevel(name) {\r\n // Case-insensitive matching via lower-casing\r\n // Yes, I know case-folding is a complicated problem in Unicode, but we only support\r\n // the ASCII strings defined in LogLevelNameMapping anyway, so it's fine -anurse.\r\n const mapping = LogLevelNameMapping[name.toLowerCase()];\r\n if (typeof mapping !== \"undefined\") {\r\n return mapping;\r\n }\r\n else {\r\n throw new Error(`Unknown log level: ${name}`);\r\n }\r\n}\r\n/** A builder for configuring {@link @microsoft/signalr.HubConnection} instances. */\r\nexport class HubConnectionBuilder {\r\n configureLogging(logging) {\r\n Arg.isRequired(logging, \"logging\");\r\n if (isLogger(logging)) {\r\n this.logger = logging;\r\n }\r\n else if (typeof logging === \"string\") {\r\n const logLevel = parseLogLevel(logging);\r\n this.logger = new ConsoleLogger(logLevel);\r\n }\r\n else {\r\n this.logger = new ConsoleLogger(logging);\r\n }\r\n return this;\r\n }\r\n withUrl(url, transportTypeOrOptions) {\r\n Arg.isRequired(url, \"url\");\r\n Arg.isNotEmpty(url, \"url\");\r\n this.url = url;\r\n // Flow-typing knows where it's at. Since HttpTransportType is a number and IHttpConnectionOptions is guaranteed\r\n // to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called.\r\n if (typeof transportTypeOrOptions === \"object\") {\r\n this.httpConnectionOptions = { ...this.httpConnectionOptions, ...transportTypeOrOptions };\r\n }\r\n else {\r\n this.httpConnectionOptions = {\r\n ...this.httpConnectionOptions,\r\n transport: transportTypeOrOptions,\r\n };\r\n }\r\n return this;\r\n }\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to use the specified Hub Protocol.\r\n *\r\n * @param {IHubProtocol} protocol The {@link @microsoft/signalr.IHubProtocol} implementation to use.\r\n */\r\n withHubProtocol(protocol) {\r\n Arg.isRequired(protocol, \"protocol\");\r\n this.protocol = protocol;\r\n return this;\r\n }\r\n withAutomaticReconnect(retryDelaysOrReconnectPolicy) {\r\n if (this.reconnectPolicy) {\r\n throw new Error(\"A reconnectPolicy has already been set.\");\r\n }\r\n if (!retryDelaysOrReconnectPolicy) {\r\n this.reconnectPolicy = new DefaultReconnectPolicy();\r\n }\r\n else if (Array.isArray(retryDelaysOrReconnectPolicy)) {\r\n this.reconnectPolicy = new DefaultReconnectPolicy(retryDelaysOrReconnectPolicy);\r\n }\r\n else {\r\n this.reconnectPolicy = retryDelaysOrReconnectPolicy;\r\n }\r\n return this;\r\n }\r\n /** Configures {@link @microsoft/signalr.HubConnection.serverTimeoutInMilliseconds} for the {@link @microsoft/signalr.HubConnection}.\r\n *\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n withServerTimeout(milliseconds) {\r\n Arg.isRequired(milliseconds, \"milliseconds\");\r\n this._serverTimeoutInMilliseconds = milliseconds;\r\n return this;\r\n }\r\n /** Configures {@link @microsoft/signalr.HubConnection.keepAliveIntervalInMilliseconds} for the {@link @microsoft/signalr.HubConnection}.\r\n *\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n withKeepAliveInterval(milliseconds) {\r\n Arg.isRequired(milliseconds, \"milliseconds\");\r\n this._keepAliveIntervalInMilliseconds = milliseconds;\r\n return this;\r\n }\r\n /** Enables and configures options for the Stateful Reconnect feature.\r\n *\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n withStatefulReconnect(options) {\r\n if (this.httpConnectionOptions === undefined) {\r\n this.httpConnectionOptions = {};\r\n }\r\n this.httpConnectionOptions._useStatefulReconnect = true;\r\n this._statefulReconnectBufferSize = options === null || options === void 0 ? void 0 : options.bufferSize;\r\n return this;\r\n }\r\n /** Creates a {@link @microsoft/signalr.HubConnection} from the configuration options specified in this builder.\r\n *\r\n * @returns {HubConnection} The configured {@link @microsoft/signalr.HubConnection}.\r\n */\r\n build() {\r\n // If httpConnectionOptions has a logger, use it. Otherwise, override it with the one\r\n // provided to configureLogger\r\n const httpConnectionOptions = this.httpConnectionOptions || {};\r\n // If it's 'null', the user **explicitly** asked for null, don't mess with it.\r\n if (httpConnectionOptions.logger === undefined) {\r\n // If our logger is undefined or null, that's OK, the HttpConnection constructor will handle it.\r\n httpConnectionOptions.logger = this.logger;\r\n }\r\n // Now create the connection\r\n if (!this.url) {\r\n throw new Error(\"The 'HubConnectionBuilder.withUrl' method must be called before building the connection.\");\r\n }\r\n const connection = new HttpConnection(this.url, httpConnectionOptions);\r\n return HubConnection.create(connection, this.logger || NullLogger.instance, this.protocol || new JsonHubProtocol(), this.reconnectPolicy, this._serverTimeoutInMilliseconds, this._keepAliveIntervalInMilliseconds, this._statefulReconnectBufferSize);\r\n }\r\n}\r\nfunction isLogger(logger) {\r\n return logger.log !== undefined;\r\n}\r\n//# sourceMappingURL=HubConnectionBuilder.js.map","import { HubConnectionBuilder, LogLevel, Subject } from \"@microsoft/signalr\";\r\nimport { reactive } from 'vue'\r\nimport util from \"@core/services/util\";\r\nimport LogRocket from \"logrocket\";\r\n\r\n\r\nexport default {\r\n install(app) {\r\n const connection = reactive(new HubConnectionBuilder()\r\n .withUrl(\"/MeetingRoomHub\", { withCredentials: false })\r\n //.withAutomaticReconnect([0, 2000, 10000, 30000]) yields the default behavior\r\n .withAutomaticReconnect([0, 3000, 8000, 10000, 12000])\r\n .configureLogging(LogLevel.Debug)\r\n .build()\r\n );\r\n // use new Vue instance as an event bus\r\n const meetingHub = reactive({\r\n manuallyClosed: false,\r\n connected: false,\r\n code: '',\r\n myConnectionId: null,\r\n connection: connection,\r\n volumeLevel: 0.5,\r\n isSendCustomerHtmlEnabled: false,\r\n isRetryingToSendMsg: false,\r\n });\r\n\r\n app.config.globalProperties.EventBus.emit('MeetingHubConnectionChanged', meetingHub.connected);\r\n // every component will use this.$meetingHub to access the event bus\r\n app.config.globalProperties.$meetingHub = reactive(meetingHub);\r\n app.provide('$meetingHub', app.config.globalProperties.$meetingHub);\r\n // Forward server side SignalR events through $meetingHub, where components will listen to them\r\n\r\n connection.onreconnected(connectionId => {\r\n console.log(`Connection reestablished. Connected with connectionId \"${connectionId}\".`);\r\n meetingHub.myConnectionId = connectionId;\r\n app.config.globalProperties.MeetingHubBus.emit('reconnectedMeetingHub');\r\n\r\n });\r\n\r\n connection.onreconnecting(error => {\r\n console.log('%cRECONNECTING', 'padding: 12px; background: orange;')\r\n console.log(`Connection lost due to error \"${error}\". Reconnecting.`);\r\n app.config.globalProperties.MeetingHubBus.emit('reconnectingMeetingHub');\r\n });\r\n\r\n connection.onclose(() => {\r\n console.log(\"****** Connection has been closed ******\");\r\n meetingHub.connected = false;\r\n\r\n if (app.config.globalProperties.meetingHelper.inStore && app.config.globalProperties.meetingHelper.myRole == \"fimanager\") {\r\n app.config.globalProperties.meetingHelper.currentMeetingUsers = []\r\n }\r\n\r\n app.config.globalProperties.EventBus.emit('BroadcastReconnect');\r\n });\r\n\r\n connection.on(\"ConnectedToSignalR\", myConnectionId => {\r\n console.log(\r\n \"ConnectedToSignalR. My connectionId is: \" + myConnectionId,\r\n \"meetingHub.code\",\r\n meetingHub.code\r\n );\r\n meetingHub.myConnectionId = myConnectionId;\r\n });\r\n connection.on(\"DisconnectedFromSignalR\", connectionId => {\r\n console.log(\"DisconnectedFromSignalR. The disconnected users connectionid is: \" + connectionId);\r\n\r\n //I GOT DISCONNECTED\r\n if (meetingHub.myConnectionId == connectionId) {\r\n meetingHub.myConnectionId = null;\r\n }\r\n\r\n //EMIT THAT SOMEONE GOT DISCONNECTED (me or someone else)\r\n app.config.globalProperties.MeetingHubBus.emit('disconnectedFromSignalR', connectionId);\r\n\r\n\r\n });\r\n\r\n //THIS SHOULD ONLY GET CALLED ON THE CUSTOMER APP\r\n //THIS TELLS ALL CUSTOMER PARTICIPANTS TO DISCONNECT\r\n connection.on('EndMeeting', async () => {\r\n console.log('Meeting Has Ended. Stopping meetingHub connection.');\r\n app.config.globalProperties.MeetingHubBus.emit('endMeeting');\r\n await meetingHub.stopConnection(\"FI Manager has ended meeting for all participants\");\r\n });\r\n\r\n //General Actions Watchers\r\n\r\n connection.on('MeetingRoomJoinSuccess', (role, isInStoreConnection, meetingRoomCode, currentMeetingDetails) => { app.config.globalProperties.MeetingHubBus.emit('meetingRoomJoinSuccess', {role, isInStoreConnection, meetingRoomCode, currentMeetingDetails}) })\r\n // connection.on('MeetingRoomJoinError', () => { app.config.globalProperties.MeetingHubBus.emit('meetingRoomJoinSuccess', null) })\r\n connection.on('RegisterCustomerViewed', (viewedType, viewedDateTime, videosSeen) => { app.config.globalProperties.MeetingHubBus.emit('registerCustomerViewed', {viewedType, viewedDateTime, videosSeen})})\r\n connection.on('UpdatePreferredCoverage', (term) => { app.config.globalProperties.MeetingHubBus.emit('updatePreferredCoverage', term) })\r\n connection.on('UpdateLoanDaysToPayment', (days) => { app.config.globalProperties.MeetingHubBus.emit('updateLoanDaysToPayment', days) })\r\n connection.on('UpdateDraftLoanTerms', (term, sellRate, buyRate) => { app.config.globalProperties.MeetingHubBus.emit('updateDraftLoanTerms', {term, sellRate, buyRate}) })\r\n connection.on('CustomerDisconnected', (updatedMeetingParticipants) => { app.config.globalProperties.MeetingHubBus.emit('customerDisconnected', updatedMeetingParticipants) })\r\n // connection.on('CheckIfMeetingStillActiveResponse', (isMeetingStillActive) => { app.config.globalProperties.MeetingHubBus.emit('CheckIfMeetingStillActiveResponse', isMeetingStillActive) })\r\n connection.on('ReceiveDocument', (doc) => { app.config.globalProperties.MeetingHubBus.emit('receiveDocument', doc) })\r\n connection.on('MoveToSecureRoom', (newSecureRoom) => { app.config.globalProperties.MeetingHubBus.emit('moveToSecureRoom', {newSecureRoom}) })\r\n connection.on('MeetingRoomError', (errorMessage) => {app.config.globalProperties.MeetingHubBus.emit('meetingRoomError', errorMessage) })\r\n\r\n //Customer Actions Watchers\r\n connection.on('TriggerCustomerAction', (action, fimenuStringified) => { app.config.globalProperties.MeetingHubBus.emit('triggerCustomerAction', {action, fimenuStringified}) })\r\n connection.on('CheckIfCustomerShouldGoToPaymentSheet', (action, fimenu) => { app.config.globalProperties.MeetingHubBus.emit('checkIfCustomerShouldGoToPaymentSheet') })\r\n connection.on('LanguageChanged', (language) => { app.config.globalProperties.MeetingHubBus.emit('languageChanged', language) })\r\n\r\n\r\n //Fimanager Actions Watchers\r\n connection.on('TriggerFIManagerAction', (action, fimenu) => { app.config.globalProperties.MeetingHubBus.emit('triggerFIManagerAction', {action, fimenu}) })\r\n connection.on('TriggerSaveFIMenu', () => { app.config.globalProperties.MeetingHubBus.emit(\"triggerSaveFIMenu\"); })\r\n connection.on('UpdatePaperworkToSigned', (document) => {\r\n app.config.globalProperties.MeetingHubBus.emit('updatePaperworkToSigned', document)\r\n })\r\n connection.on('CheckFinishedPaperwork', () => { app.config.globalProperties.MeetingHubBus.emit(\"checkFinishedPaperwork\"); })\r\n connection.on('ReceivingHTMLFromCustomer', (customerScreenData) => { app.config.globalProperties.MeetingHubBus.emit('receivingHTMLFromCustomer', customerScreenData) })\r\n connection.on('ReceiveScrollData', (metadata) => {\r\n app.config.globalProperties.MeetingHubBus.emit('receiveScrollData', metadata);\r\n })\r\n connection.on('PlayVideoFromCustomer', (time) => { app.config.globalProperties.MeetingHubBus.emit('playVideoFromCustomer', time) })\r\n connection.on('PauseVideoFromCustomer', () => { app.config.globalProperties.MeetingHubBus.emit('pauseVideoFromCustomer') })\r\n connection.on('ChangeCustomerVideoVolume', (volumeLevel) => { app.config.globalProperties.MeetingHubBus.emit('changeCustomerVideoVolume', volumeLevel) })\r\n connection.on('ShowLastFrameVideo', () => { app.config.globalProperties.MeetingHubBus.emit('showLastFrameVideo') })\r\n connection.on('DownloadDocument', (path) => { app.config.globalProperties.MeetingHubBus.emit('downloadDocument', path) })\r\n connection.on('UpdateSignatureAndInitials', (signatureInfo) => { app.config.globalProperties.MeetingHubBus.emit(\"updateSignatureAndInitials\", signatureInfo); })\r\n connection.on('UpdateDocumentIsOpen', (pdfIndex, isOpen) => { app.config.globalProperties.MeetingHubBus.emit('updateDocumentIsOpen', {pdfIndex, isOpen}) })\r\n connection.on('UpdateMeetingHubParticipants', (updatedMeetingParticipants) => { app.config.globalProperties.MeetingHubBus.emit('updateMeetingHubParticipants', updatedMeetingParticipants) })\r\n connection.on('UserRequestingToPresent', (userId) => { app.config.globalProperties.MeetingHubBus.emit('userRequestingToPresent', userId) })\r\n\r\n connection.on('SetAccessKey', (accessKey) => { meetingHub.accessKey = accessKey })\r\n connection.on('SetUserId', (id) => { meetingHub.userId = id })\r\n\r\n connection.on('UserJoinedVideoChatRoom', (userId) => { app.config.globalProperties.MeetingHubBus.emit('userJoinedVideoChatRoom', userId) })\r\n connection.on('GetInitiatorSignal', (signal) => { app.config.globalProperties.MeetingHubBus.emit('getInitiatorSignal', signal) })\r\n connection.on('GetNonInitiatorSignal', (signal) => { app.config.globalProperties.MeetingHubBus.emit('getNonInitiatorSignal', signal) })\r\n\r\n //CashBash\r\n connection.on('CashBashReadyToStartAdmin', () => { app.config.globalProperties.MeetingHubBus.emit('cashBashReadyToStartAdmin') })\r\n connection.on('CashBashReadyToStartGame', (playerConnectedCode) => { app.config.globalProperties.MeetingHubBus.emit('cashBashReadyToStartGame', playerConnectedCode) })\r\n connection.on('CashBashGameConnected', () => { app.config.globalProperties.MeetingHubBus.emit('cashBashGameConnected') })\r\n\r\n connection.on('CashBashAlreadyReadyGame', () => { app.config.globalProperties.MeetingHubBus.emit('cashBashAlreadyReadyGame') })\r\n\r\n connection.on('CashBashAdminCloseConnection', () => { app.config.globalProperties.MeetingHubBus.emit('cashBashAdminCloseConnection') })\r\n connection.on('CashBashGameCloseConnection', (playerConnectedCode) => { app.config.globalProperties.MeetingHubBus.emit('cashBashGameCloseConnection', playerConnectedCode) })\r\n\r\n connection.on('CashBashReadySelectPlayer', (playerId) => { app.config.globalProperties.MeetingHubBus.emit('cashBashReadySelectPlayer', playerId) })\r\n connection.on('CashBashReadySelectCard', (cardObject) => { app.config.globalProperties.MeetingHubBus.emit('cashBashReadySelectCard', cardObject) })\r\n connection.on('CashBashReadySelectPage', (page) => { app.config.globalProperties.MeetingHubBus.emit('cashBashReadySelectPage', page) })\r\n connection.on('CashBashReadySelectCardOK', (cardObject) => { app.config.globalProperties.MeetingHubBus.emit('cashBashReadySelectCardOK', cardObject) })\r\n connection.on('CashBashUpdateActivePlayer', (JSONStringPlayer) => { app.config.globalProperties.MeetingHubBus.emit('cashBashUpdateActivePlayer', JSONStringPlayer) })\r\n connection.on('CashBashUpdateBashInfo', (JSONStringBash) => { app.config.globalProperties.MeetingHubBus.emit('cashBashUpdateBashInfo', JSONStringBash) })\r\n\r\n\r\n connection.on('SendBackBuffer', (data) => { app.config.globalProperties.MeetingHubBus.emit('sendBackBuffer', data) })\r\n connection.on('StreamVideoData', (data) => { app.config.globalProperties.MeetingHubBus.emit('streamVideoData', data) })\r\n\r\n //class Variables\r\n meetingHub.subject = new Subject();\r\n meetingHub.accessKey = null;\r\n meetingHub.userId = null; // We're actually using connectionId; not userIdentifier.\r\n\r\n // Other Functions\r\n meetingHub.accessAllowed = pageThis$router => {\r\n if (!meetingHub.connected) {\r\n pageThis$router.push(\"/meetingroom/inStoreConnection\");\r\n }\r\n };\r\n\r\n meetingHub.generateLobbyCode = () => {\r\n let codes = [];\r\n for (var i = 0; i < 6; i++) {\r\n let number = parseInt(Math.random() * 10);\r\n if (i == 0 && number == 0) {\r\n codes.push(1);\r\n } else {\r\n codes.push(parseInt(Math.random() * 10));\r\n }\r\n }\r\n return codes.join(\"\");\r\n };\r\n\r\n meetingHub.decodeMeetingCode = code => {\r\n let dealNumber = \"\";\r\n let storeCode = \"\";\r\n code.split(\"\").forEach((c, index) => {\r\n if (index % 2) {\r\n //this will trigger if odd\r\n storeCode += c;\r\n } else {\r\n dealNumber += c;\r\n }\r\n });\r\n let dif = parseInt(dealNumber) % 10;\r\n dealNumber = parseInt(dealNumber / 10);\r\n storeCode = storeCode.substring(0, storeCode.length - dif);\r\n return dealNumber + \"-\" + storeCode;\r\n };\r\n meetingHub.encodeMeetingCode = (dealNumber, storeCode) => {\r\n let dif = dealNumber.length - storeCode.length;\r\n let output = \"\";\r\n let tempStoreCode = storeCode.split(\"\");\r\n dealNumber.split(\"\").forEach((c, index) => {\r\n output +=\r\n c +\r\n (tempStoreCode[index]\r\n ? tempStoreCode[index]\r\n : String.fromCharCode(Math.floor(Math.random() * 26) + 97).toUpperCase());\r\n });\r\n return (output + dif).toUpperCase();\r\n };\r\n\r\n let startedPromise = null;\r\n meetingHub.connect = () => {\r\n //IF I AM CONNECTED ALREADY, DO NOTHING\r\n if (!meetingHub.connected && connection._connectionState === \"Disconnected\") {\r\n console.log(\"INIT HUB CONNECTION\");\r\n startedPromise = connection\r\n .start()\r\n .then(() => {\r\n app.config.globalProperties.$meetingHub.connected = true;\r\n })\r\n .catch(err => {\r\n console.error(\"Failed to connect with hub\", err);\r\n return new Promise((resolve, reject) =>\r\n setTimeout(() => meetingHub.connect().then(resolve).catch(reject), 5000)\r\n );\r\n });\r\n }\r\n return startedPromise;\r\n };\r\n\r\n meetingHub.startConnection = code => {\r\n console.log(\"*** meetingHub - startConnection\", meetingHub.code, code);\r\n console.log(\"*** meetingHub - meetingHub.connected\", meetingHub.connected);\r\n console.log(\"!!!! connection._connectionState\", connection._connectionState);\r\n\r\n meetingHub.code = code;\r\n return meetingHub.connect();\r\n };\r\n\r\n meetingHub.stopConnection = async message => {\r\n meetingHub.manuallyClosed = true;\r\n console.log(\"disconnected. Reason:\", message);\r\n console.log(\"*** meetingHub - stopConnection\", meetingHub.code);\r\n if (meetingHub.connected && connection._connectionState !== \"Disconnected\") {\r\n return await connection\r\n .stop()\r\n .then(() => {\r\n meetingHub.connected = false;\r\n meetingHub.manuallyClosed = false;\r\n meetingHub.code = \"\";\r\n meetingHub.myConnectionId = \"\";\r\n })\r\n .catch(err => {\r\n console.log(err);\r\n });\r\n }\r\n };\r\n\r\n meetingHub.fimanagerStopConnection = async message => {\r\n meetingHub.manuallyClosed = true;\r\n console.log(\"disconnected. Reason:\", message);\r\n console.log(\"*** meetingHub - stopConnection\", meetingHub.code);\r\n if (meetingHub.connected && connection._connectionState !== \"Disconnected\") {\r\n return await connection\r\n .stop()\r\n .then(() => {\r\n meetingHub.connected = false;\r\n meetingHub.manuallyClosed = false;\r\n meetingHub.code = \"\";\r\n meetingHub.myConnectionId = \"\";\r\n })\r\n .catch(err => {\r\n console.log(err);\r\n });\r\n }\r\n };\r\n\r\n // General Invoke Functions\r\n meetingHub.sendScrollEvent = scrollData => {\r\n util.debounce(meetingHub.sendScrollEventDebounced, 100, scrollData);\r\n };\r\n\r\n meetingHub.sendScrollEventDebounced = scrollData => {\r\n console.log(\"SENDSCROLLEVENTDEBOUNCED\", meetingHub.code, scrollData);\r\n return startedPromise\r\n .then(() => connection.invoke('SendScrollEvent', meetingHub.code, scrollData))\r\n .catch((err) => {\r\n console.error(err)\r\n })\r\n }\r\n\r\n meetingHub.joinMeetingRoom = (\r\n role,\r\n isInStoreConnection = true,\r\n fimenuDealId = null,\r\n firstName = null,\r\n lastName = null,\r\n fullName = null,\r\n ) => {\r\n console.log(\"joining \", meetingHub.code, \" role: \", role, \" fimenuDealId: \", fimenuDealId);\r\n console.log(\"meetingHub.code :\", meetingHub.code);\r\n return startedPromise\r\n .then(() =>\r\n connection.invoke(\r\n \"JoinMeetingRoom\",\r\n meetingHub.code,\r\n role,\r\n isInStoreConnection,\r\n fimenuDealId,\r\n firstName,\r\n lastName,\r\n fullName,\r\n ),\r\n )\r\n .catch(error => console.error(error));\r\n };\r\n\r\n meetingHub.allowUserIntoMeeting = meetingUser => {\r\n console.log(\"allowUserIntoMeeting \", meetingUser);\r\n return startedPromise\r\n .then(() => connection.invoke(\"AllowUserIntoMeeting\", meetingHub.code, meetingUser))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.inStorePreConnection = (role, newSecureRoom) => {\r\n console.log(\"*** meetingHub - inStorePreConnection - \", role, meetingHub.code);\r\n console.log(\"*** meetingHub - meetingHub.connected\", meetingHub.connected);\r\n console.log(\"*** meetingHub - newSecureRoom\", newSecureRoom);\r\n return startedPromise\r\n .then(() => connection.invoke(\"InStorePreConnection\", meetingHub.code, role, newSecureRoom))\r\n .catch(console.error);\r\n };\r\n meetingHub.leavePreConnectionRoom = (newSecureRoom) => {\r\n console.log(\"*** meetingHub - leavePreConnectionRoom\");\r\n console.log(\"newSecureRoom => \", newSecureRoom, \", MeetingHubCode => \", meetingHub.code);\r\n let oldCode = meetingHub.code;\r\n console.log('oldCode: ', typeof oldCode);\r\n\r\n meetingHub.code = newSecureRoom;\r\n console.log('meetingHub.code: ', meetingHub.code);\r\n return startedPromise\r\n .then(() => connection.invoke(\"LeavePreConnectionRoom\", oldCode))\r\n .catch(console.error);\r\n };\r\n\r\n //FIManager Invoke Functions\r\n meetingHub.sendActionToCustomer = (customerAction, fimenu) => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendActionToCustomer\", meetingHub.code, customerAction, fimenu))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.saveFIMenu = () => {\r\n return startedPromise\r\n .then(() => connection.invoke('SaveFIMenu', meetingHub.code))\r\n .catch(console.error)\r\n }\r\n\r\n meetingHub.openPaymentSheet = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"OpenPaymentSheet\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.openPaperworkScreen = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"OpenPaperworkScreen\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.changeFimenuLanguage = language => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"ChangeFimenuLanguage\", meetingHub.code, language))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.fimanagerAlreadyConnected = fimenu => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"FIManagerAlreadyConnected\", meetingHub.code, fimenu))\r\n .catch(console.error);\r\n };\r\n meetingHub.sendDownloadedDocument = doc => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendDownloadedDocument\", meetingHub.code, doc))\r\n .catch(err => {\r\n console.error(err);\r\n console.log(\"No doc data received\");\r\n });\r\n };\r\n meetingHub.disconnectParticipant = (userId, shouldMeetingEnd = false) => {\r\n console.log(\"DisconnectParticipant\", meetingHub.code, userId);\r\n return startedPromise\r\n .then(() => connection.invoke(\"DisconnectParticipant\", meetingHub.code, userId, shouldMeetingEnd))\r\n .catch(console.error);\r\n };\r\n meetingHub.reconnectParticipant = (\r\n role,\r\n isInStoreConnection = true,\r\n fimenuDealId = null,\r\n firstName = null,\r\n lastName = null\r\n ) => {\r\n console.log(\"reconnectParticipant\", meetingHub.code, role, isInStoreConnection, fimenuDealId, firstName, lastName);\r\n return startedPromise\r\n .then(() =>\r\n connection.invoke(\r\n \"ReconnectParticipant\",\r\n meetingHub.code,\r\n role,\r\n isInStoreConnection,\r\n fimenuDealId,\r\n firstName,\r\n lastName\r\n )\r\n )\r\n .catch(console.error);\r\n };\r\n meetingHub.sendParticipantToLobby = (userId, shouldMeetingEnd = null) => {\r\n console.log(\"SendParticipantToLobby\", meetingHub.code, userId);\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendParticipantToLobby\", meetingHub.code, userId, shouldMeetingEnd))\r\n .catch(console.error);\r\n };\r\n meetingHub.adjustCustomerVideoVolume = volumeLevel => {\r\n console.log(\"adjustCustomerVideoVolume\", meetingHub.code, volumeLevel);\r\n return startedPromise\r\n .then(() => connection.invoke(\"AdjustCustomerVideoVolume\", meetingHub.code, volumeLevel))\r\n .catch(console.error);\r\n };\r\n\r\n //Customer Invoke Functions\r\n meetingHub.customerAlreadyConnected = role => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"customerAlreadyConnected\", meetingHub.code, role))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.saveCustomerViewed = (type, moment, videoId) => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SaveCustomerViewed\", meetingHub.code, type, moment, videoId))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.setPreferredCoverage = term => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SetPreferredCoverage\", meetingHub.code, term))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.sendCustomerVideoDataToSave = videoData => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendCustomerVideoDataToSave\", meetingHub.code, videoData))\r\n .catch(console.error);\r\n };\r\n meetingHub.shouldCustomerGoToPaymentSheet = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"ShouldCustomerGoToPaymentSheet\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n meetingHub.setLoanDaysToPayment = days => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SetLoanDaysToPayment\", meetingHub.code, days))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.setDraftLoanTerms = (term, sellRate, buyRate) => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SetDraftLoanTerms\", meetingHub.code, term, sellRate, buyRate))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.saveCustomerFImenu = fimenu => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SaveCustomerFImenu\", meetingHub.code, fimenu))\r\n .catch(console.error);\r\n };\r\n\r\n async function resendMessageHandler(callback, time, retries = 3) {\r\n console.log('resendingMessage retry attempt: ', retries);\r\n if (retries <= 0) {\r\n console.warn('Retry limit reached');\r\n meetingHub.isRetryingToSendMsg = false;\r\n return;\r\n }\r\n \r\n let timeout = null;\r\n \r\n const waitForRetry = () => new Promise(resolve => {\r\n timeout = setTimeout(resolve, time);\r\n });\r\n \r\n try {\r\n await waitForRetry();\r\n const success = await callback(); // Expect callback to return true/false\r\n if (success) {\r\n console.log(\"Message sent successfully, exiting retries.\");\r\n return; // Exit retries on success\r\n }\r\n } finally {\r\n clearTimeout(timeout);\r\n }\r\n \r\n // Exponential backoff\r\n // const nextDelay = time * 2;\r\n const nextDelay = time;\r\n\r\n console.log(`Retrying in ${nextDelay}ms...`);\r\n \r\n // Update retries by decrementing its value\r\n await resendMessageHandler(callback, nextDelay, retries - 1); // Reduce retries count\r\n }\r\n\r\n meetingHub.paperworkSigned = async (pdfIndex, document, signer = null) => {\r\n const docInfo = {\r\n overlays: document.overlays,\r\n status: document.status,\r\n description: document.description,\r\n };\r\n \r\n console.log(\"Attempt to invoke.\", \"pdfIndex:\", pdfIndex, \"Document:\", docInfo, \"Signer:\", signer, \"MeetinghubCode:\", meetingHub.code);\r\n \r\n try {\r\n await startedPromise;\r\n await connection.invoke(\"PaperworkSigned\", {\r\n ...docInfo,\r\n meetingRoomCode: meetingHub.code,\r\n pdfIndex,\r\n signer,\r\n });\r\n return true;\r\n } catch (err) {\r\n LogRocket.track('Paperwork Signed Error');\r\n console.error('PAPER WORK SIGNED ERROR doc:', document.description, err);\r\n \r\n if (!meetingHub.isRetryingToSendMsg) {\r\n meetingHub.isRetryingToSendMsg = true;\r\n app.config.globalProperties.MeetingHubBus.emit('openResendMessageModal');\r\n // Await the first call to ensure retries are handled sequentially\r\n await resendMessageHandler(async() => await meetingHub.paperworkSigned(pdfIndex, document, signer), 2000, 1000);\r\n meetingHub.isRetryingToSendMsg = false;\r\n return false;\r\n } else {\r\n console.log('Retry already in progress, skipping redundant call.');\r\n }\r\n }\r\n };\r\n\r\n\r\n meetingHub.paperworkFinished = () => { \r\n return startedPromise\r\n .then(() => connection.invoke(\"PaperworkFinished\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n meetingHub.requestMissingSignedDocuments = async(missingPdfList) => {\r\n await connection.invoke(\"RequestMissingSignedDocuments\", meetingHub.code, missingPdfList);\r\n }\r\n meetingHub.customerDisconnect = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"CustomerDisconnect\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n // meetingHub.checkIfMeetingStillActive = (code) => {\r\n // return startedPromise\r\n // .then(() => connection.invoke('CheckIfMeetingStillActive', code))\r\n // .catch(console.error)\r\n // }\r\n meetingHub.sendHTMLFromCustomer = customerScreenData => {\r\n customerScreenData.meetingRoomCode = meetingHub.code;\r\n\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendHTMLFromCustomer\", customerScreenData))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.requestToBePresenter = userId => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"RequestToBePresenter\", meetingHub.code, userId))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.grantRequestToBePresenter = userId => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"GrantRequestToBePresenter\", meetingHub.code, userId))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.updateMutedStatus = (userId, isMuted) => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"UpdateMutedStatus\", meetingHub.code, userId, isMuted))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.sendPlayVideoFromCustomer = time => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"sendPlayVideoFromCustomer\", meetingHub.code, time))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.sendPauseVideoFromCustomer = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendPauseVideoFromCustomer\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.sendShowLastFrameVideo = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendShowLastFrameVideo\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.requestDownloadDocument = path => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"RequestDownloadDocument\", meetingHub.code, path))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.sendClientSignatureInitials = (who, signature, initials, signatureId, initialsId) => {\r\n console.log(\r\n \"Attempt to invoke. \",\r\n \"who: \",\r\n who,\r\n \"signature: \",\r\n !!signature,\r\n \"initials: \",\r\n !!initials,\r\n \"MeetinghubCode: \",\r\n meetingHub.code\r\n );\r\n return startedPromise\r\n .then(() =>\r\n connection.invoke(\"SendClientSignatureInitials\", {\r\n meetingRoomCode: meetingHub.code,\r\n who,\r\n signature,\r\n initials,\r\n signatureId,\r\n initialsId,\r\n })\r\n )\r\n .catch(err => {\r\n console.error(err);\r\n })\r\n }\r\n\r\n meetingHub.sendDocumentIsOpen = (docIndex, isOpen) => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendDocumentIsOpen\", meetingHub.code, docIndex, isOpen))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.saveScreenRecordEndTime = endTime => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SaveScreenRecordEndTime\", meetingHub.code, endTime))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.saveLatestTimestamp = latestTimeStamp => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SaveLatestTimestamp\", meetingHub.code, latestTimeStamp))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.saveVideoChunk = videoData => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SaveVideoChunk\", meetingHub.code, videoData))\r\n .catch(console.error);\r\n };\r\n\r\n //Cash Bash\r\n meetingHub.adminCashBashReadyToStart = () => {\r\n return meetingHub\r\n .startConnection()\r\n .then(() => connection.invoke(\"AdminCashBashReadyToStart\"))\r\n .catch(console.error);\r\n };\r\n meetingHub.gameCashBashReadyToStart = playerConnectedCode => {\r\n return meetingHub\r\n .startConnection()\r\n .then(() => connection.invoke(\"GameCashBashReadyToStart\", playerConnectedCode))\r\n .catch(console.error);\r\n };\r\n meetingHub.gameCashBashLeave = playerConnectedCode => {\r\n return meetingHub\r\n .startConnection()\r\n .then(() => connection.invoke(\"GameCashBashLeave\", playerConnectedCode))\r\n .catch(console.error);\r\n };\r\n meetingHub.adminCashBashLeave = () => {\r\n return meetingHub\r\n .startConnection()\r\n .then(() => connection.invoke(\"AdminCashBashLeave\"))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.gameCashBashConnected = () => {\r\n return meetingHub\r\n .startConnection()\r\n .then(() => connection.invoke(\"GameCashBashConnected\"))\r\n .catch(console.error);\r\n };\r\n meetingHub.gameAlreadyReady = () => {\r\n return startedPromise.then(() => connection.invoke(\"GameAlreadyReady\")).catch(console.error);\r\n };\r\n meetingHub.adminSelectActivePlayer = playerId => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"AdminSelectActivePlayer\", playerId))\r\n .catch(console.error);\r\n };\r\n meetingHub.gameSelectCard = cardObject => {\r\n return startedPromise.then(() => connection.invoke(\"GameSelectCard\", cardObject)).catch(console.error);\r\n };\r\n meetingHub.gameChangePage = page => {\r\n return startedPromise.then(() => connection.invoke(\"GameChangePage\", page)).catch(console.error);\r\n };\r\n meetingHub.adminSelectCardOk = cardObject => {\r\n return startedPromise.then(() => connection.invoke(\"AdminSelectCardOk\", cardObject)).catch(console.error);\r\n };\r\n meetingHub.gameUpdateActivePlayerInfo = JSONStringPlayer => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"GameUpdateActivePlayerInfo\", JSONStringPlayer))\r\n .catch(console.error);\r\n };\r\n meetingHub.adminUpdateBashInfo = JSONStringBash => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"AdminUpdateBashInfo\", JSONStringBash))\r\n .catch(console.error);\r\n };\r\n\r\n //Stream Video Functions\r\n meetingHub.videoDataSendToServer = blob => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"VideoDataReceive\", meetingHub.code, blob))\r\n .catch(console.error);\r\n };\r\n\r\n // Video Chat Room\r\n meetingHub.joinVideoChatRoom = () => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"JoinVideoChatRoom\", meetingHub.code))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.sendingSignal = signal => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"SendingSignal\", meetingHub.code, signal))\r\n .catch(console.error);\r\n };\r\n meetingHub.requestDirectConnectionSignal = signal => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"RequestDirectConnectionSignal\", meetingHub.code, signal))\r\n .catch(console.error);\r\n };\r\n meetingHub.acceptedInitiatorSignal = signal => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"AcceptedInitiatorSignal\", meetingHub.code, signal))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.returningSignal = signal => {\r\n return startedPromise\r\n .then(() => connection.invoke(\"ReturningSignal\", meetingHub.code, signal))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.subscribeToGroupEvent = (eventName, groupId, callback) => {\r\n //ON EVENT BROADCAST, WE CALL THE callback METHOD\r\n connection.on(eventName, data => {\r\n if (data) callback(data);\r\n else callback();\r\n });\r\n\r\n return meetingHub\r\n .connect()\r\n .then(() => connection.invoke(\"JoinGroup\", groupId, eventName))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.unsubscribeToGroupEvent = (eventName) => {\r\n connection.off(eventName);\r\n };\r\n\r\n meetingHub.unsubscribeToGroupEvents = groupId => {\r\n return meetingHub\r\n .connect()\r\n .then(() => connection.invoke(\"LeaveGroup\", groupId))\r\n .catch(console.error);\r\n };\r\n\r\n meetingHub.broadcastGroupEvent = (eventName, groupId, message) => {\r\n return meetingHub\r\n .connect()\r\n .then(() => connection.invoke(\"BroadcastGroupEvent\", eventName, groupId, message))\r\n .catch(console.error);\r\n };\r\n },\r\n};\r\n","export default class MeetingInfo {\r\n\r\n constructor(init) {\r\n\r\n if (init) {\r\n this.id = init.id\r\n this.dealId = init.dealId;\r\n this.employeeId = init.employeeId;\r\n this.employeeCode = init.employeeCode;\r\n this.inStore = init.inStore;\r\n this.language = init.language;\r\n this.dealNumber = init.dealNumber;\r\n this.storeCode = init.storeCode;\r\n this.meetingCode = init.meetingCode;\r\n //this.verificationCode = MeetingHelper.createNumberCode(6);\r\n this.validAfter = init.validAfter;\r\n this.validUntil = init.validUntil;\r\n this.startedAt = init.startedAt;\r\n this.finishedAt = init.finishedAt;\r\n\r\n this.meetings = [];\r\n this.meetingLogs = [];\r\n } else {\r\n this.id = null;\r\n this.dealId = null;\r\n this.employeeId = null;\r\n this.employeeCode = null;\r\n this.inStore = null;\r\n this.language = null;\r\n this.dealNumber = null;\r\n this.storeCode = null;\r\n this.meetingCode = null;\r\n //this.verificationCode = MeetingHelper.createNumberCode(6);\r\n this.validAfter = null;\r\n this.validUntil = null;\r\n this.startedAt = null;\r\n this.finishedAt = null;\r\n\r\n this.meetings = [];\r\n this.meetingLogs = [];\r\n }\r\n\r\n }\r\n\r\n}","import { App, reactive } from \"vue\";\r\nimport { broadcastEmitEvent, broadcastUnsubscribeAllEvents } from \"@core/helpers/broadcast-helper\";\r\nimport ENUMS, { CUSTOMER_VIEWS } from \"@core/classes/Enums\";\r\nimport api from \"@core/services/api\";\r\nimport auth from \"@core/services/auth\";\r\nimport FIMenu from \"@core/classes/FIMenu\";\r\nimport FIMenuCustomerViewed from \"@core/classes/FIMenuCustomerViewed\";\r\nimport LogRocket from 'logrocket';\r\nimport MeetingInfo from \"@core/classes/MeetingInfo\";\r\nimport moment from \"moment\";\r\nimport util from \"@core/services/util\";\r\n\r\n// Create a Vue instance, so we can access meetingHubP\r\n// access meetingHub with globalProperties.$meetingHub\r\nexport default {\r\n install(app: App) {\r\n const { globalProperties } = app.config;\r\n\r\n function encodeMeetingCode(dealNumber: string, storeCode: string) {\r\n const dif = dealNumber.length - storeCode.length;\r\n let output = \"\";\r\n const tempStoreCode = storeCode.split(\"\");\r\n dealNumber.split(\"\").forEach((c, index) => {\r\n output +=\r\n c +\r\n (tempStoreCode[ index ]\r\n ? tempStoreCode[ index ]\r\n : String.fromCharCode(Math.floor(Math.random() * 26) + 97).toUpperCase());\r\n });\r\n return (output + dif).toUpperCase();\r\n }\r\n\r\n function decodeMeetingCode(code: string) {\r\n let dealNumber = \"\";\r\n let storeCode = \"\";\r\n code.split(\"\").forEach((c, index) => {\r\n if (index % 2) {\r\n //this will trigger if odd\r\n storeCode += c;\r\n } else {\r\n dealNumber += c;\r\n }\r\n });\r\n const dif = parseInt(dealNumber) % 10;\r\n const newDealNumber = dealNumber.slice(0, dealNumber.length - 1);\r\n storeCode = storeCode.substring(0, storeCode.length - dif);\r\n return newDealNumber + \"-\" + storeCode;\r\n }\r\n\r\n function initiateMeeting(dealNumber: string, storeCode: string) {\r\n meetingHelper.dealNumber = dealNumber;\r\n meetingHelper.storeCode = storeCode;\r\n\r\n // CREATE ENCODED MEETING ROOM CODE\r\n meetingHelper.meetingCodeEncoded = encodeMeetingCode(dealNumber, storeCode);\r\n\r\n // GET MEETINGS FROM DATABASE\r\n // api.meeting.getDealMeetings(storeCode, dealNumber).then((response) => {\r\n // // store previous meetings in helper until we create a meeting\r\n // meetingHelper.meetings = response.data.reverse()\r\n // }).catch((err) => {\r\n // console.log(err)\r\n // })\r\n\r\n // GET EMPLOYEE DATA\r\n const payload = auth.getTokenPayload();\r\n meetingHelper.employeeId = payload.id;\r\n meetingHelper.employeeCode = payload.EmployeeCode;\r\n }\r\n\r\n function createMeeting(dealNumber: string, storeCode: string, fimenu: FIMenu) {\r\n LogRocket.log(\"--------------- createMeeting -------------\", dealNumber, storeCode, fimenu);\r\n const start = moment();\r\n\r\n const meetingObject = {\r\n dealId: fimenu.id,\r\n employeeId: meetingHelper.employeeId,\r\n employeeCode: meetingHelper.employeeCode,\r\n inStore: meetingHelper.inStore,\r\n language: fimenu.language,\r\n dealNumber: dealNumber,\r\n storeCode: storeCode,\r\n meetingCode: decodeMeetingCode(meetingHelper.meetingCodeEncoded),\r\n //verificationCode: meetingHelper.createNumberCode(6),\r\n validAfter: start,\r\n validUntil: util.toMoment(start).add(20, \"seconds\"),\r\n };\r\n\r\n // Create a new meetingInfo object\r\n meetingHelper.meetingInfo = new MeetingInfo(meetingObject);\r\n\r\n // Assign previous meetings to our current meetingInfo object\r\n // meetingHelper.meetingInfo.meetings = meetingHelper.meetings;\r\n\r\n LogRocket.log(\"meetingInfo\", meetingHelper.meetingInfo);\r\n\r\n return api.meeting.createMeeting(meetingHelper.meetingInfo);\r\n }\r\n\r\n // async function customerGetMeetingByCode() {\r\n // console.log('!!! customerGetMeetingByCode', meetingHelper.meetingCodeEncoded);\r\n // try {\r\n // const response = await api.meeting.getMeetingByCode(decodeMeetingCode(meetingHelper.meetingCodeEncoded))\r\n\r\n // // Populate meetingHelper\r\n // meetingHelper.storeCode = response.data[0].storeCode;\r\n // meetingHelper.dealNumber = response.data[0].dealNumber;\r\n // meetingHelper.employeeId = response.data[0].employeeId;\r\n // meetingHelper.employeeCode = response.data[0].employeeCode;\r\n // meetingHelper.inStore = response.data[0].inStore;\r\n\r\n // // Populate meetingInfo\r\n // meetingHelper.meetingInfo = new MeetingInfo({\r\n // id: response.data[0].id,\r\n // dealId: response.data[0].dealId,\r\n // employeeId: response.data[0].employeeId,\r\n // employeeCode: response.data[0].employeeCode,\r\n // inStore: response.data[0].inStore,\r\n // language: response.data[0].language,\r\n // dealNumber: response.data[0].dealNumber,\r\n // storeCode: response.data[0].storeCode,\r\n // meetingCode: response.data[0].meetingCode,\r\n // //verificationCode: meetingHelper.createNumberCode(6),\r\n // validAfter: response.data[0].validAfter,\r\n // validUntil: response.data[0].validUntil,\r\n // startedAt: response.data[0].startedAt,\r\n // finishedAt: response.data[0].finishedAt,\r\n // meetingLogs: response.data[0].meetingLogs\r\n\r\n // });\r\n\r\n // } catch (e) {\r\n // console.log(\"error - customerGetMeetingByCode\", e);\r\n // }\r\n\r\n // }\r\n\r\n // async function checkIfMeetingStillActive() {\r\n // let decodedMeetingCode = meetingHelper.decodeMeetingCode(meetingHelper.meetingCodeEncoded)\r\n // console.log(\"checkIfMeetingStillActive\", decodedMeetingCode)\r\n // globalProperties.$meetingHub.startConnection(decodedMeetingCode);\r\n // await globalProperties.$meetingHub.checkIfMeetingStillActive(decodedMeetingCode);\r\n // }\r\n\r\n // function checkIfMeetingStillActiveResponse(isMeetingStillActive) {\r\n // console.log('-- MEETING HELPER >> isMeetingStillActive', isMeetingStillActive)\r\n // meetingHelper.isMeetingStillActive = isMeetingStillActive;\r\n // }\r\n\r\n async function startRemoteMeeting(fimenu: FIMenu) {\r\n LogRocket.log(`-------------- startRemoteMeeting ----------------`);\r\n\r\n meetingHelper.inStore = false;\r\n meetingHelper.myRole = \"fimanager\";\r\n\r\n const payload = auth.getTokenPayload();\r\n\r\n meetingHelper.fullName = util.toProperCase(payload.EmployeeName.split(\", \").reverse().join(\" \"));\r\n [ meetingHelper.firstName, meetingHelper.lastName ] = meetingHelper.fullName.split(\" \");\r\n\r\n meetingHelper.initiateMeeting(meetingHelper.dealNumber, meetingHelper.storeCode);\r\n\r\n //CONNECT\r\n if (meetingHelper.currentMeetingUsers.length < 1) {\r\n try {\r\n const response = await meetingHelper.createMeeting(meetingHelper.dealNumber, meetingHelper.storeCode, fimenu);\r\n meetingHelper.meetingInfo.id = response.data.id;\r\n meetingHelper.currentMeeting = response.data;\r\n meetingHelper.currentMeeting.startedAt = moment();\r\n\r\n await globalProperties.$meetingHub.startConnection(meetingHelper.dealNumber + \"-\" + meetingHelper.storeCode);\r\n\r\n globalProperties.$meetingHub.connected = true;\r\n\r\n globalProperties.$meetingHub.joinMeetingRoom(\r\n \"fimanager\",\r\n meetingHelper.inStore,\r\n fimenu.id,\r\n meetingHelper.firstName,\r\n meetingHelper.lastName,\r\n meetingHelper.fullName\r\n );\r\n\r\n // meetingHelper.setCurrentMeeting(response.data);\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns Boolean to see if you are currently connected to a meeting.\r\n */\r\n function meetingCurrentlyOpen() {\r\n return globalProperties.$meetingHub.connected;\r\n }\r\n\r\n async function allowUserIntoMeeting(fimenu: FIMenu, userToAllow: any) {\r\n // If we are not already in the meeting, join the meeting\r\n if (!globalProperties.$meetingHub.code) {\r\n await meetingHelper.startRemoteMeeting(fimenu);\r\n }\r\n globalProperties.$meetingHub.allowUserIntoMeeting(userToAllow);\r\n }\r\n\r\n // function setCurrentMeeting(meetingData) {\r\n // console.log('setCurrentMeeting', meetingData);\r\n // // meetingInfo was initialized in createMeeting, now we set the id that was provided by back-end as well as the meetingLogs\r\n // meetingHelper.meetingInfo.id = meetingData.id;\r\n // meetingHelper.meetingInfo.meetingLogs = meetingData.meetingLogs;\r\n\r\n // // Move current meeting to beginning of meetings in meetingInfo\r\n // meetingHelper.meetingInfo.meetings.unshift(meetingData);\r\n\r\n // meetingHelper.currentMeeting = meetingHelper.meetingInfo.meetings[0];\r\n\r\n // }\r\n\r\n async function sendLinkToMeetingRoomParticipant(meetingInvitation: any, fimenu: FIMenu) {\r\n const failMessage = \"Failed to send message\";\r\n\r\n meetingHelper.meetingCodeEncoded = meetingHelper.encodeMeetingCode(meetingHelper.dealNumber, meetingHelper.storeCode);\r\n\r\n const sendMethod = meetingInvitation.sendEmailOrText;\r\n const who: keyof FIMenu = meetingInvitation.who;\r\n\r\n const participantEmail = fimenu[ who ].email;\r\n const participantCell = fimenu[ who ].cell;\r\n\r\n let participantFirstName = '';\r\n let participantLastName = '';\r\n const participantFullName = util.toProperCase(fimenu[ who ].fullName);\r\n\r\n const dealershipName = fimenu.store.storeName;\r\n const fimanagerName = util.toProperCase(fimenu.fiManagerName.split(\", \").reverse().join(\" \"));\r\n\r\n if (!fimenu[ who ].isEntity) {\r\n // If customer is not a business, set the first and last name\r\n participantFirstName = util.toProperCase(fimenu[ who ].firstName);\r\n participantLastName = util.toProperCase(fimenu[ who ].lastName);\r\n }\r\n\r\n const meetingLinkInfo = {\r\n meetingCode: meetingHelper.meetingCodeEncoded,\r\n participant: meetingInvitation.who,\r\n firstName: participantFirstName,\r\n lastName: participantLastName,\r\n fullName: participantFullName\r\n };\r\n\r\n console.log(\"meetingLinkInfo\", meetingLinkInfo);\r\n const encodedLinkInfo = util.encryptJSONText(JSON.stringify(meetingLinkInfo));\r\n\r\n LogRocket.log(\"encodedLinkInfo \", encodedLinkInfo);\r\n\r\n let sendEmailLinkRequest = null;\r\n let sendTextMsgLinkRequest = null;\r\n\r\n // Setting up Email To Send\r\n const emailSubject =\r\n fimenu.language == \"Spanish\"\r\n ? `Unirse a la reunión`\r\n : `Your Meeting Invitation: ${participantFullName} at ${dealershipName}`;\r\n\r\n const emailBody =\r\n fimenu.language == \"Spanish\"\r\n ? `

Siga el enlace para unirse a la reunión:

Unirse a la reunión`\r\n : `

Hello ${participantFirstName ? participantFirstName : participantFullName},

\r\n

We're thrilled to extend an invitation for an exclusive online meeting with our Finance and Insurance Manager at ${dealershipName}! This personalized session is tailored to address your unique car needs and provide expert guidance on financing options and insurance coverage.

\r\n

We're committed to making your car buying journey seamless and enjoyable, and this meeting is another step towards ensuring you have all the information you need to make informed decisions.

\r\n

Please follow the link to join meeting:

\r\n Join Meeting\r\n
\r\n

Best regards,
\r\n ${fimanagerName}
\r\n ${dealershipName}

`;\r\n\r\n sendEmailLinkRequest = {\r\n sendToList: [ participantEmail ],\r\n isBodyHtml: true,\r\n encodedLinkInfo: encodedLinkInfo,\r\n emailSubject: emailSubject,\r\n emailBody: emailBody,\r\n };\r\n\r\n // Setting up Text To Send\r\n const textBody =\r\n fimenu.language == \"Spanish\"\r\n ? \"Siga el enlace para unirse a la reunión: insertLinkHere\"\r\n : `Hello ${participantFirstName ? participantFirstName : participantFullName}, your meeting with ${fimanagerName} is about to begin. Please click the link to start your meeting: \\n insertLinkHere`;\r\n\r\n sendTextMsgLinkRequest = {\r\n toPhoneNumber: \"+1\" + participantCell,\r\n body: textBody,\r\n encodedLinkInfo: encodedLinkInfo,\r\n storeCode: fimenu.storeCode,\r\n };\r\n console.log(`sendEmailLinkRequest ${sendEmailLinkRequest.encodedLinkInfo}`);\r\n console.log(`sendTextMsgLinkRequest ${sendTextMsgLinkRequest.encodedLinkInfo}`);\r\n\r\n if (sendMethod === \"Email\" || sendMethod === \"Email and Text\") {\r\n //SENDS THE EMAIL INVITATION\r\n try {\r\n const emailResponse = await api.meeting.sendEmailInvitationLink(sendEmailLinkRequest);\r\n\r\n if (emailResponse && emailResponse.data) {\r\n util.toastr(\"success\", \"Success\", emailResponse.data);\r\n } else {\r\n util.toastr(\"error\", \"Error\", failMessage);\r\n }\r\n } catch (error: any) {\r\n util.toastr('error', 'Error', error.data ?? failMessage);\r\n }\r\n }\r\n\r\n if (sendMethod === \"Text\" || sendMethod === \"Email and Text\") {\r\n //SENDS THE TEXT INVITATION\r\n try {\r\n const textResponse = await api.meeting.sendTextMessageInvitationLink(sendTextMsgLinkRequest);\r\n\r\n if (textResponse && textResponse.data) {\r\n util.toastr(\"success\", \"Success\", textResponse.data);\r\n }\r\n } catch (error: any) {\r\n util.toastr('error', 'Error', error.data ?? failMessage);\r\n }\r\n }\r\n }\r\n\r\n function startInStoreMeeting(inStoreConnectionCode: string) {\r\n meetingHelper.inStore = true;\r\n meetingHelper.preConnectionFound = false;\r\n meetingHelper.initiateMeeting(meetingHelper.dealNumber, meetingHelper.storeCode);\r\n\r\n globalProperties.$meetingHub\r\n .startConnection(inStoreConnectionCode)\r\n .then(() => {\r\n setTimeout(() => {\r\n if (meetingHelper.currentMeetingUsers.length < 2) {\r\n globalProperties.$meetingHub.stopConnection(\"Customer Failed to Join Meeting\");\r\n meetingHelper.preConnectionFound = null;\r\n meetingHelper.connectionFailed = true;\r\n LogRocket.log(\r\n \"startInStoreMeeting - fimanager failed to find preconnection: \",\r\n inStoreConnectionCode\r\n );\r\n } else {\r\n meetingHelper.preConnectionFound = true;\r\n }\r\n }, 8000);\r\n globalProperties.$meetingHub.connected = true;\r\n globalProperties.$meetingHub.inStorePreConnection(\"fimanager\", meetingHelper.dealNumber + \"-\" + meetingHelper.storeCode);\r\n })\r\n .catch((error: any) => {\r\n LogRocket.log(\"Connection Error:\", error);\r\n });\r\n }\r\n\r\n async function fimanagerConnectToSecureRoom(fimenu: FIMenu) {\r\n LogRocket.log(\"------------ fimanagerConnectToSecureRoom ---------------\");\r\n //globalProperties.$meetingHub.startConnection(meetingHelper.dealNumber + '-' + meetingHelper.storeCode).then((response) => {\r\n const response = await meetingHelper.createMeeting(meetingHelper.dealNumber, meetingHelper.storeCode, fimenu);\r\n meetingHelper.currentMeeting = response.data;\r\n // meetingHelper.setCurrentMeeting(response.data);\r\n\r\n globalProperties.$meetingHub.code = meetingHelper.dealNumber + \"-\" + meetingHelper.storeCode;\r\n globalProperties.$meetingHub.joinMeetingRoom(\"fimanager\", true, fimenu.id);\r\n //})\r\n }\r\n\r\n function meetingRoomJoinSuccessHandler(role: any, isInStoreConnection: boolean, meetingRoomCode: any, currentMeetingDetails: any) {\r\n\r\n console.log(\"--------------------- meetingRoomJoinSuccessHandler ----------------------\", role);\r\n\r\n meetingHelper.currentMeetingUsers = Object.values(JSON.parse(currentMeetingDetails).users);\r\n\r\n meetingHelper.myUserDetails = meetingHelper.currentMeetingUsers.find(user => user.role === meetingHelper.myRole);\r\n\r\n // LogRocket.log('currentMeetingUsers', meetingHelper.currentMeetingUsers);\r\n // LogRocket.log(\"currentMeeting\", meetingHelper.currentMeeting);\r\n // LogRocket.log(\"myUserDetails\", meetingHelper.myUserDetails);\r\n\r\n meetingHelper.currentMeeting.meetingLogs.push(\r\n new FIMenuCustomerViewed({\r\n viewedType: CUSTOMER_VIEWS.CONNECTED,\r\n viewedDateTime: moment(),\r\n extraInfo: role,\r\n })\r\n );\r\n\r\n if (role == \"customer\" || role == \"coCustomer\") {\r\n meetingHelper.currentMeeting.meetingLogs.push(\r\n new FIMenuCustomerViewed({\r\n viewedType: CUSTOMER_VIEWS.VIDEO_PRESENTATION,\r\n viewedDateTime: moment(),\r\n extraInfo: \"customerEvent\",\r\n })\r\n );\r\n } else if (role == \"fimanager\") {\r\n console.log(\"SETTING MEETING STARTED AT\");\r\n meetingHelper.currentMeeting.startedAt = meetingHelper.currentMeeting.startedAt\r\n ? meetingHelper.currentMeeting.startedAt\r\n : moment();\r\n meetingHelper.currentMeeting.meetingLogs.push(\r\n new FIMenuCustomerViewed({\r\n viewedType: CUSTOMER_VIEWS.WAITING,\r\n viewedDateTime: moment(),\r\n extraInfo: \"customer\",\r\n })\r\n );\r\n }\r\n }\r\n\r\n async function updateMeetingHubParticipantsHandler(updatedMeetingParticipants: any) {\r\n console.log(\"--------------------- updateMeetingHubParticipantsHandler ----------------------\", updatedMeetingParticipants);\r\n meetingHelper.usersToDisconnect = updatedMeetingParticipants.usersToDisconnect;\r\n meetingHelper.shouldMeetingEnd = updatedMeetingParticipants.shouldMeetingEnd;\r\n meetingHelper.currentMeetingUsers = Object.values(updatedMeetingParticipants.usersList);\r\n meetingHelper.myUserDetails = meetingHelper.currentMeetingUsers.find(user => user.role === meetingHelper.myRole);\r\n meetingHelper.isMuted = meetingHelper.myUserDetails?.isMuted ?? false;\r\n meetingHelper.isBusyConnecting = false;\r\n console.log(\"meetingHelper.myUserDetails\", meetingHelper.myUserDetails);\r\n console.log(\"meetingHelper.myRole\", meetingHelper.myRole);\r\n console.log(\"meetingHelper.inStore\", meetingHelper.inStore);\r\n console.log(\"meetingHelper.shouldMeetingEnd\", meetingHelper.shouldMeetingEnd);\r\n\r\n // If the fimanager presses endMeeting Button then shouldMeetingEnd should be true and the customer should disconnect\r\n if (meetingHelper.myRole === 'customer' && meetingHelper.inStore && meetingHelper.shouldMeetingEnd) {\r\n globalProperties.$meetingHub.stopConnection(\"Customer Left Meeting\");\r\n return;\r\n }\r\n\r\n if (meetingHelper.myUserDetails && meetingHelper.currentMeetingUsers.length < 2 && meetingHelper.inStore && meetingHelper.shouldMeetingEnd) {\r\n console.log('???????? disconnectParticipant - called from updateMeetingHubParticipantsHandler');\r\n await meetingHelper.disconnectParticipant(meetingHelper.myUserDetails.userId);\r\n }\r\n\r\n meetingHelper.hasRequestToPresentBeenSent = false;\r\n\r\n if (meetingHelper.currentMeetingUsers.some(user => user.isPresenting)) {\r\n meetingHelper.customerScreenConnected = true;\r\n } else {\r\n meetingHelper.customerScreenConnected = false;\r\n }\r\n }\r\n\r\n async function disconnectParticipant(userId: string) {\r\n LogRocket.log(\"--------------------- disconnectParticipant --------------------- \", userId);\r\n\r\n if (!meetingHelper.inStore) {\r\n // SendParticipantToLobby expects a list\r\n globalProperties.$meetingHub.sendParticipantToLobby([ userId ]);\r\n } else if (meetingHelper.inStore && meetingHelper.myRole !== 'fimanager') {\r\n globalProperties.$meetingHub.stopConnection(\"Customer/Co-customer has disconnected\");\r\n } else {\r\n console.log('!!!!!!!!!!!!!!!!!! END MEETING - called from disconnectParticipant');\r\n await meetingHelper.endMeeting();\r\n }\r\n }\r\n\r\n async function customerDisconnectedHandler(updatedMeetingParticipants: any) {\r\n LogRocket.log(\r\n \"--------------------- customerDisconnectedHandler ---------------------\",\r\n updatedMeetingParticipants\r\n );\r\n if (updatedMeetingParticipants) {\r\n meetingHelper.userToDisconnect = updatedMeetingParticipants.userToDisconnect;\r\n meetingHelper.currentMeetingUsers = Object.values(updatedMeetingParticipants.usersList);\r\n }\r\n\r\n const usersLeftInRoom = meetingHelper.currentMeetingUsers ? meetingHelper.currentMeetingUsers : [];\r\n\r\n if (\r\n usersLeftInRoom.length === 1 &&\r\n usersLeftInRoom[ 0 ].role === \"fimanager\" &&\r\n usersLeftInRoom[ 0 ].isInStoreConnection\r\n ) {\r\n console.log('!!!!!!!!!!!!!!!!!! END MEETING - called from customerDisconnectedHandler');\r\n await meetingHelper.endMeeting();\r\n }\r\n }\r\n\r\n async function endMeeting() {\r\n console.log(\"-------------- endMeeting ------------\");\r\n meetingHelper.shouldMeetingEnd = true;\r\n\r\n const usersToSendToLobby = meetingHelper.currentMeetingUsers\r\n ?.filter(user => user.role !== \"fimanager\")\r\n ?.map(user => user.userId);\r\n\r\n console.log(\"usersToSendToLobby\", usersToSendToLobby);\r\n\r\n if (usersToSendToLobby) {\r\n if (!meetingHelper.inStore) {\r\n // For remote meetings we might have a list of users to send to the lobby\r\n await globalProperties.$meetingHub.sendParticipantToLobby(usersToSendToLobby, meetingHelper.shouldMeetingEnd);\r\n } else {\r\n // In-store meetings will only have one user that will be disconnected from the meeting\r\n const userToDisconnect = Object.values(meetingHelper.currentMeetingUsers)?.find(\r\n user => user.role !== \"fimanager\"\r\n )?.userId;\r\n\r\n if (userToDisconnect) {\r\n await globalProperties.$meetingHub.disconnectParticipant(userToDisconnect, meetingHelper.shouldMeetingEnd);\r\n }\r\n }\r\n }\r\n await meetingHelper.fimanagerDisconnect();\r\n\r\n meetingHelper.currentMeetingUsers = [];\r\n\r\n }\r\n\r\n async function fimanagerDisconnect() {\r\n console.log(\"----------- fimanagerDisconnect ----------- \");\r\n if (globalProperties.$meetingHub.connected && globalProperties.$meetingHub.code) {\r\n // api.meeting.updateMeeting(meetingHelper.currentMeeting);\r\n await api.meeting.setMeetingFinishedAt(meetingHelper.currentMeeting.id);\r\n\r\n broadcastUnsubscribeAllEvents(globalProperties.$meetingHub);\r\n globalProperties.$meetingHub.fimanagerStopConnection(\"Fi Mgr Left Meeting\");\r\n\r\n //Clear any relevant fields so fimanager can have another meeting w/o refreshing\r\n meetingHelper.fimanagerResetHelper();\r\n }\r\n }\r\n\r\n function fimanagerResetHelper() {\r\n console.log('%c FIMANAGER RESET HELPER', 'background: orange');\r\n meetingHelper.currentMeetingUsers = [];\r\n meetingHelper.meetingCodeEncoded = null;\r\n meetingHelper.myUserDetails = null;\r\n meetingHelper.usersToDisconnect = null;\r\n //meetingHelper.employeeId = null;\r\n //meetingHelper.employeeCode = null;\r\n //meetingHelper.storeCode = null;\r\n //meetingHelper.dealNumber = null;\r\n meetingHelper.inStore = null;\r\n // meetingHelper.meetings = [];\r\n meetingHelper.cameraAccessAcknowledged = null;\r\n meetingHelper.customerScreenConnected = false;\r\n meetingHelper.cameraAccessAllowed = null;\r\n meetingHelper.shouldMeetingEnd = null;\r\n //meetingHelper.noUsersInMeeting = null;\r\n }\r\n\r\n /***********************************************************\r\n *\r\n * Customer Meeting Handlers\r\n *\r\n * ********************************************************/\r\n\r\n function customerMoveToSecureRoomHandler(newSecureRoom: string) {\r\n console.log(\"*** meetingHub - moveToSecureRoom -> leavePreConnectionRoom\", newSecureRoom);\r\n console.log(\"--- customerMoveToSecureRoomHandler --- \", newSecureRoom);\r\n // meetingHelper.meetingCodeEncoded = newSecureRoom;\r\n meetingHelper.inStore = true;\r\n globalProperties.$meetingHub.leavePreConnectionRoom(newSecureRoom);\r\n }\r\n\r\n async function customerConnectToSecureRoom(who = \"customer\", inStore = true) {\r\n console.log(\"meetingHelper.meetingCodeEncoded\", meetingHelper.meetingCodeEncoded);\r\n\r\n // If remote meeting, we need to start a meetingHub connection, if we are inStore we are already connected to meetingHub\r\n if (!inStore) {\r\n meetingHelper.dealNumber = meetingHelper.decodeMeetingCode(meetingHelper.meetingCodeEncoded);\r\n await globalProperties.$meetingHub.startConnection(meetingHelper.dealNumber);\r\n }\r\n globalProperties.$meetingHub.connected = true;\r\n globalProperties.$meetingHub.joinMeetingRoom(who, inStore, null, meetingHelper.firstName, meetingHelper.lastName, meetingHelper.fullName);\r\n }\r\n\r\n function requestToBePresenter() {\r\n console.log(\"requestToBePresenter\", meetingHelper.myUserDetails);\r\n if (meetingHelper.myUserDetails) {\r\n globalProperties.$meetingHub.requestToBePresenter(meetingHelper.myUserDetails.userId);\r\n meetingHelper.hasRequestToPresentBeenSent = true;\r\n }\r\n }\r\n\r\n function userRequestingToPresentHandler(userId: string) {\r\n console.log(\"userRequestingToPresentHandler\", userId);\r\n meetingHelper.userRequestingToPresent = userId;\r\n\r\n util.toastr(\"warn\", \"Meeting Notification\", \"User is requesting control of the meeting\", 12000);\r\n }\r\n\r\n function grantRequestToBePresenter(role: string) {\r\n console.log(\"grantRequestToBePresenter\", role);\r\n const userToGrantRequest = meetingHelper.currentMeetingUsers.find(user => user.role === role);\r\n if (userToGrantRequest) {\r\n globalProperties.$meetingHub.grantRequestToBePresenter(userToGrantRequest.userId);\r\n meetingHelper.userRequestingToPresent = null;\r\n }\r\n }\r\n\r\n function customerMeetingRoomJoinSuccessHandler(\r\n role: string,\r\n isInStoreConnection: boolean,\r\n meetingRoomCode: string,\r\n currentMeetingDetails: any\r\n ) {\r\n meetingHelper.currentMeetingDetails = JSON.parse(currentMeetingDetails);\r\n meetingHelper.currentMeetingUsers = Object.values(meetingHelper.currentMeetingDetails.users);\r\n console.log(\"meetingHelper.currentMeetingUsers\", meetingHelper.currentMeetingUsers);\r\n if(meetingHelper.myRole != \"fimanager\" && meetingHelper.myRole == role) {\r\n broadcastEmitEvent(globalProperties.$meetingHub,\r\n ENUMS.EVENT_EMITS.BROADCAST.CUSTOMER_JOINED_MEETING,\r\n currentMeetingDetails);\r\n }\r\n\r\n meetingHelper.myUserDetails = meetingHelper.currentMeetingUsers.find(user => user.role === meetingHelper.myRole);\r\n console.log(\"meetingHelper.myUserDetails\", meetingHelper.myUserDetails);\r\n }\r\n\r\n async function customerFinishMeetingHandler() {\r\n const usersLeftInRoom = meetingHelper.currentMeetingUsers\r\n ? Object.keys(meetingHelper.currentMeetingUsers)\r\n : [];\r\n\r\n console.log(\"customerFinishMeetingHandler\", meetingHelper.currentMeetingUsers);\r\n console.log(\"meetingHelper.inStore\", meetingHelper.inStore);\r\n console.log(\"usersLeftInRoom\", usersLeftInRoom);\r\n\r\n if (usersLeftInRoom.length < 2) {\r\n //await api.meeting.setMeetingFinishedAt(meetingHelper.meetingInfo.id) //\r\n await globalProperties.$meetingHub.stopConnection(\"finishMeetingHandler\");\r\n }\r\n //else {\r\n // await globalProperties.$meetingHub.stopConnection(\"customerFinishMeetingHandler\");\r\n //}\r\n }\r\n\r\n function customerResetHelper() {\r\n meetingHelper.currentMeetingUsers = [];\r\n meetingHelper.currentMeetingDetails = null;\r\n meetingHelper.meetingCodeEncoded = null;\r\n meetingHelper.employeeId = null;\r\n meetingHelper.employeeCode = null;\r\n meetingHelper.storeCode = null;\r\n meetingHelper.dealNumber = null;\r\n meetingHelper.inStore = null;\r\n // meetingHelper.meetings = [];\r\n //meetingHelper.noUsersInMeeting = null;\r\n }\r\n\r\n function reconnectedMeetingHubHandler(dealId: string = null) {\r\n console.log('reconnectedMeetingHubHandler', meetingHelper.myRole, meetingHelper.inStore, dealId, meetingHelper.firstName, meetingHelper.lastName);\r\n globalProperties.$meetingHub.reconnectParticipant(meetingHelper.myRole, meetingHelper.inStore, dealId, meetingHelper.firstName, meetingHelper.lastName);\r\n }\r\n\r\n const meetingHelper = reactive({\r\n // Meeting utility functions\r\n //createNumberCode,\r\n encodeMeetingCode,\r\n decodeMeetingCode,\r\n // setCurrentMeeting,\r\n\r\n // Meeting Actions\r\n createMeeting,\r\n initiateMeeting,\r\n sendLinkToMeetingRoomParticipant,\r\n startRemoteMeeting,\r\n allowUserIntoMeeting,\r\n startInStoreMeeting,\r\n fimanagerConnectToSecureRoom,\r\n meetingRoomJoinSuccessHandler,\r\n disconnectParticipant,\r\n updateMeetingHubParticipantsHandler,\r\n meetingCurrentlyOpen,\r\n\r\n customerDisconnectedHandler,\r\n endMeeting,\r\n fimanagerDisconnect,\r\n fimanagerResetHelper,\r\n customerResetHelper,\r\n reconnectedMeetingHubHandler,\r\n\r\n // Meeting data - contains data that may be put into the MeetingInfo class and some extra data that may be useful in the MeetingHelper\r\n meetingCodeEncoded: null,\r\n encodedUrlParam: null,\r\n employeeId: null,\r\n employeeCode: null,\r\n storeCode: null,\r\n dealNumber: null,\r\n inStore: null,\r\n myRole: null,\r\n myUserDetails: null,\r\n firstName: null,\r\n lastName: null,\r\n fullName: null,\r\n preConnectionFound: null,\r\n connectionFailed: null,\r\n usersToDisconnect: null,\r\n // meetings: [],\r\n //noUsersInMeeting: null,\r\n customerScreenConnected: false,\r\n isBusyConnecting: false,\r\n isMuted: false,\r\n\r\n // Meeting room mgmt\r\n currentMeeting: null,\r\n currentMeetingUsers: [],\r\n currentMeetingDetails: null,\r\n userToDisconnect: null,\r\n shouldMeetingEnd: null,\r\n\r\n // Meeting Info Class\r\n meetingInfo: null,\r\n\r\n /***************************\r\n * Customer Meeting\r\n * *************************/\r\n isMeetingStillActive: false,\r\n customerMoveToSecureRoomHandler,\r\n // customerGetMeetingByCode,\r\n customerConnectToSecureRoom,\r\n customerMeetingRoomJoinSuccessHandler,\r\n customerFinishMeetingHandler,\r\n // checkIfMeetingStillActive,\r\n // checkIfMeetingStillActiveResponse,\r\n cameraAccessAllowed: null,\r\n cameraAccessAcknowledged: null,\r\n\r\n /***************************************************************\r\n * Customer Presenter Handlers (who is in control in the meeting)\r\n * *************************************************************/\r\n requestToBePresenter,\r\n hasRequestToPresentBeenSent: false,\r\n userRequestingToPresentHandler,\r\n userRequestingToPresent: null,\r\n grantRequestToBePresenter,\r\n\r\n disableVideoChat: null,\r\n });\r\n globalProperties.meetingHelper = meetingHelper;\r\n app.provide(\"meetingHelper\", meetingHelper);\r\n },\r\n};\r\n","/* eslint-disable */\r\nimport { createApp } from \"vue\";\r\nimport { piniaInstance } from \"@core/stores/pinia-instance\";\r\nimport App from \"./App.vue\";\r\nimport router from \"@/router\";\r\nimport Static from '@core/plugins/static'\r\nimport settings from \"settings\";\r\nimport filters from \"@core/services/filters\"; //IMPORTANT. do not remove. Vue needs to see this before other components. Weird stuff\r\nimport api from \"@core/services/api\";\r\nimport LogRocket from \"logrocket\";\r\nimport mitt from \"mitt\";\r\nimport Notifications from \"@kyvg/vue3-notification\";\r\nimport util from \"@core/services/util\";\r\nimport moment from \"moment\";\r\nmoment.locale(\"en\");\r\n\r\nimport MeetingHub from \"@core/plugins/meetingHub\";\r\nimport MeetingHelper from \"@core/plugins/MeetingHelper\";\r\n\r\nconst app = createApp(App);\r\napp.use(piniaInstance);\r\napp.use(router)\r\n\r\nconst eventBus = mitt();\r\nconst meetingHub = mitt();\r\n\r\n// Global Properties\r\napp.config.globalProperties.EventBus = eventBus;\r\napp.config.globalProperties.MeetingHubBus = meetingHub;\r\n// app.config.globalProperties.DealRoomBus = dealRoomHub;\r\napp.config.globalProperties.$filters = filters;\r\n// app.config.productionTip = false;\r\napp.use(Static);\r\n\r\napp.use(MeetingHub).use(MeetingHelper);\r\napp.use(Notifications);\r\n\r\nimport { useUserStore } from \"@core/stores/UserStore\";\r\nrouter.isReady().then(async() => {\r\n const route = router.currentRoute.value;\r\n\r\n if (route.meta.requiresCustomerData) {\r\n const userStore = useUserStore();\r\n\r\n const queryId = route.query.id as string;\r\n if (queryId) {\r\n const decryptedId = util.decryptJSONText(queryId);\r\n const customerId = JSON.parse(decryptedId);\r\n\r\n if (customerId) {\r\n await userStore.initializeCustomerData(customerId);\r\n }\r\n }\r\n }\r\n});\r\n\r\n\r\napp.provide(\"EventBus\", eventBus);\r\napp.provide(\"MeetingHubBus\", meetingHub);\r\napp.provide(\"$filters\", filters);\r\n\r\napi.settings.getCustomerAppSettings().then(async (res: any) => {\r\n if (res.data) {\r\n await api\r\n .getCountryDetails()\r\n .then((response: any) => {\r\n settings.countries = response.data;\r\n })\r\n .catch((err: any) => {\r\n console.log(\"error\", err);\r\n });\r\n\r\n Object.assign(settings, res.data);\r\n }\r\n //INIT LOG ROCKET\r\n // only record when the application is done INSTORE on the prefilled data page off the bat.\r\n // if the lead source = web, dont record here.\r\n const shouldRecordSession = () => {\r\n const subdomain = window.location.href.split(settings.logRocketRootHostName)[1]; // Extracts the subdomain\r\n if (!subdomain) return true;\r\n\r\n const excludedSubdomains = settings.logRocketExclusionsList; // Subdomains to exclude\r\n\r\n // Returns true if the current exludedSubDomains is not included in the subdomain\r\n return !excludedSubdomains.some((sb: string) => subdomain.includes(sb));\r\n };\r\n\r\n if (shouldRecordSession()) {\r\n LogRocket.init(settings.logRocketOrg);\r\n //LogRocket.init(settings.logRocketOrg, { rootHostname: settings.logRocketRootHostName });\r\n }\r\n});\r\n\r\napp.mount(\"#customerApp\");\r\nconsole.log(\"This is customer app\", app);\r\n"],"file":"js/main.js"}