Advertisement
Guest User

Untitled

a guest
Jan 4th, 2025
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.20 KB | None | 0 0
  1. {"WILDBERRIES.ru-s":{"link":"^(global\\.)?wildberries\\.ru/(?:catalog/|product/[-\\w]+-)(\\d+)(?:/(detail\\.aspx|feedbacks)(\\S+)?)?","url":"data:,$&","res":":\n// debugger;\nlet show_videos = true;\nlet show_reviews_sidebar = true;\n\nlet asyncMode = false;\nlet hasVideo = false;\nvar r = [];\nvar that = this;\n\n// show images only for global.wildberries.ru\nif ($[1]) {\n show_videos = false;\n asyncMode = true;\n}\n\nconst x = new XMLHttpRequest();\nconst cardInfoUrl = constructHostV2($[2], 'nm') + `/info/ru/card.json`;\nx.open('GET', cardInfoUrl, asyncMode);\nx.onloadend = function () {\n const info = JSON.parse(this.responseText);\n\n // fetch item photos\n // skip when triggered by feedback links or elements\n if (($[2] || $[3] == 'detail.aspx') && !$[4]?.includes('#Comments')\n && !that.TRG.className?.includes('product-review')\n && !that.TRG.className?.includes('product-product-review__rating')\n && !that.TRG.className?.includes('product-review__count-review'))\n {\n // const folder = 1e4 * Math.floor(info.nm_id / 1e4);\n if (info.media.has_video && show_videos) {\n // r.push([`https://video.wbstatic.net/video/new/${folder}/${info.nm_id}.mp4`, info.imt_name]);\n r.push(['', `<imagus-extension type=\"videojs\" url=\"${urlVideoProduct(info.nm_id, \"hls\", \"1440p\")}\"></imagus-extension>${info.imt_name}`]);\n hasVideo = true;\n }\n\n for (var i = 1; i <= info.media.photo_count; i++) {\n r.push([imageUrl(info.nm_id, 'big', i), info.imt_name]);\n }\n }\n\n const x2 = new XMLHttpRequest();\n\n // fetch feedback photos page by page\n x2.open('GET', `${feedbackDomain(info.imt_id)}/feedbacks/v1/${info.imt_id}`, asyncMode);\n x2.onloadend = function () {\n const resp = JSON.parse(this.responseText);\n\n // put current item's feedbacks first\n resp.feedbacks?.sort((a, b) => {\n return a.nmId === info.nm_id && b.nmId !== info.nm_id ? -1 :\n a.nmId !== info.nm_id && b.nmId === info.nm_id ? 1 :\n new Date(b.createdDate) - new Date(a.createdDate);\n });\n\n let fbTexts = [];\n resp.feedbacks?.forEach(f => {\n let text = [\n '&#11088;' + f.productValuation,\n f.nmId !== info.nm_id ? `ДРУГОЙ ВАРИАНТ` : '',\n f.pros ? '&#128077;&#127995; ' + f.pros : '',\n f.cons ? '&#128078;&#127995; ' + f.cons : '',\n f.text,\n f.createdDate.substring(0, 10),\n ].filter(Boolean).join(' | ');\n f.photo?.forEach(p => r.push([urlFeedbackPhoto(p), text]))\n\n if (f.text && fbTexts.length < 100) fbTexts.push(text);\n\n if (show_videos && f.video) {\n hasVideo = true;\n let [idx, id] = f.video.id.split('/');\n let vUrl = `https://videofeedback${String(idx).padStart(2, '0')}.wbbasket.ru/${id}/index.m3u8`;\n r.push(['', `<imagus-extension type=\"videojs\" url=\"${vUrl}\"></imagus-extension>${text}`]);\n }\n });\n\n if (r.length && !asyncMode && show_reviews_sidebar) {\n const fbIndx = r[0][1].startsWith('<imagus-extension') ? 1 : 0;\n const distr = resp.valuationDistributionPercent;\n const distrKeys = Object.keys(distr).reverse();\n r[fbIndx][1] =\n `<imagus-extension type=\"sidebar\"><div>\n <style>\n #imagus-extension > div { display: flex; flex-direction: column; row-gap: 10px; padding-top: 6px; }\n #imagus-extension .valuation-distr { display: flex; }\n #imagus-extension .valuation-distr > * { padding: 4px 6px; border: 1px solid gray; margin: 0 -1px 0 0; text-align: right; }\n #imagus-extension p { border-bottom: 1px solid #80808080; padding-bottom: 6px; }\n </style>\n <div class=\"valuation\">Оценка: &#11088; ${resp.valuation} &bull; ${resp.feedbackCount}</div>\n <div class=\"valuation-distr\">\n <span>${distrKeys.map(k => `${k}&nbsp;&#11088;`).join('<br>')}</span>\n <span>${distrKeys.map(k => `${distr[k]}%`).join('<br>')}</span>\n <span>${distrKeys.map(k => `<progress max=\"100\" value=\"${distr[k]}\">${distr[k]}%</progress>`).join('<br>')}</span>\n </div>\n ${fbTexts.map(t => `<p>${t}</p>`).join('')}\n </div></imagus-extension>${r[fbIndx][1]}`;\n }\n\n if (r.length == 0) {\n r = false;\n\n } else if (!asyncMode) {\n that.TRG.IMGS_ext_data = r;\n r = { loop: 'imagus://extension' };\n if (!that.TRG.IMGS_c_resolved?.URL) {\n that.TRG.IMGS_c_resolved = { URL: that.TRG.href };\n }\n\n } else if (asyncMode && (that.TRG?.IMGS_ext_data?.length || r?.length)) {\n that.TRG.IMGS_album = $[0];\n that.stack[$[0]] = that.TRG?.IMGS_ext_data || r;\n that.stack[$[0]].unshift(1);\n that.album(0);\n }\n }\n x2.send();\n}\nx.send();\n\nif (asyncMode) {\n return null\n}\n\nreturn r;\n\nfunction urlFeedbackPhoto(e) {\n const n = parseInt(e, 10);\n return `${constructHostV2(n, \"feedbackPhoto\")}/photos/fs.webp`\n}\n\nfunction feedbackDomain(t) {\n const e = crc16Arc(t) % 100 >= 50 ? \"2\" : \"1\";\n return `https://feedbacks${e}.wb.ru`;\n}\n\nfunction imageUrl(id, size, number) {\n var i = parseInt(id, 10);\n var ext = \"webp\";\n var url = constructHostV2(i);\n return \"\".concat(url, \"/images/\").concat(size, \"/\").concat(null != number ? number : 1, \".\").concat(ext)\n}\n\nfunction volHostV2(e) {\n const t = ~~(e / 1e5);\n let r;\n switch (!0) {\n case t >= 0 && t <= 143: r = \"01\"; break;\n case t <= 287: r = \"02\"; break;\n case t <= 431: r = \"03\"; break;\n case t <= 719: r = \"04\"; break;\n case t <= 1007: r = \"05\"; break;\n case t <= 1061: r = \"06\"; break;\n case t <= 1115: r = \"07\"; break;\n case t <= 1169: r = \"08\"; break;\n case t <= 1313: r = \"09\"; break;\n case t <= 1601: r = \"10\"; break;\n case t <= 1655: r = \"11\"; break;\n case t <= 1919: r = \"12\"; break;\n case t <= 2045: r = \"13\"; break;\n case t <= 2189: r = \"14\"; break;\n case t <= 2405: r = \"15\"; break;\n case t <= 2621: r = \"16\"; break;\n case t <= 2837: r = \"17\"; break;\n case t <= 3053: r = \"18\"; break;\n case t <= 3269: r = \"19\"; break;\n case t <= 3485: r = \"20\"; break;\n default: r = \"21\"\n }\n return `basket-${r}.wbbasket.ru/vol${t}`\n}\n\nfunction volFeedbackPhotoHost(e) {\n const t = ~~(e / 1e5);\n let r;\n switch (!0) {\n case t >= 0 && t <= 431: r = \"01\"; break;\n case t <= 863: r = \"02\"; break;\n case t <= 1199: r = \"03\"; break;\n case t <= 1535: r = \"04\"; break;\n case t <= 1919: r = \"05\"; break;\n case t <= 2303: r = \"06\"; break;\n case t <= 2688: r = \"07\"; break;\n default: r = \"08\"\n }\n return `feedback${r}.wbbasket.ru/vol${t}`\n}\n\nfunction volVideoHost(e) {\n const t = e % 144;\n let r;\n switch (!0) {\n case t >= 0 && t <= 11: r = \"01\"; break;\n case t <= 23: r = \"02\"; break;\n case t <= 35: r = \"03\"; break;\n case t <= 47: r = \"04\"; break;\n case t <= 59: r = \"05\"; break;\n case t <= 71: r = \"06\"; break;\n case t <= 83: r = \"07\"; break;\n case t <= 95: r = \"08\"; break;\n case t <= 107: r = \"09\"; break;\n case t <= 119: r = \"10\"; break;\n case t <= 131: r = \"11\"; break;\n case t <= 143: r = \"12\"; break;\n default: r = \"13\"\n }\n return `videonme-basket-${r}.wbbasket.ru/vol${t}`\n}\n\nfunction constructHostV2(e, t = \"nm\", r = !1) {\n const n = parseInt(e, 10)\n , s = \"video\" === t ? ~~(n / 1e4) : ~~(n / 1e3);\n let o;\n return \"nm\" === t ? o = volHostV2(n, r) : \"feedbackPhoto\" === t ? o = volFeedbackPhotoHost(n, r) : \"video\" === t && (o = volVideoHost(n, r)),\n `https://${o}/part${s}/${n}`\n}\n\nfunction urlVideoProduct(e, t = \"mp4\", r = \"360p\") {\n const n = parseInt(e, 10);\n return `${constructHostV2(n, \"video\")}/${t}/${r}/${\"mp4\" === t ? \"1.mp4\" : \"index.m3u8\"}`\n}\n\nfunction numToUint8Array(r) {\n const t = new Uint8Array(8);\n for (let n = 0; n < 8; n++) {\n t[n] = r % 256;\n r = Math.floor(r / 256);\n }\n return t;\n}\n\nfunction crc16Arc(r) {\n const t = numToUint8Array(r);\n let n = 0;\n for (let r = 0; r < t.length; r++) {\n n ^= t[r];\n for (let r = 0; r < 8; r++)\n (1 & n) > 0 ? n = n >> 1 ^ 40961 : n >>= 1;\n }\n return n;\n}\n","img":"^(?:(feedback\\d+\\.(?:wb|wbbasket)\\.ru/.+/photos)/[fm]s\\.(?:webp|jpg)|(basket-\\d+\\.(?:wb\\.ru|wbcontent\\.net|wbbasket\\.ru)/.+/images)/c\\d+x\\d+/(\\d+\\.webp)|(videofeedback\\d+\\.(?:wb|wbbasket)\\.ru/.+)/preview\\.(?:webp|jpg))","ci":2,"loop":2,"to":":\nif (!this.styleAdded && document.URL.includes('/feedbacks')) {\n const style = document.createElement(\"style\")\n style.textContent = `\n .sw-slider-thumbs-gallery .gallery-set .gallery-set__item::before { z-index: 0 !important; }\n .gallery-set__list > li > img.hide-desktop { display: block !important;}\n `\n document.head.appendChild(style)\n this.styleAdded = true;\n}\n\nif ($[1]) {\n\treturn `${$[1]}/fs.webp`\n} else if ($[2]) {\n\treturn `${$[2]}/big/${$[3]}`\n} else if ($[4]) {\n return `${$[4]}/index.m3u8`\n}\n","note":"hababr\nhttp://forum.ru-board.com/topic.cgi?forum=5&topic=50874&start=2680&limit=1&m=1#1\nOLD\nhttp://forum.ru-board.com/topic.cgi?forum=5&topic=50874&start=2671#1\n\n\n!!!\nКурсор рекомендуется наводить на область с названием товара.\n+\nФильтр показывает видео (если есть) + оценку + фото/видео/отзывы покупателей.\n+\nНа первом фото есть сайдбар с рейтингом и отзывами покупателей, его, как и видео, можно отключить в фильтре так:\nlet show_videos = false;\nlet show_reviews_sidebar = false;\n\n\nПРИМЕРЫ\nhttps://global.wildberries.ru/catalog?search=свитер+женский&tail-location=SNS\nhttps://global.wildberries.ru/catalog?category=15584&sort=rate&page=1\nhttps://www.wildberries.ru/seller/664010\nhttps://www.wildberries.ru/catalog/igrushki/igrovye-nabory\nhttps://www.wildberries.ru/catalog/0/search.aspx?search=мини%20пылесос\nhttps://www.wildberries.ru/catalog/58113505/feedbacks?imtId=43628090"}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement