PageSourceSearch

https://kodomo-net.or.jp/cms/wp-content/themes/kodomonet/assets/js/pages.js

js kodomo-net.or.jp collected 2026-10-08 21:19:03 UTC 29,487 bytes, 701 lines download raw bytes

1// GSAPプラグインの登録
2gsap.registerPlugin(ScrollTrigger);
3
4// カードのスタッガーアニメーション(staggerに最適化)
5gsap.fromTo('.card', 
6    {
7        y: 100,
8        opacity: 0
9    },
10    {
11        y: 0,
12        opacity: 1,
13        duration: 0.8,
14        ease: 'power3.out',
15        stagger: 0.15, // delay の代わりに stagger を使用
16        scrollTrigger: {
17            trigger: '.card',
18            start: 'top 85%',
19            once: true,
20        }
21    }
22);
23
24// キャラクター目のアニメーション設定
25document.addEventListener('DOMContentLoaded', function() {
26    
27    // GSAP版パララックス(simpleParallax の代替)
28    if (document.getElementsByClassName('thumbnail').length > 0) {
29        gsap.utils.toArray('.thumbnail').forEach(img => {
30            gsap.to(img, {
31                yPercent: -20,
32                ease: 'none',
33                scrollTrigger: {
34                    trigger: img,
35                    start: 'top bottom',
36                    end: 'bottom top',
37                    scrub: 1,
38                }
39            });
40        });
41    }
42    
43    // まばたき機能(統合版)
44    function randomBlink() {
45        const eyelids = document.querySelectorAll('.eyelid');
46        if (eyelids.length > 0) {
47            gsap.to('.eyelid', {
48                scaleY: 1,
49                duration: 0.1,
50                yoyo: true,
51                repeat: 1,
52                ease: 'power2.inOut'
53            });
54        }
55    }
56    
57    function naturalBlink() {
58        const eyelids = document.querySelectorAll('.eyelid');
59        if (eyelids.length > 0) {
60            const tl = gsap.timeline();
61            tl.to('.eyelid', {
62                scaleY: 1,
63                duration: 0.08,
64                ease: 'power2.in'
65            })
66            .to('.eyelid', {
67                scaleY: 0,
68                duration: 0.12,
69                ease: 'power2.out'
70            });
71        }
72    }
73    
74    // まばたきを統合(1つのsetIntervalで管理)
75    setInterval(() => {
76        const rand = Math.random();
77        if (rand < 0.15) {
78            naturalBlink();
79        } else if (rand < 0.25) {
80            randomBlink();
81        }
82    }, 4000);
83    
84    // キャラクターコンテナの取得とイベント設定
85    const characterContainer = document.querySelector('.character-container');
86    
87    if (characterContainer) {
88        characterContainer.addEventListener('mouseenter', () => {
89            randomBlink();
90        });
91    }
92});
93
94// デバッグ用
95console.log('GSAP loaded:', typeof gsap !== 'undefined');
96console.log('ScrollTrigger loaded:', typeof ScrollTrigger !== 'undefined');
97
98// アニメーションタイムライン
99
100
101
102let tl;
103
104function createAnimation() {
105    tl = gsap.timeline({ paused: true });
106    
107    const bubbles = ['.bubble-1', '.bubble-2', '.bubble-3', '.bubble-4', '.bubble-5', '.bubble-6'];
108    
109    bubbles.forEach((bubble, index) => {
110        tl.to(bubble, {
111            opacity: 1,
112            scale: 1,
113            duration: 0.6,
114            ease: "back.out(1.7)",
115            delay: index * 0.2
116        }, index * 0.3);
117    });
118    
119    tl.to('#centerShape', {
120        opacity: 1,
121        scale: 1,
122        duration: 0.8,
123        ease: "elastic.out(1, 0.5)"
124    }, "+=0.3");
125    
126    return tl;
127}
128
129function setupScrollTrigger() {
130    ScrollTrigger.create({
131        trigger: "#animationSection",
132        start: "top 80%",
133        once: true,
134        onEnter: () => {
135            if (tl) {
136                tl.restart();
137            }
138        },
139        onLeave: () => {
140            // 必要に応じて、画面外に出た時の処理
141        },
142        onEnterBack: () => {
143            if (tl) {
144                tl.restart();
145            }
146        }
147    });
148}
149
150function resetAnimation() {
151    gsap.set(['.speech-bubble', '#centerShape'], {
152        opacity: 0,
153        scale: 0
154    });
155}
156
157function init() {
158    resetAnimation();
159    createAnimation();
160    setupScrollTrigger();
161    
162    const replayBtn = document.getElementById('replayBtn');
163    const resetBtn = document.getElementById('resetBtn');
164    
165    if (replayBtn) {
166        replayBtn.addEventListener('click', () => {
167            if (tl) {
168                tl.restart();
169            }
170        });
171    } else {
172        console.warn('replayBtn element not found');
173    }
174    
175    if (resetBtn) {
176        resetBtn.addEventListener('click', resetAnimation);
177    } else {
178        console.warn('resetBtn element not found');
179    }
180}
181
182document.addEventListener('DOMContentLoaded', init);
183
184// デバウンス処理を追加(スマホ最適化)
185let resizeTimer;
186window.addEventListener('resize', () => {
187    clearTimeout(resizeTimer);
188    resizeTimer = setTimeout(() => {
189        ScrollTrigger.refresh();
190    }, 250);
191});
192
193// ハンバーガーメニュー
194document.addEventListener('DOMContentLoaded', function () {
195    const hamburgerBtn = document.getElementById('js__hd_nav');
196    const navMenu = document.getElementById('js__hd_navwrap');
197    
198    if (hamburgerBtn && navMenu) {
199        hamburgerBtn.addEventListener('click', function () {
200            hamburgerBtn.classList.toggle('active');
201            navMenu.classList.toggle('active');
202        });
203    }
204});
205
206// スムーズナビゲーション閉じる
207$('a[href*="#"]').on('click', function() {  
208    $('#js__hd_navwrap').removeClass('active');
209});
210
211// 働き方の切り替え
212const tabData = [
213    {
214        title: '児童館スタッフ',
215        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_01.webp',
216        description: '中・高校生世代向け児童館青少年ステーションCAPSまたは緑ケ丘児童館でのお仕事です。\n児童館において、子どもが安心・安全に過ごせる居場所をつくるとともに、遊びを通して関わり、成長を見守ります。また子育て家庭を支援し、地域における健全育成の環境づくりに努めます。'
217    },
218    {
219        title: '学童クラブスタッフ',
220        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_02.webp',
221        description: '緑ケ丘児童館学童クラブまたはせんがわ学童クラブでのお仕事です。\n就労等の理由により保護者が昼間家庭にいない小学生を対象に、家庭に代わる放課後の適切な遊びや生活の場を提供しています。また、集団生活を通して、子どもたちの成長や基本的生活習慣の確立を支援します。'
222    },
223    {
224        title: '相談員',
225        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_03.webp',
226        description: '中・高校生世代向け児童館青少年ステーションCAPSでのお仕事です。\n利用者が抱える様々な悩みや困りごとを解決できるよう相談に応じるだけでなく、関係機関と連携を行います。'
227    },
228    {
229        title: 'あそビバサポーター',
230        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_04.webp',
231        description: '緑ケ丘小学校の空き教室を活用した、緑ヶ丘小学校あそビバ(放課後子供教室)でのお仕事です。\nあそビバは放課後にランドセルを背負ったまま、友だち同士で遊びに行くことができる、自由で安全な遊び場です。子どもたちが安全に、仲良く楽しく元気に過ごせるようにサポートします。'
232    },
233    {
234        title: 'ユースワーカー',
235        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_05.webp',
236        description: '中高生世代の居場所づくりを担うユースワーカーの仕事は、「信頼関係づくり」と「成長のサポート」が中心です。\n児童館に来る生徒たちと日常的に会話を交わしながら、安心して過ごせる雰囲気をつくります。\n一緒に遊んだり、イベントを企画したり、進路や友人関係などの相談に耳を傾けたりと、関わり方はさまざま。\n「自分の居場所がここにある」と感じてもらえるような環境づくりを目指す、やりがいのある仕事です。'
237    },
238    {
239        title: '経理・総務',
240        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_08.jpg',
241        description: '法人運営における事務業務全般(経理・総務・人事)に携わっていただきます。\n職員が働きやすい環境を整えると共に、法人のバックオフィスのサポートを行います。経理・人事労務・総務のいずれかの経験者や簿記資格をお持ちの方は大歓迎です。'
242    },
243    {
244        title: '総務',
245        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_07.jpg',
246        description: '法人運営における事務業務全般(経理・総務・人事)に携わっていただきます。職員が働きやすい環境を整えると共に、法人のバックオフィスもサポートしていただきます。\n経理・人事労務・総務のいずれかの経験者や簿記資格をお持ちの方は大歓迎します。'
247    },
248    {
249        title: '経理',
250        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_08.jpg',
251        description: '法人運営における事務業務全般(経理・総務・人事)に携わっていただきます。職員が働きやすい環境を整えると共に、法人のバックオフィスもサポートしていただきます。\n経理・人事労務・総務のいずれかの経験者や簿記資格をお持ちの方は大歓迎します。'
252    },
253    {
254        title: '観光案内スタッフ',
255        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_09.jpg',
256        description: 'ブランクOK・社会復帰歓迎!無理のない勤務で、就労経験のない方も安心してスタートしていただけます。\n丁寧なサポート体制で、社会に出る第一歩を全力応援します!'
257    },
258    {
259        title: '調布市Webサイト管理',
260        image: '/cms/wp-content/themes/kodomonet/assets/img/ph_workstyle_10.jpg',
261        description: 'パソコンでの業務に抵抗がない方大歓迎!\n調布市公式Webサイトの更新作業や、市報掲載ページの作成、公開などを行ã
261ªã£ã¦ã„ます。'
262    }
263];
264
265// すべてのタブコンテナを取得して個別に処理
266const containers = document.querySelectorAll('.workstyle-container');
267
268containers.forEach(container => {
269    const buttons = container.querySelectorAll('.workstyle-tab-button');
270    const contentTitle = container.querySelector('.workstyle-content-title');
271    const contentImage = container.querySelector('.workstyle-content-image');
272    const contentDescription = container.querySelector('.workstyle-content-description');
273
274    buttons.forEach(button => {
275        button.addEventListener('click', function() {
276            const tabIndex = parseInt(this.getAttribute('data-tab'));
277            const data = tabData[tabIndex];
278
279            // 同じコンテナ内のボタンのアクティブ状態を更新
280            buttons.forEach(btn => btn.classList.remove('active'));
281            this.classList.add('active');
282
283            // コンテンツを更新
284            contentTitle.textContent = data.title;
285            contentImage.src = data.image;
286            contentImage.alt = data.title;
287            contentDescription.innerHTML = data.description.replace(/\n/g, '<br>');
288
289            // スムーズなアニメーション効果
290            contentTitle.style.opacity = '0.7';
291            setTimeout(() => {
292                contentTitle.style.opacity = '1';
293            }, 100);
294        });
295    });
296});
297
298// アニメーション効果のCSS
299const style = document.createElement('style');
300style.textContent = `
301    .workstyle-content-title {
302        transition: opacity 0.3s ease;
303    }
304`;
305document.head.appendChild(style);
306
307
308//top mv btn
309(() => {
310  const scrollBtn = document.querySelector('.top_btn__scroll');
311  if (scrollBtn) {
312    scrollBtn.style.transition = 'opacity 0.3s ease';
313    window.addEventListener('scroll', () => {
314      const currentScroll = window.pageYOffset;
315      if (currentScroll > 50) {
316        scrollBtn.style.opacity = '0';
317        scrollBtn.style.pointerEvents = 'none';
318      } else {
319        scrollBtn.style.opacity = '1';
320        scrollBtn.style.pointerEvents = 'auto';
321      }
322    });
323  }
324})();
325
326// (() => {
327//     const scrollBtn = document.querySelector('.top_btn__scroll');
328//     if (scrollBtn) {
329//       scrollBtn.style.transition = 'opacity 0.3s ease';
330
331//       window.addEventListener('scroll', () => {
332//         const currentScroll = window.pageYOffset;
333//         if (currentScroll > 50) {
334//           scrollBtn.style.opacity = '0';
335//           scrollBtn.style.pointerEvents = 'none';
336//         } else {
337//           scrollBtn.style.opacity = '1';
338//           scrollBtn.style.pointerEvents = 'auto';
339//         }
340//       });
341//     }
342// })();
343
344
345// //top mv scroll btn:スクロールでボタンをフェードアウト
346// const scrollBtn = document.querySelector('.top_btn__scroll');
347
348// // CSSトランジションを設定
349// scrollBtn.style.transition = 'opacity 0.3s ease';
350
351// window.addEventListener('scroll', () => {
352// const currentScroll = window.pageYOffset;
353
354// // 50px以上スクロールしたら非表示
355// if (currentScroll > 50) {
356// scrollBtn.style.opacity = '0';
357// scrollBtn.style.pointerEvents = 'none';
358// } else {
359// scrollBtn.style.opacity = '1';
360// scrollBtn.style.pointerEvents = 'auto';
361// }
362// });
363
364
365
366// CHIDE VOICE スライダー 
367(function() {
368  var slides = [
369    {
370      voice: "01",
371      title: "気楽に過ごせる居場所であり、\n活動や交流の場",
372      text: "私はCAPSを利用している高校生です。ここは気楽に過ごせる大切な居場所で、活動や人との交流を楽しめる場所です。スタッフさんとは趣味の話で盛り上がったり、友人のように話せたりして、とても楽しい時間を過ごしています。お祭りやイベントのお手伝いを通して地域の方とも関われるのが嬉しいです。卒業後もCAPSや地域の活動に関わり続けたいと思っています。こんな居場所があるのは、支えてくださる皆さんのおかげです。ありがとうございます。",
373    },
374    {
375      voice: "02",
376      title: "遊びも交流も趣味も広がる場所",
377      text: "僕がCAPSで楽しんでいることは、ゲームやバスケットボール、麻雀など本当にいろいろあります。ドッジボールや卓球、ゲーム大会などを通して、たくさんの人と交流できるのが魅力です。また、ギターやドラムなどの楽器ã
377‚’使えたり、eスポーツの大会に出られたりと、自分の趣味を見つけて伸ばせるのもCAPSの素晴らしいところだと思います。\nこれからもCAPSでたくさんの経験を重ねていきたいです。応援してくださる皆さんに心から感謝しています。",
378    },
379    {
380      voice: "03",
381      title: "自分らしくいられる居場所",
382      text: "CAPSは、私にとって学校や家とは違う「自分らしくいられる場所」です。年齢や趣味の違う人たちと出会うことで新しい刺激を受け、自分の世界がどんどん広がっていきます。普段の生活では出会えない考え方に触れ、毎日がより充実し、大切な場所だと感じています。\nこうした出会いや経験を通して、自分を少しずつ成長させることができています。その機会をくださっている皆さんに、いつも感謝の気持ちを抱いています。",
383    },
384    {
385      voice: "04",
386      title: "友だちと安心して遊べる楽しい場所",
387      text: "児童館には友だちと約束してよく来ます。\nみんなでゲームをしたり、近くの公園で自由に遊べるところがすごく楽しいです。\n広い場所でドッチビーができるのも気に入っています。\nいつも楽しくすごせる場所があることに、ありがとうって思っています。",
388    },
389    {
390      voice: "05",
391      title: "毎日わくわくできる場所",
392      text: "学童クラブにはマンガがたくさんあって、ほかにも新しいおもちゃで遊べるのがとっても楽しいです。\nお茶も飲めるし、たまに自由におやつを食べられる時間があるのもいいところです。\n毎日わくわくできる場所があってうれしいです。いつもありがとうございます。",
393    }
394  ];
395
396/*-----------------------------------------------------------
397*/
398
399  var cur = 0;
400  var track = document.getElementById("chideVoiceSliderTrack");
401  var btnP = document.getElementById("chideVoicePrevBtn");
402  var btnN = document.getElementById("chideVoiceNextBtn");
403  var pag = document.getElementById("chideVoicePagination");
404
405  if (!track || !btnP || !btnN || !pag) return;
406
407  function createSlides() {
408    slides.forEach(function(s) {
409      var slide = document.createElement("div");
410      slide.className = "chide_voice_slide";
411      
412      var voiceNum = document.createElement("div");
413      voiceNum.className = "chide_voice_slide_voice_number";
414      voiceNum.innerHTML = '<span>VOICE</span>' + s.voice;
415      
416      var content = document.createElement("div");
417      content.className = "chide_voice_slide_content";
418
419      var title = document.createElement("h2");
420      title.className = "chide_voice_slide_title";
421      title.innerHTML = s.title.replace(/\n/g, "<br>");
422
423      var text = document.createElement("p");
424      text.className = "chide_voice_slide_text";
425      text.innerHTML = s.text.replace(/\n/g, "<br>");
426      
427      content.appendChild(voiceNum);
428      content.appendChild(title);
429      content.appendChild(text);      
430      
431      slide.appendChild(content);
432      track.appendChild(slide);
433    });
434  }
435
436  function createPagination() {
437    slides.forEach(function(_, i) {
438      var dot = document.createElement("button");
439      dot.className = "chide_voice_dot";
440      if (i === 0) dot.classList.add("chide_voice_active");
441      dot.onclick = function() { goTo(i); };
442      pag.appendChild(dot);
443    });
444  }
445
446  function goTo(i) {
447    cur = i;
448    update();
449  }
450
451  function update() {
452    var slidesEl = track.children;
453
454    for (var i = 0; i < slidesEl.length; i++) {
455      if (i === cur) {
456        slidesEl[i].classList.add("active");
457      } else {
458        slidesEl[i].classList.remove("active");
459      }
460    }
461
462    btnP.disabled = cur === 0;
463    btnN.disabled = cur === slides.length - 1;
464
465    var dots = pag.children;
466    for (var j = 0; j < dots.length; j++) {
467      if (j === cur) dots[j].classList.add("chide_voice_active");
468      else dots[j].classList.remove("chide_voice_active");
469    }
470  }
471
472  btnP.onclick = function() { if (cur > 0) { cur--; update(); } };
473  btnN.onclick = function() { if (cur < slides.length - 1) { cur++; update(); } };
474
475  createSlides();
476  createPagination();
477  update();
478})();
479//20260108//
480// (function() {
481//   var slides = [
482//     {
483//       voice: "01",
484//       title: "気楽に過ごせる居場所であり、\n活動や交流の場",
485//       text: "私はCAPSを利用している高校生です。ここは気楽に過ごせる大切な居場所で、活動や人との交流を楽しめる場所です。スタッフさんとは趣味の話で盛り上がったり、友人のように話せたりして、とても楽しい時間を過ごしています。お祭りやイベントのお手伝いを通して地域の方とも関われるのが嬉しいです。卒業後もCAPSや地域の活動に関わり続けたいと思っています。こんな
485居場所があるのは、支えてくださる皆さんのおかげです。ありがとうございます。",
486//     },
487//     {
488//       voice: "02",
489//       title: "遊びも交流も趣味も広がる場所",
490//       text: "僕がCAPSで楽しんでいることは、ゲームやバスケットボール、麻雀など本当にいろいろあります。ドッジボールや卓球、ゲーム大会などを通して、たくさんの人と交流できるのが魅力です。また、ギターやドラムなどの楽器を使えたり、eスポーツの大会に出られたりと、自分の趣味を見つけて伸ばせるのもCAPSの素晴らしいところだと思います。\nこれからもCAPSでたくさんの経験を重ねていきたいです。応援してくださる皆さんに心から感謝しています。",
491//     },
492//     {
493//       voice: "03",
494//       title: "自分らしくいられる居場所",
495//       text: "CAPSは、私にとって学校や家とは違う「自分らしくいられる場所」です。年齢や趣味の違う人たちと出会うことで新しい刺激を受け、自分の世界がどんどん広がっていきます。普段の生活では出会えなã
495„考え方に触れ、毎日がより充実し、大切な場所だと感じています。\nこうした出会いや経験を通して、自分を少しずつ成長させることができています。その機会をくださっている皆さんに、いつも感謝の気持ちを抱いています。",
496//     },
497//     {
498//       voice: "04",
499//       title: "友だちと安心して遊べる楽しい場所",
500//       text: "児童館には友だちと約束してよく来ます。\nみんなでゲームをしたり、近くの公園で自由に遊べるところがすごく楽しいです。\n広い場所でドッチビーができるのも気に入っています。\nいつも楽しくすごせる場所があることに、ありがとうって思っています。",
501//     },
502//     {
503//       voice: "05",
504//       title: "毎日わくわくできる場所",
505//       text: "学童クラブにはマンガがたくさんあって、ほかにも新しいおもちゃで遊べるのがとっても楽しいです。\nお茶も飲めるし、たまに自由におやつを食べられる時間があるのもいいところです。\n毎日わくわくできる場所があってうれしいです。いつもありがとうございます。",
506//     }
507//   ];
508
509//   var cur = 0, drag = false, startX = 0, trans = 0, prev = 0;
510//   var track = document.getElementById("chideVoiceSliderTrack");
511//   var btnP = document.getElementById("chideVoicePrevBtn");
512//   var btnN = document.getElementById("chideVoiceNextBtn");
513//   var pag = document.getElementById("chideVoicePagination");
514
515//   if (!track || !btnP || !btnN || !pag) return;
516
517//   function createSlides() {
518//     slides.forEach(function(s) {
519//       var slide = document.createElement("div");
520//       slide.className = "chide_voice_slide";
521      
522//       var voiceNum = document.createElement("div");
523//       voiceNum.className = "chide_voice_slide_voice_number";
524//       voiceNum.innerHTML = '<span>VOICE</span>' + s.voice;
525      
526//       var content = document.createElement("div");
527//       content.className = "chide_voice_slide_content";
528
529//       var title = document.createElement("h2");
530//       title.className = "chide_voice_slide_title";
531//       // 改行コードを <br> に変換
532//       title.innerHTML = s.title.replace(/\n/g, "<br>");
533
534//       var text = document.createElement("p");
535//       text.className = "chide_voice_slide_text";
536//       text.innerHTML = s.text.replace(/\n/g, "<br>");
537
538//       // var title = document.createElement("h2");
539//       // title.className = "chide_voice_slide_title";
540//       // title.textContent = s.title;
541      
542//       // var text = document.createElement("p");
543//       // text.className = "chide_voice_slide_text";
544//       // text.textContent = s.text;
545      
546//       content.appendChild(voiceNum);
547//       content.appendChild(title);
548//       content.appendChild(text);      
549//       // var img = document.createElement("div");
550//       // img.className = "chide_voice_slide_image";
551//       // img.style.backgroundImage = "url('" + s.image + "')";
552      
553//       slide.appendChild(content);
554//       // slide.appendChild(img);
555//       track.appendChild(slide);
556//     });
557//   }
558
559//   function createPagination() {
560//     slides.forEach(function(_, i) {
561//       var dot = document.createElement("button");
562//       dot.className = "chide_voice_dot";
563//       if (i === 0) dot.classList.add("chide_voice_active");
564//       dot.onclick = function() { goTo(i); };
565//       pag.appendChild(dot);
566//     });
567//   }
568
569//   function goTo(i) {
570//     cur = i;
571//     update();
572//   }
573
574// function update() {
575//   var slidesEl = track.children;
576
577//   for (var i = 0; i < slidesEl.length; i++) {
578//     // アクティブスライドだけ表示
579//     if (i === cur) {
580//       slidesEl[i].classList.add("active");
581//     } else {
582//       slidesEl[i].classList.remove("active");
583//     }
584//   }
585
586//   btnP.disabled = cur === 0;
587//   btnN.disabled = cur === slides.length - 1;
588
589//   var dots = pag.children;
590//   for (var j = 0; j < dots.length; j++) {
591//     if (j === cur) dots[j].classList.add("chide_voice_active");
592//     else dots[j].classList.remove("chide_voice_active");
593//   }
594// }
595//   // function update() {
596//   //   trans = -cur * 100;
597//   //   prev = trans;
598//   //   track.style.transform = "translateX(" + trans + "%)";
599//   //   btnP.disabled = cur === 0;
600//   //   btnN.disabled = cur === slides.length - 1;
601    
602//   //   var dots = pag.children;
603//   //   for (var i = 0; i < dots.length; i++) {
604//   //     if (i === cur) dots[i].classList.add("chide_voice_active");
605//   //     else dots[i].classList.remove("chide_voice_active");
606//   //   }
607//   // }
608
609//   function handleStart(e) {
610//     drag = true;
611//     startX = e.type.indexOf("mouse") > -1 ? e.pageX : e.touches[0].clientX;
612//     track.classList.add("chide_voice_dragging");
613//   }
614
615//   function handleMove(e) {
616//     if (!drag) return;
617//     var x = e.type.indexOf("mouse") > -1 ? e.pageX : e.touches[0].clientX;
618//     var diff = x - startX;
619//     trans = prev + (diff / track.offsetWidth) * 100;
620//     track.style.transform = "translateX(" + trans + "%)";
621//   }
622
623//   function handleEnd() {
624//     if (!drag) return;
625//     drag = false;
626//     track.classList.remove("chide_voice_dragging");
627//     var moved = trans - prev;
628//     if (moved < -10 && cur < slides.length - 1) cur++;
629//     else if (moved > 10 && cur > 0) cur--;
630//     update();
631//   }
632
633//   btnP.onclick = function() { if (cur > 0) { cur--; update(); } };
634//   btnN.onclick = function() { if (cur < slides.length - 1) { cur++; update(); } };
635  
636//   track.addEventListener("mousedown", handleStart);
637//   track.addEventListener("touchstart", handleStart);
638//   track.addEventListener("mousemove", handleMove);
639//   track.addEventListener("touchmove", handleMove);
640//   track.addEventListener("mouseup", handleEnd);
641//   track.addEventListener("touchend", handleEnd);
642//   track.addEventListener("mouseleave", handleEnd);
643//   track.addEventListener("dragstart", function(e) { e.preventDefault(); });
644
645//   createSlides();
646//   createPagination();
647//   update();
648// })();
649
650
651
652
653//pages nav
654(() => {
655document.addEventListener('DOMContentLoaded', () => {
656  const navBtn = document.getElementById('js_pagenav');
657  const navMenu = document.getElementById('js_pagenavMb');
658  const navClose = document.getElementById('js_pagenavClose');
659
660  if (!navBtn || !navMenu || !navClose) return;
661
662  // 開く
663  navBtn.addEventListener('click', (e) => {
664    e.preventDefault();
665    navMenu.classList.add('active');
666  });
667
668  // 閉じる
669  const closeMenu = () => navMenu.classList.remove('active');
670  navClose.addEventListener('click', (e) => {
671    e.preventDefault();
672    closeMenu();
673  });
674
675  // 背景タップで閉じる
676  navMenu.addEventListener('click', (e) => {
677    if (e.target === navMenu) closeMenu();
678  });
679
680  // &#x1f4cd;アンカーリンククリック時にモーダルを閉じる
681  const links = navMenu.querySelectorAll('a[href^="#"]');
682  links.forEach(link => {
683    link.addEventListener('click', (e) => {
684      closeMenu();
685      // スムーススクロール(任意)
686      const targetId = link.getAttribute('href');
687      if (targetId && targetId !== '#') {
688        const targetEl = document.querySelector(targetId);
689        if (targetEl) {
690          e.preventDefault();
691          const top = targetEl.getBoundingClientRect().top + window.pageYOffset;
692          window.scrollTo({
693            top,
694            behavior: 'smooth'
695          });
696        }
697      }
698    });
699  });
700});
701})();

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.