/* Учебный чемпионат. Расчёт повторяет шкалу Irish points текущего сайта. */ (function (document) { 'use strict'; var demo = document.querySelector('[data-home-demo]'); var inputTable = demo && demo.querySelector('[data-demo-champ-inputs]'); if (!inputTable || inputTable.getAttribute('data-initialized') === '1') { return; } inputTable.setAttribute('data-initialized', '1'); var protocol = demo.querySelector('[data-demo-champ-protocol]'); var openButton = demo.querySelector('[data-demo-champ-open]'); var statuses = Array.prototype.slice.call(demo.querySelectorAll('[data-demo-champ-status]')); var inputs = Array.prototype.slice.call(inputTable.querySelectorAll('[data-demo-champ-mark]')); var grid = [100, 75, 65, 60, 56, 53, 50, 47, 45, 43]; function setStatus(kind) { statuses.forEach(function (status) { status.textContent = status.getAttribute('data-' + kind); }); } function markDirty() { setStatus('dirty'); openButton.disabled = true; [inputTable, protocol].forEach(function (table) { Array.prototype.forEach.call(table.querySelectorAll('[data-demo-champ-total], [data-demo-champ-points], [data-demo-champ-place], [data-demo-champ-combined], [data-demo-champ-round-mark]'), function (cell) { cell.textContent = '—'; }); }); } function calculate() { var invalid = inputs.filter(function (input) { var failed = !input.checkValidity() || !isFinite(parseFloat(input.value)); input.setAttribute('aria-invalid', failed ? 'true' : 'false'); return failed; }); if (invalid.length) { setStatus('invalid'); invalid[0].focus(); return; } var records = Array.prototype.map.call(inputTable.querySelectorAll('[data-demo-champ-number]'), function (row) { var totals = [0, 0, 0]; var rounds = [[], [], []]; Array.prototype.forEach.call(row.querySelectorAll('[data-demo-champ-mark]'), function (input) { // Целые сотые исключают погрешность сравнения одинаковых сумм. var judge = Number(input.getAttribute('data-judge')); var mark = Math.round(Number(input.value) * 100); totals[judge] += mark; rounds[judge][Number(input.getAttribute('data-round'))] = mark; }); return { number: row.getAttribute('data-demo-champ-number'), totals: totals, rounds: rounds, points: [0, 0, 0], combined: 0 }; }); for (var judge = 0; judge < 3; judge++) { var order = records.slice().sort(function (first, second) { return second.totals[judge] - first.totals[judge]; }); var start = 0; while (start < order.length) { var end = start + 1; while (end < order.length && order[end].totals[judge] === order[start].totals[judge]) { end++; } var sum = 0; for (var index = start; index < end; index++) { sum += grid[index]; } var points = Math.round(sum / (end - start) * 100); for (var index = start; index < end; index++) { order[index].points[judge] = points; } start = end; } } records.forEach(function (record) { record.combined = record.points.reduce(function (sum, value) { return sum + value; }, 0); var row = protocol.querySelector('[data-demo-champ-number="' + record.number + '"]'); for (var judge = 0; judge < 3; judge++) { row.querySelector('[data-demo-champ-total="' + judge + '"]').textContent = (record.totals[judge] / 100).toFixed(2); row.querySelector('[data-demo-champ-points="' + judge + '"]').textContent = (record.points[judge] / 100).toFixed(2); for (var round = 0; round < 3; round++) { row.querySelector('[data-demo-champ-round-mark="' + judge + '-' + round + '"]').textContent = (record.rounds[judge][round] / 100).toFixed(1); } } }); records.sort(function (first, second) { return second.combined - first.combined || Number(first.number) - Number(second.number); }); var place = 0; var previous = null; records.forEach(function (record, index) { if (record.combined !== previous) { place = index + 1; previous = record.combined; } var row = protocol.querySelector('[data-demo-champ-number="' + record.number + '"]'); row.querySelector('[data-demo-champ-place]').textContent = place; row.querySelector('[data-demo-champ-combined]').textContent = (record.combined / 100).toFixed(2); protocol.querySelector('tbody').appendChild(row); }); openButton.disabled = false; setStatus('ready'); } inputs.forEach(function (input) { input.addEventListener('input', markDirty); }); demo.querySelector('[data-demo-champ-calculate]').addEventListener('click', calculate); openButton.addEventListener('click', function () { demo.querySelector('[data-demo-mode="1"]').click(); demo.querySelector('[data-demo-slide="6"]').click(); }); calculate(); })(document);