// deno-lint-ignore-file no-unused-vars // Not ideal code at all. /** @type {Resources} */ const resources = Promise.all([ fetch('meta.json').then(r => r.json()), fetch('data.json').then(r => r.json()) ]).then(([meta, data]) => ({ meta: meta, data: data })); /** * @param {string} selector * @returns {HTMLElement} */ function query(selector) { return document.querySelector(selector); } /** * @param {string} tag * @returns {HTMLElement} */ function create(tag) { return document.createElement(tag); } function format(n) { const s = []; const k = n.toString(); for (let i = k.length; i >= 0; i -= 3) s.unshift(k.slice(i < 3 ? 0 : i - 3, i)); return s.join(' '); } /** * * @param {string | string[]} from * @param {string | string[]} to * @param {Record<string, string>} info */ function mkitem(from, to, info) { const table = create('table'); if (typeof from === 'string') from = [from]; if (typeof to === 'string') to = [to]; const continued = [false, false]; let state = 0; function add(key, value, indent) { const tr = create('tr'); const lead = (state === 0 ? '借:' : ' 贷:'); const a = create('td'); const [head, tail] = key.split('——'); if (!indent) a.append( (continued[state] ? ' '.repeat(lead.length) : lead), Object.assign(create('abbr'), { innerText: head, title: '不要偷看 |ω・`)' }), tail ? '——' + tail : '' ); else a.append( (continued[state] ? ' '.repeat(lead.length) : lead), ' '.repeat(indent), Object.assign(create('span'), { innerText: head, }), tail ? '——' + tail : '' ); tr.append( a, Object.assign(create('td'), { innerText: state === 0 ? value : '' }), Object.assign(create('td'), { innerText: state === 0 ? '' : value }) ); table.appendChild(tr); continued[state] = true; } function getflag(i) { for (const k in info) if (i.includes('%' + k)) return k; return 'total'; } for (const s of [0, 1]) { state = s; for (const i of [from, to][state]) { const flag = getflag(i); const name = i.replace('%' + flag, ''); if (info.code && i.endsWith('——')) { add(name + info.code1, info.bonus1); if (info.split2 !== '') add('——' + info.code2, info.bonus2, name.length - 2 + 1 /* css padding */); } else add(name, info[flag]); } } return table; } /** * * @param {T[]} array * @returns {T} */ function select(array) { return array[Math.random() * array.length | 0]; } if (!('replaceAll' in String)) String.prototype.replaceAll = function (search, replace) { return this.replace(new RegExp(search, 'g'), replace); } /** * * @param {string} topic * @param {Record<string, string>} holders */ function hold(topic, holders) { for (const key in holders) { topic = topic.replaceAll('%' + key, holders[key]); } return topic; } function maxdate(year, month) { switch (month) { case 4: case 6: case 9: case 11: return 30; case 2: return (year % 4 === 0 && year % 100 !== 0) ? 29 : 28; default: return 31; } } const today = new Date(); /** * * @param {QuizMeta} meta * @param {string} topic * @param {string} sub * @returns */ function getinfo(meta, topic, sub) { /** * @param {string} string * @param {string} flag * @returns {boolean} */ function hasflag(flag) { return topic.includes('%' + flag); } const self = select(meta.self); const code = sub ? select(meta.code[sub]) : ''; const code1 = code; const code2 = code1 ? select(meta.code[sub].filter(x => x !== code)) : ''; const y = today.getFullYear(); const m = hasflag('month12') ? 12 : today.getMonth() + 1; /* const d = hasflag('date1') ? 1 : hasflag('date15') ? (Math.random() * maxdate(y, m) | 0 + 1) : maxdate(y, m); */ const d = maxdate(y, m); const date = ` ${y} 年 ${m} 月 ${d} 日`; const other = sub === 'others' ? code : select(meta.code['others']); const split = hasflag('split') ? (2 + (Math.random() * 6 | 0)) / 10 : 1; const amount = 10 * (Math.random() * 5 + 1 | 0); const amount1 = amount * split | 0; const amount2 = amount - amount1; const price = 100 * (Math.random() * 100 + 1 | 0); const sum = amount * price; const split1 = sum * split | 0; const split2 = sum - split1; let rate = hasflag('rate') || hasflag('rate13') || hasflag('inc') ? 0.13 : 0; if (hasflag('rate10')) rate = 0.1; else if (hasflag('rate5')) rate = 0.05; else if (hasflag('rate25')) rate = 0.25; const inc = sum * rate; const period = ' ' + (2 + Math.random() * 10 | 0).toString() + ' ' + (hasflag('longterm') ? '年' : '个月'); //FIXME: various extras? const extra = 100 * (Math.random() * 50 + 1 | 0); const extra_count = topic.match(/%extra/g)?.length ?? 0; const bonus = sum + extra * extra_count; const bonus1 = bonus * split | 0; const bonus2 = bonus - bonus1; const total = bonus + inc; return { 'longterm': '', 'date1': '', 'month12': '', 'rate5': '', 'rate10': '', 'rate13': '', 'rate25': '', 'date': date, 'self': self, 'other': other, 'code1': code1, 'code2': code2, 'code': code, 'amount1': format(amount1), 'amount2': format(amount2), 'amount': format(amount), 'price': format(price), 'sum': format(sum), 'rate': (rate * 100).toString() + '%', 'inc': format(inc), 'extra': format(extra), 'bonus': format(bonus), 'total': format(total), 'split1': format(split1), 'split2': split2 === 0 ? '' : format(split2), 'bonus1': format(bonus1), 'bonus2': bonus2 === 0 ? '' : format(bonus2), 'period': period, 'split': '', }; } // @license-end