const { createContext, useContext, useState, useEffect, useRef } = React;

// ─── Palette: warm paper + ink + one considered blue ───
const K = {
  paper:  '#F5F4F1',
  paper2: '#EBE9E4',
  paper3: '#E2DFD8',
  ink:    '#12181F',
  ink70:  'rgba(18,24,31,0.70)',
  ink45:  'rgba(18,24,31,0.62)',
  ink12:  'rgba(18,24,31,0.12)',
  ink06:  'rgba(18,24,31,0.06)',
  blue:   '#1B4DE4',
  blueSoft:'#E8EDFD',
  white:  '#ffffff',
};

const V4Ctx = createContext({});
const useV4 = () => useContext(V4Ctx);
const V4_DEFAULTS = /*EDITMODE-BEGIN*/{
  "lang": "ko"
}/*EDITMODE-END*/;

function useInView(threshold = 0.12) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const o = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setSeen(true); o.disconnect(); } }, { threshold });
    o.observe(el); return () => o.disconnect();
  }, [threshold]);
  return [ref, seen];
}

function Rise({ children, delay = 0, y = 28, style = {} }) {
  const [ref, seen] = useInView(0.08);
  return (
    <div ref={ref} style={{
      ...style,
      opacity: seen ? 1 : 0,
      transform: seen ? 'none' : `translateY(${y}px)`,
      transition: `opacity .85s cubic-bezier(.16,1,.3,1) ${delay}s, transform .85s cubic-bezier(.16,1,.3,1) ${delay}s`,
    }}>{children}</div>
  );
}

// ─── Eyebrow: mono, tiny, tracked ───
function Eyebrow({ children, tone = 'blue' }) {
  return (
    <div className="mono" style={{
      fontSize: 11, fontWeight: 500, letterSpacing: '0.2em', textTransform: 'uppercase',
      color: tone === 'blue' ? K.blue : tone === 'light' ? 'rgba(255,255,255,0.72)' : K.ink45,
      display: 'flex', alignItems: 'center', gap: 10,
    }}>
      <span style={{ width: 18, height: 1, background: 'currentColor', opacity: .5 }}/>
      {children}
    </div>
  );
}

// ─── Display heading ───
function Display({ children, size = 'clamp(38px, 4.6vw, 68px)', color = K.ink, style = {} }) {
  return (
    <h2 style={{
      fontSize: size, fontWeight: 800, lineHeight: 1.04,
      letterSpacing: '-0.04em', color, textWrap: 'balance', ...style,
    }}>{children}</h2>
  );
}

// ─── Buttons ───
function Btn({ children, href = '#', onClick, tone = 'ink', size = 'md' }) {
  const [h, setH] = useState(false);
  const pad = size === 'lg' ? '18px 34px' : size === 'sm' ? '10px 18px' : '15px 28px';
  const fs = size === 'lg' ? 15 : size === 'sm' ? 12.5 : 14;
  const skin = {
    ink:   { bg: h ? K.blue : K.ink,  fg: '#fff',   bd: 'transparent' },
    blue:  { bg: h ? K.ink : K.blue,  fg: '#fff',   bd: 'transparent' },
    line:  { bg: h ? K.ink : 'transparent', fg: h ? '#fff' : K.ink, bd: K.ink },
    lineL: { bg: h ? '#fff' : 'transparent', fg: h ? K.ink : '#fff', bd: 'rgba(255,255,255,.4)' },
  }[tone];
  return (
    <a href={href} onClick={onClick}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 10, padding: pad,
        fontSize: fs, fontWeight: 700, letterSpacing: '-0.01em', whiteSpace: 'nowrap',
        background: skin.bg, color: skin.fg, border: `1.5px solid ${skin.bd}`,
        cursor: 'pointer', transition: 'all .32s cubic-bezier(.16,1,.3,1)',
      }}>
      {children}
      <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"
        style={{ transform: h ? 'translateX(4px)' : 'none', transition: 'transform .32s' }}>
        <path d="M5 12h14M12 5l7 7-7 7"/>
      </svg>
    </a>
  );
}

