"use strict";
function cleanVendorName(rawName){
let cleaned=rawName.trim().replace(/(\s*-?\s*(fr|com|eu|emea|-))$/i, "");
if(/DocMorris FR|DoctiPharma FR/i.test(cleaned)){
return { cleaned: "doc-morris", display: "Doc Morris" };}else if(/Place des Tendances/i.test(cleaned)){
return { cleaned: "placedestendances", display: "Place des Tendances" };}else if(/Puzzle\./i.test(cleaned)){
return { cleaned: "puzzlefr", display: "Puzzle.fr" };}else if(/Sonos/i.test(cleaned)){
return { cleaned: "sonos", display: "Sonos" };}else if(/iRobot/i.test(cleaned)){
return { cleaned: "irobot", display: "iRobot" };}
const accentMap={
"à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a",
"ç":"c",
"è":"e","é":"e","ê":"e","ë":"e",
"ì":"i","í":"i","î":"i","ï":"i",
"ñ":"n",
"ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o",
"ù":"u","ú":"u","û":"u","ü":"u",
"ý":"y","ÿ":"y",
"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A",
"Ç":"C",
"È":"E","É":"E","Ê":"E","Ë":"E",
"Ì":"I","Í":"I","Î":"I","Ï":"I",
"Ñ":"N",
"Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O",
"Ù":"U","Ú":"U","Û":"U","Ü":"U",
"Ý":"Y"
};
cleaned=cleaned.replace(/[^\u0000-\u007E]/g, ch=> accentMap[ch]||ch);
const finalCleaned=cleaned.toLowerCase().replace(/\s+/g, "");
return { cleaned: finalCleaned, display: rawName.trim() };}
function isManoVendorName(rawName){
const v=(rawName||"").toLowerCase();
return /mano\s*mano|manomano\.?fr?/i.test(v);
}
function normalizeItemName(name){
return (name||"")
.trim()
.toLowerCase()
.replace(/\s+/g, " ");
}
function getItemEAN(deal){
return (deal.ean||"").toString().trim();
}
function getPhoneKind(deal){
const name=(deal.article||"")
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "");
if(/iphone\b/.test(name)){
return "iphone";
}
if(name.includes("samsung")||name.includes("galaxy")){
return "samsung";
}
if(name.includes("pixel")||name.includes("google pixel")){
return "pixel";
}
return "other";
}
function isIphoneOrSamsungDeal(deal){
const kind=getPhoneKind(deal);
return kind==="iphone"||kind==="samsung"||kind==="pixel";
}
function sanitizePhoneTitle(raw){
let name=(raw||"")
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "");
name=name.replace(/\b\d+\s*(go|g|gb|mo|ko|to)\b/g, " ");
name=name.replace(/\b\d+(?:[\.,]\d+)?\s*(po|pouce|pouces|")\b/g, " ");
name=name.replace(/\b\d+\s*g\b/g, " ");
name=name.replace(/\s+/g, " ").trim();
return name;
}
function getSamsungGenerationInfo(deal){
const rawName=deal.article||"";
const name=sanitizePhoneTitle(rawName);
if(!name.includes("samsung")&&!name.includes("galaxy")) return null;
let m;
m=name.match(/z\s*fold\s*(\d{1,2})\b/);
if(m){
const n=parseInt(m[1], 10)||0;
return {
family: "z",
isZ: true,
rawGen: n,
generation: n + 18
};}
m=name.match(/z\s*flip\s*(\d{1,2})\b/);
if(m){
const n=parseInt(m[1], 10)||0;
return {
family: "z",
isZ: true,
rawGen: n,
generation: n + 18
};}
m=name.match(/galaxy\s*s\s*(\d{1,2})\b/);
if(!m) m=name.match(/\bs(\d{1,2})\b/);
if(m){
const n=parseInt(m[1], 10)||0;
return {
family: "s",
isZ: false,
rawGen: n,
generation: n
};}
m=name.match(/galaxy\s*a\s*(\d{1,2})\b/);
if(!m) m=name.match(/\ba(\d{1,2})\b/);
if(m){
const n=parseInt(m[1], 10)||0;
return {
family: "a",
isZ: false,
rawGen: n,
generation: n
};}
m=name.match(/note\s*(\d{1,2})\b/);
if(m){
const n=parseInt(m[1], 10)||0;
return {
family: "note",
isZ: false,
rawGen: n,
generation: n
};}
return null;
}
function getPhoneGenerationRank(deal){
const rawName=deal.article||"";
const name=sanitizePhoneTitle(rawName);
let score=0;
if(name.includes("iphone")){
let gen=0;
let m=name.match(/iphone\s+(\d{1,2})\b/);
if(!m){
m=name.match(/\b(\d{1,2})\s*iphone\b/);
}
if(m){
gen=parseInt(m[1], 10)||0;
}
if(/iphone\s*se/.test(name)){
if(/2022/.test(name)) gen=13;
else if(/2020/.test(name)) gen=11;
else if(!gen) gen=8;
}
score=300 + gen;
return score;
}
if(name.includes("pixel")){
let gen=0;
let m=name.match(/pixel\s+(\d{1,2})\b/);
if(!m){
m=name.match(/\b(\d{1,2})\s*pixel\b/);
}
if(m){
gen=parseInt(m[1], 10)||0;
}
if(/pixel\s+\d{1,2}\s*a\b/.test(name)||/\bpixel\s*a\d{1,2}\b/.test(name)){
gen=gen - 0.2;
}
score=200 + gen;
return score;
}
if(name.includes("samsung")||name.includes("galaxy")){
const info=getSamsungGenerationInfo(deal);
if(info&&info.generation > 0){
let familyWeight=1;
if(info.family==="z") familyWeight=3;
else if(info.family==="s") familyWeight=2;
else if(info.family==="note") familyWeight=1.5;
return 100 + info.generation * 10 + familyWeight;
}
return 100;
}
return score;
}
window.scrollKrousel=function(direction, blockId){
const block=document.getElementById(blockId);
if(!block) return;
const scrollAmount=300;
const currentScrollLeft=block.scrollLeft;
const maxScrollLeft=block.scrollWidth - block.clientWidth;
if(direction==="left"){
if(currentScrollLeft <=0){
block.scrollTo({ left: maxScrollLeft, behavior: "smooth" });
}else{
block.scrollBy({ left: -scrollAmount, behavior: "smooth" });
}}else{
if(currentScrollLeft >=maxScrollLeft - 5){
block.scrollTo({ left: 0, behavior: "smooth" });
}else{
block.scrollBy({ left: scrollAmount, behavior: "smooth" });
}}
};
function computeDealImgForPreload(item, iconKey){
let dealImg="https://blackfridayfrance.com/images_api/" + item.id + ".jpg";
const specialCase=["marionnaud","bhv","sephora","thenorthface","courir"];
if(specialCase.includes(iconKey)&&item.realpics_url){
dealImg=item.realpics_url;
}
return dealImg;
}
function preloadImages(items, iconResolver){
items.forEach(it=> {
const key=iconResolver ? iconResolver(it):"";
const url=computeDealImgForPreload(it, key);
if(!url) return;
const link=document.createElement("link");
link.rel="preload";
link.as="image";
link.href=url;
document.head.appendChild(link);
const img=new Image();
img.decoding="async";
img.loading="eager";
img.src=url;
});
}
function initRocketPromoBlock(config){
const container=document.getElementById(config.containerId);
if(!container){
return;
}
const realUrl=atob(config.keRl);
let iconsUrl=null;
if(config.iconsKeRl){
try {
iconsUrl=atob(config.iconsKeRl);
} catch (e){
console.warn("iconsKeRl: base64 decode failed", e);
}}
let isByBoutique=false;
try {
const u=new URL(realUrl, window.location.href);
isByBoutique =
u.searchParams.has("onlythisseller") ||
/seller-|cache_seller/i.test(u.pathname);
} catch (e){
isByBoutique=/onlythisseller=/.test(realUrl)||/seller-|cache_seller/i.test(realUrl);
}
const itemsPerPage=(config.design==="carroussel") ? 10:25;
const isMobile=window.matchMedia('(max-width: 768px)').matches;
const BOOST_COUNT=isMobile ? 2:5;
let boostedSoFar=0;
let dataMaster=[];
let currentIndex=0;
let carrouselItemCount=0;
if(config.design==="carroussel"){
container.style.overflowX="scroll";
container.style.display="flex";
container.style.scrollSnapType="x mandatory";
}
let weAreInApp=false;
try {
const qs=new URLSearchParams(window.location.search);
weAreInApp=qs.get("weareinapp")==="1";
} catch (e){
weAreInApp=false;
}
function buildSeeMoreUrl(){
const validCategoryTypes=["bff_tag", "real_tag"];
if(!validCategoryTypes.includes(config.type)){
return "https://blackfridayfrance.com/tous-les-deals/";
}
if(!config.syncId){
return "https://blackfridayfrance.com/tous-les-deals/";
}
let url=`https://blackfridayfrance.com/tous-les-deals/?category=${encodeURIComponent(config.syncId)}`;
if(weAreInApp){
url +="&weareinapp=1";
}
return url;
}
function fetchAndInitData(){
const ensureIcons=iconsUrl
? fetch(iconsUrl)
.then(r=> r.ok ? r.json():{})
.then(map=> {
if(map&&typeof map==="object"){
config.icons=map;
}})
.catch(()=> {})
: Promise.resolve();
ensureIcons.then(()=> {
fetch(realUrl)
.then(res=> res.json())
.then(data=> {
const SMARTPHONE_TAGS=["123", "21", "24", "157"];
function isSmartphoneTag(id){
if(id==null) return false;
return SMARTPHONE_TAGS.includes(String(id));
}
let favorSmartphoneTag=false;
const sortByPourcentageDesc=(a, b)=> {
const pa=parseInt(a.pourcentage, 10)||0;
const pb=parseInt(b.pourcentage, 10)||0;
return pb - pa;
};
const sortByRecencyThenPourcentageDesc=(a, b)=> {
const ga=getPhoneGenerationRank(a);
const gb=getPhoneGenerationRank(b);
if(ga!==gb){
return gb - ga;
}
const pa=parseInt(a.pourcentage, 10)||0;
const pb=parseInt(b.pourcentage, 10)||0;
return pb - pa;
};
function reorderSamsungWithZAlternation(list){
if(!list||!list.length) return list;
const NO_GEN_KEY=-1;
const genMap=new Map();
list.forEach(deal=> {
const info=getSamsungGenerationInfo(deal);
const key=(info&&info.generation) ? info.generation:NO_GEN_KEY;
const isZ=info&&info.isZ;
if(!genMap.has(key)){
genMap.set(key, { z: [], nonZ: [] });
}
const bucket=genMap.get(key);
(isZ ? bucket.z:bucket.nonZ).push(deal);
});
const gens=Array.from(genMap.keys()).sort((a, b)=> {
if(a===NO_GEN_KEY) return 1;
if(b===NO_GEN_KEY) return -1;
return b - a;
});
gens.forEach(g=> {
const bucket=genMap.get(g);
bucket.z.sort(sortByPourcentageDesc);
bucket.nonZ.sort(sortByPourcentageDesc);
});
const result=[];
gens.forEach(g=> {
const bucket=genMap.get(g);
let zi=0, ni=0;
while (zi < bucket.z.length||ni < bucket.nonZ.length){
if(zi < bucket.z.length) result.push(bucket.z[zi++]);
if(ni < bucket.nonZ.length) result.push(bucket.nonZ[ni++]);
}});
return result;
}
if(typeof config.syncId!=="undefined"&&config.syncId!==null){
favorSmartphoneTag=isSmartphoneTag(config.syncId);
}else{
try {
const u=new URL(realUrl, window.location.href);
const tagId =
u.searchParams.get("id_thema") ||
u.searchParams.get("tag_id") ||
u.searchParams.get("tag");
if(tagId&&isSmartphoneTag(tagId)){
favorSmartphoneTag=true;
}} catch (e){
}}
if(favorSmartphoneTag){
data=data.filter(deal=> {
const priceStr=(deal.new_price||"").toString().replace(",", ".");
const priceNum=parseFloat(priceStr);
if(Number.isNaN(priceNum)) return true;
return priceNum >=99;
});
const boostedIphone=[];
let   boostedSamsung=[];
const boostedPixel=[];
const normal=[];
const mano=[];
data.forEach(deal=> {
const isMano=isManoVendorName(deal.vendeur);
const kind=getPhoneKind(deal); // "iphone" / "samsung" / "pixel" / "other"
if(isMano){
mano.push(deal);
}else if(kind==="iphone"){
boostedIphone.push(deal);
}else if(kind==="samsung"){
const sInfo=getSamsungGenerationInfo(deal);
if(sInfo&&(sInfo.family==="s"||sInfo.family==="z"||sInfo.family==="note")){
boostedSamsung.push(deal);
}else{
normal.push(deal);
}}else if(kind==="pixel"){
boostedPixel.push(deal);
}else{
normal.push(deal);
}});
boostedIphone.sort(sortByRecencyThenPourcentageDesc);
boostedSamsung=reorderSamsungWithZAlternation(boostedSamsung);
boostedPixel.sort(sortByRecencyThenPourcentageDesc);
normal.sort(sortByPourcentageDesc);
mano.sort(sortByPourcentageDesc);
const buckets={
iphone:  boostedIphone,
samsung: boostedSamsung,
pixel:   boostedPixel
};
const topPourc=kind=>
buckets[kind].length
? (parseInt(buckets[kind][0].pourcentage, 10)||0)
: -Infinity;
let order=["iphone", "samsung", "pixel"];
order.sort((a, b)=> topPourc(b) - topPourc(a));
const idx={ iphone: 0, samsung: 0, pixel: 0 };
let remaining =
boostedIphone.length + boostedSamsung.length + boostedPixel.length;
const boostedMixed=[];
while (remaining > 0){
for (const kind of order){
const arr=buckets[kind];
const i=idx[kind];
if(i < arr.length){
boostedMixed.push(arr[i]);
idx[kind]=i + 1;
remaining--;
}}
}
data=[...boostedMixed, ...normal, ...mano];
}else{
const nonMano=[];
const mano=[];
data.forEach(deal=> {
if(isManoVendorName(deal.vendeur)){
mano.push(deal);
}else{
nonMano.push(deal);
}});
const vendorBuckets={};
nonMano.forEach(deal=> {
const vendorKey=cleanVendorName(deal.vendeur||"").cleaned||"_unknown_";
if(!vendorBuckets[vendorKey]){
vendorBuckets[vendorKey]=[];
}
vendorBuckets[vendorKey].push(deal);
});
Object.keys(vendorBuckets).forEach(key=> {
vendorBuckets[key].sort(sortByPourcentageDesc);
});
const vendorKeys=Object.keys(vendorBuckets);
vendorKeys.sort((a, b)=> {
const arrA=vendorBuckets[a];
const arrB=vendorBuckets[b];
const pa=arrA.length ? (parseInt(arrA[0].pourcentage, 10)||0):0;
const pb=arrB.length ? (parseInt(arrB[0].pourcentage, 10)||0):0;
return pb - pa;
});
const alternated=[];
const idxByVendor={};
let remaining=nonMano.length;
const nbVendors=vendorKeys.length;
let k=0;
while (remaining > 0&&nbVendors > 0){
const vendorKey=vendorKeys[k];
const bucket=vendorBuckets[vendorKey];
const i=idxByVendor[vendorKey]||0;
if(i < bucket.length){
alternated.push(bucket[i]);
idxByVendor[vendorKey]=i + 1;
remaining--;
}
k=(k + 1) % nbVendors;
}
mano.sort(sortByPourcentageDesc);
data=alternated.concat(mano);
}
const seenCombos=new Set();
const deduped=[];
for (const deal of data){
const eanKey=getItemEAN(deal);
const vendorKey=cleanVendorName(deal.vendeur||"").cleaned;
if(!eanKey&&!vendorKey){
deduped.push(deal);
continue;
}
const comboKey=`${eanKey}__${vendorKey}`;
if(seenCombos.has(comboKey)){
continue;
}
seenCombos.add(comboKey);
deduped.push(deal);
}
dataMaster=deduped;
loadItems();
})
.catch(err=> console.error("Erreur fetch JSON:", err));
});
}
function loadItems(){
const nextItems=dataMaster.slice(currentIndex, currentIndex + itemsPerPage);
if(nextItems.length===0){
stopScrollListeners();
return;
}
const itemsToShow=(window.innerWidth <=768)
? nextItems.filter(it=> !isManoVendorName(it.vendeur))
: nextItems;
if(config.design==="carroussel"){
const nextBatchStart=currentIndex + itemsPerPage;
const iconResolver=(it)=> cleanVendorName(it.vendeur||"").cleaned;
const toPreload=dataMaster.slice(nextBatchStart, nextBatchStart + (isMobile ? 2:4));
if(toPreload.length) preloadImages(toPreload, iconResolver);
itemsToShow.forEach((item)=> {
const li=document.createElement("li");
const newPrice=item.new_price;
const oldPrice=item.old_price;
const avantageFire=(newPrice!=oldPrice);
const reduction=item.economie;
const pourcentage=item.pourcentage;
const push2click=item.push2click;
const vendorNames=cleanVendorName(item.vendeur||"");
const iconKey=vendorNames.cleaned;
const displayVendor=vendorNames.display;
const finalIcon=config.icons[iconKey]||config.icons.default;
let dealImg="https://blackfridayfrance.com/images_api/" + item.id + ".jpg";
const specialCase=["marionnaud","bhv","sephora","thenorthface","courir","delonghi"];
if(specialCase.includes(iconKey)&&item.realpics_url){
dealImg=item.realpics_url;
}
let nameToShow=item.article;
let htmlCode=`<span class="kamesen" datasin="${item.url_encode}">`;
if(item.globalement!=1){
if(avantageFire){
htmlCode +=`<span class="pourcentcarroussel">-${pourcentage}</span>`;
}
const needBoost=boostedSoFar < BOOST_COUNT;
const imgAttrs=needBoost
? 'fetchpriority="high" loading="eager" decoding="async"'
: 'loading="lazy" decoding="async"';
if(needBoost) boostedSoFar++;
htmlCode +=`
<span class="bim_pix" style="display:block;position:relative;aspect-ratio:1/1;overflow:hidden;">
<svg class="img-ph" viewBox="0 0 24 24" width="44" height="44"
style="position:absolute;inset:0;margin:auto;opacity:.5;transform-origin:50% 50%;animation:spin 1.2s linear infinite">
<path d="M7 2h10a1 1 0 0 1 .9 1.45L15 8l2.9 4.55A1 1 0 0 1 17 14H7a1 1 0 0 1-.9-1.45L9 8 6.1 3.45A1 1 0 0 1 7 2Z" fill="currentColor"/>
<style>@keyframes spin{to{transform:rotate(360deg)}}</style>
</svg>
<img ${imgAttrs}
src="${dealImg}"
alt="${nameToShow}"
style="position:absolute;inset:0;width:100%;height:100%;object-fit:contain;opacity:0;transition:opacity .25s ease;margin:auto;"
onload="this.style.opacity=1; var ph=this.previousElementSibling; if(ph) ph.style.display='none';"
onerror="var ph=this.previousElementSibling; if(ph) ph.style.opacity=.3;">
</span>
`;
htmlCode +=`
<span class="bim_blokprod">
<span class="bim_name"><span>[${item.marque}]</span> ${nameToShow}</span>
<span class="bim_price">
<span class="patate">${newPrice} €</span>
`;
if(!avantageFire&&push2click){
htmlCode +=`<span class="bim_ko">${push2click}</span>`;
}
if(avantageFire){
htmlCode +=`
<strike>${oldPrice} €</strike>
</span>
<span class="bim_ko">${reduction}€ de réduction</span>
`;
}else{
htmlCode +=`</span>`;
}
htmlCode +=`
<span class="bim_marchand">
<img width="25" height="25" src="${finalIcon}" alt="icone" />
<span style="margin-left:3px;text-transform:capitalize;">${displayVendor}</span>
</span>
<span class="bim_cta">Voir l'offre <img src="https://blackfridayfrance.com/rivetoile/themes/vendredinoir/assets/external-link.svg" class="icon_2k25" alt="icone externallink"></span>
</span>
`;
}else{
const specialrules=(item.specialrules) ? " " + item.specialrules:"";
htmlCode +=`
<span class="econome3">${nameToShow}</span>
chez <strong>${displayVendor}</strong>${specialrules}
<span class="bim_cta">Ouvrir le site <img src="https://blackfridayfrance.com/rivetoile/themes/vendredinoir/assets/external-link.svg" class="icon_2k25" alt="icone externallink"></span>
`;
}
htmlCode +=`</span>`;
if((item.vendeur||"").toLowerCase().includes("amazon")){
htmlCode +=`<span class="amament">#Amazon #Rémunéré</span>`;
}
let owoSmartCss="";
const isEvenIndex=carrouselItemCount % 2===0;
const yatilaumoinsunepromo=item.yatilaumoinsunepromo||0;
const yatilcombiendarticle=item.yatilcombiendarticle||0;
if(isEvenIndex){
if(avantageFire||yatilaumoinsunepromo===0){
owoSmartCss="kmh ";
}
owoSmartCss +="samba";
}else{
if(avantageFire&&yatilaumoinsunepromo!==0&&yatilaumoinsunepromo!==yatilcombiendarticle){
owoSmartCss="kmh ";
}
owoSmartCss +="jonlok";
}
li.className=owoSmartCss;
li.innerHTML=htmlCode;
carrouselItemCount++;
container.appendChild(li);
if(!isByBoutique&&config.showMore&&config.syncId&&(carrouselItemCount===5||carrouselItemCount===15)){
const moreLi=document.createElement("li");
moreLi.className="see-more-item";
moreLi.innerHTML=`
<a href="${buildSeeMoreUrl()}" class="see-more-btn">
Affiner ma recherche dans le détecteur de deals
<img src="https://blackfridayfrance.com/rivetoile/themes/vendredinoir/assets/arrow-right.svg" class="icon_2k25" alt="icone fleche droite">
</a>
`;
li.insertAdjacentElement("afterend", moreLi);
}});
}else{
itemsToShow.forEach((item)=> {
const li=document.createElement("li");
const newPrice=item.new_price;
const oldPrice=item.old_price;
const avantageFire=(newPrice!=oldPrice);
const reduction=item.economie;
const pourcentage=item.pourcentage;
const push2click=item.push2click;
const vendorNames=cleanVendorName(item.vendeur||"");
const iconKey=vendorNames.cleaned;
const displayVendor=vendorNames.display;
const finalIcon=config.icons[iconKey]||config.icons.default;
let dealImg="https://blackfridayfrance.com/images_api/" + item.id + ".jpg";
const specialCase=["marionnaud","bhv","sephora","thenorthface","courir","delonghi"];
if(specialCase.includes(iconKey)&&item.realpics_url){
dealImg=item.realpics_url;
}
let nameToShow=item.article;
if(config.design!=="carroussel"){
if(nameToShow.length > 70){
nameToShow=nameToShow.substring(0,70) + "...";
}}
let htmlCode=`<span class="kamesen" datasin="${item.url_encode}">`;
if(item.globalement!=1){
if(avantageFire){
htmlCode +=`<span class="pourcentcarroussel">-${pourcentage}</span>`;
}
htmlCode +=`
<span class="bim_pix">
<img loading="lazy" src="${dealImg}" alt="${nameToShow}">
</span>
`;
htmlCode +=`
<span class="bim_blokprod">
<span class="bim_name"><span>[${item.marque}]</span> ${nameToShow}</span> à
<span class="bim_price">
<span class="patate">${newPrice} €</span>
`;
if(!avantageFire&&push2click){
htmlCode +=`<span class="bim_ko">${push2click}</span>`;
}
if(avantageFire){
htmlCode +=`
au lieu de <strike>${oldPrice} €</strike>
</span>
soit <span class="bim_ko">-${reduction}€</span> de réduction chez
`;
}else{
htmlCode +=`</span>`;
}
htmlCode +=`
<span class="bim_marchand">
<img width="25" height="25" src="${finalIcon}" alt="icone" />
<span style="margin-left:3px;text-transform:capitalize;">${displayVendor}</span>
</span>
`;
}else{
const specialrules=(item.specialrules) ? " " + item.specialrules:"";
htmlCode +=`
<span class="econome3">${nameToShow}</span>
chez <strong>${displayVendor}</strong>${specialrules}
<span class="bim_cta">Ouvrir le site <img src="https://blackfridayfrance.com/rivetoile/themes/vendredinoir/assets/external-link.svg" class="icon_2k25" alt="icone externallink"></span>
`;
}
htmlCode +=`</span>`;
if((item.vendeur||"").toLowerCase().includes("amazon")){
htmlCode +=`<span class="amament">#Amazon #Rémunéré</span>`;
}
let owoSmartCss="";
const isEvenIndex=carrouselItemCount % 2===0;
const yatilaumoinsunepromo=item.yatilaumoinsunepromo||0;
const yatilcombiendarticle=item.yatilcombiendarticle||0;
if(isEvenIndex){
if(avantageFire||yatilaumoinsunepromo===0){
owoSmartCss="kmh ";
}
owoSmartCss +="samba";
}else{
if(avantageFire&&yatilaumoinsunepromo!==0&&yatilaumoinsunepromo!==yatilcombiendarticle){
owoSmartCss="kmh ";
}
owoSmartCss +="jonlok";
}
li.className=owoSmartCss;
li.innerHTML=htmlCode;
carrouselItemCount++;
container.appendChild(li);
});
}
currentIndex +=itemsPerPage;
if(!isByBoutique&&config.showMore&&config.syncId&&currentIndex >=dataMaster.length){
const lastLi=container.querySelector("li:last-child");
if(lastLi){
const moreLi=document.createElement("li");
moreLi.className="see-more-item";
moreLi.innerHTML=`
<a href="${buildSeeMoreUrl()}" class="see-more-btn">
Affiner ma recherche dans le détecteur de deals
<img src="https://blackfridayfrance.com/rivetoile/themes/vendredinoir/assets/arrow-right.svg" class="icon_2k25" alt="icone fleche droite">
</a>
`;
lastLi.insertAdjacentElement("afterend", moreLi);
}}
if(currentIndex >=dataMaster.length){
stopScrollListeners();
}}
function handleVerticalScroll(){
if(window.innerHeight + window.scrollY >=document.body.offsetHeight - 200){
loadItems();
}}
function handleHorizontalScroll(){
const scrollLeft=container.scrollLeft;
const scrollWidth=container.scrollWidth;
const clientWidth=container.clientWidth;
if(scrollLeft + clientWidth >=scrollWidth - 10){
loadItems();
}}
function stopScrollListeners(){
if(config.design==="carroussel"){
container.removeEventListener("scroll", handleHorizontalScroll);
}else{
window.removeEventListener("scroll", handleVerticalScroll);
}}
if(config.design==="carroussel"){
container.addEventListener("scroll", handleHorizontalScroll);
}else{
window.addEventListener("scroll", handleVerticalScroll);
}
fetchAndInitData();
}
document.addEventListener("DOMContentLoaded", function(){
if(!window.rocketPromoFeedConfigs){
return;
}
window.rocketPromoFeedConfigs.forEach(function(cfg){
initRocketPromoBlock(cfg);
});
});
function handleKamesenClick(event){
const target=event.target.closest('.kamesen');
if(!target||!target.hasAttribute("datasin")) return;
const encodedUrl=target.getAttribute("datasin");
const url=decodeURIComponent(window.atob(encodedUrl));
if(event.ctrlKey){
const newWindow=window.open(url, '_blank');
if(newWindow) newWindow.focus();
event.preventDefault();
}else{
document.location.href=url;
}}
function handleKamesenContextMenu(event){
const target=event.target.closest('.kamesen');
if(!target||!target.hasAttribute("datasin")) return;
event.preventDefault();
const encodedUrl=target.getAttribute("datasin");
const url=decodeURIComponent(window.atob(encodedUrl));
window.open(url, '_blank');
}
function handleKamesenMiddleClick(event){
if(event.button===1){
const target=event.target.closest('.kamesen');
if(!target||!target.hasAttribute("datasin")) return;
event.preventDefault();
const encodedUrl=target.getAttribute("datasin");
const url=decodeURIComponent(window.atob(encodedUrl));
const newWindow=window.open(url, '_blank');
if(newWindow) newWindow.focus();
}}
document.addEventListener("DOMContentLoaded", function(){
if(window.disableSameInRocketPromo){
console.log("❌ Rocket Promo Feed Kamesen désactivé par un autre script.");
return;
}
window.disableSameInRocketPromo=true;
console.log("✅ Rocket Promo Feed activé.");
document.addEventListener("click", handleKamesenClick);
document.addEventListener("contextmenu", handleKamesenContextMenu);
document.addEventListener("mousedown", handleKamesenMiddleClick);
});