PageSourceSearch

https://muxtly.pages.dev/assets/js/i18n.js

js muxtly.pages.dev collected 2026-10-03 05:40:39 UTC 9,581 bytes, 155 lines download raw bytes

1(function(){var FALLBACK=['zh-TW','zh-CN','es','fr','ja','ko','pt','de'];var SUPPORTED=(function(){try{var out=[];var ls=document.querySelectorAll('link[rel=alternate][hreflang]');for(var i=0;i<ls.length;i++){var h=ls[i].getAttribute('hreflang');if(!h||h==='x-default'||h==='en')continue;if(out.indexOf(h)===-1)out.push(h);}return out.length?out:FALLBACK;}catch(e){return FALLBACK;}})();function detectLang(){var raw=(navigator.languages&&navigator.languages[0])||navigator.language||'';var lang=raw.toLowerCase().replace('_','-');var exact=SUPPORTED.find(function(s){return s.toLowerCase()===lang;});if(exact)return exact;var prefix=lang.split('-')[0];var pref=SUPPORTED.find(function(s){return s.toLowerCase()===prefix;});if(pref)return pref;return null;}function maybeRedirect(){if(location.pathname!=='/'&&location.pathname!=='/index.html')return;if(localStorage.getItem('toolhub-lang-chosen'))return;var target=detectLang();if(!target)return;var newPath='/'+target+'/';var base=location.pathname.replace(/\/(index\.html)?\/?$/,'');if(base&&base!=='/')newPath=base+newPath;if(location.pathname!==newPath)location.replace(newPath);}maybeRedirect();document.addEventListener('DOMContentLoaded',function(){var dropdown=document.querySelector('.lang-dropdown');if(!dropdown)return;var btn=dropdown.querySelector('.lang-btn');var menu=dropdown.querySelector('.lang-menu');if(!btn||!menu)return;btn.addEventListener('click',function(e){e.stopPropagation();menu.classList.toggle('show');});document.addEventListener('click',function(){menu.classList.remove('show');});menu.addEventListener('click',function(e){if(!e.target.closest('a'))e.stopPropagation();});menu.querySelectorAll('a').forEach(function(link){link.addEventListener('click',function(){localStorage.setItem('toolhub-lang-chosen','1');});});});})();
2
3
4/* ===== Custom English date picker (replaces browser-native date calendar) ===== */
5/* perf(batch46-B, 2026-08-17): the calendar widget (42+ nodes) and its render
6 * listeners were built at script execution on EVERY page, even pages with no
7 * date input at all. Now the calendar DOM is created lazily by ensureDP() on
8 * the first date-input interaction; the MutationObserver (cheap) still starts
9 * immediately so dynamically added date rows are enhanced as before. */
10(function () {
11  var dp = null, titleEl = null, weekEl = null, gridEl = null;
12  var viewY = 0, viewM = 0, currentInput = null;
13
14  var MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
15  var WEEKDAYS = ['Su','Mo','Tu','We','Th','Fr','Sa'];
16  var pad = function (n) { return n < 10 ? '0' + n : '' + n; };
17  var fmt = function (d) { return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()); };
18
19  function ensureDP() {
20    if (dp) return dp;
21    dp = document.createElement('div');
22    dp.className = 'muxtly-dp';
23    dp.style.cssText = 'position:fixed;z-index:2147483000;display:none;background:var(--surface,#ffffff);border:1px solid var(--border,#d1d5db);border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.18);padding:10px;width:264px;color:var(--text,#111827);user-select:none;font-size:.85rem';
24    dp.innerHTML =
25      '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">' +
26        '<button type="button" class="muxtly-dp-prev" style="border:1px solid var(--border,#d1d5db);background:var(--surface,#f9fafb);border-radius:6px;width:26px;height:26px;cursor:pointer;font-size:1rem;line-height:1">&#8249;</button>' +
27        '<span class="muxtly-dp-title" style="font-weight:700;font-size:.9rem"></span>' +
28        '<button type="button" class="muxtly-dp-next" style="border:1px solid var(--border,#d1d5db);background:var(--surface,#f9fafb);border-radius:6px;width:26px;height:26px;cursor:pointer;font-size:1rem;line-height:1">&#8250;</button>' +
29      '</div>' +
30      '<div class="muxtly-dp-week" style="display:grid;grid-template-columns:repeat(7,1fr);text-align:center;font-weight:600;color:var(--text-muted,#6b7280);font-size:.72rem;margin-bottom:4px"></div>' +
31      '<div class="muxtly-dp-grid" style="display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center"></div>';
32    document.body.appendChild(dp);
33    titleEl = dp.querySelector('.muxtly-dp-title');
34    weekEl = dp.querySelector('.muxtly-dp-week');
35    gridEl = dp.querySelector('.muxtly-dp-grid');
36    WEEKDAYS.forEach(function (w) {
37      var s = document.createElement('div'); s.textContent = w; weekEl.appendChild(s);
38    });
39    dp.querySelector('.muxtly-dp-prev').addEventListener('click', function (e) { e.stopPropagation(); viewM--; if (viewM < 0) { viewM = 11; viewY--; } render(); });
40    dp.querySelector('.muxtly-dp-next').addEventListener('click', function (e) { e.stopPropagation(); viewM++; if (viewM > 11) { viewM = 0; viewY++; } render(); });
41    dp.addEventListener('click', function (e) { e.stopPropagation(); });
42    document.addEventListener('click', close);
43    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
44    window.addEventListener('scroll', close, true);
45    return dp;
46  }
47
48  function close() {
49    if (!dp) return;
50    dp.style.display = 'none';
51    currentInput = null;
52  }
53
54  function render() {
55    titleEl.textContent = MONTHS[viewM] + ' ' + viewY;
56    gridEl.innerHTML = '';
57    var first = new Date(viewY, viewM, 1);
58    var startDow = first.getDay();
59    var daysInMonth = new Date(viewY, viewM + 1, 0).getDate();
60    var today = new Date(); today.setHours(0, 0, 0, 0);
61    var todayStr = fmt(today);
62    var selectedStr = currentInput && currentInput.value ? currentInput.value : '';
63    var blank = daysInMonth + startDow;
64    var cells = Math.ceil(blank / 7) * 7;
65    for (var i = 0; i < cells; i++) {
66      var d = i - startDow + 1;
67      var cell = document.createElement('button');
68      cell.type = 'button';
69      if (d < 1 || d > daysInMonth) {
70        cell.style.visibility = 'hidden';
71      } else {
72        var dt = new Date(viewY, viewM, d);
73        var ds = fmt(dt);
74        cell.textContent = d;
75        cell.style.cssText = 'border:none;background:none;border-radius:6px;height:30px;cursor:pointer;color:var(--text,#111827)';
76        if (ds === todayStr) { cell.style.fontWeight = '800'; cell.style.color = '#2563eb'; }
77        if (ds === selectedStr) { cell.style.background = '#2563eb'; cell.style.color = '#fff'; cell.style.fontWeight = '700'; }
78        cell.addEventListener('mouseenter', function () {
79          if (this.style.background !== 'rgb(37, 99, 235)') this.style.background = 'var(--primary,#2563eb)';
80          if (this.style.background.indexOf('37, 99, 235') === -1 && this.style.background !== 'rgb(37, 99, 235)') this.style.background = 'rgba(37,99,235,.12)';
81        });
82        cell.addEventListener('mouseleave', function () {
83          if (this.style.background.indexOf('rgba') !== -1) this.style.background = 'none';
84        });
85        (function (dsv) {
86          cell.addEventListener('click', function () {
87            if (currentInput) {
88              currentInput.value = dsv;
89              currentInput.dispatchEvent(new Event('input', { bubbles: true }));
90              currentInput.dispatchEvent(new Event('change', { bubbles: true }));
91            }
92            close();
93          });
94        })(ds);
95      }
96      gridEl.appendChild(cell);
97    }
98  }
99
100  function open(input) {
101    ensureDP();
102    var now = new Date();
103    var v = input.value;
104    if (v && /^\d{4}-\d{2}-\d{2}$/.test(v)) {
105      var parts = v.split('-');
106      viewY = parseInt(parts[0], 10); viewM = parseInt(parts[1], 10) - 1;
107    } else {
108      viewY = now.getFullYear(); viewM = now.getMonth();
109    }
110    currentInput = input;
111    render();
112    var rect = input.getBoundingClientRect();
113    var top = rect.bottom + 6;
114    if (top + 320 > window.innerHeight) { top = rect.top - 310; }
115    if (top < 4) { top = 4; }
116    var left = Math.min(Math.max(4, rect.left), window.innerWidth - 280);
117    dp.style.display = 'block';
118    dp.style.top = top + 'px';
119    dp.style.left = left + 'px';
120  }
121
122  function enhance() {
123    document.querySelectorAll('input[data-date], input[type="date"]').forEach(function (inp) {
124      if (inp.dataset.muxtlyDp) return;
125      inp.dataset.muxtlyDp = '1';
126      var v = inp.value;
127      if (inp.type === 'date') { try { inp.type = 'text'; } catch (e) { /* keep date type */ } }
128      inp.value = v;
129      inp.setAttribute('placeholder', 'dd/mm/yyyy');
130      inp.readOnly = true;
131      inp.style.cursor = 'pointer';
132      inp.addEventListener('click', function (e) { e.stopPropagation(); open(inp); });
133      inp.addEventListener('keydown', function (e) {
134        if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); open(inp); }
135      });
136    });
137  }
138  enhance();
139  if (document.readyState === 'loading') {
140    document.addEventListener('DOMContentLoaded', enhance);
141  }
142  var observer = new MutationObserver(function (mutations) {
143    for (var i = 0; i < mutations.length; i++) {
144      var added = mutations[i].addedNodes;
145      for (var j = 0; j < added.length; j++) {
146        var node = added[j];
147        if (node.nodeType === 1) {
148          if (node.tagName === 'INPUT' && (node.getAttribute('data-date') || node.type === 'date')) { enhance(); return; }
149          if (node.querySelectorAll) { if (node.querySelectorAll('input[data-date], input[type="date"]').length) { enhance(); return; } }
150        }
151      }
152    }
153  });
154  observer.observe(document.documentElement || document.body || document, { childList: true, subtree: true });
155})();

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.