no message
1
.gitignore
vendored
@ -18,7 +18,6 @@
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/storage/pail
|
||||
/vendor
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
Thumbs.db
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
!function(){var e=function(t,i){function s(){this.q=[],this.add=function(e){this.q.push(e)};var e,t;this.call=function(){for(e=0,t=this.q.length;e<t;e++)this.q[e].call()}}function o(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null).getPropertyValue(t):e.style[t]}function n(e,t){if(e.resizedAttached){if(e.resizedAttached)return void e.resizedAttached.add(t)}else e.resizedAttached=new s,e.resizedAttached.add(t);e.resizeSensor=document.createElement("div"),e.resizeSensor.className="resize-sensor";var i="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;",n="position: absolute; left: 0; top: 0; transition: 0s;";e.resizeSensor.style.cssText=i,e.resizeSensor.innerHTML='<div class="resize-sensor-expand" style="'+i+'"><div style="'+n+'"></div></div><div class="resize-sensor-shrink" style="'+i+'"><div style="'+n+' width: 200%; height: 200%"></div></div>',e.appendChild(e.resizeSensor),{fixed:1,absolute:1}[o(e,"position")]||(e.style.position="relative");var d,r,l=e.resizeSensor.childNodes[0],c=l.childNodes[0],h=e.resizeSensor.childNodes[1],a=(h.childNodes[0],function(){c.style.width=l.offsetWidth+10+"px",c.style.height=l.offsetHeight+10+"px",l.scrollLeft=l.scrollWidth,l.scrollTop=l.scrollHeight,h.scrollLeft=h.scrollWidth,h.scrollTop=h.scrollHeight,d=e.offsetWidth,r=e.offsetHeight});a();var f=function(){e.resizedAttached&&e.resizedAttached.call()},u=function(e,t,i){e.attachEvent?e.attachEvent("on"+t,i):e.addEventListener(t,i)},p=function(){e.offsetWidth==d&&e.offsetHeight==r||f(),a()};u(l,"scroll",p),u(h,"scroll",p)}var d=Object.prototype.toString.call(t),r="[object Array]"===d||"[object NodeList]"===d||"[object HTMLCollection]"===d||"undefined"!=typeof jQuery&&t instanceof jQuery||"undefined"!=typeof Elements&&t instanceof Elements;if(r)for(var l=0,c=t.length;l<c;l++)n(t[l],i);else n(t,i);this.detach=function(){if(r)for(var i=0,s=t.length;i<s;i++)e.detach(t[i]);else e.detach(t)}};e.detach=function(e){e.resizeSensor&&(e.removeChild(e.resizeSensor),delete e.resizeSensor,delete e.resizedAttached)},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=e:window.ResizeSensor=e}();
|
||||
;
|
||||
@ -1,6 +0,0 @@
|
||||
jQuery(document).ready(function(jQuery){jQuery(document).on("submit","#commentform",function(){var e=jQuery(this);jQuery.ajax({url:globals.ajax_url,data:e.serialize()+"&action=ajax_comment",type:e.attr("method"),error:function(e){ncPopupTips(0,e.responseText)},success:function(e){jQuery("textarea").each(function(){this.value=""});var t=addComment,o=t.I("cancel-comment-reply-link"),r=t.I("wp-temp-form-div"),a=t.I(t.respondId),n=t.I("comment_post_ID").value,i=t.I("comment_parent").value;if(i!="0"){jQuery("#respond").before('<ul class="children">'+e+"</ul>")}else if(!jQuery(".commentlist").length){jQuery("#respond").after('<ul class="commentlist">'+e+"</ul>")}else{jQuery(".commentlist").append(e)}
|
||||
ncPopupTips(1,__("Success!","pandapro"));o.style.display="none";o.onclick=null;t.I("comment_parent").value="0";if(r&&a){r.parentNode.insertBefore(a,r);r.parentNode.removeChild(r)}},});return!1});addComment={moveForm:function(e,t,o){var r=this,i,s=r.I(e),c=r.I(o),m=r.I("cancel-comment-reply-link"),l=r.I("comment_parent"),d=r.I("comment_post_ID");r.respondId=o;if(!r.I("wp-temp-form-div")){i=document.createElement("div");i.id="wp-temp-form-div";i.style.display="none";c.parentNode.insertBefore(i,c)}
|
||||
!s?((temp=r.I("wp-temp-form-div")),(r.I("comment_parent").value="0"),temp.parentNode.insertBefore(c,temp),temp.parentNode.removeChild(temp)):s.parentNode.insertBefore(c,s.nextSibling);jQuery("body").animate({scrollTop:jQuery("#respond").offset().top-180,},400);l.value=t;m.style.display="";m.onclick=function(){var e=addComment,t=e.I("wp-temp-form-div"),o=e.I(e.respondId);e.I("comment_parent").value="0";if(t&&o){t.parentNode.insertBefore(o,t);t.parentNode.removeChild(t)}
|
||||
this.style.display="none";this.onclick=null;return!1};try{r.I("comment").focus()}catch(u){}
|
||||
return!1},I:function(e){return document.getElementById(e)},};window.addComment=addComment})
|
||||
;
|
||||
@ -1,10 +0,0 @@
|
||||
/*
|
||||
* email-autocomplete - 0.1.3
|
||||
* jQuery plugin that displays in-place autocomplete suggestions for email input fields.
|
||||
*
|
||||
*
|
||||
* Made by Low Yong Zhen <yz@stargate.io>
|
||||
*/
|
||||
|
||||
"use strict";!function(a,b,c,d){function e(b,c){this.$field=a(b),this.options=a.extend(!0,{},f,c),this._defaults=f,this._domains=this.options.domains,this.init()}var f={suggClass:"eac-sugg",domains:["yahoo.com","hotmail.com","gmail.com","me.com","aol.com","mac.com","live.com","comcast.net","googlemail.com","msn.com","hotmail.co.uk","yahoo.co.uk","facebook.com","verizon.net","sbcglobal.net","att.net","gmx.com","outlook.com","icloud.com"]};e.prototype={init:function(){Array.prototype.indexOf||this.doIndexOf(),this.fieldLeftOffset=null;var b=a("<div class='eac-input-wrap' />").css({display:this.$field.css("display"),position:"static"===this.$field.css("position")?"relative":this.$field.css("position"),fontSize:this.$field.css("fontSize")});this.$field.wrap(b),this.$cval=a("<span class='eac-cval' />").css({visibility:"hidden",position:"absolute",display:"inline-block",fontFamily:this.$field.css("fontFamily"),fontWeight:this.$field.css("fontWeight"),letterSpacing:this.$field.css("letterSpacing")}).insertAfter(this.$field);var c=(this.$field.outerHeight(!0)-this.$field.height())/2;this.$suggOverlay=a("<span class='"+this.options.suggClass+"' />").css({display:"block","box-sizing":"content-box",lineHeight:this.$field.css("lineHeight"),paddingTop:c+"px",paddingBottom:c+"px",fontFamily:this.$field.css("fontFamily"),fontWeight:this.$field.css("fontWeight"),letterSpacing:this.$field.css("letterSpacing"),position:"absolute",top:0,left:0}).insertAfter(this.$field),this.$field.on("keyup.eac",a.proxy(this.displaySuggestion,this)),this.$field.on("blur.eac",a.proxy(this.autocomplete,this)),this.$field.on("keydown.eac",a.proxy(function(a){39!==a.which&&9!==a.which||this.autocomplete()},this)),this.$suggOverlay.on("mousedown.eac touchstart.eac",a.proxy(this.autocomplete,this))},suggest:function(a){var b=a.split("@");return b.length>1?(a=b.pop(),a.length?(this._domains.filter(function(b){return 0===b.indexOf(a)}).shift()||"").replace(a,""):""):""},autocomplete:function(){if(void 0===this.suggestion||this.suggestion.length<1)return!1;this.$field.val(this.val+this.suggestion),this.$suggOverlay.text(""),this.$cval.text("")},displaySuggestion:function(a){this.val=this.$field.val(),this.suggestion=this.suggest(this.val),this.suggestion.length?a.preventDefault():this.$suggOverlay.text(""),this.$suggOverlay.text(this.suggestion),this.$cval.text(this.val),null===this.fieldLeftOffset&&(this.fieldLeftOffset=(this.$field.outerWidth(!0)-this.$field.width())/2);var b=this.$cval.width();this.$field.outerWidth()>b&&this.$suggOverlay.css("left",this.fieldLeftOffset+b+"px")},doIndexOf:function(){Array.prototype.indexOf=function(a,b){if(void 0===this||null===this)throw new TypeError('"this" is null or not defined');var c=this.length>>>0;for(b=+b||0,Math.abs(b)===1/0&&(b=0),b<0&&(b+=c)<0&&(b=0);b<c;b++)if(this[b]===a)return b;return-1}}},a.fn.emailautocomplete=function(b){return this.each(function(){a.data(this,"yz_emailautocomplete")||a.data(this,"yz_emailautocomplete",new e(this,b))})}}(jQuery,window,document);
|
||||
;
|
||||
@ -1,3 +0,0 @@
|
||||
/*! This file is auto-generated */
|
||||
(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{actions:()=>S,addAction:()=>m,addFilter:()=>p,applyFilters:()=>k,createHooks:()=>h,currentAction:()=>w,currentFilter:()=>I,defaultHooks:()=>f,didAction:()=>O,didFilter:()=>j,doAction:()=>b,doingAction:()=>x,doingFilter:()=>T,filters:()=>z,hasAction:()=>v,hasFilter:()=>y,removeAction:()=>A,removeAllActions:()=>F,removeAllFilters:()=>g,removeFilter:()=>_});const n=function(t){return"string"!=typeof t||""===t?(console.error("The namespace must be a non-empty string."),!1):!!/^[a-zA-Z][a-zA-Z0-9_.\-\/]*$/.test(t)||(console.error("The namespace can only contain numbers, letters, dashes, periods, underscores and slashes."),!1)};const r=function(t){return"string"!=typeof t||""===t?(console.error("The hook name must be a non-empty string."),!1):/^__/.test(t)?(console.error("The hook name cannot begin with `__`."),!1):!!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(t)||(console.error("The hook name can only contain numbers, letters, dashes, periods and underscores."),!1)};const o=function(t,e){return function(o,i,s,c=10){const l=t[e];if(!r(o))return;if(!n(i))return;if("function"!=typeof s)return void console.error("The hook callback must be a function.");if("number"!=typeof c)return void console.error("If specified, the hook priority must be a number.");const u={callback:s,priority:c,namespace:i};if(l[o]){const t=l[o].handlers;let e;for(e=t.length;e>0&&!(c>=t[e-1].priority);e--);e===t.length?t[e]=u:t.splice(e,0,u),l.__current.forEach((t=>{t.name===o&&t.currentIndex>=e&&t.currentIndex++}))}else l[o]={handlers:[u],runs:0};"hookAdded"!==o&&t.doAction("hookAdded",o,i,s,c)}};const i=function(t,e,o=!1){return function(i,s){const c=t[e];if(!r(i))return;if(!o&&!n(s))return;if(!c[i])return 0;let l=0;if(o)l=c[i].handlers.length,c[i]={runs:c[i].runs,handlers:[]};else{const t=c[i].handlers;for(let e=t.length-1;e>=0;e--)t[e].namespace===s&&(t.splice(e,1),l++,c.__current.forEach((t=>{t.name===i&&t.currentIndex>=e&&t.currentIndex--})))}return"hookRemoved"!==i&&t.doAction("hookRemoved",i,s),l}};const s=function(t,e){return function(n,r){const o=t[e];return void 0!==r?n in o&&o[n].handlers.some((t=>t.namespace===r)):n in o}};const c=function(t,e,n=!1){return function(r,...o){const i=t[e];i[r]||(i[r]={handlers:[],runs:0}),i[r].runs++;const s=i[r].handlers;if(!s||!s.length)return n?o[0]:void 0;const c={name:r,currentIndex:0};for(i.__current.push(c);c.currentIndex<s.length;){const t=s[c.currentIndex].callback.apply(null,o);n&&(o[0]=t),c.currentIndex++}return i.__current.pop(),n?o[0]:void 0}};const l=function(t,e){return function(){var n;const r=t[e];return null!==(n=r.__current[r.__current.length-1]?.name)&&void 0!==n?n:null}};const u=function(t,e){return function(n){const r=t[e];return void 0===n?void 0!==r.__current[0]:!!r.__current[0]&&n===r.__current[0].name}};const a=function(t,e){return function(n){const o=t[e];if(r(n))return o[n]&&o[n].runs?o[n].runs:0}};class d{constructor(){this.actions=Object.create(null),this.actions.__current=[],this.filters=Object.create(null),this.filters.__current=[],this.addAction=o(this,"actions"),this.addFilter=o(this,"filters"),this.removeAction=i(this,"actions"),this.removeFilter=i(this,"filters"),this.hasAction=s(this,"actions"),this.hasFilter=s(this,"filters"),this.removeAllActions=i(this,"actions",!0),this.removeAllFilters=i(this,"filters",!0),this.doAction=c(this,"actions"),this.applyFilters=c(this,"filters",!0),this.currentAction=l(this,"actions"),this.currentFilter=l(this,"filters"),this.doingAction=u(this,"actions"),this.doingFilter=u(this,"filters"),this.didAction=a(this,"actions"),this.didFilter=a(this,"filters")}}const h=function(){return new d},f=h(),{addAction:m,addFilter:p,removeAction:A,removeFilter:_,hasAction:v,hasFilter:y,removeAllActions:F,removeAllFilters:g,doAction:b,applyFilters:k,currentAction:w,currentFilter:I,doingAction:x,doingFilter:T,didAction:O,didFilter:j,actions:S,filters:z}=f;(window.wp=window.wp||{}).hooks=e})();
|
||||
;
|
||||
@ -1,40 +0,0 @@
|
||||
window.$=jQuery;const isApollo=$("meta[name=apollo-enabled]").attr("content")==="1";var{__}=wp.i18n;function toggleCommentAuthorInfo(){var changeMsg=__("[Edit]","pandapro");var closeMsg=__("[Close]","pandapro");$(".comment-form-info").slideToggle("slow",function(){if($(".comment-form-info").css("display")=="none"){$("#toggle-comment-author-info").html(changeMsg)}else{$("#toggle-comment-author-info").html(closeMsg)}})}
|
||||
function setLightModeClass(){$("body").removeClass("nice-dark-mode");$(".logo-dark").removeClass("d-inline-block");$(".logo-dark").addClass("d-none");$(".logo-light").removeClass("d-none");$(".logo-light").addClass("d-inline-block")}
|
||||
function setDarkMode(){$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{toggle_action:"on",action:"pandapro_toggle_dark_mode",},}).done(function(){setDarkModeClass()})}
|
||||
function setDarkModeClass(){$("body").addClass("nice-dark-mode");$(".logo-dark").removeClass("d-none");$(".logo-dark").addClass("d-inline-block");$(".logo-light").removeClass("d-inline-block");$(".logo-light").addClass("d-none")}
|
||||
function setLightMode(){$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{toggle_action:"off",action:"pandapro_toggle_dark_mode",},}).done(function(){setLightModeClass()})}
|
||||
function toggleSidebar(){$(".sidebar-close, .mobile-overlay").on("click",function(){$("body").removeClass("modal-open");$(".mobile-sidebar").removeClass("active");$(".mobile-overlay").removeClass("active")});$("#sidebarCollapse").on("click",function(){$("body").addClass("modal-open");$(".mobile-sidebar").addClass("active");$(".mobile-overlay").addClass("active");$(".collapse.in").toggleClass("in");$("a[aria-expanded=true]").attr("aria-expanded","false")})}
|
||||
function setCurrentmenu(){var b=$(".mobile-sidebar-menu .current-menu-parent");if(b.hasClass("current-menu-ancestor")){b.children().siblings(".sub-menu").stop(!0).slideDown(300)}}
|
||||
jQuery(document).ready(function($){toggleSidebar();setCurrentmenu();$("#email").emailautocomplete({domains:["qq.com","163.com","126.com","sina.com","21cn.com","sogou.com","aliyun.com","56.com","sohu.com","yahoo.cn","yahoo.com","msn.com","aol.com","ask.com","live.com","gmail.com","hotmail.com","live.cn",],});const loadingSvg=`<div class="text-center"><div class="spinner-border spinner-border-sm text-light" role="status"></div></div>`;var innerHeight=window.innerHeight;var mainHeight=$("main").innerHeight();if(mainHeight>innerHeight){var headerHeight=$(".header").height();$(window).on("scroll",{TopPrev:0,},function(){var TopCurrent=$(window).scrollTop();if(TopCurrent<this.TopPrev){if(TopCurrent>0&&$(".header").hasClass("fixed-header")){$(".header").addClass("visible-scroll-up")}else{$(".header").removeClass("visible-scroll-up fixed-header")}}else{$(".header").removeClass("visible-scroll-up");if(TopCurrent>headerHeight&&!$(".header").hasClass("fixed-header"))
|
||||
$(".header").addClass("fixed-header")}
|
||||
this.TopPrev=TopCurrent})}
|
||||
$(window).scroll(function(){var $window=$(window),$window_width=$window.width();if($(this).scrollTop()>200&&$window_width>=1024){$("#scrollToTOP").filter(":hidden").fadeIn("fast")}else{$("#scrollToTOP").filter(":visible").fadeOut("fast")}});$("#scrollToTOP").on("click",function(){$("html, body").animate({scrollTop:0,},"slow");return!1});$('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function(){if(location.pathname.replace(/^\//,"")==this.pathname.replace(/^\//,"")&&location.hostname==this.hostname){var target=$(this.hash);target=target.length?target:$("[name="+this.hash.slice(1)+"]");if(target.length){$("html, body").animate({scrollTop:target.offset().top-60,},1000,"easeInOutExpo");return!1}}});$(".sidebar").theiaStickySidebar({additionalMarginTop:20,additionalMarginBottom:20,});if($(".main-menu li").hasClass("menu-item-has-children")){$(".main-menu .menu-item-has-children").prepend('<div class="submenu-arrow iconfont icon-jiantou1"></div>')}
|
||||
$(".mobile-sidebar-menu .menu-item-has-children > a").append('<div class="dropdown-sub-menu"><span class="iconfont icon-right"></span></div>'),$(document).on("click",".mobile-sidebar-menu .menu-item-has-children > a",function(event){var i=$(this);i.siblings(".mobile-sidebar-menu .sub-menu")[0]&&(event.preventDefault(),i.parent().hasClass("in")?(i.parent().removeClass("in"),i.parent().find(".in").removeClass("in"),i.parent().find(".sub-menu").stop(!0).slideUp(300)):(i.closest(".in")[0]||(i.find(".menu-item-has-children.in .sub-menu").stop(!0).slideUp(300),i.find(".menu-item-has-children.in").removeClass("in")),i.parent().addClass("in"),i.parent().siblings(".in").find(".sub-menu").stop(!0).slideUp(300),i.parent().siblings(".current-menu-parent").find(".sub-menu").stop(!0).slideUp(300),i.parent().siblings(".in").removeClass("in"),i.siblings(".sub-menu").stop(!0).slideDown(300)))});var banner1=$(".slide-style-1");if(banner1.length>0){var banner1=new Swiper(".slide-style-1",{loop:!0,spaceBetween:15,autoplay:{delay:5000,disableOnInteraction:!1,},pagination:{el:".swiper-pagination",clickable:!0,},})}
|
||||
var banner2=$(".slide-style-2");if(banner2.length>0){var banner2=new Swiper(".slide-style-2",{loop:!0,spaceBetween:15,autoplay:{delay:5000,disableOnInteraction:!1,},pagination:{el:".swiper-pagination",clickable:!0,},})}
|
||||
var banner3=$(".slide-style-3 .swiper");if(banner3.length>0){var banner3=new Swiper(".slide-style-3 .swiper",{loop:!0,spaceBetween:15,autoplay:{delay:5000,disableOnInteraction:!1,},pagination:{el:".swiper-pagination",clickable:!0,},})}
|
||||
var banner4=$(".slide-style-4");if(banner4.length>0){var banner2=new Swiper(".slide-style-4",{loop:!0,spaceBetween:15,autoplay:{delay:5000,disableOnInteraction:!1,},pagination:{el:".swiper-pagination",clickable:!0,},})}
|
||||
var ajaxSwiper=$(".slide-ajax-menu");if(ajaxSwiper.length>0){var ajaxSwiper=new Swiper(".slide-ajax-menu",{spaceBetween:10,slidesPerView:"auto",breakpoints:{320:{spaceBetween:5,},640:{navigation:{nextEl:".slide-ajax-menu .button-next",prevEl:".slide-ajax-menu .button-prev",},},},})}
|
||||
var columnsSwiper=$(".index-columns-cat");if(columnsSwiper.length>0){var columnsSwiper=new Swiper(".index-columns-cat",{freeMode:!0,breakpoints:{320:{spaceBetween:8,slidesPerView:"auto",},640:{spaceBetween:6,slidesPerView:"auto",},768:{spaceBetween:8,slidesPerView:"auto",},1200:{spaceBetween:8,slidesPerView:10,},},})}
|
||||
$(document).on("click",".list-ajax-menu .btn-ajaxpost",function(event){event.preventDefault();var t=$(this);var cid=t.data("cid");$(".list-ajax-menu .btn-ajaxpost").removeClass("active");t.addClass("active");if(cid){$(".dposts-ajax-load").data("tabcid",cid)}else{$(".dposts-ajax-load").removeData("tabcid")}
|
||||
$(".dposts-ajax-load").data("paged",1);$("."+$(".dposts-ajax-load").data().append).html("");$(".dposts-ajax-load").addClass("loading").text(__("Load more...","pandapro"));$(".list-ajax-menu .btn-ajaxpost").attr("disabled","disabled");$(".dposts-ajax-load").removeAttr("disabled");ajax_load_posts($(".dposts-ajax-load").data(),function(){$(".list-ajax-menu .btn-ajaxpost").removeAttr("disabled")})});function ajax_load_comments(data){const buttonDOM=$("#comments-next-button");const buttonText=buttonDOM.text();buttonDOM.html(loadingSvg).attr("disabled","disabled");$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:data,}).done(function(response){if(response){if(data.commentspage=="newest"){buttonDOM.data("paged",data.paged*1-1)}else{buttonDOM.data("paged",data.paged*1+1)}
|
||||
$("."+data.append).append(response);buttonDOM.text(buttonText).removeAttr("disabled")}else{buttonDOM.hide()}})}
|
||||
if($(".toc").length>0){var headerEl="h2,h3,h4",content=".toc-class",idArr={};$(".post-content").find(headerEl).parent().addClass("toc-class");$(content).children(headerEl).each(function(){var headerId=$(this).text().replace(/[\s|\~|`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\||\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?|\:|\,|\。]/g,"");headerId=headerId.toLowerCase();if(idArr[headerId]){$(this).attr("id",headerId+"-"+idArr[headerId]);idArr[headerId]++}else{idArr[headerId]=1;$(this).attr("id",headerId)}});tocbot.init({tocSelector:".toc",contentSelector:content,headingSelector:headerEl,positionFixedSelector:".toc",positionFixedClass:"is-position-fixed",scrollSmooth:!0,scrollSmoothOffset:-100,headingsOffset:100,})}
|
||||
$(document).on("click","#comments-next-button",function(event){event.preventDefault();ajax_load_comments($("#comments-next-button").data())});$(document).on("click",'.post-like-button[data-action="like"]',function(event){event.preventDefault();var $this=$(".post-like-button");var id=$(this).data("id");if($this.hasClass("requesting")){return!1}
|
||||
$this.addClass("requesting");$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{action:"pandapro_like",id,like_action:"like"},}).done(function(data){$this.addClass("active");$this.attr("data-action","unlike");ncPopupTips(1,__("Thank you!","pandapro"));$(".like-count").html(data.trim());isApollo&&apolloAjaxPostLikeSection(id)}).always(function(){$this.removeClass("requesting")});return!1});$(document).on("click",'.post-like-button[data-action="unlike"]',function(event){event.preventDefault();var $this=$(".post-like-button");var id=$(this).data("id");if($this.hasClass("requesting")){return!1}
|
||||
$this.addClass("requesting");$this.removeClass("active");$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{action:"pandapro_like",id,like_action:"unlike"},}).done(function(data){$this.removeClass("active");$this.attr("data-action","like");ncPopupTips(0,__("Cancelled.","pandapro"));$(".like-count").html(data.trim());isApollo&&apolloAjaxPostLikeSection(id)}).always(function(){$this.removeClass("requesting")});return!1});function apolloAjaxPostLikeSection(id){$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{action:"ajax_apollo_userlike_section",id:id,},}).done(function(response){$("#apollo-postlike-section").length>0&&$("#apollo-postlike-section").remove();if(response.trim()){$(".post-actions").after(response)}})}
|
||||
$(document).on("click",".single-popup",function(event){event.preventDefault();var img=$(this).data("img");var title=$(this).data("title");var desc=$(this).data("desc");var html='<div class="text-center"><h6 class="py-1">'+title+'</h6>\
|
||||
<div class="text-muted text-sm mb-2" > '+desc+' </div>\
|
||||
<img src="'+img+'" alt="'+title+'" style="width:100%;height:auto;">\
|
||||
</div>';ncPopup("small",html)});$(document).on("click",".plus-power-popup",function(event){event.preventDefault();var $this=$("#plus-power-popup-wrap");ncPopup("no-padding",$this.html())});$(document).on("click",".btn-share-toggler",function(event){event.preventDefault();ncPopup("middle",$("#single-share-template").html())});function isElementInViewport(el){var rect=el.getBoundingClientRect();return(rect.top>=0&&rect.left>=0&&rect.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&rect.right<=(window.innerWidth||document.documentElement.clientWidth))}
|
||||
function givenElementInViewport(el,fn){return function(){if(isElementInViewport(el)){fn.call()}}}
|
||||
function addViewportEvent(el,fn){if(window.addEventListener){addEventListener("DOMContentLoaded",givenElementInViewport(el,fn),!1);addEventListener("load",givenElementInViewport(el,fn),!1);addEventListener("scroll",givenElementInViewport(el,fn),!1);addEventListener("resize",givenElementInViewport(el,fn),!1)}else if(window.attachEvent){attachEvent("DOMContentLoaded",givenElementInViewport(el,fn));attachEvent("load",givenElementInViewport(el,fn));attachEvent("scroll",givenElementInViewport(el,fn));attachEvent("resize",givenElementInViewport(el,fn))}}
|
||||
if($(".list-ajax-load").length>0){addViewportEvent(document.querySelector(".list-ajax-load"),function(){if($(".dposts-ajax-load").data("comments")=="comments"){return!1}
|
||||
if($(".list-ajax-load").hasClass("loading")===!1){var data=$(".dposts-ajax-load").data();if($(".dposts-ajax-load").data("paged")<=3){$(".list-ajax-load").addClass("loading");ajax_load_posts($(".dposts-ajax-load").data())}}})}
|
||||
$(document).on("click",".refresh-random-post",function(event){event.preventDefault();var $this=jQuery(this);$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{action:"ajax_refresh_random_post",id:$this.data().id,},}).done(function(response){if(response.trim()){$this.parents(".widget_post_card").html(response.trim())}})});if(globals.allow_switch_darkmode!=="0"){if(globals.allow_switch_darkmode==="device"&&window.matchMedia&&window.matchMedia("(prefers-color-scheme)").media!=="not all"){if(window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||
setDarkMode();window.matchMedia("(prefers-color-scheme: dark)").addListener(function(e){e.matches&&setDarkMode()});if(window.matchMedia("(prefers-color-scheme: light)").matches)
|
||||
setLightMode();window.matchMedia("(prefers-color-scheme: light)").addListener(function(e){e.matches&&setLightMode()})}
|
||||
$(document).on("click",".switch-dark-mode",function(event){event.preventDefault();$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:{toggle_action:$("body").hasClass("nice-dark-mode")===!0?"off":"on",action:"pandapro_toggle_dark_mode",},}).done(function(response){if(!$("body").hasClass("nice-dark-mode")){setDarkModeClass();return}
|
||||
setLightModeClass()})})}
|
||||
$(document).on("click",".dposts-ajax-load",function(event){event.preventDefault();var $this=jQuery(this);if($(".list-ajax-load").hasClass("loading")===!1){$(".list-ajax-load").addClass("loading");ajax_load_posts($this.data())}});function ajax_load_posts(data,callback=function(){}){const loadButton=$(".dposts-ajax-load");const listAjaxLoad=$(".list-ajax-load");if(loadButton.attr("disabled")){return!1}
|
||||
loadButton.html(loadingSvg).attr("disabled","disabled");$.ajax({url:globals.ajax_url,type:"POST",dataType:"html",data:data,}).done(function(response){callback();if(response.trim()){loadButton.removeAttr("disabled");loadButton.data("paged",data.paged*1+1);$("."+data.append).append(response);listAjaxLoad.removeClass("loading");loadButton.text(__("Load more...","pandapro"))}else{loadButton.attr("disabled","disabled");loadButton.text(__("You've reached the end.","pandapro"))}})}});console.log("\n"+" %c PandaPRO Designed by nicetheme® %c https://www.nicetheme.cn "+"\n","color: #fadfa3; background: #030307; padding:5px 0; font-size:12px;","background: #fadfa3; padding:5px 0; font-size:12px;")
|
||||
;
|
||||
@ -1,23 +0,0 @@
|
||||
if(typeof jQuery!="undefined"){var $=jQuery.noConflict()}
|
||||
function ncPopupTips(type,msg){var c=type?"success":"error";var icon=type?"<i class='icon me-2'></i>":"<i class='icon me-2'></i>";var html='<div class="nice-popup nice-popup-sm nice-popup-error '+c+'">'+'<div class="nice-popup-body">'+'<div class="nice-popup-content">'+icon+msg+"</div>"+"</div>"+"</div>";var tips=$(html);$("body").append(tips);setTimeout(function(){tips.addClass("nice-popup-open")},300);if(typeof lazyLoadInstance!=="undefined"){lazyLoadInstance.update()}
|
||||
setTimeout(function(){tips.removeClass("nice-popup-open");setTimeout(function(){setTimeout(function(){tips.remove()},600)},1000)},1600)}
|
||||
function ncPopup(type,html,maskStyle,btnCallBack){var maskStyle=maskStyle?'style="'+maskStyle+'"':"";var size="";if(type=="big"){size="nice-popup-lg"}else if(type=="no-padding"){size="nice-popup-nopd"}else if(type=="cover"){size="nice-popup-cover nice-popup-nopd"}else if(type=="full"){size="nice-popup-xl"}else if(type=="scroll"){size="nice-popup-scroll"}else if(type=="middle"){size="nice-popup-md"}else if(type=="small"){size="nice-popup-sm"}
|
||||
var template='\
|
||||
<div class="nice-popup nice-popup-center '+size+'">\
|
||||
<div class="nice-popup-overlay" '+maskStyle+'></div>\
|
||||
<div class="nice-popup-body">\
|
||||
<div class="nice-popup-close">\
|
||||
<span class="svg-white"></span>\
|
||||
<span class="svg-dark"></span>\
|
||||
</div>\
|
||||
<div class="nice-popup-content">\
|
||||
'+html+"\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
";var popup=$(template);$("body").append(popup);$("body").addClass("nice-popup-hidden");setTimeout(function(){popup.addClass("nice-popup-open")},300);if(typeof lazyLoadInstance!=="undefined"){lazyLoadInstance.update()}
|
||||
var close=function(){$("body").removeClass("nice-popup-hidden");$(popup).removeClass("nice-popup-open");setTimeout(function(){setTimeout(function(){popup.remove()},300)},600)};$(popup).on("click touchstart",".nice-popup-close, .nice-popup-overlay",function(event){event.preventDefault();close()});if(typeof btnCallBack=="object"){Object.keys(btnCallBack).forEach(function(key){$(popup).on("click touchstart",key,function(event){var ret=btnCallBack[key](event,close)})})}
|
||||
return popup}
|
||||
$(document).ready(function(){$(".post-video .wp-video").attr("style","");$(".post-video video").attr("width","100%");$(".post-video video").attr("height",null);if(typeof globals!=="undefined"&&globals.comment_ip==="1"){$(".author-ip").each(function(){var ip=$(this).data("ip")+"";var that=this;if(ip.split(".").length!==4)return;$.ajax({url:"https://ip-delta.vercel.app/"+ip,}).done(function(location){if(location&&location.length&&location.length>2){$(that).text(location[1]+" "+location[2])}})})}});function nicethemeResponsiveEmbeds(){var proportion,parentWidth;document.querySelectorAll('iframe').forEach(function(iframe){if(iframe.width&&iframe.height){proportion=parseFloat(iframe.width)/parseFloat(iframe.height);parentWidth=parseFloat(window.getComputedStyle(iframe.parentElement,null).width.replace('px',''));iframe.style.maxWidth='100%';iframe.style.maxHeight=Math.round(parentWidth/proportion).toString()+'px'}})}
|
||||
nicethemeResponsiveEmbeds();window.onresize=nicethemeResponsiveEmbeds
|
||||
;
|
||||
@ -1,3 +0,0 @@
|
||||
<?php
|
||||
echo 1;
|
||||
?>
|
||||
@ -1,3 +0,0 @@
|
||||
<?php
|
||||
echo 1;
|
||||
?>
|
||||
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 91 B |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 22 KiB |
@ -1,77 +0,0 @@
|
||||
/*!!
|
||||
* Matomo - free/libre analytics platform
|
||||
*
|
||||
* JavaScript tracking client
|
||||
*
|
||||
* @link https://piwik.org
|
||||
* @source https://github.com/matomo-org/matomo/blob/master/js/piwik.js
|
||||
* @license https://piwik.org/free-software/bsd/ BSD-3 Clause (also in js/LICENSE.txt)
|
||||
* @license magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt BSD-3-Clause
|
||||
*/
|
||||
;if(typeof _paq!=="object"){_paq=[]}if(typeof window.Matomo!=="object"){window.Matomo=window.Piwik=(function(){var s,b={},A={},K=document,g=navigator,ac=screen,X=window,h=X.performance||X.mozPerformance||X.msPerformance||X.webkitPerformance,u=X.encodeURIComponent,W=X.decodeURIComponent,k=unescape,M=[],I,v,am=[],z=0,ag=0,Y=0,m=false,q="";function p(au){try{return W(au)}catch(av){return unescape(au)}}function N(av){var au=typeof av;return au!=="undefined"}function D(au){return typeof au==="function"}function aa(au){return typeof au==="object"}function y(au){return typeof au==="string"||au instanceof String}function al(au){return typeof au==="number"||au instanceof Number
|
||||
}function ad(au){return N(au)&&(al(au)||(y(au)&&au.length))}function E(av){if(!av){return true}var au;for(au in av){if(Object.prototype.hasOwnProperty.call(av,au)){return false}}return true}function ap(au){var av=typeof console;if(av!=="undefined"&&console&&console.error){console.error(au)}}function ak(){var az,ay,aB,av,au;for(az=0;az<arguments.length;az+=1){au=null;if(arguments[az]&&arguments[az].slice){au=arguments[az].slice()}av=arguments[az];aB=av.shift();var aA,aw;var ax=y(aB)&&aB.indexOf("::")>0;if(ax){aA=aB.split("::");aw=aA[0];aB=aA[1];if("object"===typeof v[aw]&&"function"===typeof v[aw][aB]){v[aw][aB].apply(v[aw],av)}else{if(au){am.push(au)}}}else{for(ay=0;ay<M.length;ay++){if(y(aB)){aw=M[ay];var aC=aB.indexOf(".")>0;if(aC){aA=aB.split(".");if(aw&&"object"===typeof aw[aA[0]]){aw=aw[aA[0]];aB=aA[1]}else{if(au){am.push(au);break}}}if(aw[aB]){aw[aB].apply(aw,av)}else{var aD="The method '"+aB+'\' was not found in "_paq" variable. Please have a look at the Matomo tracker documentation: https://developer.matomo.org/api-reference/tracking-javascript';
|
||||
ap(aD);if(!aC){throw new TypeError(aD)}}if(aB==="addTracker"){break}if(aB==="setTrackerUrl"||aB==="setSiteId"){break}}else{aB.apply(M[ay],av)}}}}}function at(ax,aw,av,au){if(ax.addEventListener){ax.addEventListener(aw,av,au);return true}if(ax.attachEvent){return ax.attachEvent("on"+aw,av)}ax["on"+aw]=av}function n(au){if(K.readyState==="complete"){au()}else{if(X.addEventListener){X.addEventListener("load",au,false)}else{if(X.attachEvent){X.attachEvent("onload",au)}}}}function r(ax){var au=false;if(K.attachEvent){au=K.readyState==="complete"}else{au=K.readyState!=="loading"}if(au){ax();return}var aw;if(K.addEventListener){at(K,"DOMContentLoaded",function av(){K.removeEventListener("DOMContentLoaded",av,false);if(!au){au=true;ax()}})}else{if(K.attachEvent){K.attachEvent("onreadystatechange",function av(){if(K.readyState==="complete"){K.detachEvent("onreadystatechange",av);if(!au){au=true;ax()}}});if(K.documentElement.doScroll&&X===X.top){(function av(){if(!au){try{K.documentElement.doScroll("left")
|
||||
}catch(ay){setTimeout(av,0);return}au=true;ax()}}())}}}at(X,"load",function(){if(!au){au=true;ax()}},false)}function ah(av,aA,aB){if(!av){return""}var au="",ax,aw,ay,az;for(ax in b){if(Object.prototype.hasOwnProperty.call(b,ax)){az=b[ax]&&"function"===typeof b[ax][av];if(az){aw=b[ax][av];ay=aw(aA||{},aB);if(ay){au+=ay}}}}return au}function an(av){var au;m=true;ah("unload");au=new Date();var aw=au.getTimeAlias();if((s-aw)>3000){s=aw+3000}if(s){do{au=new Date()}while(au.getTimeAlias()<s)}}function o(aw,av){var au=K.createElement("script");au.type="text/javascript";au.src=aw;if(au.readyState){au.onreadystatechange=function(){var ax=this.readyState;if(ax==="loaded"||ax==="complete"){au.onreadystatechange=null;av()}}}else{au.onload=av}K.getElementsByTagName("head")[0].appendChild(au)}function O(){var au="";try{au=X.top.document.referrer}catch(aw){if(X.parent){try{au=X.parent.document.referrer}catch(av){au=""}}}if(au===""){au=K.referrer}return au}function t(au){var aw=new RegExp("^([a-z]+):"),av=aw.exec(au);
|
||||
return av?av[1]:null}function d(au){var aw=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),av=aw.exec(au);return av?av[1]:au}function H(au){return(/^[0-9][0-9]*(\.[0-9]+)?$/).test(au)}function R(aw,ax){var au={},av;for(av in aw){if(aw.hasOwnProperty(av)&&ax(aw[av])){au[av]=aw[av]}}return au}function C(aw){var au={},av;for(av in aw){if(aw.hasOwnProperty(av)){if(H(aw[av])){au[av]=Math.round(aw[av])}else{throw new Error('Parameter "'+av+'" provided value "'+aw[av]+'" is not valid. Please provide a numeric value.')}}}return au}function l(av){var aw="",au;for(au in av){if(av.hasOwnProperty(au)){aw+="&"+u(au)+"="+u(av[au])}}return aw}function ao(av,au){av=String(av);return av.lastIndexOf(au,0)===0}function V(av,au){av=String(av);return av.indexOf(au,av.length-au.length)!==-1}function B(av,au){av=String(av);return av.indexOf(au)!==-1}function f(av,au){av=String(av);return av.substr(0,av.length-au)}function J(ax,aw,az){ax=String(ax);if(!az){az=""}var au=ax.indexOf("#");var aA=ax.length;
|
||||
if(au===-1){au=aA}var ay=ax.substr(0,au);var av=ax.substr(au,aA-au);if(ay.indexOf("?")===-1){ay+="?"}else{if(!V(ay,"?")){ay+="&"}}return ay+u(aw)+"="+u(az)+av}function j(av,aw){av=String(av);if(av.indexOf("?"+aw+"=")===-1&&av.indexOf("&"+aw+"=")===-1&&av.indexOf("#"+aw+"=")===-1){return av}var aB="";var aD=av.indexOf("#");if(aD!==-1){aB=av.substr(aD+1);av=av.substr(0,aD)}var ax=av.indexOf("?");var au="";var aA=av;if(ax>-1){au=av.substr(ax+1);aA=av.substr(0,ax)}var az=function(aF){var aH;var aG=aF.length-1;for(aG;aG>=0;aG--){aH=aF[aG].split("=")[0];if(aH===aw){aF.splice(aG,1)}}return aF};if(au){var aC=az(au.split("&")).join("&");if(aC){aA+="?"+aC}}if(aB&&aB.indexOf("=")>0){var ay=aB.charAt(0)==="?";if(ay){aB=aB.substr(1)}var aE=az(aB.split("&")).join("&");if(aE){aA+="#";if(ay){aA+="?"}aA+=aE}}else{if(aB){aA+="#"+aB}}return aA}function e(aw,av){var au="[\\?&#]"+av+"=([^&#]*)";var ay=new RegExp(au);var ax=ay.exec(aw);return ax?p(ax[1]):""}function a(au){if(au&&String(au)===au){return au.replace(/^\s+|\s+$/g,"")
|
||||
}return au}function G(au){return unescape(u(au))}function ar(aJ){var aw=function(aP,aO){return(aP<<aO)|(aP>>>(32-aO))},aK=function(aR){var aP="",aQ,aO;for(aQ=7;aQ>=0;aQ--){aO=(aR>>>(aQ*4))&15;aP+=aO.toString(16)}return aP},az,aM,aL,av=[],aD=1732584193,aB=4023233417,aA=2562383102,ay=271733878,ax=3285377520,aI,aH,aG,aF,aE,aN,au,aC=[];aJ=G(aJ);au=aJ.length;for(aM=0;aM<au-3;aM+=4){aL=aJ.charCodeAt(aM)<<24|aJ.charCodeAt(aM+1)<<16|aJ.charCodeAt(aM+2)<<8|aJ.charCodeAt(aM+3);aC.push(aL)}switch(au&3){case 0:aM=2147483648;break;case 1:aM=aJ.charCodeAt(au-1)<<24|8388608;break;case 2:aM=aJ.charCodeAt(au-2)<<24|aJ.charCodeAt(au-1)<<16|32768;break;case 3:aM=aJ.charCodeAt(au-3)<<24|aJ.charCodeAt(au-2)<<16|aJ.charCodeAt(au-1)<<8|128;break}aC.push(aM);while((aC.length&15)!==14){aC.push(0)}aC.push(au>>>29);aC.push((au<<3)&4294967295);for(az=0;az<aC.length;az+=16){for(aM=0;aM<16;aM++){av[aM]=aC[az+aM]}for(aM=16;aM<=79;aM++){av[aM]=aw(av[aM-3]^av[aM-8]^av[aM-14]^av[aM-16],1)}aI=aD;aH=aB;aG=aA;aF=ay;aE=ax;for(aM=0;
|
||||
aM<=19;aM++){aN=(aw(aI,5)+((aH&aG)|(~aH&aF))+aE+av[aM]+1518500249)&4294967295;aE=aF;aF=aG;aG=aw(aH,30);aH=aI;aI=aN}for(aM=20;aM<=39;aM++){aN=(aw(aI,5)+(aH^aG^aF)+aE+av[aM]+1859775393)&4294967295;aE=aF;aF=aG;aG=aw(aH,30);aH=aI;aI=aN}for(aM=40;aM<=59;aM++){aN=(aw(aI,5)+((aH&aG)|(aH&aF)|(aG&aF))+aE+av[aM]+2400959708)&4294967295;aE=aF;aF=aG;aG=aw(aH,30);aH=aI;aI=aN}for(aM=60;aM<=79;aM++){aN=(aw(aI,5)+(aH^aG^aF)+aE+av[aM]+3395469782)&4294967295;aE=aF;aF=aG;aG=aw(aH,30);aH=aI;aI=aN}aD=(aD+aI)&4294967295;aB=(aB+aH)&4294967295;aA=(aA+aG)&4294967295;ay=(ay+aF)&4294967295;ax=(ax+aE)&4294967295}aN=aK(aD)+aK(aB)+aK(aA)+aK(ay)+aK(ax);return aN.toLowerCase()}function af(aw,au,av){if(!aw){aw=""}if(!au){au=""}if(aw==="translate.googleusercontent.com"){if(av===""){av=au}au=e(au,"u");aw=d(au)}else{if(aw==="cc.bingj.com"||aw==="webcache.googleusercontent.com"||aw.slice(0,5)==="74.6."){au=K.links[0].href;aw=d(au)}}return[aw,au,av]}function P(av){var au=av.length;if(av.charAt(--au)==="."){av=av.slice(0,au)}if(av.slice(0,2)==="*."){av=av.slice(1)
|
||||
}if(av.indexOf("/")!==-1){av=av.substr(0,av.indexOf("/"))}return av}function aq(av){av=av&&av.text?av.text:av;if(!y(av)){var au=K.getElementsByTagName("title");if(au&&N(au[0])){av=au[0].text}}return av}function T(au){if(!au){return[]}if(!N(au.children)&&N(au.childNodes)){return au.children}if(N(au.children)){return au.children}return[]}function Z(av,au){if(!av||!au){return false}if(av.contains){return av.contains(au)}if(av===au){return true}if(av.compareDocumentPosition){return !!(av.compareDocumentPosition(au)&16)}return false}function Q(aw,ax){if(aw&&aw.indexOf){return aw.indexOf(ax)}if(!N(aw)||aw===null){return -1}if(!aw.length){return -1}var au=aw.length;if(au===0){return -1}var av=0;while(av<au){if(aw[av]===ax){return av}av++}return -1}function i(aw){if(!aw){return false}function au(ay,az){if(X.getComputedStyle){return K.defaultView.getComputedStyle(ay,null)[az]}if(ay.currentStyle){return ay.currentStyle[az]}}function ax(ay){ay=ay.parentNode;while(ay){if(ay===K){return true}ay=ay.parentNode
|
||||
}return false}function av(aA,aG,ay,aD,aB,aE,aC){var az=aA.parentNode,aF=1;if(!ax(aA)){return false}if(9===az.nodeType){return true}if("0"===au(aA,"opacity")||"none"===au(aA,"display")||"hidden"===au(aA,"visibility")){return false}if(!N(aG)||!N(ay)||!N(aD)||!N(aB)||!N(aE)||!N(aC)){aG=aA.offsetTop;aB=aA.offsetLeft;aD=aG+aA.offsetHeight;ay=aB+aA.offsetWidth;aE=aA.offsetWidth;aC=aA.offsetHeight}if(aw===aA&&(0===aC||0===aE)&&"hidden"===au(aA,"overflow")){return false}if(az){if(("hidden"===au(az,"overflow")||"scroll"===au(az,"overflow"))){if(aB+aF>az.offsetWidth+az.scrollLeft||aB+aE-aF<az.scrollLeft||aG+aF>az.offsetHeight+az.scrollTop||aG+aC-aF<az.scrollTop){return false}}if(aA.offsetParent===az){aB+=az.offsetLeft;aG+=az.offsetTop}return av(az,aG,ay,aD,aB,aE,aC)}return true}return av(aw)}var aj={htmlCollectionToArray:function(aw){var au=[],av;if(!aw||!aw.length){return au}for(av=0;av<aw.length;av++){au.push(aw[av])}return au},find:function(au){if(!document.querySelectorAll||!au){return[]}var av=document.querySelectorAll(au);
|
||||
return this.htmlCollectionToArray(av)},findMultiple:function(aw){if(!aw||!aw.length){return[]}var av,ax;var au=[];for(av=0;av<aw.length;av++){ax=this.find(aw[av]);au=au.concat(ax)}au=this.makeNodesUnique(au);return au},findNodesByTagName:function(av,au){if(!av||!au||!av.getElementsByTagName){return[]}var aw=av.getElementsByTagName(au);return this.htmlCollectionToArray(aw)},makeNodesUnique:function(au){var az=[].concat(au);au.sort(function(aB,aA){if(aB===aA){return 0}var aD=Q(az,aB);var aC=Q(az,aA);if(aD===aC){return 0}return aD>aC?-1:1});if(au.length<=1){return au}var av=0;var ax=0;var ay=[];var aw;aw=au[av++];while(aw){if(aw===au[av]){ax=ay.push(av)}aw=au[av++]||null}while(ax--){au.splice(ay[ax],1)}return au},getAttributeValueFromNode:function(ay,aw){if(!this.hasNodeAttribute(ay,aw)){return}if(ay&&ay.getAttribute){return ay.getAttribute(aw)}if(!ay||!ay.attributes){return}var ax=(typeof ay.attributes[aw]);if("undefined"===ax){return}if(ay.attributes[aw].value){return ay.attributes[aw].value
|
||||
}if(ay.attributes[aw].nodeValue){return ay.attributes[aw].nodeValue}var av;var au=ay.attributes;if(!au){return}for(av=0;av<au.length;av++){if(au[av].nodeName===aw){return au[av].nodeValue}}return null},hasNodeAttributeWithValue:function(av,au){var aw=this.getAttributeValueFromNode(av,au);return !!aw},hasNodeAttribute:function(aw,au){if(aw&&aw.hasAttribute){return aw.hasAttribute(au)}if(aw&&aw.attributes){var av=(typeof aw.attributes[au]);return"undefined"!==av}return false},hasNodeCssClass:function(aw,au){if(aw&&au&&aw.className){var av=typeof aw.className==="string"?aw.className.split(" "):[];if(-1!==Q(av,au)){return true}}return false},findNodesHavingAttribute:function(ay,aw,au){if(!au){au=[]}if(!ay||!aw){return au}var ax=T(ay);if(!ax||!ax.length){return au}var av,az;for(av=0;av<ax.length;av++){az=ax[av];if(this.hasNodeAttribute(az,aw)){au.push(az)}au=this.findNodesHavingAttribute(az,aw,au)}return au},findFirstNodeHavingAttribute:function(aw,av){if(!aw||!av){return}if(this.hasNodeAttribute(aw,av)){return aw
|
||||
}var au=this.findNodesHavingAttribute(aw,av);if(au&&au.length){return au[0]}},findFirstNodeHavingAttributeWithValue:function(ax,aw){if(!ax||!aw){return}if(this.hasNodeAttributeWithValue(ax,aw)){return ax}var au=this.findNodesHavingAttribute(ax,aw);if(!au||!au.length){return}var av;for(av=0;av<au.length;av++){if(this.getAttributeValueFromNode(au[av],aw)){return au[av]}}},findNodesHavingCssClass:function(ay,ax,au){if(!au){au=[]}if(!ay||!ax){return au}if(ay.getElementsByClassName){var az=ay.getElementsByClassName(ax);return this.htmlCollectionToArray(az)}var aw=T(ay);if(!aw||!aw.length){return[]}var av,aA;for(av=0;av<aw.length;av++){aA=aw[av];if(this.hasNodeCssClass(aA,ax)){au.push(aA)}au=this.findNodesHavingCssClass(aA,ax,au)}return au},findFirstNodeHavingClass:function(aw,av){if(!aw||!av){return}if(this.hasNodeCssClass(aw,av)){return aw}var au=this.findNodesHavingCssClass(aw,av);if(au&&au.length){return au[0]}},isLinkElement:function(av){if(!av){return false}var au=String(av.nodeName).toLowerCase();
|
||||
var ax=["a","area"];var aw=Q(ax,au);return aw!==-1},setAnyAttribute:function(av,au,aw){if(!av||!au){return}if(av.setAttribute){av.setAttribute(au,aw)}else{av[au]=aw}}};var x={CONTENT_ATTR:"data-track-content",CONTENT_CLASS:"matomoTrackContent",LEGACY_CONTENT_CLASS:"piwikTrackContent",CONTENT_NAME_ATTR:"data-content-name",CONTENT_PIECE_ATTR:"data-content-piece",CONTENT_PIECE_CLASS:"matomoContentPiece",LEGACY_CONTENT_PIECE_CLASS:"piwikContentPiece",CONTENT_TARGET_ATTR:"data-content-target",CONTENT_TARGET_CLASS:"matomoContentTarget",LEGACY_CONTENT_TARGET_CLASS:"piwikContentTarget",CONTENT_IGNOREINTERACTION_ATTR:"data-content-ignoreinteraction",CONTENT_IGNOREINTERACTION_CLASS:"matomoContentIgnoreInteraction",LEGACY_CONTENT_IGNOREINTERACTION_CLASS:"piwikContentIgnoreInteraction",location:undefined,findContentNodes:function(){var av="."+this.CONTENT_CLASS;var aw="."+this.LEGACY_CONTENT_CLASS;var au="["+this.CONTENT_ATTR+"]";var ax=aj.findMultiple([av,aw,au]);return ax},findContentNodesWithinNode:function(ax){if(!ax){return[]
|
||||
}var av=aj.findNodesHavingCssClass(ax,this.CONTENT_CLASS);av=aj.findNodesHavingCssClass(ax,this.LEGACY_CONTENT_CLASS,av);var au=aj.findNodesHavingAttribute(ax,this.CONTENT_ATTR);if(au&&au.length){var aw;for(aw=0;aw<au.length;aw++){av.push(au[aw])}}if(aj.hasNodeAttribute(ax,this.CONTENT_ATTR)){av.push(ax)}else{if(aj.hasNodeCssClass(ax,this.CONTENT_CLASS)){av.push(ax)}else{if(aj.hasNodeCssClass(ax,this.LEGACY_CONTENT_CLASS)){av.push(ax)}}}av=aj.makeNodesUnique(av);return av},findParentContentNode:function(av){if(!av){return}var aw=av;var au=0;while(aw&&aw!==K&&aw.parentNode){if(aj.hasNodeAttribute(aw,this.CONTENT_ATTR)){return aw}if(aj.hasNodeCssClass(aw,this.CONTENT_CLASS)){return aw}if(aj.hasNodeCssClass(aw,this.LEGACY_CONTENT_CLASS)){return aw}aw=aw.parentNode;if(au>1000){break}au++}},findPieceNode:function(av){var au;au=aj.findFirstNodeHavingAttribute(av,this.CONTENT_PIECE_ATTR);if(!au){au=aj.findFirstNodeHavingClass(av,this.CONTENT_PIECE_CLASS)}if(!au){au=aj.findFirstNodeHavingClass(av,this.LEGACY_CONTENT_PIECE_CLASS)
|
||||
}if(au){return au}return av},findTargetNodeNoDefault:function(au){if(!au){return}var av=aj.findFirstNodeHavingAttributeWithValue(au,this.CONTENT_TARGET_ATTR);if(av){return av}av=aj.findFirstNodeHavingAttribute(au,this.CONTENT_TARGET_ATTR);if(av){return av}av=aj.findFirstNodeHavingClass(au,this.CONTENT_TARGET_CLASS);if(av){return av}av=aj.findFirstNodeHavingClass(au,this.LEGACY_CONTENT_TARGET_CLASS);if(av){return av}},findTargetNode:function(au){var av=this.findTargetNodeNoDefault(au);if(av){return av}return au},findContentName:function(av){if(!av){return}var ay=aj.findFirstNodeHavingAttributeWithValue(av,this.CONTENT_NAME_ATTR);if(ay){return aj.getAttributeValueFromNode(ay,this.CONTENT_NAME_ATTR)}var au=this.findContentPiece(av);if(au){return this.removeDomainIfIsInLink(au)}if(aj.hasNodeAttributeWithValue(av,"title")){return aj.getAttributeValueFromNode(av,"title")}var aw=this.findPieceNode(av);if(aj.hasNodeAttributeWithValue(aw,"title")){return aj.getAttributeValueFromNode(aw,"title")}var ax=this.findTargetNode(av);
|
||||
if(aj.hasNodeAttributeWithValue(ax,"title")){return aj.getAttributeValueFromNode(ax,"title")}},findContentPiece:function(av){if(!av){return}var ax=aj.findFirstNodeHavingAttributeWithValue(av,this.CONTENT_PIECE_ATTR);if(ax){return aj.getAttributeValueFromNode(ax,this.CONTENT_PIECE_ATTR)}var au=this.findPieceNode(av);var aw=this.findMediaUrlInNode(au);if(aw){return this.toAbsoluteUrl(aw)}},findContentTarget:function(aw){if(!aw){return}var ax=this.findTargetNode(aw);if(aj.hasNodeAttributeWithValue(ax,this.CONTENT_TARGET_ATTR)){return aj.getAttributeValueFromNode(ax,this.CONTENT_TARGET_ATTR)}var av;if(aj.hasNodeAttributeWithValue(ax,"href")){av=aj.getAttributeValueFromNode(ax,"href");return this.toAbsoluteUrl(av)}var au=this.findPieceNode(aw);if(aj.hasNodeAttributeWithValue(au,"href")){av=aj.getAttributeValueFromNode(au,"href");return this.toAbsoluteUrl(av)}},isSameDomain:function(au){if(!au||!au.indexOf){return false}if(0===au.indexOf(this.getLocation().origin)){return true}var av=au.indexOf(this.getLocation().host);
|
||||
if(8>=av&&0<=av){return true}return false},removeDomainIfIsInLink:function(aw){var av="^https?://[^/]+";var au="^.*//[^/]+";if(aw&&aw.search&&-1!==aw.search(new RegExp(av))&&this.isSameDomain(aw)){aw=aw.replace(new RegExp(au),"");if(!aw){aw="/"}}return aw},findMediaUrlInNode:function(ay){if(!ay){return}var aw=["img","embed","video","audio"];var au=ay.nodeName.toLowerCase();if(-1!==Q(aw,au)&&aj.findFirstNodeHavingAttributeWithValue(ay,"src")){var ax=aj.findFirstNodeHavingAttributeWithValue(ay,"src");return aj.getAttributeValueFromNode(ax,"src")}if(au==="object"&&aj.hasNodeAttributeWithValue(ay,"data")){return aj.getAttributeValueFromNode(ay,"data")}if(au==="object"){var az=aj.findNodesByTagName(ay,"param");if(az&&az.length){var av;for(av=0;av<az.length;av++){if("movie"===aj.getAttributeValueFromNode(az[av],"name")&&aj.hasNodeAttributeWithValue(az[av],"value")){return aj.getAttributeValueFromNode(az[av],"value")}}}var aA=aj.findNodesByTagName(ay,"embed");if(aA&&aA.length){return this.findMediaUrlInNode(aA[0])
|
||||
}}},trim:function(au){return a(au)},isOrWasNodeInViewport:function(az){if(!az||!az.getBoundingClientRect||az.nodeType!==1){return true}var ay=az.getBoundingClientRect();var ax=K.documentElement||{};var aw=ay.top<0;if(aw&&az.offsetTop){aw=(az.offsetTop+ay.height)>0}var av=ax.clientWidth;if(X.innerWidth&&av>X.innerWidth){av=X.innerWidth}var au=ax.clientHeight;if(X.innerHeight&&au>X.innerHeight){au=X.innerHeight}return((ay.bottom>0||aw)&&ay.right>0&&ay.left<av&&((ay.top<au)||aw))},isNodeVisible:function(av){var au=i(av);var aw=this.isOrWasNodeInViewport(av);return au&&aw},buildInteractionRequestParams:function(au,av,aw,ax){var ay="";if(au){ay+="c_i="+u(au)}if(av){if(ay){ay+="&"}ay+="c_n="+u(av)}if(aw){if(ay){ay+="&"}ay+="c_p="+u(aw)}if(ax){if(ay){ay+="&"}ay+="c_t="+u(ax)}if(ay){ay+="&ca=1"}return ay},buildImpressionRequestParams:function(au,av,aw){var ax="c_n="+u(au)+"&c_p="+u(av);if(aw){ax+="&c_t="+u(aw)}if(ax){ax+="&ca=1"}return ax},buildContentBlock:function(aw){if(!aw){return}var au=this.findContentName(aw);
|
||||
var av=this.findContentPiece(aw);var ax=this.findContentTarget(aw);au=this.trim(au);av=this.trim(av);ax=this.trim(ax);return{name:au||"Unknown",piece:av||"Unknown",target:ax||""}},collectContent:function(ax){if(!ax||!ax.length){return[]}var aw=[];var au,av;for(au=0;au<ax.length;au++){av=this.buildContentBlock(ax[au]);if(N(av)){aw.push(av)}}return aw},setLocation:function(au){this.location=au},getLocation:function(){var au=this.location||X.location;if(!au.origin){au.origin=au.protocol+"//"+au.hostname+(au.port?":"+au.port:"")}return au},toAbsoluteUrl:function(av){if((!av||String(av)!==av)&&av!==""){return av}if(""===av){return this.getLocation().href}if(av.search(/^\/\//)!==-1){return this.getLocation().protocol+av}if(av.search(/:\/\//)!==-1){return av}if(0===av.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+av}if(0===av.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+av}if(0===av.search("^[a-zA-Z]{2,11}:")){return av}if(av.search(/^\//)!==-1){return this.getLocation().origin+av
|
||||
}var au="(.*/)";var aw=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(au))[0];return aw+av},isUrlToCurrentDomain:function(av){var aw=this.toAbsoluteUrl(av);if(!aw){return false}var au=this.getLocation().origin;if(au===aw){return true}if(0===String(aw).indexOf(au)){if(":"===String(aw).substr(au.length,1)){return false}return true}return false},setHrefAttribute:function(av,au){if(!av||!au){return}aj.setAnyAttribute(av,"href",au)},shouldIgnoreInteraction:function(au){if(aj.hasNodeAttribute(au,this.CONTENT_IGNOREINTERACTION_ATTR)){return true}if(aj.hasNodeCssClass(au,this.CONTENT_IGNOREINTERACTION_CLASS)){return true}if(aj.hasNodeCssClass(au,this.LEGACY_CONTENT_IGNOREINTERACTION_CLASS)){return true}return false}};function ab(av,ay){if(ay){return ay}av=x.toAbsoluteUrl(av);if(B(av,"?")){var ax=av.indexOf("?");av=av.slice(0,ax)}if(V(av,"matomo.php")){av=f(av,"matomo.php".length)}else{if(V(av,"piwik.php")){av=f(av,"piwik.php".length)}else{if(V(av,".php")){var au=av.lastIndexOf("/");
|
||||
var aw=1;av=av.slice(0,au+aw)}}}if(V(av,"/js/")){av=f(av,"js/".length)}return av}function S(aA){var aC="Matomo_Overlay";var av=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=[^&]*)?");var aw=av.exec(K.referrer);if(aw){var ay=aw[1];if(ay!==String(aA)){return false}var az=aw[2],au=aw[3],ax=aw[4];if(!ax){ax=""}else{if(ax.indexOf("&segment=")===0){ax=ax.substr("&segment=".length)}}X.name=aC+"###"+az+"###"+au+"###"+ax}var aB=X.name.split("###");return aB.length===4&&aB[0]===aC}function ae(av,aA,aw){var az=X.name.split("###"),ay=az[1],au=az[2],ax=az[3],aB=ab(av,aA);o(aB+"plugins/Overlay/client/client.js?v=1",function(){Matomo_Overlay_Client.initialize(aB,aw,ay,au,ax)})}function w(){var aw;try{aw=X.frameElement}catch(av){return true}if(N(aw)){return(aw&&String(aw.nodeName).toLowerCase()==="iframe")?true:false}try{return X.self!==X.top}catch(au){return true}}function U(ct,cn){var bV=this,bo="mtm_consent",c1="mtm_cookie_consent",da="mtm_consent_removed",ch=af(K.domain,X.location.href,O()),di=P(ch[0]),bZ=p(ch[1]),bA=p(ch[2]),dg=false,cx="GET",dC=cx,aQ="application/x-www-form-urlencoded; charset=UTF-8",cR=aQ,aM=ct||"",bU="",dr="",cD="",cj=cn||"",bL="",b0="",bf,bu="",dy=["7z","aac","apk","arc","arj","asc","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","md5","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","rtf","sea","sha","sha256","sha512","sig","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","xz","z","zip"],aG=[di],bM=[],cS=[".paypal.com"],cy=[],bY=[],bj=[],bW=500,dl=true,c7,bg,b4,b1,aw,cH=["pk_campaign","mtm_campaign","piwik_campaign","matomo_campaign","utm_campaign","utm_source","utm_medium"],bT=["pk_kwd","mtm_kwd","piwik_kwd","matomo_kwd","utm_term"],cV=["mtm_campaign","matomo_campaign","mtm_cpn","pk_campaign","piwik_campaign","pk_cpn","utm_campaign","mtm_keyword","matomo_kwd","mtm_kwd","pk_keyword","piwik_kwd","pk_kwd","utm_term","mtm_source","pk_source","utm_source","mtm_medium","pk_medium","utm_medium","mtm_content","pk_content","utm_content","mtm_cid","pk_cid","utm_id","mtm_clid","mtm_group","pk_group","mtm_placement","pk_placement"],bv="_pk_",aD="pk_vid",ba=180,dp,bC,b5=false,aR="Lax",bx=false,de,bp,dm=true,bI,c8=33955200000,cE=1800000,dx=15768000000,bd=true,bR=false,bs=false,b3=false,aZ=false,cq,b9={},cC={},bz={},bG=200,cN={},ds={},dz={},a3={},co=[],by=false,ck=false,cp=[],cu=false,cZ=false,ax=false,dA=false,db=false,aW=false,bn=w(),cT=null,dq=null,a0,bO,cl=ar,bB,aU,bN=false,cK=0,bH=["id","ses","cvar","ref"],cY=false,bP=null,c9=[],cM=[],aF=Y++,aE=false,dn=true,cW=false;
|
||||
try{bu=K.title}catch(cU){bu=""}function aL(dN){if(bx&&dN!==da){return 0}var dL=new RegExp("(^|;)[ ]*"+dN+"=([^;]*)"),dM=dL.exec(K.cookie);return dM?W(dM[2]):0}bP=!aL(da);function dG(dP,dQ,dT,dS,dN,dO,dR){if(bx&&dP!==da){return}var dM;if(dT){dM=new Date();dM.setTime(dM.getTime()+dT)}if(!dR){dR="Lax"}K.cookie=dP+"="+u(dQ)+(dT?";expires="+dM.toGMTString():"")+";path="+(dS||"/")+(dN?";domain="+dN:"")+(dO?";secure":"")+";SameSite="+dR;if((!dT||dT>=0)&&aL(dP)!==String(dQ)){var dL="There was an error setting cookie `"+dP+"`. Please check domain and path.";ap(dL)}}function cf(dL){var dN,dM;if(dm!==true&&!cY){for(dM=0;dM<cH.length;dM++){dL=j(dL,cH[dM])}for(dM=0;dM<bT.length;dM++){dL=j(dL,bT[dM])}for(dM=0;dM<cV.length;dM++){dL=j(dL,cV[dM])}}dL=j(dL,aD);dL=j(dL,"ignore_referrer");dL=j(dL,"ignore_referer");for(dM=0;dM<cy.length;dM++){dL=j(dL,cy[dM])}if(b1){dN=new RegExp("#.*");return dL.replace(dN,"")}return dL}function b8(dN,dL){var dO=t(dL),dM;if(dO){return dL}if(dL.slice(0,1)==="/"){return t(dN)+"://"+d(dN)+dL
|
||||
}dN=cf(dN);dM=dN.indexOf("?");if(dM>=0){dN=dN.slice(0,dM)}dM=dN.lastIndexOf("/");if(dM!==dN.length-1){dN=dN.slice(0,dM+1)}return dN+dL}function c5(dN,dL){var dM;dN=String(dN).toLowerCase();dL=String(dL).toLowerCase();if(dN===dL){return true}if(dL.slice(0,1)==="."){if(dN===dL.slice(1)){return true}dM=dN.length-dL.length;if((dM>0)&&(dN.slice(dM)===dL)){return true}}return false}function cB(dL){var dM=document.createElement("a");if(dL.indexOf("//")!==0&&dL.indexOf("http")!==0){if(dL.indexOf("*")===0){dL=dL.substr(1)}if(dL.indexOf(".")===0){dL=dL.substr(1)}dL="http://"+dL}dM.href=x.toAbsoluteUrl(dL);if(dM.pathname){return dM.pathname}return""}function be(dM,dL){if(!ao(dL,"/")){dL="/"+dL}if(!ao(dM,"/")){dM="/"+dM}var dN=(dL==="/"||dL==="/*");if(dN){return true}if(dM===dL){return true}dL=String(dL).toLowerCase();dM=String(dM).toLowerCase();if(V(dL,"*")){dL=dL.slice(0,-1);dN=(!dL||dL==="/");if(dN){return true}if(dM===dL){return true}return dM.indexOf(dL)===0}if(!V(dM,"/")){dM+="/"}if(!V(dL,"/")){dL+="/"
|
||||
}return dM.indexOf(dL)===0}function aA(dP,dR){var dM,dL,dN,dO,dQ;for(dM=0;dM<aG.length;dM++){dO=P(aG[dM]);dQ=cB(aG[dM]);if(c5(dP,dO)&&be(dR,dQ)){return true}}return false}function a6(dO){var dM,dL,dN;for(dM=0;dM<aG.length;dM++){dL=P(aG[dM].toLowerCase());if(dO===dL){return true}if(dL.slice(0,1)==="."){if(dO===dL.slice(1)){return true}dN=dO.length-dL.length;if((dN>0)&&(dO.slice(dN)===dL)){return true}}}return false}function cJ(dL){var dM,dO,dQ,dN,dP;if(!dL.length||!cS.length){return false}dO=d(dL);dQ=cB(dL);if(dO.indexOf("www.")===0){dO=dO.substr(4)}for(dM=0;dM<cS.length;dM++){dN=P(cS[dM]);dP=cB(cS[dM]);if(dN.indexOf("www.")===0){dN=dN.substr(4)}if(c5(dO,dN)&&be(dQ,dP)){return true}}return false}function au(){if(q&&q.length>0){return true}q=e(X.location.href,"tracker_install_check");return q&&q.length>0}function cI(){if(au()&&aa(X)){X.close()}}function cF(dL,dN){dL=dL.replace("send_image=0","send_image=1");var dM=new Image(1,1);dM.onload=function(){I=0;if(typeof dN==="function"){dN({request:dL,trackerUrl:aM,success:true})
|
||||
}};dM.onerror=function(){if(typeof dN==="function"){dN({request:dL,trackerUrl:aM,success:false})}};dM.src=aM+(aM.indexOf("?")<0?"?":"&")+dL;cI()}function c2(dL){if(dC==="POST"){return true}return dL&&(dL.length>2000||dL.indexOf('{"requests"')===0)}function aT(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob}function bh(dP,dS,dR){var dN=aT();if(!dN){return false}var dO={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dT=false;var dM=aM;try{var dL=new Blob([dP],dO);if(dR&&!c2(dP)){dL=new Blob([],dO);dM=dM+(dM.indexOf("?")<0?"?":"&")+dP}dT=g.sendBeacon(dM,dL)}catch(dQ){return false}if(dT&&typeof dS==="function"){dS({request:dP,trackerUrl:aM,success:true,isSendBeacon:true})}cI();return dT}function dw(dM,dN,dL){if(!N(dL)||null===dL){dL=true}if(m&&bh(dM,dN,dL)){return}setTimeout(function(){if(m&&bh(dM,dN,dL)){return}var dQ;try{var dP=X.XMLHttpRequest?new X.XMLHttpRequest():X.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dP.open("POST",aM,true);
|
||||
dP.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dR=m&&bh(dM,dN,dL);if(!dR&&dL){cF(dM,dN)}else{if(typeof dN==="function"){dN({request:dM,trackerUrl:aM,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dN==="function")){dN({request:dM,trackerUrl:aM,success:true,xhr:this})}}};dP.setRequestHeader("Content-Type",cR);dP.withCredentials=true;dP.send(dM)}catch(dO){dQ=m&&bh(dM,dN,dL);if(!dQ&&dL){cF(dM,dN)}else{if(typeof dN==="function"){dN({request:dM,trackerUrl:aM,success:false})}}}cI()},50)}function cv(dM){var dL=new Date();var dN=dL.getTime()+dM;if(!s||dN>s){s=dN}}function bl(){bn=true;cT=new Date().getTime()}function dF(){var dL=new Date().getTime();return !cT||(dL-cT)>bg}function aH(){if(dF()){b4()}}function a5(){if(K.visibilityState==="hidden"&&dF()){b4()}else{if(K.visibilityState==="visible"){cT=new Date().getTime()}}}function dJ(){if(aW||!bg){return}aW=true;at(X,"focus",bl);at(X,"blur",aH);at(X,"visibilitychange",a5);ag++;v.addPlugin("HeartBeat"+ag,{unload:function(){if(aW&&dF()){b4()
|
||||
}}})}function c0(dP){var dM=new Date();var dL=dM.getTime();dq=dL;if(cZ&&dL<cZ){var dN=cZ-dL;setTimeout(dP,dN);cv(dN+50);cZ+=50;return}if(cZ===false){var dO=800;cZ=dL+dO}dP()}function aX(){if(aL(da)){bP=false}else{if(aL(bo)){bP=true}}}function b2(dO){var dN,dM="",dL="";for(dN in dz){if(Object.prototype.hasOwnProperty.call(dz,dN)){dL+="&"+dN+"="+dz[dN]}}if(a3){dM="&uadata="+u(X.JSON.stringify(a3))}if(dO instanceof Array){for(dN=0;dN<dO.length;dN++){dO[dN]+=dM+dL}}else{dO+=dM+dL}return dO}function av(){return N(g.userAgentData)&&D(g.userAgentData.getHighEntropyValues)}function cG(dL){if(by||ck){return}ck=true;a3={brands:g.userAgentData.brands,platform:g.userAgentData.platform};g.userAgentData.getHighEntropyValues(["brands","model","platform","platformVersion","uaFullVersion","fullVersionList"]).then(function(dN){var dM;if(dN.fullVersionList){delete dN.brands;delete dN.uaFullVersion}a3=dN;by=true;ck=false;dL()},function(dM){by=true;ck=false;dL()})}function bS(dM,dL,dN){aX();if(!bP){c9.push([dM,dN]);
|
||||
return}if(dn&&!by&&av()){co.push([dM,dN]);return}aE=true;if(!de&&dM){if(cY&&bP){dM+="&consent=1"}dM=b2(dM);c0(function(){if(dl&&bh(dM,dN,true)){cv(100);return}if(c2(dM)){dw(dM,dN)}else{cF(dM,dN)}cv(dL)})}if(!aW){dJ()}}function cA(dL){if(de){return false}return(dL&&dL.length)}function dv(dL,dP){if(!dP||dP>=dL.length){return[dL]}var dM=0;var dN=dL.length;var dO=[];for(dM;dM<dN;dM+=dP){dO.push(dL.slice(dM,dM+dP))}return dO}function dH(dM,dL){if(!cA(dM)){return}if(dn&&!by&&av()){co.push([dM,null]);return}if(!bP){c9.push([dM,null]);return}aE=true;c0(function(){var dP=dv(dM,50);var dN=0,dO;for(dN;dN<dP.length;dN++){dO='{"requests":["?'+b2(dP[dN]).join('","?')+'"],"send_image":0}';if(dl&&bh(dO,null,false)){cv(100)}else{dw(dO,null,false)}}cv(dL)})}function a2(dL){return bv+dL+"."+cj+"."+bB}function cc(dN,dM,dL){dG(dN,"",-129600000,dM,dL)}function ci(){if(bx){return"0"}if(!N(X.showModalDialog)&&N(g.cookieEnabled)){return g.cookieEnabled?"1":"0"}var dL=bv+"testcookie";dG(dL,"1",undefined,bC,dp,b5,aR);
|
||||
var dM=aL(dL)==="1"?"1":"0";cc(dL);return dM}function bt(){bB=cl((dp||di)+(bC||"/")).slice(0,4)}function ay(){var dM,dL;for(dM=0;dM<co.length;dM++){dL=typeof co[dM][0];if(dL==="string"){bS(co[dM][0],bW,co[dM][1])}else{if(dL==="object"){dH(co[dM][0],bW)}}}co=[]}function c6(){if(!dn){return{}}if(av()){cG(ay)}if(N(dz.res)){return dz}var dM,dO,dP={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",fla:"application/x-shockwave-flash",java:"application/x-java-vm",ag:"application/x-silverlight"};if(!((new RegExp("MSIE")).test(g.userAgent))){if(g.mimeTypes&&g.mimeTypes.length){for(dM in dP){if(Object.prototype.hasOwnProperty.call(dP,dM)){dO=g.mimeTypes[dP[dM]];dz[dM]=(dO&&dO.enabledPlugin)?"1":"0"}}}if(!((new RegExp("Edge[ /](\\d+[\\.\\d]+)")).test(g.userAgent))&&typeof navigator.javaEnabled!=="unknown"&&N(g.javaEnabled)&&g.javaEnabled()){dz.java="1"}if(!N(X.showModalDialog)&&N(g.cookieEnabled)){dz.cookie=g.cookieEnabled?"1":"0"}else{dz.cookie=ci()
|
||||
}}var dN=parseInt(ac.width,10);var dL=parseInt(ac.height,10);dz.res=parseInt(dN,10)+"x"+parseInt(dL,10);return dz}function ca(){var dM=a2("cvar"),dL=aL(dM);if(dL&&dL.length){dL=X.JSON.parse(dL);if(aa(dL)){return dL}}return{}}function c3(){if(aZ===false){aZ=ca()}}function df(){var dL=c6();return cl((g.userAgent||"")+(g.platform||"")+X.JSON.stringify(dL)+(new Date()).getTime()+Math.random()).slice(0,16)}function aJ(){var dL=c6();return cl((g.userAgent||"")+(g.platform||"")+X.JSON.stringify(dL)).slice(0,6)}function bq(){return Math.floor((new Date()).getTime()/1000)}function aS(){var dM=bq();var dN=aJ();var dL=String(dM)+dN;return dL}function du(dN){dN=String(dN);var dQ=aJ();var dO=dQ.length;var dP=dN.substr(-1*dO,dO);var dM=parseInt(dN.substr(0,dN.length-dO),10);if(dM&&dP&&dP===dQ){var dL=bq();if(ba<=0){return true}if(dL>=dM&&dL<=(dM+ba)){return true}}return false}function dI(dL){if(!db){return""}var dP=e(dL,aD);if(!dP){return""}dP=String(dP);var dN=new RegExp("^[a-zA-Z0-9]+$");if(dP.length===32&&dN.test(dP)){var dM=dP.substr(16,32);
|
||||
if(du(dM)){var dO=dP.substr(0,16);return dO}}return""}function dc(){if(!b0){b0=dI(bZ)}var dN=new Date(),dL=Math.round(dN.getTime()/1000),dM=a2("id"),dQ=aL(dM),dP,dO;if(dQ){dP=dQ.split(".");dP.unshift("0");if(b0.length){dP[1]=b0}return dP}if(b0.length){dO=b0}else{if("0"===ci()){dO=""}else{dO=df()}}dP=["1",dO,dL];return dP}function a9(){var dO=dc(),dM=dO[0],dN=dO[1],dL=dO[2];return{newVisitor:dM,uuid:dN,createTs:dL}}function aP(){var dO=new Date(),dM=dO.getTime(),dP=a9().createTs;var dL=parseInt(dP,10);var dN=(dL*1000)+c8-dM;return dN}function aV(dL){if(!cj){return}var dN=new Date(),dM=Math.round(dN.getTime()/1000);if(!N(dL)){dL=a9()}var dO=dL.uuid+"."+dL.createTs+".";dG(a2("id"),dO,aP(),bC,dp,b5,aR)}function bX(){var dL=aL(a2("ref"));if(dL.length){try{dL=X.JSON.parse(dL);if(aa(dL)){return dL}}catch(dM){}}return["","",0,""]}function bJ(dN){var dM=bv+"testcookie_domain";var dL="testvalue";dG(dM,dL,10000,null,dN,b5,aR);if(aL(dM)===dL){cc(dM,null,dN);return true}return false}function aN(){var dM=bx;
|
||||
bx=false;var dL,dN;for(dL=0;dL<bH.length;dL++){dN=a2(bH[dL]);if(dN!==da&&dN!==bo&&0!==aL(dN)){cc(dN,bC,dp)}}bx=dM}function cg(dL){cj=dL}function dK(dP){if(!dP||!aa(dP)){return}var dO=[];var dN;for(dN in dP){if(Object.prototype.hasOwnProperty.call(dP,dN)){dO.push(dN)}}var dQ={};dO.sort();var dL=dO.length;var dM;for(dM=0;dM<dL;dM++){dQ[dO[dM]]=dP[dO[dM]]}return dQ}function cs(){dG(a2("ses"),"1",cE,bC,dp,b5,aR)}function br(){var dO="";var dM="abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";var dN=dM.length;var dL;for(dL=0;dL<6;dL++){dO+=dM.charAt(Math.floor(Math.random()*dN))}return dO}function aI(dM){if(cD!==""){dM+=cD;bs=true;return dM}if(!h){return dM}var dN=(typeof h.timing==="object")&&h.timing?h.timing:undefined;if(!dN){dN=(typeof h.getEntriesByType==="function")&&h.getEntriesByType("navigation")?h.getEntriesByType("navigation")[0]:undefined}if(!dN){return dM}var dL="";if(dN.connectEnd&&dN.fetchStart){if(dN.connectEnd<dN.fetchStart){return dM}dL+="&pf_net="+Math.round(dN.connectEnd-dN.fetchStart)
|
||||
}if(dN.responseStart&&dN.requestStart){if(dN.responseStart<dN.requestStart){return dM}dL+="&pf_srv="+Math.round(dN.responseStart-dN.requestStart)}if(dN.responseStart&&dN.responseEnd){if(dN.responseEnd<dN.responseStart){return dM}dL+="&pf_tfr="+Math.round(dN.responseEnd-dN.responseStart)}if(N(dN.domLoading)){if(dN.domInteractive&&dN.domLoading){if(dN.domInteractive<dN.domLoading){return dM}dL+="&pf_dm1="+Math.round(dN.domInteractive-dN.domLoading)}}else{if(dN.domInteractive&&dN.responseEnd){if(dN.domInteractive<dN.responseEnd){return dM}dL+="&pf_dm1="+Math.round(dN.domInteractive-dN.responseEnd)}}if(dN.domComplete&&dN.domInteractive){if(dN.domComplete<dN.domInteractive){return dM}dL+="&pf_dm2="+Math.round(dN.domComplete-dN.domInteractive)}if(dN.loadEventEnd&&dN.loadEventStart){if(dN.loadEventEnd<dN.loadEventStart){return dM}dL+="&pf_onl="+Math.round(dN.loadEventEnd-dN.loadEventStart)}return dM+dL}function cr(dL){return e(dL,"ignore_referrer")==="1"||e(dL,"ignore_referer")==="1"}function dB(){var dV,dO=new Date(),dP=Math.round(dO.getTime()/1000),d0,dN,dQ=1024,dX,dR,dM=a2("ses"),dU=a2("ref"),dT=aL(dM),dL=bX(),dZ=bf||bZ,dW,dS,dY={};
|
||||
dW=dL[0];dS=dL[1];d0=dL[2];dN=dL[3];if(!cr(dZ)&&!dT){if((!bI||!dW.length)&&(dm||cY)){for(dV in cH){if(Object.prototype.hasOwnProperty.call(cH,dV)){dW=e(dZ,cH[dV]);if(dW.length){break}}}for(dV in bT){if(Object.prototype.hasOwnProperty.call(bT,dV)){dS=e(dZ,bT[dV]);if(dS.length){break}}}}dX=d(bA);dR=dN.length?d(dN):"";if(dX.length&&!a6(dX)&&!cJ(bA)&&(!bI||!dR.length||a6(dR)||cJ(dN))){dN=bA}if(dN.length||dW.length){d0=dP;dL=[dW,dS,d0,cf(dN.slice(0,dQ))];dG(dU,X.JSON.stringify(dL),dx,bC,dp,b5,aR)}}if(dW.length){dY._rcn=u(dW)}if(dS.length){dY._rck=u(dS)}dY._refts=d0;if(String(dN).length){dY._ref=u(cf(dN.slice(0,dQ)))}return dY}function cL(dM,dY,dZ){var dX,dL=new Date(),dW=aZ,dS=a2("cvar"),d1=bf||bZ,dN=cr(d1);if(bx){aN()}if(de){return""}var d0=new RegExp("^file://","i");if(!cW&&(X.location.protocol==="file:"||d0.test(d1))){return""}c6();var dT=a9();var dQ=K.characterSet||K.charset;if(!dQ||dQ.toLowerCase()==="utf-8"){dQ=null}dM+="&idsite="+cj+"&rec=1&r="+String(Math.random()).slice(2,8)+"&h="+dL.getHours()+"&m="+dL.getMinutes()+"&s="+dL.getSeconds()+"&url="+u(cf(d1))+(bA.length&&!cJ(bA)&&!dN?"&urlref="+u(cf(bA)):"")+(ad(bL)?"&uid="+u(bL):"")+"&_id="+dT.uuid+"&_idn="+dT.newVisitor+(dQ?"&cs="+u(dQ):"")+"&send_image=0";
|
||||
var dV=dB();for(dX in dV){if(Object.prototype.hasOwnProperty.call(dV,dX)){dM+="&"+dX+"="+dV[dX]}}var d3=[];if(dY){for(dX in dY){if(Object.prototype.hasOwnProperty.call(dY,dX)&&/^dimension\d+$/.test(dX)){var dO=dX.replace("dimension","");d3.push(parseInt(dO,10));d3.push(String(dO));dM+="&"+dX+"="+u(dY[dX]);delete dY[dX]}}}if(dY&&E(dY)){dY=null}for(dX in cN){if(Object.prototype.hasOwnProperty.call(cN,dX)){dM+="&"+dX+"="+u(cN[dX])}}for(dX in bz){if(Object.prototype.hasOwnProperty.call(bz,dX)){var dR=(-1===Q(d3,dX));if(dR){dM+="&dimension"+dX+"="+u(bz[dX])}}}if(dY){dM+="&data="+u(X.JSON.stringify(dY))}else{if(aw){dM+="&data="+u(X.JSON.stringify(aw))}}function dP(d4,d5){var d6=X.JSON.stringify(d4);if(d6.length>2){return"&"+d5+"="+u(d6)}return""}var d2=dK(b9);var dU=dK(cC);dM+=dP(d2,"cvar");dM+=dP(dU,"e_cvar");if(aZ){dM+=dP(aZ,"_cvar");for(dX in dW){if(Object.prototype.hasOwnProperty.call(dW,dX)){if(aZ[dX][0]===""||aZ[dX][1]===""){delete aZ[dX]}}}if(b3){dG(dS,X.JSON.stringify(aZ),cE,bC,dp,b5,aR)
|
||||
}}if(bd&&bR&&!bs){dM=aI(dM);bs=true}if(aU){dM+="&pv_id="+aU}aV(dT);cs();dM+=ah(dZ,{tracker:bV,request:dM});if(dr.length){dM+="&"+dr}if(au()){dM+="&tracker_install_check="+q}if(D(cq)){dM=cq(dM)}return dM}b4=function bi(){var dL=new Date();dL=dL.getTime();if(!dq){return false}if(dq+bg<=dL){bV.ping();return true}return false};function bD(dO,dN,dS,dP,dL,dV){var dR="idgoal=0",dM=new Date(),dT=[],dU,dQ=String(dO).length;if(dQ){dR+="&ec_id="+u(dO)}dR+="&revenue="+dN;if(String(dS).length){dR+="&ec_st="+dS}if(String(dP).length){dR+="&ec_tx="+dP}if(String(dL).length){dR+="&ec_sh="+dL}if(String(dV).length){dR+="&ec_dt="+dV}if(ds){for(dU in ds){if(Object.prototype.hasOwnProperty.call(ds,dU)){if(!N(ds[dU][1])){ds[dU][1]=""}if(!N(ds[dU][2])){ds[dU][2]=""}if(!N(ds[dU][3])||String(ds[dU][3]).length===0){ds[dU][3]=0}if(!N(ds[dU][4])||String(ds[dU][4]).length===0){ds[dU][4]=1}dT.push(ds[dU])}}dR+="&ec_items="+u(X.JSON.stringify(dT))}dR=cL(dR,aw,"ecommerce");bS(dR,bW);if(dQ){ds={}}}function cb(dL,dP,dO,dN,dM,dQ){if(String(dL).length&&N(dP)){bD(dL,dP,dO,dN,dM,dQ)
|
||||
}}function bF(dL){if(N(dL)){bD("",dL,"","","","")}}function cd(dM,dO,dN){if(!bN){aU=br()}var dL=cL("action_name="+u(aq(dM||bu)),dO,"log");if(bd&&!bs){dL=aI(dL)}bS(dL,bW,dN)}function bb(dN,dM){var dO,dL="(^| )(piwik[_-]"+dM+"|matomo[_-]"+dM;if(dN){for(dO=0;dO<dN.length;dO++){dL+="|"+dN[dO]}}dL+=")( |$)";return new RegExp(dL)}function a4(dL){return(aM&&dL&&0===String(dL).indexOf(aM))}function cP(dP,dL,dQ,dM){if(a4(dL)){return 0}var dO=bb(bY,"download"),dN=bb(bj,"link"),dR=new RegExp("\\.("+dy.join("|")+")([?&#]|$)","i");if(dN.test(dP)){return"link"}if(dM||dO.test(dP)||dR.test(dL)){return"download"}if(dQ){return 0}return"link"}function aC(dM){var dL;dL=dM.parentNode;while(dL!==null&&N(dL)){if(aj.isLinkElement(dM)){break}dM=dL;dL=dM.parentNode}return dM}function dE(dQ){dQ=aC(dQ);if(!aj.hasNodeAttribute(dQ,"href")){return}if(!N(dQ.href)){return}var dP=aj.getAttributeValueFromNode(dQ,"href");var dM=dQ.pathname||cB(dQ.href);var dR=dQ.hostname||d(dQ.href);var dS=dR.toLowerCase();var dN=dQ.href.replace(dR,dS);
|
||||
var dO=new RegExp("^(javascript|vbscript|jscript|mocha|livescript|ecmascript|mailto|tel):","i");if(!dO.test(dN)){var dL=cP(dQ.className,dN,aA(dS,dM),aj.hasNodeAttribute(dQ,"download"));if(dL){return{type:dL,href:dN}}}}function aY(dL,dM,dN,dO){var dP=x.buildInteractionRequestParams(dL,dM,dN,dO);if(!dP){return}return cL(dP,null,"contentInteraction")}function bm(dL,dM){if(!dL||!dM){return false}var dN=x.findTargetNode(dL);if(x.shouldIgnoreInteraction(dN)){return false}dN=x.findTargetNodeNoDefault(dL);if(dN&&!Z(dN,dM)){return false}return true}function cO(dN,dM,dP){if(!dN){return}var dL=x.findParentContentNode(dN);if(!dL){return}if(!bm(dL,dN)){return}var dO=x.buildContentBlock(dL);if(!dO){return}if(!dO.target&&dP){dO.target=dP}return x.buildInteractionRequestParams(dM,dO.name,dO.piece,dO.target)}function a7(dM){if(!cp||!cp.length){return false}var dL,dN;for(dL=0;dL<cp.length;dL++){dN=cp[dL];if(dN&&dN.name===dM.name&&dN.piece===dM.piece&&dN.target===dM.target){return true}}return false}function a8(dL){return function(dP){if(!dL){return
|
||||
}var dN=x.findParentContentNode(dL);var dM;if(dP){dM=dP.target||dP.srcElement}if(!dM){dM=dL}if(!bm(dN,dM)){return}if(!dN){return false}var dQ=x.findTargetNode(dN);if(!dQ||x.shouldIgnoreInteraction(dQ)){return false}var dO=dE(dQ);if(dA&&dO&&dO.type){return dO.type}return bV.trackContentInteractionNode(dM,"click")}}function ce(dN){if(!dN||!dN.length){return}var dL,dM;for(dL=0;dL<dN.length;dL++){dM=x.findTargetNode(dN[dL]);if(dM&&!dM.contentInteractionTrackingSetupDone){dM.contentInteractionTrackingSetupDone=true;at(dM,"click",a8(dM))}}}function bK(dN,dO){if(!dN||!dN.length){return[]}var dL,dM;for(dL=0;dL<dN.length;dL++){if(a7(dN[dL])){dN.splice(dL,1);dL--}else{cp.push(dN[dL])}}if(!dN||!dN.length){return[]}ce(dO);var dP=[];for(dL=0;dL<dN.length;dL++){dM=cL(x.buildImpressionRequestParams(dN[dL].name,dN[dL].piece,dN[dL].target),undefined,"contentImpressions");if(dM){dP.push(dM)}}return dP}function cX(dM){var dL=x.collectContent(dM);return bK(dL,dM)}function bk(dM){if(!dM||!dM.length){return[]
|
||||
}var dL;for(dL=0;dL<dM.length;dL++){if(!x.isNodeVisible(dM[dL])){dM.splice(dL,1);dL--}}if(!dM||!dM.length){return[]}return cX(dM)}function aO(dN,dL,dM){var dO=x.buildImpressionRequestParams(dN,dL,dM);return cL(dO,null,"contentImpression")}function dD(dO,dM){if(!dO){return}var dL=x.findParentContentNode(dO);var dN=x.buildContentBlock(dL);if(!dN){return}if(!dM){dM="Unknown"}return aY(dM,dN.name,dN.piece,dN.target)}function dd(dM,dO,dL,dN){return"e_c="+u(dM)+"&e_a="+u(dO)+(N(dL)?"&e_n="+u(dL):"")+(N(dN)?"&e_v="+u(dN):"")+"&ca=1"}function aB(dN,dP,dL,dO,dR,dQ){if(!ad(dN)||!ad(dP)){ap("Error while logging event: Parameters `category` and `action` must not be empty or filled with whitespaces");return false}var dM=cL(dd(dN,dP,dL,dO),dR,"event");bS(dM,bW,dQ)}function cm(dL,dO,dM,dP){var dN=cL("search="+u(dL)+(dO?"&search_cat="+u(dO):"")+(N(dM)?"&search_count="+dM:""),dP,"sitesearch");bS(dN,bW)}function dh(dL,dP,dO,dN){var dM=cL("idgoal="+dL+(dP?"&revenue="+dP:""),dO,"goal");bS(dM,bW,dN)}function dt(dO,dL,dS,dR,dN){var dQ=dL+"="+u(cf(dO));
|
||||
var dM=cO(dN,"click",dO);if(dM){dQ+="&"+dM}var dP=cL(dQ,dS,"link");bS(dP,bW,dR)}function b7(dM,dL){if(dM!==""){return dM+dL.charAt(0).toUpperCase()+dL.slice(1)}return dL}function cw(dQ){var dP,dL,dO=["","webkit","ms","moz"],dN;if(!bp){for(dL=0;dL<dO.length;dL++){dN=dO[dL];if(Object.prototype.hasOwnProperty.call(K,b7(dN,"hidden"))){if(K[b7(dN,"visibilityState")]==="prerender"){dP=true}break}}}if(dP){at(K,dN+"visibilitychange",function dM(){K.removeEventListener(dN+"visibilitychange",dM,false);dQ()});return}dQ()}function bE(){var dM=bV.getVisitorId();var dL=aS();return dM+dL}function cz(dL){if(!dL){return}if(!aj.hasNodeAttribute(dL,"href")){return}var dM=aj.getAttributeValueFromNode(dL,"href");if(!dM||a4(dM)){return}if(!bV.getVisitorId()){return}dM=j(dM,aD);var dN=bE();dM=J(dM,aD,dN);aj.setAnyAttribute(dL,"href",dM)}function bw(dO){var dP=aj.getAttributeValueFromNode(dO,"href");if(!dP){return false}dP=String(dP);var dM=dP.indexOf("//")===0||dP.indexOf("http://")===0||dP.indexOf("https://")===0;
|
||||
if(!dM){return false}var dL=dO.pathname||cB(dO.href);var dN=(dO.hostname||d(dO.href)).toLowerCase();if(aA(dN,dL)){if(!c5(di,P(dN))){return true}return false}return false}function c4(dL){var dM=dE(dL);if(dM&&dM.type){dM.href=p(dM.href);dt(dM.href,dM.type,undefined,null,dL);return}if(db){dL=aC(dL);if(bw(dL)){cz(dL)}}}function cQ(){return K.all&&!K.addEventListener}function dj(dL){var dN=dL.which;var dM=(typeof dL.button);if(!dN&&dM!=="undefined"){if(cQ()){if(dL.button&1){dN=1}else{if(dL.button&2){dN=3}else{if(dL.button&4){dN=2}}}}else{if(dL.button===0||dL.button==="0"){dN=1}else{if(dL.button&1){dN=2}else{if(dL.button&2){dN=3}}}}}return dN}function b6(dL){switch(dj(dL)){case 1:return"left";case 2:return"middle";case 3:return"right"}}function bc(dL){return dL.target||dL.srcElement}function dk(dL){return dL==="A"||dL==="AREA"}function aK(dL){function dM(dO){var dP=bc(dO);var dQ=dP.nodeName;var dN=bb(bM,"ignore");while(!dk(dQ)&&dP&&dP.parentNode){dP=dP.parentNode;dQ=dP.nodeName}if(dP&&dk(dQ)&&!dN.test(dP.className)){return dP
|
||||
}}return function(dP){dP=dP||X.event;var dQ=dM(dP);if(!dQ){return}var dO=b6(dP);if(dP.type==="click"){var dN=false;if(dL&&dO==="middle"){dN=true}if(dQ&&!dN){c4(dQ)}}else{if(dP.type==="mousedown"){if(dO==="middle"&&dQ){a0=dO;bO=dQ}else{a0=bO=null}}else{if(dP.type==="mouseup"){if(dO===a0&&dQ===bO){c4(dQ)}a0=bO=null}else{if(dP.type==="contextmenu"){c4(dQ)}}}}}}function az(dO,dN,dL){var dM=typeof dN;if(dM==="undefined"){dN=true}at(dO,"click",aK(dN),dL);if(dN){at(dO,"mouseup",aK(dN),dL);at(dO,"mousedown",aK(dN),dL);at(dO,"contextmenu",aK(dN),dL)}}function a1(dM,dP,dQ){if(cu){return true}cu=true;var dR=false;var dO,dN;function dL(){dR=true}n(function(){function dS(dU){setTimeout(function(){if(!cu){return}dR=false;dQ.trackVisibleContentImpressions();dS(dU)},dU)}function dT(dU){setTimeout(function(){if(!cu){return}if(dR){dR=false;dQ.trackVisibleContentImpressions()}dT(dU)},dU)}if(dM){dO=["scroll","resize"];for(dN=0;dN<dO.length;dN++){if(K.addEventListener){K.addEventListener(dO[dN],dL,false)}else{X.attachEvent("on"+dO[dN],dL)
|
||||
}}dT(100)}if(dP&&dP>0){dP=parseInt(dP,10);dS(dP)}})}var bQ={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dL=this.requests;this.requests=[];if(dL.length===1){bS(dL[0],bW)}else{dH(dL,bW)}},canQueue:function(){return !m&&this.enabled},pushMultiple:function(dM){if(!this.canQueue()){dH(dM,bW);return}var dL;for(dL=0;dL<dM.length;dL++){this.push(dM[dL])}},push:function(dL){if(!dL){return}if(!this.canQueue()){bS(dL,bW);return}bQ.requests.push(dL);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bQ.timeout=null;bQ.sendRequests()},bQ.interval);var dM="RequestQueue"+aF;if(!Object.prototype.hasOwnProperty.call(b,dM)){b[dM]={unload:function(){if(bQ.timeout){clearTimeout(bQ.timeout)}bQ.sendRequests()}}}}};bt();this.hasConsent=function(){return bP};this.getVisitorInfo=function(){if(!aL(a2("id"))){aV()}return dc()};this.getVisitorId=function(){return this.getVisitorInfo()[1]};this.getAttributionInfo=function(){return bX()
|
||||
};this.getAttributionCampaignName=function(){return bX()[0]};this.getAttributionCampaignKeyword=function(){return bX()[1]};this.getAttributionReferrerTimestamp=function(){return bX()[2]};this.getAttributionReferrerUrl=function(){return bX()[3]};this.setTrackerUrl=function(dL){aM=dL};this.getTrackerUrl=function(){return aM};this.getMatomoUrl=function(){return ab(this.getTrackerUrl(),bU)};this.getPiwikUrl=function(){return this.getMatomoUrl()};this.addTracker=function(dN,dM){if(!N(dN)||null===dN){dN=this.getTrackerUrl()}var dL=new U(dN,dM);M.push(dL);v.trigger("TrackerAdded",[this]);return dL};this.getSiteId=function(){return cj};this.setSiteId=function(dL){cg(dL)};this.resetUserId=function(){bL=""};this.setUserId=function(dL){if(ad(dL)){bL=dL}};this.setVisitorId=function(dM){var dL=/[0-9A-Fa-f]{16}/g;if(y(dM)&&dL.test(dM)){b0=dM}else{ap("Invalid visitorId set"+dM)}};this.getUserId=function(){return bL};this.setCustomData=function(dL,dM){if(aa(dL)){aw=dL}else{if(!aw){aw={}}aw[dL]=dM}};this.getCustomData=function(){return aw
|
||||
};this.setCustomRequestProcessing=function(dL){cq=dL};this.appendToTrackingUrl=function(dL){dr=dL};this.getRequest=function(dL){return cL(dL)};this.addPlugin=function(dL,dM){b[dL]=dM};this.setCustomDimension=function(dL,dM){dL=parseInt(dL,10);if(dL>0){if(!N(dM)){dM=""}if(!y(dM)){dM=String(dM)}bz[dL]=dM}};this.getCustomDimension=function(dL){dL=parseInt(dL,10);if(dL>0&&Object.prototype.hasOwnProperty.call(bz,dL)){return bz[dL]}};this.deleteCustomDimension=function(dL){dL=parseInt(dL,10);if(dL>0){delete bz[dL]}};this.setCustomVariable=function(dM,dL,dP,dN){var dO;if(!N(dN)){dN="visit"}if(!N(dL)){return}if(!N(dP)){dP=""}if(dM>0){dL=!y(dL)?String(dL):dL;dP=!y(dP)?String(dP):dP;dO=[dL.slice(0,bG),dP.slice(0,bG)];if(dN==="visit"||dN===2){c3();aZ[dM]=dO}else{if(dN==="page"||dN===3){b9[dM]=dO}else{if(dN==="event"){cC[dM]=dO}}}}};this.getCustomVariable=function(dM,dN){var dL;if(!N(dN)){dN="visit"}if(dN==="page"||dN===3){dL=b9[dM]}else{if(dN==="event"){dL=cC[dM]}else{if(dN==="visit"||dN===2){c3();
|
||||
dL=aZ[dM]}}}if(!N(dL)||(dL&&dL[0]==="")){return false}return dL};this.deleteCustomVariable=function(dL,dM){if(this.getCustomVariable(dL,dM)){this.setCustomVariable(dL,"","",dM)}};this.deleteCustomVariables=function(dL){if(dL==="page"||dL===3){b9={}}else{if(dL==="event"){cC={}}else{if(dL==="visit"||dL===2){aZ={}}}}};this.storeCustomVariablesInCookie=function(){b3=true};this.setLinkTrackingTimer=function(dL){bW=dL};this.getLinkTrackingTimer=function(){return bW};this.setDownloadExtensions=function(dL){if(y(dL)){dL=dL.split("|")}dy=dL};this.addDownloadExtensions=function(dM){var dL;if(y(dM)){dM=dM.split("|")}for(dL=0;dL<dM.length;dL++){dy.push(dM[dL])}};this.removeDownloadExtensions=function(dN){var dM,dL=[];if(y(dN)){dN=dN.split("|")}for(dM=0;dM<dy.length;dM++){if(Q(dN,dy[dM])===-1){dL.push(dy[dM])}}dy=dL};this.setDomains=function(dL){aG=y(dL)?[dL]:dL;var dP=false,dN=0,dM;for(dN;dN<aG.length;dN++){dM=String(aG[dN]);if(c5(di,P(dM))){dP=true;break}var dO=cB(dM);if(dO&&dO!=="/"&&dO!=="/*"){dP=true;
|
||||
break}}if(!dP){aG.push(di)}};this.setExcludedReferrers=function(dL){cS=y(dL)?[dL]:dL};this.enableCrossDomainLinking=function(){db=true};this.disableCrossDomainLinking=function(){db=false};this.isCrossDomainLinkingEnabled=function(){return db};this.setCrossDomainLinkingTimeout=function(dL){ba=dL};this.getCrossDomainLinkingUrlParameter=function(){return u(aD)+"="+u(bE())};this.setIgnoreClasses=function(dL){bM=y(dL)?[dL]:dL};this.setRequestMethod=function(dL){if(dL){dC=String(dL).toUpperCase()}else{dC=cx}if(dC==="GET"){this.disableAlwaysUseSendBeacon()}};this.setRequestContentType=function(dL){cR=dL||aQ};this.setGenerationTimeMs=function(dL){ap("setGenerationTimeMs is no longer supported since Matomo 4. The call will be ignored. The replacement is setPagePerformanceTiming.")};this.setPagePerformanceTiming=function(dP,dR,dQ,dM,dS,dN){var dO={pf_net:dP,pf_srv:dR,pf_tfr:dQ,pf_dm1:dM,pf_dm2:dS,pf_onl:dN};try{dO=R(dO,N);dO=C(dO);cD=l(dO);if(cD===""){ap("setPagePerformanceTiming() called without parameters. This function needs to be called with at least one performance parameter.");
|
||||
return}bs=false;bR=true}catch(dL){ap("setPagePerformanceTiming: "+dL.toString())}};this.setReferrerUrl=function(dL){bA=dL};this.setCustomUrl=function(dL){bf=b8(bZ,dL)};this.getCurrentUrl=function(){return bf||bZ};this.setDocumentTitle=function(dL){bu=dL};this.setPageViewId=function(dL){aU=dL;bN=true};this.getPageViewId=function(){return aU};this.setAPIUrl=function(dL){bU=dL};this.setDownloadClasses=function(dL){bY=y(dL)?[dL]:dL};this.setLinkClasses=function(dL){bj=y(dL)?[dL]:dL};this.setCampaignNameKey=function(dL){cH=y(dL)?[dL]:dL};this.setCampaignKeywordKey=function(dL){bT=y(dL)?[dL]:dL};this.discardHashTag=function(dL){b1=dL};this.setCookieNamePrefix=function(dL){bv=dL;if(aZ){aZ=ca()}};this.setCookieDomain=function(dL){var dM=P(dL);if(!bx&&!bJ(dM)){ap("Can't write cookie on domain "+dL)}else{dp=dM;bt()}};this.setExcludedQueryParams=function(dL){cy=y(dL)?[dL]:dL};this.getCookieDomain=function(){return dp};this.hasCookies=function(){return"1"===ci()};this.setSessionCookie=function(dN,dM,dL){if(!dN){throw new Error("Missing cookie name")
|
||||
}if(!N(dL)){dL=cE}bH.push(dN);dG(a2(dN),dM,dL,bC,dp,b5,aR)};this.getCookie=function(dM){var dL=aL(a2(dM));if(dL===0){return null}return dL};this.setCookiePath=function(dL){bC=dL;bt()};this.getCookiePath=function(){return bC};this.setVisitorCookieTimeout=function(dL){c8=dL*1000};this.setSessionCookieTimeout=function(dL){cE=dL*1000};this.getSessionCookieTimeout=function(){return cE};this.setReferralCookieTimeout=function(dL){dx=dL*1000};this.setConversionAttributionFirstReferrer=function(dL){bI=dL};this.setSecureCookie=function(dL){if(dL&&location.protocol!=="https:"){ap("Error in setSecureCookie: You cannot use `Secure` on http.");return}b5=dL};this.setCookieSameSite=function(dL){dL=String(dL);dL=dL.charAt(0).toUpperCase()+dL.toLowerCase().slice(1);if(dL!=="None"&&dL!=="Lax"&&dL!=="Strict"){ap("Ignored value for sameSite. Please use either Lax, None, or Strict.");return}if(dL==="None"){if(location.protocol==="https:"){this.setSecureCookie(true)}else{ap("sameSite=None cannot be used on http, reverted to sameSite=Lax.");
|
||||
dL="Lax"}}aR=dL};this.disableCookies=function(){bx=true;if(cj){aN()}};this.areCookiesEnabled=function(){return !bx};this.setCookieConsentGiven=function(){if(bx&&!de){bx=false;if(!dn){this.enableBrowserFeatureDetection()}if(cj&&aE){aV();var dL=cL("ping=1",null,"ping");bS(dL,bW)}}};this.requireCookieConsent=function(){if(this.getRememberedCookieConsent()){return false}this.disableCookies();return true};this.getRememberedCookieConsent=function(){return aL(c1)};this.forgetCookieConsentGiven=function(){cc(c1,bC,dp);this.disableCookies()};this.rememberCookieConsentGiven=function(dM){if(dM){dM=dM*60*60*1000}else{dM=30*365*24*60*60*1000}this.setCookieConsentGiven();var dL=new Date().getTime();dG(c1,dL,dM,bC,dp,b5,aR)};this.deleteCookies=function(){aN()};this.setDoNotTrack=function(dM){var dL=g.doNotTrack||g.msDoNotTrack;de=dM&&(dL==="yes"||dL==="1");if(de){this.disableCookies()}};this.disableCampaignParameters=function(){dm=false};this.alwaysUseSendBeacon=function(){dl=true};this.disableAlwaysUseSendBeacon=function(){dl=false
|
||||
};this.addListener=function(dM,dL){az(dM,dL,false)};this.enableLinkTracking=function(dM){if(dA){return}dA=true;var dL=this;r(function(){ax=true;var dN=K.body;az(dN,dM,true)})};this.enableJSErrorTracking=function(){if(dg){return}dg=true;var dL=X.onerror;X.onerror=function(dQ,dO,dN,dP,dM){cw(function(){var dR="JavaScript Errors";var dS=dO+":"+dN;if(dP){dS+=":"+dP}if(Q(cM,dR+dS+dQ)===-1){cM.push(dR+dS+dQ);aB(dR,dS,dQ)}});if(dL){return dL(dQ,dO,dN,dP,dM)}return false}};this.disablePerformanceTracking=function(){bd=false};this.enableHeartBeatTimer=function(dL){dL=Math.max(dL||15,5);bg=dL*1000;if(dq!==null){dJ()}};this.disableHeartBeatTimer=function(){if(bg||aW){if(X.removeEventListener){X.removeEventListener("focus",bl);X.removeEventListener("blur",aH);X.removeEventListener("visibilitychange",a5)}else{if(X.detachEvent){X.detachEvent("onfocus",bl);X.detachEvent("onblur",aH);X.detachEvent("visibilitychange",a5)}}}bg=null;aW=false};this.killFrame=function(){if(X.location!==X.top.location){X.top.location=X.location
|
||||
}};this.redirectFile=function(dL){if(X.location.protocol==="file:"){X.location=dL}};this.setCountPreRendered=function(dL){bp=dL};this.trackGoal=function(dL,dO,dN,dM){cw(function(){dh(dL,dO,dN,dM)})};this.trackLink=function(dM,dL,dO,dN){cw(function(){dt(dM,dL,dO,dN)})};this.getNumTrackedPageViews=function(){return cK};this.trackPageView=function(dL,dN,dM){cp=[];c9=[];cM=[];if(S(cj)){cw(function(){ae(aM,bU,cj)})}else{cw(function(){cK++;cd(dL,dN,dM)})}};this.disableBrowserFeatureDetection=function(){dn=false;dz={};if(av()){ay()}};this.enableBrowserFeatureDetection=function(){dn=true;c6()};this.trackAllContentImpressions=function(){if(S(cj)){return}cw(function(){r(function(){var dL=x.findContentNodes();var dM=cX(dL);bQ.pushMultiple(dM)})})};this.trackVisibleContentImpressions=function(dL,dM){if(S(cj)){return}if(!N(dL)){dL=true}if(!N(dM)){dM=750}a1(dL,dM,this);cw(function(){n(function(){var dN=x.findContentNodes();var dO=bk(dN);bQ.pushMultiple(dO)})})};this.trackContentImpression=function(dN,dL,dM){if(S(cj)){return
|
||||
}dN=a(dN);dL=a(dL);dM=a(dM);if(!dN){return}dL=dL||"Unknown";cw(function(){var dO=aO(dN,dL,dM);bQ.push(dO)})};this.trackContentImpressionsWithinNode=function(dL){if(S(cj)||!dL){return}cw(function(){if(cu){n(function(){var dM=x.findContentNodesWithinNode(dL);var dN=bk(dM);bQ.pushMultiple(dN)})}else{r(function(){var dM=x.findContentNodesWithinNode(dL);var dN=cX(dM);bQ.pushMultiple(dN)})}})};this.trackContentInteraction=function(dN,dO,dL,dM){if(S(cj)){return}dN=a(dN);dO=a(dO);dL=a(dL);dM=a(dM);if(!dN||!dO){return}dL=dL||"Unknown";cw(function(){var dP=aY(dN,dO,dL,dM);if(dP){bQ.push(dP)}})};this.trackContentInteractionNode=function(dN,dM){if(S(cj)||!dN){return}var dL=null;cw(function(){dL=dD(dN,dM);if(dL){bQ.push(dL)}});return dL};this.logAllContentBlocksOnPage=function(){var dN=x.findContentNodes();var dL=x.collectContent(dN);var dM=typeof console;if(dM!=="undefined"&&console&&console.log){console.log(dL)}};this.trackEvent=function(dM,dO,dL,dN,dQ,dP){cw(function(){aB(dM,dO,dL,dN,dQ,dP)})};this.trackSiteSearch=function(dL,dN,dM,dO){cp=[];
|
||||
cw(function(){cm(dL,dN,dM,dO)})};this.setEcommerceView=function(dP,dL,dN,dM){cN={};if(ad(dN)){dN=String(dN)}if(!N(dN)||dN===null||dN===false||!dN.length){dN=""}else{if(dN instanceof Array){dN=X.JSON.stringify(dN)}}var dO="_pkc";cN[dO]=dN;if(N(dM)&&dM!==null&&dM!==false&&String(dM).length){dO="_pkp";cN[dO]=dM}if(!ad(dP)&&!ad(dL)){return}if(ad(dP)){dO="_pks";cN[dO]=dP}if(!ad(dL)){dL=""}dO="_pkn";cN[dO]=dL};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(ds))};this.addEcommerceItem=function(dP,dL,dN,dM,dO){if(ad(dP)){ds[dP]=[String(dP),dL,dN,dM,dO]}};this.removeEcommerceItem=function(dL){if(ad(dL)){dL=String(dL);delete ds[dL]}};this.clearEcommerceCart=function(){ds={}};this.trackEcommerceOrder=function(dL,dP,dO,dN,dM,dQ){cb(dL,dP,dO,dN,dM,dQ)};this.trackEcommerceCartUpdate=function(dL){bF(dL)};this.trackRequest=function(dM,dO,dN,dL){cw(function(){var dP=cL(dM,dO,dL);bS(dP,bW,dN)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bQ.enabled=false
|
||||
};this.setRequestQueueInterval=function(dL){if(dL<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bQ.interval=dL};this.queueRequest=function(dM,dL){cw(function(){var dN=dL?dM:cL(dM);bQ.push(dN)})};this.isConsentRequired=function(){return cY};this.getRememberedConsent=function(){var dL=aL(bo);if(aL(da)){if(dL){cc(bo,bC,dp)}return null}if(!dL||dL===0){return null}return dL};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()};this.requireConsent=function(){cY=true;bP=this.hasRememberedConsent();if(!bP){bx=true}z++;b["CoreConsent"+z]={unload:function(){if(!bP){aN()}}}};this.setConsentGiven=function(dM){bP=true;if(!dn){this.enableBrowserFeatureDetection()}cc(da,bC,dp);var dN,dL;for(dN=0;dN<c9.length;dN++){dL=typeof c9[dN][0];if(dL==="string"){bS(c9[dN][0],bW,c9[dN][1])}else{if(dL==="object"){dH(c9[dN][0],bW)}}}c9=[];if(!N(dM)||dM){this.setCookieConsentGiven()}};this.rememberConsentGiven=function(dN){if(dN){dN=dN*60*60*1000}else{dN=30*365*24*60*60*1000
|
||||
}var dL=true;this.setConsentGiven(dL);var dM=new Date().getTime();dG(bo,dM,dN,bC,dp,b5,aR)};this.forgetConsentGiven=function(dL){if(dL){dL=dL*60*60*1000}else{dL=30*365*24*60*60*1000}cc(bo,bC,dp);dG(da,new Date().getTime(),dL,bC,dp,b5,aR);this.forgetCookieConsentGiven();this.requireConsent()};this.isUserOptedOut=function(){return !bP};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=function(){this.setConsentGiven(false)};this.enableFileTracking=function(){cW=true};n(function(){setTimeout(function(){bR=true},0)});v.trigger("TrackerSetup",[this]);v.addPlugin("TrackerVisitorIdCookie"+aF,{unload:function(){if(av()&&!by){by=true;ay()}if(!aE){aV();dB()}}})}function L(){return{push:ak}}function c(az,ay){var aA={};var aw,ax;for(aw=0;aw<ay.length;aw++){var au=ay[aw];aA[au]=1;for(ax=0;ax<az.length;ax++){if(az[ax]&&az[ax][0]){var av=az[ax][0];if(au===av){ak(az[ax]);delete az[ax];if(aA[av]>1&&av!=="addTracker"&&av!=="enableLinkTracking"){ap("The method "+av+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Matomo trackers documentation: https://developer.matomo.org/guides/tracking-javascript-guide#multiple-piwik-trackers')
|
||||
}aA[av]++}}}}return az}var F=["addTracker","enableFileTracking","forgetCookieConsentGiven","requireCookieConsent","disableBrowserFeatureDetection","disableCampaignParameters","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setCookieNamePrefix","setCookieSameSite","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setVisitorId","setSiteId","alwaysUseSendBeacon","disableAlwaysUseSendBeacon","enableLinkTracking","setCookieConsentGiven","requireConsent","setConsentGiven","disablePerformanceTracking","setPagePerformanceTiming","setExcludedQueryParams","setExcludedReferrers"];function ai(aw,av){var au=new U(aw,av);M.push(au);_paq=c(_paq,F);for(I=0;I<_paq.length;I++){if(_paq[I]){ak(_paq[I])}}_paq=new L();v.trigger("TrackerAdded",[au]);return au}at(X,"beforeunload",an,false);at(X,"visibilitychange",function(){if(m){return}if(K.visibilityState==="hidden"){ah("unload")
|
||||
}},false);at(X,"online",function(){if(N(g.serviceWorker)){g.serviceWorker.ready.then(function(au){if(au&&au.sync){return au.sync.register("matomoSync")}},function(){})}},false);at(X,"message",function(az){if(!az||!az.origin){return}var aB,ax,av;var aC=d(az.origin);var ay=v.getAsyncTrackers();for(ax=0;ax<ay.length;ax++){av=d(ay[ax].getMatomoUrl());if(av===aC){aB=ay[ax];break}}if(!aB){return}var aw=null;try{aw=JSON.parse(az.data)}catch(aA){return}if(!aw){return}function au(aF){var aH=K.getElementsByTagName("iframe");for(ax=0;ax<aH.length;ax++){var aG=aH[ax];var aD=d(aG.src);if(aG.contentWindow&&N(aG.contentWindow.postMessage)&&aD===aC){var aE=JSON.stringify(aF);aG.contentWindow.postMessage(aE,az.origin)}}}if(N(aw.maq_initial_value)){au({maq_opted_in:aw.maq_initial_value&&aB.hasConsent(),maq_url:aB.getMatomoUrl(),maq_optout_by_default:aB.isConsentRequired()})}else{if(N(aw.maq_opted_in)){ay=v.getAsyncTrackers();for(ax=0;ax<ay.length;ax++){aB=ay[ax];if(aw.maq_opted_in){aB.rememberConsentGiven()
|
||||
}else{aB.forgetConsentGiven()}}au({maq_confirm_opted_in:aB.hasConsent(),maq_url:aB.getMatomoUrl(),maq_optout_by_default:aB.isConsentRequired()})}}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;v={initialized:false,JSON:X.JSON,DOM:{addEventListener:function(ax,aw,av,au){var ay=typeof au;if(ay==="undefined"){au=false}at(ax,aw,av,au)},onLoad:n,onReady:r,isNodeVisible:i,isOrWasNodeVisible:x.isNodeVisible},on:function(av,au){if(!A[av]){A[av]=[]}A[av].push(au)},off:function(aw,av){if(!A[aw]){return}var au=0;for(au;au<A[aw].length;au++){if(A[aw][au]===av){A[aw].splice(au,1)}}},trigger:function(aw,ax,av){if(!A[aw]){return}var au=0;for(au;au<A[aw].length;au++){A[aw][au].apply(av||X,ax)}},addPlugin:function(au,av){b[au]=av},getTracker:function(av,au){if(!N(au)){au=this.getAsyncTracker().getSiteId()}if(!N(av)){av=this.getAsyncTracker().getTrackerUrl()}return new U(av,au)},getAsyncTrackers:function(){return M},addTracker:function(aw,av){var au;if(!M.length){au=ai(aw,av)}else{au=M[0].addTracker(aw,av)
|
||||
}return au},getAsyncTracker:function(ay,ax){var aw;if(M&&M.length&&M[0]){aw=M[0]}else{return ai(ay,ax)}if(!ax&&!ay){return aw}if((!N(ax)||null===ax)&&aw){ax=aw.getSiteId()}if((!N(ay)||null===ay)&&aw){ay=aw.getTrackerUrl()}var av,au=0;for(au;au<M.length;au++){av=M[au];if(av&&String(av.getSiteId())===String(ax)&&av.getTrackerUrl()===ay){return av}}},retryMissedPluginCalls:function(){var av=am;am=[];var au=0;for(au;au<av.length;au++){ak(av[au])}}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return v});define("matomo",[],function(){return v})}return v}())}
|
||||
/*!!! pluginTrackerHook */
|
||||
(function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.matomoPluginAsyncInit&&window.matomoPluginAsyncInit.length){var a=0;for(a;a<window.matomoPluginAsyncInit.length;a++){if(typeof window.matomoPluginAsyncInit[a]==="function"){window.matomoPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()
|
||||
}if(window&&window.matomoAsyncInit){window.matomoAsyncInit()}if(!window.Matomo.getAsyncTrackers().length){if(b()){window.Matomo.addTracker()}else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)}}}}}window.Matomo.trigger("MatomoInitialized",[]);window.Matomo.initialized=true}());(function(){var a=(typeof window.AnalyticsTracker);if(a==="undefined"){window.AnalyticsTracker=window.Matomo}}());if(typeof window.piwik_log!=="function"){window.piwik_log=function(c,e,g,f){function b(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var d,a=window.Matomo.getTracker(g,e);
|
||||
a.setDocumentTitle(c);a.setCustomData(f);d=b("tracker_pause");if(d){a.setLinkTrackingTimer(d)}d=b("download_extensions");if(d){a.setDownloadExtensions(d)}d=b("hosts_alias");if(d){a.setDomains(d)}d=b("ignore_classes");if(d){a.setIgnoreClasses(d)}a.trackPageView();if(b("install_tracker")){piwik_track=function(i,j,k,h){a.setSiteId(j);a.setTrackerUrl(k);a.trackLink(i,h)};a.enableLinkTracking()}}}
|
||||
/*!! @license-end */;
|
||||
25
vendor/autoload.php
vendored
Executable file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitc514d8f7b9fc5970bdd94287905ef584::getLoader();
|
||||
119
vendor/bin/carbon
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../nesbot/carbon/bin/carbon)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nesbot/carbon/bin/carbon');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/nesbot/carbon/bin/carbon';
|
||||
119
vendor/bin/patch-type-declarations
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/error-handler/Resources/bin/patch-type-declarations)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/error-handler/Resources/bin/patch-type-declarations');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/symfony/error-handler/Resources/bin/patch-type-declarations';
|
||||
119
vendor/bin/php-parse
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../nikic/php-parser/bin/php-parse)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse';
|
||||
122
vendor/bin/phpunit
vendored
Executable file
@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../phpunit/phpunit/phpunit)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
$GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'] = $GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST'] = array(realpath(__DIR__ . '/..'.'/phpunit/phpunit/phpunit'));
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = 'phpvfscomposer://'.$this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
$data = str_replace('__DIR__', var_export(dirname($this->realpath), true), $data);
|
||||
$data = str_replace('__FILE__', var_export($this->realpath, true), $data);
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpunit/phpunit/phpunit');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/phpunit/phpunit/phpunit';
|
||||
119
vendor/bin/pint
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../laravel/pint/builds/pint)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/laravel/pint/builds/pint');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/laravel/pint/builds/pint';
|
||||
119
vendor/bin/pinyin
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../overtrue/pinyin/bin/pinyin)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/overtrue/pinyin/bin/pinyin');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/overtrue/pinyin/bin/pinyin';
|
||||
119
vendor/bin/psysh
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../psy/psysh/bin/psysh)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/psy/psysh/bin/psysh');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/psy/psysh/bin/psysh';
|
||||
37
vendor/bin/sail
vendored
Executable file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Support bash to support `source` with fallback on $0 if this does not run with bash
|
||||
# https://stackoverflow.com/a/35006505/6512
|
||||
selfArg="$BASH_SOURCE"
|
||||
if [ -z "$selfArg" ]; then
|
||||
selfArg="$0"
|
||||
fi
|
||||
|
||||
self=$(realpath $selfArg 2> /dev/null)
|
||||
if [ -z "$self" ]; then
|
||||
self="$selfArg"
|
||||
fi
|
||||
|
||||
dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../laravel/sail/bin' && pwd)
|
||||
|
||||
if [ -d /proc/cygdrive ]; then
|
||||
case $(which php) in
|
||||
$(readlink -n /proc/cygdrive)/*)
|
||||
# We are in Cygwin using Windows php, so the path must be translated
|
||||
dir=$(cygpath -m "$dir");
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
export COMPOSER_RUNTIME_BIN_DIR="$(cd "${self%[/\\]*}" > /dev/null; pwd)"
|
||||
|
||||
# If bash is sourcing this file, we have to source the target as well
|
||||
bashSource="$BASH_SOURCE"
|
||||
if [ -n "$bashSource" ]; then
|
||||
if [ "$bashSource" != "$0" ]; then
|
||||
source "${dir}/sail" "$@"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "${dir}/sail" "$@"
|
||||
119
vendor/bin/var-dump-server
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/var-dumper/Resources/bin/var-dump-server)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server';
|
||||
119
vendor/bin/yaml-lint
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/yaml/Resources/bin/yaml-lint)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint';
|
||||
523
vendor/brick/math/CHANGELOG.md
vendored
Executable file
@ -0,0 +1,523 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.14.1](https://github.com/brick/math/releases/tag/0.14.1) - 2025-11-24
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- New method: `BigNumber::ofNullable()` (#94 by @mrkh995)
|
||||
|
||||
✨ **Compatibility fixes**
|
||||
|
||||
- Fixed warnings on PHP 8.5 (#101 and #102 by @julien-boudry)
|
||||
|
||||
## [0.14.0](https://github.com/brick/math/releases/tag/0.14.0) - 2025-08-29
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- New methods: `BigInteger::clamp()` and `BigDecimal::clamp()` (#96 by @JesterIruka)
|
||||
|
||||
✨ **Improvements**
|
||||
|
||||
- All pure methods in `BigNumber` classes are now marked as `@pure` for better static analysis
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- Minimum PHP version is now 8.2
|
||||
- `BigNumber` classes are now `readonly`
|
||||
- `BigNumber` is now marked as sealed: it must not be extended outside of this package
|
||||
- Exception classes are now `final`
|
||||
|
||||
## [0.13.1](https://github.com/brick/math/releases/tag/0.13.1) - 2025-03-29
|
||||
|
||||
✨ **Improvements**
|
||||
|
||||
- `__toString()` methods of `BigInteger` and `BigDecimal` are now type-hinted as returning `numeric-string` instead of `string` (#90 by @vudaltsov)
|
||||
|
||||
## [0.13.0](https://github.com/brick/math/releases/tag/0.13.0) - 2025-03-03
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- `BigDecimal::ofUnscaledValue()` no longer throws an exception if the scale is negative
|
||||
- `MathException` now extends `RuntimeException` instead of `Exception`; this reverts the change introduced in version `0.11.0` (#82)
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigDecimal::ofUnscaledValue()` allows a negative scale (and converts the values to create a zero scale number)
|
||||
|
||||
## [0.12.3](https://github.com/brick/math/releases/tag/0.12.3) - 2025-02-28
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigDecimal::getPrecision()` Returns the number of significant digits in a decimal number
|
||||
|
||||
## [0.12.2](https://github.com/brick/math/releases/tag/0.12.2) - 2025-02-26
|
||||
|
||||
⚡️ **Performance improvements**
|
||||
|
||||
- Division in `NativeCalculator` is now faster for small divisors, thanks to [@Izumi-kun](https://github.com/Izumi-kun) in [#87](https://github.com/brick/math/pull/87).
|
||||
|
||||
👌 **Improvements**
|
||||
|
||||
- Add missing `RoundingNecessaryException` to the `@throws` annotation of `BigNumber::of()`
|
||||
|
||||
## [0.12.1](https://github.com/brick/math/releases/tag/0.12.1) - 2023-11-29
|
||||
|
||||
⚡️ **Performance improvements**
|
||||
|
||||
- `BigNumber::of()` is now faster, thanks to [@SebastienDug](https://github.com/SebastienDug) in [#77](https://github.com/brick/math/pull/77).
|
||||
|
||||
## [0.12.0](https://github.com/brick/math/releases/tag/0.12.0) - 2023-11-26
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- Minimum PHP version is now 8.1
|
||||
- `RoundingMode` is now an `enum`; if you're type-hinting rounding modes, you need to type-hint against `RoundingMode` instead of `int` now
|
||||
- `BigNumber` classes do not implement the `Serializable` interface anymore (they use the [new custom object serialization mechanism](https://wiki.php.net/rfc/custom_object_serialization))
|
||||
- The following breaking changes only affect you if you're creating your own `BigNumber` subclasses:
|
||||
- the return type of `BigNumber::of()` is now `static`
|
||||
- `BigNumber` has a new abstract method `from()`
|
||||
- all `public` and `protected` functions of `BigNumber` are now `final`
|
||||
|
||||
## [0.11.0](https://github.com/brick/math/releases/tag/0.11.0) - 2023-01-16
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- Minimum PHP version is now 8.0
|
||||
- Methods accepting a union of types are now strongly typed<sup>*</sup>
|
||||
- `MathException` now extends `Exception` instead of `RuntimeException`
|
||||
|
||||
<sup>* You may now run into type errors if you were passing `Stringable` objects to `of()` or any of the methods
|
||||
internally calling `of()`, with `strict_types` enabled. You can fix this by casting `Stringable` objects to `string`
|
||||
first.</sup>
|
||||
|
||||
## [0.10.2](https://github.com/brick/math/releases/tag/0.10.2) - 2022-08-11
|
||||
|
||||
👌 **Improvements**
|
||||
|
||||
- `BigRational::toFloat()` now simplifies the fraction before performing division (#73) thanks to @olsavmic
|
||||
|
||||
## [0.10.1](https://github.com/brick/math/releases/tag/0.10.1) - 2022-08-02
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::gcdMultiple()` returns the GCD of multiple `BigInteger` numbers
|
||||
|
||||
## [0.10.0](https://github.com/brick/math/releases/tag/0.10.0) - 2022-06-18
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- Minimum PHP version is now 7.4
|
||||
|
||||
## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15
|
||||
|
||||
🚀 **Compatibility with PHP 8.1**
|
||||
|
||||
- Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (#60) thanks @TRowbotham
|
||||
|
||||
## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20
|
||||
|
||||
🐛 **Bug fix**
|
||||
|
||||
- Incorrect results could be returned when using the BCMath calculator, with a default scale set with `bcscale()`, on PHP >= 7.2 (#55).
|
||||
|
||||
## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::not()` returns the bitwise `NOT` value
|
||||
|
||||
🐛 **Bug fixes**
|
||||
|
||||
- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers
|
||||
- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available
|
||||
|
||||
## [0.9.0](https://github.com/brick/math/releases/tag/0.9.0) - 2020-08-18
|
||||
|
||||
👌 **Improvements**
|
||||
|
||||
- `BigNumber::of()` now accepts `.123` and `123.` formats, both of which return a `BigDecimal`
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- Deprecated method `BigInteger::powerMod()` has been removed - use `modPow()` instead
|
||||
- Deprecated method `BigInteger::parse()` has been removed - use `fromBase()` instead
|
||||
|
||||
## [0.8.17](https://github.com/brick/math/releases/tag/0.8.17) - 2020-08-19
|
||||
|
||||
🐛 **Bug fix**
|
||||
|
||||
- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers
|
||||
- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available
|
||||
|
||||
## [0.8.16](https://github.com/brick/math/releases/tag/0.8.16) - 2020-08-18
|
||||
|
||||
🚑 **Critical fix**
|
||||
|
||||
- This version reintroduces the deprecated `BigInteger::parse()` method, that has been removed by mistake in version `0.8.9` and should have lasted for the whole `0.8` release cycle.
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::modInverse()` calculates a modular multiplicative inverse
|
||||
- `BigInteger::fromBytes()` creates a `BigInteger` from a byte string
|
||||
- `BigInteger::toBytes()` converts a `BigInteger` to a byte string
|
||||
- `BigInteger::randomBits()` creates a pseudo-random `BigInteger` of a given bit length
|
||||
- `BigInteger::randomRange()` creates a pseudo-random `BigInteger` between two bounds
|
||||
|
||||
💩 **Deprecations**
|
||||
|
||||
- `BigInteger::powerMod()` is now deprecated in favour of `modPow()`
|
||||
|
||||
## [0.8.15](https://github.com/brick/math/releases/tag/0.8.15) - 2020-04-15
|
||||
|
||||
🐛 **Fixes**
|
||||
|
||||
- added missing `ext-json` requirement, due to `BigNumber` implementing `JsonSerializable`
|
||||
|
||||
⚡️ **Optimizations**
|
||||
|
||||
- additional optimization in `BigInteger::remainder()`
|
||||
|
||||
## [0.8.14](https://github.com/brick/math/releases/tag/0.8.14) - 2020-02-18
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::getLowestSetBit()` returns the index of the rightmost one bit
|
||||
|
||||
## [0.8.13](https://github.com/brick/math/releases/tag/0.8.13) - 2020-02-16
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::isEven()` tests whether the number is even
|
||||
- `BigInteger::isOdd()` tests whether the number is odd
|
||||
- `BigInteger::testBit()` tests if a bit is set
|
||||
- `BigInteger::getBitLength()` returns the number of bits in the minimal representation of the number
|
||||
|
||||
## [0.8.12](https://github.com/brick/math/releases/tag/0.8.12) - 2020-02-03
|
||||
|
||||
🛠️ **Maintenance release**
|
||||
|
||||
Classes are now annotated for better static analysis with [psalm](https://psalm.dev/).
|
||||
|
||||
This is a maintenance release: no bug fixes, no new features, no breaking changes.
|
||||
|
||||
## [0.8.11](https://github.com/brick/math/releases/tag/0.8.11) - 2020-01-23
|
||||
|
||||
✨ **New feature**
|
||||
|
||||
`BigInteger::powerMod()` performs a power-with-modulo operation. Useful for crypto.
|
||||
|
||||
## [0.8.10](https://github.com/brick/math/releases/tag/0.8.10) - 2020-01-21
|
||||
|
||||
✨ **New feature**
|
||||
|
||||
`BigInteger::mod()` returns the **modulo** of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different.
|
||||
|
||||
## [0.8.9](https://github.com/brick/math/releases/tag/0.8.9) - 2020-01-08
|
||||
|
||||
⚡️ **Performance improvements**
|
||||
|
||||
A few additional optimizations in `BigInteger` and `BigDecimal` when one of the operands can be returned as is. Thanks to @tomtomsen in #24.
|
||||
|
||||
## [0.8.8](https://github.com/brick/math/releases/tag/0.8.8) - 2019-04-25
|
||||
|
||||
🐛 **Bug fixes**
|
||||
|
||||
- `BigInteger::toBase()` could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected)
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::toArbitraryBase()` converts a number to an arbitrary base, using a custom alphabet
|
||||
- `BigInteger::fromArbitraryBase()` converts a string in an arbitrary base, using a custom alphabet, back to a number
|
||||
|
||||
These methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation.
|
||||
|
||||
💩 **Deprecations**
|
||||
|
||||
- `BigInteger::parse()` is now deprecated in favour of `fromBase()`
|
||||
|
||||
`BigInteger::fromBase()` works the same way as `parse()`, with 2 minor differences:
|
||||
|
||||
- the `$base` parameter is required, it does not default to `10`
|
||||
- it throws a `NumberFormatException` instead of an `InvalidArgumentException` when the number is malformed
|
||||
|
||||
## [0.8.7](https://github.com/brick/math/releases/tag/0.8.7) - 2019-04-20
|
||||
|
||||
**Improvements**
|
||||
|
||||
- Safer conversion from `float` when using custom locales
|
||||
- **Much faster** `NativeCalculator` implementation 🚀
|
||||
|
||||
You can expect **at least a 3x performance improvement** for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before.
|
||||
|
||||
## [0.8.6](https://github.com/brick/math/releases/tag/0.8.6) - 2019-04-11
|
||||
|
||||
**New method**
|
||||
|
||||
`BigNumber::sum()` returns the sum of one or more numbers.
|
||||
|
||||
## [0.8.5](https://github.com/brick/math/releases/tag/0.8.5) - 2019-02-12
|
||||
|
||||
**Bug fix**: `of()` factory methods could fail when passing a `float` in environments using a `LC_NUMERIC` locale with a decimal separator other than `'.'` (#20).
|
||||
|
||||
Thanks @manowark 👍
|
||||
|
||||
## [0.8.4](https://github.com/brick/math/releases/tag/0.8.4) - 2018-12-07
|
||||
|
||||
**New method**
|
||||
|
||||
`BigDecimal::sqrt()` calculates the square root of a decimal number, to a given scale.
|
||||
|
||||
## [0.8.3](https://github.com/brick/math/releases/tag/0.8.3) - 2018-12-06
|
||||
|
||||
**New method**
|
||||
|
||||
`BigInteger::sqrt()` calculates the square root of a number (thanks @peter279k).
|
||||
|
||||
**New exception**
|
||||
|
||||
`NegativeNumberException` is thrown when calling `sqrt()` on a negative number.
|
||||
|
||||
## [0.8.2](https://github.com/brick/math/releases/tag/0.8.2) - 2018-11-08
|
||||
|
||||
**Performance update**
|
||||
|
||||
- Further improvement of `toInt()` performance
|
||||
- `NativeCalculator` can now perform some multiplications more efficiently
|
||||
|
||||
## [0.8.1](https://github.com/brick/math/releases/tag/0.8.1) - 2018-11-07
|
||||
|
||||
Performance optimization of `toInt()` methods.
|
||||
|
||||
## [0.8.0](https://github.com/brick/math/releases/tag/0.8.0) - 2018-10-13
|
||||
|
||||
**Breaking changes**
|
||||
|
||||
The following deprecated methods have been removed. Use the new method name instead:
|
||||
|
||||
| Method removed | Replacement method |
|
||||
| --- | --- |
|
||||
| `BigDecimal::getIntegral()` | `BigDecimal::getIntegralPart()` |
|
||||
| `BigDecimal::getFraction()` | `BigDecimal::getFractionalPart()` |
|
||||
|
||||
---
|
||||
|
||||
**New features**
|
||||
|
||||
`BigInteger` has been augmented with 5 new methods for bitwise operations:
|
||||
|
||||
| New method | Description |
|
||||
| --- | --- |
|
||||
| `and()` | performs a bitwise `AND` operation on two numbers |
|
||||
| `or()` | performs a bitwise `OR` operation on two numbers |
|
||||
| `xor()` | performs a bitwise `XOR` operation on two numbers |
|
||||
| `shiftedLeft()` | returns the number shifted left by a number of bits |
|
||||
| `shiftedRight()` | returns the number shifted right by a number of bits |
|
||||
|
||||
Thanks to @DASPRiD 👍
|
||||
|
||||
## [0.7.3](https://github.com/brick/math/releases/tag/0.7.3) - 2018-08-20
|
||||
|
||||
**New method:** `BigDecimal::hasNonZeroFractionalPart()`
|
||||
|
||||
**Renamed/deprecated methods:**
|
||||
|
||||
- `BigDecimal::getIntegral()` has been renamed to `getIntegralPart()` and is now deprecated
|
||||
- `BigDecimal::getFraction()` has been renamed to `getFractionalPart()` and is now deprecated
|
||||
|
||||
## [0.7.2](https://github.com/brick/math/releases/tag/0.7.2) - 2018-07-21
|
||||
|
||||
**Performance update**
|
||||
|
||||
`BigInteger::parse()` and `toBase()` now use GMP's built-in base conversion features when available.
|
||||
|
||||
## [0.7.1](https://github.com/brick/math/releases/tag/0.7.1) - 2018-03-01
|
||||
|
||||
This is a maintenance release, no code has been changed.
|
||||
|
||||
- When installed with `--no-dev`, the autoloader does not autoload tests anymore
|
||||
- Tests and other files unnecessary for production are excluded from the dist package
|
||||
|
||||
This will help make installations more compact.
|
||||
|
||||
## [0.7.0](https://github.com/brick/math/releases/tag/0.7.0) - 2017-10-02
|
||||
|
||||
Methods renamed:
|
||||
|
||||
- `BigNumber:sign()` has been renamed to `getSign()`
|
||||
- `BigDecimal::unscaledValue()` has been renamed to `getUnscaledValue()`
|
||||
- `BigDecimal::scale()` has been renamed to `getScale()`
|
||||
- `BigDecimal::integral()` has been renamed to `getIntegral()`
|
||||
- `BigDecimal::fraction()` has been renamed to `getFraction()`
|
||||
- `BigRational::numerator()` has been renamed to `getNumerator()`
|
||||
- `BigRational::denominator()` has been renamed to `getDenominator()`
|
||||
|
||||
Classes renamed:
|
||||
|
||||
- `ArithmeticException` has been renamed to `MathException`
|
||||
|
||||
## [0.6.2](https://github.com/brick/math/releases/tag/0.6.2) - 2017-10-02
|
||||
|
||||
The base class for all exceptions is now `MathException`.
|
||||
`ArithmeticException` has been deprecated, and will be removed in 0.7.0.
|
||||
|
||||
## [0.6.1](https://github.com/brick/math/releases/tag/0.6.1) - 2017-10-02
|
||||
|
||||
A number of methods have been renamed:
|
||||
|
||||
- `BigNumber:sign()` is deprecated; use `getSign()` instead
|
||||
- `BigDecimal::unscaledValue()` is deprecated; use `getUnscaledValue()` instead
|
||||
- `BigDecimal::scale()` is deprecated; use `getScale()` instead
|
||||
- `BigDecimal::integral()` is deprecated; use `getIntegral()` instead
|
||||
- `BigDecimal::fraction()` is deprecated; use `getFraction()` instead
|
||||
- `BigRational::numerator()` is deprecated; use `getNumerator()` instead
|
||||
- `BigRational::denominator()` is deprecated; use `getDenominator()` instead
|
||||
|
||||
The old methods will be removed in version 0.7.0.
|
||||
|
||||
## [0.6.0](https://github.com/brick/math/releases/tag/0.6.0) - 2017-08-25
|
||||
|
||||
- Minimum PHP version is now [7.1](https://gophp71.org/); for PHP 5.6 and PHP 7.0 support, use version `0.5`
|
||||
- Deprecated method `BigDecimal::withScale()` has been removed; use `toScale()` instead
|
||||
- Method `BigNumber::toInteger()` has been renamed to `toInt()`
|
||||
|
||||
## [0.5.4](https://github.com/brick/math/releases/tag/0.5.4) - 2016-10-17
|
||||
|
||||
`BigNumber` classes now implement [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php).
|
||||
The JSON output is always a string.
|
||||
|
||||
## [0.5.3](https://github.com/brick/math/releases/tag/0.5.3) - 2016-03-31
|
||||
|
||||
This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
||||
|
||||
## [0.5.2](https://github.com/brick/math/releases/tag/0.5.2) - 2015-08-06
|
||||
|
||||
The `$scale` parameter of `BigDecimal::dividedBy()` is now optional again.
|
||||
|
||||
## [0.5.1](https://github.com/brick/math/releases/tag/0.5.1) - 2015-07-05
|
||||
|
||||
**New method: `BigNumber::toScale()`**
|
||||
|
||||
This allows to convert any `BigNumber` to a `BigDecimal` with a given scale, using rounding if necessary.
|
||||
|
||||
## [0.5.0](https://github.com/brick/math/releases/tag/0.5.0) - 2015-07-04
|
||||
|
||||
**New features**
|
||||
- Common `BigNumber` interface for all classes, with the following methods:
|
||||
- `sign()` and derived methods (`isZero()`, `isPositive()`, ...)
|
||||
- `compareTo()` and derived methods (`isEqualTo()`, `isGreaterThan()`, ...) that work across different `BigNumber` types
|
||||
- `toBigInteger()`, `toBigDecimal()`, `toBigRational`() conversion methods
|
||||
- `toInteger()` and `toFloat()` conversion methods to native types
|
||||
- Unified `of()` behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type
|
||||
- New method: `BigDecimal::exactlyDividedBy()`; this method automatically computes the scale of the result, provided that the division yields a finite number of digits
|
||||
- New methods: `BigRational::quotient()` and `remainder()`
|
||||
- Fine-grained exceptions: `DivisionByZeroException`, `RoundingNecessaryException`, `NumberFormatException`
|
||||
- Factory methods `zero()`, `one()` and `ten()` available in all classes
|
||||
- Rounding mode reintroduced in `BigInteger::dividedBy()`
|
||||
|
||||
This release also comes with many performance improvements.
|
||||
|
||||
---
|
||||
|
||||
**Breaking changes**
|
||||
- `BigInteger`:
|
||||
- `getSign()` is renamed to `sign()`
|
||||
- `toString()` is renamed to `toBase()`
|
||||
- `BigInteger::dividedBy()` now throws an exception by default if the remainder is not zero; use `quotient()` to get the previous behaviour
|
||||
- `BigDecimal`:
|
||||
- `getSign()` is renamed to `sign()`
|
||||
- `getUnscaledValue()` is renamed to `unscaledValue()`
|
||||
- `getScale()` is renamed to `scale()`
|
||||
- `getIntegral()` is renamed to `integral()`
|
||||
- `getFraction()` is renamed to `fraction()`
|
||||
- `divideAndRemainder()` is renamed to `quotientAndRemainder()`
|
||||
- `dividedBy()` now takes a **mandatory** `$scale` parameter **before** the rounding mode
|
||||
- `toBigInteger()` does not accept a `$roundingMode` parameter anymore
|
||||
- `toBigRational()` does not simplify the fraction anymore; explicitly add `->simplified()` to get the previous behaviour
|
||||
- `BigRational`:
|
||||
- `getSign()` is renamed to `sign()`
|
||||
- `getNumerator()` is renamed to `numerator()`
|
||||
- `getDenominator()` is renamed to `denominator()`
|
||||
- `of()` is renamed to `nd()`, while `parse()` is renamed to `of()`
|
||||
- Miscellaneous:
|
||||
- `ArithmeticException` is moved to an `Exception\` sub-namespace
|
||||
- `of()` factory methods now throw `NumberFormatException` instead of `InvalidArgumentException`
|
||||
|
||||
## [0.4.3](https://github.com/brick/math/releases/tag/0.4.3) - 2016-03-31
|
||||
|
||||
Backport of two bug fixes from the 0.5 branch:
|
||||
- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected
|
||||
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
||||
|
||||
## [0.4.2](https://github.com/brick/math/releases/tag/0.4.2) - 2015-06-16
|
||||
|
||||
New method: `BigDecimal::stripTrailingZeros()`
|
||||
|
||||
## [0.4.1](https://github.com/brick/math/releases/tag/0.4.1) - 2015-06-12
|
||||
|
||||
Introducing a `BigRational` class, to perform calculations on fractions of any size.
|
||||
|
||||
## [0.4.0](https://github.com/brick/math/releases/tag/0.4.0) - 2015-06-12
|
||||
|
||||
Rounding modes have been removed from `BigInteger`, and are now a concept specific to `BigDecimal`.
|
||||
|
||||
`BigInteger::dividedBy()` now always returns the quotient of the division.
|
||||
|
||||
## [0.3.5](https://github.com/brick/math/releases/tag/0.3.5) - 2016-03-31
|
||||
|
||||
Backport of two bug fixes from the 0.5 branch:
|
||||
|
||||
- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected
|
||||
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
||||
|
||||
## [0.3.4](https://github.com/brick/math/releases/tag/0.3.4) - 2015-06-11
|
||||
|
||||
New methods:
|
||||
- `BigInteger::remainder()` returns the remainder of a division only
|
||||
- `BigInteger::gcd()` returns the greatest common divisor of two numbers
|
||||
|
||||
## [0.3.3](https://github.com/brick/math/releases/tag/0.3.3) - 2015-06-07
|
||||
|
||||
Fix `toString()` not handling negative numbers.
|
||||
|
||||
## [0.3.2](https://github.com/brick/math/releases/tag/0.3.2) - 2015-06-07
|
||||
|
||||
`BigInteger` and `BigDecimal` now have a `getSign()` method that returns:
|
||||
- `-1` if the number is negative
|
||||
- `0` if the number is zero
|
||||
- `1` if the number is positive
|
||||
|
||||
## [0.3.1](https://github.com/brick/math/releases/tag/0.3.1) - 2015-06-05
|
||||
|
||||
Minor performance improvements
|
||||
|
||||
## [0.3.0](https://github.com/brick/math/releases/tag/0.3.0) - 2015-06-04
|
||||
|
||||
The `$roundingMode` and `$scale` parameters have been swapped in `BigDecimal::dividedBy()`.
|
||||
|
||||
## [0.2.2](https://github.com/brick/math/releases/tag/0.2.2) - 2015-06-04
|
||||
|
||||
Stronger immutability guarantee for `BigInteger` and `BigDecimal`.
|
||||
|
||||
So far, it would have been possible to break immutability of these classes by calling the `unserialize()` internal function. This release fixes that.
|
||||
|
||||
## [0.2.1](https://github.com/brick/math/releases/tag/0.2.1) - 2015-06-02
|
||||
|
||||
Added `BigDecimal::divideAndRemainder()`
|
||||
|
||||
## [0.2.0](https://github.com/brick/math/releases/tag/0.2.0) - 2015-05-22
|
||||
|
||||
- `min()` and `max()` do not accept an `array` anymore, but a variable number of parameters
|
||||
- **minimum PHP version is now 5.6**
|
||||
- continuous integration with PHP 7
|
||||
|
||||
## [0.1.1](https://github.com/brick/math/releases/tag/0.1.1) - 2014-09-01
|
||||
|
||||
- Added `BigInteger::power()`
|
||||
- Added HHVM support
|
||||
|
||||
## [0.1.0](https://github.com/brick/math/releases/tag/0.1.0) - 2014-08-31
|
||||
|
||||
First beta release.
|
||||
|
||||
20
vendor/brick/math/LICENSE
vendored
Executable file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-present Benjamin Morel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
39
vendor/brick/math/composer.json
vendored
Executable file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "brick/math",
|
||||
"description": "Arbitrary-precision arithmetic library",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"Brick",
|
||||
"Math",
|
||||
"Mathematics",
|
||||
"Arbitrary-precision",
|
||||
"Arithmetic",
|
||||
"BigInteger",
|
||||
"BigDecimal",
|
||||
"BigRational",
|
||||
"BigNumber",
|
||||
"Bignum",
|
||||
"Decimal",
|
||||
"Rational",
|
||||
"Integer"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"phpstan/phpstan": "2.1.22"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Brick\\Math\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Brick\\Math\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
||||
14
vendor/brick/math/phpstan.neon
vendored
Executable file
@ -0,0 +1,14 @@
|
||||
parameters:
|
||||
level: 10
|
||||
checkUninitializedProperties: true
|
||||
paths:
|
||||
- src
|
||||
ignoreErrors:
|
||||
- '~Impure call to function array_shift\(\) in pure method~'
|
||||
- '~Possibly impure call to function assert\(\) in pure method~'
|
||||
- '~Possibly impure call to function hex2bin\(\) in pure method~'
|
||||
- '~Possibly impure call to function preg_match\(\) in pure method~'
|
||||
- '~Impure static variable in pure method Brick\\Math\\Big(Integer|Decimal|Rational)::(zero|one|ten)\(\)~'
|
||||
-
|
||||
message: '~Parameter #\d \$\S+ of function bc\S+ expects numeric-string, string given~'
|
||||
path: src/Internal/Calculator/BcMathCalculator.php
|
||||
874
vendor/brick/math/src/BigDecimal.php
vendored
Executable file
@ -0,0 +1,874 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NegativeNumberException;
|
||||
use Brick\Math\Internal\Calculator;
|
||||
use Brick\Math\Internal\CalculatorRegistry;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Override;
|
||||
|
||||
use function rtrim;
|
||||
use function sprintf;
|
||||
use function str_pad;
|
||||
use function str_repeat;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
|
||||
use const STR_PAD_LEFT;
|
||||
|
||||
/**
|
||||
* Immutable, arbitrary-precision signed decimal numbers.
|
||||
*/
|
||||
final readonly class BigDecimal extends BigNumber
|
||||
{
|
||||
/**
|
||||
* The unscaled value of this decimal number.
|
||||
*
|
||||
* This is a string of digits with an optional leading minus sign.
|
||||
* No leading zero must be present.
|
||||
* No leading minus sign must be present if the value is 0.
|
||||
*/
|
||||
private string $value;
|
||||
|
||||
/**
|
||||
* The scale (number of digits after the decimal point) of this decimal number.
|
||||
*
|
||||
* This must be zero or more.
|
||||
*/
|
||||
private int $scale;
|
||||
|
||||
/**
|
||||
* Protected constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param string $value The unscaled value, validated.
|
||||
* @param int $scale The scale, validated.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
protected function __construct(string $value, int $scale = 0)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->scale = $scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigDecimal from an unscaled value and a scale.
|
||||
*
|
||||
* Example: `(12345, 3)` will result in the BigDecimal `12.345`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger.
|
||||
* @param int $scale The scale of the number. If negative, the scale will be set to zero
|
||||
* and the unscaled value will be adjusted accordingly.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function ofUnscaledValue(BigNumber|int|float|string $value, int $scale = 0): BigDecimal
|
||||
{
|
||||
$value = (string) BigInteger::of($value);
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($value !== '0') {
|
||||
$value .= str_repeat('0', -$scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing zero, with a scale of zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function zero(): BigDecimal
|
||||
{
|
||||
/** @var BigDecimal|null $zero */
|
||||
static $zero;
|
||||
|
||||
if ($zero === null) {
|
||||
$zero = new BigDecimal('0');
|
||||
}
|
||||
|
||||
return $zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing one, with a scale of zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function one(): BigDecimal
|
||||
{
|
||||
/** @var BigDecimal|null $one */
|
||||
static $one;
|
||||
|
||||
if ($one === null) {
|
||||
$one = new BigDecimal('1');
|
||||
}
|
||||
|
||||
return $one;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing ten, with a scale of zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function ten(): BigDecimal
|
||||
{
|
||||
/** @var BigDecimal|null $ten */
|
||||
static $ten;
|
||||
|
||||
if ($ten === null) {
|
||||
$ten = new BigDecimal('10');
|
||||
}
|
||||
|
||||
return $ten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function plus(BigNumber|int|float|string $that): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->value === '0' && $this->scale <= $that->scale) {
|
||||
return $that;
|
||||
}
|
||||
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$value = CalculatorRegistry::get()->add($a, $b);
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function minus(BigNumber|int|float|string $that): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$value = CalculatorRegistry::get()->sub($a, $b);
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `$this->scale + $that->scale`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function multipliedBy(BigNumber|int|float|string $that): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '1' && $that->scale === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->value === '1' && $this->scale === 0) {
|
||||
return $that;
|
||||
}
|
||||
|
||||
$value = CalculatorRegistry::get()->mul($this->value, $that->value);
|
||||
$scale = $this->scale + $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the division of this number by the given one, at the given scale.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor.
|
||||
* @param int|null $scale The desired scale, or null to use the scale of this number.
|
||||
* @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY.
|
||||
*
|
||||
* @throws InvalidArgumentException If the scale or rounding mode is invalid.
|
||||
* @throws MathException If the number is invalid, is zero, or rounding was necessary.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
if ($scale === null) {
|
||||
$scale = $this->scale;
|
||||
} elseif ($scale < 0) {
|
||||
throw new InvalidArgumentException('Scale cannot be negative.');
|
||||
}
|
||||
|
||||
if ($that->value === '1' && $that->scale === 0 && $scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale + $scale);
|
||||
$q = $that->valueWithMinScale($this->scale - $scale);
|
||||
|
||||
$result = CalculatorRegistry::get()->divRound($p, $q, $roundingMode);
|
||||
|
||||
return new BigDecimal($result, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exact result of the division of this number by the given one.
|
||||
*
|
||||
* The scale of the result is automatically calculated to fit all the fraction digits.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero,
|
||||
* or the result yields an infinite number of digits.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function exactlyDividedBy(BigNumber|int|float|string $that): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0') {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
[, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$d = rtrim($b, '0');
|
||||
$scale = strlen($b) - strlen($d);
|
||||
|
||||
$calculator = CalculatorRegistry::get();
|
||||
|
||||
foreach ([5, 2] as $prime) {
|
||||
for (; ;) {
|
||||
$lastDigit = (int) $d[-1];
|
||||
|
||||
if ($lastDigit % $prime !== 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$d = $calculator->divQ($d, (string) $prime);
|
||||
$scale++;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dividedBy($that, $scale)->stripTrailingZeros();
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits (clamps) this number between the given minimum and maximum values.
|
||||
*
|
||||
* If the number is lower than $min, returns a copy of $min.
|
||||
* If the number is greater than $max, returns a copy of $max.
|
||||
* Otherwise, returns this number unchanged.
|
||||
*
|
||||
* @param BigNumber|int|float|string $min The minimum. Must be convertible to a BigDecimal.
|
||||
* @param BigNumber|int|float|string $max The maximum. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If min/max are not convertible to a BigDecimal.
|
||||
*/
|
||||
public function clamp(BigNumber|int|float|string $min, BigNumber|int|float|string $max): BigDecimal
|
||||
{
|
||||
if ($this->isLessThan($min)) {
|
||||
return BigDecimal::of($min);
|
||||
} elseif ($this->isGreaterThan($max)) {
|
||||
return BigDecimal::of($max);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this number exponentiated to the given value.
|
||||
*
|
||||
* The result has a scale of `$this->scale * $exponent`.
|
||||
*
|
||||
* @throws InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function power(int $exponent): BigDecimal
|
||||
{
|
||||
if ($exponent === 0) {
|
||||
return BigDecimal::one();
|
||||
}
|
||||
|
||||
if ($exponent === 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($exponent < 0 || $exponent > Calculator::MAX_POWER) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The exponent %d is not in the range 0 to %d.',
|
||||
$exponent,
|
||||
Calculator::MAX_POWER,
|
||||
));
|
||||
}
|
||||
|
||||
return new BigDecimal(CalculatorRegistry::get()->pow($this->value, $exponent), $this->scale * $exponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of this number by the given one.
|
||||
*
|
||||
* The quotient has a scale of `0`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function quotient(BigNumber|int|float|string $that): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
$quotient = CalculatorRegistry::get()->divQ($p, $q);
|
||||
|
||||
return new BigDecimal($quotient, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of this number by the given one.
|
||||
*
|
||||
* The remainder has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function remainder(BigNumber|int|float|string $that): BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
$remainder = CalculatorRegistry::get()->divR($p, $q);
|
||||
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($remainder, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of this number by the given one.
|
||||
*
|
||||
* The quotient has a scale of `0`, and the remainder has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return array{BigDecimal, BigDecimal} An array containing the quotient and the remainder.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function quotientAndRemainder(BigNumber|int|float|string $that): array
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
[$quotient, $remainder] = CalculatorRegistry::get()->divQR($p, $q);
|
||||
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
$quotient = new BigDecimal($quotient, 0);
|
||||
$remainder = new BigDecimal($remainder, $scale);
|
||||
|
||||
return [$quotient, $remainder];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of this number, rounded down to the given number of decimals.
|
||||
*
|
||||
* @throws InvalidArgumentException If the scale is negative.
|
||||
* @throws NegativeNumberException If this number is negative.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function sqrt(int $scale): BigDecimal
|
||||
{
|
||||
if ($scale < 0) {
|
||||
throw new InvalidArgumentException('Scale cannot be negative.');
|
||||
}
|
||||
|
||||
if ($this->value === '0') {
|
||||
return new BigDecimal('0', $scale);
|
||||
}
|
||||
|
||||
if ($this->value[0] === '-') {
|
||||
throw new NegativeNumberException('Cannot calculate the square root of a negative number.');
|
||||
}
|
||||
|
||||
$value = $this->value;
|
||||
$addDigits = 2 * $scale - $this->scale;
|
||||
|
||||
if ($addDigits > 0) {
|
||||
// add zeros
|
||||
$value .= str_repeat('0', $addDigits);
|
||||
} elseif ($addDigits < 0) {
|
||||
// trim digits
|
||||
if (-$addDigits >= strlen($this->value)) {
|
||||
// requesting a scale too low, will always yield a zero result
|
||||
return new BigDecimal('0', $scale);
|
||||
}
|
||||
|
||||
$value = substr($value, 0, $addDigits);
|
||||
}
|
||||
|
||||
$value = CalculatorRegistry::get()->sqrt($value);
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the left.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function withPointMovedLeft(int $n): BigDecimal
|
||||
{
|
||||
if ($n === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($n < 0) {
|
||||
return $this->withPointMovedRight(-$n);
|
||||
}
|
||||
|
||||
return new BigDecimal($this->value, $this->scale + $n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the right.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function withPointMovedRight(int $n): BigDecimal
|
||||
{
|
||||
if ($n === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($n < 0) {
|
||||
return $this->withPointMovedLeft(-$n);
|
||||
}
|
||||
|
||||
$value = $this->value;
|
||||
$scale = $this->scale - $n;
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($value !== '0') {
|
||||
$value .= str_repeat('0', -$scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function stripTrailingZeros(): BigDecimal
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$trimmedValue = rtrim($this->value, '0');
|
||||
|
||||
if ($trimmedValue === '') {
|
||||
return BigDecimal::zero();
|
||||
}
|
||||
|
||||
$trimmableZeros = strlen($this->value) - strlen($trimmedValue);
|
||||
|
||||
if ($trimmableZeros === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($trimmableZeros > $this->scale) {
|
||||
$trimmableZeros = $this->scale;
|
||||
}
|
||||
|
||||
$value = substr($this->value, 0, -$trimmableZeros);
|
||||
$scale = $this->scale - $trimmableZeros;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function abs(): BigDecimal
|
||||
{
|
||||
return $this->isNegative() ? $this->negated() : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function negated(): BigDecimal
|
||||
{
|
||||
return new BigDecimal(CalculatorRegistry::get()->neg($this->value), $this->scale);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function compareTo(BigNumber|int|float|string $that): int
|
||||
{
|
||||
$that = BigNumber::of($that);
|
||||
|
||||
if ($that instanceof BigInteger) {
|
||||
$that = $that->toBigDecimal();
|
||||
}
|
||||
|
||||
if ($that instanceof BigDecimal) {
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
return CalculatorRegistry::get()->cmp($a, $b);
|
||||
}
|
||||
|
||||
return -$that->compareTo($this);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getSign(): int
|
||||
{
|
||||
return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public function getUnscaledValue(): BigInteger
|
||||
{
|
||||
return self::newBigInteger($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public function getScale(): int
|
||||
{
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of significant digits in the number.
|
||||
*
|
||||
* This is the number of digits to both sides of the decimal point, stripped of leading zeros.
|
||||
* The sign has no impact on the result.
|
||||
*
|
||||
* Examples:
|
||||
* 0 => 0
|
||||
* 0.0 => 0
|
||||
* 123 => 3
|
||||
* 123.456 => 6
|
||||
* 0.00123 => 3
|
||||
* 0.0012300 => 5
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function getPrecision(): int
|
||||
{
|
||||
$value = $this->value;
|
||||
|
||||
if ($value === '0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$length = strlen($value);
|
||||
|
||||
return ($value[0] === '-') ? $length - 1 : $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the integral part of this decimal number.
|
||||
*
|
||||
* Example: `-123.456` => `-123`.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function getIntegralPart(): string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return substr($value, 0, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the fractional part of this decimal number.
|
||||
*
|
||||
* If the scale is zero, an empty string is returned.
|
||||
*
|
||||
* Examples: `-123.456` => '456', `123` => ''.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function getFractionalPart(): string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return substr($value, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this decimal number has a non-zero fractional part.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function hasNonZeroFractionalPart(): bool
|
||||
{
|
||||
return $this->getFractionalPart() !== str_repeat('0', $this->scale);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBigInteger(): BigInteger
|
||||
{
|
||||
$zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0);
|
||||
|
||||
return self::newBigInteger($zeroScaleDecimal->value);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBigDecimal(): BigDecimal
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBigRational(): BigRational
|
||||
{
|
||||
$numerator = self::newBigInteger($this->value);
|
||||
$denominator = self::newBigInteger('1' . str_repeat('0', $this->scale));
|
||||
|
||||
return self::newBigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY): BigDecimal
|
||||
{
|
||||
if ($scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toInt(): int
|
||||
{
|
||||
return $this->toBigInteger()->toInt();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toFloat(): float
|
||||
{
|
||||
return (float) (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return numeric-string
|
||||
*/
|
||||
#[Override]
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
/** @var numeric-string */
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
/** @phpstan-ignore return.type */
|
||||
return substr($value, 0, -$this->scale) . '.' . substr($value, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required for serializing the object and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return array{value: string, scale: int}
|
||||
*/
|
||||
public function __serialize(): array
|
||||
{
|
||||
return ['value' => $this->value, 'scale' => $this->scale];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to allow unserializing the object and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array{value: string, scale: int} $data
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
/** @phpstan-ignore isset.initializedProperty */
|
||||
if (isset($this->value)) {
|
||||
throw new LogicException('__unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
/** @phpstan-ignore deadCode.unreachable */
|
||||
$this->value = $data['value'];
|
||||
$this->scale = $data['scale'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
protected static function from(BigNumber $number): static
|
||||
{
|
||||
return $number->toBigDecimal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the internal values of the given decimal numbers on the same scale.
|
||||
*
|
||||
* @return array{string, string} The scaled integer values of $x and $y.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function scaleValues(BigDecimal $x, BigDecimal $y): array
|
||||
{
|
||||
$a = $x->value;
|
||||
$b = $y->value;
|
||||
|
||||
if ($b !== '0' && $x->scale > $y->scale) {
|
||||
$b .= str_repeat('0', $x->scale - $y->scale);
|
||||
} elseif ($a !== '0' && $x->scale < $y->scale) {
|
||||
$a .= str_repeat('0', $y->scale - $x->scale);
|
||||
}
|
||||
|
||||
return [$a, $b];
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
private function valueWithMinScale(int $scale): string
|
||||
{
|
||||
$value = $this->value;
|
||||
|
||||
if ($this->value !== '0' && $scale > $this->scale) {
|
||||
$value .= str_repeat('0', $scale - $this->scale);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds leading zeros if necessary to the unscaled value to represent the full decimal number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function getUnscaledValueWithLeadingZeros(): string
|
||||
{
|
||||
$value = $this->value;
|
||||
$targetLength = $this->scale + 1;
|
||||
$negative = ($value[0] === '-');
|
||||
$length = strlen($value);
|
||||
|
||||
if ($negative) {
|
||||
$length--;
|
||||
}
|
||||
|
||||
if ($length >= $targetLength) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
if ($negative) {
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
|
||||
$value = str_pad($value, $targetLength, '0', STR_PAD_LEFT);
|
||||
|
||||
if ($negative) {
|
||||
$value = '-' . $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
1161
vendor/brick/math/src/BigInteger.php
vendored
Executable file
621
vendor/brick/math/src/BigNumber.php
vendored
Executable file
@ -0,0 +1,621 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NumberFormatException;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
use Override;
|
||||
use Stringable;
|
||||
|
||||
use function array_shift;
|
||||
use function assert;
|
||||
use function filter_var;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
use function is_nan;
|
||||
use function is_null;
|
||||
use function ltrim;
|
||||
use function preg_match;
|
||||
use function str_contains;
|
||||
use function str_repeat;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
|
||||
use const FILTER_VALIDATE_INT;
|
||||
|
||||
use const PREG_UNMATCHED_AS_NULL;
|
||||
|
||||
/**
|
||||
* Base class for arbitrary-precision numbers.
|
||||
*
|
||||
* This class is sealed: it is part of the public API but should not be subclassed in userland.
|
||||
* Protected methods may change in any version.
|
||||
*
|
||||
* @phpstan-sealed BigInteger|BigDecimal|BigRational
|
||||
*/
|
||||
abstract readonly class BigNumber implements JsonSerializable, Stringable
|
||||
{
|
||||
/**
|
||||
* The regular expression used to parse integer or decimal numbers.
|
||||
*/
|
||||
private const PARSE_REGEXP_NUMERICAL =
|
||||
'/^' .
|
||||
'(?<sign>[\-\+])?' .
|
||||
'(?<integral>[0-9]+)?' .
|
||||
'(?<point>\.)?' .
|
||||
'(?<fractional>[0-9]+)?' .
|
||||
'(?:[eE](?<exponent>[\-\+]?[0-9]+))?' .
|
||||
'$/';
|
||||
|
||||
/**
|
||||
* The regular expression used to parse rational numbers.
|
||||
*/
|
||||
private const PARSE_REGEXP_RATIONAL =
|
||||
'/^' .
|
||||
'(?<sign>[\-\+])?' .
|
||||
'(?<numerator>[0-9]+)' .
|
||||
'\/?' .
|
||||
'(?<denominator>[0-9]+)' .
|
||||
'$/';
|
||||
|
||||
/**
|
||||
* Creates a BigNumber of the given value.
|
||||
*
|
||||
* When of() is called on BigNumber, the concrete return type is dependent on the given value, with the following
|
||||
* rules:
|
||||
*
|
||||
* - BigNumber instances are returned as is
|
||||
* - integer numbers are returned as BigInteger
|
||||
* - floating point numbers are converted to a string then parsed as such
|
||||
* - strings containing a `/` character are returned as BigRational
|
||||
* - strings containing a `.` character or using an exponential notation are returned as BigDecimal
|
||||
* - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger
|
||||
*
|
||||
* When of() is called on BigInteger, BigDecimal, or BigRational, the resulting number is converted to an instance
|
||||
* of the subclass when possible; otherwise a RoundingNecessaryException exception is thrown.
|
||||
*
|
||||
* @throws NumberFormatException If the format of the number is not valid.
|
||||
* @throws DivisionByZeroException If the value represents a rational number with a denominator of zero.
|
||||
* @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public static function of(BigNumber|int|float|string $value): static
|
||||
{
|
||||
$value = self::_of($value);
|
||||
|
||||
if (static::class === BigNumber::class) {
|
||||
assert($value instanceof static);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
return static::from($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigNumber of the given value, or returns null if the input is null.
|
||||
*
|
||||
* Behaves like of() for non-null values.
|
||||
*
|
||||
* @see BigNumber::of()
|
||||
*
|
||||
* @throws NumberFormatException If the format of the number is not valid.
|
||||
* @throws DivisionByZeroException If the value represents a rational number with a denominator of zero.
|
||||
* @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding.
|
||||
*/
|
||||
public static function ofNullable(BigNumber|int|float|string|null $value): ?static
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return static::of($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @throws InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public static function min(BigNumber|int|float|string ...$values): static
|
||||
{
|
||||
$min = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($min === null || $value->isLessThan($min)) {
|
||||
$min = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($min === null) {
|
||||
throw new InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @throws InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public static function max(BigNumber|int|float|string ...$values): static
|
||||
{
|
||||
$max = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($max === null || $value->isGreaterThan($max)) {
|
||||
$max = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($max === null) {
|
||||
throw new InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of the given values.
|
||||
*
|
||||
* When called on BigNumber, sum() accepts any supported type and returns a result whose type is the widest among
|
||||
* the given values (BigInteger < BigDecimal < BigRational).
|
||||
*
|
||||
* When called on BigInteger, BigDecimal, or BigRational, sum() requires that all values can be converted to that
|
||||
* specific subclass, and returns a result of the same type.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The values to add. All values must be convertible to the class on
|
||||
* which this method is called.
|
||||
*
|
||||
* @throws InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public static function sum(BigNumber|int|float|string ...$values): static
|
||||
{
|
||||
$first = array_shift($values);
|
||||
|
||||
if ($first === null) {
|
||||
throw new InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
$sum = static::of($first);
|
||||
|
||||
foreach ($values as $value) {
|
||||
$sum = self::add($sum, static::of($value));
|
||||
}
|
||||
|
||||
assert($sum instanceof static);
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is equal to the given one.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isEqualTo(BigNumber|int|float|string $that): bool
|
||||
{
|
||||
return $this->compareTo($that) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly lower than the given one.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isLessThan(BigNumber|int|float|string $that): bool
|
||||
{
|
||||
return $this->compareTo($that) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is lower than or equal to the given one.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isLessThanOrEqualTo(BigNumber|int|float|string $that): bool
|
||||
{
|
||||
return $this->compareTo($that) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly greater than the given one.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isGreaterThan(BigNumber|int|float|string $that): bool
|
||||
{
|
||||
return $this->compareTo($that) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is greater than or equal to the given one.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isGreaterThanOrEqualTo(BigNumber|int|float|string $that): bool
|
||||
{
|
||||
return $this->compareTo($that) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number equals zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isZero(): bool
|
||||
{
|
||||
return $this->getSign() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly negative.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isNegative(): bool
|
||||
{
|
||||
return $this->getSign() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is negative or zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isNegativeOrZero(): bool
|
||||
{
|
||||
return $this->getSign() <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly positive.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isPositive(): bool
|
||||
{
|
||||
return $this->getSign() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is positive or zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function isPositiveOrZero(): bool
|
||||
{
|
||||
return $this->getSign() >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sign of this number.
|
||||
*
|
||||
* Returns -1 if the number is negative, 0 if zero, 1 if positive.
|
||||
*
|
||||
* @return -1|0|1
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function getSign(): int;
|
||||
|
||||
/**
|
||||
* Compares this number to the given one.
|
||||
*
|
||||
* Returns -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`.
|
||||
*
|
||||
* @return -1|0|1
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function compareTo(BigNumber|int|float|string $that): int;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigInteger.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function toBigInteger(): BigInteger;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function toBigDecimal(): BigDecimal;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigRational.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function toBigRational(): BigRational;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal with the given scale, using rounding if necessary.
|
||||
*
|
||||
* @param int $scale The scale of the resulting `BigDecimal`.
|
||||
* @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding.
|
||||
* This only applies when RoundingMode::UNNECESSARY is used.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY): BigDecimal;
|
||||
|
||||
/**
|
||||
* Returns the exact value of this number as a native integer.
|
||||
*
|
||||
* If this number cannot be converted to a native integer without losing precision, an exception is thrown.
|
||||
* Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit.
|
||||
*
|
||||
* @throws MathException If this number cannot be exactly converted to a native integer.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function toInt(): int;
|
||||
|
||||
/**
|
||||
* Returns an approximation of this number as a floating-point value.
|
||||
*
|
||||
* Note that this method can discard information as the precision of a floating-point value
|
||||
* is inherently limited.
|
||||
*
|
||||
* If the number is greater than the largest representable floating point number, positive infinity is returned.
|
||||
* If the number is less than the smallest representable floating point number, negative infinity is returned.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function toFloat(): float;
|
||||
|
||||
#[Override]
|
||||
final public function jsonSerialize(): string
|
||||
{
|
||||
return $this->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this number.
|
||||
*
|
||||
* The output of this method can be parsed by the `of()` factory method;
|
||||
* this will yield an object equal to this one, without any information loss.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function __toString(): string;
|
||||
|
||||
/**
|
||||
* Overridden by subclasses to convert a BigNumber to an instance of the subclass.
|
||||
*
|
||||
* @throws RoundingNecessaryException If the value cannot be converted.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract protected static function from(BigNumber $number): static;
|
||||
|
||||
/**
|
||||
* Proxy method to access BigInteger's protected constructor from sibling classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final protected function newBigInteger(string $value): BigInteger
|
||||
{
|
||||
return new BigInteger($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy method to access BigDecimal's protected constructor from sibling classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final protected function newBigDecimal(string $value, int $scale = 0): BigDecimal
|
||||
{
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy method to access BigRational's protected constructor from sibling classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final protected function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator): BigRational
|
||||
{
|
||||
return new BigRational($numerator, $denominator, $checkDenominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NumberFormatException If the format of the number is not valid.
|
||||
* @throws DivisionByZeroException If the value represents a rational number with a denominator of zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private static function _of(BigNumber|int|float|string $value): BigNumber
|
||||
{
|
||||
if ($value instanceof BigNumber) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_int($value)) {
|
||||
return new BigInteger((string) $value);
|
||||
}
|
||||
|
||||
if (is_float($value)) {
|
||||
if (is_nan($value)) {
|
||||
$value = 'NAN';
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains($value, '/')) {
|
||||
// Rational number
|
||||
if (preg_match(self::PARSE_REGEXP_RATIONAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) {
|
||||
throw NumberFormatException::invalidFormat($value);
|
||||
}
|
||||
|
||||
$sign = $matches['sign'];
|
||||
$numerator = $matches['numerator'];
|
||||
$denominator = $matches['denominator'];
|
||||
|
||||
$numerator = self::cleanUp($sign, $numerator);
|
||||
$denominator = self::cleanUp(null, $denominator);
|
||||
|
||||
if ($denominator === '0') {
|
||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
||||
}
|
||||
|
||||
return new BigRational(
|
||||
new BigInteger($numerator),
|
||||
new BigInteger($denominator),
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
// Integer or decimal number
|
||||
if (preg_match(self::PARSE_REGEXP_NUMERICAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) {
|
||||
throw NumberFormatException::invalidFormat($value);
|
||||
}
|
||||
|
||||
$sign = $matches['sign'];
|
||||
$point = $matches['point'];
|
||||
$integral = $matches['integral'];
|
||||
$fractional = $matches['fractional'];
|
||||
$exponent = $matches['exponent'];
|
||||
|
||||
if ($integral === null && $fractional === null) {
|
||||
throw NumberFormatException::invalidFormat($value);
|
||||
}
|
||||
|
||||
if ($integral === null) {
|
||||
$integral = '0';
|
||||
}
|
||||
|
||||
if ($point !== null || $exponent !== null) {
|
||||
$fractional ??= '';
|
||||
|
||||
if ($exponent !== null) {
|
||||
if ($exponent[0] === '-') {
|
||||
$exponent = ltrim(substr($exponent, 1), '0') ?: '0';
|
||||
$exponent = filter_var($exponent, FILTER_VALIDATE_INT);
|
||||
if ($exponent !== false) {
|
||||
$exponent = -$exponent;
|
||||
}
|
||||
} else {
|
||||
if ($exponent[0] === '+') {
|
||||
$exponent = substr($exponent, 1);
|
||||
}
|
||||
$exponent = ltrim($exponent, '0') ?: '0';
|
||||
$exponent = filter_var($exponent, FILTER_VALIDATE_INT);
|
||||
}
|
||||
} else {
|
||||
$exponent = 0;
|
||||
}
|
||||
|
||||
if ($exponent === false) {
|
||||
throw new NumberFormatException('Exponent too large.');
|
||||
}
|
||||
|
||||
$unscaledValue = self::cleanUp($sign, $integral . $fractional);
|
||||
|
||||
$scale = strlen($fractional) - $exponent;
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($unscaledValue !== '0') {
|
||||
$unscaledValue .= str_repeat('0', -$scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($unscaledValue, $scale);
|
||||
}
|
||||
|
||||
$integral = self::cleanUp($sign, $integral);
|
||||
|
||||
return new BigInteger($integral);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes optional leading zeros and applies sign.
|
||||
*
|
||||
* @param string|null $sign The sign, '+' or '-', optional. Null is allowed for convenience and treated as '+'.
|
||||
* @param string $number The number, validated as a string of digits.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private static function cleanUp(string|null $sign, string $number): string
|
||||
{
|
||||
$number = ltrim($number, '0');
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
return $sign === '-' ? '-' . $number : $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private static function add(BigNumber $a, BigNumber $b): BigNumber
|
||||
{
|
||||
if ($a instanceof BigRational) {
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
if ($b instanceof BigRational) {
|
||||
return $b->plus($a);
|
||||
}
|
||||
|
||||
if ($a instanceof BigDecimal) {
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
if ($b instanceof BigDecimal) {
|
||||
return $b->plus($a);
|
||||
}
|
||||
|
||||
return $a->plus($b);
|
||||
}
|
||||
}
|
||||
444
vendor/brick/math/src/BigRational.php
vendored
Executable file
@ -0,0 +1,444 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NumberFormatException;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* An arbitrarily large rational number.
|
||||
*
|
||||
* This class is immutable.
|
||||
*/
|
||||
final readonly class BigRational extends BigNumber
|
||||
{
|
||||
/**
|
||||
* The numerator.
|
||||
*/
|
||||
private BigInteger $numerator;
|
||||
|
||||
/**
|
||||
* The denominator. Always strictly positive.
|
||||
*/
|
||||
private BigInteger $denominator;
|
||||
|
||||
/**
|
||||
* Protected constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param BigInteger $numerator The numerator.
|
||||
* @param BigInteger $denominator The denominator.
|
||||
* @param bool $checkDenominator Whether to check the denominator for negative and zero.
|
||||
*
|
||||
* @throws DivisionByZeroException If the denominator is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
protected function __construct(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator)
|
||||
{
|
||||
if ($checkDenominator) {
|
||||
if ($denominator->isZero()) {
|
||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
||||
}
|
||||
|
||||
if ($denominator->isNegative()) {
|
||||
$numerator = $numerator->negated();
|
||||
$denominator = $denominator->negated();
|
||||
}
|
||||
}
|
||||
|
||||
$this->numerator = $numerator;
|
||||
$this->denominator = $denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigRational out of a numerator and a denominator.
|
||||
*
|
||||
* If the denominator is negative, the signs of both the numerator and the denominator
|
||||
* will be inverted to ensure that the denominator is always positive.
|
||||
*
|
||||
* @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger.
|
||||
* @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger.
|
||||
*
|
||||
* @throws NumberFormatException If an argument does not represent a valid number.
|
||||
* @throws RoundingNecessaryException If an argument represents a non-integer number.
|
||||
* @throws DivisionByZeroException If the denominator is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function nd(
|
||||
BigNumber|int|float|string $numerator,
|
||||
BigNumber|int|float|string $denominator,
|
||||
): BigRational {
|
||||
$numerator = BigInteger::of($numerator);
|
||||
$denominator = BigInteger::of($denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function zero(): BigRational
|
||||
{
|
||||
/** @var BigRational|null $zero */
|
||||
static $zero;
|
||||
|
||||
if ($zero === null) {
|
||||
$zero = new BigRational(BigInteger::zero(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing one.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function one(): BigRational
|
||||
{
|
||||
/** @var BigRational|null $one */
|
||||
static $one;
|
||||
|
||||
if ($one === null) {
|
||||
$one = new BigRational(BigInteger::one(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $one;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing ten.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function ten(): BigRational
|
||||
{
|
||||
/** @var BigRational|null $ten */
|
||||
static $ten;
|
||||
|
||||
if ($ten === null) {
|
||||
$ten = new BigRational(BigInteger::ten(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $ten;
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public function getNumerator(): BigInteger
|
||||
{
|
||||
return $this->numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public function getDenominator(): BigInteger
|
||||
{
|
||||
return $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of the numerator by the denominator.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function quotient(): BigInteger
|
||||
{
|
||||
return $this->numerator->quotient($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of the numerator by the denominator.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function remainder(): BigInteger
|
||||
{
|
||||
return $this->numerator->remainder($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return array{BigInteger, BigInteger}
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function quotientAndRemainder(): array
|
||||
{
|
||||
return $this->numerator->quotientAndRemainder($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to add.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function plus(BigNumber|int|float|string $that): BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to subtract.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function minus(BigNumber|int|float|string $that): BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The multiplier.
|
||||
*
|
||||
* @throws MathException If the multiplier is not a valid number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function multipliedBy(BigNumber|int|float|string $that): BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->numerator);
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the division of this number by the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid number, or is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function dividedBy(BigNumber|int|float|string $that): BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$denominator = $this->denominator->multipliedBy($that->numerator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this number exponentiated to the given value.
|
||||
*
|
||||
* @throws InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function power(int $exponent): BigRational
|
||||
{
|
||||
if ($exponent === 0) {
|
||||
$one = BigInteger::one();
|
||||
|
||||
return new BigRational($one, $one, false);
|
||||
}
|
||||
|
||||
if ($exponent === 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new BigRational(
|
||||
$this->numerator->power($exponent),
|
||||
$this->denominator->power($exponent),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reciprocal of this BigRational.
|
||||
*
|
||||
* The reciprocal has the numerator and denominator swapped.
|
||||
*
|
||||
* @throws DivisionByZeroException If the numerator is zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function reciprocal(): BigRational
|
||||
{
|
||||
return new BigRational($this->denominator, $this->numerator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this BigRational.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function abs(): BigRational
|
||||
{
|
||||
return new BigRational($this->numerator->abs(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this BigRational.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function negated(): BigRational
|
||||
{
|
||||
return new BigRational($this->numerator->negated(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the simplified value of this BigRational.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function simplified(): BigRational
|
||||
{
|
||||
$gcd = $this->numerator->gcd($this->denominator);
|
||||
|
||||
$numerator = $this->numerator->quotient($gcd);
|
||||
$denominator = $this->denominator->quotient($gcd);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function compareTo(BigNumber|int|float|string $that): int
|
||||
{
|
||||
return $this->minus($that)->getSign();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getSign(): int
|
||||
{
|
||||
return $this->numerator->getSign();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBigInteger(): BigInteger
|
||||
{
|
||||
$simplified = $this->simplified();
|
||||
|
||||
if (! $simplified->denominator->isEqualTo(1)) {
|
||||
throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.');
|
||||
}
|
||||
|
||||
return $simplified->numerator;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBigDecimal(): BigDecimal
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBigRational(): BigRational
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY): BigDecimal
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toInt(): int
|
||||
{
|
||||
return $this->toBigInteger()->toInt();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toFloat(): float
|
||||
{
|
||||
$simplified = $this->simplified();
|
||||
|
||||
return $simplified->numerator->toFloat() / $simplified->denominator->toFloat();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function __toString(): string
|
||||
{
|
||||
$numerator = (string) $this->numerator;
|
||||
$denominator = (string) $this->denominator;
|
||||
|
||||
if ($denominator === '1') {
|
||||
return $numerator;
|
||||
}
|
||||
|
||||
return $numerator . '/' . $denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required for serializing the object and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return array{numerator: BigInteger, denominator: BigInteger}
|
||||
*/
|
||||
public function __serialize(): array
|
||||
{
|
||||
return ['numerator' => $this->numerator, 'denominator' => $this->denominator];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to allow unserializing the object and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array{numerator: BigInteger, denominator: BigInteger} $data
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
/** @phpstan-ignore isset.initializedProperty */
|
||||
if (isset($this->numerator)) {
|
||||
throw new LogicException('__unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
/** @phpstan-ignore deadCode.unreachable */
|
||||
$this->numerator = $data['numerator'];
|
||||
$this->denominator = $data['denominator'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
protected static function from(BigNumber $number): static
|
||||
{
|
||||
return $number->toBigRational();
|
||||
}
|
||||
}
|
||||
35
vendor/brick/math/src/Exception/DivisionByZeroException.php
vendored
Executable file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a division by zero occurs.
|
||||
*/
|
||||
final class DivisionByZeroException extends MathException
|
||||
{
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public static function divisionByZero(): DivisionByZeroException
|
||||
{
|
||||
return new self('Division by zero.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public static function modulusMustNotBeZero(): DivisionByZeroException
|
||||
{
|
||||
return new self('The modulus must not be zero.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public static function denominatorMustNotBeZero(): DivisionByZeroException
|
||||
{
|
||||
return new self('The denominator of a rational number cannot be zero.');
|
||||
}
|
||||
}
|
||||
28
vendor/brick/math/src/Exception/IntegerOverflowException.php
vendored
Executable file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
use Brick\Math\BigInteger;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
use const PHP_INT_MAX;
|
||||
use const PHP_INT_MIN;
|
||||
|
||||
/**
|
||||
* Exception thrown when an integer overflow occurs.
|
||||
*/
|
||||
final class IntegerOverflowException extends MathException
|
||||
{
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public static function toIntOverflow(BigInteger $value): IntegerOverflowException
|
||||
{
|
||||
$message = '%s is out of range %d to %d and cannot be represented as an integer.';
|
||||
|
||||
return new self(sprintf($message, (string) $value, PHP_INT_MIN, PHP_INT_MAX));
|
||||
}
|
||||
}
|
||||
14
vendor/brick/math/src/Exception/MathException.php
vendored
Executable file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Base class for all math exceptions.
|
||||
*/
|
||||
class MathException extends RuntimeException
|
||||
{
|
||||
}
|
||||
12
vendor/brick/math/src/Exception/NegativeNumberException.php
vendored
Executable file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to perform an unsupported operation, such as a square root, on a negative number.
|
||||
*/
|
||||
final class NegativeNumberException extends MathException
|
||||
{
|
||||
}
|
||||
49
vendor/brick/math/src/Exception/NumberFormatException.php
vendored
Executable file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
use function dechex;
|
||||
use function ord;
|
||||
use function sprintf;
|
||||
use function strtoupper;
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to create a number from a string with an invalid format.
|
||||
*/
|
||||
final class NumberFormatException extends MathException
|
||||
{
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public static function invalidFormat(string $value): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'The given value "%s" does not represent a valid number.',
|
||||
$value,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $char The failing character.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public static function charNotInAlphabet(string $char): self
|
||||
{
|
||||
$ord = ord($char);
|
||||
|
||||
if ($ord < 32 || $ord > 126) {
|
||||
$char = strtoupper(dechex($ord));
|
||||
|
||||
if ($ord < 10) {
|
||||
$char = '0' . $char;
|
||||
}
|
||||
} else {
|
||||
$char = '"' . $char . '"';
|
||||
}
|
||||
|
||||
return new self(sprintf('Char %s is not a valid character in the given alphabet.', $char));
|
||||
}
|
||||
}
|
||||
19
vendor/brick/math/src/Exception/RoundingNecessaryException.php
vendored
Executable file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a number cannot be represented at the requested scale without rounding.
|
||||
*/
|
||||
final class RoundingNecessaryException extends MathException
|
||||
{
|
||||
/**
|
||||
* @pure
|
||||
*/
|
||||
public static function roundingNecessary(): RoundingNecessaryException
|
||||
{
|
||||
return new self('Rounding is necessary to represent the result of the operation at this scale.');
|
||||
}
|
||||
}
|
||||
685
vendor/brick/math/src/Internal/Calculator.php
vendored
Executable file
@ -0,0 +1,685 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal;
|
||||
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
use Brick\Math\RoundingMode;
|
||||
|
||||
use function chr;
|
||||
use function ltrim;
|
||||
use function ord;
|
||||
use function str_repeat;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strrev;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
* Performs basic operations on arbitrary size integers.
|
||||
*
|
||||
* Unless otherwise specified, all parameters must be validated as non-empty strings of digits,
|
||||
* without leading zero, and with an optional leading minus sign if the number is not zero.
|
||||
*
|
||||
* Any other parameter format will lead to undefined behaviour.
|
||||
* All methods must return strings respecting this format, unless specified otherwise.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract readonly class Calculator
|
||||
{
|
||||
/**
|
||||
* The maximum exponent value allowed for the pow() method.
|
||||
*/
|
||||
public const MAX_POWER = 1_000_000;
|
||||
|
||||
/**
|
||||
* The alphabet for converting from and to base 2 to 36, lowercase.
|
||||
*/
|
||||
public const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function abs(string $n): string
|
||||
{
|
||||
return ($n[0] === '-') ? substr($n, 1) : $n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Negates a number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function neg(string $n): string
|
||||
{
|
||||
if ($n === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($n[0] === '-') {
|
||||
return substr($n, 1);
|
||||
}
|
||||
|
||||
return '-' . $n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two numbers.
|
||||
*
|
||||
* Returns -1 if the first number is less than, 0 if equal to, 1 if greater than the second number.
|
||||
*
|
||||
* @return -1|0|1
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function cmp(string $a, string $b): int
|
||||
{
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
if ($aNeg && ! $bNeg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($bNeg && ! $aNeg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$aLen = strlen($aDig);
|
||||
$bLen = strlen($bDig);
|
||||
|
||||
if ($aLen < $bLen) {
|
||||
$result = -1;
|
||||
} elseif ($aLen > $bLen) {
|
||||
$result = 1;
|
||||
} else {
|
||||
$result = $aDig <=> $bDig;
|
||||
}
|
||||
|
||||
return $aNeg ? -$result : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two numbers.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function add(string $a, string $b): string;
|
||||
|
||||
/**
|
||||
* Subtracts two numbers.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function sub(string $a, string $b): string;
|
||||
|
||||
/**
|
||||
* Multiplies two numbers.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function mul(string $a, string $b): string;
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string The quotient.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function divQ(string $a, string $b): string;
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string The remainder.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function divR(string $a, string $b): string;
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return array{string, string} An array containing the quotient and remainder.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function divQR(string $a, string $b): array;
|
||||
|
||||
/**
|
||||
* Exponentiates a number.
|
||||
*
|
||||
* @param string $a The base number.
|
||||
* @param int $e The exponent, validated as an integer between 0 and MAX_POWER.
|
||||
*
|
||||
* @return string The power.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function pow(string $a, int $e): string;
|
||||
|
||||
/**
|
||||
* @param string $b The modulus; must not be zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function mod(string $a, string $b): string
|
||||
{
|
||||
return $this->divR($this->add($this->divR($a, $b), $b), $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modular multiplicative inverse of $x modulo $m.
|
||||
*
|
||||
* If $x has no multiplicative inverse mod m, this method must return null.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library has built-in support.
|
||||
*
|
||||
* @param string $m The modulus; must not be negative or zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function modInverse(string $x, string $m): ?string
|
||||
{
|
||||
if ($m === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$modVal = $x;
|
||||
|
||||
if ($x[0] === '-' || ($this->cmp($this->abs($x), $m) >= 0)) {
|
||||
$modVal = $this->mod($x, $m);
|
||||
}
|
||||
|
||||
[$g, $x] = $this->gcdExtended($modVal, $m);
|
||||
|
||||
if ($g !== '1') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->mod($this->add($this->mod($x, $m), $m), $m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises a number into power with modulo.
|
||||
*
|
||||
* @param string $base The base number; must be positive or zero.
|
||||
* @param string $exp The exponent; must be positive or zero.
|
||||
* @param string $mod The modulus; must be strictly positive.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function modPow(string $base, string $exp, string $mod): string;
|
||||
|
||||
/**
|
||||
* Returns the greatest common divisor of the two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for GCD calculations.
|
||||
*
|
||||
* @return string The GCD, always positive, or zero if both arguments are zero.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function gcd(string $a, string $b): string
|
||||
{
|
||||
if ($a === '0') {
|
||||
return $this->abs($b);
|
||||
}
|
||||
|
||||
if ($b === '0') {
|
||||
return $this->abs($a);
|
||||
}
|
||||
|
||||
return $this->gcd($b, $this->divR($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of the given number, rounded down.
|
||||
*
|
||||
* The result is the largest x such that x² ≤ n.
|
||||
* The input MUST NOT be negative.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
abstract public function sqrt(string $n): string;
|
||||
|
||||
/**
|
||||
* Converts a number from an arbitrary base.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for base conversion.
|
||||
*
|
||||
* @param string $number The number, positive or zero, non-empty, case-insensitively validated for the given base.
|
||||
* @param int $base The base of the number, validated from 2 to 36.
|
||||
*
|
||||
* @return string The converted number, following the Calculator conventions.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function fromBase(string $number, int $base): string
|
||||
{
|
||||
return $this->fromArbitraryBase(strtolower($number), self::ALPHABET, $base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number to an arbitrary base.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for base conversion.
|
||||
*
|
||||
* @param string $number The number to convert, following the Calculator conventions.
|
||||
* @param int $base The base to convert to, validated from 2 to 36.
|
||||
*
|
||||
* @return string The converted number, lowercase.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function toBase(string $number, int $base): string
|
||||
{
|
||||
$negative = ($number[0] === '-');
|
||||
|
||||
if ($negative) {
|
||||
$number = substr($number, 1);
|
||||
}
|
||||
|
||||
$number = $this->toArbitraryBase($number, self::ALPHABET, $base);
|
||||
|
||||
if ($negative) {
|
||||
return '-' . $number;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-negative number in an arbitrary base using a custom alphabet, to base 10.
|
||||
*
|
||||
* @param string $number The number to convert, validated as a non-empty string,
|
||||
* containing only chars in the given alphabet/base.
|
||||
* @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum.
|
||||
* @param int $base The base of the number, validated from 2 to alphabet length.
|
||||
*
|
||||
* @return string The number in base 10, following the Calculator conventions.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function fromArbitraryBase(string $number, string $alphabet, int $base): string
|
||||
{
|
||||
// remove leading "zeros"
|
||||
$number = ltrim($number, $alphabet[0]);
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// optimize for "one"
|
||||
if ($number === $alphabet[1]) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
$result = '0';
|
||||
$power = '1';
|
||||
|
||||
$base = (string) $base;
|
||||
|
||||
for ($i = strlen($number) - 1; $i >= 0; $i--) {
|
||||
$index = strpos($alphabet, $number[$i]);
|
||||
|
||||
if ($index !== 0) {
|
||||
$result = $this->add(
|
||||
$result,
|
||||
($index === 1) ? $power : $this->mul($power, (string) $index),
|
||||
);
|
||||
}
|
||||
|
||||
if ($i !== 0) {
|
||||
$power = $this->mul($power, $base);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-negative number to an arbitrary base using a custom alphabet.
|
||||
*
|
||||
* @param string $number The number to convert, positive or zero, following the Calculator conventions.
|
||||
* @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum.
|
||||
* @param int $base The base to convert to, validated from 2 to alphabet length.
|
||||
*
|
||||
* @return string The converted number in the given alphabet.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function toArbitraryBase(string $number, string $alphabet, int $base): string
|
||||
{
|
||||
if ($number === '0') {
|
||||
return $alphabet[0];
|
||||
}
|
||||
|
||||
$base = (string) $base;
|
||||
$result = '';
|
||||
|
||||
while ($number !== '0') {
|
||||
[$number, $remainder] = $this->divQR($number, $base);
|
||||
$remainder = (int) $remainder;
|
||||
|
||||
$result .= $alphabet[$remainder];
|
||||
}
|
||||
|
||||
return strrev($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a rounded division.
|
||||
*
|
||||
* Rounding is performed when the remainder of the division is not zero.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
* @param RoundingMode $roundingMode The rounding mode.
|
||||
*
|
||||
* @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public function divRound(string $a, string $b, RoundingMode $roundingMode): string
|
||||
{
|
||||
[$quotient, $remainder] = $this->divQR($a, $b);
|
||||
|
||||
$hasDiscardedFraction = ($remainder !== '0');
|
||||
$isPositiveOrZero = ($a[0] === '-') === ($b[0] === '-');
|
||||
|
||||
$discardedFractionSign = function () use ($remainder, $b): int {
|
||||
$r = $this->abs($this->mul($remainder, '2'));
|
||||
$b = $this->abs($b);
|
||||
|
||||
return $this->cmp($r, $b);
|
||||
};
|
||||
|
||||
$increment = false;
|
||||
|
||||
switch ($roundingMode) {
|
||||
case RoundingMode::UNNECESSARY:
|
||||
if ($hasDiscardedFraction) {
|
||||
throw RoundingNecessaryException::roundingNecessary();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::UP:
|
||||
$increment = $hasDiscardedFraction;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::DOWN:
|
||||
break;
|
||||
|
||||
case RoundingMode::CEILING:
|
||||
$increment = $hasDiscardedFraction && $isPositiveOrZero;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::FLOOR:
|
||||
$increment = $hasDiscardedFraction && ! $isPositiveOrZero;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_UP:
|
||||
$increment = $discardedFractionSign() >= 0;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_DOWN:
|
||||
$increment = $discardedFractionSign() > 0;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_CEILING:
|
||||
$increment = $isPositiveOrZero ? $discardedFractionSign() >= 0 : $discardedFractionSign() > 0;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_FLOOR:
|
||||
$increment = $isPositiveOrZero ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
|
||||
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_EVEN:
|
||||
$lastDigit = (int) $quotient[-1];
|
||||
$lastDigitIsEven = ($lastDigit % 2 === 0);
|
||||
$increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($increment) {
|
||||
return $this->add($quotient, $isPositiveOrZero ? '1' : '-1');
|
||||
}
|
||||
|
||||
return $quotient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise AND of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function and(string $a, string $b): string
|
||||
{
|
||||
return $this->bitwise('and', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise OR of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function or(string $a, string $b): string
|
||||
{
|
||||
return $this->bitwise('or', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise XOR of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
public function xor(string $a, string $b): string
|
||||
{
|
||||
return $this->bitwise('xor', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the sign & digits of the operands.
|
||||
*
|
||||
* @return array{bool, bool, string, string} Whether $a and $b are negative, followed by their digits.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final protected function init(string $a, string $b): array
|
||||
{
|
||||
return [
|
||||
$aNeg = ($a[0] === '-'),
|
||||
$bNeg = ($b[0] === '-'),
|
||||
|
||||
$aNeg ? substr($a, 1) : $a,
|
||||
$bNeg ? substr($b, 1) : $b,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{string, string, string} GCD, X, Y
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function gcdExtended(string $a, string $b): array
|
||||
{
|
||||
if ($a === '0') {
|
||||
return [$b, '0', '1'];
|
||||
}
|
||||
|
||||
[$gcd, $x1, $y1] = $this->gcdExtended($this->mod($b, $a), $a);
|
||||
|
||||
$x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1));
|
||||
$y = $x1;
|
||||
|
||||
return [$gcd, $x, $y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a bitwise operation on a decimal number.
|
||||
*
|
||||
* @param 'and'|'or'|'xor' $operator The operator to use.
|
||||
* @param string $a The left operand.
|
||||
* @param string $b The right operand.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function bitwise(string $operator, string $a, string $b): string
|
||||
{
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$aBin = $this->toBinary($aDig);
|
||||
$bBin = $this->toBinary($bDig);
|
||||
|
||||
$aLen = strlen($aBin);
|
||||
$bLen = strlen($bBin);
|
||||
|
||||
if ($aLen > $bLen) {
|
||||
$bBin = str_repeat("\x00", $aLen - $bLen) . $bBin;
|
||||
} elseif ($bLen > $aLen) {
|
||||
$aBin = str_repeat("\x00", $bLen - $aLen) . $aBin;
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$aBin = $this->twosComplement($aBin);
|
||||
}
|
||||
if ($bNeg) {
|
||||
$bBin = $this->twosComplement($bBin);
|
||||
}
|
||||
|
||||
$value = match ($operator) {
|
||||
'and' => $aBin & $bBin,
|
||||
'or' => $aBin | $bBin,
|
||||
'xor' => $aBin ^ $bBin,
|
||||
};
|
||||
|
||||
$negative = match ($operator) {
|
||||
'and' => $aNeg and $bNeg,
|
||||
'or' => $aNeg or $bNeg,
|
||||
'xor' => $aNeg xor $bNeg,
|
||||
};
|
||||
|
||||
if ($negative) {
|
||||
$value = $this->twosComplement($value);
|
||||
}
|
||||
|
||||
$result = $this->toDecimal($value);
|
||||
|
||||
return $negative ? $this->neg($result) : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number A positive, binary number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function twosComplement(string $number): string
|
||||
{
|
||||
$xor = str_repeat("\xff", strlen($number));
|
||||
|
||||
$number ^= $xor;
|
||||
|
||||
for ($i = strlen($number) - 1; $i >= 0; $i--) {
|
||||
$byte = ord($number[$i]);
|
||||
|
||||
if (++$byte !== 256) {
|
||||
$number[$i] = chr($byte);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$number[$i] = "\x00";
|
||||
|
||||
if ($i === 0) {
|
||||
$number = "\x01" . $number;
|
||||
}
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a decimal number to a binary string.
|
||||
*
|
||||
* @param string $number The number to convert, positive or zero, only digits.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function toBinary(string $number): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
while ($number !== '0') {
|
||||
[$number, $remainder] = $this->divQR($number, '256');
|
||||
$result .= chr((int) $remainder);
|
||||
}
|
||||
|
||||
return strrev($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the positive decimal representation of a binary number.
|
||||
*
|
||||
* @param string $bytes The bytes representing the number.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function toDecimal(string $bytes): string
|
||||
{
|
||||
$result = '0';
|
||||
$power = '1';
|
||||
|
||||
for ($i = strlen($bytes) - 1; $i >= 0; $i--) {
|
||||
$index = ord($bytes[$i]);
|
||||
|
||||
if ($index !== 0) {
|
||||
$result = $this->add(
|
||||
$result,
|
||||
($index === 1) ? $power : $this->mul($power, (string) $index),
|
||||
);
|
||||
}
|
||||
|
||||
if ($i !== 0) {
|
||||
$power = $this->mul($power, '256');
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
82
vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
vendored
Executable file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
use Override;
|
||||
|
||||
use function bcadd;
|
||||
use function bcdiv;
|
||||
use function bcmod;
|
||||
use function bcmul;
|
||||
use function bcpow;
|
||||
use function bcpowmod;
|
||||
use function bcsqrt;
|
||||
use function bcsub;
|
||||
|
||||
/**
|
||||
* Calculator implementation built around the bcmath library.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final readonly class BcMathCalculator extends Calculator
|
||||
{
|
||||
#[Override]
|
||||
public function add(string $a, string $b): string
|
||||
{
|
||||
return bcadd($a, $b, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function sub(string $a, string $b): string
|
||||
{
|
||||
return bcsub($a, $b, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function mul(string $a, string $b): string
|
||||
{
|
||||
return bcmul($a, $b, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divQ(string $a, string $b): string
|
||||
{
|
||||
return bcdiv($a, $b, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divR(string $a, string $b): string
|
||||
{
|
||||
return bcmod($a, $b, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divQR(string $a, string $b): array
|
||||
{
|
||||
$q = bcdiv($a, $b, 0);
|
||||
$r = bcmod($a, $b, 0);
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function pow(string $a, int $e): string
|
||||
{
|
||||
return bcpow($a, (string) $e, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function modPow(string $base, string $exp, string $mod): string
|
||||
{
|
||||
return bcpowmod($base, $exp, $mod, 0);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function sqrt(string $n): string
|
||||
{
|
||||
return bcsqrt($n, 0);
|
||||
}
|
||||
}
|
||||
145
vendor/brick/math/src/Internal/Calculator/GmpCalculator.php
vendored
Executable file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
use GMP;
|
||||
use Override;
|
||||
|
||||
use function gmp_add;
|
||||
use function gmp_and;
|
||||
use function gmp_div_q;
|
||||
use function gmp_div_qr;
|
||||
use function gmp_div_r;
|
||||
use function gmp_gcd;
|
||||
use function gmp_init;
|
||||
use function gmp_invert;
|
||||
use function gmp_mul;
|
||||
use function gmp_or;
|
||||
use function gmp_pow;
|
||||
use function gmp_powm;
|
||||
use function gmp_sqrt;
|
||||
use function gmp_strval;
|
||||
use function gmp_sub;
|
||||
use function gmp_xor;
|
||||
|
||||
/**
|
||||
* Calculator implementation built around the GMP library.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final readonly class GmpCalculator extends Calculator
|
||||
{
|
||||
#[Override]
|
||||
public function add(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_add($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function sub(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_sub($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function mul(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_mul($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divQ(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_div_q($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divR(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_div_r($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divQR(string $a, string $b): array
|
||||
{
|
||||
[$q, $r] = gmp_div_qr($a, $b);
|
||||
|
||||
/**
|
||||
* @var GMP $q
|
||||
* @var GMP $r
|
||||
*/
|
||||
return [
|
||||
gmp_strval($q),
|
||||
gmp_strval($r),
|
||||
];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function pow(string $a, int $e): string
|
||||
{
|
||||
return gmp_strval(gmp_pow($a, $e));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function modInverse(string $x, string $m): ?string
|
||||
{
|
||||
$result = gmp_invert($x, $m);
|
||||
|
||||
if ($result === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return gmp_strval($result);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function modPow(string $base, string $exp, string $mod): string
|
||||
{
|
||||
return gmp_strval(gmp_powm($base, $exp, $mod));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function gcd(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_gcd($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fromBase(string $number, int $base): string
|
||||
{
|
||||
return gmp_strval(gmp_init($number, $base));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function toBase(string $number, int $base): string
|
||||
{
|
||||
return gmp_strval($number, $base);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function and(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_and($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function or(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_or($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function xor(string $a, string $b): string
|
||||
{
|
||||
return gmp_strval(gmp_xor($a, $b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function sqrt(string $n): string
|
||||
{
|
||||
return gmp_strval(gmp_sqrt($n));
|
||||
}
|
||||
}
|
||||
618
vendor/brick/math/src/Internal/Calculator/NativeCalculator.php
vendored
Executable file
@ -0,0 +1,618 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
use Override;
|
||||
|
||||
use function assert;
|
||||
use function in_array;
|
||||
use function intdiv;
|
||||
use function is_int;
|
||||
use function ltrim;
|
||||
use function str_pad;
|
||||
use function str_repeat;
|
||||
use function strcmp;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
|
||||
use const PHP_INT_SIZE;
|
||||
use const STR_PAD_LEFT;
|
||||
|
||||
/**
|
||||
* Calculator implementation using only native PHP code.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final readonly class NativeCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* The max number of digits the platform can natively add, subtract, multiply or divide without overflow.
|
||||
* For multiplication, this represents the max sum of the lengths of both operands.
|
||||
*
|
||||
* In addition, it is assumed that an extra digit can hold a carry (1) without overflowing.
|
||||
* Example: 32-bit: max number 1,999,999,999 (9 digits + carry)
|
||||
* 64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry)
|
||||
*/
|
||||
private int $maxDigits;
|
||||
|
||||
/**
|
||||
* @pure
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->maxDigits = match (PHP_INT_SIZE) {
|
||||
4 => 9,
|
||||
8 => 18,
|
||||
};
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function add(string $a, string $b): string
|
||||
{
|
||||
/**
|
||||
* @var numeric-string $a
|
||||
* @var numeric-string $b
|
||||
*/
|
||||
$result = $a + $b;
|
||||
|
||||
if (is_int($result)) {
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
if ($a === '0') {
|
||||
return $b;
|
||||
}
|
||||
|
||||
if ($b === '0') {
|
||||
return $a;
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$result = $aNeg === $bNeg ? $this->doAdd($aDig, $bDig) : $this->doSub($aDig, $bDig);
|
||||
|
||||
if ($aNeg) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function sub(string $a, string $b): string
|
||||
{
|
||||
return $this->add($a, $this->neg($b));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function mul(string $a, string $b): string
|
||||
{
|
||||
/**
|
||||
* @var numeric-string $a
|
||||
* @var numeric-string $b
|
||||
*/
|
||||
$result = $a * $b;
|
||||
|
||||
if (is_int($result)) {
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
if ($a === '0' || $b === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($a === '1') {
|
||||
return $b;
|
||||
}
|
||||
|
||||
if ($b === '1') {
|
||||
return $a;
|
||||
}
|
||||
|
||||
if ($a === '-1') {
|
||||
return $this->neg($b);
|
||||
}
|
||||
|
||||
if ($b === '-1') {
|
||||
return $this->neg($a);
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$result = $this->doMul($aDig, $bDig);
|
||||
|
||||
if ($aNeg !== $bNeg) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divQ(string $a, string $b): string
|
||||
{
|
||||
return $this->divQR($a, $b)[0];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divR(string $a, string $b): string
|
||||
{
|
||||
return $this->divQR($a, $b)[1];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function divQR(string $a, string $b): array
|
||||
{
|
||||
if ($a === '0') {
|
||||
return ['0', '0'];
|
||||
}
|
||||
|
||||
if ($a === $b) {
|
||||
return ['1', '0'];
|
||||
}
|
||||
|
||||
if ($b === '1') {
|
||||
return [$a, '0'];
|
||||
}
|
||||
|
||||
if ($b === '-1') {
|
||||
return [$this->neg($a), '0'];
|
||||
}
|
||||
|
||||
/** @var numeric-string $a */
|
||||
$na = $a * 1; // cast to number
|
||||
|
||||
if (is_int($na)) {
|
||||
/** @var numeric-string $b */
|
||||
$nb = $b * 1;
|
||||
|
||||
if (is_int($nb)) {
|
||||
// the only division that may overflow is PHP_INT_MIN / -1,
|
||||
// which cannot happen here as we've already handled a divisor of -1 above.
|
||||
$q = intdiv($na, $nb);
|
||||
$r = $na % $nb;
|
||||
|
||||
return [
|
||||
(string) $q,
|
||||
(string) $r,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
[$q, $r] = $this->doDiv($aDig, $bDig);
|
||||
|
||||
if ($aNeg !== $bNeg) {
|
||||
$q = $this->neg($q);
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$r = $this->neg($r);
|
||||
}
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function pow(string $a, int $e): string
|
||||
{
|
||||
if ($e === 0) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
if ($e === 1) {
|
||||
return $a;
|
||||
}
|
||||
|
||||
$odd = $e % 2;
|
||||
$e -= $odd;
|
||||
|
||||
$aa = $this->mul($a, $a);
|
||||
|
||||
$result = $this->pow($aa, $e / 2);
|
||||
|
||||
if ($odd === 1) {
|
||||
$result = $this->mul($result, $a);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/.
|
||||
*/
|
||||
#[Override]
|
||||
public function modPow(string $base, string $exp, string $mod): string
|
||||
{
|
||||
// special case: the algorithm below fails with 0 power 0 mod 1 (returns 1 instead of 0)
|
||||
if ($base === '0' && $exp === '0' && $mod === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// special case: the algorithm below fails with power 0 mod 1 (returns 1 instead of 0)
|
||||
if ($exp === '0' && $mod === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$x = $base;
|
||||
|
||||
$res = '1';
|
||||
|
||||
// numbers are positive, so we can use remainder instead of modulo
|
||||
$x = $this->divR($x, $mod);
|
||||
|
||||
while ($exp !== '0') {
|
||||
if (in_array($exp[-1], ['1', '3', '5', '7', '9'])) { // odd
|
||||
$res = $this->divR($this->mul($res, $x), $mod);
|
||||
}
|
||||
|
||||
$exp = $this->divQ($exp, '2');
|
||||
$x = $this->divR($this->mul($x, $x), $mod);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapted from https://cp-algorithms.com/num_methods/roots_newton.html.
|
||||
*/
|
||||
#[Override]
|
||||
public function sqrt(string $n): string
|
||||
{
|
||||
if ($n === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// initial approximation
|
||||
$x = str_repeat('9', intdiv(strlen($n), 2) ?: 1);
|
||||
|
||||
$decreased = false;
|
||||
|
||||
for (; ;) {
|
||||
$nx = $this->divQ($this->add($x, $this->divQ($n, $x)), '2');
|
||||
|
||||
if ($x === $nx || $this->cmp($nx, $x) > 0 && $decreased) {
|
||||
break;
|
||||
}
|
||||
|
||||
$decreased = $this->cmp($nx, $x) < 0;
|
||||
$x = $nx;
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the addition of two non-signed large integers.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function doAdd(string $a, string $b): string
|
||||
{
|
||||
[$a, $b, $length] = $this->pad($a, $b);
|
||||
|
||||
$carry = 0;
|
||||
$result = '';
|
||||
|
||||
for ($i = $length - $this->maxDigits; ; $i -= $this->maxDigits) {
|
||||
$blockLength = $this->maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockLength += $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
/** @var numeric-string $blockA */
|
||||
$blockA = substr($a, $i, $blockLength);
|
||||
|
||||
/** @var numeric-string $blockB */
|
||||
$blockB = substr($b, $i, $blockLength);
|
||||
|
||||
$sum = (string) ($blockA + $blockB + $carry);
|
||||
$sumLength = strlen($sum);
|
||||
|
||||
if ($sumLength > $blockLength) {
|
||||
$sum = substr($sum, 1);
|
||||
$carry = 1;
|
||||
} else {
|
||||
if ($sumLength < $blockLength) {
|
||||
$sum = str_repeat('0', $blockLength - $sumLength) . $sum;
|
||||
}
|
||||
$carry = 0;
|
||||
}
|
||||
|
||||
$result = $sum . $result;
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($carry === 1) {
|
||||
$result = '1' . $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the subtraction of two non-signed large integers.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function doSub(string $a, string $b): string
|
||||
{
|
||||
if ($a === $b) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// Ensure that we always subtract to a positive result: biggest minus smallest.
|
||||
$cmp = $this->doCmp($a, $b);
|
||||
|
||||
$invert = ($cmp === -1);
|
||||
|
||||
if ($invert) {
|
||||
$c = $a;
|
||||
$a = $b;
|
||||
$b = $c;
|
||||
}
|
||||
|
||||
[$a, $b, $length] = $this->pad($a, $b);
|
||||
|
||||
$carry = 0;
|
||||
$result = '';
|
||||
|
||||
$complement = 10 ** $this->maxDigits;
|
||||
|
||||
for ($i = $length - $this->maxDigits; ; $i -= $this->maxDigits) {
|
||||
$blockLength = $this->maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockLength += $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
/** @var numeric-string $blockA */
|
||||
$blockA = substr($a, $i, $blockLength);
|
||||
|
||||
/** @var numeric-string $blockB */
|
||||
$blockB = substr($b, $i, $blockLength);
|
||||
|
||||
$sum = $blockA - $blockB - $carry;
|
||||
|
||||
if ($sum < 0) {
|
||||
$sum += $complement;
|
||||
$carry = 1;
|
||||
} else {
|
||||
$carry = 0;
|
||||
}
|
||||
|
||||
$sum = (string) $sum;
|
||||
$sumLength = strlen($sum);
|
||||
|
||||
if ($sumLength < $blockLength) {
|
||||
$sum = str_repeat('0', $blockLength - $sumLength) . $sum;
|
||||
}
|
||||
|
||||
$result = $sum . $result;
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Carry cannot be 1 when the loop ends, as a > b
|
||||
assert($carry === 0);
|
||||
|
||||
$result = ltrim($result, '0');
|
||||
|
||||
if ($invert) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the multiplication of two non-signed large integers.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function doMul(string $a, string $b): string
|
||||
{
|
||||
$x = strlen($a);
|
||||
$y = strlen($b);
|
||||
|
||||
$maxDigits = intdiv($this->maxDigits, 2);
|
||||
$complement = 10 ** $maxDigits;
|
||||
|
||||
$result = '0';
|
||||
|
||||
for ($i = $x - $maxDigits; ; $i -= $maxDigits) {
|
||||
$blockALength = $maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockALength += $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
$blockA = (int) substr($a, $i, $blockALength);
|
||||
|
||||
$line = '';
|
||||
$carry = 0;
|
||||
|
||||
for ($j = $y - $maxDigits; ; $j -= $maxDigits) {
|
||||
$blockBLength = $maxDigits;
|
||||
|
||||
if ($j < 0) {
|
||||
$blockBLength += $j;
|
||||
$j = 0;
|
||||
}
|
||||
|
||||
$blockB = (int) substr($b, $j, $blockBLength);
|
||||
|
||||
$mul = $blockA * $blockB + $carry;
|
||||
$value = $mul % $complement;
|
||||
$carry = ($mul - $value) / $complement;
|
||||
|
||||
$value = (string) $value;
|
||||
$value = str_pad($value, $maxDigits, '0', STR_PAD_LEFT);
|
||||
|
||||
$line = $value . $line;
|
||||
|
||||
if ($j === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($carry !== 0) {
|
||||
$line = $carry . $line;
|
||||
}
|
||||
|
||||
$line = ltrim($line, '0');
|
||||
|
||||
if ($line !== '') {
|
||||
$line .= str_repeat('0', $x - $blockALength - $i);
|
||||
$result = $this->add($result, $line);
|
||||
}
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the division of two non-signed large integers.
|
||||
*
|
||||
* @return string[] The quotient and remainder.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function doDiv(string $a, string $b): array
|
||||
{
|
||||
$cmp = $this->doCmp($a, $b);
|
||||
|
||||
if ($cmp === -1) {
|
||||
return ['0', $a];
|
||||
}
|
||||
|
||||
$x = strlen($a);
|
||||
$y = strlen($b);
|
||||
|
||||
// we now know that a >= b && x >= y
|
||||
|
||||
$q = '0'; // quotient
|
||||
$r = $a; // remainder
|
||||
$z = $y; // focus length, always $y or $y+1
|
||||
|
||||
/** @var numeric-string $b */
|
||||
$nb = $b * 1; // cast to number
|
||||
// performance optimization in cases where the remainder will never cause int overflow
|
||||
if (is_int(($nb - 1) * 10 + 9)) {
|
||||
$r = (int) substr($a, 0, $z - 1);
|
||||
|
||||
for ($i = $z - 1; $i < $x; $i++) {
|
||||
$n = $r * 10 + (int) $a[$i];
|
||||
/** @var int $nb */
|
||||
$q .= intdiv($n, $nb);
|
||||
$r = $n % $nb;
|
||||
}
|
||||
|
||||
return [ltrim($q, '0') ?: '0', (string) $r];
|
||||
}
|
||||
|
||||
for (; ;) {
|
||||
$focus = substr($a, 0, $z);
|
||||
|
||||
$cmp = $this->doCmp($focus, $b);
|
||||
|
||||
if ($cmp === -1) {
|
||||
if ($z === $x) { // remainder < dividend
|
||||
break;
|
||||
}
|
||||
|
||||
$z++;
|
||||
}
|
||||
|
||||
$zeros = str_repeat('0', $x - $z);
|
||||
|
||||
$q = $this->add($q, '1' . $zeros);
|
||||
$a = $this->sub($a, $b . $zeros);
|
||||
|
||||
$r = $a;
|
||||
|
||||
if ($r === '0') { // remainder == 0
|
||||
break;
|
||||
}
|
||||
|
||||
$x = strlen($a);
|
||||
|
||||
if ($x < $y) { // remainder < dividend
|
||||
break;
|
||||
}
|
||||
|
||||
$z = $y;
|
||||
}
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two non-signed large numbers.
|
||||
*
|
||||
* @return -1|0|1
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function doCmp(string $a, string $b): int
|
||||
{
|
||||
$x = strlen($a);
|
||||
$y = strlen($b);
|
||||
|
||||
$cmp = $x <=> $y;
|
||||
|
||||
if ($cmp !== 0) {
|
||||
return $cmp;
|
||||
}
|
||||
|
||||
return strcmp($a, $b) <=> 0; // enforce -1|0|1
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads the left of one of the given numbers with zeros if necessary to make both numbers the same length.
|
||||
*
|
||||
* The numbers must only consist of digits, without leading minus sign.
|
||||
*
|
||||
* @return array{string, string, int}
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
private function pad(string $a, string $b): array
|
||||
{
|
||||
$x = strlen($a);
|
||||
$y = strlen($b);
|
||||
|
||||
if ($x > $y) {
|
||||
$b = str_repeat('0', $x - $y) . $b;
|
||||
|
||||
return [$a, $b, $x];
|
||||
}
|
||||
|
||||
if ($x < $y) {
|
||||
$a = str_repeat('0', $y - $x) . $a;
|
||||
|
||||
return [$a, $b, $y];
|
||||
}
|
||||
|
||||
return [$a, $b, $x];
|
||||
}
|
||||
}
|
||||
74
vendor/brick/math/src/Internal/CalculatorRegistry.php
vendored
Executable file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal;
|
||||
|
||||
use function extension_loaded;
|
||||
|
||||
/**
|
||||
* Stores the current Calculator instance used by BigNumber classes.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class CalculatorRegistry
|
||||
{
|
||||
/**
|
||||
* The Calculator instance in use.
|
||||
*/
|
||||
private static ?Calculator $instance = null;
|
||||
|
||||
/**
|
||||
* Sets the Calculator instance to use.
|
||||
*
|
||||
* An instance is typically set only in unit tests: autodetect is usually the best option.
|
||||
*
|
||||
* @param Calculator|null $calculator The calculator instance, or null to revert to autodetect.
|
||||
*/
|
||||
final public static function set(?Calculator $calculator): void
|
||||
{
|
||||
self::$instance = $calculator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Calculator instance to use.
|
||||
*
|
||||
* If none has been explicitly set, the fastest available implementation will be returned.
|
||||
*
|
||||
* Note: even though this method is not technically pure, it is considered pure when used in a normal context, when
|
||||
* only relying on autodetect.
|
||||
*
|
||||
* @pure
|
||||
*/
|
||||
final public static function get(): Calculator
|
||||
{
|
||||
/** @phpstan-ignore impure.staticPropertyAccess */
|
||||
if (self::$instance === null) {
|
||||
/** @phpstan-ignore impure.propertyAssign */
|
||||
self::$instance = self::detect();
|
||||
}
|
||||
|
||||
/** @phpstan-ignore impure.staticPropertyAccess */
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fastest available Calculator implementation.
|
||||
*
|
||||
* @pure
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private static function detect(): Calculator
|
||||
{
|
||||
if (extension_loaded('gmp')) {
|
||||
return new Calculator\GmpCalculator();
|
||||
}
|
||||
|
||||
if (extension_loaded('bcmath')) {
|
||||
return new Calculator\BcMathCalculator();
|
||||
}
|
||||
|
||||
return new Calculator\NativeCalculator();
|
||||
}
|
||||
}
|
||||
98
vendor/brick/math/src/RoundingMode.php
vendored
Executable file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
/**
|
||||
* Specifies a rounding behavior for numerical operations capable of discarding precision.
|
||||
*
|
||||
* Each rounding mode indicates how the least significant returned digit of a rounded result
|
||||
* is to be calculated. If fewer digits are returned than the digits needed to represent the
|
||||
* exact numerical result, the discarded digits will be referred to as the discarded fraction
|
||||
* regardless the digits' contribution to the value of the number. In other words, considered
|
||||
* as a numerical value, the discarded fraction could have an absolute value greater than one.
|
||||
*/
|
||||
enum RoundingMode
|
||||
{
|
||||
/**
|
||||
* Asserts that the requested operation has an exact result, hence no rounding is necessary.
|
||||
*
|
||||
* If this rounding mode is specified on an operation that yields a result that
|
||||
* cannot be represented at the requested scale, a RoundingNecessaryException is thrown.
|
||||
*/
|
||||
case UNNECESSARY;
|
||||
|
||||
/**
|
||||
* Rounds away from zero.
|
||||
*
|
||||
* Always increments the digit prior to a nonzero discarded fraction.
|
||||
* Note that this rounding mode never decreases the magnitude of the calculated value.
|
||||
*/
|
||||
case UP;
|
||||
|
||||
/**
|
||||
* Rounds towards zero.
|
||||
*
|
||||
* Never increments the digit prior to a discarded fraction (i.e., truncates).
|
||||
* Note that this rounding mode never increases the magnitude of the calculated value.
|
||||
*/
|
||||
case DOWN;
|
||||
|
||||
/**
|
||||
* Rounds towards positive infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for UP; if negative, behaves as for DOWN.
|
||||
* Note that this rounding mode never decreases the calculated value.
|
||||
*/
|
||||
case CEILING;
|
||||
|
||||
/**
|
||||
* Rounds towards negative infinity.
|
||||
*
|
||||
* If the result is positive, behave as for DOWN; if negative, behave as for UP.
|
||||
* Note that this rounding mode never increases the calculated value.
|
||||
*/
|
||||
case FLOOR;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
|
||||
*
|
||||
* Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN.
|
||||
* Note that this is the rounding mode commonly taught at school.
|
||||
*/
|
||||
case HALF_UP;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
|
||||
*
|
||||
* Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN.
|
||||
*/
|
||||
case HALF_DOWN;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN.
|
||||
*/
|
||||
case HALF_CEILING;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP.
|
||||
*/
|
||||
case HALF_FLOOR;
|
||||
|
||||
/**
|
||||
* Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor.
|
||||
*
|
||||
* Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd;
|
||||
* behaves as for HALF_DOWN if it's even.
|
||||
*
|
||||
* Note that this is the rounding mode that statistically minimizes
|
||||
* cumulative error when applied repeatedly over a sequence of calculations.
|
||||
* It is sometimes known as "Banker's rounding", and is chiefly used in the USA.
|
||||
*/
|
||||
case HALF_EVEN;
|
||||
}
|
||||
10
vendor/brick/math/tools/ecs/composer.json
vendored
Executable file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"require": {
|
||||
"brick/coding-standard": "v2"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": false
|
||||
}
|
||||
}
|
||||
}
|
||||
33
vendor/brick/math/tools/ecs/ecs.php
vendored
Executable file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PhpCsFixer\Fixer\ClassNotation\OrderedTypesFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesOrderFixer;
|
||||
use SlevomatCodingStandard\Sniffs\Whitespaces\DuplicateSpacesSniff;
|
||||
use Symplify\EasyCodingStandard\Config\ECSConfig;
|
||||
|
||||
return static function (ECSConfig $ecsConfig): void {
|
||||
$ecsConfig->import(__DIR__ . '/vendor/brick/coding-standard/ecs.php');
|
||||
|
||||
$libRootPath = realpath(__DIR__ . '/../..');
|
||||
|
||||
$ecsConfig->paths(
|
||||
[
|
||||
$libRootPath . '/src',
|
||||
$libRootPath . '/tests',
|
||||
$libRootPath . '/phpunit.php',
|
||||
$libRootPath . '/random-tests.php',
|
||||
__FILE__,
|
||||
],
|
||||
);
|
||||
|
||||
$ecsConfig->skip([
|
||||
// Allows alignment in test providers
|
||||
DuplicateSpacesSniff::class => [$libRootPath . '/tests'],
|
||||
|
||||
// We want to keep BigNumber|int|float|string order
|
||||
OrderedTypesFixer::class => null,
|
||||
PhpdocTypesOrderFixer::class => null,
|
||||
]);
|
||||
};
|
||||
21
vendor/carbonphp/carbon-doctrine-types/LICENSE
vendored
Executable file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Carbon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
14
vendor/carbonphp/carbon-doctrine-types/README.md
vendored
Executable file
@ -0,0 +1,14 @@
|
||||
# carbonphp/carbon-doctrine-types
|
||||
|
||||
Types to use Carbon in Doctrine
|
||||
|
||||
## Documentation
|
||||
|
||||
[Check how to use in the official Carbon documentation](https://carbon.nesbot.com/symfony/)
|
||||
|
||||
This package is an externalization of [src/Carbon/Doctrine](https://github.com/briannesbitt/Carbon/tree/2.71.0/src/Carbon/Doctrine)
|
||||
from `nestbot/carbon` package.
|
||||
|
||||
Externalization allows to better deal with different versions of dbal. With
|
||||
version 4.0 of dbal, it no longer sustainable to be compatible with all version
|
||||
using a single code.
|
||||
36
vendor/carbonphp/carbon-doctrine-types/composer.json
vendored
Executable file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "carbonphp/carbon-doctrine-types",
|
||||
"description": "Types to use Carbon in Doctrine",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"date",
|
||||
"time",
|
||||
"DateTime",
|
||||
"Carbon",
|
||||
"Doctrine"
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/dbal": "^4.0.0",
|
||||
"nesbot/carbon": "^2.71.0 || ^3.0.0",
|
||||
"phpunit/phpunit": "^10.3"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/dbal": "<4.0.0 || >=5.0.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "KyleKatarn",
|
||||
"email": "kylekatarnls@gmail.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
16
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/CarbonDoctrineType.php
vendored
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
interface CarbonDoctrineType
|
||||
{
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
|
||||
|
||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform);
|
||||
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform);
|
||||
}
|
||||
9
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/CarbonImmutableType.php
vendored
Executable file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
class CarbonImmutableType extends DateTimeImmutableType implements CarbonDoctrineType
|
||||
{
|
||||
}
|
||||
9
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/CarbonType.php
vendored
Executable file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
class CarbonType extends DateTimeType implements CarbonDoctrineType
|
||||
{
|
||||
}
|
||||
131
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/CarbonTypeConverter.php
vendored
Executable file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonInterface;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\DB2Platform;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
use Doctrine\DBAL\Types\Exception\InvalidType;
|
||||
use Doctrine\DBAL\Types\Exception\ValueNotConvertible;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @template T of CarbonInterface
|
||||
*/
|
||||
trait CarbonTypeConverter
|
||||
{
|
||||
/**
|
||||
* This property differentiates types installed by carbonphp/carbon-doctrine-types
|
||||
* from the ones embedded previously in nesbot/carbon source directly.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
public bool $external = true;
|
||||
|
||||
/**
|
||||
* @return class-string<T>
|
||||
*/
|
||||
protected function getCarbonClassName(): string
|
||||
{
|
||||
return Carbon::class;
|
||||
}
|
||||
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
|
||||
{
|
||||
$precision = min(
|
||||
$fieldDeclaration['precision'] ?? DateTimeDefaultPrecision::get(),
|
||||
$this->getMaximumPrecision($platform),
|
||||
);
|
||||
|
||||
$type = parent::getSQLDeclaration($fieldDeclaration, $platform);
|
||||
|
||||
if (!$precision) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
if (str_contains($type, '(')) {
|
||||
return preg_replace('/\(\d+\)/', "($precision)", $type);
|
||||
}
|
||||
|
||||
[$before, $after] = explode(' ', "$type ");
|
||||
|
||||
return trim("$before($precision) $after");
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
|
||||
{
|
||||
if ($value === null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value instanceof DateTimeInterface) {
|
||||
return $value->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
throw InvalidType::new(
|
||||
$value,
|
||||
static::class,
|
||||
['null', 'DateTime', 'Carbon']
|
||||
);
|
||||
}
|
||||
|
||||
private function doConvertToPHPValue(mixed $value)
|
||||
{
|
||||
$class = $this->getCarbonClassName();
|
||||
|
||||
if ($value === null || is_a($value, $class)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value instanceof DateTimeInterface) {
|
||||
return $class::instance($value);
|
||||
}
|
||||
|
||||
$date = null;
|
||||
$error = null;
|
||||
|
||||
try {
|
||||
$date = $class::parse($value);
|
||||
} catch (Exception $exception) {
|
||||
$error = $exception;
|
||||
}
|
||||
|
||||
if (!$date) {
|
||||
throw ValueNotConvertible::new(
|
||||
$value,
|
||||
static::class,
|
||||
'Y-m-d H:i:s.u or any format supported by '.$class.'::parse()',
|
||||
$error
|
||||
);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
private function getMaximumPrecision(AbstractPlatform $platform): int
|
||||
{
|
||||
if ($platform instanceof DB2Platform) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
if ($platform instanceof OraclePlatform) {
|
||||
return 9;
|
||||
}
|
||||
|
||||
if ($platform instanceof SQLServerPlatform || $platform instanceof SQLitePlatform) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
30
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/DateTimeDefaultPrecision.php
vendored
Executable file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
class DateTimeDefaultPrecision
|
||||
{
|
||||
private static $precision = 6;
|
||||
|
||||
/**
|
||||
* Change the default Doctrine datetime and datetime_immutable precision.
|
||||
*
|
||||
* @param int $precision
|
||||
*/
|
||||
public static function set(int $precision): void
|
||||
{
|
||||
self::$precision = $precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default Doctrine datetime and datetime_immutable precision.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function get(): int
|
||||
{
|
||||
return self::$precision;
|
||||
}
|
||||
}
|
||||
32
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/DateTimeImmutableType.php
vendored
Executable file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\VarDateTimeImmutableType;
|
||||
|
||||
class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType
|
||||
{
|
||||
/** @use CarbonTypeConverter<CarbonImmutable> */
|
||||
use CarbonTypeConverter;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?CarbonImmutable
|
||||
{
|
||||
return $this->doConvertToPHPValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string<CarbonImmutable>
|
||||
*/
|
||||
protected function getCarbonClassName(): string
|
||||
{
|
||||
return CarbonImmutable::class;
|
||||
}
|
||||
}
|
||||
24
vendor/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine/DateTimeType.php
vendored
Executable file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Carbon\Doctrine;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\VarDateTimeType;
|
||||
|
||||
class DateTimeType extends VarDateTimeType implements CarbonDoctrineType
|
||||
{
|
||||
/** @use CarbonTypeConverter<Carbon> */
|
||||
use CarbonTypeConverter;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Carbon
|
||||
{
|
||||
return $this->doConvertToPHPValue($value);
|
||||
}
|
||||
}
|
||||