<div id="calculator" class="cost-calculator-out section">
<div class=" section-content cost-calculator">
<div class="cost-calculator-side">
<div class="cost-calculator-side-anim">
<video class="cost-calculator-side-anim-video" src="assets/images/videonft/nftvid1.mp4" autoplay muted loop playsinline></video>
<img class="cost-calculator-side-anim-image" src="assets/images/videonft/videoframe.png" />
</div>
</div>
<div class="cost-calculator-main">
<div class="cost-calculator-main-inner w80 w-xl-90 w-lg-100">
<h2 class="marginBottomBig">Cost Calculator</h2>
<form>
<div class="row">
<div class="form-control-out col-xl-6 col-lg-7 col-md-8 col-sm-10 col-xs-12">
<div class="input-container">
<select id="network" class="form-control" style="width: 100%;">
<option value="poly" data-icon="uploads/admin/icons/icon-crypto-poly.svg">Polygon</option>
<!-- Add more if needed -->
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-control-out col-xl-6 col-lg-7 col-md-8 col-sm-10 col-xs-7">
<div class="input-container">
<input class="form-control" type="text" id="totalcertificates" placeholder=" " required />
<label for="businessname">Total Certificate</label>
</div>
</div>
</div>
<div class="row">
<div class="form-control-out col-xl-6 col-lg-7 col-md-8 col-sm-10 col-xs-7">
<div class="input-container">
<input class="form-control" type="text" id="totalcashback" placeholder=" " required />
<label for="website">Total Cashback</label>
</div>
</div>
<div class="form-control-out col-xl-6 col-lg-7 col-md-8 col-sm-10 col-xs-7">
<div class="info-container" for="totalcashback">
<div class="w100">
<span id="cryptoAmount">1235.00</span>
<span id="cryptoCoin">Poly</span>
</div>
<div class="w100">
<span id="perCertificate">1.00</span>
<span>$ Per Certificate</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-control-out col-xl-6 col-lg-7 col-md-8 col-sm-10 col-xs-12">
<label for="suffleRange">Suffle</label>
<div class="input-container range-input-container">
<input type="range" id="suffleRange" class="range-slider" min="0" max="100" step="5" value="50" />
<span class="range-value" id="suffleValue">50%</span>
</div>
</div>
<div id="validationMessage" style="color: red; font-size: 14px; display: none;">
The values don't match the total cashback or item count. Please adjust them.
</div>
</div>
<div class="row">
<div class="form-control-out col-xl-10 col-lg-11 col-md-12 col-sm-12 col-xs-12">
<div class="row">
<div class="col-xl-4 col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="cc-icons-out cc-certificates">
<img class="cc-icon" src="uploads/admin/icons/icon-48-cert.svg" />
<div class="cc-certificates-info cc-icons-info">
<div class="w100">
<input type="number" class="value-input green" id="certificateItemsNo" />
<span class="green">item</span>
</div>
<div class="w100">
<input type="number" class="value-input green" step="0.01" id="certificateItemsCashback" />
<span class="green">each</span>
</div>
</div>
</div>
</div>
<div class="col-xl-4 col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="cc-icons-out cc-certificates">
<img class="cc-icon" src="uploads/admin/icons/icon-48-star.svg" />
<div class="cc-semijackpots-info cc-icons-info">
<div class="w100">
<input type="number" class="value-input orangeLighten" id="semijackpotItemsNo" />
<span class="orangeLighten">item</span>
</div>
<div class="w100">
<input type="number" class="value-input orangeLighten" step="0.01" id="semijackpotItemsCashback" />
<span class="orangeLighten">each</span>
</div>
</div>
</div>
</div>
<div class="col-xl-4 col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="cc-icons-out cc-certificates">
<img class="cc-icon" src="uploads/admin/icons/icon-48-star2.svg" />
<div class="cc-jackpots-info cc-icons-info">
<div class="w100">
<input type="number" class="value-input orange" id="jackpotItemsNo" value="1" readonly />
<span class="orange">item</span>
</div>
<div class="w100">
<input type="number" class="value-input orange" step="0.01" id="jackpotItemsCashback" />
<span class="orange">each</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-control-out col-6">
<div class="input-container">
<input class="anime button scrollTo" data-scroll-to="#register" onClick="javascript:void(0);" type="submit" value="Start Building" />
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<style type="text/css">
.select2-container .select2-selection--single {
height: auto;
background-color: #F5F5F5 !important;
padding: 10px 10px 10px !important;
border-radius: 22px !important;
color: #000 !important;
border: 2px solid #F2F2F2 !important;
width: 100% !important;
font-size: 16px !important;
line-height: 1.2 !important;
outline: none;
transition: all 0.3s ease;
height: auto !important;
}
.select2-container .select2-selection--single .select2-selection__rendered {
padding-left: 0 !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
top: 14px !important;
right: 11px !important;
}
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
padding: 6px 11px !important;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", () => {
const slider = document.getElementById("suffleRange");
const sliderValue = document.getElementById("suffleValue");
const totalCertsInput = document.getElementById("totalcertificates");
const totalCashbackInput = document.getElementById("totalcashback");
const certItemsNo = document.getElementById("certificateItemsNo");
const certItemsCashback = document.getElementById("certificateItemsCashback");
const semiJackpotNo = document.getElementById("semijackpotItemsNo");
const semiJackpotCashback = document.getElementById("semijackpotItemsCashback");
const jackpotNo = document.getElementById("jackpotItemsNo");
const jackpotCashback = document.getElementById("jackpotItemsCashback");
const validationMessage = document.getElementById("validationMessage");
let regCashbackArr = [], semiCashbackArr = [], jackpotCashbackArr = [];
fetchMaticPrice();
async function fetchMaticPrice() {
try {
const response = await fetch("https://api.coingecko.com/api/v3/simple/price?ids=matic-network&vs_currencies=usd");
const data = await response.json();
currentMaticPrice = data["matic-network"].usd;
updateCryptoAmount(); // call it immediately on fetch
} catch (err) {
console.error("Failed to fetch MATIC price:", err);
}
}
function updateCryptoAmount() {
const totalCashback = parseFloat(totalCashbackInput.value) || 0;
if (currentMaticPrice > 0) {
const polygonAmount = totalCashback / currentMaticPrice;
document.getElementById("cryptoAmount").textContent = polygonAmount.toFixed(2);
}
}
totalCashbackInput.addEventListener("input", () => {
updateFromSlider();
updateCryptoAmount(); // 👈 Add this
});
function updatePerCertificate() {
const totalCashback = parseFloat(totalCashbackInput.value) || 0;
const totalCerts = parseInt(totalCertsInput.value) || 0;
const perCert = totalCerts > 0 ? totalCashback / totalCerts : 0;
document.getElementById("perCertificate").textContent = perCert.toFixed(2);
}
totalCashbackInput.addEventListener("input", () => {
updateFromSlider();
updateCryptoAmount();
updatePerCertificate(); // 👈 add this
});
totalCertsInput.addEventListener("input", () => {
updateFromSlider();
updatePerCertificate(); // 👈 add this
});
updatePerCertificate();
function updateFromSlider() {
const totalCerts = parseInt(totalCertsInput.value) || 100;
const totalCashback = parseFloat(totalCashbackInput.value) || 100;
const shufflePercent = parseInt(slider.value) || 0;
sliderValue.textContent = shufflePercent + "%";
let jackpotCount = 0;
let semiCount = 0;
let regularCount = totalCerts;
if (shufflePercent > 0) {
jackpotCount = 1;
semiCount = 4;
regularCount = totalCerts - semiCount - jackpotCount;
}
// Cashback distribution
let regTotal = 0, semiTotal = 0, jackpotTotal = 0;
if (shufflePercent === 0) {
regTotal = totalCashback;
} else {
const regShare = (100 - shufflePercent) / 100;
const shuffleShare = shufflePercent / 100;
regTotal = +(totalCashback * regShare).toFixed(4);
const shuffledAmount = +(totalCashback - regTotal).toFixed(4);
// 1:4 ratio for semi:jackpot
const totalWeight = semiCount * 1 + jackpotCount * 4;
const unit = shuffledAmount / totalWeight;
semiTotal = +(unit * semiCount).toFixed(4);
jackpotTotal = +(unit * 4 * jackpotCount).toFixed(4);
}
// Build precise arrays using rounding adjustment
regCashbackArr = roundWithAdjustment(regTotal, regularCount);
semiCashbackArr = roundWithAdjustment(semiTotal, semiCount);
jackpotCashbackArr = roundWithAdjustment(jackpotTotal, jackpotCount);
// Update UI fields with accurate averages
const regAvg = average(regCashbackArr);
const semiAvg = average(semiCashbackArr);
const jackpotAvg = average(jackpotCashbackArr);
certItemsNo.value = regularCount;
certItemsCashback.value = regAvg.toFixed(2);
semiJackpotNo.value = semiCount;
semiJackpotCashback.value = semiAvg.toFixed(2);
jackpotNo.value = jackpotCount;
jackpotCashback.value = jackpotAvg.toFixed(2);
validateTotals();
}
function roundWithAdjustment(total, count) {
if (count === 0) return [];
const raw = total / count;
const floored = Math.floor(raw * 100) / 100;
const arr = Array(count).fill(floored);
let currentSum = arr.reduce((a, b) => a + b, 0);
let remaining = +(total - currentSum).toFixed(2);
arr[arr.length - 1] = +(arr[arr.length - 1] + remaining).toFixed(2);
return arr;
}
function sumArray(arr) {
return arr.reduce((a, b) => a + b, 0);
}
function average(arr) {
return arr.length ? sumArray(arr) / arr.length : 0;
}
function average(arr) {
if (!arr.length) return 0;
return arr.reduce((a, b) => a + b, 0) / arr.length;
}
function validateTotals() {
const enteredCerts = parseInt(totalCertsInput.value) || 100;
const enteredCashback = parseFloat(totalCashbackInput.value) || 100;
const regCount = parseInt(certItemsNo.value) || 0;
const semiCount = parseInt(semiJackpotNo.value) || 0;
const jackpotCount = parseInt(jackpotNo.value) || 0;
const totalItems = regCount + semiCount + jackpotCount;
const realCashbackSum =
sumArray(regCashbackArr) +
sumArray(semiCashbackArr) +
sumArray(jackpotCashbackArr);
const isValid =
totalItems === enteredCerts &&
Math.abs(realCashbackSum - enteredCashback) < 0.01;
const inputsToValidate = [
certItemsNo,
certItemsCashback,
semiJackpotNo,
semiJackpotCashback,
jackpotNo,
jackpotCashback
];
if (!isValid) {
validationMessage.style.display = "block";
inputsToValidate.forEach(input => input.classList.add("invalid"));
} else {
validationMessage.style.display = "none";
inputsToValidate.forEach(input => input.classList.remove("invalid"));
}
}
// Attach listeners
slider.addEventListener("input", updateFromSlider);
totalCertsInput.addEventListener("input", updateFromSlider);
totalCashbackInput.addEventListener("input", updateFromSlider);
[
certItemsNo,
certItemsCashback,
semiJackpotNo,
semiJackpotCashback,
jackpotNo,
jackpotCashback
].forEach(input => input.addEventListener("input", validateTotals));
updateFromSlider();
});
</script>
<!-- Select2 CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<!-- Select2 JS -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<script>
$(document).ready(function() {
function formatOption(option) {
if (!option.id) return option.text;
const icon = $(option.element).data('icon');
return $(`
<span>
<img src="${icon}" style="width: 32px; height: 32px; margin-right: 8px;" />
${option.text}
</span>
`);
}
$('#network').select2({
templateResult: formatOption,
templateSelection: formatOption,
minimumResultsForSearch: Infinity // hides the search box
});
});
</script>