Sonuçlar burada görünecek.
Başlamak için kullanım amacını seçin.
"']/g, function (character) {
return {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
}[character];
});
}
function unique(values) {
return values.filter(function (value, index, array) {
return array.indexOf(value) === index;
});
}
function formatNumber(value, maxDecimals) {
return new Intl.NumberFormat("tr-TR", {
maximumFractionDigits: maxDecimals,
minimumFractionDigits: 0
}).format(value);
}
function mmToInch(mm) {
return Math.round((mm / 25.4) / 0.05) * 0.05;
}
function tireDisplay(mm) {
return formatNumber(mm, 2) + " mm / " + formatNumber(mmToInch(mm), 2) + "\"";
}
function formatHoleOption(value) {
var text = String(value).trim().toUpperCase();
return /H$/.test(text) ? text : text + "H";
}
function fillSelect(select, values, placeholder, labels, order) {
var current = select.value;
var sorted = values.slice();
if (order) {
sorted.sort(function (a, b) { return order.indexOf(a) - order.indexOf(b); });
}
select.innerHTML = "";
if (sorted.length !== 1) {
var placeholderOption = document.createElement("option");
placeholderOption.value = "";
placeholderOption.textContent = placeholder;
select.appendChild(placeholderOption);
}
sorted.forEach(function (value) {
var option = document.createElement("option");
option.value = value;
option.textContent = labels[value] || value;
select.appendChild(option);
});
if (sorted.length === 1) {
select.value = sorted[0];
} else if (sorted.indexOf(current) !== -1) {
select.value = current;
} else {
select.value = "";
}
select.disabled = sorted.length <= 1;
select.setAttribute("data-locked", sorted.length === 1 ? "true" : "false");
return sorted.length;
}
function init(root) {
if (root.getAttribute("data-rjm-ready") === "true") return;
root.setAttribute("data-rjm-ready", "true");
var form = root.querySelector("[data-rjm-form]");
var resultsNode = root.querySelector("[data-results]");
var tireHint = root.querySelector("[data-tire-hint]");
var tireOutput = root.querySelector("[data-tire-output]");
var tireMinLabel = root.querySelector("[data-tire-min]");
var tireMaxLabel = root.querySelector("[data-tire-max]");
var sizeHelp = root.querySelector("[data-size-help]");
var brakeHelp = root.querySelector("[data-brake-help]");
var fields = {
use: root.querySelector('[data-field="use"]'),
size: root.querySelector('[data-field="size"]'),
brake: root.querySelector('[data-field="brake"]'),
tire: root.querySelector('[data-field="tire"]')
};
var sliderSignature = "";
function availableRims() {
return RIMS.slice();
}
function rimsForUse(use) {
return availableRims().filter(function (rim) {
return rim.uses.indexOf(use) !== -1;
});
}
function candidatesBeforeTire() {
if (!fields.use.value) return [];
return rimsForUse(fields.use.value).filter(function (rim) {
if (fields.size.value && rim.size !== fields.size.value) return false;
if (fields.brake.value && rim.brake !== fields.brake.value) return false;
return true;
});
}
function updateSliderVisual() {
if (fields.tire.disabled) return;
var value = Number(fields.tire.value);
var min = Number(fields.tire.min);
var max = Number(fields.tire.max);
var progress = max === min ? 100 : ((value - min) / (max - min)) * 100;
fields.tire.style.setProperty("--rjm-range-progress", Math.max(0, Math.min(100, progress)) + "%");
tireOutput.textContent = tireDisplay(value);
}
function compatibilityScore(rim, tireMm) {
var span = Math.max(1, rim.maxMm - rim.minMm);
var margin = Math.min(tireMm - rim.minMm, rim.maxMm - tireMm);
return margin / span;
}
function findResults(tireMm) {
return candidatesBeforeTire().filter(function (rim) {
return tireMm >= rim.minMm && tireMm <= rim.maxMm;
}).sort(function (a, b) {
if (a.active !== b.active) return a.active === false ? 1 : -1;
var scoreDifference = compatibilityScore(b, tireMm) - compatibilityScore(a, tireMm);
if (scoreDifference !== 0) return scoreDifference;
return (a.brand + " " + a.model).localeCompare(b.brand + " " + b.model, "tr");
});
}
function productCard(rim, tireMm) {
var holeKnown = Array.isArray(rim.holes) && rim.holes.length > 0;
var discontinued = rim.active === false;
var edgeMargin = Math.min(tireMm - rim.minMm, rim.maxMm - tireMm);
var edgeBadge = edgeMargin <= 1 ? 'Aralık sınırına yakın' : "";
var statusBadge = discontinued
? 'Üretimden kaldırıldı'
: "";
var holeBadge = holeKnown
? 'Jant deliği: ' + escapeHtml(rim.holes.map(formatHoleOption).join(", ")) + ""
: 'Jant deliği doğrulanmalı';
var holeText = holeKnown ? "" : " Kullanılacak göbekle jant deliği sayısını doğrulayın.";
var link = rim.url
? 'Ürünü görüntüle →'
: "";
return '' +
'' +
'' +
'
' + escapeHtml(rim.brand) + "
" +
'
' + escapeHtml(rim.model) + "
" +
'
' +
'' + escapeHtml(LABELS.materials[rim.material]) + "" +
'' + escapeHtml(LABELS.brakes[rim.brake]) + "" +
statusBadge + edgeBadge + holeBadge +
"
" +
"
" +
'' +
'
' +
'- Boyut
- ' + escapeHtml(LABELS.sizes[rim.size]) + "
" +
'- Lastik genişliği
- ' + escapeHtml(tireDisplay(rim.minMm)) + " – " + escapeHtml(tireDisplay(rim.maxMm)) + "
" +
'- İç genişlik
- ' + escapeHtml(formatNumber(rim.innerMm, 2)) + " mm
" +
'- Dış genişlik
- ' + escapeHtml(formatNumber(rim.outerMm, 2)) + " mm
" +
'- Profil yüksekliği
- ' + escapeHtml(formatNumber(rim.heightMm, 2)) + " mm
" +
'- Lastik sistemi
- ' + escapeHtml(LABELS.systems[rim.system]) + "
" +
"
" +
'
' + escapeHtml(tireDisplay(tireMm)) + " genişliğindeki lastik bu jantın veri aralığındadır." + escapeHtml(holeText) + "
" +
link +
"
" +
"";
}
function renderResults(rims, tireMm) {
if (rims.length === 0) {
resultsNode.innerHTML = '' +
'
' +
'Bu lastik genişliği için uyumlu jant bulunamadı.' +
'Aralık dışındaki ölçüleri kullanmayın. Lastik genişliğini değiştirin veya tekerlek boyutu ile fren sistemini yeniden kontrol edin.' +
"
";
return;
}
var unknownHoleCount = rims.filter(function (rim) { return !Array.isArray(rim.holes) || rim.holes.length === 0; }).length;
var holeNotice = unknownHoleCount > 0
? '
Jant deliği verileri eksik. ' + unknownHoleCount + " / " + rims.length + " sonuçta montajdan önce jant deliği sayısının doğrulanması gerekir.
"
: "";
var hooklessNotice = rims.some(function (rim) { return rim.system === "TR_HOOKLESS"; })
? '
Hookless için dikkat: Açıkça hookless uyumlu olduğu belirtilen lastikleri kullanın ve jant ile lastik üreticilerinin basınç sınırlarına uyun.
'
: "";
var discontinuedCount = rims.filter(function (rim) { return rim.active === false; }).length;
var discontinuedNotice = discontinuedCount > 0
? '
Üretimden kaldırılmış ürün durumu: ' + discontinuedCount + " sonuç artık aktif bir ürün değildir. Stok sınırlı olabilir; satın almadan önce ürün sayfasını kontrol edin veya bayiye danışın.
"
: "";
resultsNode.innerHTML = '' +
'
' +
'
Uyumlu jantlar
Slider hareket ettirildiğinde sonuçlar otomatik olarak güncellenir. Sıralama kaliteye veya fiyata göre değil, lastik genişliğinin aralık içindeki konumuna göredir.
' +
'
' + rims.length + " sonuç" +
"
" +
'
' + rims.map(function (rim) { return productCard(rim, tireMm); }).join("") + "
" +
holeNotice + hooklessNotice + discontinuedNotice;
}
function configureSlider() {
var candidates = candidatesBeforeTire();
var ready = fields.use.value && fields.size.value && fields.brake.value && candidates.length > 0;
if (!ready) {
fields.tire.disabled = true;
fields.tire.style.setProperty("--rjm-range-progress", "0%");
tireOutput.textContent = "—";
tireMinLabel.textContent = "—";
tireMaxLabel.textContent = "—";
tireHint.textContent = "Önce kullanımı, tekerlek boyutunu ve fren sistemini seçin.";
resultsNode.innerHTML = INITIAL_RESULT_HTML;
sliderSignature = "";
return;
}
var minMm = Math.min.apply(null, candidates.map(function (rim) { return rim.minMm; }));
var maxMm = Math.max.apply(null, candidates.map(function (rim) { return rim.maxMm; }));
var signature = fields.use.value + "|" + fields.size.value + "|" + fields.brake.value;
fields.tire.min = minMm;
fields.tire.max = maxMm;
fields.tire.step = "1";
fields.tire.disabled = false;
if (signature !== sliderSignature) {
var preferred = DEFAULT_TIRE_MM[fields.use.value] || Math.round((minMm + maxMm) / 2);
fields.tire.value = Math.max(minMm, Math.min(maxMm, preferred));
sliderSignature = signature;
} else {
fields.tire.value = Math.max(minMm, Math.min(maxMm, Number(fields.tire.value)));
}
tireMinLabel.textContent = tireDisplay(minMm);
tireMaxLabel.textContent = tireDisplay(maxMm);
tireHint.textContent = "Lastiğinizin üzerinde belirtilen genişliğe göre kaydırın.";
updateSliderVisual();
renderResults(findResults(Number(fields.tire.value)), Number(fields.tire.value));
}
function refreshDependencies() {
var selectedUse = fields.use.value;
if (!selectedUse) {
fillSelect(fields.size, [], "Önce kullanımı seçin", LABELS.sizes, SIZE_ORDER);
fillSelect(fields.brake, [], "Önce tekerlek boyutunu seçin", LABELS.brakes, ["DISC", "RIM"]);
sizeHelp.textContent = "ETRTO numarası, 20 inç boyutlarının ayırt edilmesine yardımcı olur.";
brakeHelp.textContent = "Disk fren ve jant freni birbirinin yerine kullanılamaz.";
configureSlider();
return;
}
var useRims = rimsForUse(selectedUse);
var sizeCount = fillSelect(
fields.size,
unique(useRims.map(function (rim) { return rim.size; })),
"Tekerlek boyutunu seçin",
LABELS.sizes,
SIZE_ORDER
);
sizeHelp.textContent = sizeCount === 1
? "Yalnızca bir boyut bulunduğu için otomatik olarak seçildi."
: "Bisikletinizde kullanılan tekerlek boyutunu seçin.";
if (!fields.size.value) {
fillSelect(fields.brake, [], "Önce tekerlek boyutunu seçin", LABELS.brakes, ["DISC", "RIM"]);
brakeHelp.textContent = "Önce tekerlek boyutunu seçin.";
configureSlider();
return;
}
var sizeRims = useRims.filter(function (rim) { return rim.size === fields.size.value; });
var brakeCount = fillSelect(
fields.brake,
unique(sizeRims.map(function (rim) { return rim.brake; })),
"Fren sistemini seçin",
LABELS.brakes,
["DISC", "RIM"]
);
brakeHelp.textContent = brakeCount === 1
? "Yalnızca bir fren sistemi bulunduğu için otomatik olarak seçildi."
: "Bisikletinizdeki fren sistemini seçin.";
configureSlider();
}
form.addEventListener("submit", function (event) { event.preventDefault(); });
fields.use.addEventListener("change", function () {
fields.size.value = "";
fields.brake.value = "";
sliderSignature = "";
refreshDependencies();
});
fields.size.addEventListener("change", function () {
fields.brake.value = "";
sliderSignature = "";
refreshDependencies();
});
fields.brake.addEventListener("change", function () {
sliderSignature = "";
refreshDependencies();
});
fields.tire.addEventListener("input", function () {
updateSliderVisual();
renderResults(findResults(Number(fields.tire.value)), Number(fields.tire.value));
});
refreshDependencies();
}
function initAll(scope) {
var base = scope || document;
if (base.matches && base.matches("[data-rjm-rim-selector]")) init(base);
base.querySelectorAll("[data-rjm-rim-selector]").forEach(init);
}
initAll(document);
document.addEventListener("shopify:section:load", function (event) { initAll(event.target); });
})();