// ─── Count-up ───
function CountUp({ to, suffix = '', dur = 1800 }) {
  const [ref, seen] = useInView(0.4);
  const [n, setN] = useState(0);
  useEffect(() => {
    if (!seen) return;
    let t0 = 0;
    const step = ts => {
      if (!t0) t0 = ts;
      const p = Math.min((ts - t0) / dur, 1);
      setN(Math.round((1 - Math.pow(1 - p, 4)) * to));
      if (p < 1) requestAnimationFrame(step);
    };
    requestAnimationFrame(step);
  }, [seen, to, dur]);
  return <span ref={ref}>{n}{suffix}</span>;
}

// ─── Content ───
const V4_NAV = [
  { ko: '사업분야', en: 'Scope',   id: 'scope' },
  { ko: '제품·규격', en: 'Products', id: 'products' },
  { ko: '제작역량', en: 'Capability', id: 'capability' },
  { ko: '납기·자동화', en: 'Delivery', id: 'delivery' },
  { ko: '문의',     en: 'Contact', id: 'contact' },
];

const V4_TICKER = {
  ko: ['조립식 건물 부속자재', 'CNC선반 가공', '금형 · 프레스 가공', '용접 제작', '앵글 · 편철 가공', '자동화 생산', '납기 협의'],
  en: ['Prefab Building Parts', 'CNC Turning', 'Die & Press Work', 'Weld Fabrication', 'Angle & Flat Bar', 'Automated Line', 'Lead Time'],
};

// ╔══════════════════════════════════════════════════════════════════════╗
// ║  제품 카테고리 · 품목 — 태성ENG 단가표(2026) 기준                       ║
// ║                                                                      ║
// ║  사진 추가: 해당 품목의 images 배열에 경로만 넣으면 카탈로그·상세에      ║
// ║  자동 반영됩니다. hero 는 상세 대표 이미지(배경 없는 컷아웃 권장).       ║
// ║  pack = 박스/마대 입수량, fin = 표면처리. 값이 없으면 표시되지 않습니다. ║
// ╚══════════════════════════════════════════════════════════════════════╝
const V4_CATS = [
  { id: 'all',     ko: '전체',           en: 'All' },
  { id: 'roller',  ko: '로라 · 베어링',   en: 'Rollers' },
  { id: 'caster',  ko: '복차 · 주행부품', en: 'Casters' },
  { id: 'sb',      ko: 'S/B · 브라켓',   en: 'Stoppers & Brackets' },
  { id: 'door',    ko: '도어 부속',       en: 'Door Hardware' },
  { id: 'parts',   ko: '건축 부속자재',   en: 'Building Parts' },
  { id: 'fab',     ko: '가공 · 제작',     en: 'Fabrication' },
];

