1 2import Routes from './routes.js'; 3import Configs from './config.js'; 4let Translate = new window.Translate(); 5 6export default class Helpers { 7 8 constructor() { 9 10 this.timerIdProcess; 11 this.timerIdNotice; 12 this.configs = Configs; 13 this.routes = Routes; 14 this.translate = Translate; 15 this.uniSelectUpdate(); 16 this.lazyImg(); 17 18 } 19 20 config(value){ 21 return this.configs[value]; 22 } 23 24 getUrl(){ 25 var path = window.location.pathname.replace(/^\/|\/$/g, ''); 26 var search = window.location.search.replace(/^\/|\/$/g, ''); 27 return path+search; 28 } 29 30 getUrlParams(){ 31 var result = window.location.href.split('?'); 32 return result[1]; 33 } 34 35 urlParamValue(name){ 36 let params = new URLSearchParams(window.location.search); 37 return params.get(name); 38 } 39 40 amount(amount=0){ 41 42 var spacing; 43 44 var splitAmount = amount.toFixed(2).split("."); 45 46 if(splitAmount[1] != "00"){ 47 amount = amount.toFixed(2); 48 } 49 50 if(this.config("system_currency_spacing")){ spacing = " "; }else{ spacing = ""; } 51 52 if(this.config("system_currency_position") == "start"){ 53 return this.config("system_default_currency")+spacing+$.number(amount, 0, '.', ' '); 54 }else{ 55 return $.number(amount, 0, '.', ' ')+spacing+this.config("system_default_currency"); 56 } 57 58 } 59 60 ajaxData(data,button){ 61 if(data["auth"] == false){ 62 this.loadModal("auth"); 63 if(button != undefined) this.endProcessLoadButton(button); 64 return false; 65 }else if(data["verification"] == false){ 66 this.loadModal("verificationUser"); 67 if(button != undefined) this.endProcessLoadButton(button); 68 return false; 69 } 70 return true; 71 } 72 73 request(params,callback) { 74 75 var thisClass = this; 76 var precheck = false; 77 78 if(params["precheck"] != undefined){ 79 precheck = params["precheck"]; 80 } 81 82 $.ajaxSetup({ 83 headers: { 84 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), 85 'before-route': this.getCurrentRoute(), 86 } 87 }); 88 89 try { 90 91 $.ajax({url: this.getRoute(params["url"]),type: params["type"] ? params["type"] : 'POST',data: params["data"] ? params["data"] : null,dataType: params["dataType"] ? params["dataType"] : "json", contentType: params["contentType"], processData: params["processData"],success: function(data) { 92 if(precheck){ 93 if(thisClass.ajaxData(data,params["button"])){ 94 callback(data); 95 } 96 }else{ 97 callback(data); 98 } 99 thisClass.uniSelectUpdate(); 100 thisClass.initPhoneMask(); 101 thisClass.lazyImg(); 102 thisClass.initCountdown(); 103 }}); 104 105 } catch (error) { 106 console.log(error); 107 } 108 109 } 110 111 endTimeoutProcessLoadButton(thisButton){ 112 if(thisButton.prop('disabled') == true){ 113 thisButton.find('span.spinner-border').remove(); 114 thisButton.prop('disabled', false); 115 } 116 clearInterval(this.timerIdProcess); 117 } 118 119 startProcessLoadButton(thisButton){ 120 121 if(this.timerIdProcess){ 122 clearInterval(this.timerIdProcess); 123 } 124 125 this.timerIdProcess = setInterval(()=>this.endTimeoutProcessLoadButton(thisButton), 20000); 126 127 if(thisButton.find("span.spinner-border").length == 0){ 128 thisButton.html('<span class="spinner-border me-1" role="status" aria-hidden="true"></span>'+$(thisButton).html()); 129 } 130 thisButton.prop('disabled', true); 131 132 } 133 134 endProcessLoadButton(thisButton){ 135 136 thisButton.find('span.spinner-border').remove(); 137 thisButton.prop('disabled', false); 138 139 } 140 141 showNotice(type, text=''){ 142 143 if(this.timerIdNotice){ 144 clearInterval(this.timerIdNotice); 145 } 146 147 $(".splash-notification").remove(); 148 149 var body = ` 150 <div class="splash-notification" > 151 <div class="splash-notification-container" > 152 <p>`+text+`</p> 153 </div> 154 </div> 155 `; 156 157 $("body").append(body); 158 159 $(".splash-notification").fadeIn(300); 160 161 this.timerIdNotice = setInterval(()=>$(".splash-notification").fadeOut(100, function(){ $(".splash-notification").remove();
161 clearInterval(this.timerIdNotice); }), 5000); 162 163 } 164 165 loadModal(target=null,params=null,callback=null,element=null){ 166 167 var _this = this; 168 169 $(".modalContent, .modal-backdrop").remove(); 170 171 $("body").append(` 172 173 <div class="modal fade modalContent" id="preloadModal" tabindex="-1" aria-hidden="true"> 174 <div class="modal-dialog modal-dialog-centered modal-fullscreen-md-down modal-dialog-scrollable modal-size-small" > 175 <div class="modal-content"> 176 177 <div class="modal-body"> 178 179 <div class="modal-title-skeleton" ></div> 180 <div class="modal-body-skeleton" ></div> 181 182 </div> 183 184 </div> 185 </div> 186 </div> 187 188 `); 189 190 $('#preloadModal').modal('show'); 191 192 this.request({url:"modal-open", data: {target: target, params: params}}, function(data) { 193 194 $(".modalContent").attr("id", target+"Modal"); 195 $(".modalContent").html(data["content"]); 196 197 _this.openModal(target+"Modal","auto",element,params); 198 199 if(callback) callback(); 200 201 }); 202 203 } 204 205 openModal(modalId, size=null, element=null, params=null){ 206 207 if(size != "auto"){ 208 $('#'+modalId+' .modal-dialog').removeClass("modal-size-*"); 209 if(size){ 210 $('#'+modalId+' .modal-dialog').addClass("modal-size-"+size); 211 }else{ 212 $('#'+modalId+' .modal-dialog').addClass("modal-size-small"); 213 } 214 } 215 216 if(element){ 217 if($(element).parents(".modal").length){ 218 $('#'+modalId).attr("data-parent-modal-id", $(element).parents(".modal").attr("id").replace('Modal','')); 219 if(params) $('#'+modalId).attr("data-parent-modal-params", params); 220 } 221 } 222 223 // 2026-09-29: do not hide the modal we are about to show. loadModal() reuses the already open preload modal, 224 // and Bootstrap ignores show() while that same modal is fading out, so on slow mobile internet 225 // (answer after the preload finished opening) the auth/other modals never appeared. 226 $(".modal").not('#'+modalId).modal("hide"); 227 $('#'+modalId).modal('show'); 228 229 } 230 231 hideModal(modalId, element=null){ 232 233 $('#'+modalId).modal('hide'); 234 235 if(element){ 236 if($(element).parents(".modal").attr("data-parent-modal-id") != undefined){ 237 this.loadModal($(element).parents(".modal").attr("data-parent-modal-id"), $(element).parents(".modal").attr("data-parent-modal-params")); 238 } 239 } 240 241 $(".modal").removeAttr('data-parent-modal-id'); 242 243 } 244 245 showNoticeAnswer(data, type="warning"){ 246 var text = []; 247 if(data != '' && data != undefined){ 248 if($.isArray(data) == true){ 249 $.each(data,function(index,value){ 250 text.push(value); 251 }); 252 }else{ 253 text.push(data); 254 } 255 this.showNotice(type, text.join("\n")); 256 } 257 } 258 259 showUiLoadingScreen(){ 260 $(".ui-loading-screen").show(); 261 } 262 263 hideUiLoadingScreen(){ 264 $(".ui-loading-screen").hide(); 265 } 266 267 goToRoute(route=null){ 268 269 location.href=route; 270 271 } 272 273 loadRoute(route){ 274 this.request({url:route,type: "GET",cache: false}, function(data) { 275 window.history.pushState({path:route},'',route); 276 document.write(data); 277 }); 278 } 279 280 getRoute(name=null){ 281 if(this.routes[name] != undefined){ 282 if(this.config("prefix_path")){ 283 return '/' + this.config("prefix_path") + this.routes[name]; 284 }else{ 285 return this.routes[name]; 286 } 287 } 288 } 289 290 getCurrentRoute(){ 291 if(this.routes["current_route_name"] != undefined){ 292 return this.routes["current_route_name"]; 293 } 294 } 295 296 generateStr(length=6){ 297 var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 298 var res = ''; 299 for (var i = 0, n = charset.length; i < length; ++i) { 300 res += charset.charAt(Math.floor(Math.random() * n)); 301 } 302 return res; 303 } 304 305 formLabelErrors(selector,data){ 306 var element_index = []; 307 if(data != '' && data != undefined){ 308 $.each(data,function(index,value){ 309 selector.find(".form-label-error[data-name="+index+"]").html(value).show(); 310 element_index.push(index); 311 }); 312 if(!selector.parents(".modal").length){ 313 if(selector.find(".form-label-error[data-name="+element_index[0]+"]").length && element_index.length){ 314 } 315 } 316 } 317 } 318 319 formNoticeManager(selector=null,data){ 320 321 if(data["type_show"] != '' && data["type_show"] != undefined){ 322 if(data["type_show"] == "notice"){ 323 this.showNoticeAnswer(data["answer"], data["type_answer"]); 324 }else if(data["type_show"] == "form"){ 325 this.formLabelErrors(selector,data["answer"]); 326 }else{ 327 this.showNoticeAnswer(data["answer"]); 328 } 329 }else{ 330 this.showNoticeAnswer(data["answer"]); 331 } 332 333 } 334 335 deleteModalAlert(_function, selector=null){ 336 337 $(".splash-notification-alert").remove(); 338 339 var body = ` 340 <div class="splash-notification-alert" > 341 <div class="splash-notification-alert-container" > 342 <p>`+this.translate.content("tr_9f9eb51b03430c96b23bb56d647d766b")+`</p> 343 <div class="splash-notification-alert-buttons" >
344 <span class="splash-notification-alert-yes" >`+this.translate.content("tr_e04af96afe53462f72f39331b209a810")+`</span> 345 <span class="splash-notification-alert-no" >`+this.translate.content("tr_d0cd2248137f1acac2e79777d856305e")+`</span> 346 </div> 347 </div> 348 </div> 349 `; 350 351 $("body").append(body); 352 353 $(".splash-notification-alert").fadeIn(300); 354 355 document.querySelector('.splash-notification-alert-yes').onclick = function() { 356 $(".splash-notification-alert").fadeOut(300); 357 _function(); 358 }; 359 360 document.querySelector('.splash-notification-alert-no').onclick = function() { 361 $(".splash-notification-alert").fadeOut(300, function(){ 362 $(".splash-notification-alert").remove(); 363 }); 364 }; 365 366 } 367 368 deleteByAlert(route=null,params=null){ 369 370 var thisClass = this; 371 372 this.deleteModalAlert(() => { 373 374 this.request({url:route, data: params}, function(data) { 375 376 if(data["status"] == true){ 377 if(data["redirect"] != undefined){ 378 location.href = data["redirect"]; 379 }else{ 380 location.reload(); 381 } 382 } 383 384 }); 385 386 }); 387 388 } 389 390 loadCaptcha(container){ 391 $(container).html('<div class="spinner-border spinner-border-sm text-primary" role="status"></div>'); 392 this.request({url:"captcha",dataType: "html",cache: false}, function(data) { 393 $(container).html('<img src="'+data+'" >'); 394 }); 395 } 396 397 openCaptcha(captcha_id, element=null){ 398 var thisClass = this; 399 400 this.loadModal("captcha", {captcha_id: captcha_id}, function(data) { 401 thisClass.loadCaptcha('.captchaModalImageContainer'); 402 },element); 403 404 } 405 406 copyToClipboard(value){ 407 408 navigator.clipboard.writeText(value); 409 410 this.showNoticeAnswer(this.translate.content("tr_f70b4aef6db4db098688e67ca61c4c3c"), "success"); 411 412 } 413 414 endingWord(number, one, two, five){ 415 416 var ending = ''; 417 var last_digit = ''; 418 number = number % 100; 419 420 if ((number > 4 && number < 21) || number == 0){ 421 ending = five; 422 }else{ 423 last_digit = String(number).substr(-1); 424 if (last_digit > 1 && last_digit < 5) 425 ending = two; 426 else if (last_digit == 1) 427 ending = one; 428 else 429 ending = five; 430 } 431 return ending; 432 433 } 434 435 uniSelectUpdate(){ 436 437 var _this = this; 438 439 $('.uni-select').each(function (index, element) { 440 441 if( $(element).find(".uni-select-item-active").length == 1 ){ 442 $(element).find(".uni-select-name").html($(element).find(".uni-select-item-active span").html()); 443 }else if( $(element).find(".uni-select-item-active").length > 1 ){ 444 $(element).find(".uni-select-name").html(_this.translate.content("tr_c8775dcb5146e06356e352b69bb89764")+" ("+$(element).find(".uni-select-item-active").length+")" ); 445 }else if($(element).find(".uni-select-content-input").length){ 446 447 var name = $(this).find(".uni-select-name"); 448 449 if($(element).find("input[data-type=from]").val() && $(element).find("input[data-type=to]").val()){ 450 name.html(_this.translate.content("tr_996b125bc9bba860718d999df2ecc61d")+" "+$(element).find("input[data-type=from]").val()+" "+_this.translate.content("tr_538dc63d3c6db1a1839cafbaf359799b")+" "+$(element).find("input[data-type=to]").val()); 451 }else if($(element).find("input[data-type=from]").val()){ 452 name.html(_this.translate.content("tr_996b125bc9bba860718d999df2ecc61d")+" "+$(element).find("input[data-type=from]").val()); 453 }else if($(element).find("input[data-type=to]").val()){ 454 name.html(_this.translate.content("tr_c2aa9c0cecea49717bb2439da36a7387")+" "+$(element).find("input[data-type=to]").val()); 455 }else if($(element).find("input[data-type=text]").val()){ 456 name.html($(element).find("input[data-type=text]").val()); 457 }else{ 458 name.html(name.data("default-name")); 459 } 460 461 } 462 463 }); 464 465 } 466 467 checkFlashNotify(){ 468 469 var _this = this; 470 471 _this.request({url:"check-flash-notify"}, function(data) { 472 if(data != null && data != undefined){ 473 $.each(data,function(index,value){ 474 _this.showNotice(value["type"], value["message"]); 475 }); 476 } 477 }); 478 479 } 480 481 paramsForm(selector){
482 return $.param($(selector).serializeArray().filter(function(el) { 483 return $.trim(el.value); 484 })); 485 } 486 487 setParamsFormUrl(selector){ 488 var hashes = window.location.href.split('?'); 489 var params = $.param($(selector).serializeArray().filter(function(el) { 490 return $.trim(el.value); 491 })); 492 if(params){ 493 history.pushState("", "", hashes[0]+"?"+params); 494 }else{ 495 history.pushState("", "", hashes[0]); 496 } 497 } 498 499 initPhoneMask(){ 500 } 501 502 setPhoneMask(selector, template){ 503 } 504 505 lazyImg(){ 506 507 const candidates = document.querySelectorAll('img[data-src], img[data-srcset], picture > img[data-src], [data-bg]'); 508 509 const loadEl = (el) => { 510 511 if (el.tagName === 'IMG' && el.parentElement && el.parentElement.tagName === 'PICTURE') { 512 el.parentElement.querySelectorAll('source[data-srcset]').forEach((source) => { 513 source.srcset = source.dataset.srcset; 514 source.removeAttribute('data-srcset'); 515 }); 516 } 517 518 if (el.tagName === 'IMG') { 519 if (el.dataset.srcset) { 520 el.srcset = el.dataset.srcset; 521 el.removeAttribute('data-srcset'); 522 } 523 if (el.dataset.src) { 524 el.src = el.dataset.src; 525 el.removeAttribute('data-src'); 526 } 527 el.addEventListener('load', () => el.classList.add('loaded'), { once: true }); 528 } 529 530 if (el.hasAttribute('data-bg')) { 531 const url = el.getAttribute('data-bg'); 532 el.style.backgroundImage = `url("${url}")`; 533 el.removeAttribute('data-bg'); 534 requestAnimationFrame(() => el.classList.add('loaded')); 535 } 536 }; 537 538 const observe = () => { 539 if ('IntersectionObserver' in window) { 540 const io = new IntersectionObserver((entries, obs) => { 541 entries.forEach((entry) => { 542 if (entry.isIntersecting) { 543 loadEl(entry.target); 544 obs.unobserve(entry.target); 545 } 546 }); 547 }, { rootMargin: '300px 0px', threshold: 0.01 }); 548 549 candidates.forEach((el) => io.observe(el)); 550 } else { 551 const inViewport = (el, pad = 300) => { 552 const r = el.getBoundingClientRect(); 553 return r.bottom > -pad && r.top < (window.innerHeight || document.documentElement.clientHeight) + pad; 554 }; 555 const onScroll = () => { 556 candidates.forEach((el) => { 557 if (el.dataset.__loaded) return; 558 if (inViewport(el)) { 559 loadEl(el); 560 el.dataset.__loaded = '1'; 561 } 562 }); 563 if ([...candidates].every((el) => el.dataset.__loaded)) { 564 window.removeEventListener('scroll', onScroll); 565 window.removeEventListener('resize', onScroll); 566 window.removeEventListener('orientationchange', onScroll); 567 } 568 }; 569 ['scroll', 'resize', 'orientationchange'].forEach((evt) => window.addEventListener(evt, onScroll, { passive: true })); 570 onScroll(); 571 } 572 }; 573 574 if (document.readyState === 'loading') { 575 document.addEventListener('DOMContentLoaded', observe, { once: true }); 576 } else { 577 observe(); 578 } 579 580 } 581 582 initCountdown(){ 583 584 var _this = this; 585 586 $('[data-countdown="true"]').each(function (index, element) { 587 $(element).countdown( $(element).attr("data-date") ) 588 .on('update.countdown', function(event) { 589 if(event.strftime('%-D') != '0'){ 590 $(element).html(event.strftime('%-D')+" "+_this.endingWord(event.strftime('%-D'), _this.translate.content("tr_48e438a146f96b54bbe9d5046ffc3a2b"), _this.translate.content("tr_0871eeafdf38726742fa5affa8a5d6eb"), _this.translate.content("tr_c183655a02377815e6542875555b1340"))+" "+event.strftime('%H:%M:%S')); 591 }else{ 592 $(element).html(event.strftime('%H:%M:%S')); 593 } 594 $(element).css("display","inline-block"); 595 }) 596 .on('finish.countdown', function(event) { 597 $(element).removeClass("urgent").html(_this.translate.content("tr_0083ce05cc74718b7e875995296bc29a")).css("display","inline-block"); 598 }); 599 600 }); 601 602 } 603 604} 605 606window.Helpers = Helpers;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.