var/cache/dev/twig/48/4829d16cb8101c689e48e9c3a59ec7b9b502fbcc0286b35bce2ce8d6c3aedd05.php line 53

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\SandboxExtension;
  6. use Twig\Markup;
  7. use Twig\Sandbox\SecurityError;
  8. use Twig\Sandbox\SecurityNotAllowedTagError;
  9. use Twig\Sandbox\SecurityNotAllowedFilterError;
  10. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  11. use Twig\Source;
  12. use Twig\Template;
  13. /* Product/detail.twig */
  14. class __TwigTemplate_522d4049f4ae861cebe3e9e156fd17afe8d625ccd0fcb5d23594920e6cac048b extends \Eccube\Twig\Template
  15. {
  16.     private $source;
  17.     private $macros = [];
  18.     public function __construct(Environment $env)
  19.     {
  20.         parent::__construct($env);
  21.         $this->source $this->getSourceContext();
  22.         $this->blocks = [
  23.             'stylesheet' => [$this'block_stylesheet'],
  24.             'javascript' => [$this'block_javascript'],
  25.             'main' => [$this'block_main'],
  26.         ];
  27.     }
  28.     protected function doGetParent(array $context)
  29.     {
  30.         // line 11
  31.         return "default_frame.twig";
  32.     }
  33.     protected function doDisplay(array $context, array $blocks = [])
  34.     {
  35.         $macros $this->macros;
  36.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  37.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/detail.twig"));
  38.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  39.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/detail.twig"));
  40.         // line 13
  41.         $context["body_class"] = "product_page";
  42.         // line 11
  43.         $this->parent $this->loadTemplate("default_frame.twig""Product/detail.twig"11);
  44.         $this->parent->display($contextarray_merge($this->blocks$blocks));
  45.         
  46.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  47.         
  48.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  49.     }
  50.     // line 15
  51.     public function block_stylesheet($context, array $blocks = [])
  52.     {
  53.         $macros $this->macros;
  54.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  55.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  56.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  57.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  58.         // line 16
  59.         echo "    <style>
  60.         .slick-slider {
  61.             margin-bottom: 10px;
  62. \t\t\tmargin-top: -20px;
  63.         }
  64.         .slick-dots {
  65.             position: absolute;
  66.             bottom: -45px;
  67.             display: block;
  68.             width: 100%;
  69.             padding: 0;
  70.             list-style: none;
  71.             text-align: center;
  72.         }
  73.         .slick-dots li {
  74.             position: relative;
  75.             display: inline-block;
  76.             width: 20px;
  77.             height: 20px;
  78.             margin: 0 5px;
  79.             padding: 0;
  80.             cursor: pointer;
  81.         }
  82.         .slick-dots li button {
  83.             font-size: 0;
  84.             line-height: 0;
  85.             display: block;
  86.             width: 20px;
  87.             height: 20px;
  88.             padding: 5px;
  89.             cursor: pointer;
  90.             color: transparent;
  91.             border: 0;
  92.             outline: none;
  93.             background: transparent;
  94.         }
  95.         .slick-dots li button:hover,
  96.         .slick-dots li button:focus {
  97.             outline: none;
  98.         }
  99.         .slick-dots li button:hover:before,
  100.         .slick-dots li button:focus:before {
  101.             opacity: 1;
  102.         }
  103.         .slick-dots li button:before {
  104.             content: \" \";
  105.             line-height: 20px;
  106.             position: absolute;
  107.             top: 0;
  108.             left: 0;
  109.             width: 12px;
  110.             height: 12px;
  111.             text-align: center;
  112.             opacity: .25;
  113.             background-color: black;
  114.             border-radius: 50%;
  115.         }
  116.         .slick-dots li.slick-active button:before {
  117.             opacity: .75;
  118.             background-color: black;
  119.         }
  120.         .slick-dots li button.thumbnail img {
  121.             width: 0;
  122.             height: 0;
  123.         }
  124.     </style>
  125.     <link rel=\"stylesheet\" href=\"/html/user_data/js/style.css\">
  126.     <link rel=\"stylesheet\" href=\"/html/plugins/icheck-bootstrap/icheck-bootstrap.min.css\">
  127.     <style>
  128.         /* Show zoom cursor on product images to hint click-to-expand */
  129.         .item_visual .slide-item a { display: block; cursor: zoom-in; }
  130.     </style>
  131.     <style>
  132.         /* ============================================
  133.            商品詳細グリッド: 画像50% / 内容50%(均等)
  134.         ============================================ */
  135.         @media (min-width: 768px) {
  136.             body.product_page .ec-grid2 {
  137.                 display: flex;
  138.                 align-items: flex-start;
  139.             }
  140.             body.product_page .ec-grid2 .ec-grid2__cell {
  141.                 width: 50%;
  142.                 flex: 0 0 50%;
  143.                 min-width: 0;
  144.             }
  145.             body.product_page .ec-grid2 .ec-grid2__cell2 {
  146.                 width: 50%;
  147.                 flex: 0 0 50%;
  148.                 min-width: 0;
  149.             }
  150.         }
  151.         /* ============================================
  152.            商品説明欄内のHTMLが画面幅を突き抜けないように
  153.         ============================================ */
  154.         body.product_page .ec-productRole__description {
  155.             min-width: 0;
  156.             overflow-wrap: break-word;
  157.             word-break: break-word;
  158.         }
  159.         body.product_page .ec-productRole__description img,
  160.         body.product_page .ec-productRole__description table,
  161.         body.product_page .ec-productRole__description iframe,
  162.         body.product_page .ec-productRole__description video {
  163.             max-width: 100% !important;
  164.             height: auto;
  165.         }
  166.         body.product_page .ec-productRole__description table {
  167.             display: block;
  168.             overflow-x: auto;
  169.             -webkit-overflow-scrolling: touch;
  170.         }
  171.         /* ============================================
  172.            構成セット内容 (機能門柱など、セット構成を持つ商品)
  173.         ============================================ */
  174.         body.product_page .ec-productRole__setItems {
  175.             min-width: 0;
  176.             margin-bottom: 16px;
  177.         }
  178.         body.product_page .ec-productRole__setItems .set-items-table {
  179.             width: 100%;
  180.             border-collapse: collapse;
  181.             table-layout: fixed;
  182.         }
  183.         body.product_page .ec-productRole__setItems .set-items-table th,
  184.         body.product_page .ec-productRole__setItems .set-items-table td {
  185.             padding: 8px 4px;
  186.             border-bottom: 1px solid #e8e8e8;
  187.             font-size: 14px;
  188.             font-weight: normal;
  189.             overflow-wrap: break-word;
  190.             word-break: break-word;
  191.             vertical-align: top;
  192.         }
  193.         body.product_page .ec-productRole__setItems .set-items-table th {
  194.             text-align: left;
  195.         }
  196.         body.product_page .ec-productRole__setItems .set-items-table td {
  197.             text-align: right;
  198.             white-space: nowrap;
  199.             width: 30%;
  200.         }
  201.         body.product_page .ec-productRole__setItems .set-items-table tfoot th,
  202.         body.product_page .ec-productRole__setItems .set-items-table tfoot td {
  203.             border-top: 2px solid #333;
  204.             border-bottom: none;
  205.             font-weight: bold;
  206.         }
  207.         /* ============================================
  208.            スマホ用 見積金額 下部固定バー
  209.         ============================================ */
  210.         #sp-mitsumori-bar {
  211.             display: none;
  212.         }
  213.         /* ============================================
  214.            スマホ用 お見積りの詳細 ボトムシート
  215.         ============================================ */
  216.         .sp-detail-sheet { display: none; }
  217.         .sp-detail-sheet.is-open {
  218.             display: block;
  219.             position: fixed;
  220.             top: 0; left: 0; right: 0; bottom: 0;
  221.             z-index: 2000;
  222.         }
  223.         .sp-detail-sheet__overlay {
  224.             position: absolute;
  225.             top: 0; left: 0; right: 0; bottom: 0;
  226.             background: rgba(0,0,0,0.45);
  227.         }
  228.         .sp-detail-sheet__panel {
  229.             position: absolute;
  230.             left: 0; right: 0; bottom: 0;
  231.             background: #fff;
  232.             border-radius: 14px 14px 0 0;
  233.             max-height: 82vh;
  234.             display: flex;
  235.             flex-direction: column;
  236.             box-shadow: 0 -4px 20px rgba(0,0,0,0.25);
  237.             padding-bottom: env(safe-area-inset-bottom);
  238.             animation: spSheetUp 0.22s ease-out;
  239.         }
  240.         @keyframes spSheetUp {
  241.             from { transform: translateY(100%); }
  242.             to   { transform: translateY(0); }
  243.         }
  244.         .sp-detail-sheet__header {
  245.             display: flex;
  246.             align-items: center;
  247.             justify-content: space-between;
  248.             padding: 14px 16px;
  249.             border-bottom: 1px solid #eee;
  250.             flex: 0 0 auto;
  251.         }
  252.         .sp-detail-sheet__title { font-size: 16px; font-weight: bold; color: #333; }
  253.         .sp-detail-sheet__close {
  254.             background: none;
  255.             border: none;
  256.             font-size: 26px;
  257.             line-height: 1;
  258.             color: #888;
  259.             cursor: pointer;
  260.             padding: 0 4px;
  261.         }
  262.         .sp-detail-sheet__body {
  263.             overflow-y: auto;
  264.             -webkit-overflow-scrolling: touch;
  265.             padding: 4px 0;
  266.             flex: 1 1 auto;
  267.         }
  268.         .sp-detail-sheet__body ul { list-style: none; margin: 0; padding: 0; }
  269.         .sp-detail-sheet__body li { border-bottom: 1px solid #f2f2f2; }
  270.         .sp-detail-sheet__body .nav-link {
  271.             display: flex;
  272.             align-items: center;
  273.             justify-content: space-between;
  274.             padding: 12px 16px;
  275.             color: #333;
  276.             font-size: 14px;
  277.         }
  278.         .sp-detail-sheet__body .nav-link .float-right {
  279.             float: none !important;
  280.             font-weight: bold;
  281.             white-space: nowrap;
  282.             margin-left: auto;
  283.         }
  284.         .sp-detail-sheet__footer {
  285.             display: flex;
  286.             gap: 8px;
  287.             padding: 12px 16px 16px;
  288.             border-top: 1px solid #eee;
  289.             flex: 0 0 auto;
  290.         }
  291.         .sp-detail-sheet__footer button {
  292.             flex: 1 1 auto;
  293.             padding: 12px;
  294.             border-radius: 8px;
  295.             font-size: 14px;
  296.             font-weight: bold;
  297.             cursor: pointer;
  298.         }
  299.         .sp-detail-sheet__invoice {
  300.             background: #fff;
  301.             border: 1px solid #17a2b8;
  302.             color: #17a2b8;
  303.         }
  304.         .sp-detail-sheet__cart {
  305.             background: #c00;
  306.             border: 1px solid #c00;
  307.             color: #fff;
  308.         }
  309.         /* ============================================
  310.            商品タイプ選択 共通スタイル
  311.         ============================================ */
  312.         /* セクションラベル */
  313.         .rp-section-label {
  314.             font-size: 14px;
  315.             font-weight: bold;
  316.             color: #333;
  317.             margin-bottom: 10px;
  318.         }
  319.         .rp-section-label span {
  320.             font-weight: normal;
  321.             color: #c00;
  322.         }
  323.         /* ---- 1. 画像付きカード ---- */
  324.         .rp-card-group {
  325.             display: flex;
  326.             flex-wrap: wrap;
  327.             gap: 8px;
  328.             margin-bottom: 4px;
  329.         }
  330.         .rp-card {
  331.             position: relative;
  332.             cursor: pointer;
  333.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  334.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  335.             /* iOS Safari: prevent the first tap from being consumed as a text
  336.                selection (\"字だけ青くなる\" = selection highlight) which forced a
  337.                2nd tap to actually switch the option (#15). */
  338.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  339.             -webkit-touch-callout: none;
  340.             width: 110px;
  341.             border: 2px solid #ddd;
  342.             border-radius: 10px;
  343.             overflow: hidden;
  344.             transition: border-color 0.2s, box-shadow 0.2s;
  345.             background: #fff;
  346.             text-decoration: none;
  347.             color: #333;
  348.             display: block;
  349.         }
  350.         /* Gate :hover behind real hover-capable pointers. On iOS Safari a
  351.            :hover rule that changes appearance makes the first tap apply the
  352.            hover state and suppresses the click, so the option chip needed a
  353.            second tap to fire its onclick (is-selected + price update). */
  354.         @media (hover: hover) and (pointer: fine) {
  355.             .rp-card:hover {
  356.                 border-color: #999;
  357.                 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  358.             }
  359.         }
  360.         .rp-card.is-selected {
  361.             border-color: #1a6fcf;
  362.             box-shadow: 0 2px 10px rgba(26,111,207,0.25);
  363.         }
  364.         /* visually-hidden instead of display:none. A label wrapping a
  365.            display:none radio fires its tap unreliably on iOS Safari (first tap
  366.            often ignored -> \"2回タッチ\"). Keeping the input in the layout but
  367.            invisible makes the first tap register. */
  368.         .rp-card input[type=\"radio\"] {
  369.             position: absolute; opacity: 0; width: 1px; height: 1px;
  370.             margin: 0; pointer-events: none;
  371.         }
  372.         .rp-card__image {
  373.             width: 100%;
  374.             aspect-ratio: 1 / 1;
  375.             object-fit: cover;
  376.             display: block;
  377.             background: #f5f5f5;
  378.         }
  379.         .rp-card__placeholder {
  380.             width: 100%;
  381.             aspect-ratio: 1 / 1;
  382.             background: #f0f0f0;
  383.             display: flex;
  384.             align-items: center;
  385.             justify-content: center;
  386.             color: #bbb;
  387.             font-size: 24px;
  388.         }
  389.         .rp-card__name {
  390.             display: block;
  391.             padding: 5px 5px;
  392.             font-size: 11px;
  393.             color: #333;
  394.             text-align: center;
  395.             line-height: 1.4;
  396.             word-break: break-all;
  397.         }
  398.         .rp-card.is-selected .rp-card__name { color: #1a6fcf; font-weight: bold; }
  399.         .rp-card.is-selected::after {
  400.             content: \"✓\";
  401.             position: absolute;
  402.             top: 3px; right: 6px;
  403.             color: #1a6fcf;
  404.             font-size: 13px;
  405.             font-weight: bold;
  406.         }
  407.         /* ---- 2. ボタン式ラジオ(画像なし・8個以内)---- */
  408.         .rp-btn-group {
  409.             display: flex;
  410.             flex-wrap: wrap;
  411.             gap: 8px;
  412.             margin-bottom: 4px;
  413.             max-width: 100%;
  414.             min-width: 0;
  415.         }
  416.         .rp-btn {
  417.             cursor: pointer;
  418.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  419.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  420.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  421.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  422.             -webkit-touch-callout: none;
  423.             padding: 8px 14px;
  424.             border: 2px solid #ddd;
  425.             border-radius: 10px;
  426.             font-size: 13px;
  427.             color: #333;
  428.             background: #fff;
  429.             transition: border-color 0.2s, background 0.2s;
  430.             white-space: normal;
  431.             max-width: 100%;
  432.             overflow-wrap: anywhere;
  433.             text-decoration: none;
  434.         }
  435.         @media (hover: hover) and (pointer: fine) {
  436.             .rp-btn:hover { border-color: #999; }
  437.         }
  438.         .rp-btn.is-selected {
  439.             border-color: #1a6fcf;
  440.             color: #1a6fcf;
  441.             font-weight: bold;
  442.             background: #f0f6ff;
  443.         }
  444.         .rp-btn input[type=\"radio\"] {
  445.             position: absolute; opacity: 0; width: 1px; height: 1px;
  446.             margin: 0; pointer-events: none;
  447.         }
  448.         /* iOS Safari \"2回タッチ\" fix for the type-selection link chips.
  449.            The global theme stylesheet ships an ungated `a:hover{color:#296292}`
  450.            (paired with `a{color:#337ab7;text-decoration:underline}`). Because
  451.            .rp-btn / .rp-card are real <a> links, iOS Safari applies that hover
  452.            colour on the FIRST tap — the chip text turns blue (#296292, the
  453.            reported \"字だけ青くなる\") — and treats the tap as a hover, swallowing
  454.            the navigation so a 2nd tap was needed. The local .rp-*:hover rules
  455.            are already gated behind (hover:hover), but this inherited global
  456.            rule was not. Pin the hover/active colour to the base/selected colour
  457.            so tapping produces no visual change and the first tap navigates
  458.            immediately. Higher specificity (0,2,0 / 0,3,0) overrides a:hover. */
  459.         .rp-btn:hover,
  460.         .rp-btn:active { color: #333; text-decoration: none; }
  461.         .rp-btn.is-selected:hover,
  462.         .rp-btn.is-selected:active { color: #1a6fcf; text-decoration: none; }
  463.         .rp-card:hover,
  464.         .rp-card:active { color: #333; text-decoration: none; }
  465.         .rp-card:hover .rp-card__name,
  466.         .rp-card:active .rp-card__name { color: #333; }
  467.         .rp-card.is-selected:hover .rp-card__name,
  468.         .rp-card.is-selected:active .rp-card__name { color: #1a6fcf; }
  469.         /* ---- 選択肢が多い場合: 縦3段に収めて横スクロール(顧客要望「3列くらいで横スクロール」)---- */
  470.         /* grid-auto-flow:column + 3行固定 → 選択肢が縦に最大3段、超過分は右へ伸び横スクロールで閲覧 */
  471.         .rp-btn-group.is-scroll,
  472.         .opt-btn-group.is-scroll {
  473.             display: grid;
  474.             grid-auto-flow: column;
  475.             grid-template-rows: repeat(3, auto);
  476.             grid-auto-columns: max-content;
  477.             justify-content: start;
  478.             align-items: start;
  479.             gap: 8px;
  480.             overflow-x: auto;
  481.             overflow-y: hidden;
  482.             -webkit-overflow-scrolling: touch;
  483.             scrollbar-width: thin;
  484.             /* 上下に余白を確保して、行の枠線が overflow クリップ/スクロールバーに
  485.                切り取られないようにする(「文字列が長いと下枠が消える」対策)。 */
  486.             padding: 2px 0 12px;
  487.         }
  488.         /* is-scroll(横スクロール)内では選択肢を折り返さず単一行に固定する。
  489.            折り返すと行高が不揃いになり overflow-y:hidden で下枠が切れるため、
  490.            長い選択肢は折り返さず横スクロールで見せる(本来の設計意図)。 */
  491.         .rp-btn-group.is-scroll .rp-btn,
  492.         .rp-btn-group.is-scroll .opt-btn,
  493.         .opt-btn-group.is-scroll .rp-btn,
  494.         .opt-btn-group.is-scroll .opt-btn {
  495.             white-space: nowrap;
  496.             word-break: normal;
  497.             overflow-wrap: normal;
  498.         }
  499.         /* ただし画像付き選択肢(カラースウォッチ等)は max-width で幅が固定されるため、
  500.            nowrap にすると名称がボックス外へはみ出して隣の選択肢と重なる。
  501.            画像付きは常に折り返し可(名称は画像の下に収める)。 */
  502.         .rp-btn-group.is-scroll .opt-btn--with-image,
  503.         .opt-btn-group.is-scroll .opt-btn--with-image,
  504.         .rp-btn-group.is-scroll .opt-btn--with-image .opt-btn__name,
  505.         .opt-btn-group.is-scroll .opt-btn--with-image .opt-btn__name {
  506.             white-space: normal;
  507.             word-break: break-word;
  508.             overflow-wrap: anywhere;
  509.         }
  510.         .rp-btn-group.is-scroll::-webkit-scrollbar,
  511.         .opt-btn-group.is-scroll::-webkit-scrollbar {
  512.             height: 6px;
  513.         }
  514.         .rp-btn-group.is-scroll::-webkit-scrollbar-thumb,
  515.         .opt-btn-group.is-scroll::-webkit-scrollbar-thumb {
  516.             background: #c0c0c0;
  517.             border-radius: 3px;
  518.         }
  519.         /* ---- 3. プルダウン(画像なし・9個以上)---- */
  520.         .rp-select-wrap {
  521.             margin-bottom: 4px;
  522.         }
  523.         .rp-select {
  524.             width: 100%;
  525.             max-width: 420px;
  526.             padding: 8px 12px;
  527.             border: 2px solid #ddd;
  528.             border-radius: 10px;
  529.             font-size: 13px;
  530.             color: #333;
  531.             background: #fff;
  532.             appearance: none;
  533.             background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E\");
  534.             background-repeat: no-repeat;
  535.             background-position: right 12px center;
  536.             cursor: pointer;
  537.         }
  538.         .rp-select:focus {
  539.             outline: none;
  540.             border-color: #1a6fcf;
  541.         }
  542.         /* ---- オプション選択ボタン(枠線ラジオ)---- */
  543.         .opt-btn-group {
  544.             display: flex;
  545.             flex-wrap: wrap;
  546.             gap: 8px;
  547.             padding: 6px 0;
  548.             max-width: 100%;
  549.             min-width: 0;
  550.         }
  551.         .opt-btn {
  552.             cursor: pointer;
  553.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  554.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  555.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  556.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  557.             -webkit-touch-callout: none;
  558.             padding: 7px 14px;
  559.             border: 2px solid #ddd;
  560.             border-radius: 10px;
  561.             font-size: 13px;
  562.             color: #333;
  563.             background: #fff;
  564.             transition: border-color 0.2s, background 0.2s;
  565.             white-space: normal;
  566.             max-width: 100%;
  567.             overflow-wrap: anywhere;
  568.             text-decoration: none;
  569.         }
  570.         @media (hover: hover) and (pointer: fine) {
  571.             .opt-btn:hover { border-color: #999; }
  572.         }
  573.         .opt-btn.is-selected {
  574.             border-color: #1a6fcf;
  575.             color: #1a6fcf;
  576.             font-weight: bold;
  577.             background: #f0f6ff;
  578.         }
  579.         .opt-btn input[type=\"radio\"] {
  580.             position: absolute; opacity: 0; width: 1px; height: 1px;
  581.             margin: 0; pointer-events: none;
  582.         }
  583.         /* opt-btn with color swatch image. The label still works as a
  584.            radio target — clicking the image checks the input. The text
  585.            label stays under the image so users can still read the name. */
  586.         .opt-btn--with-image {
  587.             padding: 4px 6px 6px;
  588.             white-space: normal;
  589.             text-align: center;
  590.             display: inline-flex;
  591.             flex-direction: column;
  592.             align-items: center;
  593.             min-width: 96px;
  594.             max-width: 140px;
  595.         }
  596.         .opt-btn--with-image .opt-btn__img {
  597.             display: block;
  598.             width: 88px;
  599.             height: 66px;
  600.             object-fit: cover;
  601.             border-radius: 6px;
  602.             margin-bottom: 4px;
  603.             background: #f5f5f5;
  604.         }
  605.         .opt-btn--with-image .opt-btn__name {
  606.             display: block;
  607.             font-size: 11px;
  608.             line-height: 1.3;
  609.             color: inherit;
  610.         }
  611.         .opt-btn--with-image.is-selected .opt-btn__img {
  612.             outline: 2px solid #1a6fcf;
  613.             outline-offset: 1px;
  614.         }
  615.         /* sale_type=2 (内窓) 補助金対象ガラスの強調表示.
  616.            補助金が出る性能区分 (真空断熱 / Low-E複層 等) のガラス選択肢に
  617.            緑枠 + 「補助金対象」バッジを付け、選択前から判別できるようにする。 */
  618.         .opt-btn--subsidy {
  619.             border-color: #2e7d32;
  620.         }
  621.         .opt-btn--subsidy.is-selected {
  622.             border-color: #1a6fcf;
  623.         }
  624.         .opt-btn__subsidy-badge {
  625.             display: inline-block;
  626.             margin-left: 6px;
  627.             padding: 1px 6px;
  628.             border-radius: 6px;
  629.             background: #2e7d32;
  630.             color: #fff;
  631.             font-size: 11px;
  632.             font-weight: bold;
  633.             white-space: nowrap;
  634.         }
  635.         /* 補助金額・適用可否の強調 (顧客要望: もっと目立つ色とフォントに).
  636.            各窓の補助金額は緑・太字・拡大、適用条件ノートは緑の枠付きボックスにする。 */
  637.         .wt-subsidy-label {
  638.             color: #2e7d32;
  639.             font-weight: bold;
  640.             font-size: 12px;
  641.         }
  642.         .wt-subsidy-amount {
  643.             color: #2e7d32;
  644.             font-weight: bold;
  645.             font-size: 18px;
  646.             line-height: 1.2;
  647.         }
  648.         .subsidy-eligibility-note {
  649.             color: #1b5e20;
  650.             font-weight: bold;
  651.             font-size: 12.5px;
  652.             line-height: 1.5;
  653.             background: #eafaf0;
  654.             border: 1px solid #b7e4c7;
  655.             border-radius: 6px;
  656.             padding: 8px 10px;
  657.             margin-bottom: 10px;
  658.         }
  659.         .subsidy-eligibility-note strong {
  660.             color: #c0392b;  /* 「合計が5万円以上」を赤で強調 */
  661.         }
  662.         /* ============================================
  663.            施工エリア案内
  664.         ============================================ */
  665.         .ec-areaNotice {
  666.             margin: 16px 0;
  667.             padding: 16px 20px;
  668.             background: #f8f9fa;
  669.             border-left: 4px solid #1a6fcf;
  670.             border-radius: 0 8px 8px 0;
  671.         }
  672.         .ec-areaNotice__inner {
  673.             display: flex;
  674.             align-items: flex-start;
  675.             gap: 12px;
  676.         }
  677.         .ec-areaNotice__icon {
  678.             font-size: 22px;
  679.             line-height: 1;
  680.             flex-shrink: 0;
  681.             margin-top: 2px;
  682.         }
  683.         .ec-areaNotice__body {
  684.             flex: 1;
  685.         }
  686.         .ec-areaNotice__title {
  687.             font-size: 13px;
  688.             font-weight: bold;
  689.             color: #1a6fcf;
  690.             margin: 0 0 6px;
  691.         }
  692.         .ec-areaNotice__text {
  693.             font-size: 13px;
  694.             color: #444;
  695.             line-height: 1.7;
  696.             margin: 0;
  697.         }
  698.         .ec-areaNotice__text strong {
  699.             color: #222;
  700.         }
  701.         .ec-areaNotice__link {
  702.             display: inline-block;
  703.             margin-top: 8px;
  704.             font-size: 12px;
  705.             color: #1a6fcf;
  706.             text-decoration: underline;
  707.         }
  708.         .ec-areaNotice__link:hover {
  709.             color: #0d4fa0;
  710.         }
  711.         /* ============================================
  712.            SNSシェア + ブランド名 タイトル行
  713.         ============================================ */
  714.         .ec-productRole__titleRow {
  715.             display: flex;
  716.             align-items: center;
  717.             justify-content: space-between;
  718.             gap: 8px;
  719.             margin-bottom: 4px;
  720.         }
  721.         .ec-productRole__titleRow .ec-headingTitle {
  722.             margin: 0;
  723.             flex: 1;
  724.             font-size: 18px;
  725.         }
  726.         .ec-share-inline {
  727.             display: flex;
  728.             align-items: center;
  729.             gap: 8px;
  730.             flex-shrink: 0;
  731.         }
  732.         @media (max-width: 767px) {
  733.             /* maker_area の float を解除して独立表示 */
  734.             #maker_area {
  735.                 float: none !important;
  736.                 width: auto !important;
  737.                 height: auto !important;
  738.                 display: block;
  739.                 margin-bottom: 4px;
  740.             }
  741.             /* タイトル行: 商品名が全幅を占有しSNSは右寄せ下段 */
  742.             .ec-productRole__titleRow {
  743.                 flex-wrap: wrap;
  744.                 clear: both;
  745.             }
  746.             .ec-productRole__titleRow .ec-headingTitle {
  747.                 flex: 1 1 100%;
  748.                 font-size: 16px;
  749.             }
  750.             .ec-share-inline {
  751.                 flex: 0 0 auto;
  752.                 margin-left: auto;
  753.             }
  754.         }
  755.         .ec-share-inline a {
  756.             display: flex;
  757.             align-items: center;
  758.             justify-content: center;
  759.             width: 32px;
  760.             height: 32px;
  761.             border-radius: 50%;
  762.             font-size: 15px;
  763.             color: #fff;
  764.             text-decoration: none;
  765.             transition: opacity 0.2s;
  766.         }
  767.         .ec-share-inline a:hover { opacity: 0.8; }
  768.         .ec-share-inline .share-twitter  { background: #000; }
  769.         .ec-share-inline .share-facebook { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
  770.         .ec-share-inline .share-line     { background: #06c755; }
  771.         /* description_detail下のシェアブロックはPC/スマホ共通で非表示(タイトル行に移動) */
  772.         .ec-productRole__share { display: none; }
  773.         /* ============================================
  774.            PC用: 現在のお見積り額カード強調
  775.         ============================================ */
  776.         @media (min-width: 768px) {
  777.             .mitsumori-card-pc {
  778.                 border: 2px solid #1a6fcf !important;
  779.                 border-radius: 10px !important;
  780.                 box-shadow: 0 4px 16px rgba(26,111,207,0.18) !important;
  781.                 margin-top: 20px;
  782.                 overflow: hidden;
  783.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  784.             }
  785.             .mitsumori-card-pc .card-header {
  786.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  787.                 color: #fff !important;
  788.                 padding: 14px 16px !important;
  789.                 border-bottom: none !important;
  790.             }
  791.             .mitsumori-card-pc .card-title {
  792.                 color: #fff !important;
  793.                 font-size: 15px !important;
  794.                 font-weight: bold !important;
  795.                 margin: 0 !important;
  796.             }
  797.             .mitsumori-card-pc #mitsumori_message {
  798.                 font-size: 22px !important;
  799.                 font-weight: bold !important;
  800.                 color: #fff !important;
  801.             }
  802.             .mitsumori-card-pc .btn-tool {
  803.                 color: #fff !important;
  804.             }
  805.             /* 合計行を大きく強調 */
  806.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  807.                 font-size: 16px !important;
  808.                 font-weight: bold !important;
  809.                 color: #c00 !important;
  810.                 background: #fff8f8 !important;
  811.                 padding: 12px 16px !important;
  812.             }
  813.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  814.                 font-size: 20px !important;
  815.                 font-weight: bold !important;
  816.                 color: #c00 !important;
  817.             }
  818.             /* card-body(明細リスト)を白背景に */
  819.             .mitsumori-card-pc .card-body {
  820.                 background: #fff !important;
  821.             }
  822.             .mitsumori-card-pc .card-footer {
  823.                 background: #f8faff !important;
  824.                 border-top: 1px solid #dce8fb !important;
  825.                 padding: 12px 16px !important;
  826.             }
  827.         }
  828.         @media (max-width: 767px) {
  829.             /* スマホでは現在のお見積り額カードの強調スタイルをすべてリセット */
  830.             .mitsumori-card-pc {
  831.                 border: none !important;
  832.                 border-radius: 0 !important;
  833.                 box-shadow: none !important;
  834.                 margin-top: 0 !important;
  835.                 overflow: visible !important;
  836.                 background: none !important;
  837.                 /* sticky-top(position:sticky / z-index:1020) を解除。
  838.                    そのままだと最下部で #sp-mitsumori-bar(z-index:1000) の上に
  839.                    重なり、合計バーと文字が被るため通常フローへ戻す。 */
  840.                 position: static !important;
  841.                 z-index: auto !important;
  842.             }
  843.             .mitsumori-card-pc .card-header {
  844.                 background: none !important;
  845.                 color: inherit !important;
  846.                 padding: inherit !important;
  847.                 border-bottom: inherit !important;
  848.             }
  849.             .mitsumori-card-pc .card-title { color: inherit !important; }
  850.             .mitsumori-card-pc #mitsumori_message { font-size: inherit !important; color: inherit !important; }
  851.             .mitsumori-card-pc .btn-tool { color: inherit !important; }
  852.             /* 折りたたみトグルボタン */
  853.             .btn-mitsumori-toggle {
  854.                 background: none !important;
  855.                 border: 1px solid #aaa !important;
  856.                 border-radius: 4px !important;
  857.                 padding: 2px 8px !important;
  858.                 font-size: 12px !important;
  859.                 color: #333 !important;
  860.                 line-height: 1.4 !important;
  861.             }
  862.             .btn-mitsumori-toggle .toggle-icon {
  863.                 display: inline-block;
  864.                 transition: transform 0.2s;
  865.             }
  866.             /* 展開状態: ▼→▲ */
  867.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon::before {
  868.                 content: \"▲ 閉じる\";
  869.             }
  870.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon {
  871.                 display: none;
  872.             }
  873.             .card:not(.collapsed-card) .btn-mitsumori-toggle::after {
  874.                 content: \"▲ 閉じる\";
  875.                 font-size: 12px;
  876.             }
  877.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  878.                 font-size: inherit !important;
  879.                 color: inherit !important;
  880.                 background: none !important;
  881.                 padding: inherit !important;
  882.             }
  883.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  884.                 font-size: inherit !important;
  885.                 color: inherit !important;
  886.             }
  887.             .mitsumori-card-pc .card-footer {
  888.                 background: none !important;
  889.                 border-top: inherit !important;
  890.                 padding: inherit !important;
  891.             }
  892.             /* 横スクロール禁止 */
  893.             body, html {
  894.                 overflow-x: hidden;
  895.                 max-width: 100vw;
  896.             }
  897.             /* ボタンの折り返しを許可(nowrapが原因で横スクロール発生するため) */
  898.             .opt-btn,
  899.             .rp-btn {
  900.                 white-space: normal;
  901.                 word-break: break-all;
  902.             }
  903.             /* エリア案内: スマホでコンパクト */
  904.             .ec-areaNotice {
  905.                 margin: 8px 0;
  906.                 padding: 8px 10px;
  907.                 border-left-width: 3px;
  908.                 cursor: pointer;
  909.             }
  910.             .ec-areaNotice__inner {
  911.                 flex-direction: row;
  912.                 gap: 8px;
  913.                 align-items: flex-start;
  914.             }
  915.             .ec-areaNotice__icon { font-size: 15px; }
  916.             /* タイトル行: 展開トグル */
  917.             .ec-areaNotice__title {
  918.                 font-size: 11px;
  919.                 margin-bottom: 3px;
  920.                 display: flex;
  921.                 justify-content: space-between;
  922.                 align-items: center;
  923.             }
  924.             .ec-areaNotice__title::after {
  925.                 content: \"▼\";
  926.                 font-size: 9px;
  927.                 color: #888;
  928.                 margin-left: 6px;
  929.                 transition: transform 0.2s;
  930.             }
  931.             .ec-areaNotice.is-open .ec-areaNotice__title::after {
  932.                 transform: rotate(180deg);
  933.             }
  934.             /* 折りたたみ対象: 閉じた状態では非表示 */
  935.             .ec-areaNotice__detail {
  936.                 display: none;
  937.             }
  938.             .ec-areaNotice.is-open .ec-areaNotice__detail {
  939.                 display: block;
  940.             }
  941.             .ec-areaNotice__text { font-size: 11px; line-height: 1.5; }
  942.             .ec-areaNotice__text br { display: none; }
  943.             .ec-areaNotice__link { font-size: 11px; margin-top: 3px; }
  944.             .rp-card { width: calc(33.333% - 6px); min-width: 80px; }
  945.             
  946.             #sp-mitsumori-bar {
  947.                 display: flex;
  948.                 position: fixed;
  949.                 bottom: 0;
  950.                 left: 0;
  951.                 right: 0;
  952.                 z-index: 1000;
  953.                 background: #fff;
  954.                 border-top: 2px solid #e0e0e0;
  955.                 box-shadow: 0 -2px 8px rgba(0,0,0,0.12);
  956.                 align-items: center;
  957.                 padding: 8px 10px calc(8px + env(safe-area-inset-bottom)) 10px;
  958.                 gap: 8px;
  959.             }
  960.             #sp-mitsumori-bar .sp-bar__label {
  961.                 font-size: 11px;
  962.                 color: #666;
  963.                 white-space: nowrap;
  964.             }
  965.             /* 価格ラッパ: 合計金額は最重要のため常に全桁表示する(縮小・省略しない)。
  966.                幅が足りない場合は下のボタン側を縮める(flex 配分でボタンが先に縮む)。 */
  967.             #sp-mitsumori-bar .sp-bar__pricewrap {
  968.                 flex: 0 0 auto;
  969.                 min-width: 0;
  970.             }
  971.             #sp-mitsumori-bar .sp-bar__price {
  972.                 font-size: 18px;
  973.                 font-weight: bold;
  974.                 color: #c00;
  975.                 white-space: nowrap;
  976.             }
  977.             #sp-mitsumori-bar .sp-bar__btn {
  978.                 font-size: 12px;
  979.                 padding: 8px 12px;
  980.                 background: #333;
  981.                 color: #fff;
  982.                 border: none;
  983.                 border-radius: 6px;
  984.                 white-space: nowrap;
  985.                 cursor: pointer;
  986.                 position: relative;
  987.                 display: inline-flex;
  988.                 align-items: center;
  989.                 gap: 6px;
  990.                 flex: 1 1 auto;
  991.                 min-width: 0;
  992.                 justify-content: center;
  993.             }
  994.             #sp-mitsumori-bar .sp-bar__btn i {
  995.                 font-size: 14px;
  996.                 flex: 0 0 auto;
  997.             }
  998.             /* お見積りの詳細(内訳)を開くボタン。価格・カートボタンを圧迫しないよう
  999.                最小幅のアイコン+短ラベルにし、幅不足時も縮まない固定幅で維持する。 */
  1000.             #sp-mitsumori-bar .sp-bar__detail-btn {
  1001.                 display: inline-flex;
  1002.                 flex-direction: column;
  1003.                 align-items: center;
  1004.                 justify-content: center;
  1005.                 gap: 2px;
  1006.                 flex: 0 0 auto;
  1007.                 padding: 4px 8px;
  1008.                 background: #fff;
  1009.                 color: #c00;
  1010.                 border: 1px solid #c00;
  1011.                 border-radius: 6px;
  1012.                 font-size: 10px;
  1013.                 font-weight: bold;
  1014.                 line-height: 1.1;
  1015.                 white-space: nowrap;
  1016.                 cursor: pointer;
  1017.             }
  1018.             #sp-mitsumori-bar .sp-bar__detail-btn i { font-size: 15px; }
  1019.             /* 幅が足りないときはボタンの文字を省略し、価格と数字を守る。 */
  1020.             #sp-mitsumori-bar .sp-bar__btn-label {
  1021.                 overflow: hidden;
  1022.                 text-overflow: ellipsis;
  1023.                 white-space: nowrap;
  1024.             }
  1025.             #sp-mitsumori-bar .sp-bar__cart-badge {
  1026.                 position: absolute;
  1027.                 top: -6px;
  1028.                 right: -6px;
  1029.                 background: #c00;
  1030.                 color: #fff;
  1031.                 border-radius: 50%;
  1032.                 min-width: 16px;
  1033.                 height: 16px;
  1034.                 font-size: 10px;
  1035.                 line-height: 16px;
  1036.                 padding: 0 4px;
  1037.                 font-weight: bold;
  1038.             }
  1039.             #sp-mitsumori-bar .sp-bar__home-btn {
  1040.                 display: inline-flex;
  1041.                 align-items: center;
  1042.                 justify-content: center;
  1043.                 width: 36px;
  1044.                 height: 36px;
  1045.                 flex: 0 0 auto;
  1046.                 border: 1px solid #ccc;
  1047.                 border-radius: 6px;
  1048.                 background: #fff;
  1049.                 color: #333;
  1050.                 text-decoration: none;
  1051.                 cursor: pointer;
  1052.             }
  1053.             #sp-mitsumori-bar .sp-bar__home-btn i {
  1054.                 font-size: 16px;
  1055.             }
  1056.             #sp-mitsumori-bar .sp-bar__home-btn:hover {
  1057.                 background: #f0f0f0;
  1058.             }
  1059.             /* 下部バーの高さ分ページ下部にpaddingを追加 (iOS safe-area 込み) */
  1060.             body {
  1061.                 padding-bottom: calc(80px + env(safe-area-inset-bottom));
  1062.             }
  1063.         }
  1064.         /* ============================================
  1065.            カート追加モーダル: 縦並び中央配置
  1066.         ============================================ */
  1067.         .add-cart-modal__wrap {
  1068.             text-align: center;
  1069.         }
  1070.         .add-cart-modal__header {
  1071.             font-size: 16px;
  1072.             margin: 20px 0 24px;
  1073.             text-align: center;
  1074.         }
  1075.         .add-cart-modal__actions {
  1076.             display: flex;
  1077.             flex-direction: column;
  1078.             align-items: center;
  1079.             gap: 16px;
  1080.             padding: 0 20px 20px;
  1081.         }
  1082.         .add-cart-modal__primary {
  1083.             display: inline-block;
  1084.             width: 80%;
  1085.             max-width: 320px;
  1086.             padding: 14px 20px;
  1087.             font-size: 15px;
  1088.             font-weight: bold;
  1089.             text-align: center;
  1090.             background: #d9534f;
  1091.             color: #fff !important;
  1092.             border-radius: 6px;
  1093.             text-decoration: none;
  1094.             cursor: pointer;
  1095.         }
  1096.         .add-cart-modal__primary:hover {
  1097.             background: #c9302c;
  1098.             color: #fff !important;
  1099.             text-decoration: none;
  1100.         }
  1101.         .add-cart-modal__secondary {
  1102.             display: inline-block;
  1103.             padding: 6px 14px;
  1104.             font-size: 12px;
  1105.             color: #666;
  1106.             border: 1px solid #ccc;
  1107.             border-radius: 4px;
  1108.             background: #fff;
  1109.             cursor: pointer;
  1110.         }
  1111.         .add-cart-modal__secondary:hover {
  1112.             background: #f0f0f0;
  1113.             color: #333;
  1114.         }
  1115.         @media (max-width: 767px) {
  1116.             .add-cart-modal__actions {
  1117.                 gap: 20px;
  1118.             }
  1119.         }
  1120.     </style>
  1121. ";
  1122.         
  1123.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  1124.         
  1125.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  1126.     }
  1127.     // line 1113
  1128.     public function block_javascript($context, array $blocks = [])
  1129.     {
  1130.         $macros $this->macros;
  1131.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  1132.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  1133.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  1134.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  1135.         // line 1114
  1136.         echo "
  1137.     <script>
  1138.         eccube.classCategories = ";
  1139.         // line 1116
  1140.         echo $this->extensions['Eccube\Twig\Extension\EccubeExtension']->getClassCategoriesAsJson((isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1116$this->source); })()));
  1141.         echo ";
  1142.         // 規格2に選択肢を割り当てる。
  1143.         function fnSetClassCategories(form, classcat_id2_selected) {
  1144.             var \$form = \$(form);
  1145.             var product_id = \$form.find('input[name=product_id]').val();
  1146.             var \$sele1 = \$form.find('select[name=classcategory_id1]');
  1147.             var \$sele2 = \$form.find('select[name=classcategory_id2]');
  1148.             eccube.setClassCategories(\$form, product_id, \$sele1, \$sele2, classcat_id2_selected);
  1149.         }
  1150.         ";
  1151.         // line 1127
  1152.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse1127)) {
  1153.             // line 1128
  1154.             echo "        fnSetClassCategories(
  1155.             \$('#form1'), ";
  1156.             // line 1129
  1157.             echo json_encode(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'1129$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse1129), "vars", [], "any"falsefalsefalse1129), "value", [], "any"falsefalsefalse1129));
  1158.             echo "
  1159.         );
  1160.         ";
  1161.         } elseif (twig_get_attribute($this->env$this->source,         // line 1131
  1162. ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse1131)) {
  1163.             // line 1132
  1164.             echo "        eccube.checkStock(\$('#form1'), ";
  1165.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1132$this->source); })()), "id", [], "any"falsefalsefalse1132), "html"nulltrue);
  1166.             echo ", ";
  1167.             echo json_encode(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'1132$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse1132), "vars", [], "any"falsefalsefalse1132), "value", [], "any"falsefalsefalse1132));
  1168.             echo ", null);
  1169.         ";
  1170.         }
  1171.         // line 1134
  1172.         echo "    </script>
  1173.     <script>
  1174.         \$(function() {
  1175.             // bfcache無効化
  1176.             \$(window).bind('pageshow', function(event) {
  1177.                 if (event.originalEvent.persisted) {
  1178.                     location.reload(true);
  1179.                 }
  1180.             });
  1181.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  1182.             // img タグに width, height が付与されている.
  1183.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  1184.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  1185.             \$('.ec-grid2__cell').hide();
  1186.             var removeSize = function () {
  1187.                 \$('.slide-item').height('');
  1188.                 \$('.slide-item img')
  1189.                     .removeAttr('width')
  1190.                     .removeAttr('height')
  1191.                     .removeAttr('style');
  1192.             };
  1193.             var slickInitial = function(slick) {
  1194.                 \$('.ec-grid2__cell').fadeIn(1500);
  1195.                 var baseHeight = \$(slick.target).height();
  1196.                 var baseWidth = \$(slick.target).width();
  1197.                 var rate = baseWidth / baseHeight;
  1198. \t\t\t\tif(baseHeight * rate < 400){
  1199. \t                \$('.slide-item').height(baseHeight * rate); // 余白を削除する
  1200. \t\t\t\t}else{
  1201. \t                \$('.slide-item').height(400); // 余白を削除する
  1202. \t\t\t\t}
  1203.                 // transform を使用することでCLSの影響を受けないようにする
  1204.                 \$('.slide-item img')
  1205.                     .css(
  1206.                         {
  1207.                             'transform-origin': 'top left',
  1208.                             'transform': 'scaleY(' + rate + ')',
  1209.                             'transition': 'transform .1s'
  1210.                         }
  1211.                     );
  1212.                 // 正しいサイズに近くなったら属性を解除する
  1213.                 setTimeout(removeSize, 500);
  1214.             };
  1215.             \$('.item_visual').on('init', slickInitial);
  1216.             // リサイズ時は CLS の影響を受けないため属性を解除する
  1217.             \$(window).resize(removeSize);
  1218.             \$('.item_visual').slick({
  1219.                 dots: false,
  1220.                 arrows: true,
  1221.                 responsive: [{
  1222.                     breakpoint: 768,
  1223.                     settings: {
  1224.                         dots: true,
  1225.                 \t\tarrows: false
  1226.                     }
  1227.                 }]
  1228.             });
  1229.             \$('.slideThumb').on('click', function() {
  1230.                 var index = \$(this).attr('data-index');
  1231.                 \$('.item_visual').slick('slickGoTo', index, false);
  1232.             })
  1233.         });
  1234.     </script>
  1235.     <script>
  1236.         \$(function() {
  1237.             \$('.add-cart').on('click', function(event) {
  1238.                 ";
  1239.         // line 1204
  1240.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse1204)) {
  1241.             // line 1205
  1242.             echo "                // 規格1フォームの必須チェック
  1243.                 if (\$('#classcategory_id1').val() == '__unselected' || \$('#classcategory_id1').val() == '') {
  1244.                     \$('#classcategory_id1')[0].setCustomValidity('";
  1245.             // line 1207
  1246.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("項目が選択されていません"), "html"nulltrue);
  1247.             echo "');
  1248.                     return true;
  1249.                 } else {
  1250.                     \$('#classcategory_id1')[0].setCustomValidity('');
  1251.                 }
  1252.                 ";
  1253.         }
  1254.         // line 1213
  1255.         echo "
  1256.                 ";
  1257.         // line 1214
  1258.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse1214)) {
  1259.             // line 1215
  1260.             echo "                // 規格2フォームの必須チェック
  1261.                 if (\$('#classcategory_id2').val() == '__unselected' || \$('#classcategory_id2').val() == '') {
  1262.                     \$('#classcategory_id2')[0].setCustomValidity('";
  1263.             // line 1217
  1264.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("項目が選択されていません"), "html"nulltrue);
  1265.             echo "');
  1266.                     return true;
  1267.                 } else {
  1268.                     \$('#classcategory_id2')[0].setCustomValidity('');
  1269.                 }
  1270.                 ";
  1271.         }
  1272.         // line 1223
  1273.         echo "
  1274.                 // タイプ2: カート送信直前に set_count を quantity に同期
  1275.                 if(\$('#set_count').length){
  1276.                     var _sc = parseInt(\$('#set_count').val()) || 1;
  1277.                     \$('#quantity').val(_sc);
  1278.                     \$('input[name=\"quantity\"]').val(_sc);
  1279.                 }
  1280.                 // 個数フォームのチェック
  1281.                 if (\$('#quantity').val() < 1) {
  1282.                     \$('#quantity')[0].setCustomValidity('";
  1283.         // line 1233
  1284.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("1以上で入力してください。"), "html"nulltrue);
  1285.         echo "');
  1286.                     return true;
  1287.                 } else {
  1288.                     \$('#quantity')[0].setCustomValidity('');
  1289.                 }
  1290.                 event.preventDefault();
  1291.                 \$form = \$('#form1');
  1292.                 \$.ajax({
  1293.                     url: \$form.attr('action'),
  1294.                     type: \$form.attr('method'),
  1295.                     data: \$form.serialize(),
  1296.                     dataType: 'json',
  1297.                     beforeSend: function(xhr, settings) {
  1298.                         // Buttonを無効にする
  1299.                         \$('.add-cart').prop('disabled', true);
  1300.                     }
  1301.                 }).done(function(data) {
  1302.                     // レスポンス内のメッセージをalertで表示
  1303.                     \$.each(data.messages, function() {
  1304.                         \$('#ec-modal-header').text(this);
  1305.                     });
  1306.                     \$('.ec-modal').show()
  1307.                     // カートブロックを更新する
  1308.                     \$.ajax({
  1309.                         url: \"";
  1310.         // line 1260
  1311.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("block_cart");
  1312.         echo "\",
  1313.                         type: 'GET',
  1314.                         dataType: 'html'
  1315.                     }).done(function(html) {
  1316.                         \$('.ec-headerRole__cart').html(html);
  1317.                     });
  1318.                 }).fail(function(data) {
  1319.                     alert('";
  1320.         // line 1267
  1321.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートへの追加に失敗しました。"), "html"nulltrue);
  1322.         echo "');
  1323.                 }).always(function(data) {
  1324.                     // Buttonを有効にする
  1325.                     \$('.add-cart').prop('disabled', false);
  1326.                 });
  1327.             });
  1328.         });
  1329.         \$('.ec-modal-wrap').on('click', function(e) {
  1330.             // モーダル内の処理は外側にバブリングさせない
  1331.             e.stopPropagation();
  1332.         });
  1333.         \$('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  1334.             \$('.ec-modal').hide()
  1335.         });
  1336. \t\tvar pw = \"";
  1337.         // line 1284
  1338.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1284$this->source); })())) {
  1339.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1284$this->source); })()), "pw", [], "any"falsefalsefalse1284), "html"nulltrue);
  1340.         }
  1341.         echo "\";
  1342. \t\tvar pd = \"";
  1343.         // line 1285
  1344.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1285$this->source); })())) {
  1345.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1285$this->source); })()), "pd", [], "any"falsefalsefalse1285), "html"nulltrue);
  1346.         }
  1347.         echo "\";
  1348. \t\tvar ph = \"";
  1349.         // line 1286
  1350.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1286$this->source); })())) {
  1351.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1286$this->source); })()), "ph", [], "any"falsefalsefalse1286), "html"nulltrue);
  1352.         }
  1353.         echo "\";
  1354. \t\tvar pm = \"";
  1355.         // line 1287
  1356.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1287$this->source); })())) {
  1357.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1287$this->source); })()), "pm", [], "any"falsefalsefalse1287), "html"nulltrue);
  1358.         }
  1359.         echo "\";
  1360. \t\tvar pc = \"";
  1361.         // line 1288
  1362.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1288$this->source); })())) {
  1363.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1288$this->source); })()), "pc", [], "any"falsefalsefalse1288), "html"nulltrue);
  1364.         }
  1365.         echo "\";
  1366. \t\t// option1 / option2: カテゴリ別 option 軸 (um: タイプ=subtype, fe: ct_up 等)
  1367. \t\tvar option1 = \"";
  1368.         // line 1290
  1369.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1290$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse1290))) {
  1370.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1290$this->source); })()), "option1", [], "any"falsefalsefalse1290), "html"nulltrue);
  1371.         }
  1372.         echo "\";
  1373. \t\tvar option2 = \"";
  1374.         // line 1291
  1375.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1291$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse1291))) {
  1376.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1291$this->source); })()), "option2", [], "any"falsefalsefalse1291), "html"nulltrue);
  1377.         }
  1378.         echo "\";
  1379. \t\tvar op0 = \"";
  1380.         // line 1292
  1381.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1292$this->source); })())) {
  1382.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1292$this->source); })()), "op", [], "any"falsefalsefalse1292), 0, [], "array"falsefalsefalse1292), "html"nulltrue);
  1383.         }
  1384.         echo "\";
  1385. \t\tvar op1 = \"";
  1386.         // line 1293
  1387.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1293$this->source); })())) {
  1388.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1293$this->source); })()), "op", [], "any"falsefalsefalse1293), 1, [], "array"falsefalsefalse1293), "html"nulltrue);
  1389.         }
  1390.         echo "\";
  1391. \t\tvar op2 = \"";
  1392.         // line 1294
  1393.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1294$this->source); })())) {
  1394.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1294$this->source); })()), "op", [], "any"falsefalsefalse1294), 2, [], "array"falsefalsefalse1294), "html"nulltrue);
  1395.         }
  1396.         echo "\";
  1397. \t\tvar op3 = \"";
  1398.         // line 1295
  1399.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1295$this->source); })())) {
  1400.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1295$this->source); })()), "op", [], "any"falsefalsefalse1295), 3, [], "array"falsefalsefalse1295), "html"nulltrue);
  1401.         }
  1402.         echo "\";
  1403. \t\tvar op4 = \"";
  1404.         // line 1296
  1405.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1296$this->source); })())) {
  1406.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1296$this->source); })()), "op", [], "any"falsefalsefalse1296), 4, [], "array"falsefalsefalse1296), "html"nulltrue);
  1407.         }
  1408.         echo "\";
  1409. \t\tvar op5 = \"";
  1410.         // line 1297
  1411.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1297$this->source); })())) {
  1412.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1297$this->source); })()), "op", [], "any"falsefalsefalse1297), 5, [], "array"falsefalsefalse1297), "html"nulltrue);
  1413.         }
  1414.         echo "\";
  1415. \t\tvar op6 = \"";
  1416.         // line 1298
  1417.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1298$this->source); })())) {
  1418.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1298$this->source); })()), "op", [], "any"falsefalsefalse1298), 6, [], "array"falsefalsefalse1298), "html"nulltrue);
  1419.         }
  1420.         echo "\";
  1421. \t\tvar op7 = \"";
  1422.         // line 1299
  1423.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1299$this->source); })())) {
  1424.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1299$this->source); })()), "op", [], "any"falsefalsefalse1299), 7, [], "array"falsefalsefalse1299), "html"nulltrue);
  1425.         }
  1426.         echo "\";
  1427. \t\tvar op8 = \"";
  1428.         // line 1300
  1429.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1300$this->source); })())) {
  1430.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1300$this->source); })()), "op", [], "any"falsefalsefalse1300), 8, [], "array"falsefalsefalse1300), "html"nulltrue);
  1431.         }
  1432.         echo "\";
  1433. \t\tvar op9 = \"";
  1434.         // line 1301
  1435.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1301$this->source); })())) {
  1436.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1301$this->source); })()), "op", [], "any"falsefalsefalse1301), 9, [], "array"falsefalsefalse1301), "html"nulltrue);
  1437.         }
  1438.         echo "\";
  1439. \t\tvar op10 = \"";
  1440.         // line 1302
  1441.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1302$this->source); })())) {
  1442.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1302$this->source); })()), "op", [], "any"falsefalsefalse1302), 10, [], "array"falsefalsefalse1302), "html"nulltrue);
  1443.         }
  1444.         echo "\";
  1445. \t\tconst formatter = new Intl.NumberFormat('ja-JP');
  1446. \t\t// ============================================================
  1447. \t\t//  free_area 1 エントリのスキーマ(11 キー固定)
  1448. \t\t// ============================================================
  1449. \t\t//   w           : 幅 (string, 例 \"239.9cm\" / tf は \"1m\")
  1450. \t\t//   d           : 奥行
  1451. \t\t//   h           : 高さ (tf はロール長 \"10m\")
  1452. \t\t//   m           : 素材
  1453. \t\t//   c           : カラー
  1454. \t\t//   price       : 販売価格 (税抜、amount=1 ベース)
  1455. \t\t//   unit_price  : 商品 per-unit 増分 (税抜、AMOUNT_CATEGORIES のみ)
  1456. \t\t//   maker_price : メーカー価格 (税抜)
  1457. \t\t//   ct          : 基本工事費 (税抜、amount=1 ベース)
  1458. \t\t//   option1     : fe → ct_up / その他カテゴリ → category-specific
  1459. \t\t//   option2     : um → ct_up / その他カテゴリ → category-specific
  1460. \t\t//
  1461. \t\t//  ct4 (設置場所) / ct5 (撤去) / ct6 (残土) は option_area 側で扱う.
  1462. \t\t// ============================================================
  1463. \t\t// 施工オプション定義(option_area)— 各エントリ {name, comment, on, off, price}
  1464. \t\tvar op_data = ";
  1465.         // line 1325
  1466.         echo ((array_key_exists("op_json"$context)) ? (_twig_default_filter((isset($context["op_json"]) || array_key_exists("op_json"$context) ? $context["op_json"] : (function () { throw new RuntimeError('Variable "op_json" does not exist.'1325$this->source); })()), "[]")) : ("[]"));
  1467.         echo ";
  1468. \t\t// option_item_area:
  1469. \t\t//   tg 用 — block 別オプション差額表
  1470. \t\t//     { axis_labels: {F:'床材',front:'前面型',side1:'右側面型',side2:'左側面型'},
  1471. \t\t//       blocks: { 'W_label|D_label': { F:[{idx,label,diff},...], front:[...], side1:[...], side2:[...] }, ... } }
  1472. \t\t//   fe (sale_type=4) 用 — ブロックの種類×段数の差額表 (fe_block キー)
  1473. \t\t//     { fe_block: { depends_on_name: '...', depends_on_value: '...',
  1474. \t\t//                   title: '...', default_key: '...',
  1475. \t\t//                   choices: [{key,label,price}, ...] } }
  1476. \t\t// 該当しないカテゴリでは fe_block は null. axis_labels/blocks は空.
  1477. \t\tvar oi_data = ";
  1478.         // line 1336
  1479.         echo ((array_key_exists("oi_json"$context)) ? (_twig_default_filter((isset($context["oi_json"]) || array_key_exists("oi_json"$context) ? $context["oi_json"] : (function () { throw new RuntimeError('Variable "oi_json" does not exist.'1336$this->source); })()), "{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}")) : ("{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}"));
  1480.         echo ";
  1481. \t\t// 選択中の tg オプション差額 (axis -> selected choice_idx). ラジオ click で更新される.
  1482. \t\tvar oi_selected = { F: 1, front: 1, side1: 1, side2: 1 };
  1483. \t\t// 選択中の fe ブロック種類×段数 (key 文字列). 既定は oi_data.fe_block.default_key.
  1484. \t\tvar fe_block_selected = (oi_data && oi_data.fe_block && oi_data.fe_block.default_key) || '';
  1485. \t\t// sale_type ID(mtb_sale_type の id。本サイトでの意味は次の通り):
  1486. \t\t//   1 通常 / 2 補助金窓 / 3 物置 / 4 フェンス / 5 デッキ / 6 芝生 / 9 商品のみ
  1487. \t\tvar SALE_TYPE_ID = ";
  1488.         // line 1346
  1489.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'1346$this->source); })()), "SaleType", [], "any"falsefalsefalse1346), "id", [], "any"falsefalsefalse1346), "html"nulltrue);
  1490.         echo ";
  1491. \t\t";
  1492.         // line 1349
  1493.         echo "\t\t";
  1494.         $context["option1_label"] = "オプション1";
  1495.         // line 1350
  1496.         echo "\t\t";
  1497.         $context["option2_label"] = "オプション2";
  1498.         // line 1351
  1499.         echo "\t\t";
  1500.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1351$this->source); })()), "ProductCategories", [], "any"falsefalsefalse1351))) {
  1501.             // line 1352
  1502.             echo "\t\t\t";
  1503.             $context['_parent'] = $context;
  1504.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1352$this->source); })()), "ProductCategories", [], "any"falsefalsefalse1352));
  1505.             foreach ($context['_seq'] as $context["_key"] => $context["pcat"]) {
  1506.                 // line 1353
  1507.                 echo "\t\t\t\t";
  1508.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1353) == 31)) {
  1509.                     $context["option1_label"] = "サイズプリセット";
  1510.                     $context["option2_label"] = "駆動方式";
  1511.                 }
  1512.                 // line 1354
  1513.                 echo "\t\t\t\t";
  1514.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1354) == 43)) {
  1515.                     $context["option1_label"] = "ランマ";
  1516.                     $context["option2_label"] = "タイプ";
  1517.                 }
  1518.                 // line 1355
  1519.                 echo "\t\t\t\t";
  1520.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1355) == 15)) {
  1521.                     $context["option1_label"] = "棚タイプ";
  1522.                 }
  1523.                 // line 1356
  1524.                 echo "\t\t\t\t";
  1525.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1356) == 17)) {
  1526.                     $context["option1_label"] = "窓タイプ";
  1527.                 }
  1528.                 // line 1357
  1529.                 echo "\t\t\t";
  1530.             }
  1531.             $_parent $context['_parent'];
  1532.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pcat'], $context['_parent'], $context['loop']);
  1533.             $context array_intersect_key($context$_parent) + $_parent;
  1534.             // line 1358
  1535.             echo "\t\t";
  1536.         }
  1537.         // line 1359
  1538.         echo "
  1539. \t\t// 消費税率(pp.price/pp.ct/op_data.price は scraper が税抜で保存しているため、
  1540. \t\t// calcGoukei 出口で 1+TAX_RATE を掛けて税込 mitsumori_goukei にする)
  1541. \t\tvar TAX_RATE = 0.10;
  1542. \t\tfunction toIncTax(v) { return Math.round(v * (1 + TAX_RATE)); }
  1543. \t\t/**
  1544. \t\t * tg 用 block 別オプション差額の集計.
  1545. \t\t *   現選択 (W, D) から block key を作り、oi_data.blocks[blockKey] を取得.
  1546. \t\t *   各 axis (F/front/side1/side2) で oi_selected[axis] の choice の diff を合計.
  1547. \t\t * 戻り値: { total: 差額合計(税抜), items: [{name, label, diff}, ...] }
  1548. \t\t *   block が無い (tg 以外 / 該当 (W,D) が未取得) なら total=0.
  1549. \t\t */
  1550. \t\tfunction collectOptionItems(curW, curD) {
  1551. \t\t\tvar result = { total: 0, items: [] };
  1552. \t\t\tif (!oi_data || !oi_data.blocks) return result;
  1553. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  1554. \t\t\tvar block = oi_data.blocks[blockKey];
  1555. \t\t\tif (!block) return result;
  1556. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  1557. \t\t\tfor (var i = 0; i < axes.length; i++) {
  1558. \t\t\t\tvar axis = axes[i];
  1559. \t\t\t\tvar choices = block[axis];
  1560. \t\t\t\tif (!choices || !choices.length) continue;
  1561. \t\t\t\tvar idx = oi_selected[axis] || 1;
  1562. \t\t\t\tvar pick = null;
  1563. \t\t\t\tfor (var j = 0; j < choices.length; j++) {
  1564. \t\t\t\t\tif (parseInt(choices[j].idx) === parseInt(idx)) { pick = choices[j]; break; }
  1565. \t\t\t\t}
  1566. \t\t\t\tif (!pick) pick = choices[0];
  1567. \t\t\t\tvar diff = parseInt(pick.diff) || 0;
  1568. \t\t\t\tresult.total += diff;
  1569. \t\t\t\tresult.items.push({
  1570. \t\t\t\t\tname:  oi_data.axis_labels[axis] || axis,
  1571. \t\t\t\t\tlabel: pick.label,
  1572. \t\t\t\t\tdiff:  diff,
  1573. \t\t\t\t});
  1574. \t\t\t}
  1575. \t\t\treturn result;
  1576. \t\t}
  1577. \t\t/**
  1578. \t\t * tg ラジオ群を block 別に DOM へ描画する.
  1579. \t\t *   W/D が確定したら現 block の 4 軸 (F/front/side1/side2) ラジオを #tg-options 要素に出す.
  1580. \t\t *   block が空なら #tg-options を空にする.
  1581. \t\t */
  1582. \t\tfunction renderOptionItemRadios(curW, curD) {
  1583. \t\t\tvar \$box = \$('#tg-options');
  1584. \t\t\tif (!\$box.length) return;
  1585. \t\t\t\$box.empty();
  1586. \t\t\tif (!oi_data || !oi_data.blocks) return;
  1587. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  1588. \t\t\tvar block = oi_data.blocks[blockKey];
  1589. \t\t\tif (!block) return;
  1590. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  1591. \t\t\taxes.forEach(function(axis) {
  1592. \t\t\t\tvar choices = block[axis];
  1593. \t\t\t\tif (!choices || !choices.length) return;
  1594. \t\t\t\tvar axisLabel = (oi_data.axis_labels && oi_data.axis_labels[axis]) || axis;
  1595. \t\t\t\tvar \$section = \$('<div class=\"form-group tg-axis\"></div>');
  1596. \t\t\t\t\$section.append('<p class=\"rp-section-label\"><strong>' + axisLabel + '</strong>: <span class=\"tg-axis-selected\"></span></p>');
  1597. \t\t\t\t// 他オプション(opt-btn)と統一したボタン型 UI で描画(縦積み・長ラベル折返し).
  1598. \t\t\t\tvar \$list = \$('<div class=\"opt-btn-group no-hscroll\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  1599. \t\t\t\tchoices.forEach(function(ch, i) {
  1600. \t\t\t\t\tvar inputId = 'tg_' + axis + '_' + ch.idx;
  1601. \t\t\t\t\tvar name = 'tg_' + axis;
  1602. \t\t\t\t\tvar isSel = (parseInt(ch.idx) === parseInt(oi_selected[axis] || 1));
  1603. \t\t\t\t\tvar diffTxt = ch.diff > 0 ? '+' + formatter.format(ch.diff) + '円' : (ch.diff < 0 ? formatter.format(ch.diff) + '円' : '±0');
  1604. \t\t\t\t\t\$list.append(
  1605. \t\t\t\t\t\t'<label class=\"opt-btn' + (isSel ? ' is-selected' : '') + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  1606. \t\t\t\t\t\t'<input type=\"radio\" name=\"' + name + '\" id=\"' + inputId + '\" value=\"' + ch.idx + '\" data-axis=\"' + axis + '\"' + (isSel ? ' checked' : '') + '>' +
  1607. \t\t\t\t\t\tch.label + '<span class=\"tg-diff\">(' + diffTxt + ')</span></label>'
  1608. \t\t\t\t\t);
  1609. \t\t\t\t});
  1610. \t\t\t\t\$section.append(\$list);
  1611. \t\t\t\t\$box.append(\$section);
  1612. \t\t\t});
  1613. \t\t\t// ラジオ選択で oi_selected 更新 + is-selected 付替え → 再計算
  1614. \t\t\t\$box.off('change.tg').on('change.tg', 'input[type=\"radio\"][data-axis]', function() {
  1615. \t\t\t\tvar axis = \$(this).data('axis');
  1616. \t\t\t\toi_selected[axis] = parseInt(\$(this).val()) || 1;
  1617. \t\t\t\t\$(this).closest('.opt-btn-group').find('label.opt-btn').removeClass('is-selected');
  1618. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  1619. \t\t\t\tmitsumori_simulation('refresh', '');
  1620. \t\t\t});
  1621. \t\t\tupdateOptionItemSelectedLabels();
  1622. \t\t}
  1623. \t\tfunction updateOptionItemSelectedLabels() {
  1624. \t\t\t\$('#tg-options .tg-axis').each(function() {
  1625. \t\t\t\tvar \$sel = \$(this).find('input[type=\"radio\"]:checked');
  1626. \t\t\t\tif (!\$sel.length) return;
  1627. \t\t\t\tvar label = \$sel.parent().contents().filter(function() { return this.nodeType === 3; }).text().trim();
  1628. \t\t\t\t\$(this).find('.tg-axis-selected').text(label);
  1629. \t\t\t});
  1630. \t\t}
  1631. \t\t// =========================================================
  1632. \t\t// fe (sale_type=4) ブロック種類×段数 サブ UI
  1633. \t\t// =========================================================
  1634. \t\t/**
  1635. \t\t * fe_block の親オプション (= op_data 内の「ご希望のフェンス設置方法」 entry)
  1636. \t\t * を name でルックアップし、その index を返す. 見つからなければ -1.
  1637. \t\t *   fe_block.depends_on_name が設定されていればそれで照合.
  1638. \t\t *   未設定なら 'ご希望のフェンス設置方法' を含む name にフォールバック.
  1639. \t\t */
  1640. \t\tfunction findFeBlockParentOpIndex() {
  1641. \t\t\tif (!oi_data || !oi_data.fe_block) return -1;
  1642. \t\t\tvar needle = oi_data.fe_block.depends_on_name || 'ご希望のフェンス設置方法';
  1643. \t\t\tfor (var i = 0; i < op_data.length; i++) {
  1644. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  1645. \t\t\t\tif (op_data[i].name.indexOf(needle) >= 0) return i;
  1646. \t\t\t}
  1647. \t\t\treturn -1;
  1648. \t\t}
  1649. \t\t/**
  1650. \t\t * fe_block の現在の選択値の price (税抜) と choice 内容を集計.
  1651. \t\t *   親オプション (= 'ご希望のフェンス設置方法') が depends_on_value を選んでいる
  1652. \t\t *   ときだけ加算する. それ以外 (既存ブロック側 / 親未選択) は price=0.
  1653. \t\t * 戻り値: { price: 0|N, choice: {key,label,price}|null, active: bool }
  1654. \t\t */
  1655. \t\tfunction collectFeBlock() {
  1656. \t\t\tvar result = { price: 0, choice: null, active: false };
  1657. \t\t\tif (SALE_TYPE_ID !== 4) return result;
  1658. \t\t\tif (!oi_data || !oi_data.fe_block) return result;
  1659. \t\t\tif (!oi_data.fe_block.choices || !oi_data.fe_block.choices.length) return result;
  1660. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1661. \t\t\tif (parentIdx < 0) return result;
  1662. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1663. \t\t\tvar parentSel = ops[parentIdx];
  1664. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  1665. \t\t\tif (parentSel !== triggerValue) return result;  // 親が新規ブロック積み以外なら無加算
  1666. \t\t\tresult.active = true;
  1667. \t\t\tvar choices = oi_data.fe_block.choices;
  1668. \t\t\tvar pick = null;
  1669. \t\t\tfor (var j = 0; j < choices.length; j++) {
  1670. \t\t\t\tif (choices[j].key === fe_block_selected) { pick = choices[j]; break; }
  1671. \t\t\t}
  1672. \t\t\tif (!pick) pick = choices[0];
  1673. \t\t\tresult.choice = pick;
  1674. \t\t\tresult.price  = parseInt(pick.price) || 0;
  1675. \t\t\treturn result;
  1676. \t\t}
  1677. \t\t/**
  1678. \t\t * fe_block ラジオ群を #fe-block-options 要素に描画する.
  1679. \t\t *   active=false (親が「新規にブロック積み」以外) のときは非表示.
  1680. \t\t */
  1681. \t\tfunction renderFeBlockRadios() {
  1682. \t\t\tvar \$box = \$('#fe-block-options');
  1683. \t\t\tif (!\$box.length) return;
  1684. \t\t\tif (!oi_data || !oi_data.fe_block || !oi_data.fe_block.choices) {
  1685. \t\t\t\t\$box.empty().hide();
  1686. \t\t\t\treturn;
  1687. \t\t\t}
  1688. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1689. \t\t\tif (parentIdx < 0) {
  1690. \t\t\t\t\$box.empty().hide();
  1691. \t\t\t\treturn;
  1692. \t\t\t}
  1693. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1694. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  1695. \t\t\tvar visible = (ops[parentIdx] === triggerValue);
  1696. \t\t\tif (!visible) {
  1697. \t\t\t\t\$box.hide();
  1698. \t\t\t\treturn;
  1699. \t\t\t}
  1700. \t\t\tvar fb = oi_data.fe_block;
  1701. \t\t\t\$box.empty();
  1702. \t\t\tvar \$title = \$('<p class=\"rp-section-label\"><strong>' + (fb.title || 'ブロックの種類と段数') + '</strong></p>');
  1703. \t\t\t\$box.append(\$title);
  1704. \t\t\t// 他オプション群と同じ .opt-btn-group / .opt-btn 形式で描画.
  1705. \t\t\t//   生の <label><input type=radio> ... 形式だと CSS 定義が無く
  1706. \t\t\t//   ラベル折り返し・縦ズレ・隣接 opt-btn との間隔不揃いが発生する.
  1707. \t\t\tvar \$list = \$('<div class=\"opt-btn-group no-hscroll\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  1708. \t\t\tfb.choices.forEach(function(ch) {
  1709. \t\t\t\tvar inputId = 'fe_block_' + ch.key;
  1710. \t\t\t\tvar isSel   = (ch.key === fe_block_selected);
  1711. \t\t\t\tvar checked = isSel ? ' checked' : '';
  1712. \t\t\t\tvar selCls  = isSel ? ' is-selected' : '';
  1713. \t\t\t\t// 選択肢ラベルには価格を表示しない(差額は合計金額側でのみ反映)。
  1714. \t\t\t\t\$list.append(
  1715. \t\t\t\t\t'<label class=\"opt-btn' + selCls + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  1716. \t\t\t\t\t'<input type=\"radio\" name=\"fe_block\" id=\"' + inputId + '\" value=\"' + ch.key + '\"' + checked + '>' +
  1717. \t\t\t\t\t'<span class=\"fe-block-label\">' + ch.label + '</span>' +
  1718. \t\t\t\t\t'</label>'
  1719. \t\t\t\t);
  1720. \t\t\t});
  1721. \t\t\t\$box.append(\$list);
  1722. \t\t\t\$box.show();
  1723. \t\t\t\$box.off('change.fe_block').on('change.fe_block', 'input[type=\"radio\"][name=\"fe_block\"]', function() {
  1724. \t\t\t\tfe_block_selected = \$(this).val();
  1725. \t\t\t\t// is-selected 切替 (opt-btn 形式共通)
  1726. \t\t\t\t\$box.find('label.opt-btn').removeClass('is-selected');
  1727. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  1728. \t\t\t\tmitsumori_simulation('refresh', '');
  1729. \t\t\t});
  1730. \t\t}
  1731. \t\t/**
  1732. \t\t * fe (sale_type=4) で op_data エントリの連動表示制御.
  1733. \t\t *   親「ご希望のフェンス設置方法」の選択値に応じて、
  1734. \t\t *     - 「既存ブロックに穴空け工事が必要ですか?」 entry を表示/非表示
  1735. \t\t *   切替の trigger は親選択値の文字列で判定 (entry index にハードコードしない).
  1736. \t\t */
  1737. \t\tfunction updateFeOpConditionalVisibility() {
  1738. \t\t\tif (SALE_TYPE_ID !== 4) return;
  1739. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1740. \t\t\tif (parentIdx < 0) return;
  1741. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1742. \t\t\tvar parentSel = ops[parentIdx];
  1743. \t\t\t// 親が「既存ブロックに設置する」 (= off 側) のとき穴空け entry を表示
  1744. \t\t\tvar triggerOffValue = (op_data[parentIdx] && op_data[parentIdx].off) || '既存ブロックに設置する';
  1745. \t\t\t\$('div[data-op-name]').each(function() {
  1746. \t\t\t\tvar n = \$(this).attr('data-op-name') || '';
  1747. \t\t\t\tif (n.indexOf('穴空け') >= 0) {
  1748. \t\t\t\t\tif (parentSel === triggerOffValue) {
  1749. \t\t\t\t\t\t\$(this).show();
  1750. \t\t\t\t\t} else {
  1751. \t\t\t\t\t\t\$(this).hide();
  1752. \t\t\t\t\t}
  1753. \t\t\t\t}
  1754. \t\t\t});
  1755. \t\t}
  1756. \t\t/**
  1757. \t\t * 選択中の施工オプションを集計し、ON選択分の price を合計する.
  1758. \t\t * 戻り値: { total: 合計金額, items: [{name, value, price}, ...] }
  1759. \t\t */
  1760. \t\tfunction collectOptions() {
  1761. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1762. \t\t\tvar total = 0;
  1763. \t\t\tvar items = [];
  1764. \t\t\tfor (var i = 0; i < ops.length; i++) {
  1765. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  1766. \t\t\t\tvar sel = ops[i];
  1767. \t\t\t\tif (!sel) continue;
  1768. \t\t\t\tvar price = parseInt(op_data[i].price) || 0;
  1769. \t\t\t\t// 「ON」選択時のみ加算(OFF や「不要」「商品購入のみ」は加算しない)
  1770. \t\t\t\tvar isOn = (sel === op_data[i].on);
  1771. \t\t\t\titems.push({
  1772. \t\t\t\t\tname:  op_data[i].name,
  1773. \t\t\t\t\tvalue: sel,
  1774. \t\t\t\t\tprice: isOn ? price : 0,
  1775. \t\t\t\t\ton:    op_data[i].on,
  1776. \t\t\t\t\toff:   op_data[i].off,
  1777. \t\t\t\t});
  1778. \t\t\t\tif (isOn) total += price;
  1779. \t\t\t}
  1780. \t\t\t// fe (sale_type=4) のブロック種類×段数 分を items / total に統合.
  1781. \t\t\t// 親オプション「ご希望のフェンス設置方法」 が 「新規にブロック積みを行う」 のとき
  1782. \t\t\t// だけ加算される (collectFeBlock 内で判定済み).
  1783. \t\t\tvar fb = collectFeBlock();
  1784. \t\t\tif (fb.active && fb.choice) {
  1785. \t\t\t\titems.push({
  1786. \t\t\t\t\tname:  (oi_data.fe_block && oi_data.fe_block.title) || 'ブロックの種類と段数',
  1787. \t\t\t\t\tvalue: fb.choice.label,
  1788. \t\t\t\t\tprice: fb.price,
  1789. \t\t\t\t\ton:    fb.choice.label,
  1790. \t\t\t\t\toff:   '',
  1791. \t\t\t\t});
  1792. \t\t\t\ttotal += fb.price;
  1793. \t\t\t}
  1794. \t\t\treturn { total: total, items: items };
  1795. \t\t}
  1796. \t\t/**
  1797. \t\t * free_area 1 エントリ ({w,d,h,m,c,price,unit_price,maker_price,ct,option1,option2})
  1798. \t\t * から sale_type 別に最終金額を算出する.
  1799. \t\t *
  1800. \t\t * 計算式(amount=1 ベース、出口で × 1.10 税込化):
  1801. \t\t *   1 通常        : price + ct + option_sum
  1802. \t\t *   2 補助金窓    : price × set_count + (ct + (set_count-1) × option2) + option_sum
  1803. \t\t *   3 物置        : (price + ct) × daisu + option_sum
  1804. \t\t *   4 フェンス    : price + (maisu-1) × unit_price
  1805. \t\t *                  + ct + max(0, maisu-3) × option1
  1806. \t\t *                  + option_sum   (maisu >= 3)
  1807. \t\t *   5 デッキ      : price + ct + option_sum   (area は表示用、計算非関与)
  1808. \t\t *   6 芝生        : price × ceil(area / (w_m × h_m)) + ct + option_sum
  1809. \t\t *   9 商品のみ    : price のみ(カート quantity 倍で総額)
  1810. \t\t *
  1811. \t\t * fe では option1 を ct_up、um では option2 を ct_up として転用.
  1812. \t\t * tf では w / h にロール幅・長さが格納されており parseLen で数値抽出.
  1813. \t\t *
  1814. \t\t * @param {Object} pp  free_area の 1 行(matrix エントリ)
  1815. \t\t * @param {number} optionTotal  collectOptions().total
  1816. \t\t * @param {Object} ctx  UI 入力 {set_count, daisu, maisu, area, quantityOnly, ...}
  1817. \t\t * @returns {Object} {goukei, price, ct, opt, qty}  すべて税込整数
  1818. \t\t */
  1819. \t\tfunction calcGoukei(pp, optionTotal, ctx) {
  1820. \t\t\tvar basePrice  = parseInt(pp.price)       || 0;
  1821. \t\t\tvar baseCt     = parseInt(pp.ct)          || 0;
  1822. \t\t\tvar unitPrice  = parseInt(pp.unit_price)  || 0;
  1823. \t\t\tvar optSum     = optionTotal;
  1824. \t\t\tvar price      = basePrice;
  1825. \t\t\tvar ct         = baseCt;
  1826. \t\t\tvar steelRoof  = 0;   // cp 折半屋根(スチール折板 = option1, ex-shop同額)
  1827. \t\t\tvar qty        = 1;
  1828. \t\t\tvar goukei     = 0;
  1829. \t\t\t// 「商品購入のみ」選択時は工事費・オプションをゼロにする(任意 sale_type で適用)
  1830. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1831. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  1832. \t\t\tif (purchaseOnly) {
  1833. \t\t\t\tbaseCt = 0;
  1834. \t\t\t\tct     = 0;
  1835. \t\t\t\toptSum = 0;
  1836. \t\t\t}
  1837. \t\t\tswitch (SALE_TYPE_ID) {
  1838. \t\t\t\tcase 2: {  // 補助金・窓 (シンプル表引き方式 2026-05-)
  1839. \t\t\t\t\t// 2026-05 仕様簡素化: 枚数軸を廃止し、subtype に枚数を内包.
  1840. \t\t\t\t\t// pp.price / pp.ct は (W, H, ガラス, subtype) の単一価格.
  1841. \t\t\t\t\t// 複数枚をまとめて買う場合はカート quantity で表現.
  1842. \t\t\t\t\tqty    = 1;
  1843. \t\t\t\t\tprice  = basePrice;
  1844. \t\t\t\t\tct     = baseCt;
  1845. \t\t\t\t\tgoukei = price + ct + optSum;
  1846. \t\t\t\t\tbreak;
  1847. \t\t\t\t}
  1848. \t\t\t\tcase 3: {  // 物置・ゴミステーション
  1849. \t\t\t\t\tqty   = Math.max(1, parseInt(ctx.daisu) || 1);
  1850. \t\t\t\t\tprice = basePrice * qty;
  1851. \t\t\t\t\tct    = baseCt * qty;
  1852. \t\t\t\t\tgoukei = price + ct + optSum;
  1853. \t\t\t\t\tbreak;
  1854. \t\t\t\t}
  1855. \t\t\t\tcase 4: {  // フェンス・組み立て式(maisu ≥ 3、base_amount = 3)
  1856. \t\t\t\t\t// scraper は amount=3 を base にしているので pp.price = price(3),
  1857. \t\t\t\t\t// pp.unit_price = price(4) - price(3).
  1858. \t\t\t\t\tqty   = Math.max(3, parseInt(ctx.maisu) || 3);
  1859. \t\t\t\t\tprice = basePrice + (qty - 3) * unitPrice;
  1860. \t\t\t\t\t// option1 が ct_up (4枚目以降の増分). 未設定なら ct 固定動作
  1861. \t\t\t\t\tvar ctUp1 = parseInt(pp.option1) || 0;
  1862. \t\t\t\t\tct = baseCt + Math.max(0, qty - 3) * ctUp1;
  1863. \t\t\t\t\t// fe_block(ブロック積み段数): collectOptions が base(3枚分)を optSum に
  1864. \t\t\t\t\t// 算入済み. ブロック費も本体同様に枚数連動するため、4枚目以降は 1枚毎に
  1865. \t\t\t\t\t// choice.unit_price(= block(4)-block(3)) を加算する.
  1866. \t\t\t\t\t// (顧客指摘「何枚施工でも増える金額が同じ」の是正。unit_price 未設定の
  1867. \t\t\t\t\t//  旧データでは +0 で従来動作。)
  1868. \t\t\t\t\tif (!purchaseOnly) {
  1869. \t\t\t\t\t\tvar fbC = collectFeBlock();
  1870. \t\t\t\t\t\tif (fbC.active && fbC.choice) {
  1871. \t\t\t\t\t\t\toptSum += Math.max(0, qty - 3) * (parseInt(fbC.choice.unit_price) || 0);
  1872. \t\t\t\t\t\t}
  1873. \t\t\t\t\t}
  1874. \t\t\t\t\tgoukei = price + ct + optSum;
  1875. \t\t\t\t\tbreak;
  1876. \t\t\t\t}
  1877. \t\t\t\tcase 5: {  // ウッドデッキ・タイルデッキ
  1878. \t\t\t\t\t// area は担当者向けの参考値として保持(計算には使わない)
  1879. \t\t\t\t\tqty    = 1;
  1880. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  1881. \t\t\t\t\tprice  = basePrice;
  1882. \t\t\t\t\tct     = baseCt;
  1883. \t\t\t\t\tbreak;
  1884. \t\t\t\t}
  1885. \t\t\t\tcase 6: {  // 芝生・人工芝(ロール単位)
  1886. \t\t\t\t\t// pp.w \"1m\", pp.h \"10m\" から数値抽出
  1887. \t\t\t\t\tvar w_m = parseLen(pp.w);
  1888. \t\t\t\t\tvar h_m = parseLen(pp.h);
  1889. \t\t\t\t\tvar rollSize = w_m * h_m;
  1890. \t\t\t\t\tif (!rollSize || rollSize <= 0) rollSize = 1;
  1891. \t\t\t\t\t// 施工サイズ(面積)があれば必要枚数を自動算出。無ければ直接指定の枚数を使う。
  1892. \t\t\t\t\tvar area  = parseFloat(ctx.area) || 0;
  1893. \t\t\t\t\tif (area > 0) {
  1894. \t\t\t\t\t\tqty = Math.max(1, Math.ceil(area / rollSize));
  1895. \t\t\t\t\t} else {
  1896. \t\t\t\t\t\tqty = Math.max(1, parseInt(ctx.tf_qty) || 1);
  1897. \t\t\t\t\t}
  1898. \t\t\t\t\tprice  = basePrice * qty;
  1899. \t\t\t\t\tct     = baseCt;
  1900. \t\t\t\t\tgoukei = price + ct + optSum;
  1901. \t\t\t\t\tbreak;
  1902. \t\t\t\t}
  1903. \t\t\t\tcase 7: {  // 数量買い・基本工事費固定(gf ガーデンファニチャー / st 石材)
  1904. \t\t\t\t\tqty    = Math.max(1, parseInt(ctx.suuryou) || 1);
  1905. \t\t\t\t\tprice  = basePrice * qty;
  1906. \t\t\t\t\tct     = baseCt;                 // ct は固定(数量に依らない)
  1907. \t\t\t\t\tgoukei = price + ct + optSum;
  1908. \t\t\t\t\tbreak;
  1909. \t\t\t\t}
  1910. \t\t\t\tcase 9: {  // 商品のみ購入
  1911. \t\t\t\t\t// カート側で quantity × unit price するため goukei は単品価格
  1912. \t\t\t\t\tqty    = parseInt(ctx.quantityOnly) || 1;
  1913. \t\t\t\t\tprice  = basePrice;
  1914. \t\t\t\t\tct     = 0;
  1915. \t\t\t\t\toptSum = 0;
  1916. \t\t\t\t\tgoukei = price;
  1917. \t\t\t\t\tbreak;
  1918. \t\t\t\t}
  1919. \t\t\t\tdefault: {  // 1: 通常(カーポート等、matrix 選択のみ)
  1920. \t\t\t\t\tqty    = 1;
  1921. \t\t\t\t\t// cp 折半屋根(スチール折板 = option1, ex-shop同額)を工事費として加算。
  1922. \t\t\t\t\t// 非折板/他カテゴリは option1='' or 非数値 → 0。
  1923. \t\t\t\t\tsteelRoof = purchaseOnly ? 0 : (parseInt(pp.option1) || 0);
  1924. \t\t\t\t\tgoukei = basePrice + baseCt + steelRoof + optSum;
  1925. \t\t\t\t\tbreak;
  1926. \t\t\t\t}
  1927. \t\t\t}
  1928. \t\t\t// 出口で税込化(pp.price/pp.ct/op_data.price はすべて税抜で保存されている前提)
  1929. \t\t\t// 税込は請求額(mitsumori_json)・見積書・PDF 用。税抜(*Exc)は詳細ページの表示専用。
  1930. \t\t\treturn {
  1931. \t\t\t\tgoukei: toIncTax(goukei),
  1932. \t\t\t\tprice:  toIncTax(price),
  1933. \t\t\t\tct:     toIncTax(ct),
  1934. \t\t\t\tsteelRoof: toIncTax(steelRoof),
  1935. \t\t\t\topt:    toIncTax(optSum),
  1936. \t\t\t\tgoukeiExc: goukei,
  1937. \t\t\t\tpriceExc:  price,
  1938. \t\t\t\tctExc:     ct,
  1939. \t\t\t\tsteelRoofExc: steelRoof,
  1940. \t\t\t\toptExc:    optSum,
  1941. \t\t\t\tqty:    qty,
  1942. \t\t\t};
  1943. \t\t}
  1944. \t\t/**
  1945. \t\t * 寸法文字列から「メートル単位の数値」を抽出する.
  1946. \t\t *
  1947. \t\t * 単位は m / cm / mm を認識し、いずれも m 単位に正規化して返す.
  1948. \t\t * 単位が無い場合は m 単位とみなす(旧 tf データ \"1m\" \"10m\" との互換).
  1949. \t\t * 数値が見つからない場合は 0 を返す(呼び出し側で fallback).
  1950. \t\t *
  1951. \t\t * 例:
  1952. \t\t *   \"1m\"     → 1
  1953. \t\t *   \"100cm\"  → 1   (2026-06 以降の m → cm 正規化に対応)
  1954. \t\t *   \"200cm\"  → 2
  1955. \t\t *   \"5.5m\"   → 5.5
  1956. \t\t *   \"1000mm\" → 1
  1957. \t\t *   \"\"       → 0
  1958. \t\t */
  1959. \t\tfunction parseLen(s) {
  1960. \t\t\tif (!s) return 0;
  1961. \t\t\tvar str = String(s);
  1962. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)\\s*(mm|cm|m)?/i);
  1963. \t\t\tif (!m) return 0;
  1964. \t\t\tvar n = parseFloat(m[1]);
  1965. \t\t\tif (isNaN(n)) return 0;
  1966. \t\t\tvar unit = (m[2] || 'm').toLowerCase();
  1967. \t\t\tif (unit === 'cm') return n / 100;
  1968. \t\t\tif (unit === 'mm') return n / 1000;
  1969. \t\t\treturn n;  // 'm' or no unit
  1970. \t\t}
  1971. \t\t// pp は autoSelectFirstColor 等からも参照するので global にする
  1972. \t\tvar pp = ";
  1973.         // line 1818
  1974.         echo (isset($context["pp"]) || array_key_exists("pp"$context) ? $context["pp"] : (function () { throw new RuntimeError('Variable "pp" does not exist.'1818$this->source); })());
  1975.         echo ";
  1976. \t\t// sale_type=2 の幅 / 高さ ladder (Twig p_w / p_h を JS で参照するため).
  1977. \t\t// 入力 mm 値を pp の幅・高さバケット文字列にマッピングする際の元データ.
  1978. \t\t// p_w / p_h は連想配列で来ることがあるため Object.values で配列化する.
  1979. \t\tvar PP_W_LADDER = Object.values(";
  1980.         // line 1823
  1981.         echo json_encode(((array_key_exists("p_w"$context)) ? (_twig_default_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'1823$this->source); })()), [])) : ([])));
  1982.         echo " || {});
  1983. \t\tvar PP_H_LADDER = Object.values(";
  1984.         // line 1824
  1985.         echo json_encode(((array_key_exists("p_h"$context)) ? (_twig_default_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'1824$this->source); })()), [])) : ([])));
  1986.         echo " || {});
  1987. \t\t/* ============================================================
  1988. \t\t   sale_type=2 (補助金窓) 専用: 複数タイプ集計 & 補助金計算
  1989. \t\t   ============================================================
  1990. \t\t   - 入力 UI: #window-types-container 配下の .window-type-block
  1991. \t\t   - 補助金根拠: 先進的窓リノベ2026事業
  1992. \t\t     https://window-renovation2026.env.go.jp/construction/inner-window.html
  1993. \t\t   - 価格軸: (subtype, w, h, glass, color) で pp を lookup
  1994. \t\t   - 1 商品 = 1 明細 にまとめ、内訳 JSON を別途保存予定 (cart 連携は後続タスク)
  1995. \t\t   ============================================================ */
  1996. \t\t// 補助金マトリクス: [住宅区分][性能][サイズ区分] → 1 箇所あたり金額 (税抜・端数なし)
  1997. \t\tvar WINDOW_SUBSIDY_MATRIX = {
  1998. \t\t\tdetached:  { // 戸建住宅・延床240㎡以下の非住宅
  1999. \t\t\t\tP: { G: 140000, L: 89000, M: 58000, S: 36000 },
  2000. \t\t\t\tS: { G: 76000,  L: 52000, M: 34000, S: 22000 }
  2001. \t\t\t},
  2002. \t\t\tapartment: { // 低層・中高層集合住宅・240㎡超の非住宅
  2003. \t\t\t\tP: { G: 152000, L: 98000, M: 64000, S: 40000 },
  2004. \t\t\t\tS: { G: 83000,  L: 57000, M: 37000, S: 24000 }
  2005. \t\t\t}
  2006. \t\t};
  2007. \t\t// 住宅区分: 画面 UI (input[name=\"window_housing_type\"]) から取得する.
  2008. \t\t// 既定値は PFC meta_key=\"住宅区分\" を fallback (未設定なら '戸建').
  2009. \t\tvar HOUSING_TYPE_DEFAULT = ";
  2010.         // line 1850
  2011.         echo json_encode(_twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1850$this->source); })()), "id", [], "any"falsefalsefalse1850), "住宅区分"), "戸建"));
  2012.         echo ";
  2013. \t\tfunction getCurrentHousingKey() {
  2014. \t\t\tvar el = document.querySelector('input[name=\"window_housing_type\"]:checked');
  2015. \t\t\tvar v  = el ? el.value : HOUSING_TYPE_DEFAULT;
  2016. \t\t\treturn (v === '集合住宅') ? 'apartment' : 'detached';
  2017. \t\t}
  2018. \t\t// 商品シリーズ自動判定 (Product.name から)
  2019. \t\t// 根拠カタログ: YKK AP「ウチリモ」XAAAA-H26-067-1 (2026.04), 同「LiteU」XAAAA-H16-088-2,
  2020. \t\t//              三協アルミ「プラメイクEII」0142_STJ1931L, LIXIL「インプラス」(既知)
  2021. \t\tvar PRODUCT_NAME_RAW = ";
  2022.         // line 1860
  2023.         echo json_encode(((twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "name", [], "any"truetruefalse1860)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "name", [], "any"falsefalsefalse1860), "")) : ("")));
  2024.         echo ";
  2025. \t\tfunction detectProductSeries(name) {
  2026. \t\t\tif (!name) return null;
  2027. \t\t\tif (/ウチリモ/.test(name)) return 'uchirimo';
  2028. \t\t\tif (/プラマード\\s*U/i.test(name)) return 'pramado_u';
  2029. \t\t\tif (/インプラス/.test(name)) return 'inplus';
  2030. \t\t\tif (/プラメイク\\s*EII|プラメイクEII/i.test(name)) return 'plamake_eii';
  2031. \t\t\tif (/LiteU/i.test(name)) return 'lite_u';
  2032. \t\t\treturn null;
  2033. \t\t}
  2034. \t\t// シリーズ上限グレード:
  2035. \t\t//   'P'  = SS/P まで到達可能 (真空断熱ガラス採用シリーズ)
  2036. \t\t//   'S'  = Low-E 複層止まり (真空断熱ガラスのラインなし)
  2037. \t\t//   null = 単板のみ → 補助金対象外
  2038. \t\tvar SERIES_GRADE_CAP = {
  2039. \t\t\tuchirimo:    'P',
  2040. \t\t\tpramado_u:   'P',
  2041. \t\t\tinplus:      'S',
  2042. \t\t\tplamake_eii: 'S',
  2043. \t\t\tlite_u:      null
  2044. \t\t};
  2045. \t\tvar DETECTED_SERIES = detectProductSeries(PRODUCT_NAME_RAW);
  2046. \t\tvar SERIES_GRADE_CAP_VAL = (DETECTED_SERIES !== null && Object.prototype.hasOwnProperty.call(SERIES_GRADE_CAP, DETECTED_SERIES))
  2047. \t\t\t? SERIES_GRADE_CAP[DETECTED_SERIES]
  2048. \t\t\t: undefined;
  2049. \t\t// 商品単位グレード上限 (PFC `meta_key=補助金グレード上限` で個別上書き)
  2050. \t\t// 値: 'P' / 'SS' / 'S' / '対象外' / '無' / 'NONE' / 空文字 (未指定)
  2051. \t\tvar PRODUCT_GRADE_CAP_RAW = ";
  2052.         // line 1888
  2053.         echo json_encode(_twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1888$this->source); })()), "id", [], "any"falsefalsefalse1888), "補助金グレード上限"), ""));
  2054.         echo ";
  2055. \t\tfunction normalizeGradeCap(v) {
  2056. \t\t\tif (v === null || v === undefined || v === '') return undefined;
  2057. \t\t\tvar s = String(v).trim().toUpperCase();
  2058. \t\t\tif (s === 'NONE' || s === '対象外' || s === '無') return null;
  2059. \t\t\tif (s === 'P' || s === 'SS') return 'P';
  2060. \t\t\tif (s === 'S') return 'S';
  2061. \t\t\treturn undefined;
  2062. \t\t}
  2063. \t\tvar PRODUCT_GRADE_CAP = normalizeGradeCap(PRODUCT_GRADE_CAP_RAW);
  2064. \t\t// 窓種 (subtype = option1) ごとのグレード上限.
  2065. \t\t// 根拠: YKK AP「ウチリモ」業務用 (XAAAA-H26-067-1) の窓種別ラインナップで
  2066. \t\t//      真空ガラス (Glavenir) の設定有無を確認:
  2067. \t\t//        引違い窓 (2/3/4枚建) / 浴室仕様 引違い窓 / FIX窓        → P 到達可能
  2068. \t\t//        内開き窓 (居室/浴室) / 開き窓テラス / テラスドア類       → 真空ガラスなし → S 止まり
  2069. \t\tfunction detectSubtypeGradeCap(subtype) {
  2070. \t\t\tif (!subtype) return undefined;
  2071. \t\t\tvar s = String(subtype);
  2072. \t\t\tif (/内開|開き窓テラス|テラスドア|開き戸/.test(s)) return 'S';
  2073. \t\t\treturn undefined;
  2074. \t\t}
  2075. \t\t// クリップ: 強さは 'P' > 'S' > null (対象外). cap=null は強制対象外, cap=undefined は無効化なし.
  2076. \t\tfunction clipGradeBy(grade, cap) {
  2077. \t\t\tif (cap === undefined) return grade;
  2078. \t\t\tif (cap === null)      return null;
  2079. \t\t\tif (grade === null)    return null;
  2080. \t\t\tif (cap === 'S' && grade === 'P') return 'S';
  2081. \t\t\treturn grade;
  2082. \t\t}
  2083. \t\t// D-2/D-3: 一部の窓種は Low-E に「アルゴンガス入り」が必須で、ガス無は補助対象外.
  2084. \t\t//   - 浴室仕様 (ウチリモ): Low-E は Ar入のみ S、Ar無は対象外
  2085. \t\t//   - インプラス 開き窓 / テラスドア: Low-E複層 ガス有のみ S、ガス無は対象外
  2086. \t\t//   ※ 引違い窓・FIX窓・(非浴室)内開き窓は従来どおり Ar 有無を問わない.
  2087. \t\t//   server 側 WindowSubsidyCalculator の subtypeRequiresArgon / glassHasArgon /
  2088. \t\t//   applyArgonRequirement と完全一致させること.
  2089. \t\tfunction subtypeRequiresArgon(series, subtype) {
  2090. \t\t\tvar s = String(subtype || '');
  2091. \t\t\tif (/浴室/.test(s)) return true;
  2092. \t\t\tif (series === 'inplus' && (/テラスドア/.test(s) || (/開き窓/.test(s) && !/内開き/.test(s)))) return true;
  2093. \t\t\treturn false;
  2094. \t\t}
  2095. \t\tfunction glassHasArgon(glassName) {
  2096. \t\t\treturn /アルゴンガス入り/.test(String(glassName || ''));
  2097. \t\t}
  2098. \t\tfunction applyArgonRequirement(grade, glassName, subtype) {
  2099. \t\t\tif (grade === null) return null;
  2100. \t\t\t// 真空(P)等 Low-E 以外はこの規則の対象外 (真空はガス不要).
  2101. \t\t\tif (!/Low-?E/i.test(String(glassName || ''))) return grade;
  2102. \t\t\tif (subtypeRequiresArgon(DETECTED_SERIES, subtype) && !glassHasArgon(glassName)) return null;
  2103. \t\t\treturn grade;
  2104. \t\t}
  2105. \t\tfunction finalizeGlassGrade(raw, subtype, glassName) {
  2106. \t\t\tvar g = clipGradeBy(raw, SERIES_GRADE_CAP_VAL);
  2107. \t\t\tg     = clipGradeBy(g,   detectSubtypeGradeCap(subtype));
  2108. \t\t\tg     = clipGradeBy(g,   PRODUCT_GRADE_CAP);
  2109. \t\t\tg     = applyArgonRequirement(g, glassName, subtype);
  2110. \t\t\treturn g;
  2111. \t\t}
  2112. \t\t/**
  2113. \t\t * ガラスタイプ名から性能区分 'P' (SS, Uw≤1.1) / 'S' (Uw≤1.5) / null を判別.
  2114. \t\t * null = 補助対象外.
  2115. \t\t *
  2116. \t\t * 根拠: YKK AP「ウチリモ 内窓」業務用カタログ (XAAAA-H26-069-1) で
  2117. \t\t *       P (SS) は真空断熱ガラスのみ、Low-E はアルゴン入りでも S 止まり、
  2118. \t\t *       Low-E ガス無 + 型ガラス / フロストは 2026年4月で対象外、
  2119. \t\t *       が確認できた。アルゴン入り Low-E を P 判定する旧ルールは誤りだった。
  2120. \t\t *
  2121. \t\t * シリーズによっては P がそもそも存在しない (LIXIL インプラスは S 一律)
  2122. \t\t * ため、最終的には PFC で商品単位の上限を上書きできる仕組みが必要。
  2123. \t\t */
  2124. \t\tfunction detectGlassPerformance(glassName) {
  2125. \t\t\tif (!glassName) return null;
  2126. \t\t\tvar n = String(glassName);
  2127. \t\t\t// 補助対象外: 単板 / 和紙調 / 防音 / 防犯 / 型ガラス・フロスト (Low-E ガス無の型は 2026/4 で対象外)
  2128. \t\t\tif (/単ガラス|単板|和紙調|防音|防犯|複層\\/型|型ガラス|フロスト/.test(n)) return null;
  2129. \t\t\t// P (SS): 真空断熱ガラスのみ
  2130. \t\t\tif (/真空断熱/.test(n)) return 'P';
  2131. \t\t\t// S: Low-E 系のみ (アルゴン入りでも S 止まり)
  2132. \t\t\tif (/Low-?E/i.test(n)) return 'S';
  2133. \t\t\t// 一般複層 / ブラインドイン複層 / 複層強化 など Low-E 無しの複層は補助対象外
  2134. \t\t\treturn null;
  2135. \t\t}
  2136. \t\t/**
  2137. \t\t * 幅 mm × 高さ mm からサイズ区分 'G' (≥4.0㎡) / 'L' (2.8-3.9) / 'M' (1.6-2.7) / 'S' (0.2-1.5) / null.
  2138. \t\t * null = 補助対象外 (0.2㎡ 未満).
  2139. \t\t */
  2140. \t\tfunction detectSizeClass(w_mm, h_mm) {
  2141. \t\t\tvar w = parseFloat(w_mm) || 0;
  2142. \t\t\tvar h = parseFloat(h_mm) || 0;
  2143. \t\t\tif (w <= 0 || h <= 0) return null;
  2144. \t\t\tvar area = (w * h) / 1000000.0;
  2145. \t\t\tif (area < 0.2) return null;
  2146. \t\t\tif (area < 1.6) return 'S';
  2147. \t\t\tif (area < 2.8) return 'M';
  2148. \t\t\tif (area < 4.0) return 'L';
  2149. \t\t\treturn 'G';
  2150. \t\t}
  2151. \t\tfunction lookupSubsidyAmount(performance, sizeClass) {
  2152. \t\t\tif (!performance || !sizeClass) return 0;
  2153. \t\t\tvar t = WINDOW_SUBSIDY_MATRIX[getCurrentHousingKey()];
  2154. \t\t\tif (!t || !t[performance]) return 0;
  2155. \t\t\treturn t[performance][sizeClass] || 0;
  2156. \t\t}
  2157. \t\t/**
  2158. \t\t * mm 入力値を ladder バケット文字列に変換する.
  2159. \t\t *   bucketizeMm(1750, [\"100cm まで\",\"150cm まで\",\"200cm まで\",\"300cm まで\"]) → \"200cm まで\"
  2160. \t\t * - 入力が空 or 0 のときはそのまま返す (未入力扱い)
  2161. \t\t * - 入力がラダー最大を超えるときは最大バケットを返す (= 価格上限の保護)
  2162. \t\t * - 入力文字列が既にラダーラベルそのものなら無変換 (互換のため)
  2163. \t\t */
  2164. \t\tfunction bucketizeMm(input, ladder) {
  2165. \t\t\tif (!input && input !== 0) return '';
  2166. \t\t\tif (!ladder || ladder.length === 0) return input;
  2167. \t\t\tvar s = String(input).trim();
  2168. \t\t\tif (s === '') return '';
  2169. \t\t\tif (ladder.indexOf(s) >= 0) return s;
  2170. \t\t\tvar mm = parseMm(s);
  2171. \t\t\tif (mm <= 0) return s;
  2172. \t\t\tvar withMax = ladder.map(function(b) { return { label: b, max: parseMm(b) }; });
  2173. \t\t\twithMax.sort(function(a, b) { return a.max - b.max; });
  2174. \t\t\tfor (var i = 0; i < withMax.length; i++) {
  2175. \t\t\t\tif (mm <= withMax[i].max) return withMax[i].label;
  2176. \t\t\t}
  2177. \t\t\treturn withMax[withMax.length - 1].label;
  2178. \t\t}
  2179. \t\t/**
  2180. \t\t * pp 配列から該当 1 行を返す. 完全一致優先、見つからなければ最初の候補.
  2181. \t\t * 軸: subtype (option1) / w / h / m / c. axisMatch は既存ロジックと同じ.
  2182. \t\t * sale_type=2 では pw_val / ph_val に mm 数値が来るため、内部で bucketizeMm
  2183. \t\t * を通してから既存マッチングに渡す.
  2184. \t\t */
  2185. \t\tfunction lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val) {
  2186. \t\t\tif (!pp || pp.length === 0) return null;
  2187. \t\t\tvar pw_bucket = bucketizeMm(pw_val, PP_W_LADDER);
  2188. \t\t\tvar ph_bucket = bucketizeMm(ph_val, PP_H_LADDER);
  2189. \t\t\tvar axMatch = function(input, value) {
  2190. \t\t\t\treturn input == value || input === '指定なし' || value === '' || value == null;
  2191. \t\t\t};
  2192. \t\t\tvar colMatch = function(input, value) {
  2193. \t\t\t\tif (axMatch(input, value)) return true;
  2194. \t\t\t\tif (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  2195. \t\t\t\t\treturn value.split('/').some(function(s) { return s.trim() === input; });
  2196. \t\t\t\t}
  2197. \t\t\t\treturn false;
  2198. \t\t\t};
  2199. \t\t\tvar candidates = pp.filter(function(el) {
  2200. \t\t\t\treturn axMatch(pw_bucket, el.w)
  2201. \t\t\t\t\t&& axMatch(ph_bucket, el.h)
  2202. \t\t\t\t\t&& axMatch(pm_val, el.m)
  2203. \t\t\t\t\t&& axMatch(subtype, el.option1);
  2204. \t\t\t});
  2205. \t\t\tfor (var i = 0; i < candidates.length; i++) {
  2206. \t\t\t\tif (colMatch(pc_val, candidates[i].c)) return candidates[i];
  2207. \t\t\t}
  2208. \t\t\treturn candidates[0] || null;
  2209. \t\t}
  2210. \t\t/**
  2211. \t\t * \"1000mm\" / \"200cm\" / \"1.0m\" / 単位なし → mm に正規化して返す.
  2212. \t\t * UI 上の「200cm まで」等の文字列をそのまま渡せるようにする.
  2213. \t\t */
  2214. \t\tfunction parseMm(s) {
  2215. \t\t\tif (!s) return 0;
  2216. \t\t\tvar str = String(s);
  2217. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)/);
  2218. \t\t\tif (!m) return 0;
  2219. \t\t\tvar num = parseFloat(m[1]);
  2220. \t\t\tif (/mm/i.test(str)) return num;
  2221. \t\t\tif (/cm/i.test(str)) return num * 10;
  2222. \t\t\tif (/(^|\\d)\\s*m(\$|\\W)/i.test(str)) return num * 1000;
  2223. \t\t\treturn num;
  2224. \t\t}
  2225. \t\t/**
  2226. \t\t * 1 タイプブロックから入力を読み、pp lookup → 単価・補助金額を計算して返す.
  2227. \t\t * incomplete=true: 軸のどれかが未選択 → 計算しない (UI で「未選択」を示すため).
  2228. \t\t */
  2229. \t\tfunction collectWindowTypeRow(block) {
  2230. \t\t\tvar get = function(axis) {
  2231. \t\t\t\t// radio / checkbox は :checked、それ以外 (number/text) は値そのまま.
  2232. \t\t\t\tvar radio = block.querySelector('input[data-axis=\"' + axis + '\"]:checked');
  2233. \t\t\t\tif (radio) return radio.value;
  2234. \t\t\t\tvar any = block.querySelector('input[data-axis=\"' + axis + '\"]');
  2235. \t\t\t\tif (!any) return '';
  2236. \t\t\t\tif (any.type === 'radio' || any.type === 'checkbox') return '';
  2237. \t\t\t\treturn (any.value || '').trim();
  2238. \t\t\t};
  2239. \t\t\tvar setqtyEl = block.querySelector('input[data-axis=\"setqty\"]');
  2240. \t\t\tvar subtype = get('subtype');
  2241. \t\t\tvar pw_val  = get('pw');
  2242. \t\t\tvar ph_val  = get('ph');
  2243. \t\t\tvar pm_val  = get('pm');
  2244. \t\t\tvar pc_val  = get('pc');
  2245. \t\t\tvar setqty  = setqtyEl ? Math.max(1, parseInt(setqtyEl.value) || 1) : 1;
  2246. \t\t\tvar row = {
  2247. \t\t\t\tsubtype: subtype, pw: pw_val, ph: ph_val, pm: pm_val, pc: pc_val, setqty: setqty,
  2248. \t\t\t\tunit_price_exc: 0, unit_ct_exc: 0, subsidy: 0,
  2249. \t\t\t\tsize_class: null, glass_perf: null,
  2250. \t\t\t\tincomplete: false
  2251. \t\t\t};
  2252. \t\t\t// p_option1 / p_w / p_h / p_m / color のいずれかが商品データに無いときは未選択でも完了扱いにする.
  2253. \t\t\t// (例: 商品によっては subtype が無い場合がある)
  2254. \t\t\tvar hasSubtype = !!block.querySelector('input[data-axis=\"subtype\"]');
  2255. \t\t\tvar hasPw      = !!block.querySelector('input[data-axis=\"pw\"]');
  2256. \t\t\tvar hasPh      = !!block.querySelector('input[data-axis=\"ph\"]');
  2257. \t\t\tvar hasPm      = !!block.querySelector('input[data-axis=\"pm\"]');
  2258. \t\t\tvar hasPc      = !!block.querySelector('input[data-axis=\"pc\"]');
  2259. \t\t\tif ((hasSubtype && !subtype) || (hasPw && !pw_val) || (hasPh && !ph_val)
  2260. \t\t\t    || (hasPm && !pm_val)  || (hasPc && !pc_val)) {
  2261. \t\t\t\trow.incomplete = true;
  2262. \t\t\t\treturn row;
  2263. \t\t\t}
  2264. \t\t\tvar ppRow = lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val);
  2265. \t\t\tif (ppRow) {
  2266. \t\t\t\trow.unit_price_exc = parseInt(ppRow.price) || 0;
  2267. \t\t\t\trow.unit_ct_exc    = parseInt(ppRow.ct)    || 0;
  2268. \t\t\t}
  2269. \t\t\t// ガラス名検出 → シリーズ上限 → subtype 上限 → 商品上限 の順で min クリップ.
  2270. \t\t\t// 例: LiteU (SERIES_GRADE_CAP_VAL=null) は Low-E でも null に落ちて補助対象外.
  2271. \t\t\t// 例: ウチリモの「内開き窓」subtype は真空ガラスでも S に落ちる.
  2272. \t\t\trow.glass_perf = finalizeGlassGrade(detectGlassPerformance(pm_val), subtype, pm_val);
  2273. \t\t\trow.size_class = detectSizeClass(parseMm(pw_val), parseMm(ph_val));
  2274. \t\t\trow.subsidy    = lookupSubsidyAmount(row.glass_perf, row.size_class);
  2275. \t\t\treturn row;
  2276. \t\t}
  2277. \t\t/**
  2278. \t\t * sale_type=2 用集計: 全タイプから合計を出し DOM 更新.
  2279. \t\t * 計算式 (税抜→税込で出口で 1.10 倍):
  2280. \t\t *   商品金額 = Σ(各タイプ単価 × set_qty)
  2281. \t\t *   基本工事費 = 1 回分 (各タイプ pp.ct のうち最初に得た非ゼロ値)
  2282. \t\t *   補助金合計 = Σ(各タイプ補助金 × set_qty)
  2283. \t\t *   実質支払額 = (商品+ct+option) 税込 - 補助金合計
  2284. \t\t */
  2285. \t\tfunction recalcAllForSaleType2() {
  2286. \t\t\tif (typeof SALE_TYPE_ID === 'undefined' || SALE_TYPE_ID != 2) return;
  2287. \t\t\tif (!pp || pp.length === 0) {
  2288. \t\t\t\t\$('#mitsumori_message').text('価格データ準備中');
  2289. \t\t\t\t\$('#mitsumori_btn').hide();
  2290. \t\t\t\t['#mitsumori_goukei','#mitsumori_off','#mitsumori_price','#maker_price',
  2291. \t\t\t\t '#mitsumori_ct','#mitsumori_option','#mitsumori_kei','#mitsumori_shoukei','#mitsumori_tax']
  2292. \t\t\t\t .forEach(function(s){ \$(s).text('---円'); });
  2293. \t\t\t\treturn;
  2294. \t\t\t}
  2295. \t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  2296. \t\t\tif (blocks.length === 0) return;
  2297. \t\t\tvar rows = [];
  2298. \t\t\tvar hasIncomplete = false;
  2299. \t\t\tvar baseCt = 0;
  2300. \t\t\tvar hasAnyPriced = false;
  2301. \t\t\tblocks.forEach(function(b) {
  2302. \t\t\t\tvar r = collectWindowTypeRow(b);
  2303. \t\t\t\trows.push({ block: b, row: r });
  2304. \t\t\t\tif (r.incomplete) hasIncomplete = true;
  2305. \t\t\t\tif (r.unit_ct_exc > 0 && baseCt === 0) baseCt = r.unit_ct_exc;
  2306. \t\t\t\tif (r.unit_price_exc > 0) hasAnyPriced = true;
  2307. \t\t\t\tvar subSpan = b.querySelector('.wt-subsidy-amount');
  2308. \t\t\t\tif (subSpan) subSpan.textContent = r.incomplete ? '―' : Math.round(r.subsidy * r.setqty).toLocaleString();
  2309. \t\t\t});
  2310. \t\t\tif (hasIncomplete || !hasAnyPriced) {
  2311. \t\t\t\t\$('#mitsumori_message').text('窓タイプを選択してください');
  2312. \t\t\t\t\$('#mitsumori_btn').hide();
  2313. \t\t\t\treturn;
  2314. \t\t\t}
  2315. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  2316. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  2317. \t\t\tvar sumPriceExc = 0, sumSubsidy = 0, totalPanes = 0;
  2318. \t\t\trows.forEach(function(item) {
  2319. \t\t\t\tvar r = item.row;
  2320. \t\t\t\tsumPriceExc += r.unit_price_exc * r.setqty;
  2321. \t\t\t\tsumSubsidy  += r.subsidy * r.setqty;
  2322. \t\t\t\tif (r.unit_price_exc > 0) totalPanes += r.setqty;
  2323. \t\t\t});
  2324. \t\t\t// 内窓 工事費(顧客最終回答): 1枚目 22,000円 + 2枚目以降 1枚あたり +5,000円(税込表示額)。
  2325. \t\t\t// 既存パイプライン整合のため税抜(ctExc)も用意(税行 taxAmt 用)。商品購入のみは 0。
  2326. \t\t\tvar WINDOW_CT_BASE = 22000, WINDOW_CT_ADD = 5000;
  2327. \t\t\tvar ctIncTarget = purchaseOnly ? 0 : (WINDOW_CT_BASE + Math.max(0, totalPanes - 1) * WINDOW_CT_ADD);
  2328. \t\t\tvar ctExc  = purchaseOnly ? 0 : Math.round(ctIncTarget / (1 + TAX_RATE));
  2329. \t\t\tvar optExc = purchaseOnly ? 0 : (collectOptions().total || 0);
  2330. \t\t\tvar sumPriceInc = Math.round(sumPriceExc * (1 + TAX_RATE));
  2331. \t\t\tvar ctInc       = ctIncTarget;
  2332. \t\t\tvar optInc      = Math.round(optExc * (1 + TAX_RATE));
  2333. \t\t\tvar goukeiInc   = sumPriceInc + ctInc + optInc;
  2334. \t\t\t// 窓リノベ2026 申請条件:
  2335. \t\t\t//   - 補助金合計 ≥ 50,000 円 (5 万円未満は申請不可 → 還元 0 円扱い)
  2336. \t\t\t//   - 1 戸あたり上限 1,000,000 円 (住宅・非住宅240㎡以下)
  2337. \t\t\t//     ※ 非住宅 240㎡超の 10,000,000 円上限は対象外 (商品設計時に別扱い想定)
  2338. \t\t\tvar SUBSIDY_MIN_AMOUNT = 50000;
  2339. \t\t\tvar SUBSIDY_MAX_PER_UNIT = 1000000;
  2340. \t\t\tvar subsidyRawSum = sumSubsidy;
  2341. \t\t\tvar subsidyEligible = subsidyRawSum >= SUBSIDY_MIN_AMOUNT;
  2342. \t\t\tvar subsidyAmt = 0;
  2343. \t\t\tvar subsidyNote = '';
  2344. \t\t\tif (subsidyEligible) {
  2345. \t\t\t\tif (subsidyRawSum > SUBSIDY_MAX_PER_UNIT) {
  2346. \t\t\t\t\tsubsidyAmt = SUBSIDY_MAX_PER_UNIT;
  2347. \t\t\t\t\tsubsidyNote = '※補助上限 ' + SUBSIDY_MAX_PER_UNIT.toLocaleString()
  2348. \t\t\t\t\t\t+ '円 超過分は控除対象外(補助金合計 ' + subsidyRawSum.toLocaleString() + '円)';
  2349. \t\t\t\t} else {
  2350. \t\t\t\t\tsubsidyAmt = subsidyRawSum;
  2351. \t\t\t\t\tsubsidyNote = '※補助金合計 ' + subsidyRawSum.toLocaleString()
  2352. \t\t\t\t\t\t+ '円(5万円以上)が適用されます';
  2353. \t\t\t\t}
  2354. \t\t\t} else if (subsidyRawSum > 0) {
  2355. \t\t\t\t// (b) per-window 補助金額は常時表示。合計5万円以上で適用される旨と
  2356. \t\t\t\t//     あといくらで適用かを明示する(閾値 SUBSIDY_MIN_AMOUNT は据え置き)。
  2357. \t\t\t\tvar subsidyShort = SUBSIDY_MIN_AMOUNT - subsidyRawSum;
  2358. \t\t\t\tsubsidyNote = '※補助金は各窓の補助金額の合計が5万円以上で適用されます'
  2359. \t\t\t\t\t+ '(現在の合計 ' + subsidyRawSum.toLocaleString() + '円 / あと '
  2360. \t\t\t\t\t+ subsidyShort.toLocaleString() + '円で適用)';
  2361. \t\t\t} else if (SERIES_GRADE_CAP_VAL === null) {
  2362. \t\t\t\t// LiteU 等の単板構成シリーズ: グレード判定で必ず null になる
  2363. \t\t\t\tsubsidyNote = '※本商品は補助金(先進的窓リノベ2026事業)対象外です';
  2364. \t\t\t} else if (PRODUCT_GRADE_CAP === null) {
  2365. \t\t\t\tsubsidyNote = '※本商品は補助金対象外として登録されています';
  2366. \t\t\t}
  2367. \t\t\tvar implementedInc = Math.max(0, goukeiInc - subsidyAmt);
  2368. \t\t\tvar taxAmt      = Math.round((sumPriceExc + ctExc + optExc) * TAX_RATE);
  2369. \t\t\t// 詳細ページの見積カード/ヘッダー/SPバーは税抜表示に統一.
  2370. \t\t\t// 見積書(#mitsumori_kei)・実質支払額(#mitsumori_shoukei)・税額・json は税込のまま (請求額不変).
  2371. \t\t\tvar goukeiExc = sumPriceExc + ctExc + optExc;
  2372. \t\t\t\$('#mitsumori_message').text(subsidyNote);
  2373. \t\t\t\$('#mitsumori_btn').show();
  2374. \t\t\t\$('#mitsumori_goukei').text(goukeiExc.toLocaleString() + '円');
  2375. \t\t\t\$('#mitsumori_price').text(sumPriceExc.toLocaleString() + '円');
  2376. \t\t\t\$('#mitsumori_ct').text(ctExc.toLocaleString() + '円');
  2377. \t\t\t\$('#mitsumori_option').text(optExc.toLocaleString() + '円');
  2378. \t\t\t\$('#mitsumori_off').text((subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円');
  2379. \t\t\t\$('#maker_price').text('---円'); // 補助金窓では未使用
  2380. \t\t\t\$('#mitsumori_kei').text(goukeiInc.toLocaleString() + '円');
  2381. \t\t\t\$('#mitsumori_shoukei').text(implementedInc.toLocaleString() + '円');
  2382. \t\t\t\$('#mitsumori_tax').text(taxAmt.toLocaleString() + '円');
  2383. \t\t\t// 内訳を mitsumori_json に詰めて hidden input にセット (PDF / カート連携用)
  2384. \t\t\tvar window_types = rows.map(function(item) {
  2385. \t\t\t\tvar r = item.row;
  2386. \t\t\t\t// 幅 / 高さは数値入力 (mm) が来るので \"1750mm\" 形式で保存する.
  2387. \t\t\t\t// 古い radio 由来の \"200cm まで\" 形式が来た場合はそのまま保存して互換.
  2388. \t\t\t\tvar w_mm = parseMm(r.pw);
  2389. \t\t\t\tvar h_mm = parseMm(r.ph);
  2390. \t\t\t\tvar w_save = (w_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.pw))) ? (w_mm + 'mm') : r.pw;
  2391. \t\t\t\tvar h_save = (h_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.ph))) ? (h_mm + 'mm') : r.ph;
  2392. \t\t\t\treturn {
  2393. \t\t\t\t\tsubtype:        r.subtype,
  2394. \t\t\t\t\tw:              w_save,
  2395. \t\t\t\t\th:              h_save,
  2396. \t\t\t\t\tglass:          r.pm,
  2397. \t\t\t\t\tcolor:          r.pc,
  2398. \t\t\t\t\tsetqty:         r.setqty,
  2399. \t\t\t\t\tunit_price_inc: Math.round(r.unit_price_exc * (1 + TAX_RATE)),
  2400. \t\t\t\t\tline_total_inc: Math.round(r.unit_price_exc * r.setqty * (1 + TAX_RATE)),
  2401. \t\t\t\t\tsize_class:     r.size_class,
  2402. \t\t\t\t\tglass_perf:     r.glass_perf,
  2403. \t\t\t\t\tsubsidy_unit:   r.subsidy,
  2404. \t\t\t\t\tsubsidy_total:  r.subsidy * r.setqty
  2405. \t\t\t\t};
  2406. \t\t\t});
  2407. \t\t\tvar opCalc2 = collectOptions();
  2408. \t\t\tvar mitsumori_json = {
  2409. \t\t\t\t\"mitsumori_goukei\": goukeiInc.toLocaleString() + '円',
  2410. \t\t\t\t\"mitsumori_price\":  sumPriceInc.toLocaleString() + '円',
  2411. \t\t\t\t\"mitsumori_ct\":     ctInc.toLocaleString() + '円',
  2412. \t\t\t\t\"mitsumori_option\": optInc.toLocaleString() + '円',
  2413. \t\t\t\t\"mitsumori_off\":    (subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円',
  2414. \t\t\t\t\"maker_price\":      '---円',
  2415. \t\t\t\t\"product_id\":       ";
  2416.         // line 2274
  2417.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2274$this->source); })()), "id", [], "any"falsefalsefalse2274), "html"nulltrue);
  2418.         echo ",
  2419. \t\t\t\t\"sale_type\":        SALE_TYPE_ID,
  2420. \t\t\t\t\"housing_key\":      getCurrentHousingKey(),
  2421. \t\t\t\t\"series_key\":       DETECTED_SERIES,
  2422. \t\t\t\t\"series_grade_cap\": (SERIES_GRADE_CAP_VAL === undefined) ? null : SERIES_GRADE_CAP_VAL,
  2423. \t\t\t\t\"product_grade_cap\":(PRODUCT_GRADE_CAP    === undefined) ? null : PRODUCT_GRADE_CAP,
  2424. \t\t\t\t\"window_types\":     window_types,
  2425. \t\t\t\t\"subsidy_total\":    subsidyAmt,
  2426. \t\t\t\t\"subsidy_raw\":      subsidyRawSum,
  2427. \t\t\t\t\"subsidy_eligible\": subsidyEligible,
  2428. \t\t\t\t\"subsidy_note\":     subsidyNote,
  2429. \t\t\t\t\"op_items\":         opCalc2.items
  2430. \t\t\t};
  2431. \t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  2432. \t\t\trenderWindowTypesModalRows(window_types, subsidyAmt);
  2433. \t\t}
  2434. \t\t/**
  2435. \t\t * sale_type=2 用: 見積モーダル明細テーブルを window_types で動的展開.
  2436. \t\t * - 既存の商品名行 (1 行目) は hide() し、各タイプ行を上に挿入
  2437. \t\t * - 基本工事費行はそのまま (#mitsumori_ct_01 / _02 が更新されている)
  2438. \t\t * - 補助金 (割引額) 行を末尾に追加
  2439. \t\t * - 既存の renderOptionDetailRows と共存できるよう class で区別
  2440. \t\t */
  2441. \t\tfunction renderWindowTypesModalRows(window_types, subsidyAmt) {
  2442. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  2443. \t\t\tif (!\$tbody.length) return;
  2444. \t\t\t// 既存の動的行を全削除 (opt-row は既存実装、wt-row / wt-subsidy-row は今回追加)
  2445. \t\t\t\$tbody.find('tr.wt-row, tr.wt-subsidy-row').remove();
  2446. \t\t\tvar \$itemRow = \$tbody.find('tr').first();
  2447. \t\t\tvar fmt = new Intl.NumberFormat('ja-JP');
  2448. \t\t\tif (!window_types || window_types.length === 0) {
  2449. \t\t\t\t// 集計対象なし → 商品名行を表示に戻す
  2450. \t\t\t\t\$itemRow.show();
  2451. \t\t\t\treturn;
  2452. \t\t\t}
  2453. \t\t\twindow_types.forEach(function(wt, i) {
  2454. \t\t\t\tvar label = '窓タイプ' + (i + 1) + ':'
  2455. \t\t\t\t\t+ (wt.subtype || '') + ' / '
  2456. \t\t\t\t\t+ (wt.w || '') + '×' + (wt.h || '') + ' / '
  2457. \t\t\t\t\t+ (wt.glass || '') + ' / '
  2458. \t\t\t\t\t+ (wt.color || '');
  2459. \t\t\t\tvar \$tr = \$('<tr class=\"wt-row\"></tr>')
  2460. \t\t\t\t\t.append('<td>' + label + '</td>')
  2461. \t\t\t\t\t.append('<td>' + wt.setqty + '</td>')
  2462. \t\t\t\t\t.append('<td>セット</td>')
  2463. \t\t\t\t\t.append('<td>' + fmt.format(wt.unit_price_inc) + '円</td>')
  2464. \t\t\t\t\t.append('<td>' + fmt.format(wt.line_total_inc) + '円</td>');
  2465. \t\t\t\t\$itemRow.before(\$tr);
  2466. \t\t\t});
  2467. \t\t\t// 元の商品名行は複数タイプに置換されたので非表示
  2468. \t\t\t\$itemRow.hide();
  2469. \t\t\t// 補助金(割引額)行を末尾に追加
  2470. \t\t\tif (subsidyAmt > 0) {
  2471. \t\t\t\tvar \$subRow = \$('<tr class=\"wt-subsidy-row\"></tr>')
  2472. \t\t\t\t\t.append('<td>補助金(割引額)</td>')
  2473. \t\t\t\t\t.append('<td>1</td>')
  2474. \t\t\t\t\t.append('<td>式</td>')
  2475. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>')
  2476. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>');
  2477. \t\t\t\t\$tbody.append(\$subRow);
  2478. \t\t\t}
  2479. \t\t}
  2480. \t\t// 公開: onWindowTypeAxisChange (UI 骨格 task 1) からも呼ばれる
  2481. \t\twindow.recalcAll = recalcAllForSaleType2;
  2482. \t\t// 公開: ガラス選択肢が補助金対象か (窓タイプブロック生成時のバッジ判定に使う).
  2483. \t\t// subtype は P→S に落とすことはあっても null にはしないため、性能区分の
  2484. \t\t// 対象/対象外は subtype に依存しない。ここでは series/product 上限のみ適用し、
  2485. \t\t// finalizeGlassGrade が null でなければ「補助金対象ガラス」と判定する。
  2486. \t\twindow.glassYieldsSubsidy = function(glassName) {
  2487. \t\t\tif (!glassName) return false;
  2488. \t\t\treturn finalizeGlassGrade(detectGlassPerformance(glassName), '', glassName) !== null;
  2489. \t\t};
  2490. \t\tfunction mitsumori_simulation(type , value_id){
  2491. \t\t\t// sale_type=2 (補助金窓) は複数タイプ集計 UI に統合済み. 既存 mitsumori_simulation は使わない.
  2492. \t\t\tif (typeof SALE_TYPE_ID !== 'undefined' && SALE_TYPE_ID == 2) {
  2493. \t\t\t\t// type/value_id が op\\d+ (施工オプション) の場合はグローバル変数を先に更新
  2494. \t\t\t\tif (type && /^op\\d+\$/.test(type) && value_id) {
  2495. \t\t\t\t\tvar v = \$('#'+value_id).val();
  2496. \t\t\t\t\tif (type === 'op0')  op0  = v;
  2497. \t\t\t\t\tif (type === 'op1')  op1  = v;
  2498. \t\t\t\t\tif (type === 'op2')  op2  = v;
  2499. \t\t\t\t\tif (type === 'op3')  op3  = v;
  2500. \t\t\t\t\tif (type === 'op4')  op4  = v;
  2501. \t\t\t\t\tif (type === 'op5')  op5  = v;
  2502. \t\t\t\t\tif (type === 'op6')  op6  = v;
  2503. \t\t\t\t\tif (type === 'op7')  op7  = v;
  2504. \t\t\t\t\tif (type === 'op8')  op8  = v;
  2505. \t\t\t\t\tif (type === 'op9')  op9  = v;
  2506. \t\t\t\t\tif (type === 'op10') op10 = v;
  2507. \t\t\t\t}
  2508. \t\t\t\trecalcAllForSaleType2();
  2509. \t\t\t\treturn;
  2510. \t\t\t}
  2511. \t\t\t// 価格データ未登録 (pp 行 0 件) の商品は axis 入力に依存せず
  2512. \t\t\t// 「価格データ準備中」を表示して終了する.
  2513. \t\t\t// (例: scrape 未対象の新規商品 — um のウチリモ 7487/7488 等)
  2514. \t\t\tif (!pp || pp.length === 0) {
  2515. \t\t\t\t\$('#mitsumori_message').text(\"価格データ準備中\");
  2516. \t\t\t\t\$('#mitsumori_btn').hide();
  2517. \t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2518. \t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2519. \t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2520. \t\t\t\t\$('#maker_price').text(\"---円\");
  2521. \t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2522. \t\t\t\t\$('#mitsumori_steelroof_row').hide();
  2523. \t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2524. \t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  2525. \t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  2526. \t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  2527. \t\t\t\treturn;
  2528. \t\t\t}
  2529. \t\t\tif(type == \"pw\"){
  2530. \t\t\t\tpw = \$('#'+value_id).val();
  2531. \t\t\t}
  2532. \t\t\tif(type == \"pd\"){
  2533. \t\t\t\tpd = \$('#'+value_id).val();
  2534. \t\t\t}
  2535. \t\t\tif(type == \"ph\"){
  2536. \t\t\t\tph = \$('#'+value_id).val();
  2537. \t\t\t}
  2538. \t\t\tif(type == \"pm\"){
  2539. \t\t\t\tpm = \$('#'+value_id).val();
  2540. \t\t\t}
  2541. \t\t\tif(type == \"pc\"){
  2542. \t\t\t\tpc = \$('#'+value_id).val();
  2543. \t\t\t}
  2544. \t\t\tif(type == \"option1\"){
  2545. \t\t\t\toption1 = \$('#'+value_id).val();
  2546. \t\t\t}
  2547. \t\t\tif(type == \"option2\"){
  2548. \t\t\t\toption2 = \$('#'+value_id).val();
  2549. \t\t\t}
  2550. \t\t\tif(type == \"op0\"){ op0 = \$('#'+value_id).val(); }
  2551. \t\t\tif(type == \"op1\"){ op1 = \$('#'+value_id).val(); }
  2552. \t\t\tif(type == \"op2\"){ op2 = \$('#'+value_id).val(); }
  2553. \t\t\tif(type == \"op3\"){ op3 = \$('#'+value_id).val(); }
  2554. \t\t\tif(type == \"op4\"){ op4 = \$('#'+value_id).val(); }
  2555. \t\t\tif(type == \"op5\"){ op5 = \$('#'+value_id).val(); }
  2556. \t\t\tif(type == \"op6\"){ op6 = \$('#'+value_id).val(); }
  2557. \t\t\tif(type == \"op7\"){ op7 = \$('#'+value_id).val(); }
  2558. \t\t\tif(type == \"op8\"){ op8 = \$('#'+value_id).val(); }
  2559. \t\t\tif(type == \"op9\"){ op9 = \$('#'+value_id).val(); }
  2560. \t\t\tif(type == \"op10\"){ op10 = \$('#'+value_id).val(); }
  2561. \t\t\t// op0 が「商品購入のみ」のとき、他のオプション (op1..op10) を disable 化.
  2562. \t\t\t// 価格計算側 (calcGoukei の purchaseOnly 分岐) は既にゼロ化しているが、
  2563. \t\t\t// UI で選択可能に見えるとユーザーが混乱するため radio を完全に無効化する.
  2564. \t\t\t(function applyPurchaseOnlyUI() {
  2565. \t\t\t\tvar isPurchaseOnly = (op0 === '商品購入のみ');
  2566. \t\t\t\tfor (var k = 1; k <= 10; k++) {
  2567. \t\t\t\t\tvar \$inputs = \$('input[name=\"op' + k + '\"]');
  2568. \t\t\t\t\tif (\$inputs.length === 0) continue;
  2569. \t\t\t\t\t\$inputs.prop('disabled', isPurchaseOnly);
  2570. \t\t\t\t\tvar \$group = \$inputs.first().closest('.form-group');
  2571. \t\t\t\t\t\$group.css({
  2572. \t\t\t\t\t\t'opacity':        isPurchaseOnly ? '0.4'  : '1',
  2573. \t\t\t\t\t\t'pointer-events': isPurchaseOnly ? 'none' : 'auto'
  2574. \t\t\t\t\t});
  2575. \t\t\t\t}
  2576. \t\t\t})();
  2577. \t\t\t// 全 type 共通: 該当 radio を checked にし、ボタンの is-selected を付け替え + ラベル更新.
  2578. \t\t\t//   value_id が指定されていて、対応する DOM 要素が opt-btn 配下にあれば適用する.
  2579. \t\t\t//   (icheck-danger 形式から opt-btn 形式に統一した際、option1/option2/pw/pd/ph/pm/pc 等の
  2580. \t\t\t//    クリックで is-selected が更新されない不具合があったため、op\\d+ 限定の処理を一般化)
  2581. \t\t\tif (value_id) {
  2582. \t\t\t\tvar \$clicked = \$('#' + value_id);
  2583. \t\t\t\tif (\$clicked.length && \$clicked.closest('.opt-btn').length) {
  2584. \t\t\t\t\t\$clicked.prop('checked', true);
  2585. \t\t\t\t\tvar groupName = \$clicked.attr('name');
  2586. \t\t\t\t\t\$('input[name=\"' + groupName + '\"]').closest('.opt-btn').removeClass('is-selected');
  2587. \t\t\t\t\t\$clicked.closest('.opt-btn').addClass('is-selected');
  2588. \t\t\t\t\tvar \$group = \$clicked.closest('.form-group');
  2589. \t\t\t\t\tvar \$label = \$group.find('.rp-section-label');
  2590. \t\t\t\t\tif (\$label.length) {
  2591. \t\t\t\t\t\tvar labelText = \$label.text().split(':')[0].trim();
  2592. \t\t\t\t\t\t\$label.html(labelText + ': <span>' + \$clicked.val() + '</span>');
  2593. \t\t\t\t\t}
  2594. \t\t\t\t\t// op_data の price=0 & 解体/撤去/設置場所 オプションの場合、ON 選択時に「現場調査後に正式お見積もり」文言を表示.
  2595. \t\t\t\t\t//   (twig 側で is_removal_unknown ブロックを描画済み。display 切替のみ JS で行う)
  2596. \t\t\t\t\tif (/^op\\d+\$/.test(type)) {
  2597. \t\t\t\t\t\tvar opIdx = type.replace('op', '');
  2598. \t\t\t\t\t\tvar opEntry = op_data[parseInt(opIdx)];
  2599. \t\t\t\t\t\tif (opEntry) {
  2600. \t\t\t\t\t\t\tvar \$note = \$group.find('.opt-survey-note[data-op-idx=\"' + opIdx + '\"]');
  2601. \t\t\t\t\t\t\tif (\$note.length) {
  2602. \t\t\t\t\t\t\t\tvar isOn = (\$clicked.val() === opEntry.on);
  2603. \t\t\t\t\t\t\t\t\$note.toggle(isOn);
  2604. \t\t\t\t\t\t\t}
  2605. \t\t\t\t\t\t}
  2606. \t\t\t\t\t\t// wd (sale_type=5) のステップ / デッキフェンス用の注記もここで切替.
  2607. \t\t\t\t\t\t//   ステップ → deck_step (op0 だが op_data 範囲外), 必要 選択時に表示.
  2608. \t\t\t\t\t\tvar radioName = \$clicked.attr('name');
  2609. \t\t\t\t\t\tif (radioName === 'deck_step') {
  2610. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-step').toggle(\$clicked.val() === '必要');
  2611. \t\t\t\t\t\t} else if (radioName === 'deck_fence') {
  2612. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-fence').toggle(\$clicked.val() === '必要');
  2613. \t\t\t\t\t\t}
  2614. \t\t\t\t\t}
  2615. \t\t\t\t}
  2616. \t\t\t}
  2617. \t\t\t// 必須項目チェックは sale_type 1 系(カーポート/物置/フェンスなど価格マトリクス必要)に限定
  2618. \t\t\tvar requireMatrix = (SALE_TYPE_ID == 1 || SALE_TYPE_ID == 2 || SALE_TYPE_ID == 3 || SALE_TYPE_ID == 4 || SALE_TYPE_ID == 5 || SALE_TYPE_ID == 6 || SALE_TYPE_ID == 7 || SALE_TYPE_ID == 9);
  2619. \t\t\t// sale_type=3 (物置・ゴミステーション・照明 等) では「素材」を選択肢として扱わない.
  2620. \t\t\t//   - mo/gs/sy は m が \"指定なし\" など名目的にしか入っていない
  2621. \t\t\t//   - sl は m が空のままで matrix に行が来る
  2622. \t\t\t//   そのため pm の必須チェックを sale_type=3 でスキップする。
  2623. \t\t\tvar pmRequired = (SALE_TYPE_ID != 3);
  2624. \t\t\tif (requireMatrix) {
  2625. \t\t\t\tif(pmRequired && pm == \"\"){
  2626. \t\t\t\t\t\$('#mitsumori_message').text(\"素材を選択してください\");
  2627. \t\t\t\t}
  2628. \t\t\t\tif(ph == \"\"){
  2629. \t\t\t\t\t\$('#mitsumori_message').text(\"高さを選択してください\");
  2630. \t\t\t\t}
  2631. \t\t\t\tif(pd == \"\"){
  2632. \t\t\t\t\t\$('#mitsumori_message').text(\"奥行きを選択してください\");
  2633. \t\t\t\t}
  2634. \t\t\t\tif(pw == \"\"){
  2635. \t\t\t\t\t\$('#mitsumori_message').text(\"幅を選択してください\");
  2636. \t\t\t\t}
  2637. \t\t\t\tif(pc == \"\"){
  2638. \t\t\t\t\t\$('#mitsumori_message').text(\"カラーを選択してください\");
  2639. \t\t\t\t\t\$('#mitsumori_btn').hide();
  2640. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2641. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2642. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2643. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  2644. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2645. \t\t\t\t\$('#mitsumori_steelroof_row').hide();
  2646. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2647. \t\t\t\t}
  2648. \t\t\t}
  2649. \t\t\tif(pw != \"\" && pd != \"\" && ph != \"\" && (!pmRequired || pm != \"\") && pc != \"\"){
  2650. \t\t\t\t\$('#mitsumori_btn').show();
  2651. \t\t\t\t// 入力コンテキスト(sale_type 別パラメータ)
  2652. \t\t\t\tvar ctx = {
  2653. \t\t\t\t\tset_count:    parseInt(\$('#set_count').val())    || 1,
  2654. \t\t\t\t\tdaisu:        parseInt(\$('#daisu').val())        || 1,
  2655. \t\t\t\t\tmaisu:        parseInt(\$('#maisu').val())        || 3,
  2656. \t\t\t\t\tsuuryou:      parseInt(\$('#suuryou').val())      || 1,
  2657. \t\t\t\t\tarea:         (function(){
  2658. \t\t\t\t\t\t// tf(人工芝): 施工サイズ 縦(m)×横(m) から面積を算出し #area に反映.
  2659. \t\t\t\t\t\tvar L = parseFloat(\$('#tf_len').val()) || 0;
  2660. \t\t\t\t\t\tvar W = parseFloat(\$('#tf_wid').val()) || 0;
  2661. \t\t\t\t\t\tif (L > 0 && W > 0) { var a = L * W; \$('#area').val(a); return a; }
  2662. \t\t\t\t\t\treturn parseFloat(\$('#area').val()) || 0;
  2663. \t\t\t\t\t})(),
  2664. \t\t\t\t\ttf_len:       parseFloat(\$('#tf_len').val())     || 0,
  2665. \t\t\t\t\ttf_wid:       parseFloat(\$('#tf_wid').val())     || 0,
  2666. \t\t\t\t\ttf_qty:       parseInt(\$('#tf_qty').val())       || 1,
  2667. \t\t\t\t\tquantityOnly: parseInt(\$('#quantity_only').val())|| 1,
  2668. \t\t\t\t\tmado_w:       \$('#mado_w').val() || '',
  2669. \t\t\t\t\tmado_h:       \$('#mado_h').val() || '',
  2670. \t\t\t\t\tmado_type:    \$('input[name=mado_type]:checked').val()  || '',
  2671. \t\t\t\t\tglass_type:   \$('input[name=glass_type]:checked').val() || '',
  2672. \t\t\t\t\tdeck_step:    \$('input[name=deck_step]:checked').val()  || '',
  2673. \t\t\t\t\tdeck_fence:   \$('input[name=deck_fence]:checked').val() || '',
  2674. \t\t\t\t};
  2675. \t\t\t\t// 施工オプション集計(残土処理を含む)
  2676. \t\t\t\tvar opCalc = collectOptions();
  2677. \t\t\t\tvar pp_matched = false;
  2678. \t\t\t\t// 各軸の汎用 axisMatch:
  2679. \t\t\t\t//   user 選択 == matrix 値 / user \"指定なし\" / matrix 値が空
  2680. \t\t\t\tvar axisMatch = function(input, value){
  2681. \t\t\t\t    return input == value || input == \"指定なし\" || value === \"\" || value == null;
  2682. \t\t\t\t};
  2683. \t\t\t\t// 色専用マッチャー: scraper のデータ形式に合わせて拡張する
  2684. \t\t\t\t//   1. 完全一致 / \"指定なし\" / 値が空 → 真 (axisMatch と同じ)
  2685. \t\t\t\t//   2. matrix 値が \"色1/色2/色3\" の形 (同価格グループ) → split して user 選択が含まれれば真
  2686. \t\t\t\t// scraper のロジック (scraper_price.py L765-779):
  2687. \t\t\t\t//   全色同価格 → c=\"\"、価格違いグループあり → 各 group を \"/\" 結合した色名で 1 行
  2688. \t\t\t\tvar colorMatch = function(input, value){
  2689. \t\t\t\t    if (axisMatch(input, value)) return true;
  2690. \t\t\t\t    if (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  2691. \t\t\t\t        var parts = value.split('/');
  2692. \t\t\t\t        for (var idx = 0; idx < parts.length; idx++) {
  2693. \t\t\t\t            if (parts[idx].trim() === input) return true;
  2694. \t\t\t\t        }
  2695. \t\t\t\t    }
  2696. \t\t\t\t    return false;
  2697. \t\t\t\t};
  2698. \t\t\t\t// 他軸 (w/d/h/m + option1/option2) でマッチする pp 行を抽出.
  2699. \t\t\t\t// option1/option2 は um の subtype 等で使われる. axisMatch は free_area 側が
  2700. \t\t\t\t// 空のとき真を返すので、um 以外のカテゴリ (option 軸を使わない) でも影響なし.
  2701. \t\t\t\tvar candidates = pp.filter(function(el){
  2702. \t\t\t\t    return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m)
  2703. \t\t\t\t        && axisMatch(option1, el.option1) && axisMatch(option2, el.option2);
  2704. \t\t\t\t});
  2705. \t\t\t\t// フォールバック: 全軸一致が 0 件のときに限り option1/option2 を無視して再マッチ。
  2706. \t\t\t\t// 玄関ドア等で option1(なし/ランマ付き)・option2(◯◯タイプ) が pm(開き方) から
  2707. \t\t\t\t// 導出可能な冗長軸で、未選択だと全軸 AND 一致を満たせず価格が出ない事象の救済。
  2708. \t\t\t\t// pm/幅/奥行/高さ は従来どおり一致を要求するため通常商品の価格選択に影響しない。
  2709. \t\t\t\tif (candidates.length === 0) {
  2710. \t\t\t\t    candidates = pp.filter(function(el){
  2711. \t\t\t\t        return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m);
  2712. \t\t\t\t    });
  2713. \t\t\t\t}
  2714. \t\t\t\tvar picked = null;
  2715. \t\t\t\t// 優先 1: 色も含めて完全一致 (\"色1/色2\" 形式の split match を含む)
  2716. \t\t\t\tfor (var ii = 0; ii < candidates.length; ii++) {
  2717. \t\t\t\t    if (colorMatch(pc, candidates[ii].c)) { picked = candidates[ii]; break; }
  2718. \t\t\t\t}
  2719. \t\t\t\t// 優先 2: 完全一致なし & user の pc が候補のどの c 値にも該当しない (= 命名違い等)
  2720. \t\t\t\t//   かつ候補全行で price が一致する場合は、色軸を実質無視して先頭行を採用.
  2721. \t\t\t\t//   例 id=3353: pp.c は \"ステンカラー+...\" 6種だが price は全て同じなので
  2722. \t\t\t\t//     SM(スミ) を選んでも安全に最初の行の価格を返せる.
  2723. \t\t\t\tif (!picked && candidates.length > 0) {
  2724. \t\t\t\t    var ppCsInCand = candidates.map(function(r){ return r.c || ''; });
  2725. \t\t\t\t    var pcAbsent = (pc !== '' && pc !== '指定なし' && ppCsInCand.indexOf(pc) === -1
  2726. \t\t\t\t                    && ppCsInCand.every(function(v){ return v.indexOf('/') === -1 || v.split('/').map(function(s){return s.trim();}).indexOf(pc) === -1; }));
  2727. \t\t\t\t    if (pcAbsent) {
  2728. \t\t\t\t        var uniqPrices = new Set();
  2729. \t\t\t\t        candidates.forEach(function(r){ uniqPrices.add(String(r.price)); });
  2730. \t\t\t\t        if (uniqPrices.size === 1) {
  2731. \t\t\t\t            // 全候補同価格 → 色軸を wildcard 扱いで OK
  2732. \t\t\t\t            picked = candidates[0];
  2733. \t\t\t\t        }
  2734. \t\t\t\t        // 価格が異なる場合は意図的に picked=null のまま「対応しておりません」.
  2735. \t\t\t\t    }
  2736. \t\t\t\t}
  2737. \t\t\t\t// 請求額・見積書・PDF 用の税込値 (表示は税抜だが json は税込で不変).
  2738. \t\t\t\t// 未マッチ時は '---円' のまま送る.
  2739. \t\t\t\tvar jGoukei = '---円', jGoukei02 = '---円', jPrice = '---円',
  2740. \t\t\t\t    jMaker = '---円', jOff = '---円', jCt = '---円', jOption = '---円';
  2741. \t\t\t\tpp.forEach((el) => {
  2742. \t\t\t\t  if (el === picked) {
  2743. \t\t\t\t\tpp_matched = true;
  2744. \t\t\t\t\t// tg block-keyed オプション差額を集計 (tg 以外は total=0)
  2745. \t\t\t\t\tvar oiCalc = collectOptionItems(el.w || '', el.d || '');
  2746. \t\t\t\t\t// tg ブロックに合わせてラジオを再描画 (tg 以外は no-op)
  2747. \t\t\t\t\trenderOptionItemRadios(el.w || '', el.d || '');
  2748. \t\t\t\t\t// fe ブロックの種類×段数 サブ radio (fe 以外/未設定は no-op)
  2749. \t\t\t\t\trenderFeBlockRadios();
  2750. \t\t\t\t\t// fe ご希望のフェンス設置方法 — 「既存ブロックに穴空け」 entry の連動表示
  2751. \t\t\t\t\tupdateFeOpConditionalVisibility();
  2752. \t\t\t\t\tvar calc       = calcGoukei(el, opCalc.total, ctx);
  2753. \t\t\t\t\tvar goukei     = calc.goukei;     // 税込 (請求額・見積書・PDF 用)
  2754. \t\t\t\t\tvar price      = calc.price;      // 税込
  2755. \t\t\t\t\tvar ct         = calc.ct;         // 税込
  2756. \t\t\t\t\tvar optionSum  = calc.opt;        // 税込
  2757. \t\t\t\t\tvar goukeiExc  = calc.goukeiExc;  // 税抜 (詳細ページ表示専用)
  2758. \t\t\t\t\tvar priceExc   = calc.priceExc;   // 税抜
  2759. \t\t\t\t\tvar ctExc      = calc.ctExc;      // 税抜
  2760. \t\t\t\t\tvar optionExc  = calc.optExc;     // 税抜
  2761. \t\t\t\t\t// tf(人工芝): 必要枚数入力へ算出結果を反映(施工サイズ入力時は上書き、
  2762. \t\t\t\t\t// 直接指定時は同値なので実質変化なし。要素が無い sale_type では no-op)
  2763. \t\t\t\t\tvar \$tfQty = \$('#tf_qty');
  2764. \t\t\t\t\tif (\$tfQty.length) \$tfQty.val(calc.qty || 1);
  2765. \t\t\t\t\t// オプション差額は税抜 → 税込に変換して合計に加算
  2766. \t\t\t\t\tvar oiIncTax   = toIncTax(oiCalc.total);
  2767. \t\t\t\t\tgoukei += oiIncTax;
  2768. \t\t\t\t\tprice  += oiIncTax;  // 差額は本体価格扱いとして mitsumori_price にも加算
  2769. \t\t\t\t\tgoukeiExc += oiCalc.total;  // 税抜側にも同じ差額を加算
  2770. \t\t\t\t\tpriceExc  += oiCalc.total;
  2771. \t\t\t\t\t// maker_price も scraper が税抜で保存しているため税込に変換
  2772. \t\t\t\tvar makerPrice = toIncTax(parseInt(el.maker_price) || 0);      // 税込
  2773. \t\t\t\t\tvar makerPriceExc = parseInt(el.maker_price) || 0;           // 税抜
  2774. \t\t\t\t\t// 表示 (詳細ページの見積カード/ヘッダー/SPバー) は税抜に統一.
  2775. \t\t\t\t\t\$('#mitsumori_message').text(formatter.format(goukeiExc) + \"円\");
  2776. \t\t\t\t\t\$('#mitsumori_goukei').text(formatter.format(goukeiExc) + \"円\");
  2777. \t\t\t\t\t\$('#mitsumori_off').text(formatter.format(priceExc - makerPriceExc) + \"円\");
  2778. \t\t\t\t\t\$('#mitsumori_price').text(formatter.format(priceExc) + \"円\");
  2779. \t\t\t\t\t\$('#maker_price').text(formatter.format(makerPriceExc) + \"円\");
  2780. \t\t\t\t\t\$('#mitsumori_ct').text(formatter.format(ctExc) + \"円\");
  2781. \t\t\t\t\t\$('#mitsumori_option').text(formatter.format(optionExc) + \"円\");
  2782. \t\t\t\t\t// スチール折板(折半屋根 = option1): cp 折板のみ非ゼロ。工事費内に別行表示。
  2783. \t\t\t\t\tvar steelRoofExc = calc.steelRoofExc || 0;
  2784. \t\t\t\t\tif (steelRoofExc > 0) { \$('#mitsumori_steelroof_row').show(); \$('#mitsumori_steelroof').text(formatter.format(steelRoofExc) + \"円\"); }
  2785. \t\t\t\t\telse { \$('#mitsumori_steelroof_row').hide(); }
  2786. \t\t\t\t\t// 見積書モーダルは正式帳票のため税込のまま (請求額と一致).
  2787. \t\t\t\t\t\$('#mitsumori_kei').text(formatter.format(goukei) + \"円\");
  2788. \t\t\t\t\t\$('#mitsumori_price_01').text(formatter.format(price) + \"円\");
  2789. \t\t\t\t\t\$('#mitsumori_price_02').text(formatter.format(price) + \"円\");
  2790. \t\t\t\t\t\$('#mitsumori_ct_01').text(formatter.format(ct) + \"円\");
  2791. \t\t\t\t\t\$('#mitsumori_ct_02').text(formatter.format(ct) + \"円\");
  2792. \t\t\t\t\t\$('#mitsumori_goukei_02').text(formatter.format(goukei) + \"円\");
  2793. \t\t\t\t\tvar shoukei = goukei / 1.1;
  2794. \t\t\t\t\tvar tax     = parseInt(goukei - shoukei);
  2795. \t\t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(parseInt(shoukei)) + \"円\");
  2796. \t\t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + \"円\");
  2797. \t\t\t\t\t// 請求額・PDF 用 json は税込を保持 (表示 DOM が税抜でも請求額は不変).
  2798. \t\t\t\t\tjGoukei   = formatter.format(goukei) + \"円\";
  2799. \t\t\t\t\tjGoukei02 = formatter.format(goukei) + \"円\";
  2800. \t\t\t\t\tjPrice    = formatter.format(price) + \"円\";
  2801. \t\t\t\t\tjMaker    = formatter.format(makerPrice) + \"円\";
  2802. \t\t\t\t\tjOff      = formatter.format(price - makerPrice) + \"円\";
  2803. \t\t\t\t\tjCt       = formatter.format(ct) + \"円\";
  2804. \t\t\t\t\tjOption   = formatter.format(optionSum) + \"円\";
  2805. \t\t\t\t\t// PDF 明細用:オプション内訳テーブルを差し込む (施工オプション + tg block オプション)
  2806. \t\t\t\t\trenderOptionDetailRows(opCalc.items.concat(oiCalc.items.map(function(it){
  2807. \t\t\t\t\t\treturn { name: it.name, value: it.label, price: it.diff };
  2808. \t\t\t\t\t})));
  2809. \t\t\t\t  }
  2810. \t\t\t\t});
  2811. \t\t\t\tif (!pp_matched) {
  2812. \t\t\t\t\t\$('#mitsumori_message').text(\"この組み合わせは対応しておりません\");
  2813. \t\t\t\t\t\$('#mitsumori_btn').hide();
  2814. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2815. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2816. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2817. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  2818. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2819. \t\t\t\t\$('#mitsumori_steelroof_row').hide();
  2820. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2821. \t\t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  2822. \t\t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  2823. \t\t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  2824. \t\t\t\t}
  2825. \t\t\t\t// mitsumori_json: バック側に送信する見積データ
  2826. \t\t\t\tvar mitsumori_json = { \"mitsumori_goukei\": jGoukei,
  2827. \t\t\t\t\t\t\t\t\t\t\"mitsumori_goukei_02\": jGoukei02,
  2828. \t\t\t\t\t\t\t\t\t\t\"mitsumori_price\": jPrice,
  2829. \t\t\t\t\t\t\t\t\t\t\"maker_price\": jMaker,
  2830. \t\t\t\t\t\t\t\t\t\t\"mitsumori_off\": jOff,
  2831. \t\t\t\t\t\t\t\t\t\t\"mitsumori_ct\": jCt,
  2832. \t\t\t\t\t\t\t\t\t\t\"mitsumori_option\": jOption,
  2833. \t\t\t\t\t\t\t\t\t\t\"product_id\": ";
  2834.         // line 2720
  2835.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2720$this->source); })()), "id", [], "any"falsefalsefalse2720), "html"nulltrue);
  2836.         echo ",
  2837. \t\t\t\t\t\t\t\t\t\t\"sale_type\": SALE_TYPE_ID,
  2838. \t\t\t\t\t\t\t\t\t\t\"pw\": pw,
  2839. \t\t\t\t\t\t\t\t\t\t\"pd\": pd,
  2840. \t\t\t\t\t\t\t\t\t\t\"ph\": ph,
  2841. \t\t\t\t\t\t\t\t\t\t\"pm\": pm,
  2842. \t\t\t\t\t\t\t\t\t\t\"pc\": pc,
  2843. \t\t\t\t\t\t\t\t\t\t\"op\": [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10],
  2844. \t\t\t\t\t\t\t\t\t\t\"op_items\": opCalc.items,
  2845. \t\t\t\t\t\t\t\t\t\t\"mado_w\":     ctx.mado_w,
  2846. \t\t\t\t\t\t\t\t\t\t\"mado_h\":     ctx.mado_h,
  2847. \t\t\t\t\t\t\t\t\t\t\"mado_type\":  ctx.mado_type,
  2848. \t\t\t\t\t\t\t\t\t\t\"glass_type\": ctx.glass_type,
  2849. \t\t\t\t\t\t\t\t\t\t\"set_count\":  ctx.set_count,
  2850. \t\t\t\t\t\t\t\t\t\t\"daisu\":      ctx.daisu,
  2851. \t\t\t\t\t\t\t\t\t\t\"maisu\":      ctx.maisu,
  2852. \t\t\t\t\t\t\t\t\t\t\"suuryou\":    ctx.suuryou,
  2853. \t\t\t\t\t\t\t\t\t\t\"area\":       ctx.area,
  2854. \t\t\t\t\t\t\t\t\t\t\"tf_len\":     ctx.tf_len,
  2855. \t\t\t\t\t\t\t\t\t\t\"tf_wid\":     ctx.tf_wid,
  2856. \t\t\t\t\t\t\t\t\t\t\"tf_qty\":     \$('#tf_qty').val(),
  2857. \t\t\t\t\t\t\t\t\t\t\"deck_step\":  ctx.deck_step,
  2858. \t\t\t\t\t\t\t\t\t\t\"deck_fence\": ctx.deck_fence };
  2859. \t\t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  2860. \t\t\t}
  2861. \t\t}
  2862. \t\t// PDF/モーダル明細の動的差し替え(基本工事費の次にオプション行を追加)
  2863. \t\tfunction renderOptionDetailRows(items) {
  2864. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  2865. \t\t\tif (!\$tbody.length) return;
  2866. \t\t\t\$tbody.find('tr.opt-row').remove();
  2867. \t\t\tvar anchorRow = \$tbody.find('tr').filter(function(){
  2868. \t\t\t\treturn \$(this).find('td:first').text().indexOf('残土') !== -1
  2869. \t\t\t\t\t|| \$(this).find('td:first').text().indexOf('基本工事費') !== -1;
  2870. \t\t\t}).last();
  2871. \t\t\titems.forEach(function(it){
  2872. \t\t\t\tif (!it.name || !it.value) return;
  2873. \t\t\t\tvar priceTxt = it.price > 0
  2874. \t\t\t\t\t? formatter.format(it.price) + '円'
  2875. \t\t\t\t\t: '0円';
  2876. \t\t\t\tvar \$tr = \$('<tr class=\"opt-row\"></tr>')
  2877. \t\t\t\t\t.append('<td>' + it.name + ':' + it.value + '</td>')
  2878. \t\t\t\t\t.append('<td>1</td>')
  2879. \t\t\t\t\t.append('<td>式</td>')
  2880. \t\t\t\t\t.append('<td>' + priceTxt + '</td>')
  2881. \t\t\t\t\t.append('<td>' + (it.price > 0 ? formatter.format(it.price) + '円' : '') + '</td>');
  2882. \t\t\t\tif (anchorRow.length) {
  2883. \t\t\t\t\tanchorRow.after(\$tr);
  2884. \t\t\t\t\tanchorRow = \$tr;
  2885. \t\t\t\t} else {
  2886. \t\t\t\t\t\$tbody.append(\$tr);
  2887. \t\t\t\t}
  2888. \t\t\t});
  2889. \t\t}
  2890. \t\t// 見積書モーダルを開く直前に、右側「現在のお見積り額」パネルの表示値を
  2891. \t\t// モーダル内の対応 ID にコピーして金額の食い違いを防ぐ。
  2892. \t\t// pw/pd/ph/pm が未選択で mitsumori_simulation の full update に到達しない場合でも、
  2893. \t\t// パネル側の値(HTML 静的初期値 or 直近の simulation 結果)が modal にも反映される。
  2894. \t\tfunction syncMitsumoriModalFromPanel() {
  2895. \t\t\t// 見積カード表示は税抜だが、見積書モーダルは正式帳票として税込で出す.
  2896. \t\t\t// 請求と一致する税込値は hidden #mitsumori_json (税込のまま構築) から取得する.
  2897. \t\t\tvar mj = {};
  2898. \t\t\ttry { mj = JSON.parse(\$('#mitsumori_json').val() || '{}') || {}; } catch (e) { mj = {}; }
  2899. \t\t\tvar goukeiText = mj.mitsumori_goukei || '---円';
  2900. \t\t\tvar priceText  = mj.mitsumori_price  || '---円';
  2901. \t\t\tvar ctText     = mj.mitsumori_ct     || '---円';
  2902. \t\t\t\$('#mitsumori_kei').text(goukeiText);
  2903. \t\t\t\$('#mitsumori_price_01').text(priceText);
  2904. \t\t\t\$('#mitsumori_price_02').text(priceText);
  2905. \t\t\t\$('#mitsumori_ct_01').text(ctText);
  2906. \t\t\t\$('#mitsumori_ct_02').text(ctText);
  2907. \t\t\t\$('#mitsumori_goukei_02').text(goukeiText);
  2908. \t\t\t// 小計 / 消費税 は税込 goukei から逆算
  2909. \t\t\tvar num = parseInt(String(goukeiText).replace(/[^\\d-]/g, ''), 10);
  2910. \t\t\tif (!isNaN(num) && num > 0) {
  2911. \t\t\t\tvar shoukei = Math.round(num / 1.1);
  2912. \t\t\t\tvar tax     = num - shoukei;
  2913. \t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(shoukei) + '円');
  2914. \t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + '円');
  2915. \t\t\t} else {
  2916. \t\t\t\t\$('#mitsumori_shoukei').text('---円');
  2917. \t\t\t\t\$('#mitsumori_tax').text('---円');
  2918. \t\t\t}
  2919. \t\t}
  2920. \t\t\$(document).on('show.bs.modal', '#modal-mitsumori', function () {
  2921. \t\t\t// 発行日を表示時点の当日日付に設定(固定ダミー日付の残置防止)
  2922. \t\t\tvar _now = new Date();
  2923. \t\t\tvar _issue = _now.getFullYear() + '/' +
  2924. \t\t\t\t('0' + (_now.getMonth() + 1)).slice(-2) + '/' +
  2925. \t\t\t\t('0' + _now.getDate()).slice(-2);
  2926. \t\t\t\$('#mitsumori_issue_date').text(_issue);
  2927. \t\t\tsyncMitsumoriModalFromPanel();
  2928. \t\t});
  2929.         ";
  2930.         // line 2824
  2931.         echo "        ";
  2932.         if (((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2824$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2824$this->source); })())) == 1) || (twig_join_filter((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2824$this->source); })())) == "")))) {
  2933.             // line 2825
  2934.             echo "            pc = \"指定なし\";
  2935.             ";
  2936.             // line 2826
  2937.             $context['_parent'] = $context;
  2938.             $context['_seq'] = twig_ensure_traversable((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2826$this->source); })()));
  2939.             foreach ($context['_seq'] as $context["_key"] => $context["pc_val"]) {
  2940.                 if ($context["pc_val"]) {
  2941.                     echo " pc = \"";
  2942.                     echo twig_escape_filter($this->env$context["pc_val"], "html"nulltrue);
  2943.                     echo "\"; ";
  2944.                 }
  2945.             }
  2946.             $_parent $context['_parent'];
  2947.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pc_val'], $context['_parent'], $context['loop']);
  2948.             $context array_intersect_key($context$_parent) + $_parent;
  2949.             // line 2827
  2950.             echo "            ";
  2951.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2827$this->source); })()) && (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2827$this->source); })())) == 1))) {
  2952.                 // line 2828
  2953.                 echo "                ";
  2954.                 $context['_parent'] = $context;
  2955.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2828$this->source); })()));
  2956.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  2957.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2828))) {
  2958.                         echo " pc = \"";
  2959.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2828), "html"nulltrue);
  2960.                         echo "\"; ";
  2961.                     }
  2962.                 }
  2963.                 $_parent $context['_parent'];
  2964.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  2965.                 $context array_intersect_key($context$_parent) + $_parent;
  2966.                 // line 2829
  2967.                 echo "            ";
  2968.             }
  2969.             // line 2830
  2970.             echo "        ";
  2971.         } elseif (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2830$this->source); })()) && (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2830$this->source); })())) == 1))) {
  2972.             // line 2831
  2973.             echo "            pc = \"指定なし\";
  2974. \t\t\t";
  2975.             // line 2832
  2976.             $context['_parent'] = $context;
  2977.             $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2832$this->source); })()));
  2978.             foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  2979.                 if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2832))) {
  2980.                     echo " pc = \"";
  2981.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2832), "html"nulltrue);
  2982.                     echo "\"; ";
  2983.                 }
  2984.             }
  2985.             $_parent $context['_parent'];
  2986.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  2987.             $context array_intersect_key($context$_parent) + $_parent;
  2988.             // line 2833
  2989.             echo "\t\t";
  2990.         }
  2991.         // line 2834
  2992.         echo "
  2993.         ";
  2994.         // line 2835
  2995.         if (((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2835$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2835$this->source); })())) == 1) || (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2835$this->source); })())) == "")))) {
  2996.             // line 2836
  2997.             echo "            pw = \"指定なし\";
  2998. \t\t\t";
  2999.             // line 2837
  3000.             $context['_parent'] = $context;
  3001.             $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2837$this->source); })()));
  3002.             foreach ($context['_seq'] as $context["_key"] => $context["pw"]) {
  3003.                 if ($context["pw"]) {
  3004.                     echo " pw = \"";
  3005.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  3006.                     echo "\"; ";
  3007.                 }
  3008.             }
  3009.             $_parent $context['_parent'];
  3010.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw'], $context['_parent'], $context['loop']);
  3011.             $context array_intersect_key($context$_parent) + $_parent;
  3012.             // line 2838
  3013.             echo "\t\t";
  3014.         }
  3015.         // line 2839
  3016.         echo "
  3017.         ";
  3018.         // line 2840
  3019.         if (((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2840$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2840$this->source); })())) == 1) || (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2840$this->source); })())) == "")))) {
  3020.             // line 2841
  3021.             echo "            pd = \"指定なし\";
  3022. \t\t\t";
  3023.             // line 2842
  3024.             $context['_parent'] = $context;
  3025.             $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2842$this->source); })()));
  3026.             foreach ($context['_seq'] as $context["_key"] => $context["pd"]) {
  3027.                 if ($context["pd"]) {
  3028.                     echo " pd = \"";
  3029.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  3030.                     echo "\"; ";
  3031.                 }
  3032.             }
  3033.             $_parent $context['_parent'];
  3034.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd'], $context['_parent'], $context['loop']);
  3035.             $context array_intersect_key($context$_parent) + $_parent;
  3036.             // line 2843
  3037.             echo "\t\t";
  3038.         }
  3039.         // line 2844
  3040.         echo "
  3041.         ";
  3042.         // line 2845
  3043.         if (((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2845$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2845$this->source); })())) == 1) || (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2845$this->source); })())) == "")))) {
  3044.             // line 2846
  3045.             echo "            ph = \"指定なし\";
  3046. \t\t\t";
  3047.             // line 2847
  3048.             $context['_parent'] = $context;
  3049.             $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2847$this->source); })()));
  3050.             foreach ($context['_seq'] as $context["_key"] => $context["ph"]) {
  3051.                 if ($context["ph"]) {
  3052.                     echo " ph = \"";
  3053.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  3054.                     echo "\"; ";
  3055.                 }
  3056.             }
  3057.             $_parent $context['_parent'];
  3058.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph'], $context['_parent'], $context['loop']);
  3059.             $context array_intersect_key($context$_parent) + $_parent;
  3060.             // line 2848
  3061.             echo "\t\t";
  3062.         }
  3063.         // line 2849
  3064.         echo "
  3065.         ";
  3066.         // line 2850
  3067.         if (((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2850$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2850$this->source); })())) == 1) || (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2850$this->source); })())) == "")))) {
  3068.             // line 2851
  3069.             echo "            pm = \"指定なし\";
  3070. \t\t\t";
  3071.             // line 2852
  3072.             $context['_parent'] = $context;
  3073.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2852$this->source); })()));
  3074.             foreach ($context['_seq'] as $context["_key"] => $context["pm"]) {
  3075.                 if ($context["pm"]) {
  3076.                     echo " pm = \"";
  3077.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  3078.                     echo "\"; ";
  3079.                 }
  3080.             }
  3081.             $_parent $context['_parent'];
  3082.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm'], $context['_parent'], $context['loop']);
  3083.             $context array_intersect_key($context$_parent) + $_parent;
  3084.             // line 2853
  3085.             echo "\t\t";
  3086.         }
  3087.         // line 2854
  3088.         echo "
  3089.         ";
  3090.         // line 2856
  3091.         echo "        ";
  3092.         if (((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2856$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2856$this->source); })())) == 1) || (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2856$this->source); })())) == "")))) {
  3093.             // line 2857
  3094.             echo "            option1 = \"\";
  3095. \t\t\t";
  3096.             // line 2858
  3097.             $context['_parent'] = $context;
  3098.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2858$this->source); })()));
  3099.             foreach ($context['_seq'] as $context["_key"] => $context["opt1"]) {
  3100.                 if ($context["opt1"]) {
  3101.                     echo " option1 = \"";
  3102.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt1"], "js"), "html"nulltrue);
  3103.                     echo "\"; ";
  3104.                 }
  3105.             }
  3106.             $_parent $context['_parent'];
  3107.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1'], $context['_parent'], $context['loop']);
  3108.             $context array_intersect_key($context$_parent) + $_parent;
  3109.             // line 2859
  3110.             echo "\t\t";
  3111.         }
  3112.         // line 2860
  3113.         echo "
  3114.         ";
  3115.         // line 2861
  3116.         if (((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2861$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2861$this->source); })())) == 1) || (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2861$this->source); })())) == "")))) {
  3117.             // line 2862
  3118.             echo "            option2 = \"\";
  3119. \t\t\t";
  3120.             // line 2863
  3121.             $context['_parent'] = $context;
  3122.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2863$this->source); })()));
  3123.             foreach ($context['_seq'] as $context["_key"] => $context["opt2"]) {
  3124.                 if ($context["opt2"]) {
  3125.                     echo " option2 = \"";
  3126.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt2"], "js"), "html"nulltrue);
  3127.                     echo "\"; ";
  3128.                 }
  3129.             }
  3130.             $_parent $context['_parent'];
  3131.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt2'], $context['_parent'], $context['loop']);
  3132.             $context array_intersect_key($context$_parent) + $_parent;
  3133.             // line 2864
  3134.             echo "\t\t";
  3135.         }
  3136.         // line 2865
  3137.         echo "
  3138. \t\t// カラー radio が複数あるとき初期チェックが無いと「カラーを選択してください」固定になるので、
  3139. \t\t// 何もチェックされていなければ「最初の radio」を選択する。
  3140. \t\t// sale_type≠3 は name=\"color\", sale_type=3 は name=\"color3\".
  3141. \t\t//
  3142. \t\t// 注意:
  3143. \t\t//   ・search_word(= radio の値)と pp.c(= matrix の色軸)は別の命名体系のケースがある
  3144. \t\t//     (例 id=3353: radio=\"SM(スミ)\" / pp.c=\"ステンカラー+セピアブラウン\")
  3145. \t\t//   ・pp.c に合わせて radio を選ぼうとしても文字列一致しないので無意味。
  3146. \t\t//   ・単純に「先頭の radio」を選ぶ実装に戻し、マッチング側で命名体系違いを吸収する
  3147. \t\t//     (pc が pp.c のどの値にもマッチしないときは色軸を wildcard 扱いにする)。
  3148. \t\t//   ・.rp-section-label のテキストも忘れずに同期する(古い session 値が残ると
  3149. \t\t//     \"ステンカラー+セピアブラウン\" のような表示と実際の radio が食い違う)。
  3150. \t\t(function autoSelectFirstColor(){
  3151. \t\t\tvar groups = ['color', 'color3'];
  3152. \t\t\tfor (var gi = 0; gi < groups.length; gi++) {
  3153. \t\t\t\tvar name = groups[gi];
  3154. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + name + '\"]');
  3155. \t\t\t\tif (nodes.length === 0) continue;
  3156. \t\t\t\tvar anyChecked = false;
  3157. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  3158. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  3159. \t\t\t\t}
  3160. \t\t\t\tif (anyChecked) continue;
  3161. \t\t\t\tvar target = nodes[0];
  3162. \t\t\t\ttarget.checked = true;
  3163. \t\t\t\tpc = target.value;
  3164. \t\t\t\t// opt-btn の is-selected を付け替え
  3165. \t\t\t\tvar lbl = target.closest('.opt-btn');
  3166. \t\t\t\tif (lbl) {
  3167. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  3168. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  3169. \t\t\t\t\tlbl.classList.add('is-selected');
  3170. \t\t\t\t}
  3171. \t\t\t\t// 「カラー: <name>」表示の同期(古い mitsumori_json.pc が残らないように)
  3172. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  3173. \t\t\t\tif (grp) {
  3174. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  3175. \t\t\t\t\tif (section) {
  3176. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3177. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  3178. \t\t\t\t\t}
  3179. \t\t\t\t}
  3180. \t\t\t}
  3181. \t\t})();
  3182. \t\t// option1 / option2 / pw / pd / ph / pm (matrix 軸の radio 群) も同様に
  3183. \t\t// 「どれもチェックされていなければ先頭を選ぶ」を適用する.
  3184. \t\t//   sale_type=2 の窓タイプ等で「初期表示時に一番初めの選択肢が選択されていない」事象を解消.
  3185. \t\t(function autoSelectFirstMatrixAxis(){
  3186. \t\t\tvar axes = [
  3187. \t\t\t\t{ name: 'pw',      jsVar: 'pw' },
  3188. \t\t\t\t{ name: 'pd',      jsVar: 'pd' },
  3189. \t\t\t\t{ name: 'ph',      jsVar: 'ph' },
  3190. \t\t\t\t{ name: 'pm',      jsVar: 'pm' },
  3191. \t\t\t\t{ name: 'glass_type', jsVar: 'pm' },
  3192. \t\t\t\t{ name: 'option1', jsVar: 'option1' },
  3193. \t\t\t\t{ name: 'option2', jsVar: 'option2' }
  3194. \t\t\t];
  3195. \t\t\tfor (var ai = 0; ai < axes.length; ai++) {
  3196. \t\t\t\tvar ax = axes[ai];
  3197. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + ax.name + '\"]');
  3198. \t\t\t\tif (nodes.length === 0) continue;
  3199. \t\t\t\tvar anyChecked = false;
  3200. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  3201. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  3202. \t\t\t\t}
  3203. \t\t\t\tif (anyChecked) continue;
  3204. \t\t\t\tvar target = nodes[0];
  3205. \t\t\t\ttarget.checked = true;
  3206. \t\t\t\t// グローバル JS 変数も埋める
  3207. \t\t\t\tif (ax.jsVar === 'pw') pw = target.value;
  3208. \t\t\t\telse if (ax.jsVar === 'pd') pd = target.value;
  3209. \t\t\t\telse if (ax.jsVar === 'ph') ph = target.value;
  3210. \t\t\t\telse if (ax.jsVar === 'pm') pm = target.value;
  3211. \t\t\t\telse if (ax.jsVar === 'option1') option1 = target.value;
  3212. \t\t\t\telse if (ax.jsVar === 'option2') option2 = target.value;
  3213. \t\t\t\tvar lbl = target.closest('.opt-btn');
  3214. \t\t\t\tif (lbl) {
  3215. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  3216. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  3217. \t\t\t\t\tlbl.classList.add('is-selected');
  3218. \t\t\t\t}
  3219. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  3220. \t\t\t\tif (grp) {
  3221. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  3222. \t\t\t\t\tif (section) {
  3223. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3224. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  3225. \t\t\t\t\t}
  3226. \t\t\t\t}
  3227. \t\t\t}
  3228. \t\t})();
  3229. \t\t// 取付/設置工事トグル(off 値が「商品購入のみ」のオプション)は、新規アクセス時に
  3230. \t\t// どちらの radio も未チェックのため初期価格が「商品購入のみ」= 基本工事費抜きになる。
  3231. \t\t// 顧客要望(#10)に合わせ、未選択時は「工事も希望する」(on 側) を初期選択し、
  3232. \t\t// 初期表示を基本工事費込みの最安値に統一する(色・寸法軸の先頭自動選択と同型)。
  3233. \t\t//   ・判定キーは calcGoukei / applyPurchaseOnlyUI と同じ定数「商品購入のみ」。
  3234. \t\t//   ・別用途で op{n} を流用する商品(ウッドデッキ deck_step 等)は radio 値に
  3235. \t\t//     「商品購入のみ」を含まないため対象外(既存挙動を壊さない)。
  3236. \t\t//   ・mitsumori_json 復元やユーザー操作で既に選択済みなら尊重する。
  3237. \t\t(function autoSelectFirstInstall(){
  3238. \t\t\tfor (var i = 0; i <= 10; i++) {
  3239. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"op' + i + '\"]');
  3240. \t\t\t\tif (nodes.length === 0) continue;
  3241. \t\t\t\t// このグループが「商品購入のみ」を off に持つ工事トグルか判定し、
  3242. \t\t\t\t// 「商品購入のみ」でない側 (= 工事希望 on) を取得する。
  3243. \t\t\t\tvar hasPurchaseOnly = false;
  3244. \t\t\t\tvar onNode = null;
  3245. \t\t\t\tfor (var j = 0; j < nodes.length; j++) {
  3246. \t\t\t\t\tif (nodes[j].value === '商品購入のみ') hasPurchaseOnly = true;
  3247. \t\t\t\t\telse if (!onNode) onNode = nodes[j];
  3248. \t\t\t\t}
  3249. \t\t\t\tif (!hasPurchaseOnly || !onNode) continue;
  3250. \t\t\t\tvar anyChecked = false;
  3251. \t\t\t\tfor (var k = 0; k < nodes.length; k++) {
  3252. \t\t\t\t\tif (nodes[k].checked) { anyChecked = true; break; }
  3253. \t\t\t\t}
  3254. \t\t\t\tif (anyChecked) continue;
  3255. \t\t\t\tonNode.checked = true;
  3256. \t\t\t\t// グローバル op 変数を on 値で埋める(calcGoukei の purchaseOnly 判定が参照)
  3257. \t\t\t\tswitch (i) {
  3258. \t\t\t\t\tcase 0:  op0  = onNode.value; break;
  3259. \t\t\t\t\tcase 1:  op1  = onNode.value; break;
  3260. \t\t\t\t\tcase 2:  op2  = onNode.value; break;
  3261. \t\t\t\t\tcase 3:  op3  = onNode.value; break;
  3262. \t\t\t\t\tcase 4:  op4  = onNode.value; break;
  3263. \t\t\t\t\tcase 5:  op5  = onNode.value; break;
  3264. \t\t\t\t\tcase 6:  op6  = onNode.value; break;
  3265. \t\t\t\t\tcase 7:  op7  = onNode.value; break;
  3266. \t\t\t\t\tcase 8:  op8  = onNode.value; break;
  3267. \t\t\t\t\tcase 9:  op9  = onNode.value; break;
  3268. \t\t\t\t\tcase 10: op10 = onNode.value; break;
  3269. \t\t\t\t}
  3270. \t\t\t\t// opt-btn の is-selected を付け替え
  3271. \t\t\t\tvar lbl = onNode.closest('.opt-btn');
  3272. \t\t\t\tif (lbl) {
  3273. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  3274. \t\t\t\t\tfor (var s = 0; s < sib.length; s++) sib[s].classList.remove('is-selected');
  3275. \t\t\t\t\tlbl.classList.add('is-selected');
  3276. \t\t\t\t}
  3277. \t\t\t\t// rp-section-label 表示同期 + 現地調査文言(is_removal_unknown / is_tf_kouji)を on 表示に
  3278. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || onNode.closest('.form-group');
  3279. \t\t\t\tif (grp) {
  3280. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  3281. \t\t\t\t\tif (section) {
  3282. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3283. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + onNode.value + '</span>';
  3284. \t\t\t\t\t}
  3285. \t\t\t\t\tvar note = grp.querySelector('.opt-survey-note[data-op-idx=\"' + i + '\"]');
  3286. \t\t\t\t\tif (note) note.style.display = '';
  3287. \t\t\t\t}
  3288. \t\t\t}
  3289. \t\t})();
  3290. \t\t// ページ読み込み時: 見積金額が「合計」になっているため、カート数量は基本1
  3291. \t\t// sale_type=9(商品のみ購入)だけ通常 EC として数量を引き継ぐ
  3292. \t\t(function initQuantityByType(){
  3293. \t\t\tvar saleType = ";
  3294.         // line 3031
  3295.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3031$this->source); })()), "SaleType", [], "any"falsefalsefalse3031), "id", [], "any"falsefalsefalse3031), "html"nulltrue);
  3296.         echo ";
  3297. \t\t\tif (saleType == 9 && \$('#quantity_only').length) {
  3298. \t\t\t\t\$('#quantity').val(parseInt(\$('#quantity_only').val()) || 1);
  3299. \t\t\t} else {
  3300. \t\t\t\t\$('#quantity').val(1);
  3301. \t\t\t\t\$('input[name=\"quantity\"]').val(1);
  3302. \t\t\t}
  3303. \t\t})();
  3304. \t\t// type → ラベルのプレフィックス文字列
  3305. \t\t";
  3306.         // line 3044
  3307.         echo "\t\t";
  3308.         $context["pm_is_roof"] = false;
  3309.         // line 3045
  3310.         echo "\t\t";
  3311.         $context["pm_stems"] = [];
  3312.         // line 3046
  3313.         echo "\t\t";
  3314.         if ((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3046$this->source); })())) {
  3315.             $context['_parent'] = $context;
  3316.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3046$this->source); })()));
  3317.             foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  3318.                 if ($context["v"]) {
  3319.                     // line 3047
  3320.                     echo "\t\t\t";
  3321.                     if (preg_match("/ポリカ|折板|波板|熱線|ふきポリ|アルミ形材屋根|スチール折板/"$context["v"])) {
  3322.                         $context["pm_is_roof"] = true;
  3323.                     }
  3324.                     // line 3048
  3325.                     echo "\t\t\t";
  3326.                     $context["pm_stem"] = twig_trim_filter(twig_first($this->envtwig_split_filter($this->envtwig_first($this->envtwig_split_filter($this->env$context["v"], "(")), "(")));
  3327.                     // line 3049
  3328.                     echo "\t\t\t";
  3329.                     if (!twig_in_filter((isset($context["pm_stem"]) || array_key_exists("pm_stem"$context) ? $context["pm_stem"] : (function () { throw new RuntimeError('Variable "pm_stem" does not exist.'3049$this->source); })()), (isset($context["pm_stems"]) || array_key_exists("pm_stems"$context) ? $context["pm_stems"] : (function () { throw new RuntimeError('Variable "pm_stems" does not exist.'3049$this->source); })()))) {
  3330.                         $context["pm_stems"] = twig_array_merge((isset($context["pm_stems"]) || array_key_exists("pm_stems"$context) ? $context["pm_stems"] : (function () { throw new RuntimeError('Variable "pm_stems" does not exist.'3049$this->source); })()), [=> (isset($context["pm_stem"]) || array_key_exists("pm_stem"$context) ? $context["pm_stem"] : (function () { throw new RuntimeError('Variable "pm_stem" does not exist.'3049$this->source); })())]);
  3331.                     }
  3332.                     // line 3050
  3333.                     echo "\t\t";
  3334.                 }
  3335.             }
  3336.             $_parent $context['_parent'];
  3337.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  3338.             $context array_intersect_key($context$_parent) + $_parent;
  3339.         }
  3340.         // line 3051
  3341.         echo "\t\t";
  3342.         $context["pm_label"] = (((isset($context["pm_is_roof"]) || array_key_exists("pm_is_roof"$context) ? $context["pm_is_roof"] : (function () { throw new RuntimeError('Variable "pm_is_roof" does not exist.'3051$this->source); })())) ? ((((twig_length_filter($this->env, (isset($context["pm_stems"]) || array_key_exists("pm_stems"$context) ? $context["pm_stems"] : (function () { throw new RuntimeError('Variable "pm_stems" does not exist.'3051$this->source); })())) >= 2)) ? ("屋根材") : ("屋根材の色"))) : ("素材"));
  3343.         // line 3052
  3344.         echo "\t\t// option1/option2 のラベルは category 依存 (rd: ランマ/タイプ, sh: サイズプリセット/駆動方式 等).
  3345. \t\t// PHP から渡された option1_label / option2_label を埋め込み、JS 側でラベル更新に使う.
  3346. \t\tvar optLabelMap = {pc:'カラー', pw:'幅', pd:'奥行き', ph:'高さ', pm:'";
  3347.         // line 3054
  3348.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, (isset($context["pm_label"]) || array_key_exists("pm_label"$context) ? $context["pm_label"] : (function () { throw new RuntimeError('Variable "pm_label" does not exist.'3054$this->source); })()), "js"), "html"nulltrue);
  3349.         echo "',
  3350. \t\t                   option1: '";
  3351.         // line 3055
  3352.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, ((array_key_exists("option1_label"$context)) ? (_twig_default_filter((isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'3055$this->source); })()), "オプション1")) : ("オプション1")), "js"), "html"nulltrue);
  3353.         echo "',
  3354. \t\t                   option2: '";
  3355.         // line 3056
  3356.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, ((array_key_exists("option2_label"$context)) ? (_twig_default_filter((isset($context["option2_label"]) || array_key_exists("option2_label"$context) ? $context["option2_label"] : (function () { throw new RuntimeError('Variable "option2_label" does not exist.'3056$this->source); })()), "オプション2")) : ("オプション2")), "js"), "html"nulltrue);
  3357.         echo "'};
  3358. \t\t// type → input[name]
  3359. \t\tvar optNameMap  = {pc:'color', pw:'pw', pd:'pd', ph:'ph', pm:'pm',
  3360. \t\t                   option1: 'option1', option2: 'option2'};
  3361. \t\t// opt-btn用: 値を直接受け取るラッパー
  3362. \t\tfunction mitsumori_simulation_val(type, value) {
  3363. \t\t\tif (type === 'pc') pc = value;
  3364. \t\t\tif (type === 'pw') pw = value;
  3365. \t\t\tif (type === 'pd') pd = value;
  3366. \t\t\tif (type === 'ph') ph = value;
  3367. \t\t\tif (type === 'pm') pm = value;
  3368. \t\t\tif (type === 'option1') option1 = value;
  3369. \t\t\tif (type === 'option2') option2 = value;
  3370. \t\t\t// is-selected クラスを同グループ内で付け替え
  3371. \t\t\tvar inputName = optNameMap[type];
  3372. \t\t\tif (inputName) {
  3373. \t\t\t\tvar \$btns = \$('input[name=\"' + inputName + '\"]').closest('.opt-btn');
  3374. \t\t\t\t\$btns.removeClass('is-selected');
  3375. \t\t\t\t\$btns.filter(function(){
  3376. \t\t\t\t\treturn \$(this).find('input').val() === value;
  3377. \t\t\t\t}).addClass('is-selected');
  3378. \t\t\t}
  3379. \t\t\t// ラベル行の選択値テキストを更新(例: 「カラー: ブラック」)
  3380. \t\t\tvar labelPrefix = optLabelMap[type];
  3381. \t\t\tif (labelPrefix) {
  3382. \t\t\t\t// 対象のrp-section-labelを特定(input[name]を含む親を遡る)
  3383. \t\t\t\tvar \$group = \$('input[name=\"' + inputName + '\"]').first().closest('.form-group');
  3384. \t\t\t\tvar \$label = \$group.find('.rp-section-label');
  3385. \t\t\t\t\$label.html(labelPrefix + ': <span>' + value + '</span>');
  3386. \t\t\t}
  3387. \t\t\t// simulation本体を呼ぶ(value_idは空でOK、グローバル変数を使う)
  3388. \t\t\tmitsumori_simulation('', '');
  3389. \t\t}
  3390. \t\tmitsumori_simulation(\"\",\"\");
  3391. \t\t// ボタン群: 親幅を超える、または3行以上になる場合は is-scroll を付与し
  3392. \t\t// 縦3段グリッド+横スクロール表示にする(顧客要望「3列くらいで横スクロール」)
  3393. \t\tfunction applyBtnGroupScroll() {
  3394. \t\t\t\$('.rp-btn-group, .opt-btn-group').each(function() {
  3395. \t\t\t\tvar \$group = \$(this);
  3396. \t\t\t\t\$group.removeClass('is-scroll');
  3397. \t\t\t\t// 意図的な縦リスト(no-hscroll / flex-direction:column)は横スクロール化しない。
  3398. \t\t\t\t// フェンス fe_block の縦6行(A-2)や内窓(sale_type=2)の長いガラス名(A-3)が
  3399. \t\t\t\t// 3行以上/幅超過で is-scroll 化され、列崩れ・左見切れを起こすのを防ぐ。
  3400. \t\t\t\tif (\$group.hasClass('no-hscroll') || \$group.css('flex-direction') === 'column') return;
  3401. \t\t\t\tvar \$items = \$group.children();
  3402. \t\t\t\tif (\$items.length === 0) return;
  3403. \t\t\t\tvar parentWidth = \$group.parent().width() || \$group.width();
  3404. \t\t\t\tvar totalWidth = 0;
  3405. \t\t\t\tvar gap = parseInt(\$group.css('gap'), 10) || 8;
  3406. \t\t\t\t\$items.each(function() {
  3407. \t\t\t\t\ttotalWidth += this.offsetWidth + gap;
  3408. \t\t\t\t});
  3409. \t\t\t\t// 単一ボタンが親幅を超える、もしくは合計幅が親幅を超える → 横スクロール化
  3410. \t\t\t\tvar anyTooWide = false;
  3411. \t\t\t\t\$items.each(function() {
  3412. \t\t\t\t\tif (this.offsetWidth > parentWidth) { anyTooWide = true; return false; }
  3413. \t\t\t\t});
  3414. \t\t\t\t// 折り返し時の行数も計測
  3415. \t\t\t\tvar tops = {};
  3416. \t\t\t\t\$items.each(function() { tops[this.offsetTop] = true; });
  3417. \t\t\t\tvar rowCount = Object.keys(tops).length;
  3418. \t\t\t\tif (anyTooWide || totalWidth > parentWidth * 2 || rowCount >= 3) {
  3419. \t\t\t\t\t\$group.addClass('is-scroll');
  3420. \t\t\t\t}
  3421. \t\t\t});
  3422. \t\t}
  3423. \t\tapplyBtnGroupScroll();
  3424. \t\t\$(window).on('resize', function() {
  3425. \t\t\tclearTimeout(window._btnScrollTimer);
  3426. \t\t\twindow._btnScrollTimer = setTimeout(applyBtnGroupScroll, 150);
  3427. \t\t});
  3428. \t\t// iOS Safari 1-tap fix (#15 再発): is-scroll の横スクロールコンテナ内タップや
  3429. \t\t// 継承された a:hover により、初回タップが hover / スクロール判定に吸われ「2 回
  3430. \t\t// タッチ」が必要になる。touch 端末では touchend で 1 回目に選択 / 遷移を確定し、
  3431. \t\t// 後続のゴーストクリックを preventDefault で抑止する(二重発火なし)。指が動いた
  3432. \t\t// 場合はスクロール操作とみなし何もしない。デスクトップは従来の click のまま。
  3433. \t\t(function oneTapSelectFix(){
  3434. \t\t\tif (!('ontouchstart' in window)) return;
  3435. \t\t\tvar moved = false, sx = 0, sy = 0;
  3436. \t\t\tdocument.addEventListener('touchstart', function(e){
  3437. \t\t\t\tmoved = false;
  3438. \t\t\t\tvar t = e.touches && e.touches[0];
  3439. \t\t\t\tif (t) { sx = t.clientX; sy = t.clientY; }
  3440. \t\t\t}, { passive: true });
  3441. \t\t\tdocument.addEventListener('touchmove', function(e){
  3442. \t\t\t\tvar t = e.touches && e.touches[0];
  3443. \t\t\t\tif (t && (Math.abs(t.clientX - sx) > 8 || Math.abs(t.clientY - sy) > 8)) moved = true;
  3444. \t\t\t}, { passive: true });
  3445. \t\t\tdocument.addEventListener('touchend', function(e){
  3446. \t\t\t\tif (moved) return;
  3447. \t\t\t\tvar el = (e.target && e.target.closest) ? e.target.closest('.opt-btn, .rp-btn, .rp-card') : null;
  3448. \t\t\t\tif (!el) return;
  3449. \t\t\t\t// 窓タイプ / 住宅区分は専用の委譲 click ハンドラを持つため除外.
  3450. \t\t\t\tif (el.closest('#window-types-container') || el.closest('#window-housing-type-group')) return;
  3451. \t\t\t\te.preventDefault(); // 遅延ゴーストクリックを抑止し二重処理を防ぐ
  3452. \t\t\t\tif (el.tagName === 'A' && el.href) { window.location.href = el.href; return; }
  3453. \t\t\t\tel.click(); // label→radio チェック + inline onclick / change を 1 回だけ発火
  3454. \t\t\t}, { passive: false });
  3455. \t\t})();
  3456. \t\t// onload: 見積金額が確定している場合は「工事費込み価格」表示を一致させる
  3457. \t\t(function syncPrice02Display() {
  3458. \t\t\tvar goukeiEl = document.getElementById('mitsumori_goukei');
  3459. \t\t\tvar displayEl = document.getElementById('price02-display');
  3460. \t\t\tif (!goukeiEl || !displayEl) return;
  3461. \t\t\tvar goukeiText = goukeiEl.textContent.trim();
  3462. \t\t\t// ---円(未確定)の場合は書き換えない
  3463. \t\t\tif (goukeiText && goukeiText !== '---円') {
  3464. \t\t\t\tdisplayEl.textContent = goukeiText;
  3465. \t\t\t}
  3466. \t\t\t// 以降の変更にも追従: mitsumori_goukei を監視
  3467. \t\t\tnew MutationObserver(function() {
  3468. \t\t\t\tvar text = goukeiEl.textContent.trim();
  3469. \t\t\t\tif (text && text !== '---円') {
  3470. \t\t\t\t\tdisplayEl.textContent = text;
  3471. \t\t\t\t}
  3472. \t\t\t}).observe(goukeiEl, { childList: true, subtree: true, characterData: true });
  3473. \t\t})();
  3474. \t\tfunction contact_form(product_id){
  3475. \t\t\t\$('#form1').attr('action', '";
  3476.         // line 3186
  3477.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("contact", ["product" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3186$this->source); })()), "id", [], "any"falsefalsefalse3186)]), "html"nulltrue);
  3478.         echo "');
  3479. \t\t\t\$('#form1').submit();
  3480. \t\t}
  3481. \t\t// maisu / madoset は下部の新しい関数定義を使用
  3482. \t\tfunction heibei(bei){
  3483. \t\t\t\$('#heibei').val(parseInt(\$('#heibei').val()) + bei);
  3484. \t\t\tif(parseInt(\$('#heibei').val()) < 1){ \$('#heibei').val(1); }
  3485. \t\t\tif(parseInt(\$('#heibei').val()) > 100){ \$('#heibei').val(100); }
  3486. \t\t\t// goukei に既に枚数を含むため、カート数量は1で固定
  3487. \t\t\t\$('#quantity').val(1);
  3488. \t\t\tmitsumori_simulation('heibei','heibei');
  3489. \t\t}
  3490. \t\tfunction daisu(dai){
  3491. \t\t\t\$('#daisu').val(parseInt(\$('#daisu').val()) + dai);
  3492. \t\t\tif(parseInt(\$('#daisu').val()) < 1){ \$('#daisu').val(1); }
  3493. \t\t\tif(parseInt(\$('#daisu').val()) > 10){ \$('#daisu').val(10); }
  3494. \t\t\t\$('#quantity').val(1);
  3495. \t\t\tmitsumori_simulation('daisu','daisu');
  3496. \t\t}
  3497. \t\t// sale_type=7(数量買い・基本工事費固定)用:個数入力
  3498. \t\tfunction suuryou(n){
  3499. \t\t\t\$('#suuryou').val(parseInt(\$('#suuryou').val()) + n);
  3500. \t\t\tif(parseInt(\$('#suuryou').val()) < 1){ \$('#suuryou').val(1); }
  3501. \t\t\tif(parseInt(\$('#suuryou').val()) > 100){ \$('#suuryou').val(100); }
  3502. \t\t\t\$('#quantity').val(1);
  3503. \t\t\tmitsumori_simulation('suuryou','suuryou');
  3504. \t\t}
  3505. \t\tfunction maisu(mai){
  3506. \t\t\t\$('#maisu').val(parseInt(\$('#maisu').val()) + mai);
  3507. \t\t\t// sale_type=4 (フェンス) は3枚未満不可、6 (芝生) は1枚から
  3508. \t\t\tvar minMai = (SALE_TYPE_ID == 4) ? 3 : 1;
  3509. \t\t\tif(parseInt(\$('#maisu').val()) < minMai){ \$('#maisu').val(minMai); }
  3510. \t\t\tif(parseInt(\$('#maisu').val()) > 100){ \$('#maisu').val(100); }
  3511. \t\t\t\$('#quantity').val(1);
  3512. \t\t\tmitsumori_simulation('maisu','maisu');
  3513. \t\t}
  3514. \t\t// タイプ2: セット数プルダウン連動
  3515. \t\tfunction madosetSelect(val){
  3516. \t\t\tvar v = parseInt(val);
  3517. \t\t\tif(v < 1) v = 1;
  3518. \t\t\tif(v > 20) v = 20;
  3519. \t\t\t\$('#set_count').val(v);
  3520. \t\t\t\$('#quantity').val(1);
  3521. \t\t\t\$('input[name=\"quantity\"]').val(1);
  3522. \t\t\tmitsumori_simulation('set','set_count');
  3523. \t\t}
  3524. \t\t// タイプ2: ±ボタン版(後方互換)
  3525. \t\tfunction madoset(mai){
  3526. \t\t\tvar current = parseInt(\$('#set_count').val()) || 1;
  3527. \t\t\tvar next = current + mai;
  3528. \t\t\tif(next < 1) next = 1;
  3529. \t\t\tif(next > 20) next = 20;
  3530. \t\t\t\$('#set_count').val(next);
  3531. \t\t\tmadosetSelect(next);
  3532. \t\t}
  3533. \t\t// タイプ5: ステップ・フェンス選択値を mitsumori_json に保存するためのグローバル変数
  3534. \t\tvar deck_step = \"";
  3535.         // line 3247
  3536.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3247$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse3247))) {
  3537.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse3247)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"falsefalsefalse3247), "不要")) : ("不要")), "html"nulltrue);
  3538.         } else {
  3539.             echo "不要";
  3540.         }
  3541.         echo "\";
  3542. \t\tvar deck_fence = \"";
  3543.         // line 3248
  3544.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3248$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse3248))) {
  3545.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse3248)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"falsefalsefalse3248), "不要")) : ("不要")), "html"nulltrue);
  3546.         } else {
  3547.             echo "不要";
  3548.         }
  3549.         echo "\";
  3550. \t\t// PDF出力: モーダルの mitsumori_json をフォームに同期してから送信
  3551. \t\tfunction syncPdfJson(){
  3552. \t\t\tvar jsonVal = \$('#mitsumori_json').val();
  3553. \t\t\t\$('#pdf_mitsumori_json').val(jsonVal);
  3554. \t\t}
  3555. \t\t// タイプ9: 商品のみ購入
  3556. \t\tfunction quantityOnly(val){
  3557. \t\t\tvar current = parseInt(\$('#quantity_only').val()) || 1;
  3558. \t\t\tvar next = current + val;
  3559. \t\t\tif(next < 1) next = 1;
  3560. \t\t\t\$('#quantity_only').val(next);
  3561. \t\t\t\$('#quantity').val(next);
  3562. \t\t}
  3563.         // ===== スマホ用下部固定バーへの金額同期 =====
  3564.         // mitsumori_message と mitsumori_goukei を監視して下部バーを更新
  3565.         (function() {
  3566.             var msgTarget   = document.getElementById('mitsumori_message');
  3567.             var goukeiTarget = document.getElementById('mitsumori_goukei');
  3568.             var spPrice     = document.getElementById('sp-mitsumori-price');
  3569.             var spBtn       = document.querySelector('#sp-mitsumori-bar .sp-bar__btn');
  3570.             if (!spPrice || !spBtn) return;
  3571.             function syncBar() {
  3572.                 var msg    = msgTarget ? msgTarget.textContent : '';
  3573.                 var goukei = goukeiTarget ? goukeiTarget.textContent : '---円';
  3574.                 // メッセージが「〇〇を選択してください」の場合はメッセージを表示しボタンを非表示
  3575.                 if (msg.indexOf('選択してください') !== -1) {
  3576.                     spPrice.textContent = msg;
  3577.                     spPrice.style.fontSize = '13px';
  3578.                     spPrice.style.color    = '#888';
  3579.                     spBtn.style.display    = 'none';
  3580.                 } else {
  3581.                     // 価格確定時はボタンを表示
  3582.                     spPrice.textContent = goukei;
  3583.                     spPrice.style.fontSize = '18px';
  3584.                     spPrice.style.color    = '#c00';
  3585.                     spBtn.style.display    = 'block';
  3586.                 }
  3587.             }
  3588.             // 初期値を同期
  3589.             syncBar();
  3590.             // mitsumori_message の変化を監視
  3591.             if (msgTarget) {
  3592.                 new MutationObserver(syncBar).observe(
  3593.                     msgTarget, { childList: true, subtree: true, characterData: true }
  3594.                 );
  3595.             }
  3596.             // mitsumori_goukei の変化も監視
  3597.             if (goukeiTarget) {
  3598.                 new MutationObserver(syncBar).observe(
  3599.                     goukeiTarget, { childList: true, subtree: true, characterData: true }
  3600.                 );
  3601.             }
  3602.         })();
  3603.         // ===== スマホ用 お見積りの詳細 ボトムシート 開閉 =====
  3604.         // 現在の内訳カード(.mitsumori-card-pc .card-body)を複製して表示する。
  3605.         // 価格計算ロジックには触れず、その時点で表示中の内訳をそのまま見せる。
  3606.         // window に直接ぶら下げてスコープに依存せず onclick から呼べるようにする。
  3607.         window.openSpMitsumoriDetail = function () {
  3608.             var sheet = document.getElementById('sp-mitsumori-detail');
  3609.             var body  = document.getElementById('sp-detail-body');
  3610.             var src   = document.querySelector('.mitsumori-card-pc .card-body');
  3611.             if (!sheet || !body) return;
  3612.             body.innerHTML = '';
  3613.             if (src) {
  3614.                 // 複製し、重複 id を避けるため clone 側の id を除去する
  3615.                 var clone = src.cloneNode(true);
  3616.                 var ided = clone.querySelectorAll('[id]');
  3617.                 for (var i = 0; i < ided.length; i++) { ided[i].removeAttribute('id'); }
  3618.                 body.appendChild(clone);
  3619.             }
  3620.             sheet.classList.add('is-open');
  3621.             sheet.setAttribute('aria-hidden', 'false');
  3622.             document.body.style.overflow = 'hidden';
  3623.         };
  3624.         window.closeSpMitsumoriDetail = function () {
  3625.             var sheet = document.getElementById('sp-mitsumori-detail');
  3626.             if (!sheet) return;
  3627.             sheet.classList.remove('is-open');
  3628.             sheet.setAttribute('aria-hidden', 'true');
  3629.             document.body.style.overflow = '';
  3630.         };
  3631.         // ===== 現在のお見積り額: 折りたたみトグルボタンのテキスト切り替え =====
  3632.         (function() {
  3633.             var card = document.querySelector('.mitsumori-card-pc');
  3634.             var btn  = document.querySelector('.btn-mitsumori-toggle .toggle-icon');
  3635.             if (!card || !btn) return;
  3636.             // MutationObserverでcollapsed-cardクラスの変化を監視
  3637.             new MutationObserver(function() {
  3638.                 if (card.classList.contains('collapsed-card')) {
  3639.                     btn.textContent = '▼ 詳細';
  3640.                 } else {
  3641.                     btn.textContent = '▲ 閉じる';
  3642.                 }
  3643.             }).observe(card, { attributes: true, attributeFilter: ['class'] });
  3644.         })();
  3645.         // ===== エリア案内: スマホのみタップで展開 =====
  3646.         (function() {
  3647.             var notice = document.querySelector('.ec-areaNotice');
  3648.             if (!notice) return;
  3649.             notice.addEventListener('click', function(e) {
  3650.                 if (window.innerWidth > 767) return;
  3651.                 // リンククリック時は展開/折りたたみせずリンク遷移
  3652.                 if (e.target.tagName === 'A') return;
  3653.                 notice.classList.toggle('is-open');
  3654.             });
  3655.         })();
  3656.     </script>
  3657.     <script type=\"application/ld+json\">
  3658.     {
  3659.         \"@context\": \"https://schema.org/\",
  3660.         \"@type\": \"Product\",
  3661.         \"name\": \"";
  3662.         // line 3371
  3663.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3371$this->source); })()), "name", [], "any"falsefalsefalse3371), "html"nulltrue);
  3664.         echo "\",
  3665.         \"image\": [
  3666.             ";
  3667.         // line 3373
  3668.         $context['_parent'] = $context;
  3669.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3373$this->source); })()), "ProductImage", [], "any"falsefalsefalse3373));
  3670.         $context['_iterated'] = false;
  3671.         $context['loop'] = [
  3672.           'parent' => $context['_parent'],
  3673.           'index0' => 0,
  3674.           'index'  => 1,
  3675.           'first'  => true,
  3676.         ];
  3677.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3678.             $length count($context['_seq']);
  3679.             $context['loop']['revindex0'] = $length 1;
  3680.             $context['loop']['revindex'] = $length;
  3681.             $context['loop']['length'] = $length;
  3682.             $context['loop']['last'] = === $length;
  3683.         }
  3684.         foreach ($context['_seq'] as $context["_key"] => $context["img"]) {
  3685.             // line 3374
  3686.             echo "                \"";
  3687.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3374$this->source); })()), "request", [], "any"falsefalsefalse3374), "schemeAndHttpHost", [], "any"falsefalsefalse3374), "html"nulltrue);
  3688.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["img"], "save_image"), "html"nulltrue);
  3689.             echo "\"";
  3690.             if ( !twig_get_attribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse3374)) {
  3691.                 echo ",";
  3692.             }
  3693.             // line 3375
  3694.             echo "
  3695.             ";
  3696.             $context['_iterated'] = true;
  3697.             ++$context['loop']['index0'];
  3698.             ++$context['loop']['index'];
  3699.             $context['loop']['first'] = false;
  3700.             if (isset($context['loop']['length'])) {
  3701.                 --$context['loop']['revindex0'];
  3702.                 --$context['loop']['revindex'];
  3703.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3704.             }
  3705.         }
  3706.         if (!$context['_iterated']) {
  3707.             // line 3377
  3708.             echo "                \"";
  3709.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3377$this->source); })()), "request", [], "any"falsefalsefalse3377), "schemeAndHttpHost", [], "any"falsefalsefalse3377), "html"nulltrue);
  3710.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"), "html"nulltrue);
  3711.             echo "\"
  3712.             ";
  3713.         }
  3714.         $_parent $context['_parent'];
  3715.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['img'], $context['_parent'], $context['loop']);
  3716.         $context array_intersect_key($context$_parent) + $_parent;
  3717.         // line 3379
  3718.         echo "        ],
  3719.         \"description\": \"";
  3720.         // line 3380
  3721.         echo twig_escape_filter($this->envtwig_slice($this->envtwig_replace_filter(((twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "description_list", [], "any"truetruefalse3380)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "description_list", [], "any"falsefalsefalse3380), twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3380$this->source); })()), "description_detail", [], "any"falsefalsefalse3380))) : (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3380$this->source); })()), "description_detail", [], "any"falsefalsefalse3380))), ["
  3722. => """ " => ""]), 0300), "html"nulltrue);
  3723.         echo "\",
  3724.         ";
  3725.         // line 3381
  3726.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3381$this->source); })()), "code_min", [], "any"falsefalsefalse3381)) {
  3727.             // line 3382
  3728.             echo "        \"sku\": \"";
  3729.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3382$this->source); })()), "code_min", [], "any"falsefalsefalse3382), "html"nulltrue);
  3730.             echo "\",
  3731.         ";
  3732.         }
  3733.         // line 3384
  3734.         echo "        \"offers\": {
  3735.             \"@type\": \"Offer\",
  3736.             \"url\": \"";
  3737.         // line 3386
  3738.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_detail", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3386$this->source); })()), "id", [], "any"falsefalsefalse3386)]), "html"nulltrue);
  3739.         echo "\",
  3740.             \"priceCurrency\": \"";
  3741.         // line 3387
  3742.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["eccube_config"]) || array_key_exists("eccube_config"$context) ? $context["eccube_config"] : (function () { throw new RuntimeError('Variable "eccube_config" does not exist.'3387$this->source); })()), "currency", [], "any"falsefalsefalse3387), "html"nulltrue);
  3743.         echo "\",
  3744.             \"price\": ";
  3745.         // line 3388
  3746.         ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3388$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3388)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3388$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3388), "html"nulltrue))) : (print (0)));
  3747.         echo ",
  3748.             \"availability\": \"";
  3749.         // line 3389
  3750.         echo ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3389$this->source); })()), "stock_find", [], "any"falsefalsefalse3389)) ? ("InStock") : ("OutOfStock"));
  3751.         echo "\"
  3752.         }
  3753.     }
  3754.     </script>
  3755. ";
  3756.         
  3757.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  3758.         
  3759.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  3760.     }
  3761.     // line 3396
  3762.     public function block_main($context, array $blocks = [])
  3763.     {
  3764.         $macros $this->macros;
  3765.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  3766.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  3767.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  3768.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  3769.         // line 3397
  3770.         echo "    ";
  3771.         // line 3398
  3772.         echo "    ";
  3773.         $context["option1_label"] = "オプション1";
  3774.         // line 3399
  3775.         echo "    ";
  3776.         $context["option2_label"] = "オプション2";
  3777.         // line 3400
  3778.         echo "    ";
  3779.         // line 3403
  3780.         echo "    ";
  3781.         $context["is_cat43"] = false;
  3782.         // line 3404
  3783.         echo "    ";
  3784.         // line 3406
  3785.         echo "    ";
  3786.         $context["is_cp"] = false;
  3787.         // line 3407
  3788.         echo "    ";
  3789.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3407$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3407))) {
  3790.             // line 3408
  3791.             echo "        ";
  3792.             $context['_parent'] = $context;
  3793.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3408$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3408));
  3794.             foreach ($context['_seq'] as $context["_key"] => $context["pcat"]) {
  3795.                 // line 3409
  3796.                 echo "            ";
  3797.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3409) == 31)) {
  3798.                     $context["option1_label"] = "サイズプリセット";
  3799.                     $context["option2_label"] = "駆動方式";
  3800.                 }
  3801.                 // line 3410
  3802.                 echo "            ";
  3803.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3410) == 43)) {
  3804.                     $context["option1_label"] = "ランマ";
  3805.                     $context["option2_label"] = "タイプ";
  3806.                     $context["is_cat43"] = true;
  3807.                 }
  3808.                 // line 3411
  3809.                 echo "            ";
  3810.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3411) == 15)) {
  3811.                     $context["option1_label"] = "棚タイプ";
  3812.                 }
  3813.                 // line 3412
  3814.                 echo "            ";
  3815.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3412) == 17)) {
  3816.                     $context["option1_label"] = "窓タイプ";
  3817.                 }
  3818.                 // line 3413
  3819.                 echo "            ";
  3820.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3413) == 7)) {
  3821.                     $context["is_cp"] = true;
  3822.                 }
  3823.                 // line 3414
  3824.                 echo "        ";
  3825.             }
  3826.             $_parent $context['_parent'];
  3827.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pcat'], $context['_parent'], $context['loop']);
  3828.             $context array_intersect_key($context$_parent) + $_parent;
  3829.             // line 3415
  3830.             echo "    ";
  3831.         }
  3832.         // line 3416
  3833.         echo "    ";
  3834.         // line 3418
  3835.         echo "    ";
  3836.         $context["pm_is_roof"] = false;
  3837.         // line 3419
  3838.         echo "    ";
  3839.         $context["pm_stems"] = [];
  3840.         // line 3420
  3841.         echo "    ";
  3842.         if ((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3420$this->source); })())) {
  3843.             $context['_parent'] = $context;
  3844.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3420$this->source); })()));
  3845.             foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  3846.                 if ($context["v"]) {
  3847.                     // line 3421
  3848.                     echo "        ";
  3849.                     if (preg_match("/ポリカ|折板|波板|熱線|ふきポリ|アルミ形材屋根|スチール折板/"$context["v"])) {
  3850.                         $context["pm_is_roof"] = true;
  3851.                     }
  3852.                     // line 3422
  3853.                     echo "        ";
  3854.                     $context["pm_stem"] = twig_trim_filter(twig_first($this->envtwig_split_filter($this->envtwig_first($this->envtwig_split_filter($this->env$context["v"], "(")), "(")));
  3855.                     // line 3423
  3856.                     echo "        ";
  3857.                     if (!twig_in_filter((isset($context["pm_stem"]) || array_key_exists("pm_stem"$context) ? $context["pm_stem"] : (function () { throw new RuntimeError('Variable "pm_stem" does not exist.'3423$this->source); })()), (isset($context["pm_stems"]) || array_key_exists("pm_stems"$context) ? $context["pm_stems"] : (function () { throw new RuntimeError('Variable "pm_stems" does not exist.'3423$this->source); })()))) {
  3858.                         $context["pm_stems"] = twig_array_merge((isset($context["pm_stems"]) || array_key_exists("pm_stems"$context) ? $context["pm_stems"] : (function () { throw new RuntimeError('Variable "pm_stems" does not exist.'3423$this->source); })()), [=> (isset($context["pm_stem"]) || array_key_exists("pm_stem"$context) ? $context["pm_stem"] : (function () { throw new RuntimeError('Variable "pm_stem" does not exist.'3423$this->source); })())]);
  3859.                     }
  3860.                     // line 3424
  3861.                     echo "    ";
  3862.                 }
  3863.             }
  3864.             $_parent $context['_parent'];
  3865.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  3866.             $context array_intersect_key($context$_parent) + $_parent;
  3867.         }
  3868.         // line 3425
  3869.         echo "    ";
  3870.         $context["pm_label"] = (((isset($context["pm_is_roof"]) || array_key_exists("pm_is_roof"$context) ? $context["pm_is_roof"] : (function () { throw new RuntimeError('Variable "pm_is_roof" does not exist.'3425$this->source); })())) ? ((((twig_length_filter($this->env, (isset($context["pm_stems"]) || array_key_exists("pm_stems"$context) ? $context["pm_stems"] : (function () { throw new RuntimeError('Variable "pm_stems" does not exist.'3425$this->source); })())) >= 2)) ? ("屋根材") : ("屋根材の色"))) : ("素材"));
  3871.         // line 3426
  3872.         echo "    <div class=\"ec-productRole\" style=\"margin-top:20px;\">
  3873.         <div class=\"ec-grid2\">
  3874.             <div class=\"ec-grid2__cell\">
  3875.                 <div class=\"ec-sliderItemRole\">
  3876. \t                ";
  3877.         // line 3431
  3878.         echo "\t                <div class=\"ec-productRole__title\">
  3879. \t                    <div class=\"ec-productRole__titleRow\">
  3880. \t                        <h2 class=\"ec-headingTitle\">";
  3881.         // line 3433
  3882.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3433$this->source); })()), "name", [], "any"falsefalsefalse3433), "html"nulltrue);
  3883.         echo "</h2>
  3884. \t                        <div class=\"ec-share-inline\">
  3885. \t                            <a href=\"https://twitter.com/share?url=";
  3886.         // line 3435
  3887.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3435$this->source); })()), "request", [], "any"falsefalsefalse3435), "uri", [], "any"falsefalsefalse3435)), "html"nulltrue);
  3888.         echo "&text=";
  3889.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3435$this->source); })()), "name", [], "any"falsefalsefalse3435)), "html"nulltrue);
  3890.         echo "\"
  3891. \t                               class=\"share-twitter\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Xでシェア\">
  3892. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.74l7.73-8.835L1.254 2.25H8.08l4.254 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>
  3893. \t                            </a>
  3894. \t                            <a href=\"https://www.instagram.com/\" class=\"share-facebook\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Instagram\">
  3895. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"/></svg>
  3896. \t                            </a>
  3897. \t                            <a href=\"https://social-plugins.line.me/lineit/share?url=";
  3898.         // line 3442
  3899.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3442$this->source); })()), "request", [], "any"falsefalsefalse3442), "uri", [], "any"falsefalsefalse3442)), "html"nulltrue);
  3900.         echo "\"
  3901. \t                               class=\"share-line\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"LINEでシェア\">
  3902. \t                                <i class=\"fab fa-line\"></i>
  3903. \t                            </a>
  3904. \t                        </div>
  3905. \t                    </div>
  3906. \t                </div>
  3907.                     ";
  3908.         // line 3449
  3909.         if (twig_get_attribute($this->env$this->source, (isset($context["BaseInfo"]) || array_key_exists("BaseInfo"$context) ? $context["BaseInfo"] : (function () { throw new RuntimeError('Variable "BaseInfo" does not exist.'3449$this->source); })()), "option_favorite_product", [], "any"falsefalsefalse3449)) {
  3910.             // line 3450
  3911.             echo "                     <div style=\"position:relative;top: 20px;left: 10px;z-index:100;\">
  3912. \t\t\t\t\t\t";
  3913.             // line 3451
  3914.             if (((isset($context["is_favorite"]) || array_key_exists("is_favorite"$context) ? $context["is_favorite"] : (function () { throw new RuntimeError('Variable "is_favorite" does not exist.'3451$this->source); })()) == false)) {
  3915.                 // line 3452
  3916.                 echo "                        <form action=\"";
  3917.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_favorite", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3452$this->source); })()), "id", [], "any"falsefalsefalse3452)]), "html"nulltrue);
  3918.                 echo "\" method=\"post\">
  3919.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\">&#9825;</button>
  3920.                         </form>
  3921.                         ";
  3922.             } else {
  3923.                 // line 3456
  3924.                 echo "                        <form action=\"";
  3925.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_favorite", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3456$this->source); })()), "id", [], "any"falsefalsefalse3456)]), "html"nulltrue);
  3926.                 echo "\" method=\"post\">
  3927.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\" style=\"color:red;\">&#9829;</button>
  3928.                         </form>
  3929.                         ";
  3930.             }
  3931.             // line 3460
  3932.             echo "                     </div>
  3933.                     ";
  3934.         }
  3935.         // line 3462
  3936.         echo "                    <div class=\"item_visual\">
  3937.                         ";
  3938.         // line 3463
  3939.         $context['_parent'] = $context;
  3940.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3463$this->source); })()), "ProductImage", [], "any"falsefalsefalse3463));
  3941.         $context['_iterated'] = false;
  3942.         $context['loop'] = [
  3943.           'parent' => $context['_parent'],
  3944.           'index0' => 0,
  3945.           'index'  => 1,
  3946.           'first'  => true,
  3947.         ];
  3948.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3949.             $length count($context['_seq']);
  3950.             $context['loop']['revindex0'] = $length 1;
  3951.             $context['loop']['revindex'] = $length;
  3952.             $context['loop']['length'] = $length;
  3953.             $context['loop']['last'] = === $length;
  3954.         }
  3955.         foreach ($context['_seq'] as $context["_key"] => $context["ProductImage"]) {
  3956.             // line 3464
  3957.             echo "                            <div class=\"slide-item\">
  3958.                                 <a class=\"js-zoom\" href=\"";
  3959.             // line 3465
  3960.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3961.             echo "\" aria-label=\"";
  3962.             ((twig_get_attribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse3465)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3465$this->source); })()), "name", [], "any"falsefalsefalse3465), "html"nulltrue))) : (print ("")));
  3963.             echo "\">
  3964.                                     <img src=\"";
  3965.             // line 3466
  3966.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3967.             echo "\" alt=\"";
  3968.             ((twig_get_attribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse3466)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3466$this->source); })()), "name", [], "any"falsefalsefalse3466), "html"nulltrue))) : (print ("")));
  3969.             echo "\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"";
  3970.             if ((twig_get_attribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse3466) > 1)) {
  3971.                 echo " loading=\"lazy\"";
  3972.             }
  3973.             echo ">
  3974.                                 </a>
  3975.                             </div>
  3976.                         ";
  3977.             $context['_iterated'] = true;
  3978.             ++$context['loop']['index0'];
  3979.             ++$context['loop']['index'];
  3980.             $context['loop']['first'] = false;
  3981.             if (isset($context['loop']['length'])) {
  3982.                 --$context['loop']['revindex0'];
  3983.                 --$context['loop']['revindex'];
  3984.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3985.             }
  3986.         }
  3987.         if (!$context['_iterated']) {
  3988.             // line 3470
  3989.             echo "                            <div class=\"slide-item\"><img src=\"";
  3990.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"), "html"nulltrue);
  3991.             echo "\" alt=\"";
  3992.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3470$this->source); })()), "name", [], "any"falsefalsefalse3470), "html"nulltrue);
  3993.             echo "\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"></div>
  3994.                         ";
  3995.         }
  3996.         $_parent $context['_parent'];
  3997.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductImage'], $context['_parent'], $context['loop']);
  3998.         $context array_intersect_key($context$_parent) + $_parent;
  3999.         // line 3472
  4000.         echo "                    </div>
  4001.                     <div class=\"item_nav\">
  4002.                         ";
  4003.         // line 3474
  4004.         $context['_parent'] = $context;
  4005.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3474$this->source); })()), "ProductImage", [], "any"falsefalsefalse3474));
  4006.         $context['loop'] = [
  4007.           'parent' => $context['_parent'],
  4008.           'index0' => 0,
  4009.           'index'  => 1,
  4010.           'first'  => true,
  4011.         ];
  4012.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  4013.             $length count($context['_seq']);
  4014.             $context['loop']['revindex0'] = $length 1;
  4015.             $context['loop']['revindex'] = $length;
  4016.             $context['loop']['length'] = $length;
  4017.             $context['loop']['last'] = === $length;
  4018.         }
  4019.         foreach ($context['_seq'] as $context["_key"] => $context["ProductImage"]) {
  4020.             // line 3475
  4021.             echo "                            <div class=\"slideThumb\" data-index=\"";
  4022.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["loop"], "index0", [], "any"falsefalsefalse3475), "html"nulltrue);
  4023.             echo "\"><img src=\"";
  4024.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  4025.             echo "\" alt=\"\" width=\"80\" height=\"80\" loading=\"lazy\"></div>
  4026.                         ";
  4027.             ++$context['loop']['index0'];
  4028.             ++$context['loop']['index'];
  4029.             $context['loop']['first'] = false;
  4030.             if (isset($context['loop']['length'])) {
  4031.                 --$context['loop']['revindex0'];
  4032.                 --$context['loop']['revindex'];
  4033.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  4034.             }
  4035.         }
  4036.         $_parent $context['_parent'];
  4037.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductImage'], $context['_parent'], $context['loop']);
  4038.         $context array_intersect_key($context$_parent) + $_parent;
  4039.         // line 3477
  4040.         echo "                    </div>
  4041.                 </div>
  4042.                     ";
  4043.         // line 3482
  4044.         echo "                    <div class=\"ec-areaNotice\" style=\"margin-top:16px;margin-right:10px;\">
  4045.                         <div class=\"ec-areaNotice__inner\">
  4046.                             <div class=\"ec-areaNotice__icon\">📍</div>
  4047.                             <div class=\"ec-areaNotice__body\">
  4048.                                 <p class=\"ec-areaNotice__title\">施工対応エリアについて</p>
  4049.                                 <div class=\"ec-areaNotice__detail\">
  4050.                                     <p class=\"ec-areaNotice__text\">
  4051.                                         当店の施工サービスは、<strong>山梨県全域</strong>および<br>
  4052.                                         <strong>諏訪エリア(諏訪市・岡谷市・茅野市・諏訪郡)</strong>を対象としております。<br>
  4053.                                         上記エリア外のお客様には、商品のみのご購入が可能でございます。<br>
  4054.                                         ご不明な点がございましたら、お気軽にお問い合わせください。
  4055.                                     </p>
  4056.                                     <a class=\"ec-areaNotice__link\" href=\"";
  4057.         // line 3494
  4058.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("contact");
  4059.         echo "\">エリア外のお客様・ご相談はこちら →</a>
  4060.                                 </div>
  4061.                             </div>
  4062.                         </div>
  4063.                     </div>
  4064.             </div>
  4065.             <div class=\"ec-grid2__cell2\">
  4066.                 <div class=\"ec-productRole__profile\" >
  4067.                     ";
  4068.         // line 3505
  4069.         echo "                    ";
  4070.         $context["hidden_cat_ids"] = [=> 21=> 28=> 44];
  4071.         // line 3506
  4072.         echo "                    ";
  4073.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3506$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3506))) {
  4074.             // line 3507
  4075.             echo "                        <div class=\"ec-productRole__category\" style=\"padding:10px 0;\">
  4076.                             ";
  4077.             // line 3508
  4078.             $context['_parent'] = $context;
  4079.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3508$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3508));
  4080.             foreach ($context['_seq'] as $context["_key"] => $context["ProductCategory"]) {
  4081.                 // line 3509
  4082.                 echo "                                ";
  4083.                 if (!twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["ProductCategory"], "Category", [], "any"falsefalsefalse3509), "id", [], "any"falsefalsefalse3509), (isset($context["hidden_cat_ids"]) || array_key_exists("hidden_cat_ids"$context) ? $context["hidden_cat_ids"] : (function () { throw new RuntimeError('Variable "hidden_cat_ids" does not exist.'3509$this->source); })()))) {
  4084.                     // line 3510
  4085.                     echo "                                <ul>
  4086.                                     <li>
  4087.                                         ";
  4088.                     // line 3512
  4089.                     $context['_parent'] = $context;
  4090.                     $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["ProductCategory"], "Category", [], "any"falsefalsefalse3512), "path", [], "any"falsefalsefalse3512));
  4091.                     $context['loop'] = [
  4092.                       'parent' => $context['_parent'],
  4093.                       'index0' => 0,
  4094.                       'index'  => 1,
  4095.                       'first'  => true,
  4096.                     ];
  4097.                     if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  4098.                         $length count($context['_seq']);
  4099.                         $context['loop']['revindex0'] = $length 1;
  4100.                         $context['loop']['revindex'] = $length;
  4101.                         $context['loop']['length'] = $length;
  4102.                         $context['loop']['last'] = === $length;
  4103.                     }
  4104.                     foreach ($context['_seq'] as $context["_key"] => $context["Category"]) {
  4105.                         // line 3513
  4106.                         echo "                                            <a href=\"";
  4107.                         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_list");
  4108.                         echo "?category_id=";
  4109.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Category"], "id", [], "any"falsefalsefalse3513), "html"nulltrue);
  4110.                         echo "\">";
  4111.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Category"], "name", [], "any"falsefalsefalse3513), "html"nulltrue);
  4112.                         echo "</a>";
  4113.                         if ((twig_get_attribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse3513) == false)) {
  4114.                             // line 3514
  4115.                             echo "                                            <span>></span>";
  4116.                         }
  4117.                         ++$context['loop']['index0'];
  4118.                         ++$context['loop']['index'];
  4119.                         $context['loop']['first'] = false;
  4120.                         if (isset($context['loop']['length'])) {
  4121.                             --$context['loop']['revindex0'];
  4122.                             --$context['loop']['revindex'];
  4123.                             $context['loop']['last'] = === $context['loop']['revindex0'];
  4124.                         }
  4125.                     }
  4126.                     $_parent $context['_parent'];
  4127.                     unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Category'], $context['_parent'], $context['loop']);
  4128.                     $context array_intersect_key($context$_parent) + $_parent;
  4129.                     // line 3516
  4130.                     echo "                                    </li>
  4131.                                 </ul>
  4132.                                 ";
  4133.                 }
  4134.                 // line 3519
  4135.                 echo "                            ";
  4136.             }
  4137.             $_parent $context['_parent'];
  4138.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductCategory'], $context['_parent'], $context['loop']);
  4139.             $context array_intersect_key($context$_parent) + $_parent;
  4140.             // line 3520
  4141.             echo "                        </div>
  4142.                     ";
  4143.         }
  4144.         // line 3522
  4145.         echo "                    ";
  4146.         // line 3523
  4147.         echo "                    <div class=\"ec-productRole__price\">
  4148. \t\t\t\t\t\t<span style=\"color:black;font-size:15px;\">工事費込み価格</span>
  4149.                         ";
  4150.         // line 3526
  4151.         echo "                        ";
  4152.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3526$this->source); })()), "hasProductClass", [], "any"falsefalsefalse3526)) {
  4153.             // line 3527
  4154.             if ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3527$this->source); })()), "getPrice02Min", [], "any"falsefalsefalse3527) == twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3527$this->source); })()), "getPrice02Max", [], "any"falsefalsefalse3527))) {
  4155.                 // line 3528
  4156.                 echo "                                <div class=\"ec-price\">
  4157.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">";
  4158.                 // line 3529
  4159.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3529$this->source); })()), "getPrice02Min", [], "any"falsefalsefalse3529)), "html"nulltrue);
  4160.                 echo "</span>
  4161.                                     <span class=\"ec-price__tax\">(税抜)~</span>
  4162.                                 </div>
  4163.                             ";
  4164.             } else {
  4165.                 // line 3533
  4166.                 echo "                                <div class=\"ec-price\">
  4167.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">";
  4168.                 // line 3534
  4169.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3534$this->source); })()), "getPrice02Min", [], "any"falsefalsefalse3534)), "html"nulltrue);
  4170.                 echo " ~ ";
  4171.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3534$this->source); })()), "getPrice02Max", [], "any"falsefalsefalse3534)), "html"nulltrue);
  4172.                 echo "</span>
  4173.                                     <span class=\"ec-price__tax\">(税抜)</span>
  4174.                                 </div>
  4175.                             ";
  4176.             }
  4177.             // line 3538
  4178.             echo "                        ";
  4179.         } else {
  4180.             // line 3539
  4181.             echo "                            <div class=\"ec-price\">
  4182.                                 <span id=\"price02-display\" class=\"ec-price__price\">";
  4183.             // line 3540
  4184.             echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3540$this->source); })()), "getPrice02Min", [], "any"falsefalsefalse3540)), "html"nulltrue);
  4185.             echo "</span>
  4186.                                     <span class=\"ec-price__tax\">(税抜)~</span>
  4187.                             </div>
  4188.                         ";
  4189.         }
  4190.         // line 3544
  4191.         echo "                    </div>
  4192.                     ";
  4193.         // line 3546
  4194.         echo "                    <ul class=\"ec-productRole__tags\">
  4195.                         ";
  4196.         // line 3547
  4197.         $context['_parent'] = $context;
  4198.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3547$this->source); })()), "Tags", [], "any"falsefalsefalse3547));
  4199.         foreach ($context['_seq'] as $context["_key"] => $context["Tag"]) {
  4200.             // line 3548
  4201.             echo "                            <li class=\"ec-productRole__tag tag_";
  4202.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Tag"], "id", [], "any"falsefalsefalse3548), "html"nulltrue);
  4203.             echo "\">";
  4204.             echo twig_escape_filter($this->env$context["Tag"], "html"nulltrue);
  4205.             echo "</li>
  4206.                         ";
  4207.         }
  4208.         $_parent $context['_parent'];
  4209.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Tag'], $context['_parent'], $context['loop']);
  4210.         $context array_intersect_key($context$_parent) + $_parent;
  4211.         // line 3550
  4212.         echo "                    </ul>
  4213.                     ";
  4214.         // line 3552
  4215.         echo "                    ";
  4216.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3552$this->source); })()), "code_min", [], "any"falsefalsefalse3552))) {
  4217.             // line 3553
  4218.             echo "                        <div class=\"ec-productRole__code\">
  4219.                             ";
  4220.             // line 3554
  4221.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("商品コード"), "html"nulltrue);
  4222.             echo ": <span class=\"product-code-default\">";
  4223.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3554$this->source); })()), "code_min", [], "any"falsefalsefalse3554), "html"nulltrue);
  4224.             if ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3554$this->source); })()), "code_min", [], "any"falsefalsefalse3554) != twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3554$this->source); })()), "code_max", [], "any"falsefalsefalse3554))) {
  4225.                 echo " ~ ";
  4226.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3554$this->source); })()), "code_max", [], "any"falsefalsefalse3554), "html"nulltrue);
  4227.             }
  4228.             echo "</span>
  4229.                         </div>
  4230.                     ";
  4231.         }
  4232.         // line 3557
  4233.         echo "
  4234.                     <div class=\"ec-productRole__description\">
  4235. \t\t\t\t        <div class=\"ec-rectHeading\">
  4236. \t\t\t\t            <h4>製品情報</h4>
  4237. \t\t\t\t        </div>
  4238. \t\t\t\t\t\t";
  4239.         // line 3562
  4240.         echo twig_nl2br(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3562$this->source); })()), "sales_infomation", [], "any"falsefalsefalse3562));
  4241.         echo "
  4242.                     </div>
  4243.                     ";
  4244.         // line 3568
  4245.         echo "                    ";
  4246.         $context["SetItems"] = $this->extensions['Customize\Util\JsonExtension']->jsonDecode(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3568$this->source); })()), "list_spec", [], "any"falsefalsefalse3568));
  4247.         // line 3569
  4248.         echo "                    ";
  4249.         if ((((isset($context["SetItems"]) || array_key_exists("SetItems"$context) ? $context["SetItems"] : (function () { throw new RuntimeError('Variable "SetItems" does not exist.'3569$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["SetItems"] ?? null), "items", [], "any"truetruefalse3569)) &&  !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["SetItems"]) || array_key_exists("SetItems"$context) ? $context["SetItems"] : (function () { throw new RuntimeError('Variable "SetItems" does not exist.'3569$this->source); })()), "items", [], "any"falsefalsefalse3569)))) {
  4250.             // line 3570
  4251.             echo "                        <div class=\"ec-productRole__setItems\">
  4252.                             <div class=\"ec-rectHeading\">
  4253.                                 <h4>";
  4254.             // line 3572
  4255.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["SetItems"] ?? null), "title", [], "any"truetruefalse3572)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["SetItems"] ?? null), "title", [], "any"falsefalsefalse3572), "この商品の構成セット内容(メーカーカタログ価格)")) : ("この商品の構成セット内容(メーカーカタログ価格)")), "html"nulltrue);
  4256.             echo "</h4>
  4257.                             </div>
  4258.                             <table class=\"set-items-table\">
  4259.                                 <tbody>
  4260.                                 ";
  4261.             // line 3576
  4262.             $context['_parent'] = $context;
  4263.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["SetItems"]) || array_key_exists("SetItems"$context) ? $context["SetItems"] : (function () { throw new RuntimeError('Variable "SetItems" does not exist.'3576$this->source); })()), "items", [], "any"falsefalsefalse3576));
  4264.             foreach ($context['_seq'] as $context["_key"] => $context["SetItem"]) {
  4265.                 // line 3577
  4266.                 echo "                                    <tr>
  4267.                                         <th>";
  4268.                 // line 3578
  4269.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["SetItem"], "name", [], "any"falsefalsefalse3578), "html"nulltrue);
  4270.                 echo "</th>
  4271.                                         <td>";
  4272.                 // line 3579
  4273.                 if ( !twig_test_empty(twig_get_attribute($this->env$this->source$context["SetItem"], "price", [], "any"falsefalsefalse3579))) {
  4274.                     echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source$context["SetItem"], "price", [], "any"falsefalsefalse3579)), "html"nulltrue);
  4275.                 }
  4276.                 echo "</td>
  4277.                                     </tr>
  4278.                                 ";
  4279.             }
  4280.             $_parent $context['_parent'];
  4281.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['SetItem'], $context['_parent'], $context['loop']);
  4282.             $context array_intersect_key($context$_parent) + $_parent;
  4283.             // line 3582
  4284.             echo "                                </tbody>
  4285.                                 ";
  4286.             // line 3583
  4287.             if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["SetItems"]) || array_key_exists("SetItems"$context) ? $context["SetItems"] : (function () { throw new RuntimeError('Variable "SetItems" does not exist.'3583$this->source); })()), "total", [], "any"falsefalsefalse3583))) {
  4288.                 // line 3584
  4289.                 echo "                                <tfoot>
  4290.                                     <tr>
  4291.                                         <th>構成セット価格(メーカーカタログ価格)</th>
  4292.                                         <td>";
  4293.                 // line 3587
  4294.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["SetItems"]) || array_key_exists("SetItems"$context) ? $context["SetItems"] : (function () { throw new RuntimeError('Variable "SetItems" does not exist.'3587$this->source); })()), "total", [], "any"falsefalsefalse3587)), "html"nulltrue);
  4295.                 echo "</td>
  4296.                                     </tr>
  4297.                                 </tfoot>
  4298.                                 ";
  4299.             }
  4300.             // line 3591
  4301.             echo "                            </table>
  4302.                         </div>
  4303.                     ";
  4304.         }
  4305.         // line 3594
  4306.         echo "
  4307.                     ";
  4308.         // line 3596
  4309.         echo "                    ";
  4310.         if (( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3596$this->source); })()), "maker_url", [], "any"falsefalsefalse3596)) && !twig_in_filter("ex-shop.net"twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3596$this->source); })()), "maker_url", [], "any"falsefalsefalse3596)))) {
  4311.             // line 3597
  4312.             echo "                        <div class=\"ec-productRole__catalog\" style=\"margin:8px 0;\">
  4313.                             <a href=\"";
  4314.             // line 3598
  4315.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3598$this->source); })()), "maker_url", [], "any"falsefalsefalse3598), "html"nulltrue);
  4316.             echo "\" target=\"_blank\" rel=\"noopener noreferrer\">
  4317.                                 <i class=\"far fa-file-alt\"></i> この商品のメーカーカタログを見る
  4318.                             </a>
  4319.                         </div>
  4320.                     ";
  4321.         }
  4322.         // line 3603
  4323.         echo "
  4324. \t\t\t\t\t<div class=\"card card-danger\" style=\"clear:both;margin:1px;\">
  4325. \t\t\t\t\t  <div class=\"card-header\">
  4326. \t\t\t\t\t    <h3 class=\"card-title\">見積シミュレーション</h3>
  4327. \t\t\t\t\t  </div>
  4328. \t\t\t\t\t  <div class=\"card-body p-2\">
  4329.                         ";
  4330.         // line 3610
  4331.         $context["related_image"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3610$this->source); })()), "id", [], "any"falsefalsefalse3610), "related_image");
  4332.         // line 3611
  4333.         echo "                        ";
  4334.         // line 3612
  4335.         echo "                        ";
  4336.         $context["img1"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3612$this->source); })()) && twig_in_filter("1段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3612$this->source); })())));
  4337.         // line 3613
  4338.         echo "                        ";
  4339.         $context["img2"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3613$this->source); })()) && twig_in_filter("2段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3613$this->source); })())));
  4340.         // line 3614
  4341.         echo "                        ";
  4342.         $context["img3"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3614$this->source); })()) && twig_in_filter("3段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3614$this->source); })())));
  4343.         // line 3615
  4344.         echo "                        ";
  4345.         $context["img4"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3615$this->source); })()) && twig_in_filter("4段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3615$this->source); })())));
  4346.         // line 3616
  4347.         echo "\t\t\t\t\t    ";
  4348.         $context["type1"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3616$this->source); })()), "id", [], "any"falsefalsefalse3616), "related_name1");
  4349.         // line 3617
  4350.         echo "\t\t\t\t\t\t";
  4351.         $context["type2"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3617$this->source); })()), "id", [], "any"falsefalsefalse3617), "related_name2");
  4352.         // line 3618
  4353.         echo "\t\t\t\t\t\t";
  4354.         $context["type3"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3618$this->source); })()), "id", [], "any"falsefalsefalse3618), "related_name3");
  4355.         // line 3619
  4356.         echo "\t\t\t\t\t\t";
  4357.         $context["type4"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3619$this->source); })()), "id", [], "any"falsefalsefalse3619), "related_name4");
  4358.         // line 3620
  4359.         echo "\t\t\t\t\t\t";
  4360.         $context["hasRelated"] = ((((((isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3620$this->source); })()) && (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3620$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3620$this->source); })()))) || ((        // line 3621
  4361. (isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3621$this->source); })()) && (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3621$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3621$this->source); })())))) || ((        // line 3622
  4362. (isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3622$this->source); })()) && (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3622$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3622$this->source); })())))) || ((        // line 3623
  4363. (isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3623$this->source); })()) && (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3623$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3623$this->source); })()))));
  4364.         // line 3624
  4365.         echo "\t\t\t\t\t\t";
  4366.         if ((isset($context["hasRelated"]) || array_key_exists("hasRelated"$context) ? $context["hasRelated"] : (function () { throw new RuntimeError('Variable "hasRelated" does not exist.'3624$this->source); })())) {
  4367.             // line 3625
  4368.             echo "\t\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のタイプを選択してください。</label></div>
  4369. \t\t\t\t\t\t";
  4370.         }
  4371.         // line 3627
  4372.         echo "
  4373. \t\t\t\t\t\t";
  4374.         // line 3629
  4375.         echo "\t\t\t\t\t\t";
  4376.         if ((((isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3629$this->source); })()) && (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3629$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3629$this->source); })())))) {
  4377.             // line 3630
  4378.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4379. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4380.             // line 3631
  4381.             echo twig_escape_filter($this->env, (isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3631$this->source); })()), "html"nulltrue);
  4382.             if (((isset($context["img1"]) || array_key_exists("img1"$context) ? $context["img1"] : (function () { throw new RuntimeError('Variable "img1" does not exist.'3631$this->source); })()) && (isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3631$this->source); })()))) {
  4383.                 echo ": <span>";
  4384.                 echo twig_escape_filter($this->env, (isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3631$this->source); })()), "html"nulltrue);
  4385.                 echo "</span>";
  4386.             }
  4387.             echo "</div>
  4388. \t\t\t\t\t\t  ";
  4389.             // line 3632
  4390.             if ((isset($context["img1"]) || array_key_exists("img1"$context) ? $context["img1"] : (function () { throw new RuntimeError('Variable "img1" does not exist.'3632$this->source); })())) {
  4391.                 // line 3633
  4392.                 echo "\t\t\t\t\t\t    ";
  4393.                 // line 3634
  4394.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4395. \t\t\t\t\t\t      ";
  4396.                 // line 3635
  4397.                 $context['_parent'] = $context;
  4398.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3635$this->source); })()));
  4399.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4400.                     // line 3636
  4401.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4402.                     if (((isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3636$this->source); })()) == $context["rp_name"])) {
  4403.                         echo " is-selected";
  4404.                     }
  4405.                     echo "\" href=\"/products/detail/";
  4406.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4407.                     echo "\">
  4408. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4409. \t\t\t\t\t\t               src=\"";
  4410.                     // line 3638
  4411.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3638) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3638$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3638))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3638$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3638), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4412.                     echo "\"
  4413. \t\t\t\t\t\t               alt=\"";
  4414.                     // line 3639
  4415.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4416.                     echo "\"
  4417. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4418. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4419. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4420. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4421.                     // line 3643
  4422.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4423.                     echo "</span>
  4424. \t\t\t\t\t\t        </a>
  4425. \t\t\t\t\t\t      ";
  4426.                 }
  4427.                 $_parent $context['_parent'];
  4428.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4429.                 $context array_intersect_key($context$_parent) + $_parent;
  4430.                 // line 3646
  4431.                 echo "\t\t\t\t\t\t    </div>
  4432. \t\t\t\t\t\t  ";
  4433.             } else {
  4434.                 // line 3648
  4435.                 echo "\t\t\t\t\t\t    ";
  4436.                 // line 3649
  4437.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4438. \t\t\t\t\t\t      ";
  4439.                 // line 3650
  4440.                 $context['_parent'] = $context;
  4441.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3650$this->source); })()));
  4442.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4443.                     // line 3651
  4444.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4445.                     if (((isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3651$this->source); })()) == $context["rp_name"])) {
  4446.                         echo " is-selected";
  4447.                     }
  4448.                     echo "\" href=\"/products/detail/";
  4449.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4450.                     echo "\">
  4451. \t\t\t\t\t\t          ";
  4452.                     // line 3652
  4453.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4454.                     echo "
  4455. \t\t\t\t\t\t        </a>
  4456. \t\t\t\t\t\t      ";
  4457.                 }
  4458.                 $_parent $context['_parent'];
  4459.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4460.                 $context array_intersect_key($context$_parent) + $_parent;
  4461.                 // line 3655
  4462.                 echo "\t\t\t\t\t\t    </div>
  4463. \t\t\t\t\t\t  ";
  4464.             }
  4465.             // line 3657
  4466.             echo "\t\t\t\t\t\t</div>
  4467. \t\t\t\t\t\t";
  4468.         }
  4469.         // line 3659
  4470.         echo "
  4471. \t\t\t\t\t\t";
  4472.         // line 3661
  4473.         echo "\t\t\t\t\t\t";
  4474.         if ((((isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3661$this->source); })()) && (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3661$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3661$this->source); })())))) {
  4475.             // line 3662
  4476.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4477. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4478.             // line 3663
  4479.             echo twig_escape_filter($this->env, (isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3663$this->source); })()), "html"nulltrue);
  4480.             if (((isset($context["img2"]) || array_key_exists("img2"$context) ? $context["img2"] : (function () { throw new RuntimeError('Variable "img2" does not exist.'3663$this->source); })()) && (isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3663$this->source); })()))) {
  4481.                 echo ": <span>";
  4482.                 echo twig_escape_filter($this->env, (isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3663$this->source); })()), "html"nulltrue);
  4483.                 echo "</span>";
  4484.             }
  4485.             echo "</div>
  4486. \t\t\t\t\t\t  ";
  4487.             // line 3664
  4488.             if ((isset($context["img2"]) || array_key_exists("img2"$context) ? $context["img2"] : (function () { throw new RuntimeError('Variable "img2" does not exist.'3664$this->source); })())) {
  4489.                 // line 3665
  4490.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4491. \t\t\t\t\t\t      ";
  4492.                 // line 3666
  4493.                 $context['_parent'] = $context;
  4494.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3666$this->source); })()));
  4495.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4496.                     // line 3667
  4497.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4498.                     if (((isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3667$this->source); })()) == $context["rp_name"])) {
  4499.                         echo " is-selected";
  4500.                     }
  4501.                     echo "\" href=\"/products/detail/";
  4502.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4503.                     echo "\">
  4504. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4505. \t\t\t\t\t\t               src=\"";
  4506.                     // line 3669
  4507.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3669) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3669$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3669))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3669$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3669), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4508.                     echo "\"
  4509. \t\t\t\t\t\t               alt=\"";
  4510.                     // line 3670
  4511.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4512.                     echo "\"
  4513. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4514. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4515. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4516. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4517.                     // line 3674
  4518.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4519.                     echo "</span>
  4520. \t\t\t\t\t\t        </a>
  4521. \t\t\t\t\t\t      ";
  4522.                 }
  4523.                 $_parent $context['_parent'];
  4524.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4525.                 $context array_intersect_key($context$_parent) + $_parent;
  4526.                 // line 3677
  4527.                 echo "\t\t\t\t\t\t    </div>
  4528. \t\t\t\t\t\t  ";
  4529.             } else {
  4530.                 // line 3679
  4531.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4532. \t\t\t\t\t\t      ";
  4533.                 // line 3680
  4534.                 $context['_parent'] = $context;
  4535.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3680$this->source); })()));
  4536.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4537.                     // line 3681
  4538.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4539.                     if (((isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3681$this->source); })()) == $context["rp_name"])) {
  4540.                         echo " is-selected";
  4541.                     }
  4542.                     echo "\" href=\"/products/detail/";
  4543.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4544.                     echo "\">
  4545. \t\t\t\t\t\t          ";
  4546.                     // line 3682
  4547.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4548.                     echo "
  4549. \t\t\t\t\t\t        </a>
  4550. \t\t\t\t\t\t      ";
  4551.                 }
  4552.                 $_parent $context['_parent'];
  4553.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4554.                 $context array_intersect_key($context$_parent) + $_parent;
  4555.                 // line 3685
  4556.                 echo "\t\t\t\t\t\t    </div>
  4557. \t\t\t\t\t\t  ";
  4558.             }
  4559.             // line 3687
  4560.             echo "\t\t\t\t\t\t</div>
  4561. \t\t\t\t\t\t";
  4562.         }
  4563.         // line 3689
  4564.         echo "
  4565. \t\t\t\t\t\t";
  4566.         // line 3691
  4567.         echo "\t\t\t\t\t\t";
  4568.         if ((((isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3691$this->source); })()) && (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3691$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3691$this->source); })())))) {
  4569.             // line 3692
  4570.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4571. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4572.             // line 3693
  4573.             echo twig_escape_filter($this->env, (isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3693$this->source); })()), "html"nulltrue);
  4574.             if (((isset($context["img3"]) || array_key_exists("img3"$context) ? $context["img3"] : (function () { throw new RuntimeError('Variable "img3" does not exist.'3693$this->source); })()) && (isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3693$this->source); })()))) {
  4575.                 echo ": <span>";
  4576.                 echo twig_escape_filter($this->env, (isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3693$this->source); })()), "html"nulltrue);
  4577.                 echo "</span>";
  4578.             }
  4579.             echo "</div>
  4580. \t\t\t\t\t\t  ";
  4581.             // line 3694
  4582.             if ((isset($context["img3"]) || array_key_exists("img3"$context) ? $context["img3"] : (function () { throw new RuntimeError('Variable "img3" does not exist.'3694$this->source); })())) {
  4583.                 // line 3695
  4584.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4585. \t\t\t\t\t\t      ";
  4586.                 // line 3696
  4587.                 $context['_parent'] = $context;
  4588.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3696$this->source); })()));
  4589.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4590.                     // line 3697
  4591.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4592.                     if (((isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3697$this->source); })()) == $context["rp_name"])) {
  4593.                         echo " is-selected";
  4594.                     }
  4595.                     echo "\" href=\"/products/detail/";
  4596.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4597.                     echo "\">
  4598. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4599. \t\t\t\t\t\t               src=\"";
  4600.                     // line 3699
  4601.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3699) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3699$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3699))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3699$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3699), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4602.                     echo "\"
  4603. \t\t\t\t\t\t               alt=\"";
  4604.                     // line 3700
  4605.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4606.                     echo "\"
  4607. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4608. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4609. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4610. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4611.                     // line 3704
  4612.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4613.                     echo "</span>
  4614. \t\t\t\t\t\t        </a>
  4615. \t\t\t\t\t\t      ";
  4616.                 }
  4617.                 $_parent $context['_parent'];
  4618.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4619.                 $context array_intersect_key($context$_parent) + $_parent;
  4620.                 // line 3707
  4621.                 echo "\t\t\t\t\t\t    </div>
  4622. \t\t\t\t\t\t  ";
  4623.             } else {
  4624.                 // line 3709
  4625.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4626. \t\t\t\t\t\t      ";
  4627.                 // line 3710
  4628.                 $context['_parent'] = $context;
  4629.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3710$this->source); })()));
  4630.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4631.                     // line 3711
  4632.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4633.                     if (((isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3711$this->source); })()) == $context["rp_name"])) {
  4634.                         echo " is-selected";
  4635.                     }
  4636.                     echo "\" href=\"/products/detail/";
  4637.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4638.                     echo "\">
  4639. \t\t\t\t\t\t          ";
  4640.                     // line 3712
  4641.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4642.                     echo "
  4643. \t\t\t\t\t\t        </a>
  4644. \t\t\t\t\t\t      ";
  4645.                 }
  4646.                 $_parent $context['_parent'];
  4647.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4648.                 $context array_intersect_key($context$_parent) + $_parent;
  4649.                 // line 3715
  4650.                 echo "\t\t\t\t\t\t    </div>
  4651. \t\t\t\t\t\t  ";
  4652.             }
  4653.             // line 3717
  4654.             echo "\t\t\t\t\t\t</div>
  4655. \t\t\t\t\t\t";
  4656.         }
  4657.         // line 3719
  4658.         echo "
  4659. \t\t\t\t\t\t";
  4660.         // line 3721
  4661.         echo "\t\t\t\t\t\t";
  4662.         if ((((isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3721$this->source); })()) && (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3721$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3721$this->source); })())))) {
  4663.             // line 3722
  4664.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4665. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4666.             // line 3723
  4667.             echo twig_escape_filter($this->env, (isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3723$this->source); })()), "html"nulltrue);
  4668.             if (((isset($context["img4"]) || array_key_exists("img4"$context) ? $context["img4"] : (function () { throw new RuntimeError('Variable "img4" does not exist.'3723$this->source); })()) && (isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3723$this->source); })()))) {
  4669.                 echo ": <span>";
  4670.                 echo twig_escape_filter($this->env, (isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3723$this->source); })()), "html"nulltrue);
  4671.                 echo "</span>";
  4672.             }
  4673.             echo "</div>
  4674. \t\t\t\t\t\t  ";
  4675.             // line 3724
  4676.             if ((isset($context["img4"]) || array_key_exists("img4"$context) ? $context["img4"] : (function () { throw new RuntimeError('Variable "img4" does not exist.'3724$this->source); })())) {
  4677.                 // line 3725
  4678.                 echo "\t\t\t\t\t\t    ";
  4679.                 // line 3726
  4680.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4681. \t\t\t\t\t\t      ";
  4682.                 // line 3727
  4683.                 $context['_parent'] = $context;
  4684.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3727$this->source); })()));
  4685.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4686.                     // line 3728
  4687.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4688.                     if (((isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3728$this->source); })()) == $context["rp_name"])) {
  4689.                         echo " is-selected";
  4690.                     }
  4691.                     echo "\" href=\"/products/detail/";
  4692.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4693.                     echo "\">
  4694. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4695. \t\t\t\t\t\t               src=\"";
  4696.                     // line 3730
  4697.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3730) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3730$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3730))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3730$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3730), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4698.                     echo "\"
  4699. \t\t\t\t\t\t               alt=\"";
  4700.                     // line 3731
  4701.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4702.                     echo "\" width=\"120\" height=\"120\" loading=\"lazy\">
  4703. \t\t\t\t\t\t          <span class=\"rp-card__label\">";
  4704.                     // line 3732
  4705.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4706.                     echo "</span>
  4707. \t\t\t\t\t\t        </a>
  4708. \t\t\t\t\t\t      ";
  4709.                 }
  4710.                 $_parent $context['_parent'];
  4711.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4712.                 $context array_intersect_key($context$_parent) + $_parent;
  4713.                 // line 3735
  4714.                 echo "\t\t\t\t\t\t    </div>
  4715. \t\t\t\t\t\t  ";
  4716.             } else {
  4717.                 // line 3737
  4718.                 echo "\t\t\t\t\t\t    ";
  4719.                 // line 3738
  4720.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4721. \t\t\t\t\t\t      ";
  4722.                 // line 3739
  4723.                 $context['_parent'] = $context;
  4724.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3739$this->source); })()));
  4725.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4726.                     // line 3740
  4727.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4728.                     if (((isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3740$this->source); })()) == $context["rp_name"])) {
  4729.                         echo " is-selected";
  4730.                     }
  4731.                     echo "\" href=\"/products/detail/";
  4732.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4733.                     echo "\">
  4734. \t\t\t\t\t\t          ";
  4735.                     // line 3741
  4736.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4737.                     echo "
  4738. \t\t\t\t\t\t        </a>
  4739. \t\t\t\t\t\t      ";
  4740.                 }
  4741.                 $_parent $context['_parent'];
  4742.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4743.                 $context array_intersect_key($context$_parent) + $_parent;
  4744.                 // line 3744
  4745.                 echo "\t\t\t\t\t\t    </div>
  4746. \t\t\t\t\t\t  ";
  4747.             }
  4748.             // line 3746
  4749.             echo "\t\t\t\t\t\t</div>
  4750. \t\t\t\t\t\t";
  4751.         }
  4752.         // line 3748
  4753.         echo "
  4754. \t\t\t\t\t    ";
  4755.         // line 3757
  4756.         echo "\t\t\t\t\t    ";
  4757.         $context["is_gs_h"] = false;
  4758.         // line 3758
  4759.         echo "\t\t\t\t\t    ";
  4760.         $context["is_cg_h"] = false;
  4761.         // line 3759
  4762.         echo "\t\t\t\t\t    ";
  4763.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3759$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3759))) {
  4764.             // line 3760
  4765.             echo "\t\t\t\t\t        ";
  4766.             $context['_parent'] = $context;
  4767.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3760$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3760));
  4768.             foreach ($context['_seq'] as $context["_key"] => $context["pc_h"]) {
  4769.                 // line 3761
  4770.                 echo "\t\t\t\t\t            ";
  4771.                 if ((twig_get_attribute($this->env$this->source$context["pc_h"], "category_id", [], "any"falsefalsefalse3761) == 27)) {
  4772.                     $context["is_gs_h"] = true;
  4773.                 }
  4774.                 // line 3762
  4775.                 echo "\t\t\t\t\t            ";
  4776.                 if ((twig_get_attribute($this->env$this->source$context["pc_h"], "category_id", [], "any"falsefalsefalse3762) == 9)) {
  4777.                     $context["is_cg_h"] = true;
  4778.                 }
  4779.                 // line 3763
  4780.                 echo "\t\t\t\t\t        ";
  4781.             }
  4782.             $_parent $context['_parent'];
  4783.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pc_h'], $context['_parent'], $context['loop']);
  4784.             $context array_intersect_key($context$_parent) + $_parent;
  4785.             // line 3764
  4786.             echo "\t\t\t\t\t    ";
  4787.         }
  4788.         // line 3765
  4789.         echo "\t\t\t\t\t    ";
  4790.         $context["visible_op_count"] = 0;
  4791.         // line 3766
  4792.         echo "\t\t\t\t\t    ";
  4793.         if (((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3766$this->source); })()) && twig_length_filter($this->env, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3766$this->source); })())))) {
  4794.             // line 3767
  4795.             echo "\t\t\t\t\t        ";
  4796.             $context['_parent'] = $context;
  4797.             $context['_seq'] = twig_ensure_traversable((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3767$this->source); })()));
  4798.             foreach ($context['_seq'] as $context["_key"] => $context["opi"]) {
  4799.                 // line 3768
  4800.                 echo "\t\t\t\t\t            ";
  4801.                 if (twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3768)) {
  4802.                     // line 3769
  4803.                     echo "\t\t\t\t\t                ";
  4804.                     $context["_hide_h"] = false;
  4805.                     // line 3770
  4806.                     echo "\t\t\t\t\t                ";
  4807.                     if (((isset($context["is_gs_h"]) || array_key_exists("is_gs_h"$context) ? $context["is_gs_h"] : (function () { throw new RuntimeError('Variable "is_gs_h" does not exist.'3770$this->source); })()) && (preg_match("/撤去/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3770)) || preg_match("/残土/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3770))))) {
  4808.                         $context["_hide_h"] = true;
  4809.                     }
  4810.                     // line 3771
  4811.                     echo "\t\t\t\t\t                ";
  4812.                     if (((isset($context["is_cg_h"]) || array_key_exists("is_cg_h"$context) ? $context["is_cg_h"] : (function () { throw new RuntimeError('Variable "is_cg_h" does not exist.'3771$this->source); })()) && preg_match("/残土/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3771)))) {
  4813.                         $context["_hide_h"] = true;
  4814.                     }
  4815.                     // line 3772
  4816.                     echo "\t\t\t\t\t                ";
  4817.                     if ( !(isset($context["_hide_h"]) || array_key_exists("_hide_h"$context) ? $context["_hide_h"] : (function () { throw new RuntimeError('Variable "_hide_h" does not exist.'3772$this->source); })())) {
  4818.                         $context["visible_op_count"] = ((isset($context["visible_op_count"]) || array_key_exists("visible_op_count"$context) ? $context["visible_op_count"] : (function () { throw new RuntimeError('Variable "visible_op_count" does not exist.'3772$this->source); })()) + 1);
  4819.                     }
  4820.                     // line 3773
  4821.                     echo "\t\t\t\t\t            ";
  4822.                 }
  4823.                 // line 3774
  4824.                 echo "\t\t\t\t\t        ";
  4825.             }
  4826.             $_parent $context['_parent'];
  4827.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opi'], $context['_parent'], $context['loop']);
  4828.             $context array_intersect_key($context$_parent) + $_parent;
  4829.             // line 3775
  4830.             echo "\t\t\t\t\t    ";
  4831.         }
  4832.         // line 3776
  4833.         echo "\t\t\t\t\t    ";
  4834.         $context["has_any_option"] = (((((((((        // line 3777
  4835. (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3777$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3777$this->source); })()))) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3777$this->source); })()), "SaleType", [], "any"falsefalsefalse3777), "id", [], "any"falsefalsefalse3777) != 3)) || ((        // line 3778
  4836. (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3778$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3778$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3778$this->source); })())) != ""))) || ((        // line 3779
  4837. (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3779$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3779$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3779$this->source); })())) != ""))) || ((        // line 3780
  4838. (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3780$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3780$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3780$this->source); })())) != ""))) || ((        // line 3781
  4839. (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3781$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3781$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3781$this->source); })())) != ""))) || ((        // line 3782
  4840. (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3782$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3782$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3782$this->source); })())) != ""))) || ((        // line 3783
  4841. (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3783$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3783$this->source); })()))) && (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3783$this->source); })())) != ""))) || twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source,         // line 3784
  4842. (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3784$this->source); })()), "SaleType", [], "any"falsefalsefalse3784), "id", [], "any"falsefalsefalse3784), [=> 2=> 5=> 6=> 7=> 9]));
  4843.         // line 3786
  4844.         echo "\t\t\t\t\t    ";
  4845.         if ((isset($context["has_any_option"]) || array_key_exists("has_any_option"$context) ? $context["has_any_option"] : (function () { throw new RuntimeError('Variable "has_any_option" does not exist.'3786$this->source); })())) {
  4846.             // line 3787
  4847.             echo "\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のオプションを選択してください。</label></div>
  4848. \t\t\t\t\t    ";
  4849.         }
  4850.         // line 3789
  4851.         echo "
  4852.                         ";
  4853.         // line 3791
  4854.         echo "                        ";
  4855.         if (((((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3791$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3791$this->source); })()))) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3791$this->source); })()), "SaleType", [], "any"falsefalsefalse3791), "id", [], "any"falsefalsefalse3791) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3791$this->source); })()), "SaleType", [], "any"falsefalsefalse3791), "id", [], "any"falsefalsefalse3791) != 2))) {
  4856.             // line 3792
  4857.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4858.                           <div class=\"rp-section-label\">カラー";
  4859.             // line 3793
  4860.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3793$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3793$this->source); })()), "pc", [], "any"falsefalsefalse3793))) {
  4861.                 echo ": <span>";
  4862.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3793$this->source); })()), "pc", [], "any"falsefalsefalse3793), "html"nulltrue);
  4863.                 echo "</span>";
  4864.             }
  4865.             echo "</div>
  4866.                           <div class=\"opt-btn-group\">
  4867.                             ";
  4868.             // line 3795
  4869.             $context["idx"] = 0;
  4870.             // line 3796
  4871.             echo "                            ";
  4872.             $context['_parent'] = $context;
  4873.             $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3796$this->source); })()));
  4874.             foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  4875.                 if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3796))) {
  4876.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3796$this->source); })()) + 1);
  4877.                     // line 3797
  4878.                     echo "                              ";
  4879.                     $context["has_img"] = (twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"truetruefalse3797) &&  !twig_test_empty(twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3797)));
  4880.                     // line 3798
  4881.                     echo "                              <label class=\"opt-btn";
  4882.                     if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3798$this->source); })())) {
  4883.                         echo " opt-btn--with-image";
  4884.                     }
  4885.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3798$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3798$this->source); })()), "pc", [], "any"falsefalsefalse3798) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3798))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3798$this->source); })())) == 1))) {
  4886.                         echo " is-selected";
  4887.                     }
  4888.                     echo "\"
  4889.                                      onclick=\"mitsumori_simulation_val('pc', '";
  4890.                     // line 3799
  4891.                     echo twig_escape_filter($this->envtwig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3799), "js"), "html"nulltrue);
  4892.                     echo "');\">
  4893.                                 <input type=\"radio\" name=\"color\" id=\"cc_";
  4894.                     // line 3800
  4895.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3800$this->source); })()), "html"nulltrue);
  4896.                     echo "\" value=\"";
  4897.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3800), "html"nulltrue);
  4898.                     echo "\"
  4899.                                        ";
  4900.                     // line 3801
  4901.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3801$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3801$this->source); })()), "pc", [], "any"falsefalsefalse3801) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3801))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3801$this->source); })())) == 1))) {
  4902.                         echo "checked";
  4903.                     }
  4904.                     echo ">
  4905.                                 ";
  4906.                     // line 3802
  4907.                     if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3802$this->source); })())) {
  4908.                         // line 3803
  4909.                         echo "                                  <img src=\"";
  4910.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3803), "html"nulltrue);
  4911.                         echo "\" alt=\"";
  4912.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3803), "html"nulltrue);
  4913.                         echo "\" class=\"opt-btn__img\"
  4914.                                        onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  4915.                                   <span class=\"opt-btn__name\">";
  4916.                         // line 3805
  4917.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3805), "html"nulltrue);
  4918.                         echo "</span>
  4919.                                 ";
  4920.                     } else {
  4921.                         // line 3807
  4922.                         echo "                                  ";
  4923.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3807), "html"nulltrue);
  4924.                         echo "
  4925.                                 ";
  4926.                     }
  4927.                     // line 3809
  4928.                     echo "                              </label>
  4929.                             ";
  4930.                 }
  4931.             }
  4932.             $_parent $context['_parent'];
  4933.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  4934.             $context array_intersect_key($context$_parent) + $_parent;
  4935.             // line 3811
  4936.             echo "                          </div>
  4937.                         </div>
  4938.                         ";
  4939.         }
  4940.         // line 3814
  4941.         echo "
  4942.                         ";
  4943.         // line 3819
  4944.         echo "                        ";
  4945.         if (((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3819$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3819$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3819$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3819$this->source); })()), "SaleType", [], "any"falsefalsefalse3819), "id", [], "any"falsefalsefalse3819), [=> 2=> 3=> 6]))) {
  4946.             // line 3820
  4947.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4948.                           <div class=\"rp-section-label\">幅";
  4949.             // line 3821
  4950.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3821$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3821$this->source); })()), "pw", [], "any"falsefalsefalse3821))) {
  4951.                 echo ": <span>";
  4952.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3821$this->source); })()), "pw", [], "any"falsefalsefalse3821), "html"nulltrue);
  4953.                 echo "</span>";
  4954.             }
  4955.             echo "</div>
  4956.                           <div class=\"opt-btn-group\">
  4957.                             ";
  4958.             // line 3823
  4959.             $context["idx"] = 0;
  4960.             // line 3824
  4961.             echo "                            ";
  4962.             $context['_parent'] = $context;
  4963.             $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3824$this->source); })()));
  4964.             foreach ($context['_seq'] as $context["_key"] => $context["pw"]) {
  4965.                 if ($context["pw"]) {
  4966.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3824$this->source); })()) + 1);
  4967.                     // line 3825
  4968.                     echo "                              <label class=\"opt-btn";
  4969.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3825$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3825$this->source); })()), "pw", [], "any"falsefalsefalse3825) == $context["pw"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3825$this->source); })())) == 1))) {
  4970.                         echo " is-selected";
  4971.                     }
  4972.                     echo "\"
  4973.                                      onclick=\"mitsumori_simulation_val('pw', '";
  4974.                     // line 3826
  4975.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pw"], "js"), "html"nulltrue);
  4976.                     echo "');\">
  4977.                                 <input type=\"radio\" name=\"pw\" id=\"pw_";
  4978.                     // line 3827
  4979.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3827$this->source); })()), "html"nulltrue);
  4980.                     echo "\" value=\"";
  4981.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  4982.                     echo "\"
  4983.                                        ";
  4984.                     // line 3828
  4985.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3828$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3828$this->source); })()), "pw", [], "any"falsefalsefalse3828) == $context["pw"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3828$this->source); })())) == 1))) {
  4986.                         echo "checked";
  4987.                     }
  4988.                     echo ">
  4989.                                 ";
  4990.                     // line 3829
  4991.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  4992.                     echo "
  4993.                               </label>
  4994.                             ";
  4995.                 }
  4996.             }
  4997.             $_parent $context['_parent'];
  4998.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw'], $context['_parent'], $context['loop']);
  4999.             $context array_intersect_key($context$_parent) + $_parent;
  5000.             // line 3832
  5001.             echo "                          </div>
  5002.                         </div>
  5003.                         ";
  5004.         }
  5005.         // line 3835
  5006.         echo "
  5007.                         ";
  5008.         // line 3836
  5009.         if (((((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3836$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3836$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3836$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3836$this->source); })()), "SaleType", [], "any"falsefalsefalse3836), "id", [], "any"falsefalsefalse3836), [=> 3=> 6]))) {
  5010.             // line 3837
  5011.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5012.                           <div class=\"rp-section-label\">奥行き";
  5013.             // line 3838
  5014.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3838$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3838$this->source); })()), "pd", [], "any"falsefalsefalse3838))) {
  5015.                 echo ": <span>";
  5016.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3838$this->source); })()), "pd", [], "any"falsefalsefalse3838), "html"nulltrue);
  5017.                 echo "</span>";
  5018.             }
  5019.             echo "</div>
  5020.                           <div class=\"opt-btn-group\">
  5021.                             ";
  5022.             // line 3840
  5023.             $context["idx"] = 0;
  5024.             // line 3841
  5025.             echo "                            ";
  5026.             $context['_parent'] = $context;
  5027.             $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3841$this->source); })()));
  5028.             foreach ($context['_seq'] as $context["_key"] => $context["pd"]) {
  5029.                 if ($context["pd"]) {
  5030.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3841$this->source); })()) + 1);
  5031.                     // line 3842
  5032.                     echo "                              <label class=\"opt-btn";
  5033.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3842$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3842$this->source); })()), "pd", [], "any"falsefalsefalse3842) == $context["pd"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3842$this->source); })())) == 1))) {
  5034.                         echo " is-selected";
  5035.                     }
  5036.                     echo "\"
  5037.                                      onclick=\"mitsumori_simulation_val('pd', '";
  5038.                     // line 3843
  5039.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pd"], "js"), "html"nulltrue);
  5040.                     echo "');\">
  5041.                                 <input type=\"radio\" name=\"pd\" id=\"pd_";
  5042.                     // line 3844
  5043.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3844$this->source); })()), "html"nulltrue);
  5044.                     echo "\" value=\"";
  5045.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  5046.                     echo "\"
  5047.                                        ";
  5048.                     // line 3845
  5049.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3845$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3845$this->source); })()), "pd", [], "any"falsefalsefalse3845) == $context["pd"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3845$this->source); })())) == 1))) {
  5050.                         echo "checked";
  5051.                     }
  5052.                     echo ">
  5053.                                 ";
  5054.                     // line 3846
  5055.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  5056.                     echo "
  5057.                               </label>
  5058.                             ";
  5059.                 }
  5060.             }
  5061.             $_parent $context['_parent'];
  5062.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd'], $context['_parent'], $context['loop']);
  5063.             $context array_intersect_key($context$_parent) + $_parent;
  5064.             // line 3849
  5065.             echo "                          </div>
  5066.                         </div>
  5067.                         ";
  5068.         }
  5069.         // line 3852
  5070.         echo "
  5071.                         ";
  5072.         // line 3855
  5073.         echo "                        ";
  5074.         if (((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3855$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3855$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3855$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3855$this->source); })()), "SaleType", [], "any"falsefalsefalse3855), "id", [], "any"falsefalsefalse3855), [=> 2=> 3=> 6]))) {
  5075.             // line 3856
  5076.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5077.                           <div class=\"rp-section-label\">高さ";
  5078.             // line 3857
  5079.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3857$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3857$this->source); })()), "ph", [], "any"falsefalsefalse3857))) {
  5080.                 echo ": <span>";
  5081.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3857$this->source); })()), "ph", [], "any"falsefalsefalse3857), "html"nulltrue);
  5082.                 echo "</span>";
  5083.             }
  5084.             echo "</div>
  5085.                           <div class=\"opt-btn-group\">
  5086.                             ";
  5087.             // line 3859
  5088.             $context["idx"] = 0;
  5089.             // line 3860
  5090.             echo "                            ";
  5091.             $context['_parent'] = $context;
  5092.             $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3860$this->source); })()));
  5093.             foreach ($context['_seq'] as $context["_key"] => $context["ph"]) {
  5094.                 if ($context["ph"]) {
  5095.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3860$this->source); })()) + 1);
  5096.                     // line 3861
  5097.                     echo "                              <label class=\"opt-btn";
  5098.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3861$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3861$this->source); })()), "ph", [], "any"falsefalsefalse3861) == $context["ph"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3861$this->source); })())) == 1))) {
  5099.                         echo " is-selected";
  5100.                     }
  5101.                     echo "\"
  5102.                                      onclick=\"mitsumori_simulation_val('ph', '";
  5103.                     // line 3862
  5104.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["ph"], "js"), "html"nulltrue);
  5105.                     echo "');\">
  5106.                                 <input type=\"radio\" name=\"ph\" id=\"ph_";
  5107.                     // line 3863
  5108.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3863$this->source); })()), "html"nulltrue);
  5109.                     echo "\" value=\"";
  5110.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  5111.                     echo "\"
  5112.                                        ";
  5113.                     // line 3864
  5114.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3864$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3864$this->source); })()), "ph", [], "any"falsefalsefalse3864) == $context["ph"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3864$this->source); })())) == 1))) {
  5115.                         echo "checked";
  5116.                     }
  5117.                     echo ">
  5118.                                 ";
  5119.                     // line 3865
  5120.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  5121.                     echo "
  5122.                               </label>
  5123.                             ";
  5124.                 }
  5125.             }
  5126.             $_parent $context['_parent'];
  5127.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph'], $context['_parent'], $context['loop']);
  5128.             $context array_intersect_key($context$_parent) + $_parent;
  5129.             // line 3868
  5130.             echo "                          </div>
  5131.                         </div>
  5132.                         ";
  5133.         }
  5134.         // line 3871
  5135.         echo "
  5136.                         ";
  5137.         // line 3873
  5138.         echo "                        ";
  5139.         if ((((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3873$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3873$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3873$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3873$this->source); })()), "SaleType", [], "any"falsefalsefalse3873), "id", [], "any"falsefalsefalse3873) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3873$this->source); })()), "SaleType", [], "any"falsefalsefalse3873), "id", [], "any"falsefalsefalse3873) != 2))) {
  5140.             // line 3874
  5141.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5142.                           <div class=\"rp-section-label\">";
  5143.             // line 3875
  5144.             if ((isset($context["is_cat43"]) || array_key_exists("is_cat43"$context) ? $context["is_cat43"] : (function () { throw new RuntimeError('Variable "is_cat43" does not exist.'3875$this->source); })())) {
  5145.                 echo "開き方";
  5146.             } else {
  5147.                 echo twig_escape_filter($this->env, (isset($context["pm_label"]) || array_key_exists("pm_label"$context) ? $context["pm_label"] : (function () { throw new RuntimeError('Variable "pm_label" does not exist.'3875$this->source); })()), "html"nulltrue);
  5148.             }
  5149.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3875$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3875$this->source); })()), "pm", [], "any"falsefalsefalse3875))) {
  5150.                 echo ": <span>";
  5151.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3875$this->source); })()), "pm", [], "any"falsefalsefalse3875), "html"nulltrue);
  5152.                 echo "</span>";
  5153.             }
  5154.             echo "</div>
  5155.                           <div class=\"opt-btn-group\">
  5156.                             ";
  5157.             // line 3877
  5158.             $context["idx"] = 0;
  5159.             // line 3878
  5160.             echo "                            ";
  5161.             $context['_parent'] = $context;
  5162.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3878$this->source); })()));
  5163.             foreach ($context['_seq'] as $context["_key"] => $context["pm"]) {
  5164.                 if ($context["pm"]) {
  5165.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3878$this->source); })()) + 1);
  5166.                     // line 3879
  5167.                     echo "                              <label class=\"opt-btn";
  5168.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3879$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3879$this->source); })()), "pm", [], "any"falsefalsefalse3879) == $context["pm"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3879$this->source); })())) == 1))) {
  5169.                         echo " is-selected";
  5170.                     }
  5171.                     echo "\"
  5172.                                      onclick=\"mitsumori_simulation_val('pm', '";
  5173.                     // line 3880
  5174.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pm"], "js"), "html"nulltrue);
  5175.                     echo "');\">
  5176.                                 <input type=\"radio\" name=\"pm\" id=\"pm_";
  5177.                     // line 3881
  5178.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3881$this->source); })()), "html"nulltrue);
  5179.                     echo "\" value=\"";
  5180.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  5181.                     echo "\"
  5182.                                        ";
  5183.                     // line 3882
  5184.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3882$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3882$this->source); })()), "pm", [], "any"falsefalsefalse3882) == $context["pm"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3882$this->source); })())) == 1))) {
  5185.                         echo "checked";
  5186.                     }
  5187.                     echo ">
  5188.                                 ";
  5189.                     // line 3883
  5190.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  5191.                     echo "
  5192.                               </label>
  5193.                             ";
  5194.                 }
  5195.             }
  5196.             $_parent $context['_parent'];
  5197.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm'], $context['_parent'], $context['loop']);
  5198.             $context array_intersect_key($context$_parent) + $_parent;
  5199.             // line 3886
  5200.             echo "                          </div>
  5201.                         </div>
  5202.                         ";
  5203.         }
  5204.         // line 3889
  5205.         echo "
  5206.                         ";
  5207.         // line 3894
  5208.         echo "                        ";
  5209.         if (((((((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3894$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3894$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3894$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3894$this->source); })()), "SaleType", [], "any"falsefalsefalse3894), "id", [], "any"falsefalsefalse3894) != 2)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3894$this->source); })()), "SaleType", [], "any"falsefalsefalse3894), "id", [], "any"falsefalsefalse3894) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3894$this->source); })()), "SaleType", [], "any"falsefalsefalse3894), "id", [], "any"falsefalsefalse3894) != 4)) &&  !(isset($context["is_cat43"]) || array_key_exists("is_cat43"$context) ? $context["is_cat43"] : (function () { throw new RuntimeError('Variable "is_cat43" does not exist.'3894$this->source); })())) &&  !(isset($context["is_cp"]) || array_key_exists("is_cp"$context) ? $context["is_cp"] : (function () { throw new RuntimeError('Variable "is_cp" does not exist.'3894$this->source); })()))) {
  5210.             // line 3895
  5211.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5212.                           <div class=\"rp-section-label\">";
  5213.             // line 3896
  5214.             echo twig_escape_filter($this->env, (isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'3896$this->source); })()), "html"nulltrue);
  5215.             if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3896$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3896)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3896$this->source); })()), "option1", [], "any"falsefalsefalse3896))) {
  5216.                 echo ": <span>";
  5217.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3896$this->source); })()), "option1", [], "any"falsefalsefalse3896), "html"nulltrue);
  5218.                 echo "</span>";
  5219.             }
  5220.             echo "</div>
  5221.                           <div class=\"opt-btn-group\">
  5222.                             ";
  5223.             // line 3898
  5224.             $context["idx"] = 0;
  5225.             // line 3899
  5226.             echo "                            ";
  5227.             $context['_parent'] = $context;
  5228.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3899$this->source); })()));
  5229.             foreach ($context['_seq'] as $context["_key"] => $context["opt1"]) {
  5230.                 if ($context["opt1"]) {
  5231.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3899$this->source); })()) + 1);
  5232.                     // line 3900
  5233.                     echo "                              <label class=\"opt-btn";
  5234.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3900$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3900)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3900$this->source); })()), "option1", [], "any"falsefalsefalse3900) == $context["opt1"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3900$this->source); })())) == 1))) {
  5235.                         echo " is-selected";
  5236.                     }
  5237.                     echo "\"
  5238.                                      onclick=\"mitsumori_simulation_val('option1', '";
  5239.                     // line 3901
  5240.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt1"], "js"), "html"nulltrue);
  5241.                     echo "');\">
  5242.                                 <input type=\"radio\" name=\"option1\" id=\"option1_";
  5243.                     // line 3902
  5244.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3902$this->source); })()), "html"nulltrue);
  5245.                     echo "\" value=\"";
  5246.                     echo twig_escape_filter($this->env$context["opt1"], "html"nulltrue);
  5247.                     echo "\"
  5248.                                        ";
  5249.                     // line 3903
  5250.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3903$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3903)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3903$this->source); })()), "option1", [], "any"falsefalsefalse3903) == $context["opt1"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3903$this->source); })())) == 1))) {
  5251.                         echo "checked";
  5252.                     }
  5253.                     echo ">
  5254.                                 ";
  5255.                     // line 3904
  5256.                     echo twig_escape_filter($this->env$context["opt1"], "html"nulltrue);
  5257.                     echo "
  5258.                               </label>
  5259.                             ";
  5260.                 }
  5261.             }
  5262.             $_parent $context['_parent'];
  5263.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1'], $context['_parent'], $context['loop']);
  5264.             $context array_intersect_key($context$_parent) + $_parent;
  5265.             // line 3907
  5266.             echo "                          </div>
  5267.                         </div>
  5268.                         ";
  5269.         }
  5270.         // line 3910
  5271.         echo "
  5272.                         ";
  5273.         // line 3912
  5274.         echo "                        ";
  5275.         if (((((((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3912$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3912$this->source); })()))) && (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3912$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3912$this->source); })()), "SaleType", [], "any"falsefalsefalse3912), "id", [], "any"falsefalsefalse3912) != 2)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3912$this->source); })()), "SaleType", [], "any"falsefalsefalse3912), "id", [], "any"falsefalsefalse3912) != 3)) &&  !(isset($context["is_cat43"]) || array_key_exists("is_cat43"$context) ? $context["is_cat43"] : (function () { throw new RuntimeError('Variable "is_cat43" does not exist.'3912$this->source); })()))) {
  5276.             // line 3913
  5277.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5278.                           <div class=\"rp-section-label\">";
  5279.             // line 3914
  5280.             echo twig_escape_filter($this->env, (isset($context["option2_label"]) || array_key_exists("option2_label"$context) ? $context["option2_label"] : (function () { throw new RuntimeError('Variable "option2_label" does not exist.'3914$this->source); })()), "html"nulltrue);
  5281.             if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3914$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3914)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3914$this->source); })()), "option2", [], "any"falsefalsefalse3914))) {
  5282.                 echo ": <span>";
  5283.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3914$this->source); })()), "option2", [], "any"falsefalsefalse3914), "html"nulltrue);
  5284.                 echo "</span>";
  5285.             }
  5286.             echo "</div>
  5287.                           <div class=\"opt-btn-group\">
  5288.                             ";
  5289.             // line 3916
  5290.             $context["idx"] = 0;
  5291.             // line 3917
  5292.             echo "                            ";
  5293.             $context['_parent'] = $context;
  5294.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3917$this->source); })()));
  5295.             foreach ($context['_seq'] as $context["_key"] => $context["opt2"]) {
  5296.                 if ($context["opt2"]) {
  5297.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3917$this->source); })()) + 1);
  5298.                     // line 3918
  5299.                     echo "                              <label class=\"opt-btn";
  5300.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3918$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3918)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3918$this->source); })()), "option2", [], "any"falsefalsefalse3918) == $context["opt2"])) || (twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3918$this->source); })())) == 1))) {
  5301.                         echo " is-selected";
  5302.                     }
  5303.                     echo "\"
  5304.                                      onclick=\"mitsumori_simulation_val('option2', '";
  5305.                     // line 3919
  5306.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt2"], "js"), "html"nulltrue);
  5307.                     echo "');\">
  5308.                                 <input type=\"radio\" name=\"option2\" id=\"option2_";
  5309.                     // line 3920
  5310.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3920$this->source); })()), "html"nulltrue);
  5311.                     echo "\" value=\"";
  5312.                     echo twig_escape_filter($this->env$context["opt2"], "html"nulltrue);
  5313.                     echo "\"
  5314.                                        ";
  5315.                     // line 3921
  5316.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3921$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3921)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3921$this->source); })()), "option2", [], "any"falsefalsefalse3921) == $context["opt2"])) || (twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3921$this->source); })())) == 1))) {
  5317.                         echo "checked";
  5318.                     }
  5319.                     echo ">
  5320.                                 ";
  5321.                     // line 3922
  5322.                     echo twig_escape_filter($this->env$context["opt2"], "html"nulltrue);
  5323.                     echo "
  5324.                               </label>
  5325.                             ";
  5326.                 }
  5327.             }
  5328.             $_parent $context['_parent'];
  5329.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt2'], $context['_parent'], $context['loop']);
  5330.             $context array_intersect_key($context$_parent) + $_parent;
  5331.             // line 3925
  5332.             echo "                          </div>
  5333.                         </div>
  5334.                         ";
  5335.         }
  5336.         // line 3928
  5337.         echo "
  5338. \t\t\t\t\t\t<!-- 1: 施工見積(通常) → 幅/奥行/高さ/素材/カラーは上部の共通ブロックで表示済み -->
  5339. \t\t\t\t\t\t";
  5340.         // line 3930
  5341.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3930$this->source); })()), "SaleType", [], "any"falsefalsefalse3930), "id", [], "any"falsefalsefalse3930) == 1)) {
  5342.             // line 3931
  5343.             echo "\t\t\t\t\t\t";
  5344.         }
  5345.         // line 3932
  5346.         echo "
  5347. \t\t\t\t\t\t<!-- 2: 施工見積(補助金・窓) 複数タイプ追加対応 (2026-05) -->
  5348. \t\t\t\t\t\t";
  5349.         // line 3934
  5350.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3934$this->source); })()), "SaleType", [], "any"falsefalsefalse3934), "id", [], "any"falsefalsefalse3934) == 2)) {
  5351.             // line 3935
  5352.             echo "
  5353. \t\t\t\t\t\t\t";
  5354.             // line 3939
  5355.             echo "
  5356. \t\t\t\t\t\t\t";
  5357.             // line 3943
  5358.             echo "\t\t\t\t\t\t\t<style>
  5359. \t\t\t\t\t\t\t\t.ec-productRole__profile {
  5360. \t\t\t\t\t\t\t\t\toverflow: visible !important;
  5361. \t\t\t\t\t\t\t\t\tmax-height: none !important;
  5362. \t\t\t\t\t\t\t\t\theight: auto !important;
  5363. \t\t\t\t\t\t\t\t}
  5364. \t\t\t\t\t\t\t</style>
  5365. \t\t\t\t\t\t\t";
  5366.             // line 3952
  5367.             echo "\t\t\t\t\t\t\t";
  5368.             $context["housing_default"] = _twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3952$this->source); })()), "id", [], "any"falsefalsefalse3952), "住宅区分"), "戸建");
  5369.             // line 3953
  5370.             echo "\t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  5371. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  5372. \t\t\t\t\t\t\t    <strong>お住まいの種別を選択</strong>
  5373. \t\t\t\t\t\t\t    <small class=\"ms-2 text-muted\">補助金単価が変わります</small>
  5374. \t\t\t\t\t\t\t  </div>
  5375. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  5376. \t\t\t\t\t\t\t    <div class=\"opt-btn-group\" id=\"window-housing-type-group\">
  5377. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  5378. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"戸建\"
  5379. \t\t\t\t\t\t\t               ";
  5380.             // line 3962
  5381.             if (((isset($context["housing_default"]) || array_key_exists("housing_default"$context) ? $context["housing_default"] : (function () { throw new RuntimeError('Variable "housing_default" does not exist.'3962$this->source); })()) != "集合住宅")) {
  5382.                 echo "checked";
  5383.             }
  5384.             echo ">
  5385. \t\t\t\t\t\t\t        戸建住宅<small class=\"d-block text-muted\">(延床240㎡以下の非住宅含む)</small>
  5386. \t\t\t\t\t\t\t      </label>
  5387. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  5388. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"集合住宅\"
  5389. \t\t\t\t\t\t\t               ";
  5390.             // line 3967
  5391.             if (((isset($context["housing_default"]) || array_key_exists("housing_default"$context) ? $context["housing_default"] : (function () { throw new RuntimeError('Variable "housing_default" does not exist.'3967$this->source); })()) == "集合住宅")) {
  5392.                 echo "checked";
  5393.             }
  5394.             echo ">
  5395. \t\t\t\t\t\t\t        集合住宅<small class=\"d-block text-muted\">(低層・中高層/240㎡超の非住宅)</small>
  5396. \t\t\t\t\t\t\t      </label>
  5397. \t\t\t\t\t\t\t    </div>
  5398. \t\t\t\t\t\t\t  </div>
  5399. \t\t\t\t\t\t\t</div>
  5400. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  5401. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  5402. \t\t\t\t\t\t\t    <strong>窓タイプを選択(複数追加可・最大 20)</strong>
  5403. \t\t\t\t\t\t\t  </div>
  5404. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  5405. \t\t\t\t\t\t\t    ";
  5406.             // line 3980
  5407.             echo "\t\t\t\t\t\t\t    <p class=\"subsidy-eligibility-note\">※先進的窓リノベ2026の補助金は、各窓の補助金額の<strong>合計が5万円以上</strong>で適用されます。各窓ごとの補助金額は下に常時表示しています。</p>
  5408. \t\t\t\t\t\t\t    <div id=\"window-types-container\"><!-- 動的に窓タイプブロックが追加される --></div>
  5409. \t\t\t\t\t\t\t    <div class=\"text-center mt-2\">
  5410. \t\t\t\t\t\t\t      <button type=\"button\" id=\"btn-add-window-type\" class=\"btn btn-outline-primary btn-sm\" onclick=\"addWindowType();\">+ 窓タイプを追加</button>
  5411. \t\t\t\t\t\t\t      <div class=\"small text-muted mt-1\">最大 20 タイプまで追加できます</div>
  5412. \t\t\t\t\t\t\t    </div>
  5413. \t\t\t\t\t\t\t  </div>
  5414. \t\t\t\t\t\t\t</div>
  5415. \t\t\t\t\t\t\t";
  5416.             // line 3990
  5417.             echo "\t\t\t\t\t\t\t<template id=\"window-type-template\">
  5418. \t\t\t\t\t\t\t  <div class=\"window-type-block\" data-type-idx=\"__IDX__\" style=\"border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:10px;background:#fafafa;\">
  5419. \t\t\t\t\t\t\t    <div class=\"d-flex justify-content-between align-items-center mb-2\">
  5420. \t\t\t\t\t\t\t      <strong>窓タイプ <span class=\"wt-num\">__IDX__</span></strong>
  5421. \t\t\t\t\t\t\t      <button type=\"button\" class=\"btn btn-sm btn-outline-danger btn-remove-window-type\" onclick=\"removeWindowType(this);\">× 削除</button>
  5422. \t\t\t\t\t\t\t    </div>
  5423. \t\t\t\t\t\t\t    ";
  5424.             // line 3998
  5425.             echo "\t\t\t\t\t\t\t    ";
  5426.             if ((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3998$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3998$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3998$this->source); })())) != ""))) {
  5427.                 // line 3999
  5428.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5429. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓タイプ</div>
  5430. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  5431. \t\t\t\t\t\t\t        ";
  5432.                 // line 4002
  5433.                 $context['_parent'] = $context;
  5434.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4002$this->source); })()));
  5435.                 foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  5436.                     if ($context["v"]) {
  5437.                         // line 4003
  5438.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn\">
  5439. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_subtype___IDX__\" value=\"";
  5440.                         // line 4004
  5441.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5442.                         echo "\" data-axis=\"subtype\" onchange=\"onWindowTypeAxisChange(this);\">
  5443. \t\t\t\t\t\t\t            ";
  5444.                         // line 4005
  5445.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5446.                         echo "
  5447. \t\t\t\t\t\t\t          </label>
  5448. \t\t\t\t\t\t\t        ";
  5449.                     }
  5450.                 }
  5451.                 $_parent $context['_parent'];
  5452.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  5453.                 $context array_intersect_key($context$_parent) + $_parent;
  5454.                 // line 4008
  5455.                 echo "\t\t\t\t\t\t\t      </div>
  5456. \t\t\t\t\t\t\t    </div>
  5457. \t\t\t\t\t\t\t    ";
  5458.             }
  5459.             // line 4011
  5460.             echo "
  5461. \t\t\t\t\t\t\t    ";
  5462.             // line 4013
  5463.             echo "\t\t\t\t\t\t\t    ";
  5464.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4013$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4013$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4013$this->source); })())) != ""))) {
  5465.                 // line 4014
  5466.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5467. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">幅</div>
  5468. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  5469. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_pw___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  5470. \t\t\t\t\t\t\t               placeholder=\"例 1750\" data-axis=\"pw\" data-unit=\"mm\"
  5471. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  5472. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  5473. \t\t\t\t\t\t\t      </div>
  5474. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応幅: 〜";
  5475.                 // line 4022
  5476.                 echo twig_escape_filter($this->env_twig_default_filter(twig_last($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4022$this->source); })())), ""), "html"nulltrue);
  5477.                 echo "(";
  5478.                 echo twig_escape_filter($this->envtwig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4022$this->source); })())), "html"nulltrue);
  5479.                 echo " 段階の価格帯から自動選択)</small>
  5480. \t\t\t\t\t\t\t    </div>
  5481. \t\t\t\t\t\t\t    ";
  5482.             }
  5483.             // line 4025
  5484.             echo "
  5485. \t\t\t\t\t\t\t    ";
  5486.             // line 4027
  5487.             echo "\t\t\t\t\t\t\t    ";
  5488.             if ((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4027$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4027$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4027$this->source); })())) != ""))) {
  5489.                 // line 4028
  5490.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5491. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">高さ</div>
  5492. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  5493. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_ph___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  5494. \t\t\t\t\t\t\t               placeholder=\"例 1200\" data-axis=\"ph\" data-unit=\"mm\"
  5495. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  5496. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  5497. \t\t\t\t\t\t\t      </div>
  5498. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応高さ: 〜";
  5499.                 // line 4036
  5500.                 echo twig_escape_filter($this->env_twig_default_filter(twig_last($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4036$this->source); })())), ""), "html"nulltrue);
  5501.                 echo "(";
  5502.                 echo twig_escape_filter($this->envtwig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4036$this->source); })())), "html"nulltrue);
  5503.                 echo " 段階の価格帯から自動選択)</small>
  5504. \t\t\t\t\t\t\t    </div>
  5505. \t\t\t\t\t\t\t    ";
  5506.             }
  5507.             // line 4039
  5508.             echo "
  5509. \t\t\t\t\t\t\t    ";
  5510.             // line 4041
  5511.             echo "\t\t\t\t\t\t\t    ";
  5512.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4041$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4041$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4041$this->source); })())) != ""))) {
  5513.                 // line 4042
  5514.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5515. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">ガラスタイプ</div>
  5516. \t\t\t\t\t\t\t      ";
  5517.                 // line 4046
  5518.                 echo "\t\t\t\t\t\t\t      <div class=\"opt-btn-group no-hscroll\">
  5519. \t\t\t\t\t\t\t        ";
  5520.                 // line 4047
  5521.                 $context['_parent'] = $context;
  5522.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4047$this->source); })()));
  5523.                 foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  5524.                     if ($context["v"]) {
  5525.                         // line 4048
  5526.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn\">
  5527. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pm___IDX__\" value=\"";
  5528.                         // line 4049
  5529.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5530.                         echo "\" data-axis=\"pm\" onchange=\"onWindowTypeAxisChange(this);\">
  5531. \t\t\t\t\t\t\t            ";
  5532.                         // line 4050
  5533.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5534.                         echo "
  5535. \t\t\t\t\t\t\t          </label>
  5536. \t\t\t\t\t\t\t        ";
  5537.                     }
  5538.                 }
  5539.                 $_parent $context['_parent'];
  5540.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  5541.                 $context array_intersect_key($context$_parent) + $_parent;
  5542.                 // line 4053
  5543.                 echo "\t\t\t\t\t\t\t      </div>
  5544. \t\t\t\t\t\t\t      <small class=\"text-muted\">「<span style=\"color:#2e7d32;font-weight:bold;\">補助金対象</span>」が付いたガラスは、先進的窓リノベ補助金の対象です。</small>
  5545. \t\t\t\t\t\t\t    </div>
  5546. \t\t\t\t\t\t\t    ";
  5547.             }
  5548.             // line 4057
  5549.             echo "
  5550. \t\t\t\t\t\t\t    ";
  5551.             // line 4059
  5552.             echo "\t\t\t\t\t\t\t    ";
  5553.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4059$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4059$this->source); })())))) {
  5554.                 // line 4060
  5555.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5556. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓枠カラー</div>
  5557. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  5558. \t\t\t\t\t\t\t        ";
  5559.                 // line 4063
  5560.                 $context['_parent'] = $context;
  5561.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4063$this->source); })()));
  5562.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  5563.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4063))) {
  5564.                         // line 4064
  5565.                         echo "\t\t\t\t\t\t\t          ";
  5566.                         $context["has_img"] = (twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"truetruefalse4064) &&  !twig_test_empty(twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse4064)));
  5567.                         // line 4065
  5568.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn";
  5569.                         if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'4065$this->source); })())) {
  5570.                             echo " opt-btn--with-image";
  5571.                         }
  5572.                         echo "\">
  5573. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pc___IDX__\" value=\"";
  5574.                         // line 4066
  5575.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4066), "html"nulltrue);
  5576.                         echo "\" data-axis=\"pc\" onchange=\"onWindowTypeAxisChange(this);\">
  5577. \t\t\t\t\t\t\t            ";
  5578.                         // line 4067
  5579.                         if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'4067$this->source); })())) {
  5580.                             // line 4068
  5581.                             echo "\t\t\t\t\t\t\t              <img src=\"";
  5582.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse4068), "html"nulltrue);
  5583.                             echo "\" alt=\"";
  5584.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4068), "html"nulltrue);
  5585.                             echo "\" class=\"opt-btn__img\"
  5586. \t\t\t\t\t\t\t                   onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  5587. \t\t\t\t\t\t\t              <span class=\"opt-btn__name\">";
  5588.                             // line 4070
  5589.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4070), "html"nulltrue);
  5590.                             echo "</span>
  5591. \t\t\t\t\t\t\t            ";
  5592.                         } else {
  5593.                             // line 4072
  5594.                             echo "\t\t\t\t\t\t\t              ";
  5595.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4072), "html"nulltrue);
  5596.                             echo "
  5597. \t\t\t\t\t\t\t            ";
  5598.                         }
  5599.                         // line 4074
  5600.                         echo "\t\t\t\t\t\t\t          </label>
  5601. \t\t\t\t\t\t\t        ";
  5602.                     }
  5603.                 }
  5604.                 $_parent $context['_parent'];
  5605.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  5606.                 $context array_intersect_key($context$_parent) + $_parent;
  5607.                 // line 4076
  5608.                 echo "\t\t\t\t\t\t\t      </div>
  5609. \t\t\t\t\t\t\t    </div>
  5610. \t\t\t\t\t\t\t    ";
  5611.             }
  5612.             // line 4079
  5613.             echo "
  5614. \t\t\t\t\t\t\t    ";
  5615.             // line 4081
  5616.             echo "\t\t\t\t\t\t\t    <div class=\"form-group row mt-2 align-items-center\">
  5617. \t\t\t\t\t\t\t      <label class=\"col-4 col-form-label\">セット数</label>
  5618. \t\t\t\t\t\t\t      <div class=\"col-4\">
  5619. \t\t\t\t\t\t\t        <div class=\"input-group\">
  5620. \t\t\t\t\t\t\t          <input type=\"number\" name=\"wt_setqty___IDX__\" class=\"form-control wt-input-setqty\" value=\"1\" min=\"1\" max=\"99\" data-axis=\"setqty\" onchange=\"onWindowTypeAxisChange(this);\">
  5621. \t\t\t\t\t\t\t          <span class=\"input-group-text\">セット</span>
  5622. \t\t\t\t\t\t\t        </div>
  5623. \t\t\t\t\t\t\t      </div>
  5624. \t\t\t\t\t\t\t      <div class=\"col-4 text-end\">
  5625. \t\t\t\t\t\t\t        <span class=\"wt-subsidy-label\">補助金額</span><br><span class=\"wt-subsidy-amount\">―</span> <span class=\"wt-subsidy-label\">円</span>
  5626. \t\t\t\t\t\t\t      </div>
  5627. \t\t\t\t\t\t\t    </div>
  5628. \t\t\t\t\t\t\t  </div>
  5629. \t\t\t\t\t\t\t</template>
  5630. \t\t\t\t\t\t\t";
  5631.             // line 4097
  5632.             echo "\t\t\t\t\t\t\t<script>
  5633. \t\t\t\t\t\t\t(function() {
  5634. \t\t\t\t\t\t\t\tvar MAX_WINDOW_TYPES = 20;
  5635. \t\t\t\t\t\t\t\tfunction addWindowType() {
  5636. \t\t\t\t\t\t\t\t\tvar container = document.getElementById('window-types-container');
  5637. \t\t\t\t\t\t\t\t\tif (!container) return;
  5638. \t\t\t\t\t\t\t\t\tvar existing = container.querySelectorAll('.window-type-block');
  5639. \t\t\t\t\t\t\t\t\tif (existing.length >= MAX_WINDOW_TYPES) return;
  5640. \t\t\t\t\t\t\t\t\tvar newIdx = existing.length + 1;
  5641. \t\t\t\t\t\t\t\t\tvar tpl = document.getElementById('window-type-template');
  5642. \t\t\t\t\t\t\t\t\tif (!tpl) return;
  5643. \t\t\t\t\t\t\t\t\t// <template> の innerHTML を取り出して __IDX__ を新規連番に置換し、要素化して append.
  5644. \t\t\t\t\t\t\t\t\tvar html = tpl.innerHTML.replace(/__IDX__/g, String(newIdx));
  5645. \t\t\t\t\t\t\t\t\tvar wrapper = document.createElement('div');
  5646. \t\t\t\t\t\t\t\t\twrapper.innerHTML = html.trim();
  5647. \t\t\t\t\t\t\t\t\tvar block = wrapper.firstChild;
  5648. \t\t\t\t\t\t\t\t\tcontainer.appendChild(block);
  5649. \t\t\t\t\t\t\t\t\tdecorateSubsidyGlass(block);
  5650. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  5651. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5652. \t\t\t\t\t\t\t\t}
  5653. \t\t\t\t\t\t\t\t// 補助金対象ガラスの選択肢に「補助金対象」バッジ + 緑枠を付与する.
  5654. \t\t\t\t\t\t\t\t// 判定は calc script 側の window.glassYieldsSubsidy に委譲 (ロジック二重化を避ける)。
  5655. \t\t\t\t\t\t\t\tfunction decorateSubsidyGlass(block) {
  5656. \t\t\t\t\t\t\t\t\tif (!block || typeof window.glassYieldsSubsidy !== 'function') return;
  5657. \t\t\t\t\t\t\t\t\tvar radios = block.querySelectorAll('input[data-axis=\"pm\"]');
  5658. \t\t\t\t\t\t\t\t\tradios.forEach(function(inp) {
  5659. \t\t\t\t\t\t\t\t\t\tvar label = inp.closest('.opt-btn');
  5660. \t\t\t\t\t\t\t\t\t\tif (!label || label.querySelector('.opt-btn__subsidy-badge')) return;
  5661. \t\t\t\t\t\t\t\t\t\tif (window.glassYieldsSubsidy(inp.value)) {
  5662. \t\t\t\t\t\t\t\t\t\t\tlabel.classList.add('opt-btn--subsidy');
  5663. \t\t\t\t\t\t\t\t\t\t\tvar badge = document.createElement('span');
  5664. \t\t\t\t\t\t\t\t\t\t\tbadge.className = 'opt-btn__subsidy-badge';
  5665. \t\t\t\t\t\t\t\t\t\t\tbadge.textContent = '補助金対象';
  5666. \t\t\t\t\t\t\t\t\t\t\tlabel.appendChild(badge);
  5667. \t\t\t\t\t\t\t\t\t\t}
  5668. \t\t\t\t\t\t\t\t\t});
  5669. \t\t\t\t\t\t\t\t}
  5670. \t\t\t\t\t\t\t\tfunction removeWindowType(btn) {
  5671. \t\t\t\t\t\t\t\t\tvar block = btn.closest('.window-type-block');
  5672. \t\t\t\t\t\t\t\t\tif (!block) return;
  5673. \t\t\t\t\t\t\t\t\tblock.remove();
  5674. \t\t\t\t\t\t\t\t\treindexBlocks();
  5675. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  5676. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5677. \t\t\t\t\t\t\t\t}
  5678. \t\t\t\t\t\t\t\tfunction updateRemoveButtonVisibility() {
  5679. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  5680. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b) {
  5681. \t\t\t\t\t\t\t\t\t\tvar btn = b.querySelector('.btn-remove-window-type');
  5682. \t\t\t\t\t\t\t\t\t\tif (btn) btn.style.display = blocks.length > 1 ? '' : 'none';
  5683. \t\t\t\t\t\t\t\t\t});
  5684. \t\t\t\t\t\t\t\t}
  5685. \t\t\t\t\t\t\t\tfunction reindexBlocks() {
  5686. \t\t\t\t\t\t\t\t\t// ブロック削除後に 1 から振り直し. input[name] の末尾 _N も書き換える.
  5687. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  5688. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b, i) {
  5689. \t\t\t\t\t\t\t\t\t\tvar n = i + 1;
  5690. \t\t\t\t\t\t\t\t\t\tb.setAttribute('data-type-idx', String(n));
  5691. \t\t\t\t\t\t\t\t\t\tvar numSpan = b.querySelector('.wt-num');
  5692. \t\t\t\t\t\t\t\t\t\tif (numSpan) numSpan.textContent = String(n);
  5693. \t\t\t\t\t\t\t\t\t\tb.querySelectorAll('input[name]').forEach(function(inp) {
  5694. \t\t\t\t\t\t\t\t\t\t\tinp.name = inp.name.replace(/_\\d+\$/, '_' + n);
  5695. \t\t\t\t\t\t\t\t\t\t});
  5696. \t\t\t\t\t\t\t\t\t});
  5697. \t\t\t\t\t\t\t\t}
  5698. \t\t\t\t\t\t\t\t// 軸変更イベント. recalcAll が定義されていれば再計算 (task 2 で実装).
  5699. \t\t\t\t\t\t\t\twindow.onWindowTypeAxisChange = function() {
  5700. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5701. \t\t\t\t\t\t\t\t};
  5702. \t\t\t\t\t\t\t\twindow.addWindowType = addWindowType;
  5703. \t\t\t\t\t\t\t\twindow.removeWindowType = removeWindowType;
  5704. \t\t\t\t\t\t\t\t// 隠し radio(opacity:0/pointer-events:none) を label で包む opt-btn は iOS で初回タップの
  5705. \t\t\t\t\t\t\t\t// change が不発になりやすい。窓タイプ/住宅区分は label に onclick が無く change 依存だった
  5706. \t\t\t\t\t\t\t\t// ため「2回タッチ/選択できない」が発生。click は確実に発火するので委譲 click で選択状態・
  5707. \t\t\t\t\t\t\t\t// is-selected・再計算を行う(JSで複製される窓タイプにも委譲で対応)。
  5708. \t\t\t\t\t\t\t\tdocument.addEventListener('click', function(ev) {
  5709. \t\t\t\t\t\t\t\t\tif (!ev.target || !ev.target.closest) return;
  5710. \t\t\t\t\t\t\t\t\tvar label = ev.target.closest('.opt-btn');
  5711. \t\t\t\t\t\t\t\t\tif (!label) return;
  5712. \t\t\t\t\t\t\t\t\tif (!label.closest('#window-types-container') && !label.closest('#window-housing-type-group')) return;
  5713. \t\t\t\t\t\t\t\t\tvar input = label.querySelector('input[type=\"radio\"]');
  5714. \t\t\t\t\t\t\t\t\tif (!input || input.disabled) return;
  5715. \t\t\t\t\t\t\t\t\tinput.checked = true;
  5716. \t\t\t\t\t\t\t\t\tvar nm = input.getAttribute('name');
  5717. \t\t\t\t\t\t\t\t\tif (nm) {
  5718. \t\t\t\t\t\t\t\t\t\tdocument.querySelectorAll('input[name=\"' + nm + '\"]').forEach(function(i) {
  5719. \t\t\t\t\t\t\t\t\t\t\tvar l = i.closest('.opt-btn');
  5720. \t\t\t\t\t\t\t\t\t\t\tif (l) l.classList.toggle('is-selected', i.checked);
  5721. \t\t\t\t\t\t\t\t\t\t});
  5722. \t\t\t\t\t\t\t\t\t}
  5723. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5724. \t\t\t\t\t\t\t\t});
  5725. \t\t\t\t\t\t\t\t// 初期表示で 1 ブロック追加 + 住宅区分ラジオの change で再計算.
  5726. \t\t\t\t\t\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
  5727. \t\t\t\t\t\t\t\t\tif (document.querySelector('#window-types-container')) {
  5728. \t\t\t\t\t\t\t\t\t\taddWindowType();
  5729. \t\t\t\t\t\t\t\t\t}
  5730. \t\t\t\t\t\t\t\t\tvar housingInputs = document.querySelectorAll('input[name=\"window_housing_type\"]');
  5731. \t\t\t\t\t\t\t\t\tvar syncHousingSelectedClass = function() {
  5732. \t\t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  5733. \t\t\t\t\t\t\t\t\t\t\tvar lbl = el.closest('.opt-btn');
  5734. \t\t\t\t\t\t\t\t\t\t\tif (!lbl) return;
  5735. \t\t\t\t\t\t\t\t\t\t\tif (el.checked) lbl.classList.add('is-selected');
  5736. \t\t\t\t\t\t\t\t\t\t\telse            lbl.classList.remove('is-selected');
  5737. \t\t\t\t\t\t\t\t\t\t});
  5738. \t\t\t\t\t\t\t\t\t};
  5739. \t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  5740. \t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  5741. \t\t\t\t\t\t\t\t\t\tel.addEventListener('change', function() {
  5742. \t\t\t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  5743. \t\t\t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5744. \t\t\t\t\t\t\t\t\t\t});
  5745. \t\t\t\t\t\t\t\t\t});
  5746. \t\t\t\t\t\t\t\t});
  5747. \t\t\t\t\t\t\t})();
  5748. \t\t\t\t\t\t\t</script>
  5749. \t\t\t\t\t\t";
  5750.         }
  5751.         // line 4225
  5752.         echo "
  5753. \t\t\t\t\t\t<!-- 3: 施工見積(物置・ゴミステーション) -->
  5754. \t\t\t\t\t\t";
  5755.         // line 4227
  5756.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4227$this->source); })()), "SaleType", [], "any"falsefalsefalse4227), "id", [], "any"falsefalsefalse4227) == 3)) {
  5757.             // line 4228
  5758.             echo "
  5759. \t\t\t\t\t\t\t";
  5760.             // line 4230
  5761.             echo "\t\t\t\t\t\t\t";
  5762.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4230$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4230$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4230$this->source); })())) != ""))) {
  5763.                 // line 4231
  5764.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5765. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">幅";
  5766.                 // line 4232
  5767.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4232$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4232$this->source); })()), "pw", [], "any"falsefalsefalse4232))) {
  5768.                     echo ": <span>";
  5769.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4232$this->source); })()), "pw", [], "any"falsefalsefalse4232), "html"nulltrue);
  5770.                     echo "</span>";
  5771.                 }
  5772.                 echo "</div>
  5773. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5774. \t\t\t\t\t\t\t    ";
  5775.                 // line 4234
  5776.                 $context["idx"] = 0;
  5777.                 // line 4235
  5778.                 echo "\t\t\t\t\t\t\t    ";
  5779.                 $context['_parent'] = $context;
  5780.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4235$this->source); })()));
  5781.                 foreach ($context['_seq'] as $context["_key"] => $context["pw_val"]) {
  5782.                     if ($context["pw_val"]) {
  5783.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4235$this->source); })()) + 1);
  5784.                         // line 4236
  5785.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5786.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4236$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4236$this->source); })()), "pw", [], "any"falsefalsefalse4236) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4236$this->source); })())) == 1))) {
  5787.                             echo " is-selected";
  5788.                         }
  5789.                         echo "\"
  5790. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw3_";
  5791.                         // line 4237
  5792.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4237$this->source); })()), "html"nulltrue);
  5793.                         echo "');\">
  5794. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw3_";
  5795.                         // line 4238
  5796.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4238$this->source); })()), "html"nulltrue);
  5797.                         echo "\" value=\"";
  5798.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5799.                         echo "\"
  5800. \t\t\t\t\t\t\t               ";
  5801.                         // line 4239
  5802.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4239$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4239$this->source); })()), "pw", [], "any"falsefalsefalse4239) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4239$this->source); })())) == 1))) {
  5803.                             echo "checked";
  5804.                         }
  5805.                         echo ">
  5806. \t\t\t\t\t\t\t        ";
  5807.                         // line 4240
  5808.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5809.                         echo "
  5810. \t\t\t\t\t\t\t      </label>
  5811. \t\t\t\t\t\t\t    ";
  5812.                     }
  5813.                 }
  5814.                 $_parent $context['_parent'];
  5815.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw_val'], $context['_parent'], $context['loop']);
  5816.                 $context array_intersect_key($context$_parent) + $_parent;
  5817.                 // line 4243
  5818.                 echo "\t\t\t\t\t\t\t  </div>
  5819. \t\t\t\t\t\t\t</div>
  5820. \t\t\t\t\t\t\t";
  5821.             }
  5822.             // line 4246
  5823.             echo "
  5824. \t\t\t\t\t\t\t";
  5825.             // line 4247
  5826.             if ((((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'4247$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'4247$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'4247$this->source); })())) != ""))) {
  5827.                 // line 4248
  5828.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5829. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">奥行き";
  5830.                 // line 4249
  5831.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4249$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4249$this->source); })()), "pd", [], "any"falsefalsefalse4249))) {
  5832.                     echo ": <span>";
  5833.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4249$this->source); })()), "pd", [], "any"falsefalsefalse4249), "html"nulltrue);
  5834.                     echo "</span>";
  5835.                 }
  5836.                 echo "</div>
  5837. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5838. \t\t\t\t\t\t\t    ";
  5839.                 // line 4251
  5840.                 $context["idx"] = 0;
  5841.                 // line 4252
  5842.                 echo "\t\t\t\t\t\t\t    ";
  5843.                 $context['_parent'] = $context;
  5844.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'4252$this->source); })()));
  5845.                 foreach ($context['_seq'] as $context["_key"] => $context["pd_val"]) {
  5846.                     if ($context["pd_val"]) {
  5847.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4252$this->source); })()) + 1);
  5848.                         // line 4253
  5849.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5850.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4253$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4253$this->source); })()), "pd", [], "any"falsefalsefalse4253) == $context["pd_val"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'4253$this->source); })())) == 1))) {
  5851.                             echo " is-selected";
  5852.                         }
  5853.                         echo "\"
  5854. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pd','pd3_";
  5855.                         // line 4254
  5856.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4254$this->source); })()), "html"nulltrue);
  5857.                         echo "');\">
  5858. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pd\" id=\"pd3_";
  5859.                         // line 4255
  5860.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4255$this->source); })()), "html"nulltrue);
  5861.                         echo "\" value=\"";
  5862.                         echo twig_escape_filter($this->env$context["pd_val"], "html"nulltrue);
  5863.                         echo "\"
  5864. \t\t\t\t\t\t\t               ";
  5865.                         // line 4256
  5866.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4256$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4256$this->source); })()), "pd", [], "any"falsefalsefalse4256) == $context["pd_val"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'4256$this->source); })())) == 1))) {
  5867.                             echo "checked";
  5868.                         }
  5869.                         echo ">
  5870. \t\t\t\t\t\t\t        ";
  5871.                         // line 4257
  5872.                         echo twig_escape_filter($this->env$context["pd_val"], "html"nulltrue);
  5873.                         echo "
  5874. \t\t\t\t\t\t\t      </label>
  5875. \t\t\t\t\t\t\t    ";
  5876.                     }
  5877.                 }
  5878.                 $_parent $context['_parent'];
  5879.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd_val'], $context['_parent'], $context['loop']);
  5880.                 $context array_intersect_key($context$_parent) + $_parent;
  5881.                 // line 4260
  5882.                 echo "\t\t\t\t\t\t\t  </div>
  5883. \t\t\t\t\t\t\t</div>
  5884. \t\t\t\t\t\t\t";
  5885.             }
  5886.             // line 4263
  5887.             echo "
  5888. \t\t\t\t\t\t\t";
  5889.             // line 4264
  5890.             if ((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4264$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4264$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4264$this->source); })())) != ""))) {
  5891.                 // line 4265
  5892.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5893. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">高さ";
  5894.                 // line 4266
  5895.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4266$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4266$this->source); })()), "ph", [], "any"falsefalsefalse4266))) {
  5896.                     echo ": <span>";
  5897.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4266$this->source); })()), "ph", [], "any"falsefalsefalse4266), "html"nulltrue);
  5898.                     echo "</span>";
  5899.                 }
  5900.                 echo "</div>
  5901. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5902. \t\t\t\t\t\t\t    ";
  5903.                 // line 4268
  5904.                 $context["idx"] = 0;
  5905.                 // line 4269
  5906.                 echo "\t\t\t\t\t\t\t    ";
  5907.                 $context['_parent'] = $context;
  5908.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4269$this->source); })()));
  5909.                 foreach ($context['_seq'] as $context["_key"] => $context["ph_val"]) {
  5910.                     if ($context["ph_val"]) {
  5911.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4269$this->source); })()) + 1);
  5912.                         // line 4270
  5913.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5914.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4270$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4270$this->source); })()), "ph", [], "any"falsefalsefalse4270) == $context["ph_val"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4270$this->source); })())) == 1))) {
  5915.                             echo " is-selected";
  5916.                         }
  5917.                         echo "\"
  5918. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('ph','ph3_";
  5919.                         // line 4271
  5920.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4271$this->source); })()), "html"nulltrue);
  5921.                         echo "');\">
  5922. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"ph\" id=\"ph3_";
  5923.                         // line 4272
  5924.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4272$this->source); })()), "html"nulltrue);
  5925.                         echo "\" value=\"";
  5926.                         echo twig_escape_filter($this->env$context["ph_val"], "html"nulltrue);
  5927.                         echo "\"
  5928. \t\t\t\t\t\t\t               ";
  5929.                         // line 4273
  5930.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4273$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4273$this->source); })()), "ph", [], "any"falsefalsefalse4273) == $context["ph_val"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4273$this->source); })())) == 1))) {
  5931.                             echo "checked";
  5932.                         }
  5933.                         echo ">
  5934. \t\t\t\t\t\t\t        ";
  5935.                         // line 4274
  5936.                         echo twig_escape_filter($this->env$context["ph_val"], "html"nulltrue);
  5937.                         echo "
  5938. \t\t\t\t\t\t\t      </label>
  5939. \t\t\t\t\t\t\t    ";
  5940.                     }
  5941.                 }
  5942.                 $_parent $context['_parent'];
  5943.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph_val'], $context['_parent'], $context['loop']);
  5944.                 $context array_intersect_key($context$_parent) + $_parent;
  5945.                 // line 4277
  5946.                 echo "\t\t\t\t\t\t\t  </div>
  5947. \t\t\t\t\t\t\t</div>
  5948. \t\t\t\t\t\t\t";
  5949.             }
  5950.             // line 4280
  5951.             echo "
  5952. \t\t\t\t\t\t\t";
  5953.             // line 4282
  5954.             echo "\t\t\t\t\t\t\t";
  5955.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4282$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4282$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4282$this->source); })())) != ""))) {
  5956.                 // line 4283
  5957.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5958. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">棚タイプ <small class=\"text-muted\">(間仕切り仕様)</small>";
  5959.                 // line 4284
  5960.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4284$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4284$this->source); })()), "pm", [], "any"falsefalsefalse4284))) {
  5961.                     echo ": <span>";
  5962.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4284$this->source); })()), "pm", [], "any"falsefalsefalse4284), "html"nulltrue);
  5963.                     echo "</span>";
  5964.                 }
  5965.                 echo "</div>
  5966. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5967. \t\t\t\t\t\t\t    ";
  5968.                 // line 4286
  5969.                 $context["idx"] = 0;
  5970.                 // line 4287
  5971.                 echo "\t\t\t\t\t\t\t    ";
  5972.                 $context['_parent'] = $context;
  5973.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4287$this->source); })()));
  5974.                 foreach ($context['_seq'] as $context["_key"] => $context["pm_val"]) {
  5975.                     if ($context["pm_val"]) {
  5976.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4287$this->source); })()) + 1);
  5977.                         // line 4288
  5978.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5979.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4288$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4288$this->source); })()), "pm", [], "any"falsefalsefalse4288) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4288$this->source); })())) == 1))) {
  5980.                             echo " is-selected";
  5981.                         }
  5982.                         echo "\"
  5983. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm3_";
  5984.                         // line 4289
  5985.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4289$this->source); })()), "html"nulltrue);
  5986.                         echo "');\">
  5987. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm3_";
  5988.                         // line 4290
  5989.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4290$this->source); })()), "html"nulltrue);
  5990.                         echo "\" value=\"";
  5991.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5992.                         echo "\"
  5993. \t\t\t\t\t\t\t               ";
  5994.                         // line 4291
  5995.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4291$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4291$this->source); })()), "pm", [], "any"falsefalsefalse4291) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4291$this->source); })())) == 1))) {
  5996.                             echo "checked";
  5997.                         }
  5998.                         echo ">
  5999. \t\t\t\t\t\t\t        ";
  6000.                         // line 4292
  6001.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  6002.                         echo "
  6003. \t\t\t\t\t\t\t      </label>
  6004. \t\t\t\t\t\t\t    ";
  6005.                     }
  6006.                 }
  6007.                 $_parent $context['_parent'];
  6008.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm_val'], $context['_parent'], $context['loop']);
  6009.                 $context array_intersect_key($context$_parent) + $_parent;
  6010.                 // line 4295
  6011.                 echo "\t\t\t\t\t\t\t  </div>
  6012. \t\t\t\t\t\t\t</div>
  6013. \t\t\t\t\t\t\t";
  6014.             }
  6015.             // line 4298
  6016.             echo "
  6017. \t\t\t\t\t\t\t";
  6018.             // line 4300
  6019.             echo "\t\t\t\t\t\t\t";
  6020.             if ((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4300$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4300$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4300$this->source); })())) != ""))) {
  6021.                 // line 4301
  6022.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6023. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">";
  6024.                 // line 4302
  6025.                 echo twig_escape_filter($this->env, (isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'4302$this->source); })()), "html"nulltrue);
  6026.                 if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4302$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse4302)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4302$this->source); })()), "option1", [], "any"falsefalsefalse4302))) {
  6027.                     echo ": <span>";
  6028.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4302$this->source); })()), "option1", [], "any"falsefalsefalse4302), "html"nulltrue);
  6029.                     echo "</span>";
  6030.                 }
  6031.                 echo "</div>
  6032. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6033. \t\t\t\t\t\t\t    ";
  6034.                 // line 4304
  6035.                 $context["idx"] = 0;
  6036.                 // line 4305
  6037.                 echo "\t\t\t\t\t\t\t    ";
  6038.                 $context['_parent'] = $context;
  6039.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4305$this->source); })()));
  6040.                 foreach ($context['_seq'] as $context["_key"] => $context["opt1_val"]) {
  6041.                     if ($context["opt1_val"]) {
  6042.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4305$this->source); })()) + 1);
  6043.                         // line 4306
  6044.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  6045.                         if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4306$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse4306)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4306$this->source); })()), "option1", [], "any"falsefalsefalse4306) == $context["opt1_val"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4306$this->source); })())) == 1))) {
  6046.                             echo " is-selected";
  6047.                         }
  6048.                         echo "\"
  6049. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('option1','option1_3_";
  6050.                         // line 4307
  6051.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4307$this->source); })()), "html"nulltrue);
  6052.                         echo "');\">
  6053. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"option1\" id=\"option1_3_";
  6054.                         // line 4308
  6055.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4308$this->source); })()), "html"nulltrue);
  6056.                         echo "\" value=\"";
  6057.                         echo twig_escape_filter($this->env$context["opt1_val"], "html"nulltrue);
  6058.                         echo "\"
  6059. \t\t\t\t\t\t\t               ";
  6060.                         // line 4309
  6061.                         if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4309$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse4309)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4309$this->source); })()), "option1", [], "any"falsefalsefalse4309) == $context["opt1_val"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4309$this->source); })())) == 1))) {
  6062.                             echo "checked";
  6063.                         }
  6064.                         echo ">
  6065. \t\t\t\t\t\t\t        ";
  6066.                         // line 4310
  6067.                         echo twig_escape_filter($this->env$context["opt1_val"], "html"nulltrue);
  6068.                         echo "
  6069. \t\t\t\t\t\t\t      </label>
  6070. \t\t\t\t\t\t\t    ";
  6071.                     }
  6072.                 }
  6073.                 $_parent $context['_parent'];
  6074.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1_val'], $context['_parent'], $context['loop']);
  6075.                 $context array_intersect_key($context$_parent) + $_parent;
  6076.                 // line 4313
  6077.                 echo "\t\t\t\t\t\t\t  </div>
  6078. \t\t\t\t\t\t\t</div>
  6079. \t\t\t\t\t\t\t";
  6080.             }
  6081.             // line 4316
  6082.             echo "
  6083. \t\t\t\t\t\t\t";
  6084.             // line 4318
  6085.             echo "\t\t\t\t\t\t\t";
  6086.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4318$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4318$this->source); })())))) {
  6087.                 // line 4319
  6088.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6089. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">カラー";
  6090.                 // line 4320
  6091.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4320$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4320$this->source); })()), "pc", [], "any"falsefalsefalse4320))) {
  6092.                     echo ": <span>";
  6093.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4320$this->source); })()), "pc", [], "any"falsefalsefalse4320), "html"nulltrue);
  6094.                     echo "</span>";
  6095.                 }
  6096.                 echo "</div>
  6097. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6098. \t\t\t\t\t\t\t    ";
  6099.                 // line 4322
  6100.                 $context["idx"] = 0;
  6101.                 // line 4323
  6102.                 echo "\t\t\t\t\t\t\t    ";
  6103.                 $context['_parent'] = $context;
  6104.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4323$this->source); })()));
  6105.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  6106.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4323))) {
  6107.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4323$this->source); })()) + 1);
  6108.                         // line 4324
  6109.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  6110.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4324$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4324$this->source); })()), "pc", [], "any"falsefalsefalse4324) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4324))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4324$this->source); })())) == 1))) {
  6111.                             echo " is-selected";
  6112.                         }
  6113.                         echo "\"
  6114. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pc','cc3_";
  6115.                         // line 4325
  6116.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4325$this->source); })()), "html"nulltrue);
  6117.                         echo "');\">
  6118. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"color3\" id=\"cc3_";
  6119.                         // line 4326
  6120.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4326$this->source); })()), "html"nulltrue);
  6121.                         echo "\" value=\"";
  6122.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4326), "html"nulltrue);
  6123.                         echo "\"
  6124. \t\t\t\t\t\t\t               ";
  6125.                         // line 4327
  6126.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4327$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4327$this->source); })()), "pc", [], "any"falsefalsefalse4327) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4327))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4327$this->source); })())) == 1))) {
  6127.                             echo "checked";
  6128.                         }
  6129.                         echo ">
  6130. \t\t\t\t\t\t\t        ";
  6131.                         // line 4328
  6132.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4328), "html"nulltrue);
  6133.                         echo "
  6134. \t\t\t\t\t\t\t      </label>
  6135. \t\t\t\t\t\t\t    ";
  6136.                     }
  6137.                 }
  6138.                 $_parent $context['_parent'];
  6139.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  6140.                 $context array_intersect_key($context$_parent) + $_parent;
  6141.                 // line 4331
  6142.                 echo "\t\t\t\t\t\t\t  </div>
  6143. \t\t\t\t\t\t\t</div>
  6144. \t\t\t\t\t\t\t";
  6145.             }
  6146.             // line 4334
  6147.             echo "
  6148. \t\t\t\t\t\t\t";
  6149.             // line 4336
  6150.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6151. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">台数</label>
  6152. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6153. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6154. \t\t\t\t\t\t\t      <input type=\"number\" name=\"daisu\" id=\"daisu\" class=\"form-control\" value=\"";
  6155.             // line 4340
  6156.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "daisu", [], "any"truetruefalse4340)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "daisu", [], "any"falsefalsefalse4340), "1")) : ("1")), "html"nulltrue);
  6157.             echo "\" min=\"1\" max=\"10\" onchange=\"mitsumori_simulation('daisu','daisu');\">
  6158. \t\t\t\t\t\t\t      <span class=\"input-group-text\">台</span>
  6159. \t\t\t\t\t\t\t    </div>
  6160. \t\t\t\t\t\t\t  </div>
  6161. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6162. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"daisu(+1);\">+</button>
  6163. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"daisu(-1);\">ー</button>
  6164. \t\t\t\t\t\t\t  </div>
  6165. \t\t\t\t\t\t\t</div>
  6166. \t\t\t\t\t\t";
  6167.         }
  6168.         // line 4351
  6169.         echo "
  6170. \t\t\t\t\t\t<!-- 4: 施工見積(フェンス・組み立て式) -->
  6171. \t\t\t\t\t\t";
  6172.         // line 4353
  6173.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4353$this->source); })()), "SaleType", [], "any"falsefalsefalse4353), "id", [], "any"falsefalsefalse4353) == 4)) {
  6174.             // line 4354
  6175.             echo "
  6176. \t\t\t\t\t\t\t";
  6177.             // line 4356
  6178.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6179. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">枚数</label>
  6180. \t\t\t\t\t\t\t  <div class=\"col-4 mb-3\">
  6181. \t\t\t\t\t\t\t    <div class=\"input-group\">
  6182. \t\t\t\t\t\t\t      <input type=\"number\" name=\"maisu\" id=\"maisu\" class=\"form-control\" value=\"";
  6183.             // line 4360
  6184.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maisu", [], "any"truetruefalse4360)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maisu", [], "any"falsefalsefalse4360), "3")) : ("3")), "html"nulltrue);
  6185.             echo "\" min=\"3\" max=\"20\" onchange=\"if(parseInt(this.value)<3)this.value=3; mitsumori_simulation('maisu','maisu');\">
  6186. \t\t\t\t\t\t\t      <span class=\"input-group-text\">枚</span>
  6187. \t\t\t\t\t\t\t    </div>
  6188. \t\t\t\t\t\t\t  </div>
  6189. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6190. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"maisu(+1);\">+</button>
  6191. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"maisu(-1);\">ー</button>
  6192. \t\t\t\t\t\t\t  </div>
  6193. \t\t\t\t\t\t\t</div>
  6194. \t\t\t\t\t\t";
  6195.         }
  6196.         // line 4371
  6197.         echo "
  6198. \t\t\t\t\t\t<!-- 5: 施工見積(ウッドデッキ・タイルデッキ) -->
  6199. \t\t\t\t\t\t";
  6200.         // line 4373
  6201.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4373$this->source); })()), "SaleType", [], "any"falsefalsefalse4373), "id", [], "any"falsefalsefalse4373) == 5)) {
  6202.             // line 4374
  6203.             echo "
  6204. \t\t\t\t\t\t\t";
  6205.             // line 4376
  6206.             echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6207. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">ステップ</div>
  6208. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6209. \t\t\t\t\t\t\t    ";
  6210.             // line 4379
  6211.             $context["step_yes_checked"] = (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4379$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse4379)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4379$this->source); })()), "deck_step", [], "any"falsefalsefalse4379) == "必要"));
  6212.             // line 4380
  6213.             echo "\t\t\t\t\t\t\t    ";
  6214.             $context["step_no_checked"] = ((( !(isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4380$this->source); })()) ||  !twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse4380)) || (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4380$this->source); })()), "deck_step", [], "any"falsefalsefalse4380) == "不要")) ||  !twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4380$this->source); })()), "deck_step", [], "any"falsefalsefalse4380));
  6215.             // line 4381
  6216.             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6217.             if ((isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'4381$this->source); })())) {
  6218.                 echo " is-selected";
  6219.             }
  6220.             echo "\"
  6221. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_yes');\">
  6222. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_yes\" value=\"必要\"
  6223. \t\t\t\t\t\t\t             ";
  6224.             // line 4384
  6225.             if ((isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'4384$this->source); })())) {
  6226.                 echo "checked";
  6227.             }
  6228.             echo ">
  6229. \t\t\t\t\t\t\t      必要
  6230. \t\t\t\t\t\t\t    </label>
  6231. \t\t\t\t\t\t\t    <label class=\"opt-btn";
  6232.             // line 4387
  6233.             if ((isset($context["step_no_checked"]) || array_key_exists("step_no_checked"$context) ? $context["step_no_checked"] : (function () { throw new RuntimeError('Variable "step_no_checked" does not exist.'4387$this->source); })())) {
  6234.                 echo " is-selected";
  6235.             }
  6236.             echo "\"
  6237. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_no');\">
  6238. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_no\" value=\"不要\"
  6239. \t\t\t\t\t\t\t             ";
  6240.             // line 4390
  6241.             if ((isset($context["step_no_checked"]) || array_key_exists("step_no_checked"$context) ? $context["step_no_checked"] : (function () { throw new RuntimeError('Variable "step_no_checked" does not exist.'4390$this->source); })())) {
  6242.                 echo "checked";
  6243.             }
  6244.             echo ">
  6245. \t\t\t\t\t\t\t      不要
  6246. \t\t\t\t\t\t\t    </label>
  6247. \t\t\t\t\t\t\t  </div>
  6248. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-step\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  6249.             // line 4394
  6250.             if ( !(isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'4394$this->source); })())) {
  6251.                 echo "display:none;";
  6252.             }
  6253.             echo "\">
  6254. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  6255. \t\t\t\t\t\t\t  </div>
  6256. \t\t\t\t\t\t\t</div>
  6257. \t\t\t\t\t\t\t";
  6258.             // line 4400
  6259.             echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6260. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">デッキフェンス</div>
  6261. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6262. \t\t\t\t\t\t\t    ";
  6263.             // line 4403
  6264.             $context["fence_yes_checked"] = (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4403$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse4403)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4403$this->source); })()), "deck_fence", [], "any"falsefalsefalse4403) == "必要"));
  6265.             // line 4404
  6266.             echo "\t\t\t\t\t\t\t    ";
  6267.             $context["fence_no_checked"] = ((( !(isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4404$this->source); })()) ||  !twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse4404)) || (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4404$this->source); })()), "deck_fence", [], "any"falsefalsefalse4404) == "不要")) ||  !twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4404$this->source); })()), "deck_fence", [], "any"falsefalsefalse4404));
  6268.             // line 4405
  6269.             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6270.             if ((isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'4405$this->source); })())) {
  6271.                 echo " is-selected";
  6272.             }
  6273.             echo "\"
  6274. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_yes');\">
  6275. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_yes\" value=\"必要\"
  6276. \t\t\t\t\t\t\t             ";
  6277.             // line 4408
  6278.             if ((isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'4408$this->source); })())) {
  6279.                 echo "checked";
  6280.             }
  6281.             echo ">
  6282. \t\t\t\t\t\t\t      必要
  6283. \t\t\t\t\t\t\t    </label>
  6284. \t\t\t\t\t\t\t    <label class=\"opt-btn";
  6285.             // line 4411
  6286.             if ((isset($context["fence_no_checked"]) || array_key_exists("fence_no_checked"$context) ? $context["fence_no_checked"] : (function () { throw new RuntimeError('Variable "fence_no_checked" does not exist.'4411$this->source); })())) {
  6287.                 echo " is-selected";
  6288.             }
  6289.             echo "\"
  6290. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_no');\">
  6291. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_no\" value=\"不要\"
  6292. \t\t\t\t\t\t\t             ";
  6293.             // line 4414
  6294.             if ((isset($context["fence_no_checked"]) || array_key_exists("fence_no_checked"$context) ? $context["fence_no_checked"] : (function () { throw new RuntimeError('Variable "fence_no_checked" does not exist.'4414$this->source); })())) {
  6295.                 echo "checked";
  6296.             }
  6297.             echo ">
  6298. \t\t\t\t\t\t\t      不要
  6299. \t\t\t\t\t\t\t    </label>
  6300. \t\t\t\t\t\t\t  </div>
  6301. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-fence\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  6302.             // line 4418
  6303.             if ( !(isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'4418$this->source); })())) {
  6304.                 echo "display:none;";
  6305.             }
  6306.             echo "\">
  6307. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  6308. \t\t\t\t\t\t\t  </div>
  6309. \t\t\t\t\t\t\t</div>
  6310. \t\t\t\t\t\t";
  6311.         }
  6312.         // line 4424
  6313.         echo "
  6314. \t\t\t\t\t\t<!-- 6: 施工見積(芝生・枚数・数量買い) -->
  6315. \t\t\t\t\t\t";
  6316.         // line 4426
  6317.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4426$this->source); })()), "SaleType", [], "any"falsefalsefalse4426), "id", [], "any"falsefalsefalse4426) == 6)) {
  6318.             // line 4427
  6319.             echo "
  6320. \t\t\t\t\t\t\t";
  6321.             // line 4429
  6322.             echo "\t\t\t\t\t\t\t";
  6323.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4429$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4429$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4429$this->source); })())) != ""))) {
  6324.                 // line 4430
  6325.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6326. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">規格";
  6327.                 // line 4431
  6328.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4431$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4431$this->source); })()), "pm", [], "any"falsefalsefalse4431))) {
  6329.                     echo ": <span>";
  6330.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4431$this->source); })()), "pm", [], "any"falsefalsefalse4431), "html"nulltrue);
  6331.                     echo "</span>";
  6332.                 }
  6333.                 echo "</div>
  6334. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6335. \t\t\t\t\t\t\t    ";
  6336.                 // line 4433
  6337.                 $context["idx"] = 0;
  6338.                 // line 4434
  6339.                 echo "\t\t\t\t\t\t\t    ";
  6340.                 $context['_parent'] = $context;
  6341.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4434$this->source); })()));
  6342.                 foreach ($context['_seq'] as $context["_key"] => $context["pm_val"]) {
  6343.                     if ($context["pm_val"]) {
  6344.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4434$this->source); })()) + 1);
  6345.                         // line 4435
  6346.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  6347.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4435$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4435$this->source); })()), "pm", [], "any"falsefalsefalse4435) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4435$this->source); })())) == 1))) {
  6348.                             echo " is-selected";
  6349.                         }
  6350.                         echo "\"
  6351. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm6_";
  6352.                         // line 4436
  6353.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4436$this->source); })()), "html"nulltrue);
  6354.                         echo "');\">
  6355. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm6_";
  6356.                         // line 4437
  6357.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4437$this->source); })()), "html"nulltrue);
  6358.                         echo "\" value=\"";
  6359.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  6360.                         echo "\"
  6361. \t\t\t\t\t\t\t               ";
  6362.                         // line 4438
  6363.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4438$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4438$this->source); })()), "pm", [], "any"falsefalsefalse4438) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4438$this->source); })())) == 1))) {
  6364.                             echo "checked";
  6365.                         }
  6366.                         echo ">
  6367. \t\t\t\t\t\t\t        ";
  6368.                         // line 4439
  6369.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  6370.                         echo "
  6371. \t\t\t\t\t\t\t      </label>
  6372. \t\t\t\t\t\t\t    ";
  6373.                     }
  6374.                 }
  6375.                 $_parent $context['_parent'];
  6376.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm_val'], $context['_parent'], $context['loop']);
  6377.                 $context array_intersect_key($context$_parent) + $_parent;
  6378.                 // line 4442
  6379.                 echo "\t\t\t\t\t\t\t  </div>
  6380. \t\t\t\t\t\t\t</div>
  6381. \t\t\t\t\t\t\t";
  6382.             }
  6383.             // line 4445
  6384.             echo "
  6385. \t\t\t\t\t\t\t";
  6386.             // line 4448
  6387.             echo "\t\t\t\t\t\t\t";
  6388.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4448$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4448$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4448$this->source); })())) != ""))) {
  6389.                 // line 4449
  6390.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6391. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">芝の幅";
  6392.                 // line 4450
  6393.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4450$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4450$this->source); })()), "pw", [], "any"falsefalsefalse4450))) {
  6394.                     echo ": <span>";
  6395.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4450$this->source); })()), "pw", [], "any"falsefalsefalse4450), "html"nulltrue);
  6396.                     echo "</span>";
  6397.                 }
  6398.                 echo "</div>
  6399. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6400. \t\t\t\t\t\t\t    ";
  6401.                 // line 4452
  6402.                 $context["idx"] = 0;
  6403.                 // line 4453
  6404.                 echo "\t\t\t\t\t\t\t    ";
  6405.                 $context['_parent'] = $context;
  6406.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4453$this->source); })()));
  6407.                 foreach ($context['_seq'] as $context["_key"] => $context["pw_val"]) {
  6408.                     if ($context["pw_val"]) {
  6409.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4453$this->source); })()) + 1);
  6410.                         // line 4454
  6411.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  6412.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4454$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4454$this->source); })()), "pw", [], "any"falsefalsefalse4454) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4454$this->source); })())) == 1))) {
  6413.                             echo " is-selected";
  6414.                         }
  6415.                         echo "\"
  6416. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw6_";
  6417.                         // line 4455
  6418.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4455$this->source); })()), "html"nulltrue);
  6419.                         echo "');\">
  6420. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw6_";
  6421.                         // line 4456
  6422.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4456$this->source); })()), "html"nulltrue);
  6423.                         echo "\" value=\"";
  6424.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  6425.                         echo "\"
  6426. \t\t\t\t\t\t\t               ";
  6427.                         // line 4457
  6428.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4457$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4457$this->source); })()), "pw", [], "any"falsefalsefalse4457) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4457$this->source); })())) == 1))) {
  6429.                             echo "checked";
  6430.                         }
  6431.                         echo ">
  6432. \t\t\t\t\t\t\t        ";
  6433.                         // line 4458
  6434.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  6435.                         echo "
  6436. \t\t\t\t\t\t\t      </label>
  6437. \t\t\t\t\t\t\t    ";
  6438.                     }
  6439.                 }
  6440.                 $_parent $context['_parent'];
  6441.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw_val'], $context['_parent'], $context['loop']);
  6442.                 $context array_intersect_key($context$_parent) + $_parent;
  6443.                 // line 4461
  6444.                 echo "\t\t\t\t\t\t\t  </div>
  6445. \t\t\t\t\t\t\t</div>
  6446. \t\t\t\t\t\t\t";
  6447.             }
  6448.             // line 4464
  6449.             echo "
  6450. \t\t\t\t\t\t\t";
  6451.             // line 4466
  6452.             echo "\t\t\t\t\t\t\t";
  6453.             $context["_roll_h"] = (((array_key_exists("p_h"$context) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4466$this->source); })())))) ? (twig_first($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4466$this->source); })()))) : (""));
  6454.             // line 4467
  6455.             echo "\t\t\t\t\t\t\t";
  6456.             if ((isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4467$this->source); })())) {
  6457.                 // line 4468
  6458.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6459. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">1ロールの長さ:<span style=\"font-weight:bold;\">";
  6460.                 // line 4469
  6461.                 if (twig_in_filter("cm", (isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4469$this->source); })()))) {
  6462.                     echo twig_escape_filter($this->env, (twig_trim_filter(twig_replace_filter((isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4469$this->source); })()), ["cm" => """," => ""])) / 100), "html"nulltrue);
  6463.                     echo "m";
  6464.                 } else {
  6465.                     echo twig_escape_filter($this->env, (isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4469$this->source); })()), "html"nulltrue);
  6466.                 }
  6467.                 echo "</span></div>
  6468. \t\t\t\t\t\t\t</div>
  6469. \t\t\t\t\t\t\t";
  6470.             }
  6471.             // line 4472
  6472.             echo "
  6473. \t\t\t\t\t\t\t";
  6474.             // line 4475
  6475.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6476. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">施工サイズ</label>
  6477. \t\t\t\t\t\t\t  <div class=\"col-8\">
  6478. \t\t\t\t\t\t\t    <div class=\"input-group\">
  6479. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_len\" id=\"tf_len\"
  6480. \t\t\t\t\t\t\t        class=\"form-control\"
  6481. \t\t\t\t\t\t\t        value=\"";
  6482.             // line 4481
  6483.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_len", [], "any"truetruefalse4481)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_len", [], "any"falsefalsefalse4481), "")) : ("")), "html"nulltrue);
  6484.             echo "\"
  6485. \t\t\t\t\t\t\t        placeholder=\"縦\" min=\"0.1\" step=\"0.1\"
  6486. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_len','tf_len');\">
  6487. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m&nbsp;×</span>
  6488. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_wid\" id=\"tf_wid\"
  6489. \t\t\t\t\t\t\t        class=\"form-control\"
  6490. \t\t\t\t\t\t\t        value=\"";
  6491.             // line 4487
  6492.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_wid", [], "any"truetruefalse4487)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_wid", [], "any"falsefalsefalse4487), "")) : ("")), "html"nulltrue);
  6493.             echo "\"
  6494. \t\t\t\t\t\t\t        placeholder=\"横\" min=\"0.1\" step=\"0.1\"
  6495. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_wid','tf_wid');\">
  6496. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m</span>
  6497. \t\t\t\t\t\t\t    </div>
  6498. \t\t\t\t\t\t\t    ";
  6499.             // line 4493
  6500.             echo "\t\t\t\t\t\t\t    <input type=\"hidden\" name=\"area\" id=\"area\" value=\"";
  6501.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "area", [], "any"truetruefalse4493)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "area", [], "any"falsefalsefalse4493), "")) : ("")), "html"nulltrue);
  6502.             echo "\">
  6503. \t\t\t\t\t\t\t    ";
  6504.             // line 4496
  6505.             echo "\t\t\t\t\t\t\t    <div style=\"margin-top:10px;display:inline-block;background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:8px 14px;font-size:16px;color:#c00;font-weight:bold;\">
  6506. \t\t\t\t\t\t\t      必要枚数:<input type=\"number\" name=\"tf_qty\" id=\"tf_qty\"
  6507. \t\t\t\t\t\t\t        value=\"";
  6508.             // line 4498
  6509.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_qty", [], "any"truetruefalse4498)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_qty", [], "any"falsefalsefalse4498), "1")) : ("1")), "html"nulltrue);
  6510.             echo "\" min=\"1\" step=\"1\"
  6511. \t\t\t\t\t\t\t        style=\"width:80px;font-size:22px;font-weight:bold;color:#c00;text-align:right;border:1px solid #ffe69c;border-radius:4px;padding:2px 6px;\"
  6512. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_qty','tf_qty');\"> 枚
  6513. \t\t\t\t\t\t\t    </div>
  6514. \t\t\t\t\t\t\t    <div style=\"margin-top:6px;font-size:12px;color:#666;\">※ 施工サイズを入力すると必要枚数を自動計算します。サイズが分からない場合は枚数を直接ご指定ください。</div>
  6515. \t\t\t\t\t\t\t  </div>
  6516. \t\t\t\t\t\t\t</div>
  6517. \t\t\t\t\t\t";
  6518.         }
  6519.         // line 4507
  6520.         echo "
  6521. \t\t\t\t\t\t<!-- 7: 施工見積(数量買い・基本工事費固定) -->
  6522. \t\t\t\t\t\t";
  6523.         // line 4509
  6524.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4509$this->source); })()), "SaleType", [], "any"falsefalsefalse4509), "id", [], "any"falsefalsefalse4509) == 7)) {
  6525.             // line 4510
  6526.             echo "\t\t\t\t\t\t\t";
  6527.             // line 4511
  6528.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6529. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">個数</label>
  6530. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6531. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6532. \t\t\t\t\t\t\t      <input type=\"number\" name=\"suuryou\" id=\"suuryou\" class=\"form-control\"
  6533. \t\t\t\t\t\t\t        value=\"";
  6534.             // line 4516
  6535.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "suuryou", [], "any"truetruefalse4516)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "suuryou", [], "any"falsefalsefalse4516), "1")) : ("1")), "html"nulltrue);
  6536.             echo "\" min=\"1\" max=\"100\"
  6537. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('suuryou','suuryou');\">
  6538. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  6539. \t\t\t\t\t\t\t    </div>
  6540. \t\t\t\t\t\t\t  </div>
  6541. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6542. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"suuryou(+1);\">+</button>
  6543. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"suuryou(-1);\">ー</button>
  6544. \t\t\t\t\t\t\t  </div>
  6545. \t\t\t\t\t\t\t</div>
  6546. \t\t\t\t\t\t";
  6547.         }
  6548.         // line 4527
  6549.         echo "
  6550. \t\t\t\t\t\t<!-- 9: 商品のみ購入 -->
  6551. \t\t\t\t\t\t";
  6552.         // line 4529
  6553.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4529$this->source); })()), "SaleType", [], "any"falsefalsefalse4529), "id", [], "any"falsefalsefalse4529) == 9)) {
  6554.             // line 4530
  6555.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6556. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">数量</label>
  6557. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6558. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6559. \t\t\t\t\t\t\t      <input type=\"number\" name=\"quantity_only\" id=\"quantity_only\" class=\"form-control\" value=\"1\" min=\"1\" onchange=\"\$('#quantity').val(this.value);\">
  6560. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  6561. \t\t\t\t\t\t\t    </div>
  6562. \t\t\t\t\t\t\t  </div>
  6563. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6564. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"quantityOnly(+1);\">+</button>
  6565. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"quantityOnly(-1);\">ー</button>
  6566. \t\t\t\t\t\t\t  </div>
  6567. \t\t\t\t\t\t\t</div>
  6568. \t\t\t\t\t\t";
  6569.         }
  6570.         // line 4544
  6571.         echo "
  6572. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">取り付け工事のご希望に関してお答えください。</label></div>
  6573. \t\t\t\t\t\t";
  6574.         // line 4552
  6575.         echo "\t\t\t\t\t\t";
  6576.         $context["is_gs"] = false;
  6577.         // line 4553
  6578.         echo "\t\t\t\t\t\t";
  6579.         $context["is_cg"] = false;
  6580.         // line 4554
  6581.         echo "\t\t\t\t\t\t";
  6582.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4554$this->source); })()), "ProductCategories", [], "any"falsefalsefalse4554))) {
  6583.             // line 4555
  6584.             echo "\t\t\t\t\t\t\t";
  6585.             $context['_parent'] = $context;
  6586.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4555$this->source); })()), "ProductCategories", [], "any"falsefalsefalse4555));
  6587.             foreach ($context['_seq'] as $context["_key"] => $context["ProductCategory"]) {
  6588.                 // line 4556
  6589.                 echo "\t\t\t\t\t\t\t\t";
  6590.                 if ((twig_get_attribute($this->env$this->source$context["ProductCategory"], "category_id", [], "any"falsefalsefalse4556) == 27)) {
  6591.                     $context["is_gs"] = true;
  6592.                 }
  6593.                 // line 4557
  6594.                 echo "\t\t\t\t\t\t\t\t";
  6595.                 if ((twig_get_attribute($this->env$this->source$context["ProductCategory"], "category_id", [], "any"falsefalsefalse4557) == 9)) {
  6596.                     $context["is_cg"] = true;
  6597.                 }
  6598.                 // line 4558
  6599.                 echo "\t\t\t\t\t\t\t";
  6600.             }
  6601.             $_parent $context['_parent'];
  6602.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductCategory'], $context['_parent'], $context['loop']);
  6603.             $context array_intersect_key($context$_parent) + $_parent;
  6604.             // line 4559
  6605.             echo "\t\t\t\t\t\t";
  6606.         }
  6607.         // line 4560
  6608.         echo "\t\t\t\t\t\t";
  6609.         $context['_parent'] = $context;
  6610.         $context['_seq'] = twig_ensure_traversable(range(010));
  6611.         foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
  6612.             // line 4561
  6613.             echo "\t\t\t\t\t\t\t";
  6614.             if (((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4561$this->source); })()) && (twig_length_filter($this->env, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4561$this->source); })())) >= ($context["i"] + 1)))) {
  6615.                 // line 4562
  6616.                 echo "\t\t\t\t\t\t\t";
  6617.                 if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4562$this->source); })()), $context["i"], [], "array"falsefalsefalse4562), "name", [], "array"falsefalsefalse4562)) {
  6618.                     // line 4563
  6619.                     echo "\t\t\t\t\t\t\t";
  6620.                     $context["hide_opt"] = false;
  6621.                     // line 4564
  6622.                     echo "\t\t\t\t\t\t\t";
  6623.                     if (((isset($context["is_gs"]) || array_key_exists("is_gs"$context) ? $context["is_gs"] : (function () { throw new RuntimeError('Variable "is_gs" does not exist.'4564$this->source); })()) && (preg_match("/撤去/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4564$this->source); })()), $context["i"], [], "array"falsefalsefalse4564), "name", [], "array"falsefalsefalse4564)) || preg_match("/残土/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4564$this->source); })()), $context["i"], [], "array"falsefalsefalse4564), "name", [], "array"falsefalsefalse4564))))) {
  6624.                         // line 4565
  6625.                         echo "\t\t\t\t\t\t\t\t";
  6626.                         $context["hide_opt"] = true;
  6627.                         // line 4566
  6628.                         echo "\t\t\t\t\t\t\t";
  6629.                     }
  6630.                     // line 4567
  6631.                     echo "\t\t\t\t\t\t\t";
  6632.                     if (((isset($context["is_cg"]) || array_key_exists("is_cg"$context) ? $context["is_cg"] : (function () { throw new RuntimeError('Variable "is_cg" does not exist.'4567$this->source); })()) && preg_match("/残土/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4567$this->source); })()), $context["i"], [], "array"falsefalsefalse4567), "name", [], "array"falsefalsefalse4567)))) {
  6633.                         // line 4568
  6634.                         echo "\t\t\t\t\t\t\t\t";
  6635.                         $context["hide_opt"] = true;
  6636.                         // line 4569
  6637.                         echo "\t\t\t\t\t\t\t";
  6638.                     }
  6639.                     // line 4570
  6640.                     echo "\t\t\t\t\t\t\t";
  6641.                     if ( !(isset($context["hide_opt"]) || array_key_exists("hide_opt"$context) ? $context["hide_opt"] : (function () { throw new RuntimeError('Variable "hide_opt" does not exist.'4570$this->source); })())) {
  6642.                         // line 4571
  6643.                         echo "\t\t\t\t\t\t\t";
  6644.                         // line 4573
  6645.                         echo "\t\t\t\t\t\t\t";
  6646.                         $context["is_removal_unknown"] = (((((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4573), "price", [], "array"truetruefalse4573)) ? (_twig_default_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4573), "price", [], "array"falsefalsefalse4573), 0)) : (0)) == 0) || (((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4573), "price", [], "array"truetruefalse4573)) ? (_twig_default_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4573), "price", [], "array"falsefalsefalse4573), "0")) : ("0")) == "0")) && ((preg_match("/解体/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source,                         // line 4574
  6647. (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4574$this->source); })()), $context["i"], [], "array"falsefalsefalse4574), "name", [], "array"falsefalsefalse4574)) || preg_match("/撤去/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4574$this->source); })()), $context["i"], [], "array"falsefalsefalse4574), "name", [], "array"falsefalsefalse4574))) || preg_match("/設置場所/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4574$this->source); })()), $context["i"], [], "array"falsefalsefalse4574), "name", [], "array"falsefalsefalse4574))));
  6648.                         // line 4575
  6649.                         echo "\t\t\t\t\t\t\t";
  6650.                         // line 4576
  6651.                         echo "\t\t\t\t\t\t\t";
  6652.                         $context["is_tf_kouji"] = ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4576$this->source); })()), "SaleType", [], "any"falsefalsefalse4576), "id", [], "any"falsefalsefalse4576) == 6) && preg_match("/取り付け工事/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4576$this->source); })()), $context["i"], [], "array"falsefalsefalse4576), "name", [], "array"falsefalsefalse4576)));
  6653.                         // line 4577
  6654.                         echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" data-op-idx=\"";
  6655.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6656.                         echo "\" data-op-name=\"";
  6657.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4577$this->source); })()), $context["i"], [], "array"falsefalsefalse4577), "name", [], "array"falsefalsefalse4577), "html_attr");
  6658.                         echo "\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6659. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">";
  6660.                         // line 4579
  6661.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4579$this->source); })()), $context["i"], [], "array"falsefalsefalse4579), "name", [], "array"falsefalsefalse4579), "html"nulltrue);
  6662.                         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4579$this->source); })()) && twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4579$this->source); })()), "op", [], "any"falsefalsefalse4579), $context["i"], [], "array"falsefalsefalse4579))) {
  6663.                             echo ": <span>";
  6664.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4579$this->source); })()), "op", [], "any"falsefalsefalse4579), $context["i"], [], "array"falsefalsefalse4579), "html"nulltrue);
  6665.                             echo "</span>";
  6666.                         }
  6667.                         echo "</div>
  6668. \t\t\t\t\t\t\t  ";
  6669.                         // line 4580
  6670.                         if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4580$this->source); })()), $context["i"], [], "array"falsefalsefalse4580), "comment", [], "array"falsefalsefalse4580)) {
  6671.                             echo "<div class=\"opt-comment\" style=\"font-size:12px;color:#666;margin:4px 0 6px;\">";
  6672.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4580$this->source); })()), $context["i"], [], "array"falsefalsefalse4580), "comment", [], "array"falsefalsefalse4580), "html"nulltrue);
  6673.                             echo "</div>";
  6674.                         }
  6675.                         // line 4581
  6676.                         echo "\t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6677. \t\t\t\t\t\t\t    ";
  6678.                         // line 4584
  6679.                         echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6680.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4584$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4584$this->source); })()), "op", [], "any"falsefalsefalse4584), $context["i"], [], "array"falsefalsefalse4584) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4584$this->source); })()), $context["i"], [], "array"falsefalsefalse4584), "on", [], "array"falsefalsefalse4584))) ||  !twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4584$this->source); })()), $context["i"], [], "array"falsefalsefalse4584), "off", [], "array"falsefalsefalse4584))) {
  6681.                             echo " is-selected";
  6682.                         }
  6683.                         echo "\"
  6684. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op";
  6685.                         // line 4585
  6686.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6687.                         echo "','op";
  6688.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6689.                         echo "_1');\">
  6690. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op";
  6691.                         // line 4586
  6692.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6693.                         echo "\" id=\"op";
  6694.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6695.                         echo "_1\" value=\"";
  6696.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4586$this->source); })()), $context["i"], [], "array"falsefalsefalse4586), "on", [], "array"falsefalsefalse4586), "html"nulltrue);
  6697.                         echo "\" ";
  6698.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4586$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4586$this->source); })()), "op", [], "any"falsefalsefalse4586), $context["i"], [], "array"falsefalsefalse4586) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4586$this->source); })()), $context["i"], [], "array"falsefalsefalse4586), "on", [], "array"falsefalsefalse4586))) ||  !twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4586$this->source); })()), $context["i"], [], "array"falsefalsefalse4586), "off", [], "array"falsefalsefalse4586))) {
  6699.                             echo "checked";
  6700.                         }
  6701.                         echo ">
  6702. \t\t\t\t\t\t\t      ";
  6703.                         // line 4587
  6704.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4587$this->source); })()), $context["i"], [], "array"falsefalsefalse4587), "on", [], "array"falsefalsefalse4587), "html"nulltrue);
  6705.                         echo "
  6706. \t\t\t\t\t\t\t    </label>
  6707. \t\t\t\t\t\t\t    ";
  6708.                         // line 4589
  6709.                         if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4589$this->source); })()), $context["i"], [], "array"falsefalsefalse4589), "off", [], "array"falsefalsefalse4589)) {
  6710.                             // line 4590
  6711.                             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6712.                             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4590$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4590$this->source); })()), "op", [], "any"falsefalsefalse4590), $context["i"], [], "array"falsefalsefalse4590) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4590$this->source); })()), $context["i"], [], "array"falsefalsefalse4590), "off", [], "array"falsefalsefalse4590)))) {
  6713.                                 echo " is-selected";
  6714.                             }
  6715.                             echo "\"
  6716. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op";
  6717.                             // line 4591
  6718.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6719.                             echo "','op";
  6720.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6721.                             echo "_2');\">
  6722. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op";
  6723.                             // line 4592
  6724.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6725.                             echo "\" id=\"op";
  6726.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6727.                             echo "_2\" value=\"";
  6728.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4592$this->source); })()), $context["i"], [], "array"falsefalsefalse4592), "off", [], "array"falsefalsefalse4592), "html"nulltrue);
  6729.                             echo "\" ";
  6730.                             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4592$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4592$this->source); })()), "op", [], "any"falsefalsefalse4592), $context["i"], [], "array"falsefalsefalse4592) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4592$this->source); })()), $context["i"], [], "array"falsefalsefalse4592), "off", [], "array"falsefalsefalse4592)))) {
  6731.                                 echo "checked";
  6732.                             }
  6733.                             echo ">
  6734. \t\t\t\t\t\t\t      ";
  6735.                             // line 4593
  6736.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4593$this->source); })()), $context["i"], [], "array"falsefalsefalse4593), "off", [], "array"falsefalsefalse4593), "html"nulltrue);
  6737.                             echo "
  6738. \t\t\t\t\t\t\t    </label>
  6739. \t\t\t\t\t\t\t    ";
  6740.                         }
  6741.                         // line 4596
  6742.                         echo "\t\t\t\t\t\t\t  </div>
  6743. \t\t\t\t\t\t\t  ";
  6744.                         // line 4597
  6745.                         if (((isset($context["is_removal_unknown"]) || array_key_exists("is_removal_unknown"$context) ? $context["is_removal_unknown"] : (function () { throw new RuntimeError('Variable "is_removal_unknown" does not exist.'4597$this->source); })()) || (isset($context["is_tf_kouji"]) || array_key_exists("is_tf_kouji"$context) ? $context["is_tf_kouji"] : (function () { throw new RuntimeError('Variable "is_tf_kouji" does not exist.'4597$this->source); })()))) {
  6746.                             // line 4598
  6747.                             echo "\t\t\t\t\t\t\t  <div class=\"opt-survey-note\" data-op-idx=\"";
  6748.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6749.                             echo "\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  6750.                             if ( !((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4598$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4598$this->source); })()), "op", [], "any"falsefalsefalse4598), $context["i"], [], "array"falsefalsefalse4598) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4598$this->source); })()), $context["i"], [], "array"falsefalsefalse4598), "on", [], "array"falsefalsefalse4598)))) {
  6751.                                 echo "display:none;";
  6752.                             }
  6753.                             echo "\">
  6754. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  6755. \t\t\t\t\t\t\t  </div>
  6756. \t\t\t\t\t\t\t  ";
  6757.                         }
  6758.                         // line 4602
  6759.                         echo "\t\t\t\t\t\t\t</div>
  6760. \t\t\t\t\t\t\t";
  6761.                     }
  6762.                     // line 4604
  6763.                     echo "\t\t\t\t\t\t\t";
  6764.                 }
  6765.                 // line 4605
  6766.                 echo "\t\t\t\t\t\t\t";
  6767.             }
  6768.             // line 4606
  6769.             echo "\t\t\t\t\t\t";
  6770.         }
  6771.         $_parent $context['_parent'];
  6772.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['i'], $context['_parent'], $context['loop']);
  6773.         $context array_intersect_key($context$_parent) + $_parent;
  6774.         // line 4607
  6775.         echo "
  6776. \t\t\t\t\t\t";
  6777.         // line 4611
  6778.         echo "\t\t\t\t\t\t";
  6779.         if ((((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4611$this->source); })()), "SaleType", [], "any"falsefalsefalse4611), "id", [], "any"falsefalsefalse4611) == 4) && (isset($context["oi"]) || array_key_exists("oi"$context) ? $context["oi"] : (function () { throw new RuntimeError('Variable "oi" does not exist.'4611$this->source); })())) && twig_get_attribute($this->env$this->source, (isset($context["oi"]) || array_key_exists("oi"$context) ? $context["oi"] : (function () { throw new RuntimeError('Variable "oi" does not exist.'4611$this->source); })()), "fe_block", [], "any"falsefalsefalse4611))) {
  6780.             // line 4612
  6781.             echo "\t\t\t\t\t\t<div id=\"fe-block-options\" class=\"form-group mt-3 pb-3\" style=\"display:none;border-bottom:1px solid rgba(0,0,0,.125)\"></div>
  6782. \t\t\t\t\t\t";
  6783.         }
  6784.         // line 4614
  6785.         echo "
  6786. \t\t\t\t\t\t";
  6787.         // line 4617
  6788.         echo "\t\t\t\t\t\t<div id=\"tg-options\" class=\"tg-options-container col-12\"></div>
  6789. \t\t\t\t\t  </div>
  6790. \t\t\t\t\t  <!-- /.card-body -->
  6791. \t\t\t\t\t</div>
  6792.                     <form action=\"";
  6793.         // line 4624
  6794.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_cart", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4624$this->source); })()), "id", [], "any"falsefalsefalse4624)]), "html"nulltrue);
  6795.         echo "\" method=\"post\" id=\"form1\" name=\"form1\">
  6796.                         ";
  6797.         // line 4625
  6798.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4625$this->source); })()), "stock_find", [], "any"falsefalsefalse4625)) {
  6799.             // line 4626
  6800.             echo "                            <div class=\"ec-productRole__actions\">
  6801.                                 ";
  6802.             // line 4627
  6803.             if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse4627)) {
  6804.                 // line 4628
  6805.                 echo "                                    <div class=\"ec-select\">
  6806.                                         ";
  6807.                 // line 4629
  6808.                 echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4629$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse4629), 'row');
  6809.                 echo "
  6810.                                         ";
  6811.                 // line 4630
  6812.                 echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4630$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse4630), 'errors');
  6813.                 echo "
  6814.                                     </div>
  6815.                                     ";
  6816.                 // line 4632
  6817.                 if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse4632)) {
  6818.                     // line 4633
  6819.                     echo "                                        <div class=\"ec-select\">
  6820.                                             ";
  6821.                     // line 4634
  6822.                     echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4634$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse4634), 'row');
  6823.                     echo "
  6824.                                             ";
  6825.                     // line 4635
  6826.                     echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4635$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse4635), 'errors');
  6827.                     echo "
  6828.                                         </div>
  6829.                                     ";
  6830.                 }
  6831.                 // line 4638
  6832.                 echo "                                ";
  6833.             }
  6834.             // line 4639
  6835.             echo "                                <div class=\"ec-numberInput\">
  6836.                                     ";
  6837.             // line 4640
  6838.             echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4640$this->source); })()), "quantity", [], "any"falsefalsefalse4640), 'widget', ["type" => "hidden"]);
  6839.             echo "
  6840.                                     ";
  6841.             // line 4641
  6842.             echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4641$this->source); })()), "quantity", [], "any"falsefalsefalse4641), 'errors');
  6843.             echo "
  6844.                                 </div>
  6845.                             </div>
  6846.                         ";
  6847.         } else {
  6848.             // line 4646
  6849.             echo "                            <div class=\"ec-productRole__btn\">
  6850.                                 <button type=\"button\" class=\"ec-blockBtn--action\" disabled=\"disabled\">
  6851.                                     ";
  6852.             // line 4648
  6853.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("ただいま品切れ中です。"), "html"nulltrue);
  6854.             echo "
  6855.                                 </button>
  6856.                             </div>
  6857.                         ";
  6858.         }
  6859.         // line 4652
  6860.         echo "                        <div class=\"ec-productRole__btn mt-3\">
  6861.                            <button type=\"submit\" id=\"cart_btn\" class=\"ec-blockBtn--action add-cart\">カートに入れる</button>
  6862.                         </div>
  6863.                         ";
  6864.         // line 4655
  6865.         echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock((isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4655$this->source); })()), 'rest');
  6866.         echo "
  6867.                     </form>
  6868.                     <div class=\"ec-modal add-cart-modal\">
  6869.                         <div class=\"ec-modal-overlay\">
  6870.                             <div class=\"ec-modal-wrap add-cart-modal__wrap\">
  6871.                                 <span class=\"ec-modal-close\"><span class=\"ec-icon\"><img src=\"";
  6872.         // line 4660
  6873.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("assets/icon/cross-dark.svg"), "html"nulltrue);
  6874.         echo "\" alt=\"\"/></span></span>
  6875.                                 <div id=\"ec-modal-header\" class=\"text-center add-cart-modal__header\">";
  6876.         // line 4661
  6877.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートに追加しました。"), "html"nulltrue);
  6878.         echo "</div>
  6879.                                 <div class=\"ec-modal-box add-cart-modal__box\">
  6880.                                     <div class=\"ec-role add-cart-modal__actions\">
  6881.                                         <a href=\"";
  6882.         // line 4664
  6883.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("cart");
  6884.         echo "\" class=\"ec-inlineBtn--action add-cart-modal__primary\">";
  6885.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートに進む"), "html"nulltrue);
  6886.         echo "</a>
  6887.                                         <span class=\"ec-inlineBtn--cancel add-cart-modal__secondary\">";
  6888.         // line 4665
  6889.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("商品検索を続ける"), "html"nulltrue);
  6890.         echo "</span>
  6891.                                     </div>
  6892.                                 </div>
  6893.                             </div>
  6894.                         </div>
  6895.                     </div>
  6896.                     <div class=\"ec-productRole__description\">";
  6897.         // line 4671
  6898.         echo twig_nl2br(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4671$this->source); })()), "description_detail", [], "any"falsefalsefalse4671));
  6899.         echo "
  6900.                     </div>
  6901.                     ";
  6902.         // line 4675
  6903.         echo "                    <div class=\"ec-productRole__share\">
  6904.                         <ul class=\"ec-share\">
  6905.                             <li class=\"ec-share__item\">
  6906.                                 <a href=\"https://twitter.com/share?url=";
  6907.         // line 4678
  6908.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4678$this->source); })()), "request", [], "any"falsefalsefalse4678), "uri", [], "any"falsefalsefalse4678)), "html"nulltrue);
  6909.         echo "&text=";
  6910.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4678$this->source); })()), "name", [], "any"falsefalsefalse4678)), "html"nulltrue);
  6911.         echo "\" class=\"ec-share__link ec-share__link--twitter\" target=\"_blank\" rel=\"noreferrer noopener\">
  6912.                                     <i class=\"fab fa-twitter\"></i>
  6913.                                 </a>
  6914.                             </li>
  6915.                             <li class=\"ec-share__item\">
  6916.                                 <a href=\"https://www.facebook.com/sharer/sharer.php?u=";
  6917.         // line 4683
  6918.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4683$this->source); })()), "request", [], "any"falsefalsefalse4683), "uri", [], "any"falsefalsefalse4683)), "html"nulltrue);
  6919.         echo "\" class=\"ec-share__link ec-share__link--facebook\" target=\"_blank\" rel=\"noreferrer noopener\">
  6920.                                     <i class=\"fab fa-facebook-f\"></i>
  6921.                                 </a>
  6922.                             </li>
  6923.                             <li class=\"ec-share__item\">
  6924.                                 <a href=\"https://social-plugins.line.me/lineit/share?url=";
  6925.         // line 4688
  6926.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4688$this->source); })()), "request", [], "any"falsefalsefalse4688), "uri", [], "any"falsefalsefalse4688)), "html"nulltrue);
  6927.         echo "\" class=\"ec-share__link ec-share__link--line\" target=\"_blank\" rel=\"noreferrer noopener\">
  6928.                                     <i class=\"fab fa-line\"></i>
  6929.                                 </a>
  6930.                             </li>
  6931.                         </ul>
  6932.                     </div>
  6933.                 </div>
  6934. \t\t\t\t";
  6935.         // line 4696
  6936.         echo "\t\t\t\t<div id=\"sp-mitsumori-bar\">
  6937. \t\t\t\t    <div class=\"sp-bar__pricewrap\">
  6938. \t\t\t\t        <div class=\"sp-bar__label\">合計(工事費・税抜)</div>
  6939. \t\t\t\t        <div class=\"sp-bar__price\" id=\"sp-mitsumori-price\">---円</div>
  6940. \t\t\t\t    </div>
  6941. \t\t\t\t    <button type=\"button\" class=\"sp-bar__detail-btn\"
  6942. \t\t\t\t            onclick=\"openSpMitsumoriDetail();\" title=\"お見積りの詳細(内訳)を表示\">
  6943. \t\t\t\t        <i class=\"far fa-file-alt\"></i>
  6944. \t\t\t\t        <span>詳細</span>
  6945. \t\t\t\t    </button>
  6946. \t\t\t\t    <button type=\"button\" class=\"sp-bar__btn\"
  6947. \t\t\t\t            onclick=\"document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">
  6948. \t\t\t\t        <i class=\"fas fa-shopping-cart\"></i>
  6949. \t\t\t\t        <span class=\"sp-bar__btn-label\">カートへ</span>
  6950. \t\t\t\t        ";
  6951.         // line 4710
  6952.         $context["spTotalQty"] = $this->extensions['Eccube\Twig\Extension\CartServiceExtension']->get_carts_total_quantity();
  6953.         // line 4711
  6954.         echo "\t\t\t\t        ";
  6955.         if (((isset($context["spTotalQty"]) || array_key_exists("spTotalQty"$context) ? $context["spTotalQty"] : (function () { throw new RuntimeError('Variable "spTotalQty" does not exist.'4711$this->source); })()) > 0)) {
  6956.             // line 4712
  6957.             echo "\t\t\t\t            <span class=\"sp-bar__cart-badge\">";
  6958.             echo twig_escape_filter($this->envtwig_number_format_filter($this->env, (isset($context["spTotalQty"]) || array_key_exists("spTotalQty"$context) ? $context["spTotalQty"] : (function () { throw new RuntimeError('Variable "spTotalQty" does not exist.'4712$this->source); })())), "html"nulltrue);
  6959.             echo "</span>
  6960. \t\t\t\t        ";
  6961.         }
  6962.         // line 4714
  6963.         echo "\t\t\t\t    </button>
  6964. \t\t\t\t    <a href=\"";
  6965.         // line 4715
  6966.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("homepage");
  6967.         echo "\" class=\"sp-bar__home-btn\" title=\"トップページへ\">
  6968. \t\t\t\t        <i class=\"fas fa-home\"></i>
  6969. \t\t\t\t    </a>
  6970. \t\t\t\t</div>
  6971. \t\t\t\t";
  6972.         // line 4721
  6973.         echo "\t\t\t\t";
  6974.         // line 4723
  6975.         echo "\t\t\t\t<div id=\"sp-mitsumori-detail\" class=\"sp-detail-sheet\" aria-hidden=\"true\">
  6976. \t\t\t\t    <div class=\"sp-detail-sheet__overlay\" onclick=\"closeSpMitsumoriDetail();\"></div>
  6977. \t\t\t\t    <div class=\"sp-detail-sheet__panel\" role=\"dialog\" aria-label=\"お見積りの詳細\">
  6978. \t\t\t\t        <div class=\"sp-detail-sheet__header\">
  6979. \t\t\t\t            <span class=\"sp-detail-sheet__title\">お見積りの詳細</span>
  6980. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__close\" onclick=\"closeSpMitsumoriDetail();\" aria-label=\"閉じる\">&times;</button>
  6981. \t\t\t\t        </div>
  6982. \t\t\t\t        <div class=\"sp-detail-sheet__body\" id=\"sp-detail-body\"></div>
  6983. \t\t\t\t        <div class=\"sp-detail-sheet__footer\">
  6984. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__invoice\"
  6985. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('mitsumori_btn') && document.getElementById('mitsumori_btn').click();\">見積書を表示</button>
  6986. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__cart\"
  6987. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">カートに入れる</button>
  6988. \t\t\t\t        </div>
  6989. \t\t\t\t    </div>
  6990. \t\t\t\t</div>
  6991. \t\t\t\t<div class=\"card col-12 collapsed-card sticky-top float-right mitsumori-card-pc\">
  6992. \t\t\t\t\t<div class=\"card-header\">
  6993. \t\t\t\t\t  <h3 class=\"card-title\">現在のお見積り額</h3>
  6994. \t\t\t\t\t  <div class=\"card-tools\">
  6995. \t\t\t\t\t    <span class=\"float-left\" id=\"mitsumori_message\">";
  6996.         // line 4744
  6997.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_goukei", [], "any"truetruefalse4744)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_goukei", [], "any"falsefalsefalse4744), "---円")) : ("---円")), "html"nulltrue);
  6998.         echo "</span>
  6999. \t\t\t\t\t    <button type=\"button\" class=\"btn btn-tool btn-mitsumori-toggle\" data-card-widget=\"collapse\" title=\"詳細を表示\">
  7000. \t\t\t\t\t      <span class=\"toggle-icon\">▼ 詳細</span>
  7001. \t\t\t\t\t    </button>
  7002. \t\t\t\t\t  </div>
  7003. \t\t\t\t\t</div>
  7004. \t\t\t\t\t<div class=\"card-body p-0\">
  7005. \t\t\t\t\t  <ul class=\"nav nav-pills flex-column\">
  7006. \t\t\t\t\t    <li class=\"nav-item active\">
  7007. \t\t\t\t\t      <a class=\"nav-link\">
  7008. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 合計(工事費・税抜)
  7009. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_goukei\">";
  7010.         // line 4755
  7011.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_goukei", [], "any"truetruefalse4755)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_goukei", [], "any"falsefalsefalse4755), "---円")) : ("---円")), "html"nulltrue);
  7012.         echo "</span>
  7013. \t\t\t\t\t      </a>
  7014. \t\t\t\t\t    </li>
  7015. \t\t\t\t\t    <li class=\"nav-item active\">
  7016. \t\t\t\t\t      <a class=\"nav-link\">
  7017. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 商品価格
  7018. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_price\">";
  7019.         // line 4761
  7020.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_price", [], "any"truetruefalse4761)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_price", [], "any"falsefalsefalse4761), "---円")) : ("---円")), "html"nulltrue);
  7021.         echo "</span>
  7022. \t\t\t\t\t      </a>
  7023. \t\t\t\t\t    </li>
  7024. \t\t\t\t\t    ";
  7025.         // line 4765
  7026.         echo "\t\t\t\t\t    ";
  7027.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4765$this->source); })()), "SaleType", [], "any"falsefalsefalse4765), "id", [], "any"falsefalsefalse4765) != 2)) {
  7028.             // line 4766
  7029.             echo "\t\t\t\t\t    <li class=\"nav-item\">
  7030. \t\t\t\t\t      <a class=\"nav-link\">
  7031. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> カタログ価格
  7032. \t\t\t\t\t        <span class=\"float-right\" id=\"maker_price\">";
  7033.             // line 4769
  7034.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maker_price", [], "any"truetruefalse4769)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maker_price", [], "any"falsefalsefalse4769), "---円")) : ("---円")), "html"nulltrue);
  7035.             echo "</span>
  7036. \t\t\t\t\t      </a>
  7037. \t\t\t\t\t    </li>
  7038. \t\t\t\t\t    ";
  7039.         } else {
  7040.             // line 4773
  7041.             echo "\t\t\t\t\t    ";
  7042.             // line 4774
  7043.             echo "\t\t\t\t\t    <span id=\"maker_price\" style=\"display:none;\">---円</span>
  7044. \t\t\t\t\t    ";
  7045.         }
  7046.         // line 4776
  7047.         echo "\t\t\t\t\t    <li class=\"nav-item\">
  7048. \t\t\t\t\t      <a class=\"nav-link\">
  7049. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i>
  7050. \t\t\t\t\t        ";
  7051.         // line 4779
  7052.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4779$this->source); })()), "SaleType", [], "any"falsefalsefalse4779), "id", [], "any"falsefalsefalse4779) == 2)) {
  7053.             echo "補助金(割引額)";
  7054.         } else {
  7055.             echo "お値引き";
  7056.         }
  7057.         // line 4780
  7058.         echo "\t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_off\">";
  7059.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_off", [], "any"truetruefalse4780)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_off", [], "any"falsefalsefalse4780), "---円")) : ("---円")), "html"nulltrue);
  7060.         echo "</span>
  7061. \t\t\t\t\t      </a>
  7062. \t\t\t\t\t    </li>
  7063. \t\t\t\t\t    ";
  7064.         // line 4784
  7065.         echo "\t\t\t\t\t    ";
  7066.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4784$this->source); })()), "SaleType", [], "any"falsefalsefalse4784), "id", [], "any"falsefalsefalse4784) == 2)) {
  7067.             // line 4785
  7068.             echo "\t\t\t\t\t    <li class=\"nav-item\">
  7069. \t\t\t\t\t      <div style=\"padding:4px 12px 8px;color:#6c757d;font-size:11px;line-height:1.4;\">
  7070. \t\t\t\t\t        ※当店が補助金事業者として申請代行し、契約代金に充当します
  7071. \t\t\t\t\t      </div>
  7072. \t\t\t\t\t    </li>
  7073. \t\t\t\t\t    ";
  7074.         }
  7075.         // line 4791
  7076.         echo "\t\t\t\t\t    <li class=\"nav-item\">
  7077. \t\t\t\t\t      <a class=\"nav-link\">
  7078. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 基本工事費
  7079. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_ct\">";
  7080.         // line 4794
  7081.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_ct", [], "any"truetruefalse4794)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_ct", [], "any"falsefalsefalse4794), "---円")) : ("---円")), "html"nulltrue);
  7082.         echo "</span>
  7083. \t\t\t\t\t      </a>
  7084. \t\t\t\t\t    </li>
  7085. \t\t\t\t\t     ";
  7086.         // line 4798
  7087.         echo "\t\t\t\t\t     <li class=\"nav-item\" id=\"mitsumori_steelroof_row\" style=\"display:none;\">
  7088. \t\t\t\t\t       <a class=\"nav-link\">
  7089. \t\t\t\t\t         &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> スチール折板
  7090. \t\t\t\t\t         <span class=\"float-right\" id=\"mitsumori_steelroof\">";
  7091.         // line 4801
  7092.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_steelroof", [], "any"truetruefalse4801)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_steelroof", [], "any"falsefalsefalse4801), "---円")) : ("---円")), "html"nulltrue);
  7093.         echo "</span>
  7094. \t\t\t\t\t       </a>
  7095. \t\t\t\t\t     </li>
  7096. \t\t\t\t\t    <li class=\"nav-item\">
  7097. \t\t\t\t\t      <a class=\"nav-link\">
  7098. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 施工オプション
  7099. \t\t\t\t\t        <span class=\"float-right\"id=\"mitsumori_option\">";
  7100.         // line 4807
  7101.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_option", [], "any"truetruefalse4807)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_option", [], "any"falsefalsefalse4807), "---円")) : ("---円")), "html"nulltrue);
  7102.         echo "</span>
  7103. \t\t\t\t\t      </a>
  7104. \t\t\t\t\t    </li>
  7105. \t\t\t\t\t  </ul>
  7106. \t\t\t\t\t</div>
  7107. \t\t\t\t\t<div class=\"card-footer\">
  7108. \t\t                <button type=\"button\" id=\"mitsumori_btn\" class=\"btn btn-info\" data-toggle=\"modal\" data-target=\"#modal-mitsumori\">
  7109. \t\t                  見積書表示
  7110. \t\t                </button>
  7111.                         <button type=\"submit\" id=\"cart_btn2\" class=\"btn btn-info add-cart\">カートに入れる</button>
  7112. \t\t\t\t\t</div>
  7113. \t\t\t\t</div>
  7114.             </div>
  7115.         </div>
  7116.     </div>
  7117.   <div class=\"modal\" id=\"modal-mitsumori\">
  7118.     <div class=\"modal-dialog modal-mitsumori\" style=\"max-width:1000px\">
  7119.       <div class=\"modal-content\">
  7120.         <div class=\"modal-header\">
  7121.           <h4 class=\"modal-title\">お見積書</h4>
  7122.           <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">
  7123.             <span aria-hidden=\"true\">&times;</span>
  7124.           </button>
  7125.         </div>
  7126.         <div class=\"modal-body\">
  7127. \t\t\t<div class=\"invoice p-3 mb-5\" style=\"max-width:1000px; margin:auto;\">
  7128. \t\t\t  <!-- title row -->
  7129. \t\t\t  <div class=\"row\">
  7130. \t\t\t    <div class=\"col-12\">
  7131. \t\t\t      <h2>概算お見積書 
  7132. \t\t\t        <small class=\"float-right\" style=\"font-size:14px;\">発行日: <span id=\"mitsumori_issue_date\">---</span></small>
  7133. \t\t\t      </h2>
  7134. \t\t\t    </div>
  7135. \t\t\t    <!-- /.col -->
  7136. \t\t\t  </div>
  7137. \t\t\t  <!-- info row -->
  7138. \t\t\t  <div class=\"row invoice-info\">
  7139. \t\t\t    <div class=\"col-sm-8 invoice-col\">
  7140. \t\t\t      <h3>お客様</h3>
  7141. \t\t\t      <span>下記の通り、お見積もり申し上げます。</span>
  7142. \t\t\t      <br />
  7143. \t\t\t      <br / >
  7144. \t\t\t      <br />
  7145. \t\t\t      <h2>お見積金額: <span id=\"mitsumori_kei\">";
  7146.         // line 4854
  7147.         echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_goukei", [], "any"truetruefalse4854)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "mitsumori_goukei", [], "any"falsefalsefalse4854), "---円")) : ("---円")), "html"nulltrue);
  7148.         echo "</span></h2>
  7149. \t\t\t      <span>
  7150. \t\t\t        <br/>
  7151. \t\t\t        <br/>
  7152. \t\t\t        <br/>
  7153. \t\t\t        <br/>
  7154. \t\t\t      </span>
  7155. \t\t\t    </div>
  7156. \t\t\t    <div class=\"col-sm-4 invoice-col\">
  7157. \t\t\t      <p>
  7158. \t\t\t        <img alt=\"\" src=\"/html/user_data/js/images/logo.png\" style=\"width: 260px; max-width: 100%; max-height: 10mm;\">
  7159. \t\t\t      </p>
  7160. \t\t\t      <p>有限会社プラス</p>
  7161. \t\t\t      <p>〒400-0334</p>
  7162. \t\t\t      <p>山梨県南アルプス市藤田1450番地2</p>
  7163. \t\t\t      <p>TEL: 055-284-6480</p>
  7164. \t\t\t      <img alt=\"\" src=\"/html/user_data/js/images/seal.svg\" style=\"z-index: 2; position: absolute; width: 21mm; left: 58mm; top: 36mm;\">
  7165. \t\t\t    </div>
  7166. \t\t\t    <!-- /.col -->
  7167. \t\t\t    <!-- /.col -->
  7168. \t\t\t  </div>
  7169. \t\t\t  <!-- /.row -->
  7170. \t\t\t  <!-- Table row -->
  7171. \t\t\t  <div class=\"row\">
  7172. \t\t\t    <div class=\"col-12 table-responsive\">
  7173. \t\t\t      <table class=\"table table-striped\">
  7174. \t\t\t        <thead>
  7175. \t\t\t          <tr>
  7176. \t\t\t            <th>項目</th>
  7177. \t\t\t            <th>数量</th>
  7178. \t\t\t            <th>単位</th>
  7179. \t\t\t            <th>単価</th>
  7180. \t\t\t            <th>小計</th>
  7181. \t\t\t          </tr>
  7182. \t\t\t        </thead>
  7183. \t\t\t        <tbody>
  7184. \t\t\t          <tr>
  7185. \t\t\t            <td id=\"mitsumori_item_name\">";
  7186.         // line 4891
  7187.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4891$this->source); })()), "name", [], "any"falsefalsefalse4891), "html"nulltrue);
  7188.         echo "</td>
  7189. \t\t\t            <td>1</td>
  7190. \t\t\t            <td>式</td>
  7191. \t\t\t            <td id=\"mitsumori_price_01\">---</td>
  7192. \t\t\t            <td id=\"mitsumori_price_02\">---</td>
  7193. \t\t\t          </tr>
  7194. \t\t\t          <tr>
  7195. \t\t\t            <td>基本工事費</td>
  7196. \t\t\t            <td>1</td>
  7197. \t\t\t            <td>式</td>
  7198. \t\t\t            <td id=\"mitsumori_ct_01\">---</td>
  7199. \t\t\t            <td id=\"mitsumori_ct_02\">---</td>
  7200. \t\t\t          </tr>
  7201. \t\t\t          <tr>
  7202. \t\t\t            <td>残土・ガラ処理</td>
  7203. \t\t\t            <td>1</td>
  7204. \t\t\t            <td>式</td>
  7205. \t\t\t            <td>0円</td>
  7206. \t\t\t            <td></td>
  7207. \t\t\t          </tr>
  7208. \t\t\t          <tr>
  7209. \t\t\t            <td> </td>
  7210. \t\t\t            <td></td>
  7211. \t\t\t            <td></td>
  7212. \t\t\t            <td></td>
  7213. \t\t\t            <td></td>
  7214. \t\t\t          </tr>
  7215. \t\t\t        </tbody>
  7216. \t\t\t      </table>
  7217. \t\t\t    </div>
  7218. \t\t\t    <!-- /.col -->
  7219. \t\t\t  </div>
  7220. \t\t\t  <!-- /.row -->
  7221. \t\t\t  <div class=\"row\">
  7222. \t\t\t    <!-- accepted payments column -->
  7223. \t\t\t    <div class=\"col-6\">
  7224. \t\t\t      <p class=\"lead\">お支払い方法</p>
  7225. \t\t\t      <p class=\"text-muted well well-sm shadow-none\" style=\"margin-top: 10px;\">銀行振込、クレジットカード決済、PAYPAY決済
  7226. \t\t\t        <br>銀行振込:山梨中央銀行 白根支店 普通口座 391402
  7227. \t\t\t        <br>※商品代金と工事代金の総額が金100万円(税込)を超える場合、着手金として代金の半額をご契約後お支払いいただきます。 
  7228. \t\t\t      </p>
  7229. \t\t\t    </div>
  7230. \t\t\t    <!-- /.col -->
  7231. \t\t\t    <div class=\"col-6\">
  7232. \t\t\t      <div class=\"table-responsive\">
  7233. \t\t\t        <table class=\"table\">
  7234. \t\t\t          <tbody>
  7235. \t\t\t            <tr>
  7236. \t\t\t              <th style=\"width:50%\">小計:</th>
  7237. \t\t\t              <td id=\"mitsumori_shoukei\">---</td>
  7238. \t\t\t            </tr>
  7239. \t\t\t            <tr>
  7240. \t\t\t              <th>消費税 (10%)</th>
  7241. \t\t\t              <td id=\"mitsumori_tax\">---</td>
  7242. \t\t\t            </tr>
  7243. \t\t\t            <tr>
  7244. \t\t\t              <th>合計:</th>
  7245. \t\t\t              <td id=\"mitsumori_goukei_02\">---</td>
  7246. \t\t\t            </tr>
  7247. \t\t\t          </tbody>
  7248. \t\t\t        </table>
  7249. \t\t\t      </div>
  7250. \t\t\t    </div>
  7251. \t\t\t    <!-- /.col -->
  7252. \t\t\t  </div>
  7253. \t\t\t  <!-- /.row -->
  7254. \t\t\t</div>
  7255.         </div>
  7256.         <div class=\"modal-footer justify-content-between\">
  7257. \t\t\t      ";
  7258.         // line 4961
  7259.         echo "\t\t\t      <form method=\"post\" action=\"";
  7260.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("mitsumori_pdf");
  7261.         echo "\" target=\"_blank\" id=\"pdf_download_form\">
  7262. \t\t\t        <input type=\"hidden\" name=\"_token\" value=\"";
  7263.         // line 4962
  7264.         echo twig_escape_filter($this->env$this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderCsrfToken("mitsumori_pdf"), "html"nulltrue);
  7265.         echo "\">
  7266. \t\t\t        <input type=\"hidden\" name=\"mitsumori_json\" id=\"pdf_mitsumori_json\">
  7267. \t\t\t        <button type=\"submit\" class=\"btn btn-primary float-right\" style=\"margin-right: 5px;\" onclick=\"syncPdfJson();\">
  7268. \t\t\t          <i class=\"fas fa-download\"></i>PDF出力
  7269. \t\t\t        </button>
  7270. \t\t\t      </form>
  7271.                   <button type=\"submit\" id=\"cart_btn3\" class=\"btn btn-info add-cart\">カートに入れる</button>
  7272.         </div>
  7273.       </div>
  7274.       <!-- /.modal-content -->
  7275.     </div>
  7276.     <!-- /.modal-dialog -->
  7277.   </div>
  7278.   <!-- /.modal -->
  7279.     <!-- Image zoom modal: custom lightweight lightbox (no CDN dependency) -->
  7280.     <div id=\"img-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"画像拡大\">
  7281.         <button id=\"img-modal__close\" aria-label=\"閉じる\">&times;</button>
  7282.         <button id=\"img-modal__prev\" aria-label=\"前の画像\">&#10094;</button>
  7283.         <img id=\"img-modal__img\" src=\"\" alt=\"\">
  7284.         <button id=\"img-modal__next\" aria-label=\"次の画像\">&#10095;</button>
  7285.     </div>
  7286.     <style>
  7287.     #img-modal {
  7288.         display: none;
  7289.         position: fixed;
  7290.         inset: 0;
  7291.         z-index: 9999;
  7292.         background: rgba(0,0,0,0.88);
  7293.         align-items: center;
  7294.         justify-content: center;
  7295.         cursor: zoom-out;
  7296.     }
  7297.     #img-modal.is-open { display: flex; }
  7298.     #img-modal__img {
  7299.         max-width: 92vw;
  7300.         max-height: 88vh;
  7301.         object-fit: contain;
  7302.         border-radius: 4px;
  7303.         cursor: default;
  7304.         user-select: none;
  7305.         touch-action: pinch-zoom;
  7306.         display: block;
  7307.     }
  7308.     #img-modal__close {
  7309.         position: absolute;
  7310.         top: 14px;
  7311.         right: 18px;
  7312.         font-size: 38px;
  7313.         color: #fff;
  7314.         cursor: pointer;
  7315.         background: none;
  7316.         border: none;
  7317.         padding: 0;
  7318.         line-height: 1;
  7319.         z-index: 1;
  7320.         opacity: 0.85;
  7321.     }
  7322.     #img-modal__close:hover { opacity: 1; }
  7323.     #img-modal__prev,
  7324.     #img-modal__next {
  7325.         position: absolute;
  7326.         top: 50%;
  7327.         transform: translateY(-50%);
  7328.         font-size: 36px;
  7329.         color: #fff;
  7330.         cursor: pointer;
  7331.         background: rgba(0,0,0,0.32);
  7332.         border: none;
  7333.         padding: 10px 16px;
  7334.         line-height: 1;
  7335.         border-radius: 6px;
  7336.         z-index: 1;
  7337.         opacity: 0.8;
  7338.         user-select: none;
  7339.     }
  7340.     #img-modal__prev:hover, #img-modal__next:hover { opacity: 1; }
  7341.     #img-modal__prev { left: 12px; }
  7342.     #img-modal__next { right: 12px; }
  7343.     @media (max-width: 767px) {
  7344.         #img-modal__prev, #img-modal__next { font-size: 28px; padding: 8px 12px; }
  7345.     }
  7346.     </style>
  7347.     <script>
  7348.     (function(){
  7349.         var images = [];
  7350.         var current = 0;
  7351.         // Collect original (non-cloned) slide images at click time.
  7352.         // After Slick init, slides are wrapped in .slick-slide; clones have .slick-cloned.
  7353.         function collectImages() {
  7354.             images = [];
  7355.             var \$slides = \$('.item_visual .slick-slide:not(.slick-cloned)');
  7356.             if (!\$slides.length) {
  7357.                 // Slick not yet initialized (fallback)
  7358.                 \$slides = \$('.item_visual .slide-item');
  7359.             }
  7360.             \$slides.each(function() {
  7361.                 var \$a = \$(this).find('a.js-zoom');
  7362.                 if (\$a.length) {
  7363.                     images.push({ src: \$a.attr('href'), alt: \$a.find('img').attr('alt') || '' });
  7364.                 }
  7365.             });
  7366.         }
  7367.         function showImage(idx) {
  7368.             current = ((idx % images.length) + images.length) % images.length;
  7369.             \$('#img-modal__img').attr({ src: images[current].src, alt: images[current].alt });
  7370.         }
  7371.         function openModal(href) {
  7372.             collectImages();
  7373.             if (!images.length) return;
  7374.             var idx = 0;
  7375.             for (var i = 0; i < images.length; i++) {
  7376.                 if (images[i].src === href) { idx = i; break; }
  7377.             }
  7378.             showImage(idx);
  7379.             \$('#img-modal').addClass('is-open');
  7380.             \$('body').css('overflow', 'hidden');
  7381.         }
  7382.         function closeModal() {
  7383.             \$('#img-modal').removeClass('is-open');
  7384.             \$('body').css('overflow', '');
  7385.         }
  7386.         // Click handler: works for both original and Slick-cloned anchors
  7387.         \$(document).on('click', '.item_visual a.js-zoom', function(e) {
  7388.             e.preventDefault();
  7389.             openModal(\$(this).attr('href'));
  7390.         });
  7391.         // Close on backdrop click
  7392.         \$('#img-modal').on('click', function(e) {
  7393.             if (e.target === this) closeModal();
  7394.         });
  7395.         \$('#img-modal__close').on('click', closeModal);
  7396.         \$('#img-modal__prev').on('click', function(e) { e.stopPropagation(); showImage(current - 1); });
  7397.         \$('#img-modal__next').on('click', function(e) { e.stopPropagation(); showImage(current + 1); });
  7398.         // Keyboard navigation
  7399.         \$(document).on('keydown', function(e) {
  7400.             if (!\$('#img-modal').hasClass('is-open')) return;
  7401.             if (e.key === 'Escape') closeModal();
  7402.             if (e.key === 'ArrowLeft') showImage(current - 1);
  7403.             if (e.key === 'ArrowRight') showImage(current + 1);
  7404.         });
  7405.         // Touch swipe (horizontal only)
  7406.         var _tx = 0;
  7407.         var \$modal = document.getElementById('img-modal');
  7408.         \$modal.addEventListener('touchstart', function(e) {
  7409.             _tx = e.changedTouches[0].clientX;
  7410.         }, { passive: true });
  7411.         \$modal.addEventListener('touchend', function(e) {
  7412.             var dx = e.changedTouches[0].clientX - _tx;
  7413.             if (Math.abs(dx) > 48) {
  7414.                 dx < 0 ? showImage(current + 1) : showImage(current - 1);
  7415.             }
  7416.         }, { passive: true });
  7417.     })();
  7418.     </script>
  7419. ";
  7420.         
  7421.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  7422.         
  7423.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  7424.     }
  7425.     public function getTemplateName()
  7426.     {
  7427.         return "Product/detail.twig";
  7428.     }
  7429.     public function isTraitable()
  7430.     {
  7431.         return false;
  7432.     }
  7433.     public function getDebugInfo()
  7434.     {
  7435.         return array (  7518 => 4962,  7513 => 4961,  7441 => 4891,  7401 => 4854,  7351 => 4807,  7342 => 4801,  7337 => 4798,  7331 => 4794,  7326 => 4791,  7318 => 4785,  7315 => 4784,  7308 => 4780,  7302 => 4779,  7297 => 4776,  7293 => 4774,  7291 => 4773,  7284 => 4769,  7279 => 4766,  7276 => 4765,  7270 => 4761,  7261 => 4755,  7247 => 4744,  7224 => 4723,  7222 => 4721,  7214 => 4715,  7211 => 4714,  7205 => 4712,  7202 => 4711,  7200 => 4710,  7184 => 4696,  7174 => 4688,  7166 => 4683,  7156 => 4678,  7151 => 4675,  7145 => 4671,  7136 => 4665,  7130 => 4664,  7124 => 4661,  7120 => 4660,  7112 => 4655,  7107 => 4652,  7100 => 4648,  7096 => 4646,  7088 => 4641,  7084 => 4640,  7081 => 4639,  7078 => 4638,  7072 => 4635,  7068 => 4634,  7065 => 4633,  7063 => 4632,  7058 => 4630,  7054 => 4629,  7051 => 4628,  7049 => 4627,  7046 => 4626,  7044 => 4625,  7040 => 4624,  7031 => 4617,  7028 => 4614,  7024 => 4612,  7021 => 4611,  7018 => 4607,  7012 => 4606,  7009 => 4605,  7006 => 4604,  7002 => 4602,  6990 => 4598,  6988 => 4597,  6985 => 4596,  6979 => 4593,  6967 => 4592,  6961 => 4591,  6954 => 4590,  6952 => 4589,  6947 => 4587,  6935 => 4586,  6929 => 4585,  6922 => 4584,  6919 => 4581,  6913 => 4580,  6904 => 4579,  6896 => 4577,  6893 => 4576,  6891 => 4575,  6889 => 4574,  6887 => 4573,  6885 => 4571,  6882 => 4570,  6879 => 4569,  6876 => 4568,  6873 => 4567,  6870 => 4566,  6867 => 4565,  6864 => 4564,  6861 => 4563,  6858 => 4562,  6855 => 4561,  6850 => 4560,  6847 => 4559,  6841 => 4558,  6836 => 4557,  6831 => 4556,  6826 => 4555,  6823 => 4554,  6820 => 4553,  6817 => 4552,  6810 => 4544,  6794 => 4530,  6792 => 4529,  6788 => 4527,  6774 => 4516,  6767 => 4511,  6765 => 4510,  6763 => 4509,  6759 => 4507,  6747 => 4498,  6743 => 4496,  6738 => 4493,  6730 => 4487,  6721 => 4481,  6713 => 4475,  6710 => 4472,  6699 => 4469,  6696 => 4468,  6693 => 4467,  6690 => 4466,  6687 => 4464,  6682 => 4461,  6672 => 4458,  6666 => 4457,  6660 => 4456,  6656 => 4455,  6649 => 4454,  6642 => 4453,  6640 => 4452,  6631 => 4450,  6628 => 4449,  6625 => 4448,  6622 => 4445,  6617 => 4442,  6607 => 4439,  6601 => 4438,  6595 => 4437,  6591 => 4436,  6584 => 4435,  6577 => 4434,  6575 => 4433,  6566 => 4431,  6563 => 4430,  6560 => 4429,  6557 => 4427,  6555 => 4426,  6551 => 4424,  6540 => 4418,  6531 => 4414,  6523 => 4411,  6515 => 4408,  6506 => 4405,  6503 => 4404,  6501 => 4403,  6496 => 4400,  6486 => 4394,  6477 => 4390,  6469 => 4387,  6461 => 4384,  6452 => 4381,  6449 => 4380,  6447 => 4379,  6442 => 4376,  6439 => 4374,  6437 => 4373,  6433 => 4371,  6419 => 4360,  6413 => 4356,  6410 => 4354,  6408 => 4353,  6404 => 4351,  6390 => 4340,  6384 => 4336,  6381 => 4334,  6376 => 4331,  6366 => 4328,  6360 => 4327,  6354 => 4326,  6350 => 4325,  6343 => 4324,  6336 => 4323,  6334 => 4322,  6325 => 4320,  6322 => 4319,  6319 => 4318,  6316 => 4316,  6311 => 4313,  6301 => 4310,  6295 => 4309,  6289 => 4308,  6285 => 4307,  6278 => 4306,  6271 => 4305,  6269 => 4304,  6259 => 4302,  6256 => 4301,  6253 => 4300,  6250 => 4298,  6245 => 4295,  6235 => 4292,  6229 => 4291,  6223 => 4290,  6219 => 4289,  6212 => 4288,  6205 => 4287,  6203 => 4286,  6194 => 4284,  6191 => 4283,  6188 => 4282,  6185 => 4280,  6180 => 4277,  6170 => 4274,  6164 => 4273,  6158 => 4272,  6154 => 4271,  6147 => 4270,  6140 => 4269,  6138 => 4268,  6129 => 4266,  6126 => 4265,  6124 => 4264,  6121 => 4263,  6116 => 4260,  6106 => 4257,  6100 => 4256,  6094 => 4255,  6090 => 4254,  6083 => 4253,  6076 => 4252,  6074 => 4251,  6065 => 4249,  6062 => 4248,  6060 => 4247,  6057 => 4246,  6052 => 4243,  6042 => 4240,  6036 => 4239,  6030 => 4238,  6026 => 4237,  6019 => 4236,  6012 => 4235,  6010 => 4234,  6001 => 4232,  5998 => 4231,  5995 => 4230,  5992 => 4228,  5990 => 4227,  5986 => 4225,  5856 => 4097,  5839 => 4081,  5836 => 4079,  5831 => 4076,  5823 => 4074,  5817 => 4072,  5812 => 4070,  5804 => 4068,  5802 => 4067,  5798 => 4066,  5791 => 4065,  5788 => 4064,  5783 => 4063,  5778 => 4060,  5775 => 4059,  5772 => 4057,  5766 => 4053,  5756 => 4050,  5752 => 4049,  5749 => 4048,  5744 => 4047,  5741 => 4046,  5737 => 4042,  5734 => 4041,  5731 => 4039,  5723 => 4036,  5713 => 4028,  5710 => 4027,  5707 => 4025,  5699 => 4022,  5689 => 4014,  5686 => 4013,  5683 => 4011,  5678 => 4008,  5668 => 4005,  5664 => 4004,  5661 => 4003,  5656 => 4002,  5651 => 3999,  5648 => 3998,  5639 => 3990,  5628 => 3980,  5611 => 3967,  5601 => 3962,  5590 => 3953,  5587 => 3952,  5577 => 3943,  5574 => 3939,  5571 => 3935,  5569 => 3934,  5565 => 3932,  5562 => 3931,  5560 => 3930,  5556 => 3928,  5551 => 3925,  5541 => 3922,  5535 => 3921,  5529 => 3920,  5525 => 3919,  5518 => 3918,  5511 => 3917,  5509 => 3916,  5499 => 3914,  5496 => 3913,  5493 => 3912,  5490 => 3910,  5485 => 3907,  5475 => 3904,  5469 => 3903,  5463 => 3902,  5459 => 3901,  5452 => 3900,  5445 => 3899,  5443 => 3898,  5433 => 3896,  5430 => 3895,  5427 => 3894,  5424 => 3889,  5419 => 3886,  5409 => 3883,  5403 => 3882,  5397 => 3881,  5393 => 3880,  5386 => 3879,  5379 => 3878,  5377 => 3877,  5363 => 3875,  5360 => 3874,  5357 => 3873,  5354 => 3871,  5349 => 3868,  5339 => 3865,  5333 => 3864,  5327 => 3863,  5323 => 3862,  5316 => 3861,  5309 => 3860,  5307 => 3859,  5298 => 3857,  5295 => 3856,  5292 => 3855,  5289 => 3852,  5284 => 3849,  5274 => 3846,  5268 => 3845,  5262 => 3844,  5258 => 3843,  5251 => 3842,  5244 => 3841,  5242 => 3840,  5233 => 3838,  5230 => 3837,  5228 => 3836,  5225 => 3835,  5220 => 3832,  5210 => 3829,  5204 => 3828,  5198 => 3827,  5194 => 3826,  5187 => 3825,  5180 => 3824,  5178 => 3823,  5169 => 3821,  5166 => 3820,  5163 => 3819,  5160 => 3814,  5155 => 3811,  5147 => 3809,  5141 => 3807,  5136 => 3805,  5128 => 3803,  5126 => 3802,  5120 => 3801,  5114 => 3800,  5110 => 3799,  5100 => 3798,  5097 => 3797,  5090 => 3796,  5088 => 3795,  5079 => 3793,  5076 => 3792,  5073 => 3791,  5070 => 3789,  5066 => 3787,  5063 => 3786,  5061 => 3784,  5060 => 3783,  5059 => 3782,  5058 => 3781,  5057 => 3780,  5056 => 3779,  5055 => 3778,  5054 => 3777,  5052 => 3776,  5049 => 3775,  5043 => 3774,  5040 => 3773,  5035 => 3772,  5030 => 3771,  5025 => 3770,  5022 => 3769,  5019 => 3768,  5014 => 3767,  5011 => 3766,  5008 => 3765,  5005 => 3764,  4999 => 3763,  4994 => 3762,  4989 => 3761,  4984 => 3760,  4981 => 3759,  4978 => 3758,  4975 => 3757,  4971 => 3748,  4967 => 3746,  4963 => 3744,  4954 => 3741,  4945 => 3740,  4941 => 3739,  4938 => 3738,  4936 => 3737,  4932 => 3735,  4923 => 3732,  4919 => 3731,  4915 => 3730,  4905 => 3728,  4901 => 3727,  4898 => 3726,  4896 => 3725,  4894 => 3724,  4885 => 3723,  4882 => 3722,  4879 => 3721,  4876 => 3719,  4872 => 3717,  4868 => 3715,  4859 => 3712,  4850 => 3711,  4846 => 3710,  4843 => 3709,  4839 => 3707,  4830 => 3704,  4823 => 3700,  4819 => 3699,  4809 => 3697,  4805 => 3696,  4802 => 3695,  4800 => 3694,  4791 => 3693,  4788 => 3692,  4785 => 3691,  4782 => 3689,  4778 => 3687,  4774 => 3685,  4765 => 3682,  4756 => 3681,  4752 => 3680,  4749 => 3679,  4745 => 3677,  4736 => 3674,  4729 => 3670,  4725 => 3669,  4715 => 3667,  4711 => 3666,  4708 => 3665,  4706 => 3664,  4697 => 3663,  4694 => 3662,  4691 => 3661,  4688 => 3659,  4684 => 3657,  4680 => 3655,  4671 => 3652,  4662 => 3651,  4658 => 3650,  4655 => 3649,  4653 => 3648,  4649 => 3646,  4640 => 3643,  4633 => 3639,  4629 => 3638,  4619 => 3636,  4615 => 3635,  4612 => 3634,  4610 => 3633,  4608 => 3632,  4599 => 3631,  4596 => 3630,  4593 => 3629,  4590 => 3627,  4586 => 3625,  4583 => 3624,  4581 => 3623,  4580 => 3622,  4579 => 3621,  4577 => 3620,  4574 => 3619,  4571 => 3618,  4568 => 3617,  4565 => 3616,  4562 => 3615,  4559 => 3614,  4556 => 3613,  4553 => 3612,  4551 => 3611,  4549 => 3610,  4540 => 3603,  4532 => 3598,  4529 => 3597,  4526 => 3596,  4523 => 3594,  4518 => 3591,  4511 => 3587,  4506 => 3584,  4504 => 3583,  4501 => 3582,  4490 => 3579,  4486 => 3578,  4483 => 3577,  4479 => 3576,  4472 => 3572,  4468 => 3570,  4465 => 3569,  4462 => 3568,  4456 => 3562,  4449 => 3557,  4437 => 3554,  4434 => 3553,  4431 => 3552,  4428 => 3550,  4417 => 3548,  4413 => 3547,  4410 => 3546,  4407 => 3544,  4400 => 3540,  4397 => 3539,  4394 => 3538,  4385 => 3534,  4382 => 3533,  4375 => 3529,  4372 => 3528,  4370 => 3527,  4367 => 3526,  4363 => 3523,  4361 => 3522,  4357 => 3520,  4351 => 3519,  4346 => 3516,  4331 => 3514,  4322 => 3513,  4305 => 3512,  4301 => 3510,  4298 => 3509,  4294 => 3508,  4291 => 3507,  4288 => 3506,  4285 => 3505,  4272 => 3494,  4258 => 3482,  4252 => 3477,  4233 => 3475,  4216 => 3474,  4212 => 3472,  4201 => 3470,  4178 => 3466,  4172 => 3465,  4169 => 3464,  4151 => 3463,  4148 => 3462,  4144 => 3460,  4136 => 3456,  4128 => 3452,  4126 => 3451,  4123 => 3450,  4121 => 3449,  4111 => 3442,  4099 => 3435,  4094 => 3433,  4090 => 3431,  4084 => 3426,  4081 => 3425,  4073 => 3424,  4068 => 3423,  4065 => 3422,  4060 => 3421,  4053 => 3420,  4050 => 3419,  4047 => 3418,  4045 => 3416,  4042 => 3415,  4036 => 3414,  4031 => 3413,  4026 => 3412,  4021 => 3411,  4014 => 3410,  4008 => 3409,  4003 => 3408,  4000 => 3407,  3997 => 3406,  3995 => 3404,  3992 => 3403,  3990 => 3400,  3987 => 3399,  3984 => 3398,  3982 => 3397,  3972 => 3396,  3956 => 3389,  3952 => 3388,  3948 => 3387,  3944 => 3386,  3940 => 3384,  3934 => 3382,  3932 => 3381,  3927 => 3380,  3924 => 3379,  3914 => 3377,  3900 => 3375,  3892 => 3374,  3874 => 3373,  3869 => 3371,  3739 => 3248,  3731 => 3247,  3667 => 3186,  3534 => 3056,  3530 => 3055,  3526 => 3054,  3522 => 3052,  3519 => 3051,  3511 => 3050,  3506 => 3049,  3503 => 3048,  3498 => 3047,  3491 => 3046,  3488 => 3045,  3485 => 3044,  3472 => 3031,  3304 => 2865,  3301 => 2864,  3288 => 2863,  3285 => 2862,  3283 => 2861,  3280 => 2860,  3277 => 2859,  3264 => 2858,  3261 => 2857,  3258 => 2856,  3255 => 2854,  3252 => 2853,  3239 => 2852,  3236 => 2851,  3234 => 2850,  3231 => 2849,  3228 => 2848,  3215 => 2847,  3212 => 2846,  3210 => 2845,  3207 => 2844,  3204 => 2843,  3191 => 2842,  3188 => 2841,  3186 => 2840,  3183 => 2839,  3180 => 2838,  3167 => 2837,  3164 => 2836,  3162 => 2835,  3159 => 2834,  3156 => 2833,  3143 => 2832,  3140 => 2831,  3137 => 2830,  3134 => 2829,  3120 => 2828,  3117 => 2827,  3104 => 2826,  3101 => 2825,  3098 => 2824,  2995 => 2720,  2546 => 2274,  2157 => 1888,  2126 => 1860,  2113 => 1850,  2084 => 1824,  2080 => 1823,  2072 => 1818,  1611 => 1359,  1608 => 1358,  1602 => 1357,  1597 => 1356,  1592 => 1355,  1586 => 1354,  1580 => 1353,  1575 => 1352,  1572 => 1351,  1569 => 1350,  1566 => 1349,  1561 => 1346,  1548 => 1336,  1534 => 1325,  1506 => 1302,  1500 => 1301,  1494 => 1300,  1488 => 1299,  1482 => 1298,  1476 => 1297,  1470 => 1296,  1464 => 1295,  1458 => 1294,  1452 => 1293,  1446 => 1292,  1440 => 1291,  1434 => 1290,  1427 => 1288,  1421 => 1287,  1415 => 1286,  1409 => 1285,  1403 => 1284,  1383 => 1267,  1373 => 1260,  1343 => 1233,  1331 => 1223,  1322 => 1217,  1318 => 1215,  1316 => 1214,  1313 => 1213,  1304 => 1207,  1300 => 1205,  1298 => 1204,  1226 => 1134,  1218 => 1132,  1216 => 1131,  1211 => 1129,  1208 => 1128,  1206 => 1127,  1192 => 1116,  1188 => 1114,  1178 => 1113,  73 => 16,  63 => 15,  52 => 11,  50 => 13,  37 => 11,);
  7436.     }
  7437.     public function getSourceContext()
  7438.     {
  7439.         return new Source("{#
  7440. This file is part of EC-CUBE
  7441. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  7442. http://www.ec-cube.co.jp/
  7443. For the full copyright and license information, please view the LICENSE
  7444. file that was distributed with this source code.
  7445. #}
  7446. {% extends 'default_frame.twig' %}
  7447. {% set body_class = 'product_page' %}
  7448. {% block stylesheet %}
  7449.     <style>
  7450.         .slick-slider {
  7451.             margin-bottom: 10px;
  7452. \t\t\tmargin-top: -20px;
  7453.         }
  7454.         .slick-dots {
  7455.             position: absolute;
  7456.             bottom: -45px;
  7457.             display: block;
  7458.             width: 100%;
  7459.             padding: 0;
  7460.             list-style: none;
  7461.             text-align: center;
  7462.         }
  7463.         .slick-dots li {
  7464.             position: relative;
  7465.             display: inline-block;
  7466.             width: 20px;
  7467.             height: 20px;
  7468.             margin: 0 5px;
  7469.             padding: 0;
  7470.             cursor: pointer;
  7471.         }
  7472.         .slick-dots li button {
  7473.             font-size: 0;
  7474.             line-height: 0;
  7475.             display: block;
  7476.             width: 20px;
  7477.             height: 20px;
  7478.             padding: 5px;
  7479.             cursor: pointer;
  7480.             color: transparent;
  7481.             border: 0;
  7482.             outline: none;
  7483.             background: transparent;
  7484.         }
  7485.         .slick-dots li button:hover,
  7486.         .slick-dots li button:focus {
  7487.             outline: none;
  7488.         }
  7489.         .slick-dots li button:hover:before,
  7490.         .slick-dots li button:focus:before {
  7491.             opacity: 1;
  7492.         }
  7493.         .slick-dots li button:before {
  7494.             content: \" \";
  7495.             line-height: 20px;
  7496.             position: absolute;
  7497.             top: 0;
  7498.             left: 0;
  7499.             width: 12px;
  7500.             height: 12px;
  7501.             text-align: center;
  7502.             opacity: .25;
  7503.             background-color: black;
  7504.             border-radius: 50%;
  7505.         }
  7506.         .slick-dots li.slick-active button:before {
  7507.             opacity: .75;
  7508.             background-color: black;
  7509.         }
  7510.         .slick-dots li button.thumbnail img {
  7511.             width: 0;
  7512.             height: 0;
  7513.         }
  7514.     </style>
  7515.     <link rel=\"stylesheet\" href=\"/html/user_data/js/style.css\">
  7516.     <link rel=\"stylesheet\" href=\"/html/plugins/icheck-bootstrap/icheck-bootstrap.min.css\">
  7517.     <style>
  7518.         /* Show zoom cursor on product images to hint click-to-expand */
  7519.         .item_visual .slide-item a { display: block; cursor: zoom-in; }
  7520.     </style>
  7521.     <style>
  7522.         /* ============================================
  7523.            商品詳細グリッド: 画像50% / 内容50%(均等)
  7524.         ============================================ */
  7525.         @media (min-width: 768px) {
  7526.             body.product_page .ec-grid2 {
  7527.                 display: flex;
  7528.                 align-items: flex-start;
  7529.             }
  7530.             body.product_page .ec-grid2 .ec-grid2__cell {
  7531.                 width: 50%;
  7532.                 flex: 0 0 50%;
  7533.                 min-width: 0;
  7534.             }
  7535.             body.product_page .ec-grid2 .ec-grid2__cell2 {
  7536.                 width: 50%;
  7537.                 flex: 0 0 50%;
  7538.                 min-width: 0;
  7539.             }
  7540.         }
  7541.         /* ============================================
  7542.            商品説明欄内のHTMLが画面幅を突き抜けないように
  7543.         ============================================ */
  7544.         body.product_page .ec-productRole__description {
  7545.             min-width: 0;
  7546.             overflow-wrap: break-word;
  7547.             word-break: break-word;
  7548.         }
  7549.         body.product_page .ec-productRole__description img,
  7550.         body.product_page .ec-productRole__description table,
  7551.         body.product_page .ec-productRole__description iframe,
  7552.         body.product_page .ec-productRole__description video {
  7553.             max-width: 100% !important;
  7554.             height: auto;
  7555.         }
  7556.         body.product_page .ec-productRole__description table {
  7557.             display: block;
  7558.             overflow-x: auto;
  7559.             -webkit-overflow-scrolling: touch;
  7560.         }
  7561.         /* ============================================
  7562.            構成セット内容 (機能門柱など、セット構成を持つ商品)
  7563.         ============================================ */
  7564.         body.product_page .ec-productRole__setItems {
  7565.             min-width: 0;
  7566.             margin-bottom: 16px;
  7567.         }
  7568.         body.product_page .ec-productRole__setItems .set-items-table {
  7569.             width: 100%;
  7570.             border-collapse: collapse;
  7571.             table-layout: fixed;
  7572.         }
  7573.         body.product_page .ec-productRole__setItems .set-items-table th,
  7574.         body.product_page .ec-productRole__setItems .set-items-table td {
  7575.             padding: 8px 4px;
  7576.             border-bottom: 1px solid #e8e8e8;
  7577.             font-size: 14px;
  7578.             font-weight: normal;
  7579.             overflow-wrap: break-word;
  7580.             word-break: break-word;
  7581.             vertical-align: top;
  7582.         }
  7583.         body.product_page .ec-productRole__setItems .set-items-table th {
  7584.             text-align: left;
  7585.         }
  7586.         body.product_page .ec-productRole__setItems .set-items-table td {
  7587.             text-align: right;
  7588.             white-space: nowrap;
  7589.             width: 30%;
  7590.         }
  7591.         body.product_page .ec-productRole__setItems .set-items-table tfoot th,
  7592.         body.product_page .ec-productRole__setItems .set-items-table tfoot td {
  7593.             border-top: 2px solid #333;
  7594.             border-bottom: none;
  7595.             font-weight: bold;
  7596.         }
  7597.         /* ============================================
  7598.            スマホ用 見積金額 下部固定バー
  7599.         ============================================ */
  7600.         #sp-mitsumori-bar {
  7601.             display: none;
  7602.         }
  7603.         /* ============================================
  7604.            スマホ用 お見積りの詳細 ボトムシート
  7605.         ============================================ */
  7606.         .sp-detail-sheet { display: none; }
  7607.         .sp-detail-sheet.is-open {
  7608.             display: block;
  7609.             position: fixed;
  7610.             top: 0; left: 0; right: 0; bottom: 0;
  7611.             z-index: 2000;
  7612.         }
  7613.         .sp-detail-sheet__overlay {
  7614.             position: absolute;
  7615.             top: 0; left: 0; right: 0; bottom: 0;
  7616.             background: rgba(0,0,0,0.45);
  7617.         }
  7618.         .sp-detail-sheet__panel {
  7619.             position: absolute;
  7620.             left: 0; right: 0; bottom: 0;
  7621.             background: #fff;
  7622.             border-radius: 14px 14px 0 0;
  7623.             max-height: 82vh;
  7624.             display: flex;
  7625.             flex-direction: column;
  7626.             box-shadow: 0 -4px 20px rgba(0,0,0,0.25);
  7627.             padding-bottom: env(safe-area-inset-bottom);
  7628.             animation: spSheetUp 0.22s ease-out;
  7629.         }
  7630.         @keyframes spSheetUp {
  7631.             from { transform: translateY(100%); }
  7632.             to   { transform: translateY(0); }
  7633.         }
  7634.         .sp-detail-sheet__header {
  7635.             display: flex;
  7636.             align-items: center;
  7637.             justify-content: space-between;
  7638.             padding: 14px 16px;
  7639.             border-bottom: 1px solid #eee;
  7640.             flex: 0 0 auto;
  7641.         }
  7642.         .sp-detail-sheet__title { font-size: 16px; font-weight: bold; color: #333; }
  7643.         .sp-detail-sheet__close {
  7644.             background: none;
  7645.             border: none;
  7646.             font-size: 26px;
  7647.             line-height: 1;
  7648.             color: #888;
  7649.             cursor: pointer;
  7650.             padding: 0 4px;
  7651.         }
  7652.         .sp-detail-sheet__body {
  7653.             overflow-y: auto;
  7654.             -webkit-overflow-scrolling: touch;
  7655.             padding: 4px 0;
  7656.             flex: 1 1 auto;
  7657.         }
  7658.         .sp-detail-sheet__body ul { list-style: none; margin: 0; padding: 0; }
  7659.         .sp-detail-sheet__body li { border-bottom: 1px solid #f2f2f2; }
  7660.         .sp-detail-sheet__body .nav-link {
  7661.             display: flex;
  7662.             align-items: center;
  7663.             justify-content: space-between;
  7664.             padding: 12px 16px;
  7665.             color: #333;
  7666.             font-size: 14px;
  7667.         }
  7668.         .sp-detail-sheet__body .nav-link .float-right {
  7669.             float: none !important;
  7670.             font-weight: bold;
  7671.             white-space: nowrap;
  7672.             margin-left: auto;
  7673.         }
  7674.         .sp-detail-sheet__footer {
  7675.             display: flex;
  7676.             gap: 8px;
  7677.             padding: 12px 16px 16px;
  7678.             border-top: 1px solid #eee;
  7679.             flex: 0 0 auto;
  7680.         }
  7681.         .sp-detail-sheet__footer button {
  7682.             flex: 1 1 auto;
  7683.             padding: 12px;
  7684.             border-radius: 8px;
  7685.             font-size: 14px;
  7686.             font-weight: bold;
  7687.             cursor: pointer;
  7688.         }
  7689.         .sp-detail-sheet__invoice {
  7690.             background: #fff;
  7691.             border: 1px solid #17a2b8;
  7692.             color: #17a2b8;
  7693.         }
  7694.         .sp-detail-sheet__cart {
  7695.             background: #c00;
  7696.             border: 1px solid #c00;
  7697.             color: #fff;
  7698.         }
  7699.         /* ============================================
  7700.            商品タイプ選択 共通スタイル
  7701.         ============================================ */
  7702.         /* セクションラベル */
  7703.         .rp-section-label {
  7704.             font-size: 14px;
  7705.             font-weight: bold;
  7706.             color: #333;
  7707.             margin-bottom: 10px;
  7708.         }
  7709.         .rp-section-label span {
  7710.             font-weight: normal;
  7711.             color: #c00;
  7712.         }
  7713.         /* ---- 1. 画像付きカード ---- */
  7714.         .rp-card-group {
  7715.             display: flex;
  7716.             flex-wrap: wrap;
  7717.             gap: 8px;
  7718.             margin-bottom: 4px;
  7719.         }
  7720.         .rp-card {
  7721.             position: relative;
  7722.             cursor: pointer;
  7723.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7724.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7725.             /* iOS Safari: prevent the first tap from being consumed as a text
  7726.                selection (\"字だけ青くなる\" = selection highlight) which forced a
  7727.                2nd tap to actually switch the option (#15). */
  7728.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  7729.             -webkit-touch-callout: none;
  7730.             width: 110px;
  7731.             border: 2px solid #ddd;
  7732.             border-radius: 10px;
  7733.             overflow: hidden;
  7734.             transition: border-color 0.2s, box-shadow 0.2s;
  7735.             background: #fff;
  7736.             text-decoration: none;
  7737.             color: #333;
  7738.             display: block;
  7739.         }
  7740.         /* Gate :hover behind real hover-capable pointers. On iOS Safari a
  7741.            :hover rule that changes appearance makes the first tap apply the
  7742.            hover state and suppresses the click, so the option chip needed a
  7743.            second tap to fire its onclick (is-selected + price update). */
  7744.         @media (hover: hover) and (pointer: fine) {
  7745.             .rp-card:hover {
  7746.                 border-color: #999;
  7747.                 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  7748.             }
  7749.         }
  7750.         .rp-card.is-selected {
  7751.             border-color: #1a6fcf;
  7752.             box-shadow: 0 2px 10px rgba(26,111,207,0.25);
  7753.         }
  7754.         /* visually-hidden instead of display:none. A label wrapping a
  7755.            display:none radio fires its tap unreliably on iOS Safari (first tap
  7756.            often ignored -> \"2回タッチ\"). Keeping the input in the layout but
  7757.            invisible makes the first tap register. */
  7758.         .rp-card input[type=\"radio\"] {
  7759.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7760.             margin: 0; pointer-events: none;
  7761.         }
  7762.         .rp-card__image {
  7763.             width: 100%;
  7764.             aspect-ratio: 1 / 1;
  7765.             object-fit: cover;
  7766.             display: block;
  7767.             background: #f5f5f5;
  7768.         }
  7769.         .rp-card__placeholder {
  7770.             width: 100%;
  7771.             aspect-ratio: 1 / 1;
  7772.             background: #f0f0f0;
  7773.             display: flex;
  7774.             align-items: center;
  7775.             justify-content: center;
  7776.             color: #bbb;
  7777.             font-size: 24px;
  7778.         }
  7779.         .rp-card__name {
  7780.             display: block;
  7781.             padding: 5px 5px;
  7782.             font-size: 11px;
  7783.             color: #333;
  7784.             text-align: center;
  7785.             line-height: 1.4;
  7786.             word-break: break-all;
  7787.         }
  7788.         .rp-card.is-selected .rp-card__name { color: #1a6fcf; font-weight: bold; }
  7789.         .rp-card.is-selected::after {
  7790.             content: \"✓\";
  7791.             position: absolute;
  7792.             top: 3px; right: 6px;
  7793.             color: #1a6fcf;
  7794.             font-size: 13px;
  7795.             font-weight: bold;
  7796.         }
  7797.         /* ---- 2. ボタン式ラジオ(画像なし・8個以内)---- */
  7798.         .rp-btn-group {
  7799.             display: flex;
  7800.             flex-wrap: wrap;
  7801.             gap: 8px;
  7802.             margin-bottom: 4px;
  7803.             max-width: 100%;
  7804.             min-width: 0;
  7805.         }
  7806.         .rp-btn {
  7807.             cursor: pointer;
  7808.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7809.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7810.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  7811.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  7812.             -webkit-touch-callout: none;
  7813.             padding: 8px 14px;
  7814.             border: 2px solid #ddd;
  7815.             border-radius: 10px;
  7816.             font-size: 13px;
  7817.             color: #333;
  7818.             background: #fff;
  7819.             transition: border-color 0.2s, background 0.2s;
  7820.             white-space: normal;
  7821.             max-width: 100%;
  7822.             overflow-wrap: anywhere;
  7823.             text-decoration: none;
  7824.         }
  7825.         @media (hover: hover) and (pointer: fine) {
  7826.             .rp-btn:hover { border-color: #999; }
  7827.         }
  7828.         .rp-btn.is-selected {
  7829.             border-color: #1a6fcf;
  7830.             color: #1a6fcf;
  7831.             font-weight: bold;
  7832.             background: #f0f6ff;
  7833.         }
  7834.         .rp-btn input[type=\"radio\"] {
  7835.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7836.             margin: 0; pointer-events: none;
  7837.         }
  7838.         /* iOS Safari \"2回タッチ\" fix for the type-selection link chips.
  7839.            The global theme stylesheet ships an ungated `a:hover{color:#296292}`
  7840.            (paired with `a{color:#337ab7;text-decoration:underline}`). Because
  7841.            .rp-btn / .rp-card are real <a> links, iOS Safari applies that hover
  7842.            colour on the FIRST tap — the chip text turns blue (#296292, the
  7843.            reported \"字だけ青くなる\") — and treats the tap as a hover, swallowing
  7844.            the navigation so a 2nd tap was needed. The local .rp-*:hover rules
  7845.            are already gated behind (hover:hover), but this inherited global
  7846.            rule was not. Pin the hover/active colour to the base/selected colour
  7847.            so tapping produces no visual change and the first tap navigates
  7848.            immediately. Higher specificity (0,2,0 / 0,3,0) overrides a:hover. */
  7849.         .rp-btn:hover,
  7850.         .rp-btn:active { color: #333; text-decoration: none; }
  7851.         .rp-btn.is-selected:hover,
  7852.         .rp-btn.is-selected:active { color: #1a6fcf; text-decoration: none; }
  7853.         .rp-card:hover,
  7854.         .rp-card:active { color: #333; text-decoration: none; }
  7855.         .rp-card:hover .rp-card__name,
  7856.         .rp-card:active .rp-card__name { color: #333; }
  7857.         .rp-card.is-selected:hover .rp-card__name,
  7858.         .rp-card.is-selected:active .rp-card__name { color: #1a6fcf; }
  7859.         /* ---- 選択肢が多い場合: 縦3段に収めて横スクロール(顧客要望「3列くらいで横スクロール」)---- */
  7860.         /* grid-auto-flow:column + 3行固定 → 選択肢が縦に最大3段、超過分は右へ伸び横スクロールで閲覧 */
  7861.         .rp-btn-group.is-scroll,
  7862.         .opt-btn-group.is-scroll {
  7863.             display: grid;
  7864.             grid-auto-flow: column;
  7865.             grid-template-rows: repeat(3, auto);
  7866.             grid-auto-columns: max-content;
  7867.             justify-content: start;
  7868.             align-items: start;
  7869.             gap: 8px;
  7870.             overflow-x: auto;
  7871.             overflow-y: hidden;
  7872.             -webkit-overflow-scrolling: touch;
  7873.             scrollbar-width: thin;
  7874.             /* 上下に余白を確保して、行の枠線が overflow クリップ/スクロールバーに
  7875.                切り取られないようにする(「文字列が長いと下枠が消える」対策)。 */
  7876.             padding: 2px 0 12px;
  7877.         }
  7878.         /* is-scroll(横スクロール)内では選択肢を折り返さず単一行に固定する。
  7879.            折り返すと行高が不揃いになり overflow-y:hidden で下枠が切れるため、
  7880.            長い選択肢は折り返さず横スクロールで見せる(本来の設計意図)。 */
  7881.         .rp-btn-group.is-scroll .rp-btn,
  7882.         .rp-btn-group.is-scroll .opt-btn,
  7883.         .opt-btn-group.is-scroll .rp-btn,
  7884.         .opt-btn-group.is-scroll .opt-btn {
  7885.             white-space: nowrap;
  7886.             word-break: normal;
  7887.             overflow-wrap: normal;
  7888.         }
  7889.         /* ただし画像付き選択肢(カラースウォッチ等)は max-width で幅が固定されるため、
  7890.            nowrap にすると名称がボックス外へはみ出して隣の選択肢と重なる。
  7891.            画像付きは常に折り返し可(名称は画像の下に収める)。 */
  7892.         .rp-btn-group.is-scroll .opt-btn--with-image,
  7893.         .opt-btn-group.is-scroll .opt-btn--with-image,
  7894.         .rp-btn-group.is-scroll .opt-btn--with-image .opt-btn__name,
  7895.         .opt-btn-group.is-scroll .opt-btn--with-image .opt-btn__name {
  7896.             white-space: normal;
  7897.             word-break: break-word;
  7898.             overflow-wrap: anywhere;
  7899.         }
  7900.         .rp-btn-group.is-scroll::-webkit-scrollbar,
  7901.         .opt-btn-group.is-scroll::-webkit-scrollbar {
  7902.             height: 6px;
  7903.         }
  7904.         .rp-btn-group.is-scroll::-webkit-scrollbar-thumb,
  7905.         .opt-btn-group.is-scroll::-webkit-scrollbar-thumb {
  7906.             background: #c0c0c0;
  7907.             border-radius: 3px;
  7908.         }
  7909.         /* ---- 3. プルダウン(画像なし・9個以上)---- */
  7910.         .rp-select-wrap {
  7911.             margin-bottom: 4px;
  7912.         }
  7913.         .rp-select {
  7914.             width: 100%;
  7915.             max-width: 420px;
  7916.             padding: 8px 12px;
  7917.             border: 2px solid #ddd;
  7918.             border-radius: 10px;
  7919.             font-size: 13px;
  7920.             color: #333;
  7921.             background: #fff;
  7922.             appearance: none;
  7923.             background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E\");
  7924.             background-repeat: no-repeat;
  7925.             background-position: right 12px center;
  7926.             cursor: pointer;
  7927.         }
  7928.         .rp-select:focus {
  7929.             outline: none;
  7930.             border-color: #1a6fcf;
  7931.         }
  7932.         /* ---- オプション選択ボタン(枠線ラジオ)---- */
  7933.         .opt-btn-group {
  7934.             display: flex;
  7935.             flex-wrap: wrap;
  7936.             gap: 8px;
  7937.             padding: 6px 0;
  7938.             max-width: 100%;
  7939.             min-width: 0;
  7940.         }
  7941.         .opt-btn {
  7942.             cursor: pointer;
  7943.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7944.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7945.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  7946.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  7947.             -webkit-touch-callout: none;
  7948.             padding: 7px 14px;
  7949.             border: 2px solid #ddd;
  7950.             border-radius: 10px;
  7951.             font-size: 13px;
  7952.             color: #333;
  7953.             background: #fff;
  7954.             transition: border-color 0.2s, background 0.2s;
  7955.             white-space: normal;
  7956.             max-width: 100%;
  7957.             overflow-wrap: anywhere;
  7958.             text-decoration: none;
  7959.         }
  7960.         @media (hover: hover) and (pointer: fine) {
  7961.             .opt-btn:hover { border-color: #999; }
  7962.         }
  7963.         .opt-btn.is-selected {
  7964.             border-color: #1a6fcf;
  7965.             color: #1a6fcf;
  7966.             font-weight: bold;
  7967.             background: #f0f6ff;
  7968.         }
  7969.         .opt-btn input[type=\"radio\"] {
  7970.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7971.             margin: 0; pointer-events: none;
  7972.         }
  7973.         /* opt-btn with color swatch image. The label still works as a
  7974.            radio target — clicking the image checks the input. The text
  7975.            label stays under the image so users can still read the name. */
  7976.         .opt-btn--with-image {
  7977.             padding: 4px 6px 6px;
  7978.             white-space: normal;
  7979.             text-align: center;
  7980.             display: inline-flex;
  7981.             flex-direction: column;
  7982.             align-items: center;
  7983.             min-width: 96px;
  7984.             max-width: 140px;
  7985.         }
  7986.         .opt-btn--with-image .opt-btn__img {
  7987.             display: block;
  7988.             width: 88px;
  7989.             height: 66px;
  7990.             object-fit: cover;
  7991.             border-radius: 6px;
  7992.             margin-bottom: 4px;
  7993.             background: #f5f5f5;
  7994.         }
  7995.         .opt-btn--with-image .opt-btn__name {
  7996.             display: block;
  7997.             font-size: 11px;
  7998.             line-height: 1.3;
  7999.             color: inherit;
  8000.         }
  8001.         .opt-btn--with-image.is-selected .opt-btn__img {
  8002.             outline: 2px solid #1a6fcf;
  8003.             outline-offset: 1px;
  8004.         }
  8005.         /* sale_type=2 (内窓) 補助金対象ガラスの強調表示.
  8006.            補助金が出る性能区分 (真空断熱 / Low-E複層 等) のガラス選択肢に
  8007.            緑枠 + 「補助金対象」バッジを付け、選択前から判別できるようにする。 */
  8008.         .opt-btn--subsidy {
  8009.             border-color: #2e7d32;
  8010.         }
  8011.         .opt-btn--subsidy.is-selected {
  8012.             border-color: #1a6fcf;
  8013.         }
  8014.         .opt-btn__subsidy-badge {
  8015.             display: inline-block;
  8016.             margin-left: 6px;
  8017.             padding: 1px 6px;
  8018.             border-radius: 6px;
  8019.             background: #2e7d32;
  8020.             color: #fff;
  8021.             font-size: 11px;
  8022.             font-weight: bold;
  8023.             white-space: nowrap;
  8024.         }
  8025.         /* 補助金額・適用可否の強調 (顧客要望: もっと目立つ色とフォントに).
  8026.            各窓の補助金額は緑・太字・拡大、適用条件ノートは緑の枠付きボックスにする。 */
  8027.         .wt-subsidy-label {
  8028.             color: #2e7d32;
  8029.             font-weight: bold;
  8030.             font-size: 12px;
  8031.         }
  8032.         .wt-subsidy-amount {
  8033.             color: #2e7d32;
  8034.             font-weight: bold;
  8035.             font-size: 18px;
  8036.             line-height: 1.2;
  8037.         }
  8038.         .subsidy-eligibility-note {
  8039.             color: #1b5e20;
  8040.             font-weight: bold;
  8041.             font-size: 12.5px;
  8042.             line-height: 1.5;
  8043.             background: #eafaf0;
  8044.             border: 1px solid #b7e4c7;
  8045.             border-radius: 6px;
  8046.             padding: 8px 10px;
  8047.             margin-bottom: 10px;
  8048.         }
  8049.         .subsidy-eligibility-note strong {
  8050.             color: #c0392b;  /* 「合計が5万円以上」を赤で強調 */
  8051.         }
  8052.         /* ============================================
  8053.            施工エリア案内
  8054.         ============================================ */
  8055.         .ec-areaNotice {
  8056.             margin: 16px 0;
  8057.             padding: 16px 20px;
  8058.             background: #f8f9fa;
  8059.             border-left: 4px solid #1a6fcf;
  8060.             border-radius: 0 8px 8px 0;
  8061.         }
  8062.         .ec-areaNotice__inner {
  8063.             display: flex;
  8064.             align-items: flex-start;
  8065.             gap: 12px;
  8066.         }
  8067.         .ec-areaNotice__icon {
  8068.             font-size: 22px;
  8069.             line-height: 1;
  8070.             flex-shrink: 0;
  8071.             margin-top: 2px;
  8072.         }
  8073.         .ec-areaNotice__body {
  8074.             flex: 1;
  8075.         }
  8076.         .ec-areaNotice__title {
  8077.             font-size: 13px;
  8078.             font-weight: bold;
  8079.             color: #1a6fcf;
  8080.             margin: 0 0 6px;
  8081.         }
  8082.         .ec-areaNotice__text {
  8083.             font-size: 13px;
  8084.             color: #444;
  8085.             line-height: 1.7;
  8086.             margin: 0;
  8087.         }
  8088.         .ec-areaNotice__text strong {
  8089.             color: #222;
  8090.         }
  8091.         .ec-areaNotice__link {
  8092.             display: inline-block;
  8093.             margin-top: 8px;
  8094.             font-size: 12px;
  8095.             color: #1a6fcf;
  8096.             text-decoration: underline;
  8097.         }
  8098.         .ec-areaNotice__link:hover {
  8099.             color: #0d4fa0;
  8100.         }
  8101.         /* ============================================
  8102.            SNSシェア + ブランド名 タイトル行
  8103.         ============================================ */
  8104.         .ec-productRole__titleRow {
  8105.             display: flex;
  8106.             align-items: center;
  8107.             justify-content: space-between;
  8108.             gap: 8px;
  8109.             margin-bottom: 4px;
  8110.         }
  8111.         .ec-productRole__titleRow .ec-headingTitle {
  8112.             margin: 0;
  8113.             flex: 1;
  8114.             font-size: 18px;
  8115.         }
  8116.         .ec-share-inline {
  8117.             display: flex;
  8118.             align-items: center;
  8119.             gap: 8px;
  8120.             flex-shrink: 0;
  8121.         }
  8122.         @media (max-width: 767px) {
  8123.             /* maker_area の float を解除して独立表示 */
  8124.             #maker_area {
  8125.                 float: none !important;
  8126.                 width: auto !important;
  8127.                 height: auto !important;
  8128.                 display: block;
  8129.                 margin-bottom: 4px;
  8130.             }
  8131.             /* タイトル行: 商品名が全幅を占有しSNSは右寄せ下段 */
  8132.             .ec-productRole__titleRow {
  8133.                 flex-wrap: wrap;
  8134.                 clear: both;
  8135.             }
  8136.             .ec-productRole__titleRow .ec-headingTitle {
  8137.                 flex: 1 1 100%;
  8138.                 font-size: 16px;
  8139.             }
  8140.             .ec-share-inline {
  8141.                 flex: 0 0 auto;
  8142.                 margin-left: auto;
  8143.             }
  8144.         }
  8145.         .ec-share-inline a {
  8146.             display: flex;
  8147.             align-items: center;
  8148.             justify-content: center;
  8149.             width: 32px;
  8150.             height: 32px;
  8151.             border-radius: 50%;
  8152.             font-size: 15px;
  8153.             color: #fff;
  8154.             text-decoration: none;
  8155.             transition: opacity 0.2s;
  8156.         }
  8157.         .ec-share-inline a:hover { opacity: 0.8; }
  8158.         .ec-share-inline .share-twitter  { background: #000; }
  8159.         .ec-share-inline .share-facebook { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
  8160.         .ec-share-inline .share-line     { background: #06c755; }
  8161.         /* description_detail下のシェアブロックはPC/スマホ共通で非表示(タイトル行に移動) */
  8162.         .ec-productRole__share { display: none; }
  8163.         /* ============================================
  8164.            PC用: 現在のお見積り額カード強調
  8165.         ============================================ */
  8166.         @media (min-width: 768px) {
  8167.             .mitsumori-card-pc {
  8168.                 border: 2px solid #1a6fcf !important;
  8169.                 border-radius: 10px !important;
  8170.                 box-shadow: 0 4px 16px rgba(26,111,207,0.18) !important;
  8171.                 margin-top: 20px;
  8172.                 overflow: hidden;
  8173.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  8174.             }
  8175.             .mitsumori-card-pc .card-header {
  8176.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  8177.                 color: #fff !important;
  8178.                 padding: 14px 16px !important;
  8179.                 border-bottom: none !important;
  8180.             }
  8181.             .mitsumori-card-pc .card-title {
  8182.                 color: #fff !important;
  8183.                 font-size: 15px !important;
  8184.                 font-weight: bold !important;
  8185.                 margin: 0 !important;
  8186.             }
  8187.             .mitsumori-card-pc #mitsumori_message {
  8188.                 font-size: 22px !important;
  8189.                 font-weight: bold !important;
  8190.                 color: #fff !important;
  8191.             }
  8192.             .mitsumori-card-pc .btn-tool {
  8193.                 color: #fff !important;
  8194.             }
  8195.             /* 合計行を大きく強調 */
  8196.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  8197.                 font-size: 16px !important;
  8198.                 font-weight: bold !important;
  8199.                 color: #c00 !important;
  8200.                 background: #fff8f8 !important;
  8201.                 padding: 12px 16px !important;
  8202.             }
  8203.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  8204.                 font-size: 20px !important;
  8205.                 font-weight: bold !important;
  8206.                 color: #c00 !important;
  8207.             }
  8208.             /* card-body(明細リスト)を白背景に */
  8209.             .mitsumori-card-pc .card-body {
  8210.                 background: #fff !important;
  8211.             }
  8212.             .mitsumori-card-pc .card-footer {
  8213.                 background: #f8faff !important;
  8214.                 border-top: 1px solid #dce8fb !important;
  8215.                 padding: 12px 16px !important;
  8216.             }
  8217.         }
  8218.         @media (max-width: 767px) {
  8219.             /* スマホでは現在のお見積り額カードの強調スタイルをすべてリセット */
  8220.             .mitsumori-card-pc {
  8221.                 border: none !important;
  8222.                 border-radius: 0 !important;
  8223.                 box-shadow: none !important;
  8224.                 margin-top: 0 !important;
  8225.                 overflow: visible !important;
  8226.                 background: none !important;
  8227.                 /* sticky-top(position:sticky / z-index:1020) を解除。
  8228.                    そのままだと最下部で #sp-mitsumori-bar(z-index:1000) の上に
  8229.                    重なり、合計バーと文字が被るため通常フローへ戻す。 */
  8230.                 position: static !important;
  8231.                 z-index: auto !important;
  8232.             }
  8233.             .mitsumori-card-pc .card-header {
  8234.                 background: none !important;
  8235.                 color: inherit !important;
  8236.                 padding: inherit !important;
  8237.                 border-bottom: inherit !important;
  8238.             }
  8239.             .mitsumori-card-pc .card-title { color: inherit !important; }
  8240.             .mitsumori-card-pc #mitsumori_message { font-size: inherit !important; color: inherit !important; }
  8241.             .mitsumori-card-pc .btn-tool { color: inherit !important; }
  8242.             /* 折りたたみトグルボタン */
  8243.             .btn-mitsumori-toggle {
  8244.                 background: none !important;
  8245.                 border: 1px solid #aaa !important;
  8246.                 border-radius: 4px !important;
  8247.                 padding: 2px 8px !important;
  8248.                 font-size: 12px !important;
  8249.                 color: #333 !important;
  8250.                 line-height: 1.4 !important;
  8251.             }
  8252.             .btn-mitsumori-toggle .toggle-icon {
  8253.                 display: inline-block;
  8254.                 transition: transform 0.2s;
  8255.             }
  8256.             /* 展開状態: ▼→▲ */
  8257.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon::before {
  8258.                 content: \"▲ 閉じる\";
  8259.             }
  8260.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon {
  8261.                 display: none;
  8262.             }
  8263.             .card:not(.collapsed-card) .btn-mitsumori-toggle::after {
  8264.                 content: \"▲ 閉じる\";
  8265.                 font-size: 12px;
  8266.             }
  8267.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  8268.                 font-size: inherit !important;
  8269.                 color: inherit !important;
  8270.                 background: none !important;
  8271.                 padding: inherit !important;
  8272.             }
  8273.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  8274.                 font-size: inherit !important;
  8275.                 color: inherit !important;
  8276.             }
  8277.             .mitsumori-card-pc .card-footer {
  8278.                 background: none !important;
  8279.                 border-top: inherit !important;
  8280.                 padding: inherit !important;
  8281.             }
  8282.             /* 横スクロール禁止 */
  8283.             body, html {
  8284.                 overflow-x: hidden;
  8285.                 max-width: 100vw;
  8286.             }
  8287.             /* ボタンの折り返しを許可(nowrapが原因で横スクロール発生するため) */
  8288.             .opt-btn,
  8289.             .rp-btn {
  8290.                 white-space: normal;
  8291.                 word-break: break-all;
  8292.             }
  8293.             /* エリア案内: スマホでコンパクト */
  8294.             .ec-areaNotice {
  8295.                 margin: 8px 0;
  8296.                 padding: 8px 10px;
  8297.                 border-left-width: 3px;
  8298.                 cursor: pointer;
  8299.             }
  8300.             .ec-areaNotice__inner {
  8301.                 flex-direction: row;
  8302.                 gap: 8px;
  8303.                 align-items: flex-start;
  8304.             }
  8305.             .ec-areaNotice__icon { font-size: 15px; }
  8306.             /* タイトル行: 展開トグル */
  8307.             .ec-areaNotice__title {
  8308.                 font-size: 11px;
  8309.                 margin-bottom: 3px;
  8310.                 display: flex;
  8311.                 justify-content: space-between;
  8312.                 align-items: center;
  8313.             }
  8314.             .ec-areaNotice__title::after {
  8315.                 content: \"▼\";
  8316.                 font-size: 9px;
  8317.                 color: #888;
  8318.                 margin-left: 6px;
  8319.                 transition: transform 0.2s;
  8320.             }
  8321.             .ec-areaNotice.is-open .ec-areaNotice__title::after {
  8322.                 transform: rotate(180deg);
  8323.             }
  8324.             /* 折りたたみ対象: 閉じた状態では非表示 */
  8325.             .ec-areaNotice__detail {
  8326.                 display: none;
  8327.             }
  8328.             .ec-areaNotice.is-open .ec-areaNotice__detail {
  8329.                 display: block;
  8330.             }
  8331.             .ec-areaNotice__text { font-size: 11px; line-height: 1.5; }
  8332.             .ec-areaNotice__text br { display: none; }
  8333.             .ec-areaNotice__link { font-size: 11px; margin-top: 3px; }
  8334.             .rp-card { width: calc(33.333% - 6px); min-width: 80px; }
  8335.             
  8336.             #sp-mitsumori-bar {
  8337.                 display: flex;
  8338.                 position: fixed;
  8339.                 bottom: 0;
  8340.                 left: 0;
  8341.                 right: 0;
  8342.                 z-index: 1000;
  8343.                 background: #fff;
  8344.                 border-top: 2px solid #e0e0e0;
  8345.                 box-shadow: 0 -2px 8px rgba(0,0,0,0.12);
  8346.                 align-items: center;
  8347.                 padding: 8px 10px calc(8px + env(safe-area-inset-bottom)) 10px;
  8348.                 gap: 8px;
  8349.             }
  8350.             #sp-mitsumori-bar .sp-bar__label {
  8351.                 font-size: 11px;
  8352.                 color: #666;
  8353.                 white-space: nowrap;
  8354.             }
  8355.             /* 価格ラッパ: 合計金額は最重要のため常に全桁表示する(縮小・省略しない)。
  8356.                幅が足りない場合は下のボタン側を縮める(flex 配分でボタンが先に縮む)。 */
  8357.             #sp-mitsumori-bar .sp-bar__pricewrap {
  8358.                 flex: 0 0 auto;
  8359.                 min-width: 0;
  8360.             }
  8361.             #sp-mitsumori-bar .sp-bar__price {
  8362.                 font-size: 18px;
  8363.                 font-weight: bold;
  8364.                 color: #c00;
  8365.                 white-space: nowrap;
  8366.             }
  8367.             #sp-mitsumori-bar .sp-bar__btn {
  8368.                 font-size: 12px;
  8369.                 padding: 8px 12px;
  8370.                 background: #333;
  8371.                 color: #fff;
  8372.                 border: none;
  8373.                 border-radius: 6px;
  8374.                 white-space: nowrap;
  8375.                 cursor: pointer;
  8376.                 position: relative;
  8377.                 display: inline-flex;
  8378.                 align-items: center;
  8379.                 gap: 6px;
  8380.                 flex: 1 1 auto;
  8381.                 min-width: 0;
  8382.                 justify-content: center;
  8383.             }
  8384.             #sp-mitsumori-bar .sp-bar__btn i {
  8385.                 font-size: 14px;
  8386.                 flex: 0 0 auto;
  8387.             }
  8388.             /* お見積りの詳細(内訳)を開くボタン。価格・カートボタンを圧迫しないよう
  8389.                最小幅のアイコン+短ラベルにし、幅不足時も縮まない固定幅で維持する。 */
  8390.             #sp-mitsumori-bar .sp-bar__detail-btn {
  8391.                 display: inline-flex;
  8392.                 flex-direction: column;
  8393.                 align-items: center;
  8394.                 justify-content: center;
  8395.                 gap: 2px;
  8396.                 flex: 0 0 auto;
  8397.                 padding: 4px 8px;
  8398.                 background: #fff;
  8399.                 color: #c00;
  8400.                 border: 1px solid #c00;
  8401.                 border-radius: 6px;
  8402.                 font-size: 10px;
  8403.                 font-weight: bold;
  8404.                 line-height: 1.1;
  8405.                 white-space: nowrap;
  8406.                 cursor: pointer;
  8407.             }
  8408.             #sp-mitsumori-bar .sp-bar__detail-btn i { font-size: 15px; }
  8409.             /* 幅が足りないときはボタンの文字を省略し、価格と数字を守る。 */
  8410.             #sp-mitsumori-bar .sp-bar__btn-label {
  8411.                 overflow: hidden;
  8412.                 text-overflow: ellipsis;
  8413.                 white-space: nowrap;
  8414.             }
  8415.             #sp-mitsumori-bar .sp-bar__cart-badge {
  8416.                 position: absolute;
  8417.                 top: -6px;
  8418.                 right: -6px;
  8419.                 background: #c00;
  8420.                 color: #fff;
  8421.                 border-radius: 50%;
  8422.                 min-width: 16px;
  8423.                 height: 16px;
  8424.                 font-size: 10px;
  8425.                 line-height: 16px;
  8426.                 padding: 0 4px;
  8427.                 font-weight: bold;
  8428.             }
  8429.             #sp-mitsumori-bar .sp-bar__home-btn {
  8430.                 display: inline-flex;
  8431.                 align-items: center;
  8432.                 justify-content: center;
  8433.                 width: 36px;
  8434.                 height: 36px;
  8435.                 flex: 0 0 auto;
  8436.                 border: 1px solid #ccc;
  8437.                 border-radius: 6px;
  8438.                 background: #fff;
  8439.                 color: #333;
  8440.                 text-decoration: none;
  8441.                 cursor: pointer;
  8442.             }
  8443.             #sp-mitsumori-bar .sp-bar__home-btn i {
  8444.                 font-size: 16px;
  8445.             }
  8446.             #sp-mitsumori-bar .sp-bar__home-btn:hover {
  8447.                 background: #f0f0f0;
  8448.             }
  8449.             /* 下部バーの高さ分ページ下部にpaddingを追加 (iOS safe-area 込み) */
  8450.             body {
  8451.                 padding-bottom: calc(80px + env(safe-area-inset-bottom));
  8452.             }
  8453.         }
  8454.         /* ============================================
  8455.            カート追加モーダル: 縦並び中央配置
  8456.         ============================================ */
  8457.         .add-cart-modal__wrap {
  8458.             text-align: center;
  8459.         }
  8460.         .add-cart-modal__header {
  8461.             font-size: 16px;
  8462.             margin: 20px 0 24px;
  8463.             text-align: center;
  8464.         }
  8465.         .add-cart-modal__actions {
  8466.             display: flex;
  8467.             flex-direction: column;
  8468.             align-items: center;
  8469.             gap: 16px;
  8470.             padding: 0 20px 20px;
  8471.         }
  8472.         .add-cart-modal__primary {
  8473.             display: inline-block;
  8474.             width: 80%;
  8475.             max-width: 320px;
  8476.             padding: 14px 20px;
  8477.             font-size: 15px;
  8478.             font-weight: bold;
  8479.             text-align: center;
  8480.             background: #d9534f;
  8481.             color: #fff !important;
  8482.             border-radius: 6px;
  8483.             text-decoration: none;
  8484.             cursor: pointer;
  8485.         }
  8486.         .add-cart-modal__primary:hover {
  8487.             background: #c9302c;
  8488.             color: #fff !important;
  8489.             text-decoration: none;
  8490.         }
  8491.         .add-cart-modal__secondary {
  8492.             display: inline-block;
  8493.             padding: 6px 14px;
  8494.             font-size: 12px;
  8495.             color: #666;
  8496.             border: 1px solid #ccc;
  8497.             border-radius: 4px;
  8498.             background: #fff;
  8499.             cursor: pointer;
  8500.         }
  8501.         .add-cart-modal__secondary:hover {
  8502.             background: #f0f0f0;
  8503.             color: #333;
  8504.         }
  8505.         @media (max-width: 767px) {
  8506.             .add-cart-modal__actions {
  8507.                 gap: 20px;
  8508.             }
  8509.         }
  8510.     </style>
  8511. {% endblock %}
  8512. {% block javascript %}
  8513.     <script>
  8514.         eccube.classCategories = {{ class_categories_as_json(Product)|raw }};
  8515.         // 規格2に選択肢を割り当てる。
  8516.         function fnSetClassCategories(form, classcat_id2_selected) {
  8517.             var \$form = \$(form);
  8518.             var product_id = \$form.find('input[name=product_id]').val();
  8519.             var \$sele1 = \$form.find('select[name=classcategory_id1]');
  8520.             var \$sele2 = \$form.find('select[name=classcategory_id2]');
  8521.             eccube.setClassCategories(\$form, product_id, \$sele1, \$sele2, classcat_id2_selected);
  8522.         }
  8523.         {% if form.classcategory_id2 is defined %}
  8524.         fnSetClassCategories(
  8525.             \$('#form1'), {{ form.classcategory_id2.vars.value|json_encode|raw }}
  8526.         );
  8527.         {% elseif form.classcategory_id1 is defined %}
  8528.         eccube.checkStock(\$('#form1'), {{ Product.id }}, {{ form.classcategory_id1.vars.value|json_encode|raw }}, null);
  8529.         {% endif %}
  8530.     </script>
  8531.     <script>
  8532.         \$(function() {
  8533.             // bfcache無効化
  8534.             \$(window).bind('pageshow', function(event) {
  8535.                 if (event.originalEvent.persisted) {
  8536.                     location.reload(true);
  8537.                 }
  8538.             });
  8539.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  8540.             // img タグに width, height が付与されている.
  8541.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  8542.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  8543.             \$('.ec-grid2__cell').hide();
  8544.             var removeSize = function () {
  8545.                 \$('.slide-item').height('');
  8546.                 \$('.slide-item img')
  8547.                     .removeAttr('width')
  8548.                     .removeAttr('height')
  8549.                     .removeAttr('style');
  8550.             };
  8551.             var slickInitial = function(slick) {
  8552.                 \$('.ec-grid2__cell').fadeIn(1500);
  8553.                 var baseHeight = \$(slick.target).height();
  8554.                 var baseWidth = \$(slick.target).width();
  8555.                 var rate = baseWidth / baseHeight;
  8556. \t\t\t\tif(baseHeight * rate < 400){
  8557. \t                \$('.slide-item').height(baseHeight * rate); // 余白を削除する
  8558. \t\t\t\t}else{
  8559. \t                \$('.slide-item').height(400); // 余白を削除する
  8560. \t\t\t\t}
  8561.                 // transform を使用することでCLSの影響を受けないようにする
  8562.                 \$('.slide-item img')
  8563.                     .css(
  8564.                         {
  8565.                             'transform-origin': 'top left',
  8566.                             'transform': 'scaleY(' + rate + ')',
  8567.                             'transition': 'transform .1s'
  8568.                         }
  8569.                     );
  8570.                 // 正しいサイズに近くなったら属性を解除する
  8571.                 setTimeout(removeSize, 500);
  8572.             };
  8573.             \$('.item_visual').on('init', slickInitial);
  8574.             // リサイズ時は CLS の影響を受けないため属性を解除する
  8575.             \$(window).resize(removeSize);
  8576.             \$('.item_visual').slick({
  8577.                 dots: false,
  8578.                 arrows: true,
  8579.                 responsive: [{
  8580.                     breakpoint: 768,
  8581.                     settings: {
  8582.                         dots: true,
  8583.                 \t\tarrows: false
  8584.                     }
  8585.                 }]
  8586.             });
  8587.             \$('.slideThumb').on('click', function() {
  8588.                 var index = \$(this).attr('data-index');
  8589.                 \$('.item_visual').slick('slickGoTo', index, false);
  8590.             })
  8591.         });
  8592.     </script>
  8593.     <script>
  8594.         \$(function() {
  8595.             \$('.add-cart').on('click', function(event) {
  8596.                 {% if form.classcategory_id1 is defined %}
  8597.                 // 規格1フォームの必須チェック
  8598.                 if (\$('#classcategory_id1').val() == '__unselected' || \$('#classcategory_id1').val() == '') {
  8599.                     \$('#classcategory_id1')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  8600.                     return true;
  8601.                 } else {
  8602.                     \$('#classcategory_id1')[0].setCustomValidity('');
  8603.                 }
  8604.                 {% endif %}
  8605.                 {% if form.classcategory_id2 is defined %}
  8606.                 // 規格2フォームの必須チェック
  8607.                 if (\$('#classcategory_id2').val() == '__unselected' || \$('#classcategory_id2').val() == '') {
  8608.                     \$('#classcategory_id2')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  8609.                     return true;
  8610.                 } else {
  8611.                     \$('#classcategory_id2')[0].setCustomValidity('');
  8612.                 }
  8613.                 {% endif %}
  8614.                 // タイプ2: カート送信直前に set_count を quantity に同期
  8615.                 if(\$('#set_count').length){
  8616.                     var _sc = parseInt(\$('#set_count').val()) || 1;
  8617.                     \$('#quantity').val(_sc);
  8618.                     \$('input[name=\"quantity\"]').val(_sc);
  8619.                 }
  8620.                 // 個数フォームのチェック
  8621.                 if (\$('#quantity').val() < 1) {
  8622.                     \$('#quantity')[0].setCustomValidity('{{ '1以上で入力してください。'|trans }}');
  8623.                     return true;
  8624.                 } else {
  8625.                     \$('#quantity')[0].setCustomValidity('');
  8626.                 }
  8627.                 event.preventDefault();
  8628.                 \$form = \$('#form1');
  8629.                 \$.ajax({
  8630.                     url: \$form.attr('action'),
  8631.                     type: \$form.attr('method'),
  8632.                     data: \$form.serialize(),
  8633.                     dataType: 'json',
  8634.                     beforeSend: function(xhr, settings) {
  8635.                         // Buttonを無効にする
  8636.                         \$('.add-cart').prop('disabled', true);
  8637.                     }
  8638.                 }).done(function(data) {
  8639.                     // レスポンス内のメッセージをalertで表示
  8640.                     \$.each(data.messages, function() {
  8641.                         \$('#ec-modal-header').text(this);
  8642.                     });
  8643.                     \$('.ec-modal').show()
  8644.                     // カートブロックを更新する
  8645.                     \$.ajax({
  8646.                         url: \"{{ url('block_cart') }}\",
  8647.                         type: 'GET',
  8648.                         dataType: 'html'
  8649.                     }).done(function(html) {
  8650.                         \$('.ec-headerRole__cart').html(html);
  8651.                     });
  8652.                 }).fail(function(data) {
  8653.                     alert('{{ 'カートへの追加に失敗しました。'|trans }}');
  8654.                 }).always(function(data) {
  8655.                     // Buttonを有効にする
  8656.                     \$('.add-cart').prop('disabled', false);
  8657.                 });
  8658.             });
  8659.         });
  8660.         \$('.ec-modal-wrap').on('click', function(e) {
  8661.             // モーダル内の処理は外側にバブリングさせない
  8662.             e.stopPropagation();
  8663.         });
  8664.         \$('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  8665.             \$('.ec-modal').hide()
  8666.         });
  8667. \t\tvar pw = \"{% if mitsumori_json %}{{ mitsumori_json.pw }}{% endif %}\";
  8668. \t\tvar pd = \"{% if mitsumori_json %}{{ mitsumori_json.pd }}{% endif %}\";
  8669. \t\tvar ph = \"{% if mitsumori_json %}{{ mitsumori_json.ph }}{% endif %}\";
  8670. \t\tvar pm = \"{% if mitsumori_json %}{{ mitsumori_json.pm }}{% endif %}\";
  8671. \t\tvar pc = \"{% if mitsumori_json %}{{ mitsumori_json.pc }}{% endif %}\";
  8672. \t\t// option1 / option2: カテゴリ別 option 軸 (um: タイプ=subtype, fe: ct_up 等)
  8673. \t\tvar option1 = \"{% if mitsumori_json and mitsumori_json.option1 is defined %}{{ mitsumori_json.option1 }}{% endif %}\";
  8674. \t\tvar option2 = \"{% if mitsumori_json and mitsumori_json.option2 is defined %}{{ mitsumori_json.option2 }}{% endif %}\";
  8675. \t\tvar op0 = \"{% if mitsumori_json %}{{ mitsumori_json.op[0] }}{% endif %}\";
  8676. \t\tvar op1 = \"{% if mitsumori_json %}{{ mitsumori_json.op[1] }}{% endif %}\";
  8677. \t\tvar op2 = \"{% if mitsumori_json %}{{ mitsumori_json.op[2] }}{% endif %}\";
  8678. \t\tvar op3 = \"{% if mitsumori_json %}{{ mitsumori_json.op[3] }}{% endif %}\";
  8679. \t\tvar op4 = \"{% if mitsumori_json %}{{ mitsumori_json.op[4] }}{% endif %}\";
  8680. \t\tvar op5 = \"{% if mitsumori_json %}{{ mitsumori_json.op[5] }}{% endif %}\";
  8681. \t\tvar op6 = \"{% if mitsumori_json %}{{ mitsumori_json.op[6] }}{% endif %}\";
  8682. \t\tvar op7 = \"{% if mitsumori_json %}{{ mitsumori_json.op[7] }}{% endif %}\";
  8683. \t\tvar op8 = \"{% if mitsumori_json %}{{ mitsumori_json.op[8] }}{% endif %}\";
  8684. \t\tvar op9 = \"{% if mitsumori_json %}{{ mitsumori_json.op[9] }}{% endif %}\";
  8685. \t\tvar op10 = \"{% if mitsumori_json %}{{ mitsumori_json.op[10] }}{% endif %}\";
  8686. \t\tconst formatter = new Intl.NumberFormat('ja-JP');
  8687. \t\t// ============================================================
  8688. \t\t//  free_area 1 エントリのスキーマ(11 キー固定)
  8689. \t\t// ============================================================
  8690. \t\t//   w           : 幅 (string, 例 \"239.9cm\" / tf は \"1m\")
  8691. \t\t//   d           : 奥行
  8692. \t\t//   h           : 高さ (tf はロール長 \"10m\")
  8693. \t\t//   m           : 素材
  8694. \t\t//   c           : カラー
  8695. \t\t//   price       : 販売価格 (税抜、amount=1 ベース)
  8696. \t\t//   unit_price  : 商品 per-unit 増分 (税抜、AMOUNT_CATEGORIES のみ)
  8697. \t\t//   maker_price : メーカー価格 (税抜)
  8698. \t\t//   ct          : 基本工事費 (税抜、amount=1 ベース)
  8699. \t\t//   option1     : fe → ct_up / その他カテゴリ → category-specific
  8700. \t\t//   option2     : um → ct_up / その他カテゴリ → category-specific
  8701. \t\t//
  8702. \t\t//  ct4 (設置場所) / ct5 (撤去) / ct6 (残土) は option_area 側で扱う.
  8703. \t\t// ============================================================
  8704. \t\t// 施工オプション定義(option_area)— 各エントリ {name, comment, on, off, price}
  8705. \t\tvar op_data = {{ op_json|default('[]')|raw }};
  8706. \t\t// option_item_area:
  8707. \t\t//   tg 用 — block 別オプション差額表
  8708. \t\t//     { axis_labels: {F:'床材',front:'前面型',side1:'右側面型',side2:'左側面型'},
  8709. \t\t//       blocks: { 'W_label|D_label': { F:[{idx,label,diff},...], front:[...], side1:[...], side2:[...] }, ... } }
  8710. \t\t//   fe (sale_type=4) 用 — ブロックの種類×段数の差額表 (fe_block キー)
  8711. \t\t//     { fe_block: { depends_on_name: '...', depends_on_value: '...',
  8712. \t\t//                   title: '...', default_key: '...',
  8713. \t\t//                   choices: [{key,label,price}, ...] } }
  8714. \t\t// 該当しないカテゴリでは fe_block は null. axis_labels/blocks は空.
  8715. \t\tvar oi_data = {{ oi_json|default('{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}')|raw }};
  8716. \t\t// 選択中の tg オプション差額 (axis -> selected choice_idx). ラジオ click で更新される.
  8717. \t\tvar oi_selected = { F: 1, front: 1, side1: 1, side2: 1 };
  8718. \t\t// 選択中の fe ブロック種類×段数 (key 文字列). 既定は oi_data.fe_block.default_key.
  8719. \t\tvar fe_block_selected = (oi_data && oi_data.fe_block && oi_data.fe_block.default_key) || '';
  8720. \t\t// sale_type ID(mtb_sale_type の id。本サイトでの意味は次の通り):
  8721. \t\t//   1 通常 / 2 補助金窓 / 3 物置 / 4 フェンス / 5 デッキ / 6 芝生 / 9 商品のみ
  8722. \t\tvar SALE_TYPE_ID = {{ ProductClass.SaleType.id }};
  8723. \t\t{# option1 / option2 ラベルをカテゴリ別に決定 (sh=31, rd=43, mo=15) — 以降の UI / JS 両方で使用 #}
  8724. \t\t{% set option1_label = 'オプション1' %}
  8725. \t\t{% set option2_label = 'オプション2' %}
  8726. \t\t{% if Product.ProductCategories is not empty %}
  8727. \t\t\t{% for pcat in Product.ProductCategories %}
  8728. \t\t\t\t{% if pcat.category_id == 31 %}{% set option1_label = 'サイズプリセット' %}{% set option2_label = '駆動方式' %}{% endif %}
  8729. \t\t\t\t{% if pcat.category_id == 43 %}{% set option1_label = 'ランマ' %}{% set option2_label = 'タイプ' %}{% endif %}
  8730. \t\t\t\t{% if pcat.category_id == 15 %}{% set option1_label = '棚タイプ' %}{% endif %}
  8731. \t\t\t\t{% if pcat.category_id == 17 %}{% set option1_label = '窓タイプ' %}{% endif %}
  8732. \t\t\t{% endfor %}
  8733. \t\t{% endif %}
  8734. \t\t// 消費税率(pp.price/pp.ct/op_data.price は scraper が税抜で保存しているため、
  8735. \t\t// calcGoukei 出口で 1+TAX_RATE を掛けて税込 mitsumori_goukei にする)
  8736. \t\tvar TAX_RATE = 0.10;
  8737. \t\tfunction toIncTax(v) { return Math.round(v * (1 + TAX_RATE)); }
  8738. \t\t/**
  8739. \t\t * tg 用 block 別オプション差額の集計.
  8740. \t\t *   現選択 (W, D) から block key を作り、oi_data.blocks[blockKey] を取得.
  8741. \t\t *   各 axis (F/front/side1/side2) で oi_selected[axis] の choice の diff を合計.
  8742. \t\t * 戻り値: { total: 差額合計(税抜), items: [{name, label, diff}, ...] }
  8743. \t\t *   block が無い (tg 以外 / 該当 (W,D) が未取得) なら total=0.
  8744. \t\t */
  8745. \t\tfunction collectOptionItems(curW, curD) {
  8746. \t\t\tvar result = { total: 0, items: [] };
  8747. \t\t\tif (!oi_data || !oi_data.blocks) return result;
  8748. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  8749. \t\t\tvar block = oi_data.blocks[blockKey];
  8750. \t\t\tif (!block) return result;
  8751. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  8752. \t\t\tfor (var i = 0; i < axes.length; i++) {
  8753. \t\t\t\tvar axis = axes[i];
  8754. \t\t\t\tvar choices = block[axis];
  8755. \t\t\t\tif (!choices || !choices.length) continue;
  8756. \t\t\t\tvar idx = oi_selected[axis] || 1;
  8757. \t\t\t\tvar pick = null;
  8758. \t\t\t\tfor (var j = 0; j < choices.length; j++) {
  8759. \t\t\t\t\tif (parseInt(choices[j].idx) === parseInt(idx)) { pick = choices[j]; break; }
  8760. \t\t\t\t}
  8761. \t\t\t\tif (!pick) pick = choices[0];
  8762. \t\t\t\tvar diff = parseInt(pick.diff) || 0;
  8763. \t\t\t\tresult.total += diff;
  8764. \t\t\t\tresult.items.push({
  8765. \t\t\t\t\tname:  oi_data.axis_labels[axis] || axis,
  8766. \t\t\t\t\tlabel: pick.label,
  8767. \t\t\t\t\tdiff:  diff,
  8768. \t\t\t\t});
  8769. \t\t\t}
  8770. \t\t\treturn result;
  8771. \t\t}
  8772. \t\t/**
  8773. \t\t * tg ラジオ群を block 別に DOM へ描画する.
  8774. \t\t *   W/D が確定したら現 block の 4 軸 (F/front/side1/side2) ラジオを #tg-options 要素に出す.
  8775. \t\t *   block が空なら #tg-options を空にする.
  8776. \t\t */
  8777. \t\tfunction renderOptionItemRadios(curW, curD) {
  8778. \t\t\tvar \$box = \$('#tg-options');
  8779. \t\t\tif (!\$box.length) return;
  8780. \t\t\t\$box.empty();
  8781. \t\t\tif (!oi_data || !oi_data.blocks) return;
  8782. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  8783. \t\t\tvar block = oi_data.blocks[blockKey];
  8784. \t\t\tif (!block) return;
  8785. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  8786. \t\t\taxes.forEach(function(axis) {
  8787. \t\t\t\tvar choices = block[axis];
  8788. \t\t\t\tif (!choices || !choices.length) return;
  8789. \t\t\t\tvar axisLabel = (oi_data.axis_labels && oi_data.axis_labels[axis]) || axis;
  8790. \t\t\t\tvar \$section = \$('<div class=\"form-group tg-axis\"></div>');
  8791. \t\t\t\t\$section.append('<p class=\"rp-section-label\"><strong>' + axisLabel + '</strong>: <span class=\"tg-axis-selected\"></span></p>');
  8792. \t\t\t\t// 他オプション(opt-btn)と統一したボタン型 UI で描画(縦積み・長ラベル折返し).
  8793. \t\t\t\tvar \$list = \$('<div class=\"opt-btn-group no-hscroll\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  8794. \t\t\t\tchoices.forEach(function(ch, i) {
  8795. \t\t\t\t\tvar inputId = 'tg_' + axis + '_' + ch.idx;
  8796. \t\t\t\t\tvar name = 'tg_' + axis;
  8797. \t\t\t\t\tvar isSel = (parseInt(ch.idx) === parseInt(oi_selected[axis] || 1));
  8798. \t\t\t\t\tvar diffTxt = ch.diff > 0 ? '+' + formatter.format(ch.diff) + '円' : (ch.diff < 0 ? formatter.format(ch.diff) + '円' : '±0');
  8799. \t\t\t\t\t\$list.append(
  8800. \t\t\t\t\t\t'<label class=\"opt-btn' + (isSel ? ' is-selected' : '') + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  8801. \t\t\t\t\t\t'<input type=\"radio\" name=\"' + name + '\" id=\"' + inputId + '\" value=\"' + ch.idx + '\" data-axis=\"' + axis + '\"' + (isSel ? ' checked' : '') + '>' +
  8802. \t\t\t\t\t\tch.label + '<span class=\"tg-diff\">(' + diffTxt + ')</span></label>'
  8803. \t\t\t\t\t);
  8804. \t\t\t\t});
  8805. \t\t\t\t\$section.append(\$list);
  8806. \t\t\t\t\$box.append(\$section);
  8807. \t\t\t});
  8808. \t\t\t// ラジオ選択で oi_selected 更新 + is-selected 付替え → 再計算
  8809. \t\t\t\$box.off('change.tg').on('change.tg', 'input[type=\"radio\"][data-axis]', function() {
  8810. \t\t\t\tvar axis = \$(this).data('axis');
  8811. \t\t\t\toi_selected[axis] = parseInt(\$(this).val()) || 1;
  8812. \t\t\t\t\$(this).closest('.opt-btn-group').find('label.opt-btn').removeClass('is-selected');
  8813. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  8814. \t\t\t\tmitsumori_simulation('refresh', '');
  8815. \t\t\t});
  8816. \t\t\tupdateOptionItemSelectedLabels();
  8817. \t\t}
  8818. \t\tfunction updateOptionItemSelectedLabels() {
  8819. \t\t\t\$('#tg-options .tg-axis').each(function() {
  8820. \t\t\t\tvar \$sel = \$(this).find('input[type=\"radio\"]:checked');
  8821. \t\t\t\tif (!\$sel.length) return;
  8822. \t\t\t\tvar label = \$sel.parent().contents().filter(function() { return this.nodeType === 3; }).text().trim();
  8823. \t\t\t\t\$(this).find('.tg-axis-selected').text(label);
  8824. \t\t\t});
  8825. \t\t}
  8826. \t\t// =========================================================
  8827. \t\t// fe (sale_type=4) ブロック種類×段数 サブ UI
  8828. \t\t// =========================================================
  8829. \t\t/**
  8830. \t\t * fe_block の親オプション (= op_data 内の「ご希望のフェンス設置方法」 entry)
  8831. \t\t * を name でルックアップし、その index を返す. 見つからなければ -1.
  8832. \t\t *   fe_block.depends_on_name が設定されていればそれで照合.
  8833. \t\t *   未設定なら 'ご希望のフェンス設置方法' を含む name にフォールバック.
  8834. \t\t */
  8835. \t\tfunction findFeBlockParentOpIndex() {
  8836. \t\t\tif (!oi_data || !oi_data.fe_block) return -1;
  8837. \t\t\tvar needle = oi_data.fe_block.depends_on_name || 'ご希望のフェンス設置方法';
  8838. \t\t\tfor (var i = 0; i < op_data.length; i++) {
  8839. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  8840. \t\t\t\tif (op_data[i].name.indexOf(needle) >= 0) return i;
  8841. \t\t\t}
  8842. \t\t\treturn -1;
  8843. \t\t}
  8844. \t\t/**
  8845. \t\t * fe_block の現在の選択値の price (税抜) と choice 内容を集計.
  8846. \t\t *   親オプション (= 'ご希望のフェンス設置方法') が depends_on_value を選んでいる
  8847. \t\t *   ときだけ加算する. それ以外 (既存ブロック側 / 親未選択) は price=0.
  8848. \t\t * 戻り値: { price: 0|N, choice: {key,label,price}|null, active: bool }
  8849. \t\t */
  8850. \t\tfunction collectFeBlock() {
  8851. \t\t\tvar result = { price: 0, choice: null, active: false };
  8852. \t\t\tif (SALE_TYPE_ID !== 4) return result;
  8853. \t\t\tif (!oi_data || !oi_data.fe_block) return result;
  8854. \t\t\tif (!oi_data.fe_block.choices || !oi_data.fe_block.choices.length) return result;
  8855. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8856. \t\t\tif (parentIdx < 0) return result;
  8857. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8858. \t\t\tvar parentSel = ops[parentIdx];
  8859. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  8860. \t\t\tif (parentSel !== triggerValue) return result;  // 親が新規ブロック積み以外なら無加算
  8861. \t\t\tresult.active = true;
  8862. \t\t\tvar choices = oi_data.fe_block.choices;
  8863. \t\t\tvar pick = null;
  8864. \t\t\tfor (var j = 0; j < choices.length; j++) {
  8865. \t\t\t\tif (choices[j].key === fe_block_selected) { pick = choices[j]; break; }
  8866. \t\t\t}
  8867. \t\t\tif (!pick) pick = choices[0];
  8868. \t\t\tresult.choice = pick;
  8869. \t\t\tresult.price  = parseInt(pick.price) || 0;
  8870. \t\t\treturn result;
  8871. \t\t}
  8872. \t\t/**
  8873. \t\t * fe_block ラジオ群を #fe-block-options 要素に描画する.
  8874. \t\t *   active=false (親が「新規にブロック積み」以外) のときは非表示.
  8875. \t\t */
  8876. \t\tfunction renderFeBlockRadios() {
  8877. \t\t\tvar \$box = \$('#fe-block-options');
  8878. \t\t\tif (!\$box.length) return;
  8879. \t\t\tif (!oi_data || !oi_data.fe_block || !oi_data.fe_block.choices) {
  8880. \t\t\t\t\$box.empty().hide();
  8881. \t\t\t\treturn;
  8882. \t\t\t}
  8883. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8884. \t\t\tif (parentIdx < 0) {
  8885. \t\t\t\t\$box.empty().hide();
  8886. \t\t\t\treturn;
  8887. \t\t\t}
  8888. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8889. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  8890. \t\t\tvar visible = (ops[parentIdx] === triggerValue);
  8891. \t\t\tif (!visible) {
  8892. \t\t\t\t\$box.hide();
  8893. \t\t\t\treturn;
  8894. \t\t\t}
  8895. \t\t\tvar fb = oi_data.fe_block;
  8896. \t\t\t\$box.empty();
  8897. \t\t\tvar \$title = \$('<p class=\"rp-section-label\"><strong>' + (fb.title || 'ブロックの種類と段数') + '</strong></p>');
  8898. \t\t\t\$box.append(\$title);
  8899. \t\t\t// 他オプション群と同じ .opt-btn-group / .opt-btn 形式で描画.
  8900. \t\t\t//   生の <label><input type=radio> ... 形式だと CSS 定義が無く
  8901. \t\t\t//   ラベル折り返し・縦ズレ・隣接 opt-btn との間隔不揃いが発生する.
  8902. \t\t\tvar \$list = \$('<div class=\"opt-btn-group no-hscroll\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  8903. \t\t\tfb.choices.forEach(function(ch) {
  8904. \t\t\t\tvar inputId = 'fe_block_' + ch.key;
  8905. \t\t\t\tvar isSel   = (ch.key === fe_block_selected);
  8906. \t\t\t\tvar checked = isSel ? ' checked' : '';
  8907. \t\t\t\tvar selCls  = isSel ? ' is-selected' : '';
  8908. \t\t\t\t// 選択肢ラベルには価格を表示しない(差額は合計金額側でのみ反映)。
  8909. \t\t\t\t\$list.append(
  8910. \t\t\t\t\t'<label class=\"opt-btn' + selCls + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  8911. \t\t\t\t\t'<input type=\"radio\" name=\"fe_block\" id=\"' + inputId + '\" value=\"' + ch.key + '\"' + checked + '>' +
  8912. \t\t\t\t\t'<span class=\"fe-block-label\">' + ch.label + '</span>' +
  8913. \t\t\t\t\t'</label>'
  8914. \t\t\t\t);
  8915. \t\t\t});
  8916. \t\t\t\$box.append(\$list);
  8917. \t\t\t\$box.show();
  8918. \t\t\t\$box.off('change.fe_block').on('change.fe_block', 'input[type=\"radio\"][name=\"fe_block\"]', function() {
  8919. \t\t\t\tfe_block_selected = \$(this).val();
  8920. \t\t\t\t// is-selected 切替 (opt-btn 形式共通)
  8921. \t\t\t\t\$box.find('label.opt-btn').removeClass('is-selected');
  8922. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  8923. \t\t\t\tmitsumori_simulation('refresh', '');
  8924. \t\t\t});
  8925. \t\t}
  8926. \t\t/**
  8927. \t\t * fe (sale_type=4) で op_data エントリの連動表示制御.
  8928. \t\t *   親「ご希望のフェンス設置方法」の選択値に応じて、
  8929. \t\t *     - 「既存ブロックに穴空け工事が必要ですか?」 entry を表示/非表示
  8930. \t\t *   切替の trigger は親選択値の文字列で判定 (entry index にハードコードしない).
  8931. \t\t */
  8932. \t\tfunction updateFeOpConditionalVisibility() {
  8933. \t\t\tif (SALE_TYPE_ID !== 4) return;
  8934. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8935. \t\t\tif (parentIdx < 0) return;
  8936. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8937. \t\t\tvar parentSel = ops[parentIdx];
  8938. \t\t\t// 親が「既存ブロックに設置する」 (= off 側) のとき穴空け entry を表示
  8939. \t\t\tvar triggerOffValue = (op_data[parentIdx] && op_data[parentIdx].off) || '既存ブロックに設置する';
  8940. \t\t\t\$('div[data-op-name]').each(function() {
  8941. \t\t\t\tvar n = \$(this).attr('data-op-name') || '';
  8942. \t\t\t\tif (n.indexOf('穴空け') >= 0) {
  8943. \t\t\t\t\tif (parentSel === triggerOffValue) {
  8944. \t\t\t\t\t\t\$(this).show();
  8945. \t\t\t\t\t} else {
  8946. \t\t\t\t\t\t\$(this).hide();
  8947. \t\t\t\t\t}
  8948. \t\t\t\t}
  8949. \t\t\t});
  8950. \t\t}
  8951. \t\t/**
  8952. \t\t * 選択中の施工オプションを集計し、ON選択分の price を合計する.
  8953. \t\t * 戻り値: { total: 合計金額, items: [{name, value, price}, ...] }
  8954. \t\t */
  8955. \t\tfunction collectOptions() {
  8956. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8957. \t\t\tvar total = 0;
  8958. \t\t\tvar items = [];
  8959. \t\t\tfor (var i = 0; i < ops.length; i++) {
  8960. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  8961. \t\t\t\tvar sel = ops[i];
  8962. \t\t\t\tif (!sel) continue;
  8963. \t\t\t\tvar price = parseInt(op_data[i].price) || 0;
  8964. \t\t\t\t// 「ON」選択時のみ加算(OFF や「不要」「商品購入のみ」は加算しない)
  8965. \t\t\t\tvar isOn = (sel === op_data[i].on);
  8966. \t\t\t\titems.push({
  8967. \t\t\t\t\tname:  op_data[i].name,
  8968. \t\t\t\t\tvalue: sel,
  8969. \t\t\t\t\tprice: isOn ? price : 0,
  8970. \t\t\t\t\ton:    op_data[i].on,
  8971. \t\t\t\t\toff:   op_data[i].off,
  8972. \t\t\t\t});
  8973. \t\t\t\tif (isOn) total += price;
  8974. \t\t\t}
  8975. \t\t\t// fe (sale_type=4) のブロック種類×段数 分を items / total に統合.
  8976. \t\t\t// 親オプション「ご希望のフェンス設置方法」 が 「新規にブロック積みを行う」 のとき
  8977. \t\t\t// だけ加算される (collectFeBlock 内で判定済み).
  8978. \t\t\tvar fb = collectFeBlock();
  8979. \t\t\tif (fb.active && fb.choice) {
  8980. \t\t\t\titems.push({
  8981. \t\t\t\t\tname:  (oi_data.fe_block && oi_data.fe_block.title) || 'ブロックの種類と段数',
  8982. \t\t\t\t\tvalue: fb.choice.label,
  8983. \t\t\t\t\tprice: fb.price,
  8984. \t\t\t\t\ton:    fb.choice.label,
  8985. \t\t\t\t\toff:   '',
  8986. \t\t\t\t});
  8987. \t\t\t\ttotal += fb.price;
  8988. \t\t\t}
  8989. \t\t\treturn { total: total, items: items };
  8990. \t\t}
  8991. \t\t/**
  8992. \t\t * free_area 1 エントリ ({w,d,h,m,c,price,unit_price,maker_price,ct,option1,option2})
  8993. \t\t * から sale_type 別に最終金額を算出する.
  8994. \t\t *
  8995. \t\t * 計算式(amount=1 ベース、出口で × 1.10 税込化):
  8996. \t\t *   1 通常        : price + ct + option_sum
  8997. \t\t *   2 補助金窓    : price × set_count + (ct + (set_count-1) × option2) + option_sum
  8998. \t\t *   3 物置        : (price + ct) × daisu + option_sum
  8999. \t\t *   4 フェンス    : price + (maisu-1) × unit_price
  9000. \t\t *                  + ct + max(0, maisu-3) × option1
  9001. \t\t *                  + option_sum   (maisu >= 3)
  9002. \t\t *   5 デッキ      : price + ct + option_sum   (area は表示用、計算非関与)
  9003. \t\t *   6 芝生        : price × ceil(area / (w_m × h_m)) + ct + option_sum
  9004. \t\t *   9 商品のみ    : price のみ(カート quantity 倍で総額)
  9005. \t\t *
  9006. \t\t * fe では option1 を ct_up、um では option2 を ct_up として転用.
  9007. \t\t * tf では w / h にロール幅・長さが格納されており parseLen で数値抽出.
  9008. \t\t *
  9009. \t\t * @param {Object} pp  free_area の 1 行(matrix エントリ)
  9010. \t\t * @param {number} optionTotal  collectOptions().total
  9011. \t\t * @param {Object} ctx  UI 入力 {set_count, daisu, maisu, area, quantityOnly, ...}
  9012. \t\t * @returns {Object} {goukei, price, ct, opt, qty}  すべて税込整数
  9013. \t\t */
  9014. \t\tfunction calcGoukei(pp, optionTotal, ctx) {
  9015. \t\t\tvar basePrice  = parseInt(pp.price)       || 0;
  9016. \t\t\tvar baseCt     = parseInt(pp.ct)          || 0;
  9017. \t\t\tvar unitPrice  = parseInt(pp.unit_price)  || 0;
  9018. \t\t\tvar optSum     = optionTotal;
  9019. \t\t\tvar price      = basePrice;
  9020. \t\t\tvar ct         = baseCt;
  9021. \t\t\tvar steelRoof  = 0;   // cp 折半屋根(スチール折板 = option1, ex-shop同額)
  9022. \t\t\tvar qty        = 1;
  9023. \t\t\tvar goukei     = 0;
  9024. \t\t\t// 「商品購入のみ」選択時は工事費・オプションをゼロにする(任意 sale_type で適用)
  9025. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  9026. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  9027. \t\t\tif (purchaseOnly) {
  9028. \t\t\t\tbaseCt = 0;
  9029. \t\t\t\tct     = 0;
  9030. \t\t\t\toptSum = 0;
  9031. \t\t\t}
  9032. \t\t\tswitch (SALE_TYPE_ID) {
  9033. \t\t\t\tcase 2: {  // 補助金・窓 (シンプル表引き方式 2026-05-)
  9034. \t\t\t\t\t// 2026-05 仕様簡素化: 枚数軸を廃止し、subtype に枚数を内包.
  9035. \t\t\t\t\t// pp.price / pp.ct は (W, H, ガラス, subtype) の単一価格.
  9036. \t\t\t\t\t// 複数枚をまとめて買う場合はカート quantity で表現.
  9037. \t\t\t\t\tqty    = 1;
  9038. \t\t\t\t\tprice  = basePrice;
  9039. \t\t\t\t\tct     = baseCt;
  9040. \t\t\t\t\tgoukei = price + ct + optSum;
  9041. \t\t\t\t\tbreak;
  9042. \t\t\t\t}
  9043. \t\t\t\tcase 3: {  // 物置・ゴミステーション
  9044. \t\t\t\t\tqty   = Math.max(1, parseInt(ctx.daisu) || 1);
  9045. \t\t\t\t\tprice = basePrice * qty;
  9046. \t\t\t\t\tct    = baseCt * qty;
  9047. \t\t\t\t\tgoukei = price + ct + optSum;
  9048. \t\t\t\t\tbreak;
  9049. \t\t\t\t}
  9050. \t\t\t\tcase 4: {  // フェンス・組み立て式(maisu ≥ 3、base_amount = 3)
  9051. \t\t\t\t\t// scraper は amount=3 を base にしているので pp.price = price(3),
  9052. \t\t\t\t\t// pp.unit_price = price(4) - price(3).
  9053. \t\t\t\t\tqty   = Math.max(3, parseInt(ctx.maisu) || 3);
  9054. \t\t\t\t\tprice = basePrice + (qty - 3) * unitPrice;
  9055. \t\t\t\t\t// option1 が ct_up (4枚目以降の増分). 未設定なら ct 固定動作
  9056. \t\t\t\t\tvar ctUp1 = parseInt(pp.option1) || 0;
  9057. \t\t\t\t\tct = baseCt + Math.max(0, qty - 3) * ctUp1;
  9058. \t\t\t\t\t// fe_block(ブロック積み段数): collectOptions が base(3枚分)を optSum に
  9059. \t\t\t\t\t// 算入済み. ブロック費も本体同様に枚数連動するため、4枚目以降は 1枚毎に
  9060. \t\t\t\t\t// choice.unit_price(= block(4)-block(3)) を加算する.
  9061. \t\t\t\t\t// (顧客指摘「何枚施工でも増える金額が同じ」の是正。unit_price 未設定の
  9062. \t\t\t\t\t//  旧データでは +0 で従来動作。)
  9063. \t\t\t\t\tif (!purchaseOnly) {
  9064. \t\t\t\t\t\tvar fbC = collectFeBlock();
  9065. \t\t\t\t\t\tif (fbC.active && fbC.choice) {
  9066. \t\t\t\t\t\t\toptSum += Math.max(0, qty - 3) * (parseInt(fbC.choice.unit_price) || 0);
  9067. \t\t\t\t\t\t}
  9068. \t\t\t\t\t}
  9069. \t\t\t\t\tgoukei = price + ct + optSum;
  9070. \t\t\t\t\tbreak;
  9071. \t\t\t\t}
  9072. \t\t\t\tcase 5: {  // ウッドデッキ・タイルデッキ
  9073. \t\t\t\t\t// area は担当者向けの参考値として保持(計算には使わない)
  9074. \t\t\t\t\tqty    = 1;
  9075. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  9076. \t\t\t\t\tprice  = basePrice;
  9077. \t\t\t\t\tct     = baseCt;
  9078. \t\t\t\t\tbreak;
  9079. \t\t\t\t}
  9080. \t\t\t\tcase 6: {  // 芝生・人工芝(ロール単位)
  9081. \t\t\t\t\t// pp.w \"1m\", pp.h \"10m\" から数値抽出
  9082. \t\t\t\t\tvar w_m = parseLen(pp.w);
  9083. \t\t\t\t\tvar h_m = parseLen(pp.h);
  9084. \t\t\t\t\tvar rollSize = w_m * h_m;
  9085. \t\t\t\t\tif (!rollSize || rollSize <= 0) rollSize = 1;
  9086. \t\t\t\t\t// 施工サイズ(面積)があれば必要枚数を自動算出。無ければ直接指定の枚数を使う。
  9087. \t\t\t\t\tvar area  = parseFloat(ctx.area) || 0;
  9088. \t\t\t\t\tif (area > 0) {
  9089. \t\t\t\t\t\tqty = Math.max(1, Math.ceil(area / rollSize));
  9090. \t\t\t\t\t} else {
  9091. \t\t\t\t\t\tqty = Math.max(1, parseInt(ctx.tf_qty) || 1);
  9092. \t\t\t\t\t}
  9093. \t\t\t\t\tprice  = basePrice * qty;
  9094. \t\t\t\t\tct     = baseCt;
  9095. \t\t\t\t\tgoukei = price + ct + optSum;
  9096. \t\t\t\t\tbreak;
  9097. \t\t\t\t}
  9098. \t\t\t\tcase 7: {  // 数量買い・基本工事費固定(gf ガーデンファニチャー / st 石材)
  9099. \t\t\t\t\tqty    = Math.max(1, parseInt(ctx.suuryou) || 1);
  9100. \t\t\t\t\tprice  = basePrice * qty;
  9101. \t\t\t\t\tct     = baseCt;                 // ct は固定(数量に依らない)
  9102. \t\t\t\t\tgoukei = price + ct + optSum;
  9103. \t\t\t\t\tbreak;
  9104. \t\t\t\t}
  9105. \t\t\t\tcase 9: {  // 商品のみ購入
  9106. \t\t\t\t\t// カート側で quantity × unit price するため goukei は単品価格
  9107. \t\t\t\t\tqty    = parseInt(ctx.quantityOnly) || 1;
  9108. \t\t\t\t\tprice  = basePrice;
  9109. \t\t\t\t\tct     = 0;
  9110. \t\t\t\t\toptSum = 0;
  9111. \t\t\t\t\tgoukei = price;
  9112. \t\t\t\t\tbreak;
  9113. \t\t\t\t}
  9114. \t\t\t\tdefault: {  // 1: 通常(カーポート等、matrix 選択のみ)
  9115. \t\t\t\t\tqty    = 1;
  9116. \t\t\t\t\t// cp 折半屋根(スチール折板 = option1, ex-shop同額)を工事費として加算。
  9117. \t\t\t\t\t// 非折板/他カテゴリは option1='' or 非数値 → 0。
  9118. \t\t\t\t\tsteelRoof = purchaseOnly ? 0 : (parseInt(pp.option1) || 0);
  9119. \t\t\t\t\tgoukei = basePrice + baseCt + steelRoof + optSum;
  9120. \t\t\t\t\tbreak;
  9121. \t\t\t\t}
  9122. \t\t\t}
  9123. \t\t\t// 出口で税込化(pp.price/pp.ct/op_data.price はすべて税抜で保存されている前提)
  9124. \t\t\t// 税込は請求額(mitsumori_json)・見積書・PDF 用。税抜(*Exc)は詳細ページの表示専用。
  9125. \t\t\treturn {
  9126. \t\t\t\tgoukei: toIncTax(goukei),
  9127. \t\t\t\tprice:  toIncTax(price),
  9128. \t\t\t\tct:     toIncTax(ct),
  9129. \t\t\t\tsteelRoof: toIncTax(steelRoof),
  9130. \t\t\t\topt:    toIncTax(optSum),
  9131. \t\t\t\tgoukeiExc: goukei,
  9132. \t\t\t\tpriceExc:  price,
  9133. \t\t\t\tctExc:     ct,
  9134. \t\t\t\tsteelRoofExc: steelRoof,
  9135. \t\t\t\toptExc:    optSum,
  9136. \t\t\t\tqty:    qty,
  9137. \t\t\t};
  9138. \t\t}
  9139. \t\t/**
  9140. \t\t * 寸法文字列から「メートル単位の数値」を抽出する.
  9141. \t\t *
  9142. \t\t * 単位は m / cm / mm を認識し、いずれも m 単位に正規化して返す.
  9143. \t\t * 単位が無い場合は m 単位とみなす(旧 tf データ \"1m\" \"10m\" との互換).
  9144. \t\t * 数値が見つからない場合は 0 を返す(呼び出し側で fallback).
  9145. \t\t *
  9146. \t\t * 例:
  9147. \t\t *   \"1m\"     → 1
  9148. \t\t *   \"100cm\"  → 1   (2026-06 以降の m → cm 正規化に対応)
  9149. \t\t *   \"200cm\"  → 2
  9150. \t\t *   \"5.5m\"   → 5.5
  9151. \t\t *   \"1000mm\" → 1
  9152. \t\t *   \"\"       → 0
  9153. \t\t */
  9154. \t\tfunction parseLen(s) {
  9155. \t\t\tif (!s) return 0;
  9156. \t\t\tvar str = String(s);
  9157. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)\\s*(mm|cm|m)?/i);
  9158. \t\t\tif (!m) return 0;
  9159. \t\t\tvar n = parseFloat(m[1]);
  9160. \t\t\tif (isNaN(n)) return 0;
  9161. \t\t\tvar unit = (m[2] || 'm').toLowerCase();
  9162. \t\t\tif (unit === 'cm') return n / 100;
  9163. \t\t\tif (unit === 'mm') return n / 1000;
  9164. \t\t\treturn n;  // 'm' or no unit
  9165. \t\t}
  9166. \t\t// pp は autoSelectFirstColor 等からも参照するので global にする
  9167. \t\tvar pp = {{ pp|raw }};
  9168. \t\t// sale_type=2 の幅 / 高さ ladder (Twig p_w / p_h を JS で参照するため).
  9169. \t\t// 入力 mm 値を pp の幅・高さバケット文字列にマッピングする際の元データ.
  9170. \t\t// p_w / p_h は連想配列で来ることがあるため Object.values で配列化する.
  9171. \t\tvar PP_W_LADDER = Object.values({{ p_w|default({})|json_encode|raw }} || {});
  9172. \t\tvar PP_H_LADDER = Object.values({{ p_h|default({})|json_encode|raw }} || {});
  9173. \t\t/* ============================================================
  9174. \t\t   sale_type=2 (補助金窓) 専用: 複数タイプ集計 & 補助金計算
  9175. \t\t   ============================================================
  9176. \t\t   - 入力 UI: #window-types-container 配下の .window-type-block
  9177. \t\t   - 補助金根拠: 先進的窓リノベ2026事業
  9178. \t\t     https://window-renovation2026.env.go.jp/construction/inner-window.html
  9179. \t\t   - 価格軸: (subtype, w, h, glass, color) で pp を lookup
  9180. \t\t   - 1 商品 = 1 明細 にまとめ、内訳 JSON を別途保存予定 (cart 連携は後続タスク)
  9181. \t\t   ============================================================ */
  9182. \t\t// 補助金マトリクス: [住宅区分][性能][サイズ区分] → 1 箇所あたり金額 (税抜・端数なし)
  9183. \t\tvar WINDOW_SUBSIDY_MATRIX = {
  9184. \t\t\tdetached:  { // 戸建住宅・延床240㎡以下の非住宅
  9185. \t\t\t\tP: { G: 140000, L: 89000, M: 58000, S: 36000 },
  9186. \t\t\t\tS: { G: 76000,  L: 52000, M: 34000, S: 22000 }
  9187. \t\t\t},
  9188. \t\t\tapartment: { // 低層・中高層集合住宅・240㎡超の非住宅
  9189. \t\t\t\tP: { G: 152000, L: 98000, M: 64000, S: 40000 },
  9190. \t\t\t\tS: { G: 83000,  L: 57000, M: 37000, S: 24000 }
  9191. \t\t\t}
  9192. \t\t};
  9193. \t\t// 住宅区分: 画面 UI (input[name=\"window_housing_type\"]) から取得する.
  9194. \t\t// 既定値は PFC meta_key=\"住宅区分\" を fallback (未設定なら '戸建').
  9195. \t\tvar HOUSING_TYPE_DEFAULT = {{ getProduct_field(Product.id, '住宅区分')|default('戸建')|json_encode|raw }};
  9196. \t\tfunction getCurrentHousingKey() {
  9197. \t\t\tvar el = document.querySelector('input[name=\"window_housing_type\"]:checked');
  9198. \t\t\tvar v  = el ? el.value : HOUSING_TYPE_DEFAULT;
  9199. \t\t\treturn (v === '集合住宅') ? 'apartment' : 'detached';
  9200. \t\t}
  9201. \t\t// 商品シリーズ自動判定 (Product.name から)
  9202. \t\t// 根拠カタログ: YKK AP「ウチリモ」XAAAA-H26-067-1 (2026.04), 同「LiteU」XAAAA-H16-088-2,
  9203. \t\t//              三協アルミ「プラメイクEII」0142_STJ1931L, LIXIL「インプラス」(既知)
  9204. \t\tvar PRODUCT_NAME_RAW = {{ Product.name|default('')|json_encode|raw }};
  9205. \t\tfunction detectProductSeries(name) {
  9206. \t\t\tif (!name) return null;
  9207. \t\t\tif (/ウチリモ/.test(name)) return 'uchirimo';
  9208. \t\t\tif (/プラマード\\s*U/i.test(name)) return 'pramado_u';
  9209. \t\t\tif (/インプラス/.test(name)) return 'inplus';
  9210. \t\t\tif (/プラメイク\\s*EII|プラメイクEII/i.test(name)) return 'plamake_eii';
  9211. \t\t\tif (/LiteU/i.test(name)) return 'lite_u';
  9212. \t\t\treturn null;
  9213. \t\t}
  9214. \t\t// シリーズ上限グレード:
  9215. \t\t//   'P'  = SS/P まで到達可能 (真空断熱ガラス採用シリーズ)
  9216. \t\t//   'S'  = Low-E 複層止まり (真空断熱ガラスのラインなし)
  9217. \t\t//   null = 単板のみ → 補助金対象外
  9218. \t\tvar SERIES_GRADE_CAP = {
  9219. \t\t\tuchirimo:    'P',
  9220. \t\t\tpramado_u:   'P',
  9221. \t\t\tinplus:      'S',
  9222. \t\t\tplamake_eii: 'S',
  9223. \t\t\tlite_u:      null
  9224. \t\t};
  9225. \t\tvar DETECTED_SERIES = detectProductSeries(PRODUCT_NAME_RAW);
  9226. \t\tvar SERIES_GRADE_CAP_VAL = (DETECTED_SERIES !== null && Object.prototype.hasOwnProperty.call(SERIES_GRADE_CAP, DETECTED_SERIES))
  9227. \t\t\t? SERIES_GRADE_CAP[DETECTED_SERIES]
  9228. \t\t\t: undefined;
  9229. \t\t// 商品単位グレード上限 (PFC `meta_key=補助金グレード上限` で個別上書き)
  9230. \t\t// 値: 'P' / 'SS' / 'S' / '対象外' / '無' / 'NONE' / 空文字 (未指定)
  9231. \t\tvar PRODUCT_GRADE_CAP_RAW = {{ getProduct_field(Product.id, '補助金グレード上限')|default('')|json_encode|raw }};
  9232. \t\tfunction normalizeGradeCap(v) {
  9233. \t\t\tif (v === null || v === undefined || v === '') return undefined;
  9234. \t\t\tvar s = String(v).trim().toUpperCase();
  9235. \t\t\tif (s === 'NONE' || s === '対象外' || s === '無') return null;
  9236. \t\t\tif (s === 'P' || s === 'SS') return 'P';
  9237. \t\t\tif (s === 'S') return 'S';
  9238. \t\t\treturn undefined;
  9239. \t\t}
  9240. \t\tvar PRODUCT_GRADE_CAP = normalizeGradeCap(PRODUCT_GRADE_CAP_RAW);
  9241. \t\t// 窓種 (subtype = option1) ごとのグレード上限.
  9242. \t\t// 根拠: YKK AP「ウチリモ」業務用 (XAAAA-H26-067-1) の窓種別ラインナップで
  9243. \t\t//      真空ガラス (Glavenir) の設定有無を確認:
  9244. \t\t//        引違い窓 (2/3/4枚建) / 浴室仕様 引違い窓 / FIX窓        → P 到達可能
  9245. \t\t//        内開き窓 (居室/浴室) / 開き窓テラス / テラスドア類       → 真空ガラスなし → S 止まり
  9246. \t\tfunction detectSubtypeGradeCap(subtype) {
  9247. \t\t\tif (!subtype) return undefined;
  9248. \t\t\tvar s = String(subtype);
  9249. \t\t\tif (/内開|開き窓テラス|テラスドア|開き戸/.test(s)) return 'S';
  9250. \t\t\treturn undefined;
  9251. \t\t}
  9252. \t\t// クリップ: 強さは 'P' > 'S' > null (対象外). cap=null は強制対象外, cap=undefined は無効化なし.
  9253. \t\tfunction clipGradeBy(grade, cap) {
  9254. \t\t\tif (cap === undefined) return grade;
  9255. \t\t\tif (cap === null)      return null;
  9256. \t\t\tif (grade === null)    return null;
  9257. \t\t\tif (cap === 'S' && grade === 'P') return 'S';
  9258. \t\t\treturn grade;
  9259. \t\t}
  9260. \t\t// D-2/D-3: 一部の窓種は Low-E に「アルゴンガス入り」が必須で、ガス無は補助対象外.
  9261. \t\t//   - 浴室仕様 (ウチリモ): Low-E は Ar入のみ S、Ar無は対象外
  9262. \t\t//   - インプラス 開き窓 / テラスドア: Low-E複層 ガス有のみ S、ガス無は対象外
  9263. \t\t//   ※ 引違い窓・FIX窓・(非浴室)内開き窓は従来どおり Ar 有無を問わない.
  9264. \t\t//   server 側 WindowSubsidyCalculator の subtypeRequiresArgon / glassHasArgon /
  9265. \t\t//   applyArgonRequirement と完全一致させること.
  9266. \t\tfunction subtypeRequiresArgon(series, subtype) {
  9267. \t\t\tvar s = String(subtype || '');
  9268. \t\t\tif (/浴室/.test(s)) return true;
  9269. \t\t\tif (series === 'inplus' && (/テラスドア/.test(s) || (/開き窓/.test(s) && !/内開き/.test(s)))) return true;
  9270. \t\t\treturn false;
  9271. \t\t}
  9272. \t\tfunction glassHasArgon(glassName) {
  9273. \t\t\treturn /アルゴンガス入り/.test(String(glassName || ''));
  9274. \t\t}
  9275. \t\tfunction applyArgonRequirement(grade, glassName, subtype) {
  9276. \t\t\tif (grade === null) return null;
  9277. \t\t\t// 真空(P)等 Low-E 以外はこの規則の対象外 (真空はガス不要).
  9278. \t\t\tif (!/Low-?E/i.test(String(glassName || ''))) return grade;
  9279. \t\t\tif (subtypeRequiresArgon(DETECTED_SERIES, subtype) && !glassHasArgon(glassName)) return null;
  9280. \t\t\treturn grade;
  9281. \t\t}
  9282. \t\tfunction finalizeGlassGrade(raw, subtype, glassName) {
  9283. \t\t\tvar g = clipGradeBy(raw, SERIES_GRADE_CAP_VAL);
  9284. \t\t\tg     = clipGradeBy(g,   detectSubtypeGradeCap(subtype));
  9285. \t\t\tg     = clipGradeBy(g,   PRODUCT_GRADE_CAP);
  9286. \t\t\tg     = applyArgonRequirement(g, glassName, subtype);
  9287. \t\t\treturn g;
  9288. \t\t}
  9289. \t\t/**
  9290. \t\t * ガラスタイプ名から性能区分 'P' (SS, Uw≤1.1) / 'S' (Uw≤1.5) / null を判別.
  9291. \t\t * null = 補助対象外.
  9292. \t\t *
  9293. \t\t * 根拠: YKK AP「ウチリモ 内窓」業務用カタログ (XAAAA-H26-069-1) で
  9294. \t\t *       P (SS) は真空断熱ガラスのみ、Low-E はアルゴン入りでも S 止まり、
  9295. \t\t *       Low-E ガス無 + 型ガラス / フロストは 2026年4月で対象外、
  9296. \t\t *       が確認できた。アルゴン入り Low-E を P 判定する旧ルールは誤りだった。
  9297. \t\t *
  9298. \t\t * シリーズによっては P がそもそも存在しない (LIXIL インプラスは S 一律)
  9299. \t\t * ため、最終的には PFC で商品単位の上限を上書きできる仕組みが必要。
  9300. \t\t */
  9301. \t\tfunction detectGlassPerformance(glassName) {
  9302. \t\t\tif (!glassName) return null;
  9303. \t\t\tvar n = String(glassName);
  9304. \t\t\t// 補助対象外: 単板 / 和紙調 / 防音 / 防犯 / 型ガラス・フロスト (Low-E ガス無の型は 2026/4 で対象外)
  9305. \t\t\tif (/単ガラス|単板|和紙調|防音|防犯|複層\\/型|型ガラス|フロスト/.test(n)) return null;
  9306. \t\t\t// P (SS): 真空断熱ガラスのみ
  9307. \t\t\tif (/真空断熱/.test(n)) return 'P';
  9308. \t\t\t// S: Low-E 系のみ (アルゴン入りでも S 止まり)
  9309. \t\t\tif (/Low-?E/i.test(n)) return 'S';
  9310. \t\t\t// 一般複層 / ブラインドイン複層 / 複層強化 など Low-E 無しの複層は補助対象外
  9311. \t\t\treturn null;
  9312. \t\t}
  9313. \t\t/**
  9314. \t\t * 幅 mm × 高さ mm からサイズ区分 'G' (≥4.0㎡) / 'L' (2.8-3.9) / 'M' (1.6-2.7) / 'S' (0.2-1.5) / null.
  9315. \t\t * null = 補助対象外 (0.2㎡ 未満).
  9316. \t\t */
  9317. \t\tfunction detectSizeClass(w_mm, h_mm) {
  9318. \t\t\tvar w = parseFloat(w_mm) || 0;
  9319. \t\t\tvar h = parseFloat(h_mm) || 0;
  9320. \t\t\tif (w <= 0 || h <= 0) return null;
  9321. \t\t\tvar area = (w * h) / 1000000.0;
  9322. \t\t\tif (area < 0.2) return null;
  9323. \t\t\tif (area < 1.6) return 'S';
  9324. \t\t\tif (area < 2.8) return 'M';
  9325. \t\t\tif (area < 4.0) return 'L';
  9326. \t\t\treturn 'G';
  9327. \t\t}
  9328. \t\tfunction lookupSubsidyAmount(performance, sizeClass) {
  9329. \t\t\tif (!performance || !sizeClass) return 0;
  9330. \t\t\tvar t = WINDOW_SUBSIDY_MATRIX[getCurrentHousingKey()];
  9331. \t\t\tif (!t || !t[performance]) return 0;
  9332. \t\t\treturn t[performance][sizeClass] || 0;
  9333. \t\t}
  9334. \t\t/**
  9335. \t\t * mm 入力値を ladder バケット文字列に変換する.
  9336. \t\t *   bucketizeMm(1750, [\"100cm まで\",\"150cm まで\",\"200cm まで\",\"300cm まで\"]) → \"200cm まで\"
  9337. \t\t * - 入力が空 or 0 のときはそのまま返す (未入力扱い)
  9338. \t\t * - 入力がラダー最大を超えるときは最大バケットを返す (= 価格上限の保護)
  9339. \t\t * - 入力文字列が既にラダーラベルそのものなら無変換 (互換のため)
  9340. \t\t */
  9341. \t\tfunction bucketizeMm(input, ladder) {
  9342. \t\t\tif (!input && input !== 0) return '';
  9343. \t\t\tif (!ladder || ladder.length === 0) return input;
  9344. \t\t\tvar s = String(input).trim();
  9345. \t\t\tif (s === '') return '';
  9346. \t\t\tif (ladder.indexOf(s) >= 0) return s;
  9347. \t\t\tvar mm = parseMm(s);
  9348. \t\t\tif (mm <= 0) return s;
  9349. \t\t\tvar withMax = ladder.map(function(b) { return { label: b, max: parseMm(b) }; });
  9350. \t\t\twithMax.sort(function(a, b) { return a.max - b.max; });
  9351. \t\t\tfor (var i = 0; i < withMax.length; i++) {
  9352. \t\t\t\tif (mm <= withMax[i].max) return withMax[i].label;
  9353. \t\t\t}
  9354. \t\t\treturn withMax[withMax.length - 1].label;
  9355. \t\t}
  9356. \t\t/**
  9357. \t\t * pp 配列から該当 1 行を返す. 完全一致優先、見つからなければ最初の候補.
  9358. \t\t * 軸: subtype (option1) / w / h / m / c. axisMatch は既存ロジックと同じ.
  9359. \t\t * sale_type=2 では pw_val / ph_val に mm 数値が来るため、内部で bucketizeMm
  9360. \t\t * を通してから既存マッチングに渡す.
  9361. \t\t */
  9362. \t\tfunction lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val) {
  9363. \t\t\tif (!pp || pp.length === 0) return null;
  9364. \t\t\tvar pw_bucket = bucketizeMm(pw_val, PP_W_LADDER);
  9365. \t\t\tvar ph_bucket = bucketizeMm(ph_val, PP_H_LADDER);
  9366. \t\t\tvar axMatch = function(input, value) {
  9367. \t\t\t\treturn input == value || input === '指定なし' || value === '' || value == null;
  9368. \t\t\t};
  9369. \t\t\tvar colMatch = function(input, value) {
  9370. \t\t\t\tif (axMatch(input, value)) return true;
  9371. \t\t\t\tif (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  9372. \t\t\t\t\treturn value.split('/').some(function(s) { return s.trim() === input; });
  9373. \t\t\t\t}
  9374. \t\t\t\treturn false;
  9375. \t\t\t};
  9376. \t\t\tvar candidates = pp.filter(function(el) {
  9377. \t\t\t\treturn axMatch(pw_bucket, el.w)
  9378. \t\t\t\t\t&& axMatch(ph_bucket, el.h)
  9379. \t\t\t\t\t&& axMatch(pm_val, el.m)
  9380. \t\t\t\t\t&& axMatch(subtype, el.option1);
  9381. \t\t\t});
  9382. \t\t\tfor (var i = 0; i < candidates.length; i++) {
  9383. \t\t\t\tif (colMatch(pc_val, candidates[i].c)) return candidates[i];
  9384. \t\t\t}
  9385. \t\t\treturn candidates[0] || null;
  9386. \t\t}
  9387. \t\t/**
  9388. \t\t * \"1000mm\" / \"200cm\" / \"1.0m\" / 単位なし → mm に正規化して返す.
  9389. \t\t * UI 上の「200cm まで」等の文字列をそのまま渡せるようにする.
  9390. \t\t */
  9391. \t\tfunction parseMm(s) {
  9392. \t\t\tif (!s) return 0;
  9393. \t\t\tvar str = String(s);
  9394. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)/);
  9395. \t\t\tif (!m) return 0;
  9396. \t\t\tvar num = parseFloat(m[1]);
  9397. \t\t\tif (/mm/i.test(str)) return num;
  9398. \t\t\tif (/cm/i.test(str)) return num * 10;
  9399. \t\t\tif (/(^|\\d)\\s*m(\$|\\W)/i.test(str)) return num * 1000;
  9400. \t\t\treturn num;
  9401. \t\t}
  9402. \t\t/**
  9403. \t\t * 1 タイプブロックから入力を読み、pp lookup → 単価・補助金額を計算して返す.
  9404. \t\t * incomplete=true: 軸のどれかが未選択 → 計算しない (UI で「未選択」を示すため).
  9405. \t\t */
  9406. \t\tfunction collectWindowTypeRow(block) {
  9407. \t\t\tvar get = function(axis) {
  9408. \t\t\t\t// radio / checkbox は :checked、それ以外 (number/text) は値そのまま.
  9409. \t\t\t\tvar radio = block.querySelector('input[data-axis=\"' + axis + '\"]:checked');
  9410. \t\t\t\tif (radio) return radio.value;
  9411. \t\t\t\tvar any = block.querySelector('input[data-axis=\"' + axis + '\"]');
  9412. \t\t\t\tif (!any) return '';
  9413. \t\t\t\tif (any.type === 'radio' || any.type === 'checkbox') return '';
  9414. \t\t\t\treturn (any.value || '').trim();
  9415. \t\t\t};
  9416. \t\t\tvar setqtyEl = block.querySelector('input[data-axis=\"setqty\"]');
  9417. \t\t\tvar subtype = get('subtype');
  9418. \t\t\tvar pw_val  = get('pw');
  9419. \t\t\tvar ph_val  = get('ph');
  9420. \t\t\tvar pm_val  = get('pm');
  9421. \t\t\tvar pc_val  = get('pc');
  9422. \t\t\tvar setqty  = setqtyEl ? Math.max(1, parseInt(setqtyEl.value) || 1) : 1;
  9423. \t\t\tvar row = {
  9424. \t\t\t\tsubtype: subtype, pw: pw_val, ph: ph_val, pm: pm_val, pc: pc_val, setqty: setqty,
  9425. \t\t\t\tunit_price_exc: 0, unit_ct_exc: 0, subsidy: 0,
  9426. \t\t\t\tsize_class: null, glass_perf: null,
  9427. \t\t\t\tincomplete: false
  9428. \t\t\t};
  9429. \t\t\t// p_option1 / p_w / p_h / p_m / color のいずれかが商品データに無いときは未選択でも完了扱いにする.
  9430. \t\t\t// (例: 商品によっては subtype が無い場合がある)
  9431. \t\t\tvar hasSubtype = !!block.querySelector('input[data-axis=\"subtype\"]');
  9432. \t\t\tvar hasPw      = !!block.querySelector('input[data-axis=\"pw\"]');
  9433. \t\t\tvar hasPh      = !!block.querySelector('input[data-axis=\"ph\"]');
  9434. \t\t\tvar hasPm      = !!block.querySelector('input[data-axis=\"pm\"]');
  9435. \t\t\tvar hasPc      = !!block.querySelector('input[data-axis=\"pc\"]');
  9436. \t\t\tif ((hasSubtype && !subtype) || (hasPw && !pw_val) || (hasPh && !ph_val)
  9437. \t\t\t    || (hasPm && !pm_val)  || (hasPc && !pc_val)) {
  9438. \t\t\t\trow.incomplete = true;
  9439. \t\t\t\treturn row;
  9440. \t\t\t}
  9441. \t\t\tvar ppRow = lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val);
  9442. \t\t\tif (ppRow) {
  9443. \t\t\t\trow.unit_price_exc = parseInt(ppRow.price) || 0;
  9444. \t\t\t\trow.unit_ct_exc    = parseInt(ppRow.ct)    || 0;
  9445. \t\t\t}
  9446. \t\t\t// ガラス名検出 → シリーズ上限 → subtype 上限 → 商品上限 の順で min クリップ.
  9447. \t\t\t// 例: LiteU (SERIES_GRADE_CAP_VAL=null) は Low-E でも null に落ちて補助対象外.
  9448. \t\t\t// 例: ウチリモの「内開き窓」subtype は真空ガラスでも S に落ちる.
  9449. \t\t\trow.glass_perf = finalizeGlassGrade(detectGlassPerformance(pm_val), subtype, pm_val);
  9450. \t\t\trow.size_class = detectSizeClass(parseMm(pw_val), parseMm(ph_val));
  9451. \t\t\trow.subsidy    = lookupSubsidyAmount(row.glass_perf, row.size_class);
  9452. \t\t\treturn row;
  9453. \t\t}
  9454. \t\t/**
  9455. \t\t * sale_type=2 用集計: 全タイプから合計を出し DOM 更新.
  9456. \t\t * 計算式 (税抜→税込で出口で 1.10 倍):
  9457. \t\t *   商品金額 = Σ(各タイプ単価 × set_qty)
  9458. \t\t *   基本工事費 = 1 回分 (各タイプ pp.ct のうち最初に得た非ゼロ値)
  9459. \t\t *   補助金合計 = Σ(各タイプ補助金 × set_qty)
  9460. \t\t *   実質支払額 = (商品+ct+option) 税込 - 補助金合計
  9461. \t\t */
  9462. \t\tfunction recalcAllForSaleType2() {
  9463. \t\t\tif (typeof SALE_TYPE_ID === 'undefined' || SALE_TYPE_ID != 2) return;
  9464. \t\t\tif (!pp || pp.length === 0) {
  9465. \t\t\t\t\$('#mitsumori_message').text('価格データ準備中');
  9466. \t\t\t\t\$('#mitsumori_btn').hide();
  9467. \t\t\t\t['#mitsumori_goukei','#mitsumori_off','#mitsumori_price','#maker_price',
  9468. \t\t\t\t '#mitsumori_ct','#mitsumori_option','#mitsumori_kei','#mitsumori_shoukei','#mitsumori_tax']
  9469. \t\t\t\t .forEach(function(s){ \$(s).text('---円'); });
  9470. \t\t\t\treturn;
  9471. \t\t\t}
  9472. \t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  9473. \t\t\tif (blocks.length === 0) return;
  9474. \t\t\tvar rows = [];
  9475. \t\t\tvar hasIncomplete = false;
  9476. \t\t\tvar baseCt = 0;
  9477. \t\t\tvar hasAnyPriced = false;
  9478. \t\t\tblocks.forEach(function(b) {
  9479. \t\t\t\tvar r = collectWindowTypeRow(b);
  9480. \t\t\t\trows.push({ block: b, row: r });
  9481. \t\t\t\tif (r.incomplete) hasIncomplete = true;
  9482. \t\t\t\tif (r.unit_ct_exc > 0 && baseCt === 0) baseCt = r.unit_ct_exc;
  9483. \t\t\t\tif (r.unit_price_exc > 0) hasAnyPriced = true;
  9484. \t\t\t\tvar subSpan = b.querySelector('.wt-subsidy-amount');
  9485. \t\t\t\tif (subSpan) subSpan.textContent = r.incomplete ? '―' : Math.round(r.subsidy * r.setqty).toLocaleString();
  9486. \t\t\t});
  9487. \t\t\tif (hasIncomplete || !hasAnyPriced) {
  9488. \t\t\t\t\$('#mitsumori_message').text('窓タイプを選択してください');
  9489. \t\t\t\t\$('#mitsumori_btn').hide();
  9490. \t\t\t\treturn;
  9491. \t\t\t}
  9492. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  9493. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  9494. \t\t\tvar sumPriceExc = 0, sumSubsidy = 0, totalPanes = 0;
  9495. \t\t\trows.forEach(function(item) {
  9496. \t\t\t\tvar r = item.row;
  9497. \t\t\t\tsumPriceExc += r.unit_price_exc * r.setqty;
  9498. \t\t\t\tsumSubsidy  += r.subsidy * r.setqty;
  9499. \t\t\t\tif (r.unit_price_exc > 0) totalPanes += r.setqty;
  9500. \t\t\t});
  9501. \t\t\t// 内窓 工事費(顧客最終回答): 1枚目 22,000円 + 2枚目以降 1枚あたり +5,000円(税込表示額)。
  9502. \t\t\t// 既存パイプライン整合のため税抜(ctExc)も用意(税行 taxAmt 用)。商品購入のみは 0。
  9503. \t\t\tvar WINDOW_CT_BASE = 22000, WINDOW_CT_ADD = 5000;
  9504. \t\t\tvar ctIncTarget = purchaseOnly ? 0 : (WINDOW_CT_BASE + Math.max(0, totalPanes - 1) * WINDOW_CT_ADD);
  9505. \t\t\tvar ctExc  = purchaseOnly ? 0 : Math.round(ctIncTarget / (1 + TAX_RATE));
  9506. \t\t\tvar optExc = purchaseOnly ? 0 : (collectOptions().total || 0);
  9507. \t\t\tvar sumPriceInc = Math.round(sumPriceExc * (1 + TAX_RATE));
  9508. \t\t\tvar ctInc       = ctIncTarget;
  9509. \t\t\tvar optInc      = Math.round(optExc * (1 + TAX_RATE));
  9510. \t\t\tvar goukeiInc   = sumPriceInc + ctInc + optInc;
  9511. \t\t\t// 窓リノベ2026 申請条件:
  9512. \t\t\t//   - 補助金合計 ≥ 50,000 円 (5 万円未満は申請不可 → 還元 0 円扱い)
  9513. \t\t\t//   - 1 戸あたり上限 1,000,000 円 (住宅・非住宅240㎡以下)
  9514. \t\t\t//     ※ 非住宅 240㎡超の 10,000,000 円上限は対象外 (商品設計時に別扱い想定)
  9515. \t\t\tvar SUBSIDY_MIN_AMOUNT = 50000;
  9516. \t\t\tvar SUBSIDY_MAX_PER_UNIT = 1000000;
  9517. \t\t\tvar subsidyRawSum = sumSubsidy;
  9518. \t\t\tvar subsidyEligible = subsidyRawSum >= SUBSIDY_MIN_AMOUNT;
  9519. \t\t\tvar subsidyAmt = 0;
  9520. \t\t\tvar subsidyNote = '';
  9521. \t\t\tif (subsidyEligible) {
  9522. \t\t\t\tif (subsidyRawSum > SUBSIDY_MAX_PER_UNIT) {
  9523. \t\t\t\t\tsubsidyAmt = SUBSIDY_MAX_PER_UNIT;
  9524. \t\t\t\t\tsubsidyNote = '※補助上限 ' + SUBSIDY_MAX_PER_UNIT.toLocaleString()
  9525. \t\t\t\t\t\t+ '円 超過分は控除対象外(補助金合計 ' + subsidyRawSum.toLocaleString() + '円)';
  9526. \t\t\t\t} else {
  9527. \t\t\t\t\tsubsidyAmt = subsidyRawSum;
  9528. \t\t\t\t\tsubsidyNote = '※補助金合計 ' + subsidyRawSum.toLocaleString()
  9529. \t\t\t\t\t\t+ '円(5万円以上)が適用されます';
  9530. \t\t\t\t}
  9531. \t\t\t} else if (subsidyRawSum > 0) {
  9532. \t\t\t\t// (b) per-window 補助金額は常時表示。合計5万円以上で適用される旨と
  9533. \t\t\t\t//     あといくらで適用かを明示する(閾値 SUBSIDY_MIN_AMOUNT は据え置き)。
  9534. \t\t\t\tvar subsidyShort = SUBSIDY_MIN_AMOUNT - subsidyRawSum;
  9535. \t\t\t\tsubsidyNote = '※補助金は各窓の補助金額の合計が5万円以上で適用されます'
  9536. \t\t\t\t\t+ '(現在の合計 ' + subsidyRawSum.toLocaleString() + '円 / あと '
  9537. \t\t\t\t\t+ subsidyShort.toLocaleString() + '円で適用)';
  9538. \t\t\t} else if (SERIES_GRADE_CAP_VAL === null) {
  9539. \t\t\t\t// LiteU 等の単板構成シリーズ: グレード判定で必ず null になる
  9540. \t\t\t\tsubsidyNote = '※本商品は補助金(先進的窓リノベ2026事業)対象外です';
  9541. \t\t\t} else if (PRODUCT_GRADE_CAP === null) {
  9542. \t\t\t\tsubsidyNote = '※本商品は補助金対象外として登録されています';
  9543. \t\t\t}
  9544. \t\t\tvar implementedInc = Math.max(0, goukeiInc - subsidyAmt);
  9545. \t\t\tvar taxAmt      = Math.round((sumPriceExc + ctExc + optExc) * TAX_RATE);
  9546. \t\t\t// 詳細ページの見積カード/ヘッダー/SPバーは税抜表示に統一.
  9547. \t\t\t// 見積書(#mitsumori_kei)・実質支払額(#mitsumori_shoukei)・税額・json は税込のまま (請求額不変).
  9548. \t\t\tvar goukeiExc = sumPriceExc + ctExc + optExc;
  9549. \t\t\t\$('#mitsumori_message').text(subsidyNote);
  9550. \t\t\t\$('#mitsumori_btn').show();
  9551. \t\t\t\$('#mitsumori_goukei').text(goukeiExc.toLocaleString() + '円');
  9552. \t\t\t\$('#mitsumori_price').text(sumPriceExc.toLocaleString() + '円');
  9553. \t\t\t\$('#mitsumori_ct').text(ctExc.toLocaleString() + '円');
  9554. \t\t\t\$('#mitsumori_option').text(optExc.toLocaleString() + '円');
  9555. \t\t\t\$('#mitsumori_off').text((subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円');
  9556. \t\t\t\$('#maker_price').text('---円'); // 補助金窓では未使用
  9557. \t\t\t\$('#mitsumori_kei').text(goukeiInc.toLocaleString() + '円');
  9558. \t\t\t\$('#mitsumori_shoukei').text(implementedInc.toLocaleString() + '円');
  9559. \t\t\t\$('#mitsumori_tax').text(taxAmt.toLocaleString() + '円');
  9560. \t\t\t// 内訳を mitsumori_json に詰めて hidden input にセット (PDF / カート連携用)
  9561. \t\t\tvar window_types = rows.map(function(item) {
  9562. \t\t\t\tvar r = item.row;
  9563. \t\t\t\t// 幅 / 高さは数値入力 (mm) が来るので \"1750mm\" 形式で保存する.
  9564. \t\t\t\t// 古い radio 由来の \"200cm まで\" 形式が来た場合はそのまま保存して互換.
  9565. \t\t\t\tvar w_mm = parseMm(r.pw);
  9566. \t\t\t\tvar h_mm = parseMm(r.ph);
  9567. \t\t\t\tvar w_save = (w_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.pw))) ? (w_mm + 'mm') : r.pw;
  9568. \t\t\t\tvar h_save = (h_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.ph))) ? (h_mm + 'mm') : r.ph;
  9569. \t\t\t\treturn {
  9570. \t\t\t\t\tsubtype:        r.subtype,
  9571. \t\t\t\t\tw:              w_save,
  9572. \t\t\t\t\th:              h_save,
  9573. \t\t\t\t\tglass:          r.pm,
  9574. \t\t\t\t\tcolor:          r.pc,
  9575. \t\t\t\t\tsetqty:         r.setqty,
  9576. \t\t\t\t\tunit_price_inc: Math.round(r.unit_price_exc * (1 + TAX_RATE)),
  9577. \t\t\t\t\tline_total_inc: Math.round(r.unit_price_exc * r.setqty * (1 + TAX_RATE)),
  9578. \t\t\t\t\tsize_class:     r.size_class,
  9579. \t\t\t\t\tglass_perf:     r.glass_perf,
  9580. \t\t\t\t\tsubsidy_unit:   r.subsidy,
  9581. \t\t\t\t\tsubsidy_total:  r.subsidy * r.setqty
  9582. \t\t\t\t};
  9583. \t\t\t});
  9584. \t\t\tvar opCalc2 = collectOptions();
  9585. \t\t\tvar mitsumori_json = {
  9586. \t\t\t\t\"mitsumori_goukei\": goukeiInc.toLocaleString() + '円',
  9587. \t\t\t\t\"mitsumori_price\":  sumPriceInc.toLocaleString() + '円',
  9588. \t\t\t\t\"mitsumori_ct\":     ctInc.toLocaleString() + '円',
  9589. \t\t\t\t\"mitsumori_option\": optInc.toLocaleString() + '円',
  9590. \t\t\t\t\"mitsumori_off\":    (subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円',
  9591. \t\t\t\t\"maker_price\":      '---円',
  9592. \t\t\t\t\"product_id\":       {{ Product.id }},
  9593. \t\t\t\t\"sale_type\":        SALE_TYPE_ID,
  9594. \t\t\t\t\"housing_key\":      getCurrentHousingKey(),
  9595. \t\t\t\t\"series_key\":       DETECTED_SERIES,
  9596. \t\t\t\t\"series_grade_cap\": (SERIES_GRADE_CAP_VAL === undefined) ? null : SERIES_GRADE_CAP_VAL,
  9597. \t\t\t\t\"product_grade_cap\":(PRODUCT_GRADE_CAP    === undefined) ? null : PRODUCT_GRADE_CAP,
  9598. \t\t\t\t\"window_types\":     window_types,
  9599. \t\t\t\t\"subsidy_total\":    subsidyAmt,
  9600. \t\t\t\t\"subsidy_raw\":      subsidyRawSum,
  9601. \t\t\t\t\"subsidy_eligible\": subsidyEligible,
  9602. \t\t\t\t\"subsidy_note\":     subsidyNote,
  9603. \t\t\t\t\"op_items\":         opCalc2.items
  9604. \t\t\t};
  9605. \t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  9606. \t\t\trenderWindowTypesModalRows(window_types, subsidyAmt);
  9607. \t\t}
  9608. \t\t/**
  9609. \t\t * sale_type=2 用: 見積モーダル明細テーブルを window_types で動的展開.
  9610. \t\t * - 既存の商品名行 (1 行目) は hide() し、各タイプ行を上に挿入
  9611. \t\t * - 基本工事費行はそのまま (#mitsumori_ct_01 / _02 が更新されている)
  9612. \t\t * - 補助金 (割引額) 行を末尾に追加
  9613. \t\t * - 既存の renderOptionDetailRows と共存できるよう class で区別
  9614. \t\t */
  9615. \t\tfunction renderWindowTypesModalRows(window_types, subsidyAmt) {
  9616. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  9617. \t\t\tif (!\$tbody.length) return;
  9618. \t\t\t// 既存の動的行を全削除 (opt-row は既存実装、wt-row / wt-subsidy-row は今回追加)
  9619. \t\t\t\$tbody.find('tr.wt-row, tr.wt-subsidy-row').remove();
  9620. \t\t\tvar \$itemRow = \$tbody.find('tr').first();
  9621. \t\t\tvar fmt = new Intl.NumberFormat('ja-JP');
  9622. \t\t\tif (!window_types || window_types.length === 0) {
  9623. \t\t\t\t// 集計対象なし → 商品名行を表示に戻す
  9624. \t\t\t\t\$itemRow.show();
  9625. \t\t\t\treturn;
  9626. \t\t\t}
  9627. \t\t\twindow_types.forEach(function(wt, i) {
  9628. \t\t\t\tvar label = '窓タイプ' + (i + 1) + ':'
  9629. \t\t\t\t\t+ (wt.subtype || '') + ' / '
  9630. \t\t\t\t\t+ (wt.w || '') + '×' + (wt.h || '') + ' / '
  9631. \t\t\t\t\t+ (wt.glass || '') + ' / '
  9632. \t\t\t\t\t+ (wt.color || '');
  9633. \t\t\t\tvar \$tr = \$('<tr class=\"wt-row\"></tr>')
  9634. \t\t\t\t\t.append('<td>' + label + '</td>')
  9635. \t\t\t\t\t.append('<td>' + wt.setqty + '</td>')
  9636. \t\t\t\t\t.append('<td>セット</td>')
  9637. \t\t\t\t\t.append('<td>' + fmt.format(wt.unit_price_inc) + '円</td>')
  9638. \t\t\t\t\t.append('<td>' + fmt.format(wt.line_total_inc) + '円</td>');
  9639. \t\t\t\t\$itemRow.before(\$tr);
  9640. \t\t\t});
  9641. \t\t\t// 元の商品名行は複数タイプに置換されたので非表示
  9642. \t\t\t\$itemRow.hide();
  9643. \t\t\t// 補助金(割引額)行を末尾に追加
  9644. \t\t\tif (subsidyAmt > 0) {
  9645. \t\t\t\tvar \$subRow = \$('<tr class=\"wt-subsidy-row\"></tr>')
  9646. \t\t\t\t\t.append('<td>補助金(割引額)</td>')
  9647. \t\t\t\t\t.append('<td>1</td>')
  9648. \t\t\t\t\t.append('<td>式</td>')
  9649. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>')
  9650. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>');
  9651. \t\t\t\t\$tbody.append(\$subRow);
  9652. \t\t\t}
  9653. \t\t}
  9654. \t\t// 公開: onWindowTypeAxisChange (UI 骨格 task 1) からも呼ばれる
  9655. \t\twindow.recalcAll = recalcAllForSaleType2;
  9656. \t\t// 公開: ガラス選択肢が補助金対象か (窓タイプブロック生成時のバッジ判定に使う).
  9657. \t\t// subtype は P→S に落とすことはあっても null にはしないため、性能区分の
  9658. \t\t// 対象/対象外は subtype に依存しない。ここでは series/product 上限のみ適用し、
  9659. \t\t// finalizeGlassGrade が null でなければ「補助金対象ガラス」と判定する。
  9660. \t\twindow.glassYieldsSubsidy = function(glassName) {
  9661. \t\t\tif (!glassName) return false;
  9662. \t\t\treturn finalizeGlassGrade(detectGlassPerformance(glassName), '', glassName) !== null;
  9663. \t\t};
  9664. \t\tfunction mitsumori_simulation(type , value_id){
  9665. \t\t\t// sale_type=2 (補助金窓) は複数タイプ集計 UI に統合済み. 既存 mitsumori_simulation は使わない.
  9666. \t\t\tif (typeof SALE_TYPE_ID !== 'undefined' && SALE_TYPE_ID == 2) {
  9667. \t\t\t\t// type/value_id が op\\d+ (施工オプション) の場合はグローバル変数を先に更新
  9668. \t\t\t\tif (type && /^op\\d+\$/.test(type) && value_id) {
  9669. \t\t\t\t\tvar v = \$('#'+value_id).val();
  9670. \t\t\t\t\tif (type === 'op0')  op0  = v;
  9671. \t\t\t\t\tif (type === 'op1')  op1  = v;
  9672. \t\t\t\t\tif (type === 'op2')  op2  = v;
  9673. \t\t\t\t\tif (type === 'op3')  op3  = v;
  9674. \t\t\t\t\tif (type === 'op4')  op4  = v;
  9675. \t\t\t\t\tif (type === 'op5')  op5  = v;
  9676. \t\t\t\t\tif (type === 'op6')  op6  = v;
  9677. \t\t\t\t\tif (type === 'op7')  op7  = v;
  9678. \t\t\t\t\tif (type === 'op8')  op8  = v;
  9679. \t\t\t\t\tif (type === 'op9')  op9  = v;
  9680. \t\t\t\t\tif (type === 'op10') op10 = v;
  9681. \t\t\t\t}
  9682. \t\t\t\trecalcAllForSaleType2();
  9683. \t\t\t\treturn;
  9684. \t\t\t}
  9685. \t\t\t// 価格データ未登録 (pp 行 0 件) の商品は axis 入力に依存せず
  9686. \t\t\t// 「価格データ準備中」を表示して終了する.
  9687. \t\t\t// (例: scrape 未対象の新規商品 — um のウチリモ 7487/7488 等)
  9688. \t\t\tif (!pp || pp.length === 0) {
  9689. \t\t\t\t\$('#mitsumori_message').text(\"価格データ準備中\");
  9690. \t\t\t\t\$('#mitsumori_btn').hide();
  9691. \t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9692. \t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9693. \t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9694. \t\t\t\t\$('#maker_price').text(\"---円\");
  9695. \t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9696. \t\t\t\t\$('#mitsumori_steelroof_row').hide();
  9697. \t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9698. \t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  9699. \t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  9700. \t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  9701. \t\t\t\treturn;
  9702. \t\t\t}
  9703. \t\t\tif(type == \"pw\"){
  9704. \t\t\t\tpw = \$('#'+value_id).val();
  9705. \t\t\t}
  9706. \t\t\tif(type == \"pd\"){
  9707. \t\t\t\tpd = \$('#'+value_id).val();
  9708. \t\t\t}
  9709. \t\t\tif(type == \"ph\"){
  9710. \t\t\t\tph = \$('#'+value_id).val();
  9711. \t\t\t}
  9712. \t\t\tif(type == \"pm\"){
  9713. \t\t\t\tpm = \$('#'+value_id).val();
  9714. \t\t\t}
  9715. \t\t\tif(type == \"pc\"){
  9716. \t\t\t\tpc = \$('#'+value_id).val();
  9717. \t\t\t}
  9718. \t\t\tif(type == \"option1\"){
  9719. \t\t\t\toption1 = \$('#'+value_id).val();
  9720. \t\t\t}
  9721. \t\t\tif(type == \"option2\"){
  9722. \t\t\t\toption2 = \$('#'+value_id).val();
  9723. \t\t\t}
  9724. \t\t\tif(type == \"op0\"){ op0 = \$('#'+value_id).val(); }
  9725. \t\t\tif(type == \"op1\"){ op1 = \$('#'+value_id).val(); }
  9726. \t\t\tif(type == \"op2\"){ op2 = \$('#'+value_id).val(); }
  9727. \t\t\tif(type == \"op3\"){ op3 = \$('#'+value_id).val(); }
  9728. \t\t\tif(type == \"op4\"){ op4 = \$('#'+value_id).val(); }
  9729. \t\t\tif(type == \"op5\"){ op5 = \$('#'+value_id).val(); }
  9730. \t\t\tif(type == \"op6\"){ op6 = \$('#'+value_id).val(); }
  9731. \t\t\tif(type == \"op7\"){ op7 = \$('#'+value_id).val(); }
  9732. \t\t\tif(type == \"op8\"){ op8 = \$('#'+value_id).val(); }
  9733. \t\t\tif(type == \"op9\"){ op9 = \$('#'+value_id).val(); }
  9734. \t\t\tif(type == \"op10\"){ op10 = \$('#'+value_id).val(); }
  9735. \t\t\t// op0 が「商品購入のみ」のとき、他のオプション (op1..op10) を disable 化.
  9736. \t\t\t// 価格計算側 (calcGoukei の purchaseOnly 分岐) は既にゼロ化しているが、
  9737. \t\t\t// UI で選択可能に見えるとユーザーが混乱するため radio を完全に無効化する.
  9738. \t\t\t(function applyPurchaseOnlyUI() {
  9739. \t\t\t\tvar isPurchaseOnly = (op0 === '商品購入のみ');
  9740. \t\t\t\tfor (var k = 1; k <= 10; k++) {
  9741. \t\t\t\t\tvar \$inputs = \$('input[name=\"op' + k + '\"]');
  9742. \t\t\t\t\tif (\$inputs.length === 0) continue;
  9743. \t\t\t\t\t\$inputs.prop('disabled', isPurchaseOnly);
  9744. \t\t\t\t\tvar \$group = \$inputs.first().closest('.form-group');
  9745. \t\t\t\t\t\$group.css({
  9746. \t\t\t\t\t\t'opacity':        isPurchaseOnly ? '0.4'  : '1',
  9747. \t\t\t\t\t\t'pointer-events': isPurchaseOnly ? 'none' : 'auto'
  9748. \t\t\t\t\t});
  9749. \t\t\t\t}
  9750. \t\t\t})();
  9751. \t\t\t// 全 type 共通: 該当 radio を checked にし、ボタンの is-selected を付け替え + ラベル更新.
  9752. \t\t\t//   value_id が指定されていて、対応する DOM 要素が opt-btn 配下にあれば適用する.
  9753. \t\t\t//   (icheck-danger 形式から opt-btn 形式に統一した際、option1/option2/pw/pd/ph/pm/pc 等の
  9754. \t\t\t//    クリックで is-selected が更新されない不具合があったため、op\\d+ 限定の処理を一般化)
  9755. \t\t\tif (value_id) {
  9756. \t\t\t\tvar \$clicked = \$('#' + value_id);
  9757. \t\t\t\tif (\$clicked.length && \$clicked.closest('.opt-btn').length) {
  9758. \t\t\t\t\t\$clicked.prop('checked', true);
  9759. \t\t\t\t\tvar groupName = \$clicked.attr('name');
  9760. \t\t\t\t\t\$('input[name=\"' + groupName + '\"]').closest('.opt-btn').removeClass('is-selected');
  9761. \t\t\t\t\t\$clicked.closest('.opt-btn').addClass('is-selected');
  9762. \t\t\t\t\tvar \$group = \$clicked.closest('.form-group');
  9763. \t\t\t\t\tvar \$label = \$group.find('.rp-section-label');
  9764. \t\t\t\t\tif (\$label.length) {
  9765. \t\t\t\t\t\tvar labelText = \$label.text().split(':')[0].trim();
  9766. \t\t\t\t\t\t\$label.html(labelText + ': <span>' + \$clicked.val() + '</span>');
  9767. \t\t\t\t\t}
  9768. \t\t\t\t\t// op_data の price=0 & 解体/撤去/設置場所 オプションの場合、ON 選択時に「現場調査後に正式お見積もり」文言を表示.
  9769. \t\t\t\t\t//   (twig 側で is_removal_unknown ブロックを描画済み。display 切替のみ JS で行う)
  9770. \t\t\t\t\tif (/^op\\d+\$/.test(type)) {
  9771. \t\t\t\t\t\tvar opIdx = type.replace('op', '');
  9772. \t\t\t\t\t\tvar opEntry = op_data[parseInt(opIdx)];
  9773. \t\t\t\t\t\tif (opEntry) {
  9774. \t\t\t\t\t\t\tvar \$note = \$group.find('.opt-survey-note[data-op-idx=\"' + opIdx + '\"]');
  9775. \t\t\t\t\t\t\tif (\$note.length) {
  9776. \t\t\t\t\t\t\t\tvar isOn = (\$clicked.val() === opEntry.on);
  9777. \t\t\t\t\t\t\t\t\$note.toggle(isOn);
  9778. \t\t\t\t\t\t\t}
  9779. \t\t\t\t\t\t}
  9780. \t\t\t\t\t\t// wd (sale_type=5) のステップ / デッキフェンス用の注記もここで切替.
  9781. \t\t\t\t\t\t//   ステップ → deck_step (op0 だが op_data 範囲外), 必要 選択時に表示.
  9782. \t\t\t\t\t\tvar radioName = \$clicked.attr('name');
  9783. \t\t\t\t\t\tif (radioName === 'deck_step') {
  9784. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-step').toggle(\$clicked.val() === '必要');
  9785. \t\t\t\t\t\t} else if (radioName === 'deck_fence') {
  9786. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-fence').toggle(\$clicked.val() === '必要');
  9787. \t\t\t\t\t\t}
  9788. \t\t\t\t\t}
  9789. \t\t\t\t}
  9790. \t\t\t}
  9791. \t\t\t// 必須項目チェックは sale_type 1 系(カーポート/物置/フェンスなど価格マトリクス必要)に限定
  9792. \t\t\tvar requireMatrix = (SALE_TYPE_ID == 1 || SALE_TYPE_ID == 2 || SALE_TYPE_ID == 3 || SALE_TYPE_ID == 4 || SALE_TYPE_ID == 5 || SALE_TYPE_ID == 6 || SALE_TYPE_ID == 7 || SALE_TYPE_ID == 9);
  9793. \t\t\t// sale_type=3 (物置・ゴミステーション・照明 等) では「素材」を選択肢として扱わない.
  9794. \t\t\t//   - mo/gs/sy は m が \"指定なし\" など名目的にしか入っていない
  9795. \t\t\t//   - sl は m が空のままで matrix に行が来る
  9796. \t\t\t//   そのため pm の必須チェックを sale_type=3 でスキップする。
  9797. \t\t\tvar pmRequired = (SALE_TYPE_ID != 3);
  9798. \t\t\tif (requireMatrix) {
  9799. \t\t\t\tif(pmRequired && pm == \"\"){
  9800. \t\t\t\t\t\$('#mitsumori_message').text(\"素材を選択してください\");
  9801. \t\t\t\t}
  9802. \t\t\t\tif(ph == \"\"){
  9803. \t\t\t\t\t\$('#mitsumori_message').text(\"高さを選択してください\");
  9804. \t\t\t\t}
  9805. \t\t\t\tif(pd == \"\"){
  9806. \t\t\t\t\t\$('#mitsumori_message').text(\"奥行きを選択してください\");
  9807. \t\t\t\t}
  9808. \t\t\t\tif(pw == \"\"){
  9809. \t\t\t\t\t\$('#mitsumori_message').text(\"幅を選択してください\");
  9810. \t\t\t\t}
  9811. \t\t\t\tif(pc == \"\"){
  9812. \t\t\t\t\t\$('#mitsumori_message').text(\"カラーを選択してください\");
  9813. \t\t\t\t\t\$('#mitsumori_btn').hide();
  9814. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9815. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9816. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9817. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  9818. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9819. \t\t\t\t\$('#mitsumori_steelroof_row').hide();
  9820. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9821. \t\t\t\t}
  9822. \t\t\t}
  9823. \t\t\tif(pw != \"\" && pd != \"\" && ph != \"\" && (!pmRequired || pm != \"\") && pc != \"\"){
  9824. \t\t\t\t\$('#mitsumori_btn').show();
  9825. \t\t\t\t// 入力コンテキスト(sale_type 別パラメータ)
  9826. \t\t\t\tvar ctx = {
  9827. \t\t\t\t\tset_count:    parseInt(\$('#set_count').val())    || 1,
  9828. \t\t\t\t\tdaisu:        parseInt(\$('#daisu').val())        || 1,
  9829. \t\t\t\t\tmaisu:        parseInt(\$('#maisu').val())        || 3,
  9830. \t\t\t\t\tsuuryou:      parseInt(\$('#suuryou').val())      || 1,
  9831. \t\t\t\t\tarea:         (function(){
  9832. \t\t\t\t\t\t// tf(人工芝): 施工サイズ 縦(m)×横(m) から面積を算出し #area に反映.
  9833. \t\t\t\t\t\tvar L = parseFloat(\$('#tf_len').val()) || 0;
  9834. \t\t\t\t\t\tvar W = parseFloat(\$('#tf_wid').val()) || 0;
  9835. \t\t\t\t\t\tif (L > 0 && W > 0) { var a = L * W; \$('#area').val(a); return a; }
  9836. \t\t\t\t\t\treturn parseFloat(\$('#area').val()) || 0;
  9837. \t\t\t\t\t})(),
  9838. \t\t\t\t\ttf_len:       parseFloat(\$('#tf_len').val())     || 0,
  9839. \t\t\t\t\ttf_wid:       parseFloat(\$('#tf_wid').val())     || 0,
  9840. \t\t\t\t\ttf_qty:       parseInt(\$('#tf_qty').val())       || 1,
  9841. \t\t\t\t\tquantityOnly: parseInt(\$('#quantity_only').val())|| 1,
  9842. \t\t\t\t\tmado_w:       \$('#mado_w').val() || '',
  9843. \t\t\t\t\tmado_h:       \$('#mado_h').val() || '',
  9844. \t\t\t\t\tmado_type:    \$('input[name=mado_type]:checked').val()  || '',
  9845. \t\t\t\t\tglass_type:   \$('input[name=glass_type]:checked').val() || '',
  9846. \t\t\t\t\tdeck_step:    \$('input[name=deck_step]:checked').val()  || '',
  9847. \t\t\t\t\tdeck_fence:   \$('input[name=deck_fence]:checked').val() || '',
  9848. \t\t\t\t};
  9849. \t\t\t\t// 施工オプション集計(残土処理を含む)
  9850. \t\t\t\tvar opCalc = collectOptions();
  9851. \t\t\t\tvar pp_matched = false;
  9852. \t\t\t\t// 各軸の汎用 axisMatch:
  9853. \t\t\t\t//   user 選択 == matrix 値 / user \"指定なし\" / matrix 値が空
  9854. \t\t\t\tvar axisMatch = function(input, value){
  9855. \t\t\t\t    return input == value || input == \"指定なし\" || value === \"\" || value == null;
  9856. \t\t\t\t};
  9857. \t\t\t\t// 色専用マッチャー: scraper のデータ形式に合わせて拡張する
  9858. \t\t\t\t//   1. 完全一致 / \"指定なし\" / 値が空 → 真 (axisMatch と同じ)
  9859. \t\t\t\t//   2. matrix 値が \"色1/色2/色3\" の形 (同価格グループ) → split して user 選択が含まれれば真
  9860. \t\t\t\t// scraper のロジック (scraper_price.py L765-779):
  9861. \t\t\t\t//   全色同価格 → c=\"\"、価格違いグループあり → 各 group を \"/\" 結合した色名で 1 行
  9862. \t\t\t\tvar colorMatch = function(input, value){
  9863. \t\t\t\t    if (axisMatch(input, value)) return true;
  9864. \t\t\t\t    if (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  9865. \t\t\t\t        var parts = value.split('/');
  9866. \t\t\t\t        for (var idx = 0; idx < parts.length; idx++) {
  9867. \t\t\t\t            if (parts[idx].trim() === input) return true;
  9868. \t\t\t\t        }
  9869. \t\t\t\t    }
  9870. \t\t\t\t    return false;
  9871. \t\t\t\t};
  9872. \t\t\t\t// 他軸 (w/d/h/m + option1/option2) でマッチする pp 行を抽出.
  9873. \t\t\t\t// option1/option2 は um の subtype 等で使われる. axisMatch は free_area 側が
  9874. \t\t\t\t// 空のとき真を返すので、um 以外のカテゴリ (option 軸を使わない) でも影響なし.
  9875. \t\t\t\tvar candidates = pp.filter(function(el){
  9876. \t\t\t\t    return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m)
  9877. \t\t\t\t        && axisMatch(option1, el.option1) && axisMatch(option2, el.option2);
  9878. \t\t\t\t});
  9879. \t\t\t\t// フォールバック: 全軸一致が 0 件のときに限り option1/option2 を無視して再マッチ。
  9880. \t\t\t\t// 玄関ドア等で option1(なし/ランマ付き)・option2(◯◯タイプ) が pm(開き方) から
  9881. \t\t\t\t// 導出可能な冗長軸で、未選択だと全軸 AND 一致を満たせず価格が出ない事象の救済。
  9882. \t\t\t\t// pm/幅/奥行/高さ は従来どおり一致を要求するため通常商品の価格選択に影響しない。
  9883. \t\t\t\tif (candidates.length === 0) {
  9884. \t\t\t\t    candidates = pp.filter(function(el){
  9885. \t\t\t\t        return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m);
  9886. \t\t\t\t    });
  9887. \t\t\t\t}
  9888. \t\t\t\tvar picked = null;
  9889. \t\t\t\t// 優先 1: 色も含めて完全一致 (\"色1/色2\" 形式の split match を含む)
  9890. \t\t\t\tfor (var ii = 0; ii < candidates.length; ii++) {
  9891. \t\t\t\t    if (colorMatch(pc, candidates[ii].c)) { picked = candidates[ii]; break; }
  9892. \t\t\t\t}
  9893. \t\t\t\t// 優先 2: 完全一致なし & user の pc が候補のどの c 値にも該当しない (= 命名違い等)
  9894. \t\t\t\t//   かつ候補全行で price が一致する場合は、色軸を実質無視して先頭行を採用.
  9895. \t\t\t\t//   例 id=3353: pp.c は \"ステンカラー+...\" 6種だが price は全て同じなので
  9896. \t\t\t\t//     SM(スミ) を選んでも安全に最初の行の価格を返せる.
  9897. \t\t\t\tif (!picked && candidates.length > 0) {
  9898. \t\t\t\t    var ppCsInCand = candidates.map(function(r){ return r.c || ''; });
  9899. \t\t\t\t    var pcAbsent = (pc !== '' && pc !== '指定なし' && ppCsInCand.indexOf(pc) === -1
  9900. \t\t\t\t                    && ppCsInCand.every(function(v){ return v.indexOf('/') === -1 || v.split('/').map(function(s){return s.trim();}).indexOf(pc) === -1; }));
  9901. \t\t\t\t    if (pcAbsent) {
  9902. \t\t\t\t        var uniqPrices = new Set();
  9903. \t\t\t\t        candidates.forEach(function(r){ uniqPrices.add(String(r.price)); });
  9904. \t\t\t\t        if (uniqPrices.size === 1) {
  9905. \t\t\t\t            // 全候補同価格 → 色軸を wildcard 扱いで OK
  9906. \t\t\t\t            picked = candidates[0];
  9907. \t\t\t\t        }
  9908. \t\t\t\t        // 価格が異なる場合は意図的に picked=null のまま「対応しておりません」.
  9909. \t\t\t\t    }
  9910. \t\t\t\t}
  9911. \t\t\t\t// 請求額・見積書・PDF 用の税込値 (表示は税抜だが json は税込で不変).
  9912. \t\t\t\t// 未マッチ時は '---円' のまま送る.
  9913. \t\t\t\tvar jGoukei = '---円', jGoukei02 = '---円', jPrice = '---円',
  9914. \t\t\t\t    jMaker = '---円', jOff = '---円', jCt = '---円', jOption = '---円';
  9915. \t\t\t\tpp.forEach((el) => {
  9916. \t\t\t\t  if (el === picked) {
  9917. \t\t\t\t\tpp_matched = true;
  9918. \t\t\t\t\t// tg block-keyed オプション差額を集計 (tg 以外は total=0)
  9919. \t\t\t\t\tvar oiCalc = collectOptionItems(el.w || '', el.d || '');
  9920. \t\t\t\t\t// tg ブロックに合わせてラジオを再描画 (tg 以外は no-op)
  9921. \t\t\t\t\trenderOptionItemRadios(el.w || '', el.d || '');
  9922. \t\t\t\t\t// fe ブロックの種類×段数 サブ radio (fe 以外/未設定は no-op)
  9923. \t\t\t\t\trenderFeBlockRadios();
  9924. \t\t\t\t\t// fe ご希望のフェンス設置方法 — 「既存ブロックに穴空け」 entry の連動表示
  9925. \t\t\t\t\tupdateFeOpConditionalVisibility();
  9926. \t\t\t\t\tvar calc       = calcGoukei(el, opCalc.total, ctx);
  9927. \t\t\t\t\tvar goukei     = calc.goukei;     // 税込 (請求額・見積書・PDF 用)
  9928. \t\t\t\t\tvar price      = calc.price;      // 税込
  9929. \t\t\t\t\tvar ct         = calc.ct;         // 税込
  9930. \t\t\t\t\tvar optionSum  = calc.opt;        // 税込
  9931. \t\t\t\t\tvar goukeiExc  = calc.goukeiExc;  // 税抜 (詳細ページ表示専用)
  9932. \t\t\t\t\tvar priceExc   = calc.priceExc;   // 税抜
  9933. \t\t\t\t\tvar ctExc      = calc.ctExc;      // 税抜
  9934. \t\t\t\t\tvar optionExc  = calc.optExc;     // 税抜
  9935. \t\t\t\t\t// tf(人工芝): 必要枚数入力へ算出結果を反映(施工サイズ入力時は上書き、
  9936. \t\t\t\t\t// 直接指定時は同値なので実質変化なし。要素が無い sale_type では no-op)
  9937. \t\t\t\t\tvar \$tfQty = \$('#tf_qty');
  9938. \t\t\t\t\tif (\$tfQty.length) \$tfQty.val(calc.qty || 1);
  9939. \t\t\t\t\t// オプション差額は税抜 → 税込に変換して合計に加算
  9940. \t\t\t\t\tvar oiIncTax   = toIncTax(oiCalc.total);
  9941. \t\t\t\t\tgoukei += oiIncTax;
  9942. \t\t\t\t\tprice  += oiIncTax;  // 差額は本体価格扱いとして mitsumori_price にも加算
  9943. \t\t\t\t\tgoukeiExc += oiCalc.total;  // 税抜側にも同じ差額を加算
  9944. \t\t\t\t\tpriceExc  += oiCalc.total;
  9945. \t\t\t\t\t// maker_price も scraper が税抜で保存しているため税込に変換
  9946. \t\t\t\tvar makerPrice = toIncTax(parseInt(el.maker_price) || 0);      // 税込
  9947. \t\t\t\t\tvar makerPriceExc = parseInt(el.maker_price) || 0;           // 税抜
  9948. \t\t\t\t\t// 表示 (詳細ページの見積カード/ヘッダー/SPバー) は税抜に統一.
  9949. \t\t\t\t\t\$('#mitsumori_message').text(formatter.format(goukeiExc) + \"円\");
  9950. \t\t\t\t\t\$('#mitsumori_goukei').text(formatter.format(goukeiExc) + \"円\");
  9951. \t\t\t\t\t\$('#mitsumori_off').text(formatter.format(priceExc - makerPriceExc) + \"円\");
  9952. \t\t\t\t\t\$('#mitsumori_price').text(formatter.format(priceExc) + \"円\");
  9953. \t\t\t\t\t\$('#maker_price').text(formatter.format(makerPriceExc) + \"円\");
  9954. \t\t\t\t\t\$('#mitsumori_ct').text(formatter.format(ctExc) + \"円\");
  9955. \t\t\t\t\t\$('#mitsumori_option').text(formatter.format(optionExc) + \"円\");
  9956. \t\t\t\t\t// スチール折板(折半屋根 = option1): cp 折板のみ非ゼロ。工事費内に別行表示。
  9957. \t\t\t\t\tvar steelRoofExc = calc.steelRoofExc || 0;
  9958. \t\t\t\t\tif (steelRoofExc > 0) { \$('#mitsumori_steelroof_row').show(); \$('#mitsumori_steelroof').text(formatter.format(steelRoofExc) + \"円\"); }
  9959. \t\t\t\t\telse { \$('#mitsumori_steelroof_row').hide(); }
  9960. \t\t\t\t\t// 見積書モーダルは正式帳票のため税込のまま (請求額と一致).
  9961. \t\t\t\t\t\$('#mitsumori_kei').text(formatter.format(goukei) + \"円\");
  9962. \t\t\t\t\t\$('#mitsumori_price_01').text(formatter.format(price) + \"円\");
  9963. \t\t\t\t\t\$('#mitsumori_price_02').text(formatter.format(price) + \"円\");
  9964. \t\t\t\t\t\$('#mitsumori_ct_01').text(formatter.format(ct) + \"円\");
  9965. \t\t\t\t\t\$('#mitsumori_ct_02').text(formatter.format(ct) + \"円\");
  9966. \t\t\t\t\t\$('#mitsumori_goukei_02').text(formatter.format(goukei) + \"円\");
  9967. \t\t\t\t\tvar shoukei = goukei / 1.1;
  9968. \t\t\t\t\tvar tax     = parseInt(goukei - shoukei);
  9969. \t\t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(parseInt(shoukei)) + \"円\");
  9970. \t\t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + \"円\");
  9971. \t\t\t\t\t// 請求額・PDF 用 json は税込を保持 (表示 DOM が税抜でも請求額は不変).
  9972. \t\t\t\t\tjGoukei   = formatter.format(goukei) + \"円\";
  9973. \t\t\t\t\tjGoukei02 = formatter.format(goukei) + \"円\";
  9974. \t\t\t\t\tjPrice    = formatter.format(price) + \"円\";
  9975. \t\t\t\t\tjMaker    = formatter.format(makerPrice) + \"円\";
  9976. \t\t\t\t\tjOff      = formatter.format(price - makerPrice) + \"円\";
  9977. \t\t\t\t\tjCt       = formatter.format(ct) + \"円\";
  9978. \t\t\t\t\tjOption   = formatter.format(optionSum) + \"円\";
  9979. \t\t\t\t\t// PDF 明細用:オプション内訳テーブルを差し込む (施工オプション + tg block オプション)
  9980. \t\t\t\t\trenderOptionDetailRows(opCalc.items.concat(oiCalc.items.map(function(it){
  9981. \t\t\t\t\t\treturn { name: it.name, value: it.label, price: it.diff };
  9982. \t\t\t\t\t})));
  9983. \t\t\t\t  }
  9984. \t\t\t\t});
  9985. \t\t\t\tif (!pp_matched) {
  9986. \t\t\t\t\t\$('#mitsumori_message').text(\"この組み合わせは対応しておりません\");
  9987. \t\t\t\t\t\$('#mitsumori_btn').hide();
  9988. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9989. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9990. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9991. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  9992. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9993. \t\t\t\t\$('#mitsumori_steelroof_row').hide();
  9994. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9995. \t\t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  9996. \t\t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  9997. \t\t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  9998. \t\t\t\t}
  9999. \t\t\t\t// mitsumori_json: バック側に送信する見積データ
  10000. \t\t\t\tvar mitsumori_json = { \"mitsumori_goukei\": jGoukei,
  10001. \t\t\t\t\t\t\t\t\t\t\"mitsumori_goukei_02\": jGoukei02,
  10002. \t\t\t\t\t\t\t\t\t\t\"mitsumori_price\": jPrice,
  10003. \t\t\t\t\t\t\t\t\t\t\"maker_price\": jMaker,
  10004. \t\t\t\t\t\t\t\t\t\t\"mitsumori_off\": jOff,
  10005. \t\t\t\t\t\t\t\t\t\t\"mitsumori_ct\": jCt,
  10006. \t\t\t\t\t\t\t\t\t\t\"mitsumori_option\": jOption,
  10007. \t\t\t\t\t\t\t\t\t\t\"product_id\": {{ Product.id }},
  10008. \t\t\t\t\t\t\t\t\t\t\"sale_type\": SALE_TYPE_ID,
  10009. \t\t\t\t\t\t\t\t\t\t\"pw\": pw,
  10010. \t\t\t\t\t\t\t\t\t\t\"pd\": pd,
  10011. \t\t\t\t\t\t\t\t\t\t\"ph\": ph,
  10012. \t\t\t\t\t\t\t\t\t\t\"pm\": pm,
  10013. \t\t\t\t\t\t\t\t\t\t\"pc\": pc,
  10014. \t\t\t\t\t\t\t\t\t\t\"op\": [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10],
  10015. \t\t\t\t\t\t\t\t\t\t\"op_items\": opCalc.items,
  10016. \t\t\t\t\t\t\t\t\t\t\"mado_w\":     ctx.mado_w,
  10017. \t\t\t\t\t\t\t\t\t\t\"mado_h\":     ctx.mado_h,
  10018. \t\t\t\t\t\t\t\t\t\t\"mado_type\":  ctx.mado_type,
  10019. \t\t\t\t\t\t\t\t\t\t\"glass_type\": ctx.glass_type,
  10020. \t\t\t\t\t\t\t\t\t\t\"set_count\":  ctx.set_count,
  10021. \t\t\t\t\t\t\t\t\t\t\"daisu\":      ctx.daisu,
  10022. \t\t\t\t\t\t\t\t\t\t\"maisu\":      ctx.maisu,
  10023. \t\t\t\t\t\t\t\t\t\t\"suuryou\":    ctx.suuryou,
  10024. \t\t\t\t\t\t\t\t\t\t\"area\":       ctx.area,
  10025. \t\t\t\t\t\t\t\t\t\t\"tf_len\":     ctx.tf_len,
  10026. \t\t\t\t\t\t\t\t\t\t\"tf_wid\":     ctx.tf_wid,
  10027. \t\t\t\t\t\t\t\t\t\t\"tf_qty\":     \$('#tf_qty').val(),
  10028. \t\t\t\t\t\t\t\t\t\t\"deck_step\":  ctx.deck_step,
  10029. \t\t\t\t\t\t\t\t\t\t\"deck_fence\": ctx.deck_fence };
  10030. \t\t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  10031. \t\t\t}
  10032. \t\t}
  10033. \t\t// PDF/モーダル明細の動的差し替え(基本工事費の次にオプション行を追加)
  10034. \t\tfunction renderOptionDetailRows(items) {
  10035. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  10036. \t\t\tif (!\$tbody.length) return;
  10037. \t\t\t\$tbody.find('tr.opt-row').remove();
  10038. \t\t\tvar anchorRow = \$tbody.find('tr').filter(function(){
  10039. \t\t\t\treturn \$(this).find('td:first').text().indexOf('残土') !== -1
  10040. \t\t\t\t\t|| \$(this).find('td:first').text().indexOf('基本工事費') !== -1;
  10041. \t\t\t}).last();
  10042. \t\t\titems.forEach(function(it){
  10043. \t\t\t\tif (!it.name || !it.value) return;
  10044. \t\t\t\tvar priceTxt = it.price > 0
  10045. \t\t\t\t\t? formatter.format(it.price) + '円'
  10046. \t\t\t\t\t: '0円';
  10047. \t\t\t\tvar \$tr = \$('<tr class=\"opt-row\"></tr>')
  10048. \t\t\t\t\t.append('<td>' + it.name + ':' + it.value + '</td>')
  10049. \t\t\t\t\t.append('<td>1</td>')
  10050. \t\t\t\t\t.append('<td>式</td>')
  10051. \t\t\t\t\t.append('<td>' + priceTxt + '</td>')
  10052. \t\t\t\t\t.append('<td>' + (it.price > 0 ? formatter.format(it.price) + '円' : '') + '</td>');
  10053. \t\t\t\tif (anchorRow.length) {
  10054. \t\t\t\t\tanchorRow.after(\$tr);
  10055. \t\t\t\t\tanchorRow = \$tr;
  10056. \t\t\t\t} else {
  10057. \t\t\t\t\t\$tbody.append(\$tr);
  10058. \t\t\t\t}
  10059. \t\t\t});
  10060. \t\t}
  10061. \t\t// 見積書モーダルを開く直前に、右側「現在のお見積り額」パネルの表示値を
  10062. \t\t// モーダル内の対応 ID にコピーして金額の食い違いを防ぐ。
  10063. \t\t// pw/pd/ph/pm が未選択で mitsumori_simulation の full update に到達しない場合でも、
  10064. \t\t// パネル側の値(HTML 静的初期値 or 直近の simulation 結果)が modal にも反映される。
  10065. \t\tfunction syncMitsumoriModalFromPanel() {
  10066. \t\t\t// 見積カード表示は税抜だが、見積書モーダルは正式帳票として税込で出す.
  10067. \t\t\t// 請求と一致する税込値は hidden #mitsumori_json (税込のまま構築) から取得する.
  10068. \t\t\tvar mj = {};
  10069. \t\t\ttry { mj = JSON.parse(\$('#mitsumori_json').val() || '{}') || {}; } catch (e) { mj = {}; }
  10070. \t\t\tvar goukeiText = mj.mitsumori_goukei || '---円';
  10071. \t\t\tvar priceText  = mj.mitsumori_price  || '---円';
  10072. \t\t\tvar ctText     = mj.mitsumori_ct     || '---円';
  10073. \t\t\t\$('#mitsumori_kei').text(goukeiText);
  10074. \t\t\t\$('#mitsumori_price_01').text(priceText);
  10075. \t\t\t\$('#mitsumori_price_02').text(priceText);
  10076. \t\t\t\$('#mitsumori_ct_01').text(ctText);
  10077. \t\t\t\$('#mitsumori_ct_02').text(ctText);
  10078. \t\t\t\$('#mitsumori_goukei_02').text(goukeiText);
  10079. \t\t\t// 小計 / 消費税 は税込 goukei から逆算
  10080. \t\t\tvar num = parseInt(String(goukeiText).replace(/[^\\d-]/g, ''), 10);
  10081. \t\t\tif (!isNaN(num) && num > 0) {
  10082. \t\t\t\tvar shoukei = Math.round(num / 1.1);
  10083. \t\t\t\tvar tax     = num - shoukei;
  10084. \t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(shoukei) + '円');
  10085. \t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + '円');
  10086. \t\t\t} else {
  10087. \t\t\t\t\$('#mitsumori_shoukei').text('---円');
  10088. \t\t\t\t\$('#mitsumori_tax').text('---円');
  10089. \t\t\t}
  10090. \t\t}
  10091. \t\t\$(document).on('show.bs.modal', '#modal-mitsumori', function () {
  10092. \t\t\t// 発行日を表示時点の当日日付に設定(固定ダミー日付の残置防止)
  10093. \t\t\tvar _now = new Date();
  10094. \t\t\tvar _issue = _now.getFullYear() + '/' +
  10095. \t\t\t\t('0' + (_now.getMonth() + 1)).slice(-2) + '/' +
  10096. \t\t\t\t('0' + _now.getDate()).slice(-2);
  10097. \t\t\t\$('#mitsumori_issue_date').text(_issue);
  10098. \t\t\tsyncMitsumoriModalFromPanel();
  10099. \t\t});
  10100.         {# pc の auto-init: pw/pd/ph/pm と同じく p_c(matrix 派生)の length==1 or 全空で「指定なし」化.
  10101.            search_word(color) が空の「複合色」型商品で pc が空のまま放置されて
  10102.            「カラーを選択してください」固定になるバグの修正.
  10103.            search_word に登録された name があれば優先採用. #}
  10104.         {% if p_c and (p_c|length == 1 or p_c|join == \"\") %}
  10105.             pc = \"指定なし\";
  10106.             {% for pc_val in p_c %}{% if pc_val %} pc = \"{{ pc_val }}\"; {% endif %}{% endfor %}
  10107.             {% if color and color|length == 1 %}
  10108.                 {% for cc in color %}{% if cc and cc['name'] %} pc = \"{{ cc['name'] }}\"; {% endif %}{% endfor %}
  10109.             {% endif %}
  10110.         {% elseif color and color|length == 1 %}
  10111.             pc = \"指定なし\";
  10112. \t\t\t{% for cc in color %}{% if cc and cc['name'] %} pc = \"{{ cc['name'] }}\"; {% endif %}{% endfor %}
  10113. \t\t{% endif %}
  10114.         {% if p_w and (p_w|length == 1 or p_w|join == \"\") %}
  10115.             pw = \"指定なし\";
  10116. \t\t\t{% for pw in p_w %}{% if pw %} pw = \"{{ pw }}\"; {% endif %}{% endfor %}
  10117. \t\t{% endif %}
  10118.         {% if p_d and (p_d|length == 1 or p_d|join == \"\") %}
  10119.             pd = \"指定なし\";
  10120. \t\t\t{% for pd in p_d %}{% if pd %} pd = \"{{ pd }}\"; {% endif %}{% endfor %}
  10121. \t\t{% endif %}
  10122.         {% if p_h and (p_h|length == 1 or p_h|join == \"\") %}
  10123.             ph = \"指定なし\";
  10124. \t\t\t{% for ph in p_h %}{% if ph %} ph = \"{{ ph }}\"; {% endif %}{% endfor %}
  10125. \t\t{% endif %}
  10126.         {% if p_m and (p_m|length == 1 or p_m|join == \"\") %}
  10127.             pm = \"指定なし\";
  10128. \t\t\t{% for pm in p_m %}{% if pm %} pm = \"{{ pm }}\"; {% endif %}{% endfor %}
  10129. \t\t{% endif %}
  10130.         {# p_option1 / p_option2 の auto-init: length==1 or 全空で JS 変数を埋める #}
  10131.         {% if p_option1 and (p_option1|length == 1 or p_option1|join == \"\") %}
  10132.             option1 = \"\";
  10133. \t\t\t{% for opt1 in p_option1 %}{% if opt1 %} option1 = \"{{ opt1|e('js') }}\"; {% endif %}{% endfor %}
  10134. \t\t{% endif %}
  10135.         {% if p_option2 and (p_option2|length == 1 or p_option2|join == \"\") %}
  10136.             option2 = \"\";
  10137. \t\t\t{% for opt2 in p_option2 %}{% if opt2 %} option2 = \"{{ opt2|e('js') }}\"; {% endif %}{% endfor %}
  10138. \t\t{% endif %}
  10139. \t\t// カラー radio が複数あるとき初期チェックが無いと「カラーを選択してください」固定になるので、
  10140. \t\t// 何もチェックされていなければ「最初の radio」を選択する。
  10141. \t\t// sale_type≠3 は name=\"color\", sale_type=3 は name=\"color3\".
  10142. \t\t//
  10143. \t\t// 注意:
  10144. \t\t//   ・search_word(= radio の値)と pp.c(= matrix の色軸)は別の命名体系のケースがある
  10145. \t\t//     (例 id=3353: radio=\"SM(スミ)\" / pp.c=\"ステンカラー+セピアブラウン\")
  10146. \t\t//   ・pp.c に合わせて radio を選ぼうとしても文字列一致しないので無意味。
  10147. \t\t//   ・単純に「先頭の radio」を選ぶ実装に戻し、マッチング側で命名体系違いを吸収する
  10148. \t\t//     (pc が pp.c のどの値にもマッチしないときは色軸を wildcard 扱いにする)。
  10149. \t\t//   ・.rp-section-label のテキストも忘れずに同期する(古い session 値が残ると
  10150. \t\t//     \"ステンカラー+セピアブラウン\" のような表示と実際の radio が食い違う)。
  10151. \t\t(function autoSelectFirstColor(){
  10152. \t\t\tvar groups = ['color', 'color3'];
  10153. \t\t\tfor (var gi = 0; gi < groups.length; gi++) {
  10154. \t\t\t\tvar name = groups[gi];
  10155. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + name + '\"]');
  10156. \t\t\t\tif (nodes.length === 0) continue;
  10157. \t\t\t\tvar anyChecked = false;
  10158. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  10159. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  10160. \t\t\t\t}
  10161. \t\t\t\tif (anyChecked) continue;
  10162. \t\t\t\tvar target = nodes[0];
  10163. \t\t\t\ttarget.checked = true;
  10164. \t\t\t\tpc = target.value;
  10165. \t\t\t\t// opt-btn の is-selected を付け替え
  10166. \t\t\t\tvar lbl = target.closest('.opt-btn');
  10167. \t\t\t\tif (lbl) {
  10168. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  10169. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  10170. \t\t\t\t\tlbl.classList.add('is-selected');
  10171. \t\t\t\t}
  10172. \t\t\t\t// 「カラー: <name>」表示の同期(古い mitsumori_json.pc が残らないように)
  10173. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  10174. \t\t\t\tif (grp) {
  10175. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  10176. \t\t\t\t\tif (section) {
  10177. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  10178. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  10179. \t\t\t\t\t}
  10180. \t\t\t\t}
  10181. \t\t\t}
  10182. \t\t})();
  10183. \t\t// option1 / option2 / pw / pd / ph / pm (matrix 軸の radio 群) も同様に
  10184. \t\t// 「どれもチェックされていなければ先頭を選ぶ」を適用する.
  10185. \t\t//   sale_type=2 の窓タイプ等で「初期表示時に一番初めの選択肢が選択されていない」事象を解消.
  10186. \t\t(function autoSelectFirstMatrixAxis(){
  10187. \t\t\tvar axes = [
  10188. \t\t\t\t{ name: 'pw',      jsVar: 'pw' },
  10189. \t\t\t\t{ name: 'pd',      jsVar: 'pd' },
  10190. \t\t\t\t{ name: 'ph',      jsVar: 'ph' },
  10191. \t\t\t\t{ name: 'pm',      jsVar: 'pm' },
  10192. \t\t\t\t{ name: 'glass_type', jsVar: 'pm' },
  10193. \t\t\t\t{ name: 'option1', jsVar: 'option1' },
  10194. \t\t\t\t{ name: 'option2', jsVar: 'option2' }
  10195. \t\t\t];
  10196. \t\t\tfor (var ai = 0; ai < axes.length; ai++) {
  10197. \t\t\t\tvar ax = axes[ai];
  10198. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + ax.name + '\"]');
  10199. \t\t\t\tif (nodes.length === 0) continue;
  10200. \t\t\t\tvar anyChecked = false;
  10201. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  10202. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  10203. \t\t\t\t}
  10204. \t\t\t\tif (anyChecked) continue;
  10205. \t\t\t\tvar target = nodes[0];
  10206. \t\t\t\ttarget.checked = true;
  10207. \t\t\t\t// グローバル JS 変数も埋める
  10208. \t\t\t\tif (ax.jsVar === 'pw') pw = target.value;
  10209. \t\t\t\telse if (ax.jsVar === 'pd') pd = target.value;
  10210. \t\t\t\telse if (ax.jsVar === 'ph') ph = target.value;
  10211. \t\t\t\telse if (ax.jsVar === 'pm') pm = target.value;
  10212. \t\t\t\telse if (ax.jsVar === 'option1') option1 = target.value;
  10213. \t\t\t\telse if (ax.jsVar === 'option2') option2 = target.value;
  10214. \t\t\t\tvar lbl = target.closest('.opt-btn');
  10215. \t\t\t\tif (lbl) {
  10216. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  10217. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  10218. \t\t\t\t\tlbl.classList.add('is-selected');
  10219. \t\t\t\t}
  10220. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  10221. \t\t\t\tif (grp) {
  10222. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  10223. \t\t\t\t\tif (section) {
  10224. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  10225. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  10226. \t\t\t\t\t}
  10227. \t\t\t\t}
  10228. \t\t\t}
  10229. \t\t})();
  10230. \t\t// 取付/設置工事トグル(off 値が「商品購入のみ」のオプション)は、新規アクセス時に
  10231. \t\t// どちらの radio も未チェックのため初期価格が「商品購入のみ」= 基本工事費抜きになる。
  10232. \t\t// 顧客要望(#10)に合わせ、未選択時は「工事も希望する」(on 側) を初期選択し、
  10233. \t\t// 初期表示を基本工事費込みの最安値に統一する(色・寸法軸の先頭自動選択と同型)。
  10234. \t\t//   ・判定キーは calcGoukei / applyPurchaseOnlyUI と同じ定数「商品購入のみ」。
  10235. \t\t//   ・別用途で op{n} を流用する商品(ウッドデッキ deck_step 等)は radio 値に
  10236. \t\t//     「商品購入のみ」を含まないため対象外(既存挙動を壊さない)。
  10237. \t\t//   ・mitsumori_json 復元やユーザー操作で既に選択済みなら尊重する。
  10238. \t\t(function autoSelectFirstInstall(){
  10239. \t\t\tfor (var i = 0; i <= 10; i++) {
  10240. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"op' + i + '\"]');
  10241. \t\t\t\tif (nodes.length === 0) continue;
  10242. \t\t\t\t// このグループが「商品購入のみ」を off に持つ工事トグルか判定し、
  10243. \t\t\t\t// 「商品購入のみ」でない側 (= 工事希望 on) を取得する。
  10244. \t\t\t\tvar hasPurchaseOnly = false;
  10245. \t\t\t\tvar onNode = null;
  10246. \t\t\t\tfor (var j = 0; j < nodes.length; j++) {
  10247. \t\t\t\t\tif (nodes[j].value === '商品購入のみ') hasPurchaseOnly = true;
  10248. \t\t\t\t\telse if (!onNode) onNode = nodes[j];
  10249. \t\t\t\t}
  10250. \t\t\t\tif (!hasPurchaseOnly || !onNode) continue;
  10251. \t\t\t\tvar anyChecked = false;
  10252. \t\t\t\tfor (var k = 0; k < nodes.length; k++) {
  10253. \t\t\t\t\tif (nodes[k].checked) { anyChecked = true; break; }
  10254. \t\t\t\t}
  10255. \t\t\t\tif (anyChecked) continue;
  10256. \t\t\t\tonNode.checked = true;
  10257. \t\t\t\t// グローバル op 変数を on 値で埋める(calcGoukei の purchaseOnly 判定が参照)
  10258. \t\t\t\tswitch (i) {
  10259. \t\t\t\t\tcase 0:  op0  = onNode.value; break;
  10260. \t\t\t\t\tcase 1:  op1  = onNode.value; break;
  10261. \t\t\t\t\tcase 2:  op2  = onNode.value; break;
  10262. \t\t\t\t\tcase 3:  op3  = onNode.value; break;
  10263. \t\t\t\t\tcase 4:  op4  = onNode.value; break;
  10264. \t\t\t\t\tcase 5:  op5  = onNode.value; break;
  10265. \t\t\t\t\tcase 6:  op6  = onNode.value; break;
  10266. \t\t\t\t\tcase 7:  op7  = onNode.value; break;
  10267. \t\t\t\t\tcase 8:  op8  = onNode.value; break;
  10268. \t\t\t\t\tcase 9:  op9  = onNode.value; break;
  10269. \t\t\t\t\tcase 10: op10 = onNode.value; break;
  10270. \t\t\t\t}
  10271. \t\t\t\t// opt-btn の is-selected を付け替え
  10272. \t\t\t\tvar lbl = onNode.closest('.opt-btn');
  10273. \t\t\t\tif (lbl) {
  10274. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  10275. \t\t\t\t\tfor (var s = 0; s < sib.length; s++) sib[s].classList.remove('is-selected');
  10276. \t\t\t\t\tlbl.classList.add('is-selected');
  10277. \t\t\t\t}
  10278. \t\t\t\t// rp-section-label 表示同期 + 現地調査文言(is_removal_unknown / is_tf_kouji)を on 表示に
  10279. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || onNode.closest('.form-group');
  10280. \t\t\t\tif (grp) {
  10281. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  10282. \t\t\t\t\tif (section) {
  10283. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  10284. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + onNode.value + '</span>';
  10285. \t\t\t\t\t}
  10286. \t\t\t\t\tvar note = grp.querySelector('.opt-survey-note[data-op-idx=\"' + i + '\"]');
  10287. \t\t\t\t\tif (note) note.style.display = '';
  10288. \t\t\t\t}
  10289. \t\t\t}
  10290. \t\t})();
  10291. \t\t// ページ読み込み時: 見積金額が「合計」になっているため、カート数量は基本1
  10292. \t\t// sale_type=9(商品のみ購入)だけ通常 EC として数量を引き継ぐ
  10293. \t\t(function initQuantityByType(){
  10294. \t\t\tvar saleType = {{ ProductClass.SaleType.id }};
  10295. \t\t\tif (saleType == 9 && \$('#quantity_only').length) {
  10296. \t\t\t\t\$('#quantity').val(parseInt(\$('#quantity_only').val()) || 1);
  10297. \t\t\t} else {
  10298. \t\t\t\t\$('#quantity').val(1);
  10299. \t\t\t\t\$('input[name=\"quantity\"]').val(1);
  10300. \t\t\t}
  10301. \t\t})();
  10302. \t\t// type → ラベルのプレフィックス文字列
  10303. \t\t{# 屋根軸ラベル: pm(素材)の値が屋根パネル材(ポリカ/折板/波板/熱線 等)なら、
  10304. \t\t   材質が複数種→「屋根材」/ 同一材質で色違い→「屋根材の色」。屋根でない素材(デッキ材・
  10305. \t\t   ドア開き方・数量・色 等)は「素材」のまま。カテゴリ一括ではなく値の中身で判定する。 #}
  10306. \t\t{% set pm_is_roof = false %}
  10307. \t\t{% set pm_stems = [] %}
  10308. \t\t{% if p_m %}{% for v in p_m %}{% if v %}
  10309. \t\t\t{% if v matches '/ポリカ|折板|波板|熱線|ふきポリ|アルミ形材屋根|スチール折板/' %}{% set pm_is_roof = true %}{% endif %}
  10310. \t\t\t{% set pm_stem = (v|split('(')|first)|split('(')|first|trim %}
  10311. \t\t\t{% if pm_stem not in pm_stems %}{% set pm_stems = pm_stems|merge([pm_stem]) %}{% endif %}
  10312. \t\t{% endif %}{% endfor %}{% endif %}
  10313. \t\t{% set pm_label = pm_is_roof ? ((pm_stems|length >= 2) ? '屋根材' : '屋根材の色') : '素材' %}
  10314. \t\t// option1/option2 のラベルは category 依存 (rd: ランマ/タイプ, sh: サイズプリセット/駆動方式 等).
  10315. \t\t// PHP から渡された option1_label / option2_label を埋め込み、JS 側でラベル更新に使う.
  10316. \t\tvar optLabelMap = {pc:'カラー', pw:'幅', pd:'奥行き', ph:'高さ', pm:'{{ pm_label|e('js') }}',
  10317. \t\t                   option1: '{{ option1_label|default('オプション1')|e('js') }}',
  10318. \t\t                   option2: '{{ option2_label|default('オプション2')|e('js') }}'};
  10319. \t\t// type → input[name]
  10320. \t\tvar optNameMap  = {pc:'color', pw:'pw', pd:'pd', ph:'ph', pm:'pm',
  10321. \t\t                   option1: 'option1', option2: 'option2'};
  10322. \t\t// opt-btn用: 値を直接受け取るラッパー
  10323. \t\tfunction mitsumori_simulation_val(type, value) {
  10324. \t\t\tif (type === 'pc') pc = value;
  10325. \t\t\tif (type === 'pw') pw = value;
  10326. \t\t\tif (type === 'pd') pd = value;
  10327. \t\t\tif (type === 'ph') ph = value;
  10328. \t\t\tif (type === 'pm') pm = value;
  10329. \t\t\tif (type === 'option1') option1 = value;
  10330. \t\t\tif (type === 'option2') option2 = value;
  10331. \t\t\t// is-selected クラスを同グループ内で付け替え
  10332. \t\t\tvar inputName = optNameMap[type];
  10333. \t\t\tif (inputName) {
  10334. \t\t\t\tvar \$btns = \$('input[name=\"' + inputName + '\"]').closest('.opt-btn');
  10335. \t\t\t\t\$btns.removeClass('is-selected');
  10336. \t\t\t\t\$btns.filter(function(){
  10337. \t\t\t\t\treturn \$(this).find('input').val() === value;
  10338. \t\t\t\t}).addClass('is-selected');
  10339. \t\t\t}
  10340. \t\t\t// ラベル行の選択値テキストを更新(例: 「カラー: ブラック」)
  10341. \t\t\tvar labelPrefix = optLabelMap[type];
  10342. \t\t\tif (labelPrefix) {
  10343. \t\t\t\t// 対象のrp-section-labelを特定(input[name]を含む親を遡る)
  10344. \t\t\t\tvar \$group = \$('input[name=\"' + inputName + '\"]').first().closest('.form-group');
  10345. \t\t\t\tvar \$label = \$group.find('.rp-section-label');
  10346. \t\t\t\t\$label.html(labelPrefix + ': <span>' + value + '</span>');
  10347. \t\t\t}
  10348. \t\t\t// simulation本体を呼ぶ(value_idは空でOK、グローバル変数を使う)
  10349. \t\t\tmitsumori_simulation('', '');
  10350. \t\t}
  10351. \t\tmitsumori_simulation(\"\",\"\");
  10352. \t\t// ボタン群: 親幅を超える、または3行以上になる場合は is-scroll を付与し
  10353. \t\t// 縦3段グリッド+横スクロール表示にする(顧客要望「3列くらいで横スクロール」)
  10354. \t\tfunction applyBtnGroupScroll() {
  10355. \t\t\t\$('.rp-btn-group, .opt-btn-group').each(function() {
  10356. \t\t\t\tvar \$group = \$(this);
  10357. \t\t\t\t\$group.removeClass('is-scroll');
  10358. \t\t\t\t// 意図的な縦リスト(no-hscroll / flex-direction:column)は横スクロール化しない。
  10359. \t\t\t\t// フェンス fe_block の縦6行(A-2)や内窓(sale_type=2)の長いガラス名(A-3)が
  10360. \t\t\t\t// 3行以上/幅超過で is-scroll 化され、列崩れ・左見切れを起こすのを防ぐ。
  10361. \t\t\t\tif (\$group.hasClass('no-hscroll') || \$group.css('flex-direction') === 'column') return;
  10362. \t\t\t\tvar \$items = \$group.children();
  10363. \t\t\t\tif (\$items.length === 0) return;
  10364. \t\t\t\tvar parentWidth = \$group.parent().width() || \$group.width();
  10365. \t\t\t\tvar totalWidth = 0;
  10366. \t\t\t\tvar gap = parseInt(\$group.css('gap'), 10) || 8;
  10367. \t\t\t\t\$items.each(function() {
  10368. \t\t\t\t\ttotalWidth += this.offsetWidth + gap;
  10369. \t\t\t\t});
  10370. \t\t\t\t// 単一ボタンが親幅を超える、もしくは合計幅が親幅を超える → 横スクロール化
  10371. \t\t\t\tvar anyTooWide = false;
  10372. \t\t\t\t\$items.each(function() {
  10373. \t\t\t\t\tif (this.offsetWidth > parentWidth) { anyTooWide = true; return false; }
  10374. \t\t\t\t});
  10375. \t\t\t\t// 折り返し時の行数も計測
  10376. \t\t\t\tvar tops = {};
  10377. \t\t\t\t\$items.each(function() { tops[this.offsetTop] = true; });
  10378. \t\t\t\tvar rowCount = Object.keys(tops).length;
  10379. \t\t\t\tif (anyTooWide || totalWidth > parentWidth * 2 || rowCount >= 3) {
  10380. \t\t\t\t\t\$group.addClass('is-scroll');
  10381. \t\t\t\t}
  10382. \t\t\t});
  10383. \t\t}
  10384. \t\tapplyBtnGroupScroll();
  10385. \t\t\$(window).on('resize', function() {
  10386. \t\t\tclearTimeout(window._btnScrollTimer);
  10387. \t\t\twindow._btnScrollTimer = setTimeout(applyBtnGroupScroll, 150);
  10388. \t\t});
  10389. \t\t// iOS Safari 1-tap fix (#15 再発): is-scroll の横スクロールコンテナ内タップや
  10390. \t\t// 継承された a:hover により、初回タップが hover / スクロール判定に吸われ「2 回
  10391. \t\t// タッチ」が必要になる。touch 端末では touchend で 1 回目に選択 / 遷移を確定し、
  10392. \t\t// 後続のゴーストクリックを preventDefault で抑止する(二重発火なし)。指が動いた
  10393. \t\t// 場合はスクロール操作とみなし何もしない。デスクトップは従来の click のまま。
  10394. \t\t(function oneTapSelectFix(){
  10395. \t\t\tif (!('ontouchstart' in window)) return;
  10396. \t\t\tvar moved = false, sx = 0, sy = 0;
  10397. \t\t\tdocument.addEventListener('touchstart', function(e){
  10398. \t\t\t\tmoved = false;
  10399. \t\t\t\tvar t = e.touches && e.touches[0];
  10400. \t\t\t\tif (t) { sx = t.clientX; sy = t.clientY; }
  10401. \t\t\t}, { passive: true });
  10402. \t\t\tdocument.addEventListener('touchmove', function(e){
  10403. \t\t\t\tvar t = e.touches && e.touches[0];
  10404. \t\t\t\tif (t && (Math.abs(t.clientX - sx) > 8 || Math.abs(t.clientY - sy) > 8)) moved = true;
  10405. \t\t\t}, { passive: true });
  10406. \t\t\tdocument.addEventListener('touchend', function(e){
  10407. \t\t\t\tif (moved) return;
  10408. \t\t\t\tvar el = (e.target && e.target.closest) ? e.target.closest('.opt-btn, .rp-btn, .rp-card') : null;
  10409. \t\t\t\tif (!el) return;
  10410. \t\t\t\t// 窓タイプ / 住宅区分は専用の委譲 click ハンドラを持つため除外.
  10411. \t\t\t\tif (el.closest('#window-types-container') || el.closest('#window-housing-type-group')) return;
  10412. \t\t\t\te.preventDefault(); // 遅延ゴーストクリックを抑止し二重処理を防ぐ
  10413. \t\t\t\tif (el.tagName === 'A' && el.href) { window.location.href = el.href; return; }
  10414. \t\t\t\tel.click(); // label→radio チェック + inline onclick / change を 1 回だけ発火
  10415. \t\t\t}, { passive: false });
  10416. \t\t})();
  10417. \t\t// onload: 見積金額が確定している場合は「工事費込み価格」表示を一致させる
  10418. \t\t(function syncPrice02Display() {
  10419. \t\t\tvar goukeiEl = document.getElementById('mitsumori_goukei');
  10420. \t\t\tvar displayEl = document.getElementById('price02-display');
  10421. \t\t\tif (!goukeiEl || !displayEl) return;
  10422. \t\t\tvar goukeiText = goukeiEl.textContent.trim();
  10423. \t\t\t// ---円(未確定)の場合は書き換えない
  10424. \t\t\tif (goukeiText && goukeiText !== '---円') {
  10425. \t\t\t\tdisplayEl.textContent = goukeiText;
  10426. \t\t\t}
  10427. \t\t\t// 以降の変更にも追従: mitsumori_goukei を監視
  10428. \t\t\tnew MutationObserver(function() {
  10429. \t\t\t\tvar text = goukeiEl.textContent.trim();
  10430. \t\t\t\tif (text && text !== '---円') {
  10431. \t\t\t\t\tdisplayEl.textContent = text;
  10432. \t\t\t\t}
  10433. \t\t\t}).observe(goukeiEl, { childList: true, subtree: true, characterData: true });
  10434. \t\t})();
  10435. \t\tfunction contact_form(product_id){
  10436. \t\t\t\$('#form1').attr('action', '{{ url('contact', {product:Product.id}) }}');
  10437. \t\t\t\$('#form1').submit();
  10438. \t\t}
  10439. \t\t// maisu / madoset は下部の新しい関数定義を使用
  10440. \t\tfunction heibei(bei){
  10441. \t\t\t\$('#heibei').val(parseInt(\$('#heibei').val()) + bei);
  10442. \t\t\tif(parseInt(\$('#heibei').val()) < 1){ \$('#heibei').val(1); }
  10443. \t\t\tif(parseInt(\$('#heibei').val()) > 100){ \$('#heibei').val(100); }
  10444. \t\t\t// goukei に既に枚数を含むため、カート数量は1で固定
  10445. \t\t\t\$('#quantity').val(1);
  10446. \t\t\tmitsumori_simulation('heibei','heibei');
  10447. \t\t}
  10448. \t\tfunction daisu(dai){
  10449. \t\t\t\$('#daisu').val(parseInt(\$('#daisu').val()) + dai);
  10450. \t\t\tif(parseInt(\$('#daisu').val()) < 1){ \$('#daisu').val(1); }
  10451. \t\t\tif(parseInt(\$('#daisu').val()) > 10){ \$('#daisu').val(10); }
  10452. \t\t\t\$('#quantity').val(1);
  10453. \t\t\tmitsumori_simulation('daisu','daisu');
  10454. \t\t}
  10455. \t\t// sale_type=7(数量買い・基本工事費固定)用:個数入力
  10456. \t\tfunction suuryou(n){
  10457. \t\t\t\$('#suuryou').val(parseInt(\$('#suuryou').val()) + n);
  10458. \t\t\tif(parseInt(\$('#suuryou').val()) < 1){ \$('#suuryou').val(1); }
  10459. \t\t\tif(parseInt(\$('#suuryou').val()) > 100){ \$('#suuryou').val(100); }
  10460. \t\t\t\$('#quantity').val(1);
  10461. \t\t\tmitsumori_simulation('suuryou','suuryou');
  10462. \t\t}
  10463. \t\tfunction maisu(mai){
  10464. \t\t\t\$('#maisu').val(parseInt(\$('#maisu').val()) + mai);
  10465. \t\t\t// sale_type=4 (フェンス) は3枚未満不可、6 (芝生) は1枚から
  10466. \t\t\tvar minMai = (SALE_TYPE_ID == 4) ? 3 : 1;
  10467. \t\t\tif(parseInt(\$('#maisu').val()) < minMai){ \$('#maisu').val(minMai); }
  10468. \t\t\tif(parseInt(\$('#maisu').val()) > 100){ \$('#maisu').val(100); }
  10469. \t\t\t\$('#quantity').val(1);
  10470. \t\t\tmitsumori_simulation('maisu','maisu');
  10471. \t\t}
  10472. \t\t// タイプ2: セット数プルダウン連動
  10473. \t\tfunction madosetSelect(val){
  10474. \t\t\tvar v = parseInt(val);
  10475. \t\t\tif(v < 1) v = 1;
  10476. \t\t\tif(v > 20) v = 20;
  10477. \t\t\t\$('#set_count').val(v);
  10478. \t\t\t\$('#quantity').val(1);
  10479. \t\t\t\$('input[name=\"quantity\"]').val(1);
  10480. \t\t\tmitsumori_simulation('set','set_count');
  10481. \t\t}
  10482. \t\t// タイプ2: ±ボタン版(後方互換)
  10483. \t\tfunction madoset(mai){
  10484. \t\t\tvar current = parseInt(\$('#set_count').val()) || 1;
  10485. \t\t\tvar next = current + mai;
  10486. \t\t\tif(next < 1) next = 1;
  10487. \t\t\tif(next > 20) next = 20;
  10488. \t\t\t\$('#set_count').val(next);
  10489. \t\t\tmadosetSelect(next);
  10490. \t\t}
  10491. \t\t// タイプ5: ステップ・フェンス選択値を mitsumori_json に保存するためのグローバル変数
  10492. \t\tvar deck_step = \"{% if mitsumori_json and mitsumori_json.deck_step is defined %}{{ mitsumori_json.deck_step|default('不要') }}{% else %}不要{% endif %}\";
  10493. \t\tvar deck_fence = \"{% if mitsumori_json and mitsumori_json.deck_fence is defined %}{{ mitsumori_json.deck_fence|default('不要') }}{% else %}不要{% endif %}\";
  10494. \t\t// PDF出力: モーダルの mitsumori_json をフォームに同期してから送信
  10495. \t\tfunction syncPdfJson(){
  10496. \t\t\tvar jsonVal = \$('#mitsumori_json').val();
  10497. \t\t\t\$('#pdf_mitsumori_json').val(jsonVal);
  10498. \t\t}
  10499. \t\t// タイプ9: 商品のみ購入
  10500. \t\tfunction quantityOnly(val){
  10501. \t\t\tvar current = parseInt(\$('#quantity_only').val()) || 1;
  10502. \t\t\tvar next = current + val;
  10503. \t\t\tif(next < 1) next = 1;
  10504. \t\t\t\$('#quantity_only').val(next);
  10505. \t\t\t\$('#quantity').val(next);
  10506. \t\t}
  10507.         // ===== スマホ用下部固定バーへの金額同期 =====
  10508.         // mitsumori_message と mitsumori_goukei を監視して下部バーを更新
  10509.         (function() {
  10510.             var msgTarget   = document.getElementById('mitsumori_message');
  10511.             var goukeiTarget = document.getElementById('mitsumori_goukei');
  10512.             var spPrice     = document.getElementById('sp-mitsumori-price');
  10513.             var spBtn       = document.querySelector('#sp-mitsumori-bar .sp-bar__btn');
  10514.             if (!spPrice || !spBtn) return;
  10515.             function syncBar() {
  10516.                 var msg    = msgTarget ? msgTarget.textContent : '';
  10517.                 var goukei = goukeiTarget ? goukeiTarget.textContent : '---円';
  10518.                 // メッセージが「〇〇を選択してください」の場合はメッセージを表示しボタンを非表示
  10519.                 if (msg.indexOf('選択してください') !== -1) {
  10520.                     spPrice.textContent = msg;
  10521.                     spPrice.style.fontSize = '13px';
  10522.                     spPrice.style.color    = '#888';
  10523.                     spBtn.style.display    = 'none';
  10524.                 } else {
  10525.                     // 価格確定時はボタンを表示
  10526.                     spPrice.textContent = goukei;
  10527.                     spPrice.style.fontSize = '18px';
  10528.                     spPrice.style.color    = '#c00';
  10529.                     spBtn.style.display    = 'block';
  10530.                 }
  10531.             }
  10532.             // 初期値を同期
  10533.             syncBar();
  10534.             // mitsumori_message の変化を監視
  10535.             if (msgTarget) {
  10536.                 new MutationObserver(syncBar).observe(
  10537.                     msgTarget, { childList: true, subtree: true, characterData: true }
  10538.                 );
  10539.             }
  10540.             // mitsumori_goukei の変化も監視
  10541.             if (goukeiTarget) {
  10542.                 new MutationObserver(syncBar).observe(
  10543.                     goukeiTarget, { childList: true, subtree: true, characterData: true }
  10544.                 );
  10545.             }
  10546.         })();
  10547.         // ===== スマホ用 お見積りの詳細 ボトムシート 開閉 =====
  10548.         // 現在の内訳カード(.mitsumori-card-pc .card-body)を複製して表示する。
  10549.         // 価格計算ロジックには触れず、その時点で表示中の内訳をそのまま見せる。
  10550.         // window に直接ぶら下げてスコープに依存せず onclick から呼べるようにする。
  10551.         window.openSpMitsumoriDetail = function () {
  10552.             var sheet = document.getElementById('sp-mitsumori-detail');
  10553.             var body  = document.getElementById('sp-detail-body');
  10554.             var src   = document.querySelector('.mitsumori-card-pc .card-body');
  10555.             if (!sheet || !body) return;
  10556.             body.innerHTML = '';
  10557.             if (src) {
  10558.                 // 複製し、重複 id を避けるため clone 側の id を除去する
  10559.                 var clone = src.cloneNode(true);
  10560.                 var ided = clone.querySelectorAll('[id]');
  10561.                 for (var i = 0; i < ided.length; i++) { ided[i].removeAttribute('id'); }
  10562.                 body.appendChild(clone);
  10563.             }
  10564.             sheet.classList.add('is-open');
  10565.             sheet.setAttribute('aria-hidden', 'false');
  10566.             document.body.style.overflow = 'hidden';
  10567.         };
  10568.         window.closeSpMitsumoriDetail = function () {
  10569.             var sheet = document.getElementById('sp-mitsumori-detail');
  10570.             if (!sheet) return;
  10571.             sheet.classList.remove('is-open');
  10572.             sheet.setAttribute('aria-hidden', 'true');
  10573.             document.body.style.overflow = '';
  10574.         };
  10575.         // ===== 現在のお見積り額: 折りたたみトグルボタンのテキスト切り替え =====
  10576.         (function() {
  10577.             var card = document.querySelector('.mitsumori-card-pc');
  10578.             var btn  = document.querySelector('.btn-mitsumori-toggle .toggle-icon');
  10579.             if (!card || !btn) return;
  10580.             // MutationObserverでcollapsed-cardクラスの変化を監視
  10581.             new MutationObserver(function() {
  10582.                 if (card.classList.contains('collapsed-card')) {
  10583.                     btn.textContent = '▼ 詳細';
  10584.                 } else {
  10585.                     btn.textContent = '▲ 閉じる';
  10586.                 }
  10587.             }).observe(card, { attributes: true, attributeFilter: ['class'] });
  10588.         })();
  10589.         // ===== エリア案内: スマホのみタップで展開 =====
  10590.         (function() {
  10591.             var notice = document.querySelector('.ec-areaNotice');
  10592.             if (!notice) return;
  10593.             notice.addEventListener('click', function(e) {
  10594.                 if (window.innerWidth > 767) return;
  10595.                 // リンククリック時は展開/折りたたみせずリンク遷移
  10596.                 if (e.target.tagName === 'A') return;
  10597.                 notice.classList.toggle('is-open');
  10598.             });
  10599.         })();
  10600.     </script>
  10601.     <script type=\"application/ld+json\">
  10602.     {
  10603.         \"@context\": \"https://schema.org/\",
  10604.         \"@type\": \"Product\",
  10605.         \"name\": \"{{ Product.name }}\",
  10606.         \"image\": [
  10607.             {% for img in Product.ProductImage %}
  10608.                 \"{{ app.request.schemeAndHttpHost }}{{ asset(img, 'save_image') }}\"{% if not loop.last %},{% endif %}
  10609.             {% else %}
  10610.                 \"{{ app.request.schemeAndHttpHost }}{{ asset(''|no_image_product, 'save_image') }}\"
  10611.             {% endfor %}
  10612.         ],
  10613.         \"description\": \"{{ Product.description_list | default(Product.description_detail) | replace({'\\n': '', '\\r': ''}) | slice(0,300) }}\",
  10614.         {% if Product.code_min %}
  10615.         \"sku\": \"{{ Product.code_min }}\",
  10616.         {% endif %}
  10617.         \"offers\": {
  10618.             \"@type\": \"Offer\",
  10619.             \"url\": \"{{ url('product_detail', {'id': Product.id}) }}\",
  10620.             \"priceCurrency\": \"{{ eccube_config.currency }}\",
  10621.             \"price\": {{ Product.getPrice02IncTaxMin ? Product.getPrice02IncTaxMin : 0}},
  10622.             \"availability\": \"{{ Product.stock_find ? \"InStock\" : \"OutOfStock\" }}\"
  10623.         }
  10624.     }
  10625.     </script>
  10626. {% endblock %}
  10627. {% block main %}
  10628.     {# option1 / option2 ラベルをカテゴリ別に決定 (sh=31, rd=43, mo=15) - block scope のため main 側でも再定義 #}
  10629.     {% set option1_label = 'オプション1' %}
  10630.     {% set option2_label = 'オプション2' %}
  10631.     {# rd(玄関ドア, cat43) は素材(m)が開き方+ランマを内包し option1(ランマ)/option2(タイプ) が
  10632.        完全な冗長軸のため、素材のみ「開き方」として表示し option1/option2 の選択 UI は抑制する。
  10633.        価格マッチングは m + カラーで一意に決まり、未選択 option は fallback が無視するため影響なし。 #}
  10634.     {% set is_cat43 = false %}
  10635.     {# cp(カーポート, cat7): option1 は折半屋根(スチール折板)価格の運搬に使うため、選択UIは抑制する。
  10636.        価格は寸法で一意に決まり、未選択 option は fallback が無視するため影響なし(cat43 と同型)。 #}
  10637.     {% set is_cp = false %}
  10638.     {% if Product.ProductCategories is not empty %}
  10639.         {% for pcat in Product.ProductCategories %}
  10640.             {% if pcat.category_id == 31 %}{% set option1_label = 'サイズプリセット' %}{% set option2_label = '駆動方式' %}{% endif %}
  10641.             {% if pcat.category_id == 43 %}{% set option1_label = 'ランマ' %}{% set option2_label = 'タイプ' %}{% set is_cat43 = true %}{% endif %}
  10642.             {% if pcat.category_id == 15 %}{% set option1_label = '棚タイプ' %}{% endif %}
  10643.             {% if pcat.category_id == 17 %}{% set option1_label = '窓タイプ' %}{% endif %}
  10644.             {% if pcat.category_id == 7 %}{% set is_cp = true %}{% endif %}
  10645.         {% endfor %}
  10646.     {% endif %}
  10647.     {# pm(素材)軸ラベル: 屋根パネル材なら屋根材/屋根材の色、それ以外は素材。javascript block と
  10648.        同一ロジック (block scope のため main 側でも再定義)。判定は値の中身で行う。 #}
  10649.     {% set pm_is_roof = false %}
  10650.     {% set pm_stems = [] %}
  10651.     {% if p_m %}{% for v in p_m %}{% if v %}
  10652.         {% if v matches '/ポリカ|折板|波板|熱線|ふきポリ|アルミ形材屋根|スチール折板/' %}{% set pm_is_roof = true %}{% endif %}
  10653.         {% set pm_stem = (v|split('(')|first)|split('(')|first|trim %}
  10654.         {% if pm_stem not in pm_stems %}{% set pm_stems = pm_stems|merge([pm_stem]) %}{% endif %}
  10655.     {% endif %}{% endfor %}{% endif %}
  10656.     {% set pm_label = pm_is_roof ? ((pm_stems|length >= 2) ? '屋根材' : '屋根材の色') : '素材' %}
  10657.     <div class=\"ec-productRole\" style=\"margin-top:20px;\">
  10658.         <div class=\"ec-grid2\">
  10659.             <div class=\"ec-grid2__cell\">
  10660.                 <div class=\"ec-sliderItemRole\">
  10661. \t                {# 商品名 + ブランド名 + SNSシェア #}
  10662. \t                <div class=\"ec-productRole__title\">
  10663. \t                    <div class=\"ec-productRole__titleRow\">
  10664. \t                        <h2 class=\"ec-headingTitle\">{{ Product.name }}</h2>
  10665. \t                        <div class=\"ec-share-inline\">
  10666. \t                            <a href=\"https://twitter.com/share?url={{ app.request.uri|url_encode }}&text={{ Product.name|url_encode }}\"
  10667. \t                               class=\"share-twitter\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Xでシェア\">
  10668. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.74l7.73-8.835L1.254 2.25H8.08l4.254 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>
  10669. \t                            </a>
  10670. \t                            <a href=\"https://www.instagram.com/\" class=\"share-facebook\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Instagram\">
  10671. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"/></svg>
  10672. \t                            </a>
  10673. \t                            <a href=\"https://social-plugins.line.me/lineit/share?url={{ app.request.uri|url_encode }}\"
  10674. \t                               class=\"share-line\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"LINEでシェア\">
  10675. \t                                <i class=\"fab fa-line\"></i>
  10676. \t                            </a>
  10677. \t                        </div>
  10678. \t                    </div>
  10679. \t                </div>
  10680.                     {% if BaseInfo.option_favorite_product %}
  10681.                      <div style=\"position:relative;top: 20px;left: 10px;z-index:100;\">
  10682. \t\t\t\t\t\t{% if is_favorite == false %}
  10683.                         <form action=\"{{ url('product_add_favorite', {id:Product.id}) }}\" method=\"post\">
  10684.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\">&#9825;</button>
  10685.                         </form>
  10686.                         {% else %}
  10687.                         <form action=\"{{ url('product_add_favorite', {id:Product.id}) }}\" method=\"post\">
  10688.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\" style=\"color:red;\">&#9829;</button>
  10689.                         </form>
  10690.                         {% endif %}
  10691.                      </div>
  10692.                     {% endif %}
  10693.                     <div class=\"item_visual\">
  10694.                         {% for ProductImage in Product.ProductImage %}
  10695.                             <div class=\"slide-item\">
  10696.                                 <a class=\"js-zoom\" href=\"{{ asset(ProductImage, 'save_image') }}\" aria-label=\"{{ loop.first ? Product.name : '' }}\">
  10697.                                     <img src=\"{{ asset(ProductImage, 'save_image') }}\" alt=\"{{ loop.first ? Product.name : '' }}\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"{% if loop.index > 1 %} loading=\"lazy\"{% endif %}>
  10698.                                 </a>
  10699.                             </div>
  10700.                         {% else %}
  10701.                             <div class=\"slide-item\"><img src=\"{{ asset(''|no_image_product, 'save_image') }}\" alt=\"{{ Product.name }}\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"></div>
  10702.                         {% endfor %}
  10703.                     </div>
  10704.                     <div class=\"item_nav\">
  10705.                         {% for ProductImage in Product.ProductImage %}
  10706.                             <div class=\"slideThumb\" data-index=\"{{ loop.index0 }}\"><img src=\"{{ asset(ProductImage, 'save_image') }}\" alt=\"\" width=\"80\" height=\"80\" loading=\"lazy\"></div>
  10707.                         {% endfor %}
  10708.                     </div>
  10709.                 </div>
  10710.                     {# ===== 施工エリア案内(見積シミュレーションの下)===== #}
  10711.                     <div class=\"ec-areaNotice\" style=\"margin-top:16px;margin-right:10px;\">
  10712.                         <div class=\"ec-areaNotice__inner\">
  10713.                             <div class=\"ec-areaNotice__icon\">📍</div>
  10714.                             <div class=\"ec-areaNotice__body\">
  10715.                                 <p class=\"ec-areaNotice__title\">施工対応エリアについて</p>
  10716.                                 <div class=\"ec-areaNotice__detail\">
  10717.                                     <p class=\"ec-areaNotice__text\">
  10718.                                         当店の施工サービスは、<strong>山梨県全域</strong>および<br>
  10719.                                         <strong>諏訪エリア(諏訪市・岡谷市・茅野市・諏訪郡)</strong>を対象としております。<br>
  10720.                                         上記エリア外のお客様には、商品のみのご購入が可能でございます。<br>
  10721.                                         ご不明な点がございましたら、お気軽にお問い合わせください。
  10722.                                     </p>
  10723.                                     <a class=\"ec-areaNotice__link\" href=\"{{ url('contact') }}\">エリア外のお客様・ご相談はこちら →</a>
  10724.                                 </div>
  10725.                             </div>
  10726.                         </div>
  10727.                     </div>
  10728.             </div>
  10729.             <div class=\"ec-grid2__cell2\">
  10730.                 <div class=\"ec-productRole__profile\" >
  10731.                     {# 関連カテゴリ (DIY=21 / 石材=28 / 照明=44 は非表示要件のため除外) #}
  10732.                     {% set hidden_cat_ids = [21, 28, 44] %}
  10733.                     {% if Product.ProductCategories is not empty %}
  10734.                         <div class=\"ec-productRole__category\" style=\"padding:10px 0;\">
  10735.                             {% for ProductCategory in Product.ProductCategories %}
  10736.                                 {% if ProductCategory.Category.id not in hidden_cat_ids %}
  10737.                                 <ul>
  10738.                                     <li>
  10739.                                         {% for Category in ProductCategory.Category.path %}
  10740.                                             <a href=\"{{ url('product_list') }}?category_id={{ Category.id }}\">{{ Category.name }}</a> {%- if loop.last == false %}
  10741.                                             <span>></span>{% endif -%}
  10742.                                         {% endfor %}
  10743.                                     </li>
  10744.                                 </ul>
  10745.                                 {% endif %}
  10746.                             {% endfor %}
  10747.                         </div>
  10748.                     {% endif %}
  10749.                     {# 販売価格 #}
  10750.                     <div class=\"ec-productRole__price\">
  10751. \t\t\t\t\t\t<span style=\"color:black;font-size:15px;\">工事費込み価格</span>
  10752.                         {# 表示は税抜に統一 (2026-08). 請求額は不変で見積書/PDF/カート/受注は税込のまま. #}
  10753.                         {% if Product.hasProductClass -%}
  10754.                             {% if Product.getPrice02Min == Product.getPrice02Max %}
  10755.                                 <div class=\"ec-price\">
  10756.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">{{ Product.getPrice02Min|price }}</span>
  10757.                                     <span class=\"ec-price__tax\">(税抜)~</span>
  10758.                                 </div>
  10759.                             {% else %}
  10760.                                 <div class=\"ec-price\">
  10761.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">{{ Product.getPrice02Min|price }} ~ {{ Product.getPrice02Max|price }}</span>
  10762.                                     <span class=\"ec-price__tax\">(税抜)</span>
  10763.                                 </div>
  10764.                             {% endif %}
  10765.                         {% else %}
  10766.                             <div class=\"ec-price\">
  10767.                                 <span id=\"price02-display\" class=\"ec-price__price\">{{ Product.getPrice02Min|price }}</span>
  10768.                                     <span class=\"ec-price__tax\">(税抜)~</span>
  10769.                             </div>
  10770.                         {% endif %}
  10771.                     </div>
  10772.                     {# タグ #}
  10773.                     <ul class=\"ec-productRole__tags\">
  10774.                         {% for Tag in Product.Tags %}
  10775.                             <li class=\"ec-productRole__tag tag_{{ Tag.id }}\">{{ Tag }}</li>
  10776.                         {% endfor %}
  10777.                     </ul>
  10778.                     {# 商品コード #}
  10779.                     {% if Product.code_min is not empty %}
  10780.                         <div class=\"ec-productRole__code\">
  10781.                             {{ '商品コード'|trans }}: <span class=\"product-code-default\">{{ Product.code_min }}{% if Product.code_min != Product.code_max %} ~ {{ Product.code_max }}{% endif %}</span>
  10782.                         </div>
  10783.                     {% endif %}
  10784.                     <div class=\"ec-productRole__description\">
  10785. \t\t\t\t        <div class=\"ec-rectHeading\">
  10786. \t\t\t\t            <h4>製品情報</h4>
  10787. \t\t\t\t        </div>
  10788. \t\t\t\t\t\t{{ Product.sales_infomation|raw|nl2br }}
  10789.                     </div>
  10790.                     {# 構成セット内容 (機能門柱など): list_spec に JSON が入っている商品のみ表示.
  10791.                        単体商品や他カテゴリは従来どおりの平文が入っているため json_decode は
  10792.                        null を返し、このブロックごとスキップされる. #}
  10793.                     {% set SetItems = Product.list_spec|json_decode %}
  10794.                     {% if SetItems and SetItems.items is defined and SetItems.items is not empty %}
  10795.                         <div class=\"ec-productRole__setItems\">
  10796.                             <div class=\"ec-rectHeading\">
  10797.                                 <h4>{{ SetItems.title|default('この商品の構成セット内容(メーカーカタログ価格)') }}</h4>
  10798.                             </div>
  10799.                             <table class=\"set-items-table\">
  10800.                                 <tbody>
  10801.                                 {% for SetItem in SetItems.items %}
  10802.                                     <tr>
  10803.                                         <th>{{ SetItem.name }}</th>
  10804.                                         <td>{% if SetItem.price is not empty %}{{ SetItem.price|price }}{% endif %}</td>
  10805.                                     </tr>
  10806.                                 {% endfor %}
  10807.                                 </tbody>
  10808.                                 {% if SetItems.total is not empty %}
  10809.                                 <tfoot>
  10810.                                     <tr>
  10811.                                         <th>構成セット価格(メーカーカタログ価格)</th>
  10812.                                         <td>{{ SetItems.total|price }}</td>
  10813.                                     </tr>
  10814.                                 </tfoot>
  10815.                                 {% endif %}
  10816.                             </table>
  10817.                         </div>
  10818.                     {% endif %}
  10819.                     {# メーカーカタログリンク: 公式メーカードメインのみ表示. ex-shop.net ホストのPDFは情報源露出防止のため非表示 (B案) #}
  10820.                     {% if Product.maker_url is not empty and 'ex-shop.net' not in Product.maker_url %}
  10821.                         <div class=\"ec-productRole__catalog\" style=\"margin:8px 0;\">
  10822.                             <a href=\"{{ Product.maker_url }}\" target=\"_blank\" rel=\"noopener noreferrer\">
  10823.                                 <i class=\"far fa-file-alt\"></i> この商品のメーカーカタログを見る
  10824.                             </a>
  10825.                         </div>
  10826.                     {% endif %}
  10827. \t\t\t\t\t<div class=\"card card-danger\" style=\"clear:both;margin:1px;\">
  10828. \t\t\t\t\t  <div class=\"card-header\">
  10829. \t\t\t\t\t    <h3 class=\"card-title\">見積シミュレーション</h3>
  10830. \t\t\t\t\t  </div>
  10831. \t\t\t\t\t  <div class=\"card-body p-2\">
  10832.                         {% set related_image = getProduct_field(Product.id,\"related_image\") %}
  10833.                         {# related_image は配列: [\"1段目画像あり\",\"2段目画像あり\",\"3段目画像あり\"] のうち該当するものが格納 #}
  10834.                         {% set img1 = related_image and (\"1段目画像あり\" in related_image) %}
  10835.                         {% set img2 = related_image and (\"2段目画像あり\" in related_image) %}
  10836.                         {% set img3 = related_image and (\"3段目画像あり\" in related_image) %}
  10837.                         {% set img4 = related_image and (\"4段目画像あり\" in related_image) %}
  10838. \t\t\t\t\t    {% set type1 = getProduct_field(Product.id,\"related_name1\") %}
  10839. \t\t\t\t\t\t{% set type2 = getProduct_field(Product.id,\"related_name2\") %}
  10840. \t\t\t\t\t\t{% set type3 = getProduct_field(Product.id,\"related_name3\") %}
  10841. \t\t\t\t\t\t{% set type4 = getProduct_field(Product.id,\"related_name4\") %}
  10842. \t\t\t\t\t\t{% set hasRelated = (type1 and related_product1 and related_product1|length)
  10843. \t\t\t\t\t\t                 or (type2 and related_product2 and related_product2|length)
  10844. \t\t\t\t\t\t                 or (type3 and related_product3 and related_product3|length)
  10845. \t\t\t\t\t\t                 or (type4 and related_product4 and related_product4|length) %}
  10846. \t\t\t\t\t\t{% if hasRelated %}
  10847. \t\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のタイプを選択してください。</label></div>
  10848. \t\t\t\t\t\t{% endif %}
  10849. \t\t\t\t\t\t{# ===== 1段目 ===== #}
  10850. \t\t\t\t\t\t{% if type1 and related_product1 and related_product1|length %}
  10851. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10852. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type1 }}{% if img1 and base_select1 %}: <span>{{ base_select1 }}</span>{% endif %}</div>
  10853. \t\t\t\t\t\t  {% if img1 %}
  10854. \t\t\t\t\t\t    {# --- 画像付きカード --- #}
  10855. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10856. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product1 %}
  10857. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select1 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10858. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10859. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10860. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  10861. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  10862. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  10863. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  10864. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  10865. \t\t\t\t\t\t        </a>
  10866. \t\t\t\t\t\t      {% endfor %}
  10867. \t\t\t\t\t\t    </div>
  10868. \t\t\t\t\t\t  {% else %}
  10869. \t\t\t\t\t\t    {# --- ボタン式ラジオ --- #}
  10870. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10871. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product1 %}
  10872. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select1 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10873. \t\t\t\t\t\t          {{ rp_name }}
  10874. \t\t\t\t\t\t        </a>
  10875. \t\t\t\t\t\t      {% endfor %}
  10876. \t\t\t\t\t\t    </div>
  10877. \t\t\t\t\t\t  {% endif %}
  10878. \t\t\t\t\t\t</div>
  10879. \t\t\t\t\t\t{% endif %}
  10880. \t\t\t\t\t\t{# ===== 2段目 ===== #}
  10881. \t\t\t\t\t\t{% if type2 and related_product2 and related_product2|length %}
  10882. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10883. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type2 }}{% if img2 and base_select2 %}: <span>{{ base_select2 }}</span>{% endif %}</div>
  10884. \t\t\t\t\t\t  {% if img2 %}
  10885. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10886. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product2 %}
  10887. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select2 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10888. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10889. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10890. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  10891. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  10892. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  10893. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  10894. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  10895. \t\t\t\t\t\t        </a>
  10896. \t\t\t\t\t\t      {% endfor %}
  10897. \t\t\t\t\t\t    </div>
  10898. \t\t\t\t\t\t  {% else %}
  10899. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10900. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product2 %}
  10901. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select2 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10902. \t\t\t\t\t\t          {{ rp_name }}
  10903. \t\t\t\t\t\t        </a>
  10904. \t\t\t\t\t\t      {% endfor %}
  10905. \t\t\t\t\t\t    </div>
  10906. \t\t\t\t\t\t  {% endif %}
  10907. \t\t\t\t\t\t</div>
  10908. \t\t\t\t\t\t{% endif %}
  10909. \t\t\t\t\t\t{# ===== 3段目 ===== #}
  10910. \t\t\t\t\t\t{% if type3 and related_product3 and related_product3|length %}
  10911. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10912. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type3 }}{% if img3 and base_select3 %}: <span>{{ base_select3 }}</span>{% endif %}</div>
  10913. \t\t\t\t\t\t  {% if img3 %}
  10914. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10915. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product3 %}
  10916. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select3 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10917. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10918. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10919. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  10920. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  10921. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  10922. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  10923. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  10924. \t\t\t\t\t\t        </a>
  10925. \t\t\t\t\t\t      {% endfor %}
  10926. \t\t\t\t\t\t    </div>
  10927. \t\t\t\t\t\t  {% else %}
  10928. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10929. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product3 %}
  10930. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select3 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10931. \t\t\t\t\t\t          {{ rp_name }}
  10932. \t\t\t\t\t\t        </a>
  10933. \t\t\t\t\t\t      {% endfor %}
  10934. \t\t\t\t\t\t    </div>
  10935. \t\t\t\t\t\t  {% endif %}
  10936. \t\t\t\t\t\t</div>
  10937. \t\t\t\t\t\t{% endif %}
  10938. \t\t\t\t\t\t{# ===== 4段目 ===== #}
  10939. \t\t\t\t\t\t{% if type4 and related_product4 and related_product4|length %}
  10940. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10941. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type4 }}{% if img4 and base_select4 %}: <span>{{ base_select4 }}</span>{% endif %}</div>
  10942. \t\t\t\t\t\t  {% if img4 %}
  10943. \t\t\t\t\t\t    {# --- 画像付きカード --- #}
  10944. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10945. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product4 %}
  10946. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select4 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10947. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10948. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10949. \t\t\t\t\t\t               alt=\"{{ rp_name }}\" width=\"120\" height=\"120\" loading=\"lazy\">
  10950. \t\t\t\t\t\t          <span class=\"rp-card__label\">{{ rp_name }}</span>
  10951. \t\t\t\t\t\t        </a>
  10952. \t\t\t\t\t\t      {% endfor %}
  10953. \t\t\t\t\t\t    </div>
  10954. \t\t\t\t\t\t  {% else %}
  10955. \t\t\t\t\t\t    {# --- ボタン式ラジオ --- #}
  10956. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10957. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product4 %}
  10958. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select4 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10959. \t\t\t\t\t\t          {{ rp_name }}
  10960. \t\t\t\t\t\t        </a>
  10961. \t\t\t\t\t\t      {% endfor %}
  10962. \t\t\t\t\t\t    </div>
  10963. \t\t\t\t\t\t  {% endif %}
  10964. \t\t\t\t\t\t</div>
  10965. \t\t\t\t\t\t{% endif %}
  10966. \t\t\t\t\t    {# ガレージ等で全オプション空のときに見出しのみ表示される事象を回避.
  10967. \t\t\t\t\t       色 / 寸法 / 素材 / option1/2 / op_data いずれかに「描画される」要素がある場合のみ
  10968. \t\t\t\t\t       「この商品のオプションを選択してください。」見出しを表示する.
  10969. \t\t\t\t\t       op_data は cg=9 で「残土」 / gs=27 で「撤去」「残土」を後段ループで
  10970. \t\t\t\t\t       hide するため、単純な op|length > 0 では「見出しだけ残る」事象が
  10971. \t\t\t\t\t       wh / cg の一部商品で発生していた. 描画される entry を事前カウントする. #}
  10972. \t\t\t\t\t    {% set is_gs_h = false %}
  10973. \t\t\t\t\t    {% set is_cg_h = false %}
  10974. \t\t\t\t\t    {% if Product.ProductCategories is not empty %}
  10975. \t\t\t\t\t        {% for pc_h in Product.ProductCategories %}
  10976. \t\t\t\t\t            {% if pc_h.category_id == 27 %}{% set is_gs_h = true %}{% endif %}
  10977. \t\t\t\t\t            {% if pc_h.category_id == 9  %}{% set is_cg_h = true %}{% endif %}
  10978. \t\t\t\t\t        {% endfor %}
  10979. \t\t\t\t\t    {% endif %}
  10980. \t\t\t\t\t    {% set visible_op_count = 0 %}
  10981. \t\t\t\t\t    {% if op and op|length %}
  10982. \t\t\t\t\t        {% for opi in op %}
  10983. \t\t\t\t\t            {% if opi['name'] %}
  10984. \t\t\t\t\t                {% set _hide_h = false %}
  10985. \t\t\t\t\t                {% if is_gs_h and (opi['name'] matches '/撤去/' or opi['name'] matches '/残土/') %}{% set _hide_h = true %}{% endif %}
  10986. \t\t\t\t\t                {% if is_cg_h and opi['name'] matches '/残土/' %}{% set _hide_h = true %}{% endif %}
  10987. \t\t\t\t\t                {% if not _hide_h %}{% set visible_op_count = visible_op_count + 1 %}{% endif %}
  10988. \t\t\t\t\t            {% endif %}
  10989. \t\t\t\t\t        {% endfor %}
  10990. \t\t\t\t\t    {% endif %}
  10991. \t\t\t\t\t    {% set has_any_option =
  10992. \t\t\t\t\t        (color and color|length and ProductClass.SaleType.id != 3)
  10993. \t\t\t\t\t        or (p_w and p_w|length and p_w|join != \"\")
  10994. \t\t\t\t\t        or (p_d and p_d|length and p_d|join != \"\")
  10995. \t\t\t\t\t        or (p_h and p_h|length and p_h|join != \"\")
  10996. \t\t\t\t\t        or (p_m and p_m|length and p_m|join != \"\")
  10997. \t\t\t\t\t        or (p_option1 and p_option1|length and p_option1|join != \"\")
  10998. \t\t\t\t\t        or (p_option2 and p_option2|length and p_option2|join != \"\")
  10999. \t\t\t\t\t        or ProductClass.SaleType.id in [2, 5, 6, 7, 9]
  11000. \t\t\t\t\t    %}
  11001. \t\t\t\t\t    {% if has_any_option %}
  11002. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のオプションを選択してください。</label></div>
  11003. \t\t\t\t\t    {% endif %}
  11004.                         {# sale_type=2 (補助金窓) はタイプごとに個別カラー選択するため共通カラーは非表示 #}
  11005.                         {% if color and color|length and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 2 %}
  11006.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11007.                           <div class=\"rp-section-label\">カラー{% if mitsumori_json and mitsumori_json.pc %}: <span>{{ mitsumori_json.pc }}</span>{% endif %}</div>
  11008.                           <div class=\"opt-btn-group\">
  11009.                             {% set idx = 0 %}
  11010.                             {% for cc in color %}{% if cc and cc['name'] %}{% set idx = idx + 1 %}
  11011.                               {% set has_img = cc['img'] is defined and cc['img'] is not empty %}
  11012.                               <label class=\"opt-btn{% if has_img %} opt-btn--with-image{% endif %}{% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %} is-selected{% endif %}\"
  11013.                                      onclick=\"mitsumori_simulation_val('pc', '{{ cc['name']|e('js') }}');\">
  11014.                                 <input type=\"radio\" name=\"color\" id=\"cc_{{ idx }}\" value=\"{{ cc['name'] }}\"
  11015.                                        {% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %}checked{% endif %}>
  11016.                                 {% if has_img %}
  11017.                                   <img src=\"{{ cc['img'] }}\" alt=\"{{ cc['name'] }}\" class=\"opt-btn__img\"
  11018.                                        onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  11019.                                   <span class=\"opt-btn__name\">{{ cc['name'] }}</span>
  11020.                                 {% else %}
  11021.                                   {{ cc['name'] }}
  11022.                                 {% endif %}
  11023.                               </label>
  11024.                             {% endif %}{% endfor %}
  11025.                           </div>
  11026.                         </div>
  11027.                         {% endif %}
  11028.                         {# sale_type=2 (補助金窓) はタイプごとに個別幅選択するため共通幅は非表示.
  11029.                            tf (人工芝, sale_type=6) は専用の「芝の幅」+「施工サイズ」UI を下部に持つため、
  11030.                            汎用の 幅/奥行/高さ は描画しない (両方出すと name=\"pw\"/\"ph\" が重複し、
  11031.                            片方を選ぶともう片方の選択が外れる顧客指摘あり). #}
  11032.                         {% if p_w and p_w|length and p_w|join != \"\" and ProductClass.SaleType.id not in [2, 3, 6] %}
  11033.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11034.                           <div class=\"rp-section-label\">幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  11035.                           <div class=\"opt-btn-group\">
  11036.                             {% set idx = 0 %}
  11037.                             {% for pw in p_w %}{% if pw %}{% set idx = idx + 1 %}
  11038.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw) or p_w|length == 1 %} is-selected{% endif %}\"
  11039.                                      onclick=\"mitsumori_simulation_val('pw', '{{ pw|e('js') }}');\">
  11040.                                 <input type=\"radio\" name=\"pw\" id=\"pw_{{ idx }}\" value=\"{{ pw }}\"
  11041.                                        {% if (mitsumori_json and mitsumori_json.pw == pw) or p_w|length == 1 %}checked{% endif %}>
  11042.                                 {{ pw }}
  11043.                               </label>
  11044.                             {% endif %}{% endfor %}
  11045.                           </div>
  11046.                         </div>
  11047.                         {% endif %}
  11048.                         {% if p_d and p_d|length and p_d|join != \"\" and ProductClass.SaleType.id not in [3, 6] %}
  11049.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11050.                           <div class=\"rp-section-label\">奥行き{% if mitsumori_json and mitsumori_json.pd %}: <span>{{ mitsumori_json.pd }}</span>{% endif %}</div>
  11051.                           <div class=\"opt-btn-group\">
  11052.                             {% set idx = 0 %}
  11053.                             {% for pd in p_d %}{% if pd %}{% set idx = idx + 1 %}
  11054.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pd == pd) or p_d|length == 1 %} is-selected{% endif %}\"
  11055.                                      onclick=\"mitsumori_simulation_val('pd', '{{ pd|e('js') }}');\">
  11056.                                 <input type=\"radio\" name=\"pd\" id=\"pd_{{ idx }}\" value=\"{{ pd }}\"
  11057.                                        {% if (mitsumori_json and mitsumori_json.pd == pd) or p_d|length == 1 %}checked{% endif %}>
  11058.                                 {{ pd }}
  11059.                               </label>
  11060.                             {% endif %}{% endfor %}
  11061.                           </div>
  11062.                         </div>
  11063.                         {% endif %}
  11064.                         {# sale_type=2 (補助金窓) はタイプごとに個別高さ選択するため共通高さは非表示.
  11065.                            sale_type=6 (人工芝) は専用 UI なので汎用高さは描画しない. #}
  11066.                         {% if p_h and p_h|length and p_h|join != \"\" and ProductClass.SaleType.id not in [2, 3, 6] %}
  11067.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11068.                           <div class=\"rp-section-label\">高さ{% if mitsumori_json and mitsumori_json.ph %}: <span>{{ mitsumori_json.ph }}</span>{% endif %}</div>
  11069.                           <div class=\"opt-btn-group\">
  11070.                             {% set idx = 0 %}
  11071.                             {% for ph in p_h %}{% if ph %}{% set idx = idx + 1 %}
  11072.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.ph == ph) or p_h|length == 1 %} is-selected{% endif %}\"
  11073.                                      onclick=\"mitsumori_simulation_val('ph', '{{ ph|e('js') }}');\">
  11074.                                 <input type=\"radio\" name=\"ph\" id=\"ph_{{ idx }}\" value=\"{{ ph }}\"
  11075.                                        {% if (mitsumori_json and mitsumori_json.ph == ph) or p_h|length == 1 %}checked{% endif %}>
  11076.                                 {{ ph }}
  11077.                               </label>
  11078.                             {% endif %}{% endfor %}
  11079.                           </div>
  11080.                         </div>
  11081.                         {% endif %}
  11082.                         {# sale_type=2 (補助金窓) はタイプごとに個別ガラス選択するため共通素材は非表示 #}
  11083.                         {% if p_m and p_m|length and p_m|join != \"\" and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 2 %}
  11084.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11085.                           <div class=\"rp-section-label\">{% if is_cat43 %}開き方{% else %}{{ pm_label }}{% endif %}{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  11086.                           <div class=\"opt-btn-group\">
  11087.                             {% set idx = 0 %}
  11088.                             {% for pm in p_m %}{% if pm %}{% set idx = idx + 1 %}
  11089.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm) or p_m|length == 1 %} is-selected{% endif %}\"
  11090.                                      onclick=\"mitsumori_simulation_val('pm', '{{ pm|e('js') }}');\">
  11091.                                 <input type=\"radio\" name=\"pm\" id=\"pm_{{ idx }}\" value=\"{{ pm }}\"
  11092.                                        {% if (mitsumori_json and mitsumori_json.pm == pm) or p_m|length == 1 %}checked{% endif %}>
  11093.                                 {{ pm }}
  11094.                               </label>
  11095.                             {% endif %}{% endfor %}
  11096.                           </div>
  11097.                         </div>
  11098.                         {% endif %}
  11099.                         {# option1 (sale_type 2 は専用 UI が下にあるため除外 / sale_type 3 は下部ブロックで描画 /
  11100.                            sale_type 4 = fe・ts は option1 が ct_unit_price (枚数増分の工事費単価) で
  11101.                            ユーザー選択肢ではなく計算用の内部値のため radio として表示しない. 値は
  11102.                            上の auto-init (p_option1|length == 1) で JS の option1 変数に埋め込み済み) #}
  11103.                         {% if p_option1 and p_option1|length and p_option1|join != \"\" and ProductClass.SaleType.id != 2 and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 4 and not is_cat43 and not is_cp %}
  11104.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11105.                           <div class=\"rp-section-label\">{{ option1_label }}{% if mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 %}: <span>{{ mitsumori_json.option1 }}</span>{% endif %}</div>
  11106.                           <div class=\"opt-btn-group\">
  11107.                             {% set idx = 0 %}
  11108.                             {% for opt1 in p_option1 %}{% if opt1 %}{% set idx = idx + 1 %}
  11109.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1) or p_option1|length == 1 %} is-selected{% endif %}\"
  11110.                                      onclick=\"mitsumori_simulation_val('option1', '{{ opt1|e('js') }}');\">
  11111.                                 <input type=\"radio\" name=\"option1\" id=\"option1_{{ idx }}\" value=\"{{ opt1 }}\"
  11112.                                        {% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1) or p_option1|length == 1 %}checked{% endif %}>
  11113.                                 {{ opt1 }}
  11114.                               </label>
  11115.                             {% endif %}{% endfor %}
  11116.                           </div>
  11117.                         </div>
  11118.                         {% endif %}
  11119.                         {# option2 #}
  11120.                         {% if p_option2 and p_option2|length and p_option2|join != \"\" and ProductClass.SaleType.id != 2 and ProductClass.SaleType.id != 3 and not is_cat43 %}
  11121.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11122.                           <div class=\"rp-section-label\">{{ option2_label }}{% if mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 %}: <span>{{ mitsumori_json.option2 }}</span>{% endif %}</div>
  11123.                           <div class=\"opt-btn-group\">
  11124.                             {% set idx = 0 %}
  11125.                             {% for opt2 in p_option2 %}{% if opt2 %}{% set idx = idx + 1 %}
  11126.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 == opt2) or p_option2|length == 1 %} is-selected{% endif %}\"
  11127.                                      onclick=\"mitsumori_simulation_val('option2', '{{ opt2|e('js') }}');\">
  11128.                                 <input type=\"radio\" name=\"option2\" id=\"option2_{{ idx }}\" value=\"{{ opt2 }}\"
  11129.                                        {% if (mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 == opt2) or p_option2|length == 1 %}checked{% endif %}>
  11130.                                 {{ opt2 }}
  11131.                               </label>
  11132.                             {% endif %}{% endfor %}
  11133.                           </div>
  11134.                         </div>
  11135.                         {% endif %}
  11136. \t\t\t\t\t\t<!-- 1: 施工見積(通常) → 幅/奥行/高さ/素材/カラーは上部の共通ブロックで表示済み -->
  11137. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 1 %}
  11138. \t\t\t\t\t\t{% endif %}
  11139. \t\t\t\t\t\t<!-- 2: 施工見積(補助金・窓) 複数タイプ追加対応 (2026-05) -->
  11140. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 2 %}
  11141. \t\t\t\t\t\t\t{# 2026-05 改修: ex-shop プラメイク方式に倣い、1 商品で
  11142. \t\t\t\t\t\t\t   複数の「窓タイプ」(subtype × 幅 × 高さ × ガラス × カラー × セット数)
  11143. \t\t\t\t\t\t\t   を追加できる UI に変更. 各タイプは内訳 JSON として 1 明細にまとめる. #}
  11144. \t\t\t\t\t\t\t{# ec-productRole__profile は標準テンプレで height:600px / overflow:auto
  11145. \t\t\t\t\t\t\t   が当たっており、複数タイプ追加カードが内部スクロールに押し込まれて
  11146. \t\t\t\t\t\t\t   見えない. sale_type=2 のときだけ縦方向に伸ばす. #}
  11147. \t\t\t\t\t\t\t<style>
  11148. \t\t\t\t\t\t\t\t.ec-productRole__profile {
  11149. \t\t\t\t\t\t\t\t\toverflow: visible !important;
  11150. \t\t\t\t\t\t\t\t\tmax-height: none !important;
  11151. \t\t\t\t\t\t\t\t\theight: auto !important;
  11152. \t\t\t\t\t\t\t\t}
  11153. \t\t\t\t\t\t\t</style>
  11154. \t\t\t\t\t\t\t{# 住宅区分 UI: 補助金単価が戸建 / 集合住宅で異なるためお客様に申告いただく. #}
  11155. \t\t\t\t\t\t\t{% set housing_default = getProduct_field(Product.id, '住宅区分')|default('戸建') %}
  11156. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  11157. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  11158. \t\t\t\t\t\t\t    <strong>お住まいの種別を選択</strong>
  11159. \t\t\t\t\t\t\t    <small class=\"ms-2 text-muted\">補助金単価が変わります</small>
  11160. \t\t\t\t\t\t\t  </div>
  11161. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  11162. \t\t\t\t\t\t\t    <div class=\"opt-btn-group\" id=\"window-housing-type-group\">
  11163. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  11164. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"戸建\"
  11165. \t\t\t\t\t\t\t               {% if housing_default != '集合住宅' %}checked{% endif %}>
  11166. \t\t\t\t\t\t\t        戸建住宅<small class=\"d-block text-muted\">(延床240㎡以下の非住宅含む)</small>
  11167. \t\t\t\t\t\t\t      </label>
  11168. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  11169. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"集合住宅\"
  11170. \t\t\t\t\t\t\t               {% if housing_default == '集合住宅' %}checked{% endif %}>
  11171. \t\t\t\t\t\t\t        集合住宅<small class=\"d-block text-muted\">(低層・中高層/240㎡超の非住宅)</small>
  11172. \t\t\t\t\t\t\t      </label>
  11173. \t\t\t\t\t\t\t    </div>
  11174. \t\t\t\t\t\t\t  </div>
  11175. \t\t\t\t\t\t\t</div>
  11176. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  11177. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  11178. \t\t\t\t\t\t\t    <strong>窓タイプを選択(複数追加可・最大 20)</strong>
  11179. \t\t\t\t\t\t\t  </div>
  11180. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  11181. \t\t\t\t\t\t\t    {# (b) 補助金5万円要件の常設明示。各窓の補助金額はブロック内に常時表示。 #}
  11182. \t\t\t\t\t\t\t    <p class=\"subsidy-eligibility-note\">※先進的窓リノベ2026の補助金は、各窓の補助金額の<strong>合計が5万円以上</strong>で適用されます。各窓ごとの補助金額は下に常時表示しています。</p>
  11183. \t\t\t\t\t\t\t    <div id=\"window-types-container\"><!-- 動的に窓タイプブロックが追加される --></div>
  11184. \t\t\t\t\t\t\t    <div class=\"text-center mt-2\">
  11185. \t\t\t\t\t\t\t      <button type=\"button\" id=\"btn-add-window-type\" class=\"btn btn-outline-primary btn-sm\" onclick=\"addWindowType();\">+ 窓タイプを追加</button>
  11186. \t\t\t\t\t\t\t      <div class=\"small text-muted mt-1\">最大 20 タイプまで追加できます</div>
  11187. \t\t\t\t\t\t\t    </div>
  11188. \t\t\t\t\t\t\t  </div>
  11189. \t\t\t\t\t\t\t</div>
  11190. \t\t\t\t\t\t\t{# 窓タイプブロックのテンプレート. __IDX__ を JS で連番に置換して clone する. #}
  11191. \t\t\t\t\t\t\t<template id=\"window-type-template\">
  11192. \t\t\t\t\t\t\t  <div class=\"window-type-block\" data-type-idx=\"__IDX__\" style=\"border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:10px;background:#fafafa;\">
  11193. \t\t\t\t\t\t\t    <div class=\"d-flex justify-content-between align-items-center mb-2\">
  11194. \t\t\t\t\t\t\t      <strong>窓タイプ <span class=\"wt-num\">__IDX__</span></strong>
  11195. \t\t\t\t\t\t\t      <button type=\"button\" class=\"btn btn-sm btn-outline-danger btn-remove-window-type\" onclick=\"removeWindowType(this);\">× 削除</button>
  11196. \t\t\t\t\t\t\t    </div>
  11197. \t\t\t\t\t\t\t    {# 窓タイプ (subtype) #}
  11198. \t\t\t\t\t\t\t    {% if p_option1 and p_option1|length and p_option1|join != \"\" %}
  11199. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  11200. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓タイプ</div>
  11201. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  11202. \t\t\t\t\t\t\t        {% for v in p_option1 %}{% if v %}
  11203. \t\t\t\t\t\t\t          <label class=\"opt-btn\">
  11204. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_subtype___IDX__\" value=\"{{ v }}\" data-axis=\"subtype\" onchange=\"onWindowTypeAxisChange(this);\">
  11205. \t\t\t\t\t\t\t            {{ v }}
  11206. \t\t\t\t\t\t\t          </label>
  11207. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  11208. \t\t\t\t\t\t\t      </div>
  11209. \t\t\t\t\t\t\t    </div>
  11210. \t\t\t\t\t\t\t    {% endif %}
  11211. \t\t\t\t\t\t\t    {# 幅 (mm 直接入力) #}
  11212. \t\t\t\t\t\t\t    {% if p_w and p_w|length and p_w|join != \"\" %}
  11213. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  11214. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">幅</div>
  11215. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  11216. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_pw___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  11217. \t\t\t\t\t\t\t               placeholder=\"例 1750\" data-axis=\"pw\" data-unit=\"mm\"
  11218. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  11219. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  11220. \t\t\t\t\t\t\t      </div>
  11221. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応幅: 〜{{ (p_w|last)|default('') }}({{ p_w|length }} 段階の価格帯から自動選択)</small>
  11222. \t\t\t\t\t\t\t    </div>
  11223. \t\t\t\t\t\t\t    {% endif %}
  11224. \t\t\t\t\t\t\t    {# 高さ (mm 直接入力) #}
  11225. \t\t\t\t\t\t\t    {% if p_h and p_h|length and p_h|join != \"\" %}
  11226. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  11227. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">高さ</div>
  11228. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  11229. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_ph___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  11230. \t\t\t\t\t\t\t               placeholder=\"例 1200\" data-axis=\"ph\" data-unit=\"mm\"
  11231. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  11232. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  11233. \t\t\t\t\t\t\t      </div>
  11234. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応高さ: 〜{{ (p_h|last)|default('') }}({{ p_h|length }} 段階の価格帯から自動選択)</small>
  11235. \t\t\t\t\t\t\t    </div>
  11236. \t\t\t\t\t\t\t    {% endif %}
  11237. \t\t\t\t\t\t\t    {# ガラスタイプ #}
  11238. \t\t\t\t\t\t\t    {% if p_m and p_m|length and p_m|join != \"\" %}
  11239. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  11240. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">ガラスタイプ</div>
  11241. \t\t\t\t\t\t\t      {# A-3: 内窓ガラス名は長い(例 ~449px)。横スクロール(is-scroll)化すると
  11242. \t\t\t\t\t\t\t         左が見切れるため no-hscroll で縦積み+折り返し表示に固定する。 #}
  11243. \t\t\t\t\t\t\t      <div class=\"opt-btn-group no-hscroll\">
  11244. \t\t\t\t\t\t\t        {% for v in p_m %}{% if v %}
  11245. \t\t\t\t\t\t\t          <label class=\"opt-btn\">
  11246. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pm___IDX__\" value=\"{{ v }}\" data-axis=\"pm\" onchange=\"onWindowTypeAxisChange(this);\">
  11247. \t\t\t\t\t\t\t            {{ v }}
  11248. \t\t\t\t\t\t\t          </label>
  11249. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  11250. \t\t\t\t\t\t\t      </div>
  11251. \t\t\t\t\t\t\t      <small class=\"text-muted\">「<span style=\"color:#2e7d32;font-weight:bold;\">補助金対象</span>」が付いたガラスは、先進的窓リノベ補助金の対象です。</small>
  11252. \t\t\t\t\t\t\t    </div>
  11253. \t\t\t\t\t\t\t    {% endif %}
  11254. \t\t\t\t\t\t\t    {# 窓枠カラー #}
  11255. \t\t\t\t\t\t\t    {% if color and color|length %}
  11256. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  11257. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓枠カラー</div>
  11258. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  11259. \t\t\t\t\t\t\t        {% for cc in color %}{% if cc and cc['name'] %}
  11260. \t\t\t\t\t\t\t          {% set has_img = cc['img'] is defined and cc['img'] is not empty %}
  11261. \t\t\t\t\t\t\t          <label class=\"opt-btn{% if has_img %} opt-btn--with-image{% endif %}\">
  11262. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pc___IDX__\" value=\"{{ cc['name'] }}\" data-axis=\"pc\" onchange=\"onWindowTypeAxisChange(this);\">
  11263. \t\t\t\t\t\t\t            {% if has_img %}
  11264. \t\t\t\t\t\t\t              <img src=\"{{ cc['img'] }}\" alt=\"{{ cc['name'] }}\" class=\"opt-btn__img\"
  11265. \t\t\t\t\t\t\t                   onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  11266. \t\t\t\t\t\t\t              <span class=\"opt-btn__name\">{{ cc['name'] }}</span>
  11267. \t\t\t\t\t\t\t            {% else %}
  11268. \t\t\t\t\t\t\t              {{ cc['name'] }}
  11269. \t\t\t\t\t\t\t            {% endif %}
  11270. \t\t\t\t\t\t\t          </label>
  11271. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  11272. \t\t\t\t\t\t\t      </div>
  11273. \t\t\t\t\t\t\t    </div>
  11274. \t\t\t\t\t\t\t    {% endif %}
  11275. \t\t\t\t\t\t\t    {# セット数 + タイプごとの補助金額表示 (補助金は task 2 で実計算) #}
  11276. \t\t\t\t\t\t\t    <div class=\"form-group row mt-2 align-items-center\">
  11277. \t\t\t\t\t\t\t      <label class=\"col-4 col-form-label\">セット数</label>
  11278. \t\t\t\t\t\t\t      <div class=\"col-4\">
  11279. \t\t\t\t\t\t\t        <div class=\"input-group\">
  11280. \t\t\t\t\t\t\t          <input type=\"number\" name=\"wt_setqty___IDX__\" class=\"form-control wt-input-setqty\" value=\"1\" min=\"1\" max=\"99\" data-axis=\"setqty\" onchange=\"onWindowTypeAxisChange(this);\">
  11281. \t\t\t\t\t\t\t          <span class=\"input-group-text\">セット</span>
  11282. \t\t\t\t\t\t\t        </div>
  11283. \t\t\t\t\t\t\t      </div>
  11284. \t\t\t\t\t\t\t      <div class=\"col-4 text-end\">
  11285. \t\t\t\t\t\t\t        <span class=\"wt-subsidy-label\">補助金額</span><br><span class=\"wt-subsidy-amount\">―</span> <span class=\"wt-subsidy-label\">円</span>
  11286. \t\t\t\t\t\t\t      </div>
  11287. \t\t\t\t\t\t\t    </div>
  11288. \t\t\t\t\t\t\t  </div>
  11289. \t\t\t\t\t\t\t</template>
  11290. \t\t\t\t\t\t\t{# 複数タイプ管理 JS. addWindowType / removeWindowType / 再番号付け. #}
  11291. \t\t\t\t\t\t\t<script>
  11292. \t\t\t\t\t\t\t(function() {
  11293. \t\t\t\t\t\t\t\tvar MAX_WINDOW_TYPES = 20;
  11294. \t\t\t\t\t\t\t\tfunction addWindowType() {
  11295. \t\t\t\t\t\t\t\t\tvar container = document.getElementById('window-types-container');
  11296. \t\t\t\t\t\t\t\t\tif (!container) return;
  11297. \t\t\t\t\t\t\t\t\tvar existing = container.querySelectorAll('.window-type-block');
  11298. \t\t\t\t\t\t\t\t\tif (existing.length >= MAX_WINDOW_TYPES) return;
  11299. \t\t\t\t\t\t\t\t\tvar newIdx = existing.length + 1;
  11300. \t\t\t\t\t\t\t\t\tvar tpl = document.getElementById('window-type-template');
  11301. \t\t\t\t\t\t\t\t\tif (!tpl) return;
  11302. \t\t\t\t\t\t\t\t\t// <template> の innerHTML を取り出して __IDX__ を新規連番に置換し、要素化して append.
  11303. \t\t\t\t\t\t\t\t\tvar html = tpl.innerHTML.replace(/__IDX__/g, String(newIdx));
  11304. \t\t\t\t\t\t\t\t\tvar wrapper = document.createElement('div');
  11305. \t\t\t\t\t\t\t\t\twrapper.innerHTML = html.trim();
  11306. \t\t\t\t\t\t\t\t\tvar block = wrapper.firstChild;
  11307. \t\t\t\t\t\t\t\t\tcontainer.appendChild(block);
  11308. \t\t\t\t\t\t\t\t\tdecorateSubsidyGlass(block);
  11309. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  11310. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  11311. \t\t\t\t\t\t\t\t}
  11312. \t\t\t\t\t\t\t\t// 補助金対象ガラスの選択肢に「補助金対象」バッジ + 緑枠を付与する.
  11313. \t\t\t\t\t\t\t\t// 判定は calc script 側の window.glassYieldsSubsidy に委譲 (ロジック二重化を避ける)。
  11314. \t\t\t\t\t\t\t\tfunction decorateSubsidyGlass(block) {
  11315. \t\t\t\t\t\t\t\t\tif (!block || typeof window.glassYieldsSubsidy !== 'function') return;
  11316. \t\t\t\t\t\t\t\t\tvar radios = block.querySelectorAll('input[data-axis=\"pm\"]');
  11317. \t\t\t\t\t\t\t\t\tradios.forEach(function(inp) {
  11318. \t\t\t\t\t\t\t\t\t\tvar label = inp.closest('.opt-btn');
  11319. \t\t\t\t\t\t\t\t\t\tif (!label || label.querySelector('.opt-btn__subsidy-badge')) return;
  11320. \t\t\t\t\t\t\t\t\t\tif (window.glassYieldsSubsidy(inp.value)) {
  11321. \t\t\t\t\t\t\t\t\t\t\tlabel.classList.add('opt-btn--subsidy');
  11322. \t\t\t\t\t\t\t\t\t\t\tvar badge = document.createElement('span');
  11323. \t\t\t\t\t\t\t\t\t\t\tbadge.className = 'opt-btn__subsidy-badge';
  11324. \t\t\t\t\t\t\t\t\t\t\tbadge.textContent = '補助金対象';
  11325. \t\t\t\t\t\t\t\t\t\t\tlabel.appendChild(badge);
  11326. \t\t\t\t\t\t\t\t\t\t}
  11327. \t\t\t\t\t\t\t\t\t});
  11328. \t\t\t\t\t\t\t\t}
  11329. \t\t\t\t\t\t\t\tfunction removeWindowType(btn) {
  11330. \t\t\t\t\t\t\t\t\tvar block = btn.closest('.window-type-block');
  11331. \t\t\t\t\t\t\t\t\tif (!block) return;
  11332. \t\t\t\t\t\t\t\t\tblock.remove();
  11333. \t\t\t\t\t\t\t\t\treindexBlocks();
  11334. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  11335. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  11336. \t\t\t\t\t\t\t\t}
  11337. \t\t\t\t\t\t\t\tfunction updateRemoveButtonVisibility() {
  11338. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  11339. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b) {
  11340. \t\t\t\t\t\t\t\t\t\tvar btn = b.querySelector('.btn-remove-window-type');
  11341. \t\t\t\t\t\t\t\t\t\tif (btn) btn.style.display = blocks.length > 1 ? '' : 'none';
  11342. \t\t\t\t\t\t\t\t\t});
  11343. \t\t\t\t\t\t\t\t}
  11344. \t\t\t\t\t\t\t\tfunction reindexBlocks() {
  11345. \t\t\t\t\t\t\t\t\t// ブロック削除後に 1 から振り直し. input[name] の末尾 _N も書き換える.
  11346. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  11347. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b, i) {
  11348. \t\t\t\t\t\t\t\t\t\tvar n = i + 1;
  11349. \t\t\t\t\t\t\t\t\t\tb.setAttribute('data-type-idx', String(n));
  11350. \t\t\t\t\t\t\t\t\t\tvar numSpan = b.querySelector('.wt-num');
  11351. \t\t\t\t\t\t\t\t\t\tif (numSpan) numSpan.textContent = String(n);
  11352. \t\t\t\t\t\t\t\t\t\tb.querySelectorAll('input[name]').forEach(function(inp) {
  11353. \t\t\t\t\t\t\t\t\t\t\tinp.name = inp.name.replace(/_\\d+\$/, '_' + n);
  11354. \t\t\t\t\t\t\t\t\t\t});
  11355. \t\t\t\t\t\t\t\t\t});
  11356. \t\t\t\t\t\t\t\t}
  11357. \t\t\t\t\t\t\t\t// 軸変更イベント. recalcAll が定義されていれば再計算 (task 2 で実装).
  11358. \t\t\t\t\t\t\t\twindow.onWindowTypeAxisChange = function() {
  11359. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  11360. \t\t\t\t\t\t\t\t};
  11361. \t\t\t\t\t\t\t\twindow.addWindowType = addWindowType;
  11362. \t\t\t\t\t\t\t\twindow.removeWindowType = removeWindowType;
  11363. \t\t\t\t\t\t\t\t// 隠し radio(opacity:0/pointer-events:none) を label で包む opt-btn は iOS で初回タップの
  11364. \t\t\t\t\t\t\t\t// change が不発になりやすい。窓タイプ/住宅区分は label に onclick が無く change 依存だった
  11365. \t\t\t\t\t\t\t\t// ため「2回タッチ/選択できない」が発生。click は確実に発火するので委譲 click で選択状態・
  11366. \t\t\t\t\t\t\t\t// is-selected・再計算を行う(JSで複製される窓タイプにも委譲で対応)。
  11367. \t\t\t\t\t\t\t\tdocument.addEventListener('click', function(ev) {
  11368. \t\t\t\t\t\t\t\t\tif (!ev.target || !ev.target.closest) return;
  11369. \t\t\t\t\t\t\t\t\tvar label = ev.target.closest('.opt-btn');
  11370. \t\t\t\t\t\t\t\t\tif (!label) return;
  11371. \t\t\t\t\t\t\t\t\tif (!label.closest('#window-types-container') && !label.closest('#window-housing-type-group')) return;
  11372. \t\t\t\t\t\t\t\t\tvar input = label.querySelector('input[type=\"radio\"]');
  11373. \t\t\t\t\t\t\t\t\tif (!input || input.disabled) return;
  11374. \t\t\t\t\t\t\t\t\tinput.checked = true;
  11375. \t\t\t\t\t\t\t\t\tvar nm = input.getAttribute('name');
  11376. \t\t\t\t\t\t\t\t\tif (nm) {
  11377. \t\t\t\t\t\t\t\t\t\tdocument.querySelectorAll('input[name=\"' + nm + '\"]').forEach(function(i) {
  11378. \t\t\t\t\t\t\t\t\t\t\tvar l = i.closest('.opt-btn');
  11379. \t\t\t\t\t\t\t\t\t\t\tif (l) l.classList.toggle('is-selected', i.checked);
  11380. \t\t\t\t\t\t\t\t\t\t});
  11381. \t\t\t\t\t\t\t\t\t}
  11382. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  11383. \t\t\t\t\t\t\t\t});
  11384. \t\t\t\t\t\t\t\t// 初期表示で 1 ブロック追加 + 住宅区分ラジオの change で再計算.
  11385. \t\t\t\t\t\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
  11386. \t\t\t\t\t\t\t\t\tif (document.querySelector('#window-types-container')) {
  11387. \t\t\t\t\t\t\t\t\t\taddWindowType();
  11388. \t\t\t\t\t\t\t\t\t}
  11389. \t\t\t\t\t\t\t\t\tvar housingInputs = document.querySelectorAll('input[name=\"window_housing_type\"]');
  11390. \t\t\t\t\t\t\t\t\tvar syncHousingSelectedClass = function() {
  11391. \t\t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  11392. \t\t\t\t\t\t\t\t\t\t\tvar lbl = el.closest('.opt-btn');
  11393. \t\t\t\t\t\t\t\t\t\t\tif (!lbl) return;
  11394. \t\t\t\t\t\t\t\t\t\t\tif (el.checked) lbl.classList.add('is-selected');
  11395. \t\t\t\t\t\t\t\t\t\t\telse            lbl.classList.remove('is-selected');
  11396. \t\t\t\t\t\t\t\t\t\t});
  11397. \t\t\t\t\t\t\t\t\t};
  11398. \t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  11399. \t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  11400. \t\t\t\t\t\t\t\t\t\tel.addEventListener('change', function() {
  11401. \t\t\t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  11402. \t\t\t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  11403. \t\t\t\t\t\t\t\t\t\t});
  11404. \t\t\t\t\t\t\t\t\t});
  11405. \t\t\t\t\t\t\t\t});
  11406. \t\t\t\t\t\t\t})();
  11407. \t\t\t\t\t\t\t</script>
  11408. \t\t\t\t\t\t{% endif %}
  11409. \t\t\t\t\t\t<!-- 3: 施工見積(物置・ゴミステーション) -->
  11410. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 3 %}
  11411. \t\t\t\t\t\t\t{# 幅・奥行き・高さ(p_w/p_d/p_h からボタン型ラジオ生成) #}
  11412. \t\t\t\t\t\t\t{% if p_w and p_w|length and p_w|join != \"\" %}
  11413. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11414. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  11415. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11416. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11417. \t\t\t\t\t\t\t    {% for pw_val in p_w %}{% if pw_val %}{% set idx = idx + 1 %}
  11418. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %} is-selected{% endif %}\"
  11419. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw3_{{ idx }}');\">
  11420. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw3_{{ idx }}\" value=\"{{ pw_val }}\"
  11421. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %}checked{% endif %}>
  11422. \t\t\t\t\t\t\t        {{ pw_val }}
  11423. \t\t\t\t\t\t\t      </label>
  11424. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11425. \t\t\t\t\t\t\t  </div>
  11426. \t\t\t\t\t\t\t</div>
  11427. \t\t\t\t\t\t\t{% endif %}
  11428. \t\t\t\t\t\t\t{% if p_d and p_d|length and p_d|join != \"\" %}
  11429. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11430. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">奥行き{% if mitsumori_json and mitsumori_json.pd %}: <span>{{ mitsumori_json.pd }}</span>{% endif %}</div>
  11431. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11432. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11433. \t\t\t\t\t\t\t    {% for pd_val in p_d %}{% if pd_val %}{% set idx = idx + 1 %}
  11434. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pd == pd_val) or p_d|length == 1 %} is-selected{% endif %}\"
  11435. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pd','pd3_{{ idx }}');\">
  11436. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pd\" id=\"pd3_{{ idx }}\" value=\"{{ pd_val }}\"
  11437. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pd == pd_val) or p_d|length == 1 %}checked{% endif %}>
  11438. \t\t\t\t\t\t\t        {{ pd_val }}
  11439. \t\t\t\t\t\t\t      </label>
  11440. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11441. \t\t\t\t\t\t\t  </div>
  11442. \t\t\t\t\t\t\t</div>
  11443. \t\t\t\t\t\t\t{% endif %}
  11444. \t\t\t\t\t\t\t{% if p_h and p_h|length and p_h|join != \"\" %}
  11445. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11446. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">高さ{% if mitsumori_json and mitsumori_json.ph %}: <span>{{ mitsumori_json.ph }}</span>{% endif %}</div>
  11447. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11448. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11449. \t\t\t\t\t\t\t    {% for ph_val in p_h %}{% if ph_val %}{% set idx = idx + 1 %}
  11450. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.ph == ph_val) or p_h|length == 1 %} is-selected{% endif %}\"
  11451. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('ph','ph3_{{ idx }}');\">
  11452. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"ph\" id=\"ph3_{{ idx }}\" value=\"{{ ph_val }}\"
  11453. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.ph == ph_val) or p_h|length == 1 %}checked{% endif %}>
  11454. \t\t\t\t\t\t\t        {{ ph_val }}
  11455. \t\t\t\t\t\t\t      </label>
  11456. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11457. \t\t\t\t\t\t\t  </div>
  11458. \t\t\t\t\t\t\t</div>
  11459. \t\t\t\t\t\t\t{% endif %}
  11460. \t\t\t\t\t\t\t{# 棚タイプ(p_m データから選択肢を生成) #}
  11461. \t\t\t\t\t\t\t{% if p_m and p_m|length and p_m|join != \"\" %}
  11462. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11463. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">棚タイプ <small class=\"text-muted\">(間仕切り仕様)</small>{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  11464. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11465. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11466. \t\t\t\t\t\t\t    {% for pm_val in p_m %}{% if pm_val %}{% set idx = idx + 1 %}
  11467. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %} is-selected{% endif %}\"
  11468. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm3_{{ idx }}');\">
  11469. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm3_{{ idx }}\" value=\"{{ pm_val }}\"
  11470. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %}checked{% endif %}>
  11471. \t\t\t\t\t\t\t        {{ pm_val }}
  11472. \t\t\t\t\t\t\t      </label>
  11473. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11474. \t\t\t\t\t\t\t  </div>
  11475. \t\t\t\t\t\t\t</div>
  11476. \t\t\t\t\t\t\t{% endif %}
  11477. \t\t\t\t\t\t\t{# option1 (mo の 棚タイプ 等、p_option1 データから選択肢を生成) #}
  11478. \t\t\t\t\t\t\t{% if p_option1 and p_option1|length and p_option1|join != \"\" %}
  11479. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11480. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">{{ option1_label }}{% if mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 %}: <span>{{ mitsumori_json.option1 }}</span>{% endif %}</div>
  11481. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11482. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11483. \t\t\t\t\t\t\t    {% for opt1_val in p_option1 %}{% if opt1_val %}{% set idx = idx + 1 %}
  11484. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1_val) or p_option1|length == 1 %} is-selected{% endif %}\"
  11485. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('option1','option1_3_{{ idx }}');\">
  11486. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"option1\" id=\"option1_3_{{ idx }}\" value=\"{{ opt1_val }}\"
  11487. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1_val) or p_option1|length == 1 %}checked{% endif %}>
  11488. \t\t\t\t\t\t\t        {{ opt1_val }}
  11489. \t\t\t\t\t\t\t      </label>
  11490. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11491. \t\t\t\t\t\t\t  </div>
  11492. \t\t\t\t\t\t\t</div>
  11493. \t\t\t\t\t\t\t{% endif %}
  11494. \t\t\t\t\t\t\t{# カラー(共通の color データ使用) #}
  11495. \t\t\t\t\t\t\t{% if color and color|length %}
  11496. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11497. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">カラー{% if mitsumori_json and mitsumori_json.pc %}: <span>{{ mitsumori_json.pc }}</span>{% endif %}</div>
  11498. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11499. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11500. \t\t\t\t\t\t\t    {% for cc in color %}{% if cc and cc['name'] %}{% set idx = idx + 1 %}
  11501. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %} is-selected{% endif %}\"
  11502. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pc','cc3_{{ idx }}');\">
  11503. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"color3\" id=\"cc3_{{ idx }}\" value=\"{{ cc['name'] }}\"
  11504. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %}checked{% endif %}>
  11505. \t\t\t\t\t\t\t        {{ cc['name'] }}
  11506. \t\t\t\t\t\t\t      </label>
  11507. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11508. \t\t\t\t\t\t\t  </div>
  11509. \t\t\t\t\t\t\t</div>
  11510. \t\t\t\t\t\t\t{% endif %}
  11511. \t\t\t\t\t\t\t{# 台数 #}
  11512. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11513. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">台数</label>
  11514. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11515. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  11516. \t\t\t\t\t\t\t      <input type=\"number\" name=\"daisu\" id=\"daisu\" class=\"form-control\" value=\"{{ mitsumori_json.daisu|default('1') }}\" min=\"1\" max=\"10\" onchange=\"mitsumori_simulation('daisu','daisu');\">
  11517. \t\t\t\t\t\t\t      <span class=\"input-group-text\">台</span>
  11518. \t\t\t\t\t\t\t    </div>
  11519. \t\t\t\t\t\t\t  </div>
  11520. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11521. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"daisu(+1);\">+</button>
  11522. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"daisu(-1);\">ー</button>
  11523. \t\t\t\t\t\t\t  </div>
  11524. \t\t\t\t\t\t\t</div>
  11525. \t\t\t\t\t\t{% endif %}
  11526. \t\t\t\t\t\t<!-- 4: 施工見積(フェンス・組み立て式) -->
  11527. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 4 %}
  11528. \t\t\t\t\t\t\t{# 枚数 #}
  11529. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11530. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">枚数</label>
  11531. \t\t\t\t\t\t\t  <div class=\"col-4 mb-3\">
  11532. \t\t\t\t\t\t\t    <div class=\"input-group\">
  11533. \t\t\t\t\t\t\t      <input type=\"number\" name=\"maisu\" id=\"maisu\" class=\"form-control\" value=\"{{ mitsumori_json.maisu|default('3') }}\" min=\"3\" max=\"20\" onchange=\"if(parseInt(this.value)<3)this.value=3; mitsumori_simulation('maisu','maisu');\">
  11534. \t\t\t\t\t\t\t      <span class=\"input-group-text\">枚</span>
  11535. \t\t\t\t\t\t\t    </div>
  11536. \t\t\t\t\t\t\t  </div>
  11537. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11538. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"maisu(+1);\">+</button>
  11539. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"maisu(-1);\">ー</button>
  11540. \t\t\t\t\t\t\t  </div>
  11541. \t\t\t\t\t\t\t</div>
  11542. \t\t\t\t\t\t{% endif %}
  11543. \t\t\t\t\t\t<!-- 5: 施工見積(ウッドデッキ・タイルデッキ) -->
  11544. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 5 %}
  11545. \t\t\t\t\t\t\t{# ステップの有無 #}
  11546. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11547. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">ステップ</div>
  11548. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11549. \t\t\t\t\t\t\t    {% set step_yes_checked = (mitsumori_json and mitsumori_json.deck_step is defined and mitsumori_json.deck_step == '必要') %}
  11550. \t\t\t\t\t\t\t    {% set step_no_checked = (not mitsumori_json or mitsumori_json.deck_step is not defined or mitsumori_json.deck_step == '不要' or not mitsumori_json.deck_step) %}
  11551. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if step_yes_checked %} is-selected{% endif %}\"
  11552. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_yes');\">
  11553. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_yes\" value=\"必要\"
  11554. \t\t\t\t\t\t\t             {% if step_yes_checked %}checked{% endif %}>
  11555. \t\t\t\t\t\t\t      必要
  11556. \t\t\t\t\t\t\t    </label>
  11557. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if step_no_checked %} is-selected{% endif %}\"
  11558. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_no');\">
  11559. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_no\" value=\"不要\"
  11560. \t\t\t\t\t\t\t             {% if step_no_checked %}checked{% endif %}>
  11561. \t\t\t\t\t\t\t      不要
  11562. \t\t\t\t\t\t\t    </label>
  11563. \t\t\t\t\t\t\t  </div>
  11564. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-step\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not step_yes_checked %}display:none;{% endif %}\">
  11565. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  11566. \t\t\t\t\t\t\t  </div>
  11567. \t\t\t\t\t\t\t</div>
  11568. \t\t\t\t\t\t\t{# ウッドデッキフェンスの有無 #}
  11569. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11570. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">デッキフェンス</div>
  11571. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11572. \t\t\t\t\t\t\t    {% set fence_yes_checked = (mitsumori_json and mitsumori_json.deck_fence is defined and mitsumori_json.deck_fence == '必要') %}
  11573. \t\t\t\t\t\t\t    {% set fence_no_checked = (not mitsumori_json or mitsumori_json.deck_fence is not defined or mitsumori_json.deck_fence == '不要' or not mitsumori_json.deck_fence) %}
  11574. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if fence_yes_checked %} is-selected{% endif %}\"
  11575. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_yes');\">
  11576. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_yes\" value=\"必要\"
  11577. \t\t\t\t\t\t\t             {% if fence_yes_checked %}checked{% endif %}>
  11578. \t\t\t\t\t\t\t      必要
  11579. \t\t\t\t\t\t\t    </label>
  11580. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if fence_no_checked %} is-selected{% endif %}\"
  11581. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_no');\">
  11582. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_no\" value=\"不要\"
  11583. \t\t\t\t\t\t\t             {% if fence_no_checked %}checked{% endif %}>
  11584. \t\t\t\t\t\t\t      不要
  11585. \t\t\t\t\t\t\t    </label>
  11586. \t\t\t\t\t\t\t  </div>
  11587. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-fence\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not fence_yes_checked %}display:none;{% endif %}\">
  11588. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  11589. \t\t\t\t\t\t\t  </div>
  11590. \t\t\t\t\t\t\t</div>
  11591. \t\t\t\t\t\t{% endif %}
  11592. \t\t\t\t\t\t<!-- 6: 施工見積(芝生・枚数・数量買い) -->
  11593. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 6 %}
  11594. \t\t\t\t\t\t\t{# 規格(p_m データ → 素材から抽出) #}
  11595. \t\t\t\t\t\t\t{% if p_m and p_m|length and p_m|join != \"\" %}
  11596. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11597. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">規格{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  11598. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11599. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11600. \t\t\t\t\t\t\t    {% for pm_val in p_m %}{% if pm_val %}{% set idx = idx + 1 %}
  11601. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %} is-selected{% endif %}\"
  11602. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm6_{{ idx }}');\">
  11603. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm6_{{ idx }}\" value=\"{{ pm_val }}\"
  11604. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %}checked{% endif %}>
  11605. \t\t\t\t\t\t\t        {{ pm_val }}
  11606. \t\t\t\t\t\t\t      </label>
  11607. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11608. \t\t\t\t\t\t\t  </div>
  11609. \t\t\t\t\t\t\t</div>
  11610. \t\t\t\t\t\t\t{% endif %}
  11611. \t\t\t\t\t\t\t{# 芝の幅(p_w = ロール幅。free_area の w。例 100cm/200cm = 1m/2m 幅。
  11612. \t\t\t\t\t\t\t   h はロール長(例 1000cm=10m)で固定のため UI には出さない)。 #}
  11613. \t\t\t\t\t\t\t{% if p_w and p_w|length and p_w|join != \"\" %}
  11614. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11615. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">芝の幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  11616. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11617. \t\t\t\t\t\t\t    {% set idx = 0 %}
  11618. \t\t\t\t\t\t\t    {% for pw_val in p_w %}{% if pw_val %}{% set idx = idx + 1 %}
  11619. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %} is-selected{% endif %}\"
  11620. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw6_{{ idx }}');\">
  11621. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw6_{{ idx }}\" value=\"{{ pw_val }}\"
  11622. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %}checked{% endif %}>
  11623. \t\t\t\t\t\t\t        {{ pw_val }}
  11624. \t\t\t\t\t\t\t      </label>
  11625. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  11626. \t\t\t\t\t\t\t  </div>
  11627. \t\t\t\t\t\t\t</div>
  11628. \t\t\t\t\t\t\t{% endif %}
  11629. \t\t\t\t\t\t\t{# 1ロールの長さ表記(顧客要望 #10)。h はロール長 (例 1000cm=10m) で固定のため選択ではなく表示のみ。 #}
  11630. \t\t\t\t\t\t\t{% set _roll_h = (p_h is defined and p_h|length) ? (p_h|first) : '' %}
  11631. \t\t\t\t\t\t\t{% if _roll_h %}
  11632. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11633. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">1ロールの長さ:<span style=\"font-weight:bold;\">{% if 'cm' in _roll_h %}{{ (_roll_h|replace({'cm':'', ',':''})|trim) / 100 }}m{% else %}{{ _roll_h }}{% endif %}</span></div>
  11634. \t\t\t\t\t\t\t</div>
  11635. \t\t\t\t\t\t\t{% endif %}
  11636. \t\t\t\t\t\t\t{# 施工サイズ(縦 × 横、m 入力)→ 必要枚数を自動算出して表示.
  11637. \t\t\t\t\t\t\t   面積=縦×横 を #area に流し込み、case 6 の qty=ceil(area/ロール面積) を流用. #}
  11638. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11639. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">施工サイズ</label>
  11640. \t\t\t\t\t\t\t  <div class=\"col-8\">
  11641. \t\t\t\t\t\t\t    <div class=\"input-group\">
  11642. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_len\" id=\"tf_len\"
  11643. \t\t\t\t\t\t\t        class=\"form-control\"
  11644. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_len|default('') }}\"
  11645. \t\t\t\t\t\t\t        placeholder=\"縦\" min=\"0.1\" step=\"0.1\"
  11646. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_len','tf_len');\">
  11647. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m&nbsp;×</span>
  11648. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_wid\" id=\"tf_wid\"
  11649. \t\t\t\t\t\t\t        class=\"form-control\"
  11650. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_wid|default('') }}\"
  11651. \t\t\t\t\t\t\t        placeholder=\"横\" min=\"0.1\" step=\"0.1\"
  11652. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_wid','tf_wid');\">
  11653. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m</span>
  11654. \t\t\t\t\t\t\t    </div>
  11655. \t\t\t\t\t\t\t    {# area は内部計算用に保持(縦×横を JS で書き込む) #}
  11656. \t\t\t\t\t\t\t    <input type=\"hidden\" name=\"area\" id=\"area\" value=\"{{ mitsumori_json.area|default('') }}\">
  11657. \t\t\t\t\t\t\t    {# 必要枚数は直接入力も可能。施工サイズ入力時は自動算出して上書きする。
  11658. \t\t\t\t\t\t\t       施工サイズ未入力でも、ここで枚数だけ指定してカートに入れられる。 #}
  11659. \t\t\t\t\t\t\t    <div style=\"margin-top:10px;display:inline-block;background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:8px 14px;font-size:16px;color:#c00;font-weight:bold;\">
  11660. \t\t\t\t\t\t\t      必要枚数:<input type=\"number\" name=\"tf_qty\" id=\"tf_qty\"
  11661. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_qty|default('1') }}\" min=\"1\" step=\"1\"
  11662. \t\t\t\t\t\t\t        style=\"width:80px;font-size:22px;font-weight:bold;color:#c00;text-align:right;border:1px solid #ffe69c;border-radius:4px;padding:2px 6px;\"
  11663. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_qty','tf_qty');\"> 枚
  11664. \t\t\t\t\t\t\t    </div>
  11665. \t\t\t\t\t\t\t    <div style=\"margin-top:6px;font-size:12px;color:#666;\">※ 施工サイズを入力すると必要枚数を自動計算します。サイズが分からない場合は枚数を直接ご指定ください。</div>
  11666. \t\t\t\t\t\t\t  </div>
  11667. \t\t\t\t\t\t\t</div>
  11668. \t\t\t\t\t\t{% endif %}
  11669. \t\t\t\t\t\t<!-- 7: 施工見積(数量買い・基本工事費固定) -->
  11670. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 7 %}
  11671. \t\t\t\t\t\t\t{# 個数(物置の daisu と同形式、単位は「個」) #}
  11672. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11673. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">個数</label>
  11674. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11675. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  11676. \t\t\t\t\t\t\t      <input type=\"number\" name=\"suuryou\" id=\"suuryou\" class=\"form-control\"
  11677. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.suuryou|default('1') }}\" min=\"1\" max=\"100\"
  11678. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('suuryou','suuryou');\">
  11679. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  11680. \t\t\t\t\t\t\t    </div>
  11681. \t\t\t\t\t\t\t  </div>
  11682. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11683. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"suuryou(+1);\">+</button>
  11684. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"suuryou(-1);\">ー</button>
  11685. \t\t\t\t\t\t\t  </div>
  11686. \t\t\t\t\t\t\t</div>
  11687. \t\t\t\t\t\t{% endif %}
  11688. \t\t\t\t\t\t<!-- 9: 商品のみ購入 -->
  11689. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 9 %}
  11690. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11691. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">数量</label>
  11692. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11693. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  11694. \t\t\t\t\t\t\t      <input type=\"number\" name=\"quantity_only\" id=\"quantity_only\" class=\"form-control\" value=\"1\" min=\"1\" onchange=\"\$('#quantity').val(this.value);\">
  11695. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  11696. \t\t\t\t\t\t\t    </div>
  11697. \t\t\t\t\t\t\t  </div>
  11698. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11699. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"quantityOnly(+1);\">+</button>
  11700. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"quantityOnly(-1);\">ー</button>
  11701. \t\t\t\t\t\t\t  </div>
  11702. \t\t\t\t\t\t\t</div>
  11703. \t\t\t\t\t\t{% endif %}
  11704. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">取り付け工事のご希望に関してお答えください。</label></div>
  11705. \t\t\t\t\t\t{# gs (ゴミステーション, category id=27) では「撤去対応」「残土・ガラ処理」は ex-shop に存在しないため非表示
  11706. \t\t\t\t\t\t   cg (カーゲート, category id=9) では「残土・ガラ処理」分は撤去金額側に内包済みのため非表示
  11707. \t\t\t\t\t\t   (撤去オプション自体は残す) #}
  11708. \t\t\t\t\t\t{% set is_gs = false %}
  11709. \t\t\t\t\t\t{% set is_cg = false %}
  11710. \t\t\t\t\t\t{% if Product.ProductCategories is not empty %}
  11711. \t\t\t\t\t\t\t{% for ProductCategory in Product.ProductCategories %}
  11712. \t\t\t\t\t\t\t\t{% if ProductCategory.category_id == 27 %}{% set is_gs = true %}{% endif %}
  11713. \t\t\t\t\t\t\t\t{% if ProductCategory.category_id == 9 %}{% set is_cg = true %}{% endif %}
  11714. \t\t\t\t\t\t\t{% endfor %}
  11715. \t\t\t\t\t\t{% endif %}
  11716. \t\t\t\t\t\t{% for i in 0..10 %}
  11717. \t\t\t\t\t\t\t{% if op and op|length >= i+1 %}
  11718. \t\t\t\t\t\t\t{% if op[i]['name'] %}
  11719. \t\t\t\t\t\t\t{% set hide_opt = false %}
  11720. \t\t\t\t\t\t\t{% if is_gs and (op[i]['name'] matches '/撤去/' or op[i]['name'] matches '/残土/') %}
  11721. \t\t\t\t\t\t\t\t{% set hide_opt = true %}
  11722. \t\t\t\t\t\t\t{% endif %}
  11723. \t\t\t\t\t\t\t{% if is_cg and op[i]['name'] matches '/残土/' %}
  11724. \t\t\t\t\t\t\t\t{% set hide_opt = true %}
  11725. \t\t\t\t\t\t\t{% endif %}
  11726. \t\t\t\t\t\t\t{% if not hide_opt %}
  11727. \t\t\t\t\t\t\t{# price=0 で「解体」「撤去」「設置場所」(wd 等で API 差額未提供) を含むオプションは
  11728. \t\t\t\t\t\t\t   選択時に「現場調査後に正式お見積もり」文言を出す. #}
  11729. \t\t\t\t\t\t\t{% set is_removal_unknown = (op[i]['price']|default(0) == 0 or op[i]['price']|default('0') == '0')
  11730. \t\t\t\t\t\t\t                              and (op[i]['name'] matches '/解体/' or op[i]['name'] matches '/撤去/' or op[i]['name'] matches '/設置場所/') %}
  11731. \t\t\t\t\t\t\t{# tf (人工芝, sale_type=6): ex-shop に施工価格がないため「取り付け工事も希望する」選択時に現地調査文言を表示 #}
  11732. \t\t\t\t\t\t\t{% set is_tf_kouji = (ProductClass.SaleType.id == 6 and op[i]['name'] matches '/取り付け工事/') %}
  11733. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" data-op-idx=\"{{ i }}\" data-op-name=\"{{ op[i]['name']|e('html_attr') }}\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11734. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">{{ op[i]['name'] }}{% if mitsumori_json and mitsumori_json.op[i] %}: <span>{{ mitsumori_json.op[i] }}</span>{% endif %}</div>
  11735. \t\t\t\t\t\t\t  {% if op[i]['comment'] %}<div class=\"opt-comment\" style=\"font-size:12px;color:#666;margin:4px 0 6px;\">{{ op[i]['comment'] }}</div>{% endif %}
  11736. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11737. \t\t\t\t\t\t\t    {# off が空 (= ex-shop に選択肢が 1 つしかない基礎施工等) のときは on 側を
  11738. \t\t\t\t\t\t\t       既定選択にして 2 個目の空ラジオを描画しない. #}
  11739. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) or not op[i]['off'] %} is-selected{% endif %}\"
  11740. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op{{ i }}','op{{ i }}_1');\">
  11741. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op{{ i }}\" id=\"op{{ i }}_1\" value=\"{{ op[i]['on'] }}\" {% if (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) or not op[i]['off'] %}checked{% endif %}>
  11742. \t\t\t\t\t\t\t      {{ op[i]['on'] }}
  11743. \t\t\t\t\t\t\t    </label>
  11744. \t\t\t\t\t\t\t    {% if op[i]['off'] %}
  11745. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if mitsumori_json and mitsumori_json.op[i] == op[i]['off'] %} is-selected{% endif %}\"
  11746. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op{{ i }}','op{{ i }}_2');\">
  11747. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op{{ i }}\" id=\"op{{ i }}_2\" value=\"{{ op[i]['off'] }}\" {% if mitsumori_json and mitsumori_json.op[i] == op[i]['off'] %}checked{% endif %}>
  11748. \t\t\t\t\t\t\t      {{ op[i]['off'] }}
  11749. \t\t\t\t\t\t\t    </label>
  11750. \t\t\t\t\t\t\t    {% endif %}
  11751. \t\t\t\t\t\t\t  </div>
  11752. \t\t\t\t\t\t\t  {% if is_removal_unknown or is_tf_kouji %}
  11753. \t\t\t\t\t\t\t  <div class=\"opt-survey-note\" data-op-idx=\"{{ i }}\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) %}display:none;{% endif %}\">
  11754. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  11755. \t\t\t\t\t\t\t  </div>
  11756. \t\t\t\t\t\t\t  {% endif %}
  11757. \t\t\t\t\t\t\t</div>
  11758. \t\t\t\t\t\t\t{% endif %}
  11759. \t\t\t\t\t\t\t{% endif %}
  11760. \t\t\t\t\t\t\t{% endif %}
  11761. \t\t\t\t\t\t{% endfor %}
  11762. \t\t\t\t\t\t{# fe (sale_type=4) ブロックの種類×段数 サブ UI コンテナ.
  11763. \t\t\t\t\t\t   親オプション「ご希望のフェンス設置方法」 = 「新規にブロック積みを行う」
  11764. \t\t\t\t\t\t   を選択したときだけ JS (renderFeBlockRadios) で表示される. #}
  11765. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 4 and oi and oi.fe_block %}
  11766. \t\t\t\t\t\t<div id=\"fe-block-options\" class=\"form-group mt-3 pb-3\" style=\"display:none;border-bottom:1px solid rgba(0,0,0,.125)\"></div>
  11767. \t\t\t\t\t\t{% endif %}
  11768. \t\t\t\t\t\t{# tg カテゴリ用: block 別オプション差額ラジオ (W/D 確定後に JS が動的描画).
  11769. \t\t\t\t\t\t   他オプションと同じ列(card-body 内・カートボタンより前)に表示する. #}
  11770. \t\t\t\t\t\t<div id=\"tg-options\" class=\"tg-options-container col-12\"></div>
  11771. \t\t\t\t\t  </div>
  11772. \t\t\t\t\t  <!-- /.card-body -->
  11773. \t\t\t\t\t</div>
  11774.                     <form action=\"{{ url('product_add_cart', {id:Product.id}) }}\" method=\"post\" id=\"form1\" name=\"form1\">
  11775.                         {% if Product.stock_find %}
  11776.                             <div class=\"ec-productRole__actions\">
  11777.                                 {% if form.classcategory_id1 is defined %}
  11778.                                     <div class=\"ec-select\">
  11779.                                         {{ form_row(form.classcategory_id1) }}
  11780.                                         {{ form_errors(form.classcategory_id1) }}
  11781.                                     </div>
  11782.                                     {% if form.classcategory_id2 is defined %}
  11783.                                         <div class=\"ec-select\">
  11784.                                             {{ form_row(form.classcategory_id2) }}
  11785.                                             {{ form_errors(form.classcategory_id2) }}
  11786.                                         </div>
  11787.                                     {% endif %}
  11788.                                 {% endif %}
  11789.                                 <div class=\"ec-numberInput\">
  11790.                                     {{ form_widget(form.quantity, { type: 'hidden' }) }}
  11791.                                     {{ form_errors(form.quantity) }}
  11792.                                 </div>
  11793.                             </div>
  11794.                         {% else %}
  11795.                             <div class=\"ec-productRole__btn\">
  11796.                                 <button type=\"button\" class=\"ec-blockBtn--action\" disabled=\"disabled\">
  11797.                                     {{ 'ただいま品切れ中です。'|trans }}
  11798.                                 </button>
  11799.                             </div>
  11800.                         {% endif %}
  11801.                         <div class=\"ec-productRole__btn mt-3\">
  11802.                            <button type=\"submit\" id=\"cart_btn\" class=\"ec-blockBtn--action add-cart\">カートに入れる</button>
  11803.                         </div>
  11804.                         {{ form_rest(form) }}
  11805.                     </form>
  11806.                     <div class=\"ec-modal add-cart-modal\">
  11807.                         <div class=\"ec-modal-overlay\">
  11808.                             <div class=\"ec-modal-wrap add-cart-modal__wrap\">
  11809.                                 <span class=\"ec-modal-close\"><span class=\"ec-icon\"><img src=\"{{ asset('assets/icon/cross-dark.svg') }}\" alt=\"\"/></span></span>
  11810.                                 <div id=\"ec-modal-header\" class=\"text-center add-cart-modal__header\">{{ 'カートに追加しました。'|trans }}</div>
  11811.                                 <div class=\"ec-modal-box add-cart-modal__box\">
  11812.                                     <div class=\"ec-role add-cart-modal__actions\">
  11813.                                         <a href=\"{{ url('cart') }}\" class=\"ec-inlineBtn--action add-cart-modal__primary\">{{ 'カートに進む'|trans }}</a>
  11814.                                         <span class=\"ec-inlineBtn--cancel add-cart-modal__secondary\">{{ '商品検索を続ける'|trans }}</span>
  11815.                                     </div>
  11816.                                 </div>
  11817.                             </div>
  11818.                         </div>
  11819.                     </div>
  11820.                     <div class=\"ec-productRole__description\">{{ Product.description_detail|raw|nl2br }}
  11821.                     </div>
  11822.                     {# SNSシェア #}
  11823.                     <div class=\"ec-productRole__share\">
  11824.                         <ul class=\"ec-share\">
  11825.                             <li class=\"ec-share__item\">
  11826.                                 <a href=\"https://twitter.com/share?url={{ app.request.uri|url_encode }}&text={{ Product.name|url_encode }}\" class=\"ec-share__link ec-share__link--twitter\" target=\"_blank\" rel=\"noreferrer noopener\">
  11827.                                     <i class=\"fab fa-twitter\"></i>
  11828.                                 </a>
  11829.                             </li>
  11830.                             <li class=\"ec-share__item\">
  11831.                                 <a href=\"https://www.facebook.com/sharer/sharer.php?u={{ app.request.uri|url_encode }}\" class=\"ec-share__link ec-share__link--facebook\" target=\"_blank\" rel=\"noreferrer noopener\">
  11832.                                     <i class=\"fab fa-facebook-f\"></i>
  11833.                                 </a>
  11834.                             </li>
  11835.                             <li class=\"ec-share__item\">
  11836.                                 <a href=\"https://social-plugins.line.me/lineit/share?url={{ app.request.uri|url_encode }}\" class=\"ec-share__link ec-share__link--line\" target=\"_blank\" rel=\"noreferrer noopener\">
  11837.                                     <i class=\"fab fa-line\"></i>
  11838.                                 </a>
  11839.                             </li>
  11840.                         </ul>
  11841.                     </div>
  11842.                 </div>
  11843. \t\t\t\t{# ===== スマホ用 見積金額 下部固定バー ===== #}
  11844. \t\t\t\t<div id=\"sp-mitsumori-bar\">
  11845. \t\t\t\t    <div class=\"sp-bar__pricewrap\">
  11846. \t\t\t\t        <div class=\"sp-bar__label\">合計(工事費・税抜)</div>
  11847. \t\t\t\t        <div class=\"sp-bar__price\" id=\"sp-mitsumori-price\">---円</div>
  11848. \t\t\t\t    </div>
  11849. \t\t\t\t    <button type=\"button\" class=\"sp-bar__detail-btn\"
  11850. \t\t\t\t            onclick=\"openSpMitsumoriDetail();\" title=\"お見積りの詳細(内訳)を表示\">
  11851. \t\t\t\t        <i class=\"far fa-file-alt\"></i>
  11852. \t\t\t\t        <span>詳細</span>
  11853. \t\t\t\t    </button>
  11854. \t\t\t\t    <button type=\"button\" class=\"sp-bar__btn\"
  11855. \t\t\t\t            onclick=\"document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">
  11856. \t\t\t\t        <i class=\"fas fa-shopping-cart\"></i>
  11857. \t\t\t\t        <span class=\"sp-bar__btn-label\">カートへ</span>
  11858. \t\t\t\t        {% set spTotalQty = get_carts_total_quantity() %}
  11859. \t\t\t\t        {% if spTotalQty > 0 %}
  11860. \t\t\t\t            <span class=\"sp-bar__cart-badge\">{{ spTotalQty|number_format }}</span>
  11861. \t\t\t\t        {% endif %}
  11862. \t\t\t\t    </button>
  11863. \t\t\t\t    <a href=\"{{ url('homepage') }}\" class=\"sp-bar__home-btn\" title=\"トップページへ\">
  11864. \t\t\t\t        <i class=\"fas fa-home\"></i>
  11865. \t\t\t\t    </a>
  11866. \t\t\t\t</div>
  11867. \t\t\t\t{# ===== スマホ用 お見積りの詳細 ボトムシート ===== #}
  11868. \t\t\t\t{# タップ時に現在の内訳カード(.mitsumori-card-pc)の中身を複製して表示する。
  11869. \t\t\t\t   価格計算には触れず、ライブ同期済みの表示値をそのまま見せる方式。 #}
  11870. \t\t\t\t<div id=\"sp-mitsumori-detail\" class=\"sp-detail-sheet\" aria-hidden=\"true\">
  11871. \t\t\t\t    <div class=\"sp-detail-sheet__overlay\" onclick=\"closeSpMitsumoriDetail();\"></div>
  11872. \t\t\t\t    <div class=\"sp-detail-sheet__panel\" role=\"dialog\" aria-label=\"お見積りの詳細\">
  11873. \t\t\t\t        <div class=\"sp-detail-sheet__header\">
  11874. \t\t\t\t            <span class=\"sp-detail-sheet__title\">お見積りの詳細</span>
  11875. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__close\" onclick=\"closeSpMitsumoriDetail();\" aria-label=\"閉じる\">&times;</button>
  11876. \t\t\t\t        </div>
  11877. \t\t\t\t        <div class=\"sp-detail-sheet__body\" id=\"sp-detail-body\"></div>
  11878. \t\t\t\t        <div class=\"sp-detail-sheet__footer\">
  11879. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__invoice\"
  11880. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('mitsumori_btn') && document.getElementById('mitsumori_btn').click();\">見積書を表示</button>
  11881. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__cart\"
  11882. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">カートに入れる</button>
  11883. \t\t\t\t        </div>
  11884. \t\t\t\t    </div>
  11885. \t\t\t\t</div>
  11886. \t\t\t\t<div class=\"card col-12 collapsed-card sticky-top float-right mitsumori-card-pc\">
  11887. \t\t\t\t\t<div class=\"card-header\">
  11888. \t\t\t\t\t  <h3 class=\"card-title\">現在のお見積り額</h3>
  11889. \t\t\t\t\t  <div class=\"card-tools\">
  11890. \t\t\t\t\t    <span class=\"float-left\" id=\"mitsumori_message\">{{ mitsumori_json.mitsumori_goukei|default('---円') }}</span>
  11891. \t\t\t\t\t    <button type=\"button\" class=\"btn btn-tool btn-mitsumori-toggle\" data-card-widget=\"collapse\" title=\"詳細を表示\">
  11892. \t\t\t\t\t      <span class=\"toggle-icon\">▼ 詳細</span>
  11893. \t\t\t\t\t    </button>
  11894. \t\t\t\t\t  </div>
  11895. \t\t\t\t\t</div>
  11896. \t\t\t\t\t<div class=\"card-body p-0\">
  11897. \t\t\t\t\t  <ul class=\"nav nav-pills flex-column\">
  11898. \t\t\t\t\t    <li class=\"nav-item active\">
  11899. \t\t\t\t\t      <a class=\"nav-link\">
  11900. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 合計(工事費・税抜)
  11901. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_goukei\">{{ mitsumori_json.mitsumori_goukei|default('---円') }}</span>
  11902. \t\t\t\t\t      </a>
  11903. \t\t\t\t\t    </li>
  11904. \t\t\t\t\t    <li class=\"nav-item active\">
  11905. \t\t\t\t\t      <a class=\"nav-link\">
  11906. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 商品価格
  11907. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_price\">{{ mitsumori_json.mitsumori_price|default('---円') }}</span>
  11908. \t\t\t\t\t      </a>
  11909. \t\t\t\t\t    </li>
  11910. \t\t\t\t\t    {# sale_type=2 (補助金窓) ではカタログ価格軸を使わないので非表示. JS 側で #maker_price には \"---円\" を入れる. #}
  11911. \t\t\t\t\t    {% if ProductClass.SaleType.id != 2 %}
  11912. \t\t\t\t\t    <li class=\"nav-item\">
  11913. \t\t\t\t\t      <a class=\"nav-link\">
  11914. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> カタログ価格
  11915. \t\t\t\t\t        <span class=\"float-right\" id=\"maker_price\">{{ mitsumori_json.maker_price|default('---円') }}</span>
  11916. \t\t\t\t\t      </a>
  11917. \t\t\t\t\t    </li>
  11918. \t\t\t\t\t    {% else %}
  11919. \t\t\t\t\t    {# sale_type=2 でも JS が #maker_price を参照するので hidden で残す #}
  11920. \t\t\t\t\t    <span id=\"maker_price\" style=\"display:none;\">---円</span>
  11921. \t\t\t\t\t    {% endif %}
  11922. \t\t\t\t\t    <li class=\"nav-item\">
  11923. \t\t\t\t\t      <a class=\"nav-link\">
  11924. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i>
  11925. \t\t\t\t\t        {% if ProductClass.SaleType.id == 2 %}補助金(割引額){% else %}お値引き{% endif %}
  11926. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_off\">{{ mitsumori_json.mitsumori_off|default('---円') }}</span>
  11927. \t\t\t\t\t      </a>
  11928. \t\t\t\t\t    </li>
  11929. \t\t\t\t\t    {# 補助金窓のみ: 当店が申請代行する旨を補助金行の直下に小さく表示 (消費者の手続き勘違い防止) #}
  11930. \t\t\t\t\t    {% if ProductClass.SaleType.id == 2 %}
  11931. \t\t\t\t\t    <li class=\"nav-item\">
  11932. \t\t\t\t\t      <div style=\"padding:4px 12px 8px;color:#6c757d;font-size:11px;line-height:1.4;\">
  11933. \t\t\t\t\t        ※当店が補助金事業者として申請代行し、契約代金に充当します
  11934. \t\t\t\t\t      </div>
  11935. \t\t\t\t\t    </li>
  11936. \t\t\t\t\t    {% endif %}
  11937. \t\t\t\t\t    <li class=\"nav-item\">
  11938. \t\t\t\t\t      <a class=\"nav-link\">
  11939. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 基本工事費
  11940. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_ct\">{{ mitsumori_json.mitsumori_ct|default('---円') }}</span>
  11941. \t\t\t\t\t      </a>
  11942. \t\t\t\t\t    </li>
  11943. \t\t\t\t\t     {# スチール折板(折半屋根): cp 折板のみ JS が表示。ex-shop と同じく工事費内の別行。 #}
  11944. \t\t\t\t\t     <li class=\"nav-item\" id=\"mitsumori_steelroof_row\" style=\"display:none;\">
  11945. \t\t\t\t\t       <a class=\"nav-link\">
  11946. \t\t\t\t\t         &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> スチール折板
  11947. \t\t\t\t\t         <span class=\"float-right\" id=\"mitsumori_steelroof\">{{ mitsumori_json.mitsumori_steelroof|default('---円') }}</span>
  11948. \t\t\t\t\t       </a>
  11949. \t\t\t\t\t     </li>
  11950. \t\t\t\t\t    <li class=\"nav-item\">
  11951. \t\t\t\t\t      <a class=\"nav-link\">
  11952. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 施工オプション
  11953. \t\t\t\t\t        <span class=\"float-right\"id=\"mitsumori_option\">{{ mitsumori_json.mitsumori_option|default('---円') }}</span>
  11954. \t\t\t\t\t      </a>
  11955. \t\t\t\t\t    </li>
  11956. \t\t\t\t\t  </ul>
  11957. \t\t\t\t\t</div>
  11958. \t\t\t\t\t<div class=\"card-footer\">
  11959. \t\t                <button type=\"button\" id=\"mitsumori_btn\" class=\"btn btn-info\" data-toggle=\"modal\" data-target=\"#modal-mitsumori\">
  11960. \t\t                  見積書表示
  11961. \t\t                </button>
  11962.                         <button type=\"submit\" id=\"cart_btn2\" class=\"btn btn-info add-cart\">カートに入れる</button>
  11963. \t\t\t\t\t</div>
  11964. \t\t\t\t</div>
  11965.             </div>
  11966.         </div>
  11967.     </div>
  11968.   <div class=\"modal\" id=\"modal-mitsumori\">
  11969.     <div class=\"modal-dialog modal-mitsumori\" style=\"max-width:1000px\">
  11970.       <div class=\"modal-content\">
  11971.         <div class=\"modal-header\">
  11972.           <h4 class=\"modal-title\">お見積書</h4>
  11973.           <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">
  11974.             <span aria-hidden=\"true\">&times;</span>
  11975.           </button>
  11976.         </div>
  11977.         <div class=\"modal-body\">
  11978. \t\t\t<div class=\"invoice p-3 mb-5\" style=\"max-width:1000px; margin:auto;\">
  11979. \t\t\t  <!-- title row -->
  11980. \t\t\t  <div class=\"row\">
  11981. \t\t\t    <div class=\"col-12\">
  11982. \t\t\t      <h2>概算お見積書 
  11983. \t\t\t        <small class=\"float-right\" style=\"font-size:14px;\">発行日: <span id=\"mitsumori_issue_date\">---</span></small>
  11984. \t\t\t      </h2>
  11985. \t\t\t    </div>
  11986. \t\t\t    <!-- /.col -->
  11987. \t\t\t  </div>
  11988. \t\t\t  <!-- info row -->
  11989. \t\t\t  <div class=\"row invoice-info\">
  11990. \t\t\t    <div class=\"col-sm-8 invoice-col\">
  11991. \t\t\t      <h3>お客様</h3>
  11992. \t\t\t      <span>下記の通り、お見積もり申し上げます。</span>
  11993. \t\t\t      <br />
  11994. \t\t\t      <br / >
  11995. \t\t\t      <br />
  11996. \t\t\t      <h2>お見積金額: <span id=\"mitsumori_kei\">{{ mitsumori_json.mitsumori_goukei|default('---円') }}</span></h2>
  11997. \t\t\t      <span>
  11998. \t\t\t        <br/>
  11999. \t\t\t        <br/>
  12000. \t\t\t        <br/>
  12001. \t\t\t        <br/>
  12002. \t\t\t      </span>
  12003. \t\t\t    </div>
  12004. \t\t\t    <div class=\"col-sm-4 invoice-col\">
  12005. \t\t\t      <p>
  12006. \t\t\t        <img alt=\"\" src=\"/html/user_data/js/images/logo.png\" style=\"width: 260px; max-width: 100%; max-height: 10mm;\">
  12007. \t\t\t      </p>
  12008. \t\t\t      <p>有限会社プラス</p>
  12009. \t\t\t      <p>〒400-0334</p>
  12010. \t\t\t      <p>山梨県南アルプス市藤田1450番地2</p>
  12011. \t\t\t      <p>TEL: 055-284-6480</p>
  12012. \t\t\t      <img alt=\"\" src=\"/html/user_data/js/images/seal.svg\" style=\"z-index: 2; position: absolute; width: 21mm; left: 58mm; top: 36mm;\">
  12013. \t\t\t    </div>
  12014. \t\t\t    <!-- /.col -->
  12015. \t\t\t    <!-- /.col -->
  12016. \t\t\t  </div>
  12017. \t\t\t  <!-- /.row -->
  12018. \t\t\t  <!-- Table row -->
  12019. \t\t\t  <div class=\"row\">
  12020. \t\t\t    <div class=\"col-12 table-responsive\">
  12021. \t\t\t      <table class=\"table table-striped\">
  12022. \t\t\t        <thead>
  12023. \t\t\t          <tr>
  12024. \t\t\t            <th>項目</th>
  12025. \t\t\t            <th>数量</th>
  12026. \t\t\t            <th>単位</th>
  12027. \t\t\t            <th>単価</th>
  12028. \t\t\t            <th>小計</th>
  12029. \t\t\t          </tr>
  12030. \t\t\t        </thead>
  12031. \t\t\t        <tbody>
  12032. \t\t\t          <tr>
  12033. \t\t\t            <td id=\"mitsumori_item_name\">{{ Product.name }}</td>
  12034. \t\t\t            <td>1</td>
  12035. \t\t\t            <td>式</td>
  12036. \t\t\t            <td id=\"mitsumori_price_01\">---</td>
  12037. \t\t\t            <td id=\"mitsumori_price_02\">---</td>
  12038. \t\t\t          </tr>
  12039. \t\t\t          <tr>
  12040. \t\t\t            <td>基本工事費</td>
  12041. \t\t\t            <td>1</td>
  12042. \t\t\t            <td>式</td>
  12043. \t\t\t            <td id=\"mitsumori_ct_01\">---</td>
  12044. \t\t\t            <td id=\"mitsumori_ct_02\">---</td>
  12045. \t\t\t          </tr>
  12046. \t\t\t          <tr>
  12047. \t\t\t            <td>残土・ガラ処理</td>
  12048. \t\t\t            <td>1</td>
  12049. \t\t\t            <td>式</td>
  12050. \t\t\t            <td>0円</td>
  12051. \t\t\t            <td></td>
  12052. \t\t\t          </tr>
  12053. \t\t\t          <tr>
  12054. \t\t\t            <td> </td>
  12055. \t\t\t            <td></td>
  12056. \t\t\t            <td></td>
  12057. \t\t\t            <td></td>
  12058. \t\t\t            <td></td>
  12059. \t\t\t          </tr>
  12060. \t\t\t        </tbody>
  12061. \t\t\t      </table>
  12062. \t\t\t    </div>
  12063. \t\t\t    <!-- /.col -->
  12064. \t\t\t  </div>
  12065. \t\t\t  <!-- /.row -->
  12066. \t\t\t  <div class=\"row\">
  12067. \t\t\t    <!-- accepted payments column -->
  12068. \t\t\t    <div class=\"col-6\">
  12069. \t\t\t      <p class=\"lead\">お支払い方法</p>
  12070. \t\t\t      <p class=\"text-muted well well-sm shadow-none\" style=\"margin-top: 10px;\">銀行振込、クレジットカード決済、PAYPAY決済
  12071. \t\t\t        <br>銀行振込:山梨中央銀行 白根支店 普通口座 391402
  12072. \t\t\t        <br>※商品代金と工事代金の総額が金100万円(税込)を超える場合、着手金として代金の半額をご契約後お支払いいただきます。 
  12073. \t\t\t      </p>
  12074. \t\t\t    </div>
  12075. \t\t\t    <!-- /.col -->
  12076. \t\t\t    <div class=\"col-6\">
  12077. \t\t\t      <div class=\"table-responsive\">
  12078. \t\t\t        <table class=\"table\">
  12079. \t\t\t          <tbody>
  12080. \t\t\t            <tr>
  12081. \t\t\t              <th style=\"width:50%\">小計:</th>
  12082. \t\t\t              <td id=\"mitsumori_shoukei\">---</td>
  12083. \t\t\t            </tr>
  12084. \t\t\t            <tr>
  12085. \t\t\t              <th>消費税 (10%)</th>
  12086. \t\t\t              <td id=\"mitsumori_tax\">---</td>
  12087. \t\t\t            </tr>
  12088. \t\t\t            <tr>
  12089. \t\t\t              <th>合計:</th>
  12090. \t\t\t              <td id=\"mitsumori_goukei_02\">---</td>
  12091. \t\t\t            </tr>
  12092. \t\t\t          </tbody>
  12093. \t\t\t        </table>
  12094. \t\t\t      </div>
  12095. \t\t\t    </div>
  12096. \t\t\t    <!-- /.col -->
  12097. \t\t\t  </div>
  12098. \t\t\t  <!-- /.row -->
  12099. \t\t\t</div>
  12100.         </div>
  12101.         <div class=\"modal-footer justify-content-between\">
  12102. \t\t\t      {# PDF出力: mitsumori_json を POST して PDF ダウンロード #}
  12103. \t\t\t      <form method=\"post\" action=\"{{ url('mitsumori_pdf') }}\" target=\"_blank\" id=\"pdf_download_form\">
  12104. \t\t\t        <input type=\"hidden\" name=\"_token\" value=\"{{ csrf_token('mitsumori_pdf') }}\">
  12105. \t\t\t        <input type=\"hidden\" name=\"mitsumori_json\" id=\"pdf_mitsumori_json\">
  12106. \t\t\t        <button type=\"submit\" class=\"btn btn-primary float-right\" style=\"margin-right: 5px;\" onclick=\"syncPdfJson();\">
  12107. \t\t\t          <i class=\"fas fa-download\"></i>PDF出力
  12108. \t\t\t        </button>
  12109. \t\t\t      </form>
  12110.                   <button type=\"submit\" id=\"cart_btn3\" class=\"btn btn-info add-cart\">カートに入れる</button>
  12111.         </div>
  12112.       </div>
  12113.       <!-- /.modal-content -->
  12114.     </div>
  12115.     <!-- /.modal-dialog -->
  12116.   </div>
  12117.   <!-- /.modal -->
  12118.     <!-- Image zoom modal: custom lightweight lightbox (no CDN dependency) -->
  12119.     <div id=\"img-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"画像拡大\">
  12120.         <button id=\"img-modal__close\" aria-label=\"閉じる\">&times;</button>
  12121.         <button id=\"img-modal__prev\" aria-label=\"前の画像\">&#10094;</button>
  12122.         <img id=\"img-modal__img\" src=\"\" alt=\"\">
  12123.         <button id=\"img-modal__next\" aria-label=\"次の画像\">&#10095;</button>
  12124.     </div>
  12125.     <style>
  12126.     #img-modal {
  12127.         display: none;
  12128.         position: fixed;
  12129.         inset: 0;
  12130.         z-index: 9999;
  12131.         background: rgba(0,0,0,0.88);
  12132.         align-items: center;
  12133.         justify-content: center;
  12134.         cursor: zoom-out;
  12135.     }
  12136.     #img-modal.is-open { display: flex; }
  12137.     #img-modal__img {
  12138.         max-width: 92vw;
  12139.         max-height: 88vh;
  12140.         object-fit: contain;
  12141.         border-radius: 4px;
  12142.         cursor: default;
  12143.         user-select: none;
  12144.         touch-action: pinch-zoom;
  12145.         display: block;
  12146.     }
  12147.     #img-modal__close {
  12148.         position: absolute;
  12149.         top: 14px;
  12150.         right: 18px;
  12151.         font-size: 38px;
  12152.         color: #fff;
  12153.         cursor: pointer;
  12154.         background: none;
  12155.         border: none;
  12156.         padding: 0;
  12157.         line-height: 1;
  12158.         z-index: 1;
  12159.         opacity: 0.85;
  12160.     }
  12161.     #img-modal__close:hover { opacity: 1; }
  12162.     #img-modal__prev,
  12163.     #img-modal__next {
  12164.         position: absolute;
  12165.         top: 50%;
  12166.         transform: translateY(-50%);
  12167.         font-size: 36px;
  12168.         color: #fff;
  12169.         cursor: pointer;
  12170.         background: rgba(0,0,0,0.32);
  12171.         border: none;
  12172.         padding: 10px 16px;
  12173.         line-height: 1;
  12174.         border-radius: 6px;
  12175.         z-index: 1;
  12176.         opacity: 0.8;
  12177.         user-select: none;
  12178.     }
  12179.     #img-modal__prev:hover, #img-modal__next:hover { opacity: 1; }
  12180.     #img-modal__prev { left: 12px; }
  12181.     #img-modal__next { right: 12px; }
  12182.     @media (max-width: 767px) {
  12183.         #img-modal__prev, #img-modal__next { font-size: 28px; padding: 8px 12px; }
  12184.     }
  12185.     </style>
  12186.     <script>
  12187.     (function(){
  12188.         var images = [];
  12189.         var current = 0;
  12190.         // Collect original (non-cloned) slide images at click time.
  12191.         // After Slick init, slides are wrapped in .slick-slide; clones have .slick-cloned.
  12192.         function collectImages() {
  12193.             images = [];
  12194.             var \$slides = \$('.item_visual .slick-slide:not(.slick-cloned)');
  12195.             if (!\$slides.length) {
  12196.                 // Slick not yet initialized (fallback)
  12197.                 \$slides = \$('.item_visual .slide-item');
  12198.             }
  12199.             \$slides.each(function() {
  12200.                 var \$a = \$(this).find('a.js-zoom');
  12201.                 if (\$a.length) {
  12202.                     images.push({ src: \$a.attr('href'), alt: \$a.find('img').attr('alt') || '' });
  12203.                 }
  12204.             });
  12205.         }
  12206.         function showImage(idx) {
  12207.             current = ((idx % images.length) + images.length) % images.length;
  12208.             \$('#img-modal__img').attr({ src: images[current].src, alt: images[current].alt });
  12209.         }
  12210.         function openModal(href) {
  12211.             collectImages();
  12212.             if (!images.length) return;
  12213.             var idx = 0;
  12214.             for (var i = 0; i < images.length; i++) {
  12215.                 if (images[i].src === href) { idx = i; break; }
  12216.             }
  12217.             showImage(idx);
  12218.             \$('#img-modal').addClass('is-open');
  12219.             \$('body').css('overflow', 'hidden');
  12220.         }
  12221.         function closeModal() {
  12222.             \$('#img-modal').removeClass('is-open');
  12223.             \$('body').css('overflow', '');
  12224.         }
  12225.         // Click handler: works for both original and Slick-cloned anchors
  12226.         \$(document).on('click', '.item_visual a.js-zoom', function(e) {
  12227.             e.preventDefault();
  12228.             openModal(\$(this).attr('href'));
  12229.         });
  12230.         // Close on backdrop click
  12231.         \$('#img-modal').on('click', function(e) {
  12232.             if (e.target === this) closeModal();
  12233.         });
  12234.         \$('#img-modal__close').on('click', closeModal);
  12235.         \$('#img-modal__prev').on('click', function(e) { e.stopPropagation(); showImage(current - 1); });
  12236.         \$('#img-modal__next').on('click', function(e) { e.stopPropagation(); showImage(current + 1); });
  12237.         // Keyboard navigation
  12238.         \$(document).on('keydown', function(e) {
  12239.             if (!\$('#img-modal').hasClass('is-open')) return;
  12240.             if (e.key === 'Escape') closeModal();
  12241.             if (e.key === 'ArrowLeft') showImage(current - 1);
  12242.             if (e.key === 'ArrowRight') showImage(current + 1);
  12243.         });
  12244.         // Touch swipe (horizontal only)
  12245.         var _tx = 0;
  12246.         var \$modal = document.getElementById('img-modal');
  12247.         \$modal.addEventListener('touchstart', function(e) {
  12248.             _tx = e.changedTouches[0].clientX;
  12249.         }, { passive: true });
  12250.         \$modal.addEventListener('touchend', function(e) {
  12251.             var dx = e.changedTouches[0].clientX - _tx;
  12252.             if (Math.abs(dx) > 48) {
  12253.                 dx < 0 ? showImage(current + 1) : showImage(current - 1);
  12254.             }
  12255.         }, { passive: true });
  12256.     })();
  12257.     </script>
  12258. {% endblock %}
  12259. ""Product/detail.twig""/home/xs538259/exterior-plus.jp/public_html/app/template/default/Product/detail.twig");
  12260.     }
  12261. }