const V4_PRODUCTS = [
  // ── 로라 · 베어링 ──
  { cat:'roller', ko:'크랭크로라', en:'Crank Roller', size:'10', mat:'S/T · 나일론', matEn:'Steel · Nylon',
    fin:'아연도금', finEn:'Zinc plated', pack:'50입',
    desc:'컨베이어 라인 곡선 구간에 사용하는 소형 롤러입니다. 내마모성이 우수하고 경량 설계로 설치가 쉽습니다.',
    descEn:'Compact roller for conveyor curve sections. Wear-resistant with lightweight design.',
    hero:'products/crank-new-3.webp',
    images: [
      'products/crank-new-3.webp','products/crank-new-5.webp','products/crank-new-2.webp',
      'products/crank-new-4.webp','products/crank-new-1.webp',
    ], top:true },
  { cat:'roller', ko:'철크랭크로라', en:'Steel Crank Roller', size:'10', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'50입',
    desc:'크랭크로라의 강재 사양입니다. 하중이 큰 라인이나 내구성이 필요한 구간에 사용합니다.',
    descEn:'Steel version of the crank roller for higher loads and longer service life.',
    images:['products/steel-crank-1.webp','products/steel-crank-2.webp','products/steel-crank-3.webp'] },
  { cat:'roller', ko:'가이드로라', en:'Guide Roller', size:'10', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'100입',
    desc:'이송물의 주행을 안정적으로 잡아주는 가이드용 롤러입니다.',
    descEn:'Guide roller stabilising the travel of conveyed material.',
    images:['products/guide-1.webp','products/guide-2.webp','products/guide-3.webp'] },
  { cat:'roller', ko:'철가이드로라', en:'Steel Guide Roller', size:'10', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'100입',
    desc:'가이드로라의 강재 사양입니다. 측면 하중이 큰 구간에 사용합니다.',
    descEn:'Steel guide roller for sections with high lateral load.',
    images:['products/steel-guide-1.webp','products/steel-guide-2.webp','products/steel-guide-3.webp'] },
  { cat:'roller', ko:'나비로라', en:'Butterfly Roller', size:'10', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'12입',
    desc:'양쪽으로 벌어진 형상의 로라입니다. 이송물을 양방향에서 안내합니다.',
    descEn:'Twin-wing roller guiding material from both sides.',
    images:['products/butterfly-1.webp','products/butterfly-2.webp','products/butterfly-3.webp'] },
  { cat:'roller', ko:'하부로라', en:'Lower Roller', size:'50파이', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'12입',
    desc:'도어 하부 레일을 주행하는 로라입니다. Ø50 규격으로 제작합니다.',
    descEn:'Roller running on the lower door rail, Ø50.',
    images:['products/lower-roller-2.webp','products/lower-roller-1.webp','products/lower-roller-3.webp'] },
  { cat:'roller', ko:'하부베어링 (37파이)', en:'Lower Bearing · Ø37', size:'37파이', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'12입',
    desc:'하부 주행부의 축을 지지하는 베어링입니다. Ø37 규격으로, 장공 플레이트에 조립되어 공급됩니다.',
    descEn:'Bearing supporting the lower travel shaft, Ø37.',
    images:['products/lower-brg37-1.webp','products/lower-brg37-3.webp','products/lower-brg37-2.webp'] },
  { cat:'roller', ko:'하부베어링 (32파이)', en:'Lower Bearing · Ø32', size:'32파이', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'12입',
    desc:'하부 주행부의 축을 지지하는 베어링입니다. Ø32 규격으로, 장공 플레이트에 조립되어 공급됩니다.',
    descEn:'Bearing supporting the lower travel shaft, Ø32. Supplied assembled on a slotted plate.',
    images:['products/lower-brg32-2.webp','products/lower-brg32-1.webp','products/lower-brg32-3.webp'] },

  // ── 복차 · 주행부품 ──
  { cat:'caster', ko:'복차 (4발)', en:'Caster · 4-wheel', size:'37파이 / 45파이 / 60파이', mat:'S/T', matEn:'Steel',
    desc:'도어 상부 트랙을 주행하는 4륜 복차입니다. Ø37, Ø45, Ø60 세 가지 규격으로 제작하며, 부속 플레이트와 볼트가 함께 공급됩니다.',
    descEn:'Four-wheel trolley for the upper door track. Available in Ø37, Ø45 and Ø60.',
    images:['products/bokcha-4w-1.webp','products/bokcha-4w-2.webp','products/bokcha-2w-1.webp','products/bokcha-part.webp'], top:true },
  { cat:'caster', ko:'복차 (2발)', en:'Caster · 2-wheel', size:'37파이 / 45파이', mat:'S/T', matEn:'Steel',
    desc:'2륜 복차입니다. 경량 도어나 짧은 구간에 사용합니다. Ø37, Ø45 규격입니다.',
    descEn:'Two-wheel trolley for lighter doors and shorter spans. Ø37 and Ø45.',
    images:['products/bokcha-2w-new.webp'] },

  // ── S/B · 브라켓 ──
  { cat:'sb', ko:'상부 S/B', en:'Upper Stopper', size:'10', mat:'주물', matEn:'Cast iron', pack:'100입',
    desc:'도어 상부의 개폐 범위를 제한하는 주물 스톱바입니다.',
    descEn:'Cast-iron stopper limiting upper door travel.',
    images:['products/usb-a.webp','products/usb-b.webp','products/usb-c.webp'] },
  { cat:'sb', ko:'중간 S/B', en:'Middle Stopper', size:'10', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'100입',
    desc:'도어 중간 구간에 설치하는 스톱바입니다.',
    descEn:'Stopper installed at the mid-height of the door.',
    images:['products/msb-a.webp','products/msb-b.webp','products/msb-c.webp','products/msb-d.webp'] },
  { cat:'sb', ko:'상·중 겸용 S/B', en:'Upper/Middle Stopper', size:'10', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'150입',
    desc:'상부와 중간 어느 위치에나 쓸 수 있는 겸용 스톱바입니다.',
    descEn:'Stopper usable at either the upper or middle position.',
    images:['products/um-sb-1.webp','products/um-sb-2.webp','products/um-sb-3.webp','products/um-sb-4.webp'] },
  { cat:'sb', ko:'하부 S/B', en:'Lower Stopper', size:'10 / 삼각형', mat:'S/T · 주물', matEn:'Steel · Cast',
    fin:'아연도금', finEn:'Zinc plated', pack:'50~100입',
    desc:'도어 하부의 개폐 범위를 제한하는 스톱바입니다. 강재·주물, 일반형·삼각형으로 제작합니다.',
    descEn:'Lower door stopper in steel or cast iron, standard or triangular form.',
    images:['products/lower-sb-1.webp','products/lower-sb-2.webp'] },
  { cat:'sb', ko:'고무 S/B', en:'Rubber Stopper', size:'10', mat:'고무', matEn:'Rubber', pack:'300입',
    desc:'도어가 닫힐 때의 충격을 완화하는 고무 스톱바입니다. 볼트·와셔가 함께 공급됩니다.',
    descEn:'Rubber stopper absorbing impact when the door closes. Supplied with bolt and washer.',
    images:['products/rubber-sb-2.webp','products/rubber-sb-1.webp'] },
  { cat:'sb', ko:'복차 S/B', en:'Caster Stopper', size:'M트랙용', mat:'S/T', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'100입',
    desc:'M트랙에 설치하는 복차용 스톱바입니다. 주행 범위를 제한합니다.',
    descEn:'Stopper for M-track trolleys, limiting travel range.',
    images:['products/caster-sb-1.webp','products/caster-sb-2.webp','products/caster-sb-3.webp','products/caster-sb-4.webp'] },
  { cat:'sb', ko:'상부 B/K', en:'Upper Bracket', size:'75 / 50', mat:'주물', matEn:'Cast iron', pack:'50입',
    desc:'도어 상부를 트랙에 고정하는 주물 브라켓입니다. 75, 50 두 규격으로 제작합니다.',
    descEn:'Cast-iron bracket fixing the door to the upper track. Sizes 75 and 50.',
    images:['products/topbk75-1.webp','products/topbk75-3.webp','products/topbk75-2.webp','products/topbk-75.webp','products/topbk-50.webp','products/topbk-a.webp','products/topbk-b.webp'] },
  { cat:'sb', ko:'중간 B/K', en:'Middle Bracket', size:'10', mat:'주물', matEn:'Cast iron', pack:'50입',
    desc:'도어 중간부를 고정하는 주물 브라켓입니다.',
    descEn:'Cast-iron bracket fixing the mid-section of the door.',
    images:['products/midbk-2.webp','products/midbk-1.webp','products/midbk-3.webp','products/midbk-4.webp'] },

  // ── 도어 부속 ──
  { cat:'door', ko:'접빗장 양개 (구형)', en:'Folding Double Door · Legacy', size:'10', mat:'스틸', matEn:'Steel',
    fin:'아연도금', finEn:'Zinc plated', pack:'50입',
    desc:'접이식 양개 도어용 걸쇠입니다. 구형 사양으로, 받침 플레이트가 함께 공급됩니다.',
    descEn:'Hasp for folding double doors, legacy type. Supplied with the strike plate.',
    images:['products/fold-double-old-1.webp','products/fold-double-old-2.webp'] },
  { cat:'door', ko:'접빗장 양개 (신형)', en:'Folding Double Door · New', size:'10', mat:'SUS', matEn:'Stainless', pack:'50입',
    desc:'접이식 양개 도어용 걸쇠입니다. 스테인리스 신형 사양입니다.',
    descEn:'Hasp for folding double doors, new stainless type.',
    images:['products/fold-double-new-3.webp','products/fold-double-new-1.webp','products/fold-double-new-2.webp'] },
  { cat:'door', ko:'접빗장 편개', en:'Folding Single Door', size:'10', mat:'SUS', matEn:'Stainless', pack:'100입',
    desc:'접이식 편개 도어용 걸쇠입니다. 스테인리스 사양입니다.',
    descEn:'Hasp for folding single doors, stainless steel.',
    images:['products/fold-single-1.webp','products/fold-single-2.webp'] },
  { cat:'door', ko:'이지경첩', en:'Easy Hinge', size:'10', mat:'S/T', matEn:'Steel', pack:'120입',
    desc:'설치가 간편한 도어 경첩입니다.',
    descEn:'Door hinge designed for quick installation.',
    images:['products/hinge-c.webp','products/hinge-a.webp','products/hinge-b.webp'] },
  { cat:'door', ko:'인핸들', en:'Recessed Handle', size:'검정 / 아이보리', mat:'플라스틱', matEn:'Plastic', pack:'180입',
    desc:'도어 면에 매립하는 손잡이입니다. 검정과 아이보리 두 색으로 제작합니다.',
    descEn:'Flush-mounted door handle in black and ivory.',
    images:['products/ih-a.webp','products/ih-b.webp','products/ih-c.webp','products/ih-d.webp'] },
  { cat:'door', ko:'잡이쇠', en:'Latch Catch', size:'10', mat:'스틸', matEn:'Steel',
    fin:'분체도장', finEn:'Powder coated', pack:'47입',
    desc:'도어를 걸어 고정하는 잡이쇠입니다. 분체도장 마감입니다.',
    descEn:'Latch catch holding the door shut, powder-coated finish.',
    images:['products/latch-1.webp'] },

  // ── 건축 부속자재 ──
  { cat:'parts', ko:'지지대', en:'Support Post', size:'길이 맞춤', mat:'파이프 · 강판', matEn:'Pipe · Plate',
    fin:'아연도금', finEn:'Zinc plated',
    desc:'파이프에 베이스 플레이트를 용접한 지지대입니다. 현장 높이에 맞춰 길이를 맞춤 제작합니다.',
    descEn:'Pipe post welded to a base plate. Length made to your site height.',
    images:['products/support-a.webp','products/support-b.webp','products/support-c.webp'] },
  { cat:'parts', ko:'삼각대', en:'Triangle Support', size:'2T 300×800', mat:'S/T', matEn:'Steel',
    fin:'분체도장', finEn:'Powder coated', pack:'파렛트 300입',
    desc:'2T 강판을 300×800 규격으로 성형한 삼각 지지대입니다. 분체도장 마감으로 출하합니다.',
    descEn:'Triangular support formed from 2T steel plate, 300×800, powder-coated.',
    images:['products/tripod-a.webp','products/tripod-b.webp'] },
  { cat:'parts', ko:'물모음집', en:'Water Collector', size:'150 / 120 / 100 / 75', mat:'스틸', matEn:'Steel',
    fin:'분체도장', finEn:'Powder coated', pack:'12입',
    desc:'지붕이나 벽면의 물을 모아 배수로 보내는 부품입니다. 150, 120, 100, 75 네 규격으로 제작합니다.',
    descEn:'Collects roof or wall runoff into the drain line. Sizes 150, 120, 100 and 75.',
    images:['products/wc-a.webp','products/wc-b.webp','products/wc-c.webp'] },
  { cat:'parts', ko:'양날 가스켓', en:'Double-edge Gasket', size:'23 (1M)', mat:'고무', matEn:'Rubber',
    desc:'양쪽에 날이 있는 기밀용 가스켓입니다. 1M 단위로 공급합니다.',
    descEn:'Sealing gasket with edges on both sides, supplied per metre.',
    images:['products/gasket-double-1.webp'] },
  { cat:'parts', ko:'외날 가스켓', en:'Single-edge Gasket', size:'23 (1M)', mat:'고무', matEn:'Rubber',
    desc:'한쪽에 날이 있는 기밀용 가스켓입니다. 1M 단위로 공급합니다.',
    descEn:'Sealing gasket with a single edge, supplied per metre.',
    images:['products/gasket-single-1.webp'] },
  { cat:'parts', ko:'코너포인트', en:'Corner Point', size:'대 / 소', mat:'알루미늄', matEn:'Aluminium', pack:'1,000~2,000입',
    desc:'패널 모서리를 마감하는 알루미늄 부품입니다. 대·소 두 규격입니다.',
    descEn:'Aluminium trim finishing panel corners, large and small.',
    images:['products/corner-a.webp','products/corner-b.webp','products/corner-c.webp','products/corner-d.webp'] },
  // ⚠ 품명 확인 필요 — 단가표 원본의 판독 메모에 '통상적인 품명인지 확인 권장'으로 표시된 항목입니다.
  //   정확한 품명이 확인되면 ko/en 과 설명을 교체하세요.
  { cat:'parts', ko:'아교도시', en:'아교도시', size:'10', mat:'주물', matEn:'Cast iron', pack:'100입',
    images:['products/agyo-1.webp','products/agdosi-new.webp'] },

  // ── 가공 · 제작 ──
  { cat:'fab', ko:'평철 · 앵글 가공', en:'Flat Bar & Angle Work', size:'도면 기준', mat:'평철 · 앵글', matEn:'Flat bar · Angle',
    desc:'평철과 앵글의 절단, 절곡, 천공, 용접 가공을 의뢰받아 진행합니다. 도면 또는 실물 치수로 상담합니다.',
    descEn:'Cutting, bending, drilling and welding of flat bar and angle to your drawing.',
    images:['products/fab-1.webp','products/fab-2.webp','products/fab-3.webp','products/fab-4.webp','products/fab-5.webp','products/fab-6.webp','products/fab-7.webp','products/fab-8.webp'] },
  { cat:'fab', ko:'이형 제작', en:'Custom Fabrication', size:'주문 제작', mat:'문의', matEn:'By request',
    fin:'분체도장', finEn:'Powder coated',
    desc:'표준 규격에 없는 형상과 치수를 도면 기준으로 제작합니다. 물류비는 별도입니다.',
    descEn:'Non-standard shapes and dimensions built to drawing. Freight charged separately.',
    images:['products/fab-5.webp','products/fab-6.webp','products/fab-7.webp','products/fab-8.webp','products/fab-1.webp','products/fab-2.webp','products/fab-3.webp','products/fab-4.webp'] },
];

