1/** 2 * KomeKaigi 2026 ã¹ãã³ãµã¼è¡¨ç¤º 3 * data/sponsors.json ãèªã¿è¾¼ã¿ #sponsors ã»ã¯ã·ã§ã³ã«æç»ããã 4 * plans ã¯ãã©ã³(ã´ã¼ã«ãã»å人ãªã©)ãã¨ã®é åã§ãJSON ã®ä¸¦ã³é ã«è¡¨ç¤ºããã 5 * layout 㯠"logo"(伿¥ãã´) ã¾ã㯠"avatar"(å人ã¢ã¤ã³ã³+åå)ã 6 * logo ã§ image ãçç¥ããã¨ããã´ã¨åãæ ã«ç¤¾åã ããçµãã ããã¹ãã«ã¼ãã§è¡¨ç¤ºãã 7 * (ãã´æªæä¾ã®ã¹ãã³ãµã¼ãå ã«æ²è¼ãããã)ã 8 * ã¹ãã³ãµã¼ã1ä»¶ãç¡ãã»åå¾ã«å¤±æããå ´åã¯ã»ã¯ã·ã§ã³ã¨ã¡ãã¥ã¼é ç®ãé表示ã®ã¾ã¾ã«ããã 9 */ 10(function () { 11 'use strict'; 12 13 const DATA_URL = 'data/sponsors.json'; 14 15 const section = document.getElementById('sponsors'); 16 const list = section && section.querySelector('.sponsor-plan-list'); 17 const menuItem = document.querySelector('[data-sponsors-menu]'); 18 19 if (!section || !list) { 20 return; 21 } 22 23 const el = (tag, className, text) => { 24 const node = document.createElement(tag); 25 if (className) node.className = className; 26 if (text != null) node.textContent = text; 27 return node; 28 }; 29 30 const createSponsor = (sponsor, layout, showName) => { 31 // url ã空ãªããªã³ã¯ã«ããªã 32 const hasLink = typeof sponsor.url === 'string' && sponsor.url.trim() !== ''; 33 const item = hasLink ? el('a', 'sponsor') : el('div', 'sponsor'); 34 if (hasLink) { 35 item.href = sponsor.url; 36 item.target = '_blank'; 37 item.rel = 'noopener'; 38 } 39 40 const hasImage = typeof sponsor.image === 'string' && sponsor.image.trim() !== ''; 41 const media = el('div', 'sponsor-media'); 42 43 if (hasImage) { 44 const img = el('img'); 45 img.src = sponsor.image; 46 img.alt = sponsor.name || ''; 47 img.loading = 'lazy'; 48 media.appendChild(img); 49 } else { 50 // ãã´æªæä¾: æ ã®ä¸ã«ç¤¾åãçµãã§ããã´ã®ã«ã¼ãã¨åã並ã³ãä¿ã¤ 51 media.appendChild(el('span', 'sponsor-media-text', sponsor.name)); 52 } 53 54 item.appendChild(media); 55 56 // 伿¥ãã´ã¯ç»åå ã«ç¤¾åãå«ã¾ãããããååã¯ã¢ã¤ã³ã³è¡¨ç¤ºã®ã¨ãã ãåºãã 57 // ãã©ã³ã« showName: true ãæå®ããã¨ããã´è¡¨ç¤ºã§ãååãæ·»ããã 58 // ããã¹ãã«ã¼ãã¯æ å ã«ç¤¾åãåºã¦ããã®ã§ãéè¤ãããªãã 59 if (layout === 'avatar' || (showName && hasImage)) { 60 item.appendChild(el('span', 'sponsor-name', sponsor.name)); 61 } 62 63 return item; 64 }; 65 66 const createPlan = (plan) => { 67 const sponsors = (plan.sponsors || []).filter((sponsor) => sponsor && sponsor.name); 68 if (sponsors.length === 0) { 69 return null; 70 } 71 72 const layout = plan.layout === 'logo' ? 'logo' : 'avatar'; 73 const className = ['sponsor-plan', `sponsor-plan-${layout}`]; 74 if (plan.id) className.push(`sponsor-plan-${plan.id}`); 75 const block = el('div', className.join(' ')); 76 77 const heading = el('h3', 'sponsor-plan-heading'); 78 if (plan.typeEn) heading.appendChild(el('span', 'sponsor-plan-heading-en', plan.typeEn)); 79 if (plan.type) heading.appendChild(el('span', 'sponsor-plan-heading-ja', plan.type)); 80 block.appendChild(heading); 81 82 const grid = el('div', 'sponsor-grid');
83 sponsors.forEach((sponsor) => grid.appendChild(createSponsor(sponsor, layout, plan.showName === true))); 84 block.appendChild(grid); 85 86 return block; 87 }; 88 89 const render = (plans) => { 90 const blocks = plans.map(createPlan).filter(Boolean); 91 92 if (blocks.length === 0) { 93 return; 94 } 95 96 list.replaceChildren(...blocks); 97 section.hidden = false; 98 if (menuItem) menuItem.hidden = false; 99 }; 100 101 fetch(DATA_URL) 102 .then((response) => { 103 if (!response.ok) { 104 throw new Error(`HTTP error! status: ${response.status}`); 105 } 106 return response.json(); 107 }) 108 .then((data) => render(data.plans || [])) 109 .catch((error) => { 110 console.error('ã¹ãã³ãµã¼ãã¼ã¿ã®åå¾ã¨ã©ã¼:', error); 111 }); 112})();
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.