1const LIVE_TRAINING_PROGRAMS = [ 2 { 3 id: 'software-testing', 4 area: 'Software Testing & QA', 5 title: 'Software Testing & SDET Live Training', 6 description: 'Build practical QA skills across manual testing, API testing, Selenium automation and real project workflows.', 7 href: '/course/automation-testing-with-selenium-live-projects', 8 jobsHref: '/jobs?q=SDET', 9 careerHref: '/career-paths/software-testing', 10 keywords: ['software testing','qa','sdet','selenium','automation','api testing','testng','robot framework','jmeter','katalon'], 11 }, 12 { 13 id: 'cybersecurity-grc', 14 area: 'Cybersecurity & GRC', 15 title: 'Cybersecurity, GRC & AI Governance Live Training', 16 description: 'Build security, risk, compliance and governance skills with practical controls, cloud and responsible-AI context.', 17 href: '/course/cybersecurity-governance-risk-compliance-grc', 18 jobsHref: '/jobs?q=Cybersecurity%20GRC', 19 careerHref: '/career-paths/grc-analyst', 20 keywords: ['cybersecurity','cyber security','grc','security','soc','governance','risk','compliance','iam','cloud security'], 21 }, 22 { 23 id: 'business-analysis', 24 area: 'Business Analysis', 25 title: 'Business Analysis + AI Skills Live Training', 26 description: 'Learn requirements, Agile, Jira, SQL, UAT and practical AI-assisted business analysis workflows.', 27 href: '/course/certified-business-analyst', 28 jobsHref: '/jobs?q=Business%20Analyst', 29 careerHref: '/career-paths/business-analyst', 30 keywords: ['business analysis','business analyst','ba','agile','jira','uat','requirements'], 31 }, 32 { 33 id: 'data-analytics', 34 area: 'Data & Analytics', 35 title: 'Data Analytics with Python Live Training', 36 description: 'Develop practical Python, Pandas, NumPy and reporting skills through guided analytics exercises and projects.', 37 href: '/course/data-analytics-with-python', 38 jobsHref: '/jobs?q=Data%20Analyst', 39 careerHref: '/career-paths/data-analyst', 40 keywords: ['data','analytics','data analyst','python','pandas','numpy','reporting','bi'], 41 }, 42 { 43 id: 'cloud-aws', 44 area: 'Cloud & AWS', 45 title: 'AWS Cloud Foundations Live Training', 46 description: 'Build practical AWS foundations across core services, security, architecture, billing and cloud operations.', 47 href: '/course/aws-certified-cloud-practitioner-clf-c02', 48 jobsHref: '/jobs?q=Cloud%20Engineer', 49 careerHref: '/career-paths/cloud-engineer', 50 keywords: ['aws','cloud','cloud infrastructure','devops','solutions architect','cloud engineer'], 51 }, 52]; 53 54function escapeHtml(value) { 55 return String(value ?? '') 56 .replaceAll('&', '&') 57 .replaceAll('<', '<') 58 .replaceAll('>', '>') 59 .replaceAll('"', '"') 60 .replaceAll("'", '''); 61} 62 63function normalise(value) { 64 return String(value || '').trim().toLowerCase(); 65} 66 67export function liveTrainingPrograms() { 68 return LIVE_TRAINING_PROGRAMS.map((item) => ({ ...item })); 69} 70 71export function trainingForContext(context = '') { 72 const q = normalise(context); 73 if (!q) return LIVE_TRAINING_PROGRAMS[0]; 74 const scored = LIVE_TRAINING_PROGRAMS.map((program) => { 75 let score = 0; 76 for (const keyword of program.keywords) { 77 if (q.includes(keyword)) score += keyword.length + 10; 78 if (keyword.includes(q) && q.length > 2) score += q.length; 79 } 80 if (q.includes(normalise(program.area))) score += 80; 81 return { program, score }; 82 }).sort((a, b) => b.score - a.score); 83 return scored[0]?.score ? scored[0].program : LIVE_TRAINING_PROGRAMS[0]; 84} 85 86export function renderLiveTrainingCard(program, options = {}) { 87 const compact = options.compact !== false; 88 return ` 89 <aside class="liveTrainingCardV372 ${compact ? 'isCompact' : ''}"> 90 <div class="liveTrainingBadgeV372"><span></span> LIVE CAREER TRAINING</div> 91 <div class="liveTrainingAreaV372">${escapeHtml(program.area)}</div> 92 <h3>${escapeHtml(program.title)}</h3> 93 <p>${escapeHtml(program.description)}</p> 94 <div class="liveTrainingActionsV372"> 95 <a href="${escapeHtml(program.href)}" data-link>View training</a> 96 <a href="${escapeHtml(program.jobsHref || '/jobs')}" data-link>Related jobs</a> 97 <a href="${escapeHtml(program.careerHref || '/career-paths')}" data-link>Career path</a> 98 <a href="/contact" data-link>Check current batch</a> 99 </div> 100 </aside> 101 `; 102} 103 104export function renderLiveTrainingStrip(programs = LIVE_TRAINING_PROGRAMS.slice(0, 4)) { 105 return ` 106 <section class="liveTrainingStripV372"> 107 <div class="liveTrainingStripHeadV372"> 108 <div><span>LIVE CAREER TRAINING</span><h2>Build the skills connected to the jobs you want.</h2><p>Explore instructor-led programs aligned to active career areas, then compare related jobs and career paths before enrolling.</p></div> 109 <a href="/courses" data-link>View all live training â</a> 110 </div> 111 <div class="liveTrainingGridV372"> 112 ${programs.map((program) => renderLiveTrainingCard(program, { compact: true })).join('')} 113 </div> 114 </section> 115 `; 116} 117 118export const liveTrainingStyles = ` 119.liveTrainingStripV372{margin:28px 0;background:linear-gradient(135deg,#f3fbf8,#f8fbff);border:1px solid #dce9e4;border-radius:18px;padding:22px}.liveTrainingStripHeadV372{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:15px}.liveTrainingStripHeadV372>div>span,.liveTrainingBadgeV372{font-size:10px;letter-spacing:.12em;font-weight:900;color:#148466}.liveTrainingStripHeadV372 h2{margin:5px 0 5px;font-size:clamp(1.2rem,2vw,1.7rem);color:#10231d;letter-spacing:-.025em}.liveTrainingStripHeadV372 p{margin:0;color:#60736c;font-size:.86rem;line-height:1.55;max-width:720px}.liveTrainingStripHeadV372>a{color:#1769aa;font-size:.82rem;font-weight:850;text-decoration:none;white-space:nowrap}.liveTrainingGridV372{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:11px}.liveTrainingCardV372{background:#fff;border:1px solid #dce7e3;border-radius:14px;padding:15px;box-shadow:0 6px 20px rgba(25,66,53,.04)}.liveTrainingCardV372 h3{margin:6px 0 7px;color:#15362c;font-size:.95rem;line-height:1.35}.liveTrainingCardV372 p{margin:0;color:#687a74;font-size:.78rem;line-height:1.5}.liveTrainingBadgeV372{display:flex;align-items:center;gap:6px}.liveTrainingBadgeV372>span{width:7px;height:7px;border-radius:50%;background:#20b486;box-shadow:0 0 0 4px rgba(32,180,134,.1)}.liveTrainingAreaV372{margin-top:9px;font-size:.72rem;font-weight:850;color:#315a4c}.liveTrainingActionsV372{display:flex;gap:7px;flex-wrap:wrap;margin-top:13px}.liveTrainingActionsV372 a{display:inline-flex;align-items:center;justify-content:center;min-height:34px;padding:0 9px;border-radius:9px;text-decoration:none;font-size:.72rem;font-weight:850}.liveTrainingActionsV372 a:first-child{background:#1769aa;color:#fff}.liveTrainingActionsV372 a:not(:first-child){border:1px solid #d8e5df;color:#176b53;background:#f8fcfa}.liveTrainingActionsV372 a:last-child{color:#6b5a22;background:#fffaf0;border-color:#eadfbf}.liveTrainingCardV372.isCompact .liveTrainingActionsV372 a{flex:1;min-width:105px}.jobs-filter-sidebar .liveTrainingCardV372{margin-top:14px}.jobs-filter-sidebar .liveTrainingCardV372 h3{font-size:.9rem}.jobs-filter-sidebar .liveTrainingCardV372 p{font-size:.75rem}.jobs-filter-sidebar .liveTrainingActionsV372{display:grid;grid-template-columns:1fr}.jobs-filter-sidebar .liveTrainingActionsV372 a{width:100%;box-sizing:border-box}.jd-sidebar .liveTrainingCardV372{margin:0}.practiceCenterInnerV364>.liveTrainingStripV372{margin-top:26px} 120@media(max-width:1050px){.liveTrainingGridV372{grid-template-columns:repeat(2,minmax(0,1fr))}} 121@media(max-width:680px){.liveTrainingStripV372{padding:17px;border-radius:14px}.liveTrainingStripHeadV372{align-items:flex-start;flex-direction:column}.liveTrainingGridV372{grid-template-columns:1fr}.liveTrainingStripHeadV372>a{white-space:normal}} 122`;
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.