1/* Ðвиз «ÐÐ°ÐºÐ°Ñ ÑабоÑа Ñебе Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ»: 3 вопÑоÑа â ваканÑÐ¸Ñ Ð¸Ð· data.js. 2 ÐопÑоÑÑ Ð¸ Ð±Ð°Ð»Ð»Ñ Ð¿ÑавÑÑÑÑ Ð·Ð´ÐµÑÑ. ÐÐ°Ð»Ð»Ñ â какой ваканÑии ÑколÑко добавлÑÐµÑ Ð¾ÑÐ²ÐµÑ (id как в SITE.vacancies) */ 3(function () { 4 const QUESTIONS = [ 5 { 6 q: 'ЧÑо Ñебе ближе?', 7 a: [ 8 { t: 'ÐоÑовиÑÑ ÑÑками', img: 'assets/img/cook.webp', s: { cook: 3, kitchen: 1 } }, 9 { t: 'ÐÑÑÑ Ð² движении', img: 'assets/img/courier.svg', s: { courier: 3 } }, 10 { t: 'ÐбÑаÑÑÑÑ Ñ Ð»ÑдÑми', img: 'assets/img/cashier.webp', s: { cashier: 2, admin: 2 } }, 11 { t: 'ÐоÑÑдок и внимаÑелÑноÑÑÑ', img: 'assets/img/picker.webp', s: { picker: 3, kitchen: 2 } } 12 ] 13 }, 14 { 15 q: 'Ðак Ñ Ð¾ÑеÑÑ ÑабоÑаÑÑ?', 16 a: [ 17 { t: 'ÐолнÑе ÑменÑ, ÑÑÐ¾Ð±Ñ Ð±Ð¾Ð»ÑÑе заÑабоÑаÑÑ', s: { cook: 1, courier: 2, admin: 1 } }, 18 { t: 'ÐеÑеÑом или вмеÑÑе Ñ ÑÑÑбой', s: { cashier: 2, courier: 1, picker: 1 } }, 19 { t: 'Спокойно, без ÑÑеÑÑ', s: { kitchen: 2, picker: 1 } }, 20 { t: 'ÐеÑжаÑÑ Ð²ÑÑ ÑÐ¼ÐµÐ½Ñ Ð¿Ð¾Ð´ конÑÑолем', s: { admin: 3 } } 21 ] 22 }, 23 { 24 q: 'ЧÑо Ð´Ð»Ñ ÑÐµÐ±Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ðµ?', 25 a: [ 26 { t: 'ÐенÑги ÑÑазÑ', s: { courier: 2, cook: 1 } }, 27 { t: 'ÐаÑÑиÑÑÑÑ Ñ Ð½ÑлÑ', s: { cook: 2, picker: 1, kitchen: 1 } }, 28 { t: 'ÐÑÑаÑÑи до ÑпÑавлÑÑÑего', s: { admin: 2, cook: 1 } }, 29 { t: 'Ðоманда и аÑмоÑÑеÑа', s: { cashier: 1, kitchen: 1, picker: 1, admin: 1 } } 30 ] 31 } 32 ]; 33 34 // ÐоÑÐµÐ¼Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ + иÑÑоÑÐ¸Ñ ÑоÑÑа Ð´Ð»Ñ Ð¿ÑимеÑа (slug из stories.js) 35 const WHY = { 36 cook: ['Ð¢Ñ Ð»ÑбиÑÑ Ð´ÐµÐ»Ð°ÑÑ ÑÑками и видеÑÑ ÑезÑлÑÑаÑ. ÐаÑÑим Ñ Ð½ÑлÑ, а ÑеÑез полгода можно вÑÑаÑÑи до ÑеÑа', 'ivan-rakov'], 37 courier: ['Тебе Ð²Ð°Ð¶Ð½Ñ Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ðµ и Ñвобода. Сам вÑбиÑаеÑÑ ÑÐ¼ÐµÐ½Ñ Ð¸ маÑÑÑÑÑ, ÑаевÑе каждÑй денÑ', 'aleksandr-lavrinovich'], 38 admin: ['Ð¢Ñ ÑмееÑÑ Ð´ÐµÑжаÑÑ Ð²ÑÑ Ð¿Ð¾Ð´ конÑÑолем и ладиÑÑ Ñ Ð»ÑдÑми. ÐÑÑÑда пÑÑмой пÑÑÑ Ð² ÑпÑавлÑÑÑие', 'aleksandr-danilin'], 39 cashier: ['Ð¢Ñ Ð»ÐµÐ³ÐºÐ¾ обÑаеÑÑÑÑ Ñ Ð»ÑдÑми. ÐеÑеÑние ÑÐ¼ÐµÐ½Ñ Ñдобно ÑовмеÑаÑÑ Ñ ÑÑÑбой', ''], 40 picker: ['Ð¢Ñ Ð²Ð½Ð¸Ð¼Ð°ÑелÑнÑй и лÑбиÑÑ Ð¿Ð¾ÑÑдок. Ð¡Ð¿Ð¾ÐºÐ¾Ð¹Ð½Ð°Ñ ÑабоÑа, гÑаÑик вÑбиÑаеÑÑ Ñам', ''], 41 kitchen: ['Тебе нÑавиÑÑÑ, когда вÑÑ ÑиÑÑо и по меÑÑам. Ðожно без опÑÑа и Ñ Ð±ÑÑÑÑÑм вÑÑ Ð¾Ð´Ð¾Ð¼ на ÑменÑ', ''] 42 }; 43 const ORDER = ['cook', 'courier', 'admin', 'cashier', 'picker', 'kitchen']; // пÑи ÑавнÑÑ Ð±Ð°Ð»Ð»Ð°Ñ 44 45 const root = document.querySelector('[data-quiz]'); 46 if (!root || !window.SITE) return; 47 const esc = (s) => String(s).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c])); 48 let step = 0, score = {}; 49 50 function progress() { 51 return `<div class="quiz__progress" aria-hidden="true">${QUESTIONS.map((_, i) => `<i class="${i <= step ? 'is-on' : ''}"></i>`).join('')}</div>`; 52 } 53 54 function drawQuestion(dir) { 55 const Q = QUESTIONS[step]; 56 const withImg = Q.a.some((x) => x.img); 57 root.innerHTML = `<div class="quiz__step ${dir ? 'is-in' : ''}"> 58 <div class="quiz__top">${progress()}<span class="quiz__count">${step + 1} из ${QUESTIONS.length}</span></div> 59 <h3 class="h3 quiz__q">${esc(Q.q)}</h3> 60 <div class="quiz__opts ${withImg ? 'quiz__opts--img' : ''}"> 61 ${Q.a.map((a, i) => `<button type="button" class="quiz__opt quiz__opt--${i}" data-i="${i}"> 62 ${a.img ? `<span class="quiz__img"><img src="${esc(a.img)}" alt="" loading="lazy"></span>` : ''}
63 <span class="quiz__t">${esc(a.t)}</span></button>`).join('')} 64 </div> 65 ${step ? '<button type="button" class="quiz__back">â Ðазад</button>' : ''} 66 </div>`; 67 } 68 69 function drawResult() { 70 if (window.trackGoal) trackGoal('quiz_done'); 71 const best = ORDER.slice().sort((a, b) => (score[b] || 0) - (score[a] || 0) || ORDER.indexOf(a) - ORDER.indexOf(b)); 72 const v = SITE.vacancies.find((x) => x.id === best[0]); 73 const alt = SITE.vacancies.find((x) => x.id === best[1]); 74 const [why, storySlug] = WHY[v.id]; 75 const story = storySlug && (window.STORIES || []).find((s) => s.slug === storySlug); 76 root.innerHTML = `<div class="quiz__step is-in quiz__result quiz__result--${esc(v.color)}"> 77 <div class="quiz__res-img"><img src="${esc(v.img)}" alt="${esc(v.title)}"></div> 78 <div class="quiz__res-body"> 79 <span class="quiz__count">Тебе подойдÑÑ</span> 80 <h3 class="h2 quiz__res-title">${esc(v.title)}</h3> 81 <p class="quiz__why">${esc(why)}</p> 82 <p class="quiz__salary">${esc(v.salary)}${v.noNote ? '' : '<sup>*</sup>'}</p> 83 <ul class="perks">${v.perks.slice(0, 3).map((p) => `<li>${esc(p)}</li>`).join('')}</ul> 84 <div class="quiz__actions"> 85 <a href="#apply" class="btn btn--dark" data-apply="${esc(v.title)}">ÐÑкликнÑÑÑÑÑ</a> 86 <button type="button" class="btn quiz__again">ÐÑойÑи еÑÑ Ñаз</button> 87 </div> 88 ${story ? `<a class="quiz__story" href="stories.html#${esc(story.slug)}"><img src="${esc(story.face)}" alt=""><span>${esc(story.name.split(' ')[0])} Ñоже наÑинал Ñак: <b>${esc(story.from)} â ${esc(story.to)}</b></span></a>` : ''} 89 ${v.noNote ? '' : `<p class="quiz__note">* ${esc(SITE.salaryNote)}</p>`} 90 ${alt ? `<p class="quiz__alt">ÐÑÑ Ð¿ÑиÑмоÑÑиÑÑ: <a href="#vacancies">${esc(alt.title)}</a></p>` : ''} 91 </div> 92 </div>`; 93 } 94 95 root.addEventListener('click', (e) => { 96 const opt = e.target.closest('.quiz__opt'); 97 if (opt) { 98 const a = QUESTIONS[step].a[+opt.dataset.i]; 99 opt.classList.add('is-picked'); 100 Object.entries(a.s).forEach(([k, n]) => { score[k] = (score[k] || 0) + n; }); 101 (root._hist = root._hist || []).push(a.s); 102 setTimeout(() => { step++; step < QUESTIONS.length ? drawQuestion(1) : drawResult(); }, 220); 103 return; 104 } 105 if (e.target.closest('.quiz__back')) { 106 const s = root._hist.pop(); 107 Object.entries(s).forEach(([k, n]) => { score[k] -= n; }); 108 step--; drawQuestion(1); 109 return; 110 } 111 if (e.target.closest('.quiz__again')) { step = 0; score = {}; root._hist = []; drawQuestion(1); } 112 }); 113 114 drawQuestion(0); 115})();
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.