const V4_CAPABILITY = [
  { n:'01', ko:'조립식 건물 부속자재', en:'Prefab Building Parts',
    ko2:'브라켓, 롤러, 체결 부품 등 현장 조건에 맞춰 제작합니다.',
    en2:'Brackets, rollers and fasteners made to site conditions.' },
  { n:'02', ko:'정밀 CNC선반 가공', en:'Precision CNC Turning',
    ko2:'반복 정밀 가공이 필요한 금속 부품을 안정된 품질로 대응합니다.',
    en2:'Repeatable precision parts with stable quality and schedule.' },
  { n:'03', ko:'금형 · 프레스 가공', en:'Die & Press Work',
    ko2:'형상과 수량에 맞춘 금형 설계와 프레스 가공을 진행합니다.',
    en2:'Die design and press work matched to shape and volume.' },
  { n:'04', ko:'용접 제작 · 조립', en:'Weld Fabrication & Assembly',
    ko2:'구조 보조 부품과 부자재를 용접부터 조립까지 대응합니다.',
    en2:'From weld fabrication through to assembly, handled in one place.' },
];

Object.assign(window, {
  K, V4Ctx, useV4, V4_DEFAULTS, useInView, Rise, Eyebrow, Display, Btn, CountUp,
  V4_NAV, V4_TICKER, V4_CATS, V4_PRODUCTS, V4_CAPABILITY,
});
