(function(){ const mountEl = document.getElementById('videoLibrary'); if (!mountEl || !window.Vue) return; const { createApp, ref, computed, onMounted } = Vue; createApp({setup() { const videos = ref([]); const videosMirai = computed(() => videos.value.filter(v => v.category === 'mirai') ); const videosIhen = computed(() => videos.value.filter(v => v.category === 'ihen') ); const articles = computed(() => videos.value.filter(v => v.category === 'article') ); const latestVideos = computed(() => [...videos.value] .sort((a, b) => new Date(b.date) - new Date(a.date)) .slice(0, 9) ); const onImgError = (ev, v) => { const fallback = v.category === 'mirai' ? 'images/umi/thumbs/thumb_mirai_fallback.jpg' : v.category === 'ihen' ? 'images/umi/thumbs/thumb_ihen_fallback.jpg' : 'images/umi/thumbs/thumb_article_fallback.jpg'; // article用fallback if (ev && ev.target && ev.target.src !== fallback) { ev.target.src = fallback; } }; onMounted(() => { fetch('data/videoArticles.json', { cache: 'no-store' }) .then(res => res.json()) .then(json => { videos.value = Array.isArray(json) ? json : []; }) .catch(() => { videos.value = []; }); }); return { videosMirai, videosIhen, articles, latestVideos, onImgError }; } }).mount('#videoLibrary'); })();