PageSourceSearch

https://www.veltra.com/_drive/veltra-fav.js?v=39

js veltra.com collected 2026-09-24 08:59:29 UTC 19,130 bytes, 67 lines download raw bytes

1/* veltra-fav.js — お気に入り ♡ トグルエンジン(uq3i F2)。保存モデルの正は worker src/favorites.ts と一致。*/
2(function(){
3  var NAME="vw_fav",MAX=100,MAXB=3500;
4  var LG=(function(){var l=(document.documentElement.lang||"en").toLowerCase();return (l.indexOf("zh-tw")===0||l.indexOf("zh-hant")===0)?"zh-tw":(l.indexOf("zh-cn")===0||l.indexOf("zh-hans")===0)?"zh-cn":l.indexOf("zh")===0?"zh-cn":l.indexOf("ja")===0?"ja":l.indexOf("ko")===0?"ko":"en";})();
5  var STR={en:{fav:"Favorites",savedTo:"Saved to {list}",removedFrom:"Removed from {list}",change:"Change",undo:"Undo",dismiss:"Dismiss",saveToList:"Save to a list",createList:"Create a list",cancel:"Cancel",save:"Save",create:"Create",listName:"List name",removeMore:" Remove some to add more.",cap:"You\u2019ve reached the 100-item limit.",bytesFull:"Your saved list is full.",folderCap:"You can create up to 10 folders.",nameLong:"Folder name is too long (max 20 characters).",nameDup:"A folder with that name already exists.",nameEmpty:"Enter a folder name."},ja:{fav:"お気に入り",savedTo:"{list} に保存しました",removedFrom:"{list} から削除しました",change:"変更",undo:"元に戻す",dismiss:"閉じる",saveToList:"リストに保存",createList:"新しいリストを作成",cancel:"キャンセル",save:"保存",create:"作成",listName:"リスト名",removeMore:" 追加するには一部を削除してください。",cap:"保存できるのは100件までです。",bytesFull:"保存リストがいっぱいです。",folderCap:"作成できるリストは10個までです。",nameLong:"リスト名が長すぎます(最大20文字)。",nameDup:"同じ名前のリストが既にあります。",nameEmpty:"リスト名を入力してください。"},"zh-cn":{fav:"收藏",savedTo:"已保存到 {list}",removedFrom:"已从 {list} 移除",change:"更改",undo:"撤销",dismiss:"关闭",saveToList:"保存到列表",createList:"新建列表",cancel:"取消",save:"保存",create:"创建",listName:"列表名称",removeMore:" 请删除部分项目后再添加。",cap:"最多只能保存100个项目。",bytesFull:"保存列表已满。",folderCap:"最多可创建10个列表。",nameLong:"列表名称过长(最多20个字符)。",nameDup:"已存在同名列表。",nameEmpty:"请输入列表名称。"},"zh-tw":{fav:"收藏",savedTo:"已儲存至 {list}",removedFrom:"已從 {list} 移除",change:"變更",undo:"復原",dismiss:"關閉",saveToList:"儲存至清單",createList:"新增清單",cancel:"取消",save:"儲存",create:"建立",listName:"清單名稱",removeMore:" 請刪除部分項目後再新增。",cap:"最多只能儲存100個項目。",bytesFull:"儲存清單已滿。",folderCap:"最多可建立10個清單。",nameLong:"清單名稱過長(最多20個字元)。",nameDup:"已存在同名清單。",nameEmpty:"請輸入清單名稱。"},ko:{fav:"즐겨찾기",savedTo:"{list}에 저장됨",removedFrom:"{list}에서 삭제됨",change:"변경",undo:"실행 취소",dismiss:"닫기",saveToList:"목록에 저장",createList:"새 목록 만들기",cancel:"취소",save:"저장",create:"만들기",listName:"목록 이름",removeMore:" 추가하려면 일부를 삭제하세요.",cap:"최대 100개까지 저장할 수 있습니다.",bytesFull:"저장 목록이 가득 찼습니다.",folderCap:"최대 10개의 목록을 만들 수 있습니다.",nameLong:"목록 이름이 너무 깁니다(최대 20자).",nameDup:"같은 이름의 목록이 이미 있습니다.",nameEmpty:"목록 이름을 입력하세요."}};
6  function T(k){var m=STR[LG]||STR.en;return (k in m)?m[k]:STR.en[k];}
7  function favName(n){return n==="Favorites"?T("fav"):n;}
8  function read(){try{var m=document.cookie.match(/(?:^|;\s*)vw_fav=([^;]+)/);if(!m)return{v:1,d:[],f:[]};var s=JSON.parse(decodeURIComponent(m[1]));if(!s||typeof s!=="object")return{v:1,d:[],f:[]};return{v:1,d:(s.d||[]).map(String),f:(s.f||[]).map(function(f){return{n:String(f&&f.n||""),i:(f&&f.i||[]).map(String)};}),l:(typeof s.l==="string"?s.l:null)};}catch(e){return{v:1,d:[],f:[]};}}
9  function enc(s){var o={v:1,d:s.d,f:s.f};if(s.l)o.l=s.l;return encodeURIComponent(JSON.stringify(o));}
10  function write(s){var v=enc(s);document.cookie=NAME+"="+v+";path=/;max-age=31536000;samesite=lax";}
11  function norm(x){var m=String(x==null?"":x).trim().match(/^(?:VELTRA-
11)?0*([0-9]+)$/i);return m?m[1]:String(x==null?"":x).trim();}
12  function ids(s){var a=s.d.slice();s.f.forEach(function(f){f.i.forEach(function(x){a.push(x);});});return a;}
13  function has(s,id){id=norm(id);return ids(s).indexOf(id)>=0;}
14  function count(s){return ids(s).length;}
15  function lastF(s){return s.l&&s.f.some(function(f){return f.n===s.l;})?s.l:null;}
16  function add(s,id){id=norm(id);if(!id||has(s,id))return{ok:false,r:"exists"};if(count(s)>=MAX)return{ok:false,r:"cap"};var t=lastF(s);var n=t?{v:1,d:s.d,f:s.f.map(function(fo){return fo.n===t?{n:fo.n,i:[id].concat(fo.i)}:fo;}),l:s.l}:{v:1,d:[id].concat(s.d),f:s.f,l:s.l};if(enc(n).length>MAXB)return{ok:false,r:"bytes"};return{ok:true,s:n};}
17  function rm(s,id){id=norm(id);var n={v:1,d:s.d.filter(function(x){return x!==id;}),f:s.f.map(function(f){return{n:f.n,i:f.i.filter(function(x){return x!==id;})};}),l:s.l};return{ok:true,s:n};}
18  function mkFolder(s,name){name=String(name||"").trim();if(!name)return{ok:false,r:"name_empty"};if(name.length>20)return{ok:false,r:"name_too_long"};if(s.f.length>=10)return{ok:false,r:"at_folder_capacity"};if(s.f.some(function(f){return f.n===name;}))return{ok:false,r:"name_duplicate"};var n={v:1,d:s.d,f:s.f.concat([{n:name,i:[]}]),l:s.l};if(enc(n).length>MAXB)return{ok:false,r:"bytes"};return{ok:true,s:n};}
19  function reFolder(s,o,nw){nw=String(nw||"").trim();if(!nw)return{ok:false,r:"name_empty"};if(nw.length>20)return{ok:false,r:"name_too_long"};var idx=-1;for(var i=0;i<s.f.length;i++){if(s.f[i].n===o){idx=i;break;}}if(idx<0)return{ok:false,r:"folder_not_found"};if(nw!==o&&s.f.some(function(f){return f.n===nw;}))return{ok:false,r:"name_duplicate"};var f2=s.f.map(function(f,i){return i===idx?{n:nw,i:f.i}:f;});return{ok:true,s:{v:1,d:s.d,f:f2,l:(s.l===o?nw:s.l)}};}
20  function delFolder(s,name){var idx=-1;for(var i=0;i<s.f.length;i++){if(s.f[i].n===name){idx=i;break;}}if(idx<0)return{ok:false,r:"folder_not_found"};var f2=s.f.slice();f2.splice(idx,1);return{ok:true,s:{v:1,d:s.d,f:f2,l:(s.l===name?null:s.l)}};}
21  function move(s,id,target){id=norm(id);if(!has(s,id))return{ok:false,r:"not_found"};if(target!=null&&!s.f.some(function(f){return f.n===target;}))return{ok:false,r:"folder_not_found"};var d=s.d.filter(function(x){return x!==id;});var f=s.f.map(function(fo){return{n:fo.n,i:fo.i.filter(function(x){return x!==id;})};});if(target==null)d=[id].concat(d);else f=f.map(function(fo){return fo.n===target?{n:fo.n,i:[id].concat(fo.i)}:fo;});return{ok:true,s:{v:1,d:d,f:f,l:target}};}
22  function reasonMsg(r){return r==="cap"?T("cap"):r==="bytes"?T("bytesFull"):r==="at_folder_capacity"?T("folderCap"):r==="name_too_long"?T("nameLong"):r==="name_duplicate"?T("nameDup"):r==="name_empty"?T("nameEmpty"):"";}
23  function paint(){var s=read();var arr=ids(s).filter(function(x){return /^[0-9]+$/.test(x);});
24    var st=document.getElementById("vwfav");if(!st){st=document.createElement("style");st.id="vwfav";(document.head||document.documentElement).appendChild(st);}
25    st.textContent=arr.length?arr.map(function(id){return '.fav[data-fav-id="'+id+'"] .ic';}).join(",")+"{fill:currentColor}":"";
26    var btns=document.querySelectorAll(".fav[data-fav-id]");for(var i=0;i<btns.length;i++){var on=arr.indexOf(norm(btns[i].getAttribute("data-fav-id")))>=0;btns[i].setAttribute("aria-pressed",on?"true":"false");}}
27  function fire(){try{document.dispatchEvent(new CustomEvent("vwfav:change",{detail:{count:count(read())}}));}catch(e){}}
28  function tbottom(){var cb=document.getElementById("vw-consent-banner");return cb&&cb.offsetHeight?(cb.offsetHeight+16)+"px":"24px";}
29  function toast(msg){var t=document.getElementById("vwfav-toast");if(!t){t=document.createElement("div");t.id="vwfav-toast";t.setAttribute("role","status");t.style.cssText="position:fixed;left:50%;bottom:"+tbottom()+";transform:translateX(-50%);background:#2D1C21;color:#fff;padding:10px 16px;border-radius:10px;font:600 14px/1.3 system-ui,sans-serif;z-index:200000;box-shadow:0 4px 18px rgba(0,0,0,.25);max-width:90vw;text-align:center";document.body.appendChild(t);}t.textContent=msg;t.style.opacity="1";clearTimeout(t.__h);t.__h=setTimeout(function(){t.style.opacity="0";},2600);}
30  function badgeCss(){if(document.getElementById("vwfav-bcss"))return;var st=document.createElement("style");st.id="vwfav-bcss";st.textContent=".vwh-fav{position:relative}.vwh-fav-badge{position:absolute;top:-2px;right:-2px;min-width:16px;height:16px;padding:0 4px;box-sizing:border-box;border-radius:999px;background:#2D1C21;color:#fff;font:700 10px/16px system-ui,sans-serif;text-align:center;pointer-events:none}";(document.head||document.documentElement).appendChild(st);}
31  function augmentHeader(){var link=document.querySelector("a.vwh-tbtn[data-vw-fav]")||document.querySelector('a.vwh-tbtn[aria-label="Wishlist"]');if(!link)return false;link.setAttribute("href","/"+((location.pathname||"").match(/^\/([a-z]{2}(?:-[a-z]+)?)(?:\/|$)/)||[0,"en"])[1]+"/favorites");link.classList.add("vwh-fav");var badge=link.querySelector(".vwh-fav-badge");if(!badge){badge=document.createElement("span");badge.className="vwh-fav-badge";link.appendChild(badge);}var n=count(read());if(n>0){badge.textContent=n>99?"99+":String(n);badge.style.display="";}else{badge.style.display="none";}return true;}
32  function ensureHeader(){badgeCss();if(augmentHeader())return;var mo=new MutationObserver(function(){if(augmentHeader())mo.disconnect();});mo.observe(document.body||document.documentElement,{childList:true,subtree:true});setTimeout(function(){mo.disconnect();},8000);}
33  document.addEventListener("click",function(e){var b=e.target.closest&&e.target.closest(".fav[data-fav-id]");if(!b)return;e.preventDefault();e.stopPropagation();var id=b.getAttribute("data-fav-id");var s=read();var was=has(s,id);if(was){var beforeVal=enc(s);var pl=listOf(id);
33var r=rm(s,id);write(r.s);paint();augmentHeader();fire();removeToast(beforeVal,pl);}else{var r2=add(s,id);if(!r2.ok){toast(reasonMsg(r2.r)+(r2.r==="cap"||r2.r==="bytes"?T("removeMore"):""));return;}write(r2.s);paint();augmentHeader();fire();saveToast(id);}});
34  function watchNewCards(){var mo=new MutationObserver(function(muts){for(var i=0;i<muts.length;i++){for(var j=0;j<muts[i].addedNodes.length;j++){var nd=muts[i].addedNodes[j];if(nd.nodeType===1&&((nd.matches&&nd.matches(".fav[data-fav-id]"))||(nd.querySelector&&nd.querySelector(".fav[data-fav-id]")))){paint();return;}}}});mo.observe(document.body||document.documentElement,{childList:true,subtree:true});}
35  function closePicker(){var m=document.getElementById("vwfav-picker");if(m)m.remove();}
36  function curList(id){id=norm(id);var s=read();for(var i=0;i<s.f.length;i++){if(s.f[i].i.indexOf(id)>=0)return s.f[i].n;}return "";}
37  function openListPicker(id){closePicker();var s=read();var sel=curList(id);
38    var wrap=document.createElement("div");wrap.id="vwfav-picker";wrap.style.cssText="position:fixed;inset:0;z-index:200001;background:rgba(0,0,0,.4);display:flex;align-items:flex-end;justify-content:center";
39    var box=document.createElement("div");box.style.cssText="background:#fff;width:100%;max-width:420px;border-radius:16px 16px 0 0;padding:18px 18px 22px;font:400 14px/1.4 system-ui,sans-serif;color:#2D1C21;max-height:76vh;overflow:auto";
40    function rowHtml(name,val){var on=val===sel;return '<button class="vwfav-lrow" data-list="'+val.replace(/"/g,"&quot;")+'" role="radio" aria-checked="'+(on?"true":"false")+'" style="display:flex;width:100%;align-items:center;gap:10px;padding:12px;border:1px solid '+(on?"#5B86A8":"#ece5d8")+';border-radius:10px;background:'+(on?"#eef3f7":"#fff")+';margin-bottom:8px;
40cursor:pointer;font:600 14px system-ui;color:#2D1C21;text-align:left"><span class="vwfav-dot" style="width:16px">'+(on?"\u25c9":"\u25cb")+'</span><span>'+name.replace(/</g,"&lt;")+'</span></button>';}
41    var rows=rowHtml(T("fav"),"")+s.f.map(function(f){return rowHtml(f.n,f.n);}).join("");
42    box.innerHTML='<div style="font:700 16px/1.3 system-ui;margin-bottom:12px">'+T("saveToList")+'</div>'+rows+'<button id="vwfav-createlist" style="display:flex;width:100%;align-items:center;gap:8px;padding:12px;border:1px dashed #E6E0D3;border-radius:10px;background:#fff;margin:2px 0 14px;cursor:pointer;font:600 14px system-ui;color:#5B86A8;text-align:left"><span style="font-size:18px;line-height:1">+</span>'+T("createList")+'</button><div style="display:flex;gap:10px"><button id="vwfav-pclose" style="flex:1;padding:12px;border:1px solid #ece5d8;border-radius:10px;background:#fff;font:600 14px system-ui;cursor:pointer">'+T("cancel")+'</button><button id="vwfav-psave" style="flex:1;padding:12px;border:0;border-radius:10px;background:#5B86A8;color:#fff;font:700 14px system-ui;cursor:pointer">'+T("save")+'</button></div>';
43    wrap.appendChild(box);document.body.appendChild(wrap);
44    wrap.addEventListener("click",function(ev){if(ev.target===wrap){closePicker();return;}
45      var row=ev.target.closest&&ev.target.closest(".vwfav-lrow");if(row){sel=row.getAttribute("data-list");[].slice.call(box.querySelectorAll(".vwfav-lrow")).forEach(function(r){var on=r.getAttribute("data-list")===sel;r.style.borderColor=on?"#5B86A8":"#ece5d8";r.style.background=on?"#eef3f7":"#fff";r.setAttribute("aria-checked",on?"true":"false");var d=r.querySelector(".vwfav-dot");if(d)d.textContent=on?"\u25c9":"\u25cb";});return;}
46      if(ev.target.closest&&ev.target.closest("#vwfav-createlist")){openCreateList(id);return;}
47      if(ev.target.closest&&ev.target.closest("#vwfav-pclose")){closePicker();return;}
48      if(ev.target.closest&&ev.target.closest("#vwfav-psave")){var r=move(read(),id,sel||null);if(r.ok){write(r.s);paint();augmentHeader();fire();}closePicker();return;}});}
49  function openCreateList(id){closePicker();var wrap=document.createElement("div");wrap.id="vwfav-picker";wrap.style.cssText="position:fixed;inset:0;z-index:200001;background:rgba(0,0,0,.4);display:flex;align-items:center;justify-content:center;padding:18px";
50    var box=document.createElement("div");box.style.cssText="background:#fff;width:100%;max-width:360px;border-radius:14px;padding:18px;font:400 14px/1.4 system-ui,sans-serif;color:#2D1C21";
51    box.innerHTML='<div style="font:700 16px/1.3 system-ui;margin-bottom:12px">'+T("createList")+'</div><input id="vwfav-newf" maxlength="20" placeholder="'+T("listName")+'" style="width:100%;box-sizing:border-box;padding:11px 12px;border:1px solid #ece5d8;border-radius:10px;font:400 14px system-ui;margin-bottom:14px"><div style="display:flex;gap:10px"><button id="vwfav-ccancel" style="flex:1;padding:11px;border:1px solid #ece5d8;border-radius:10px;background:#fff;font:600 14px system-ui;cursor:pointer">'+T("cancel")+'</button><button id="vwfav-ccreate" style="flex:1;padding:11px;border:0;border-radius:10px;background:#5B86A8;color:#fff;font:700 14px system-ui;cursor:pointer">'+T("create")+'</button></div>';
52    wrap.appendChild(box);document.body.appendChild(wrap);var inp=box.querySelector("#vwfav-newf");
52if(inp)inp.focus();
53    wrap.addEventListener("click",function(ev){if(ev.target===wrap||(ev.target.closest&&ev.target.closest("#vwfav-ccancel"))){openListPicker(id);return;}if(ev.target.closest&&ev.target.closest("#vwfav-ccreate")){var nm=inp?inp.value:"";var cr=mkFolder(read(),nm);if(!cr.ok){toast(reasonMsg(cr.r));return;}write(cr.s);var mv=move(read(),id,String(nm).trim());if(mv.ok)write(mv.s);paint();augmentHeader();fire();closePicker();}});}
54  function openFolderPicker(id){openListPicker(id);}
55  function listOf(id){id=norm(id);var s=read();for(var i=0;i<s.f.length;i++){if(s.f[i].i.indexOf(id)>=0)return s.f[i].n;}return "Favorites";}
56  function barCss(){return "position:fixed;left:50%;bottom:"+tbottom()+";transform:translateX(-50%);background:#2D1C21;color:#fff;padding:10px 14px;border-radius:12px;font:600 14px/1.3 system-ui,sans-serif;z-index:200000;box-shadow:0 4px 18px rgba(0,0,0,.25);display:flex;align-items:center;gap:14px;max-width:92vw";}
57  function linkBtn(label){var b=document.createElement("button");b.textContent=label;b.style.cssText="border:0;background:transparent;color:#fff;text-decoration:underline;text-underline-offset:2px;font:700 14px system-ui;cursor:pointer;padding:0;flex:none";return b;}
58  function removeToastEl(){var t=document.getElementById("vwfav-toast");if(t){if(t.__cleanup)t.__cleanup();t.remove();}}
59  function armDismiss(t){var fired=false;function fade(){t.style.transition="opacity .3s";t.style.opacity="0";setTimeout(function(){if(t.parentNode)t.remove();},320);}function onI(){if(fired)return;fired=true;clearTimeout(t.__cap);t.__soft=setTimeout(fade,3000);clean();}function clean(){window.removeEventListener("scroll",onI);window.removeEventListener("pointerdown",onI);window.removeEventListener("keydown",onI);}t.__cleanup=function(){clean();clearTimeout(t.__cap);clearTimeout(t.__soft);};window.addEventListener("scroll",onI,{passive:true});window.addEventListener("pointerdown",onI);window.addEventListener("keydown",onI);t.__cap=setTimeout(fade,12000);}
60  function bar(spanText,actionLabel,onAction){removeToastEl();var t=document.createElement("div");t.id="vwfav-toast";t.setAttribute("role","status");t.style.cssText=barCss();var sp=document.createElement("span");sp.textContent=spanText;t.appendChild(sp);if(actionLabel){var a=linkBtn(actionLabel);a.onclick=onAction;t.appendChild(a);}var x=linkBtn("\u00d7");x.setAttribute("aria-label",T("dismiss"));x.style.color="#fff";x.style.textDecoration="none";x.onclick=removeToastEl;t.appendChild(x);document.body.appendChild(t);armDismiss(t);return t;}
61  function saveToast(id){bar(T("savedTo").replace("{list}",favName(listOf(id))),T("change"),function(){removeToastEl();openListPicker(id);});}
62  function removeToast(beforeVal,listName){bar(T("removedFrom").replace("{list}",favName(listName)),T("undo"),function(){document.cookie="vw_fav="+beforeVal+";path=/;max-age=31536000;samesite=lax";paint();augmentHeader();fire();removeToastEl();});}
63  window.__vwfav={count:function(){return count(read());},folders:function(){return read().f.map(function(f){return f.n;});},openFolderPicker:openFolderPicker,createFolder:function(n){var r=mkFolder(read(),n);if(r.ok){write(r.s);paint();augmentHeader();fire();}else toast(reasonMsg(r.r));return r;},rename:function(o,n){var r=reFolder(read(),o,n);if(r.ok){write(r.s);paint();fire();}else toast(reasonMsg(r.r));return r;},del:function(n){var r=delFolder(read(),n);if(r.ok){write(r.s);paint();augmentHeader();fire();}return r;},move:function(id,t){var r=move(read(),id,t);if(r.ok){write(r.s);paint();augmentHeader();fire();}return r;}};
64  function init(){ensureHeader();paint();augmentHeader();watchNewCards();}
65  if(document.readyState!=="loading")init();else document.addEventListener("DOMContentLoaded",init);
66  document.addEventListener("vwfav:change",augmentHeader);
67})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.