{"id":3045,"date":"2026-04-21T15:28:33","date_gmt":"2026-04-21T13:28:33","guid":{"rendered":"https:\/\/bosfortours.com\/?page_id=3045"},"modified":"2026-04-21T16:23:41","modified_gmt":"2026-04-21T14:23:41","slug":"tours-manager","status":"publish","type":"page","link":"https:\/\/bosfortours.com\/mk\/tours-manager\/","title":{"rendered":"Tours Manager"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"3045\" class=\"elementor elementor-3045\">\n\t\t\t\t<div class=\"elementor-element elementor-element-671554d e-con-full e-flex e-con e-parent\" data-id=\"671554d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-468da1e elementor-widget__width-inherit elementor-widget elementor-widget-html\" data-id=\"468da1e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\"\/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\/>\n  <title>Tour Passenger Manager<\/title>\n  <style>\n    #tpm-app *, #tpm-app *::before, #tpm-app *::after { box-sizing:border-box; margin:0; padding:0; }\n    #tpm-app {\n      --blue:#2563eb; --blue-d:#1d4ed8; --blue-l:#eff6ff;\n      --green:#16a34a; --red:#dc2626; --orange:#d97706;\n      --gray-50:#f9fafb; --gray-100:#f3f4f6; --gray-200:#e5e7eb;\n      --gray-300:#d1d5db; --gray-400:#9ca3af; --gray-600:#4b5563;\n      --gray-700:#374151; --gray-800:#1f2937; --white:#fff;\n      --radius:8px; --shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.08);\n      --purple:#7c3aed;\n      font-family:'Segoe UI',system-ui,sans-serif; background:var(--gray-100); color:var(--gray-800); display:block; min-height:100vh;\n    }\n    #tpm-app header { background:var(--blue); color:white; padding:15px 26px; display:flex; align-items:center; gap:12px; box-shadow:0 2px 8px rgba(0,0,0,.2); }\n    #tpm-app header h1 { font-size:1.25rem; font-weight:700; }\n    #tpm-app header p  { font-size:.78rem; opacity:.8; }\n    #tpm-app .container { max-width:1200px; margin:0 auto; padding:20px 16px; }\n    #tpm-app .card { background:var(--white); border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden; }\n    #tpm-app .card-header { background:var(--gray-50); border-bottom:1px solid var(--gray-200); padding:11px 16px; display:flex; align-items:center; gap:7px; font-weight:600; font-size:.88rem; color:var(--gray-700); }\n    #tpm-app .card-body { padding:16px; }\n    #tpm-app .form-group { margin-bottom:10px; }\n    #tpm-app label { display:block; font-size:.74rem; font-weight:600; color:var(--gray-600); margin-bottom:3px; }\n    #tpm-app input, #tpm-app select, #tpm-app textarea { width:100%; padding:7px 10px; border:1.5px solid var(--gray-300); border-radius:6px; font-size:.85rem; color:var(--gray-800); background:var(--white); transition:border-color .2s; }\n    #tpm-app input:focus, #tpm-app select:focus, #tpm-app textarea:focus { outline:none; border-color:var(--blue); box-shadow:0 0 0 3px rgba(37,99,235,.12); }\n    #tpm-app textarea { resize:vertical; min-height:48px; }\n    #tpm-app .btn { display:inline-flex; align-items:center; gap:5px; padding:7px 13px; border-radius:6px; border:none; font-size:.82rem; font-weight:600; cursor:pointer; transition:background .15s,transform .1s; line-height:1; }\n    #tpm-app .btn:active { transform:scale(.97); }\n    #tpm-app .btn-primary { background:var(--blue); color:white; } #tpm-app .btn-primary:hover { background:var(--blue-d); }\n    #tpm-app .btn-success { background:var(--green); color:white; } #tpm-app .btn-success:hover { background:#15803d; }\n    #tpm-app .btn-danger  { background:var(--red); color:white; }  #tpm-app .btn-danger:hover  { background:#b91c1c; }\n    #tpm-app .btn-outline { background:white; color:var(--gray-700); border:1.5px solid var(--gray-300); } #tpm-app .btn-outline:hover { background:var(--gray-50); }\n    #tpm-app .btn-sm { padding:4px 9px; font-size:.74rem; }\n    #tpm-app .btn-full { width:100%; justify-content:center; }\n    #tpm-app .tour-bar { background:white; border-radius:var(--radius); box-shadow:var(--shadow); padding:11px 16px; margin-bottom:18px; display:flex; align-items:center; gap:9px; flex-wrap:wrap; }\n    #tpm-app .tour-bar label { margin:0; font-weight:600; color:var(--gray-700); white-space:nowrap; }\n    #tpm-app #tourBadge { margin-left:auto; background:var(--blue-l); color:var(--blue); border:1px solid #bfdbfe; padding:3px 11px; border-radius:20px; font-size:.75rem; font-weight:600; display:none; }\n    #tpm-app .slabel { font-size:.69rem; font-weight:700; text-transform:uppercase; letter-spacing:.6px; color:var(--gray-400); margin:12px 0 7px; }\n    \/* Member rows inside group modal *\/\n    #tpm-app .member-row { background:var(--gray-50); border:1px solid var(--gray-200); border-radius:7px; padding:10px; margin-bottom:6px; }\n    #tpm-app .member-row:last-child { margin-bottom:0; }\n    #tpm-app .member-row-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:7px; }\n    #tpm-app .member-num { font-size:.72rem; font-weight:700; color:var(--gray-400); text-transform:uppercase; letter-spacing:.4px; }\n    #tpm-app .member-price-live { font-size:.83rem; font-weight:700; color:var(--green); }\n    #tpm-app .remove-btn { background:none; border:none; cursor:pointer; color:var(--gray-400); font-size:1.05rem; padding:0; line-height:1; margin-left:5px; }\n    #tpm-app .remove-btn:hover { color:var(--red); }\n    #tpm-app .mgrid { display:grid; grid-template-columns:1fr 1fr; gap:7px; }\n    #tpm-app .full { grid-column:1\/-1; }\n    \/* Room sections in group modal *\/\n    #tpm-app .room-section { background:#fffdf7; border:1.5px solid #fed7aa; border-radius:9px; margin-bottom:9px; overflow:hidden; }\n    #tpm-app .room-section-head { background:#fff7ed; border-bottom:1px solid #fed7aa; padding:9px 11px; display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }\n    #tpm-app .room-num { font-size:.73rem; font-weight:700; color:#92400e; text-transform:uppercase; letter-spacing:.5px; white-space:nowrap; }\n    #tpm-app .room-section-body { padding:10px; }\n    #tpm-app .room-remove-btn { background:none; border:1px solid #fca5a5; border-radius:5px; cursor:pointer; color:#dc2626; font-size:.72rem; font-weight:600; padding:3px 7px; line-height:1; transition:all .15s; }\n    #tpm-app .room-remove-btn:hover { background:#fee2e2; }\n    #tpm-app .room-price-live { font-size:.82rem; font-weight:700; color:var(--green); background:#f0fdf4; border:1px solid #86efac; border-radius:6px; padding:2px 8px; }\n    #tpm-app .move-room-ctrl { width:auto !important; padding:2px 5px !important; font-size:.71rem !important; border:1.5px solid var(--gray-300) !important; border-radius:5px; color:var(--gray-600); background:white; cursor:pointer; }\n    #tpm-app .drag-handle { color:var(--gray-300); cursor:grab; font-size:1.1rem; user-select:none; line-height:1; flex-shrink:0; }\n    #tpm-app .drag-handle:hover { color:var(--gray-500); }\n    #tpm-app .member-row.dragging { opacity:0.35; box-shadow:0 0 0 2px var(--blue); }\n    #tpm-app .room-section.drag-over { border-color:var(--blue) !important; box-shadow:0 0 0 3px rgba(37,99,235,.18) !important; transition:box-shadow .1s,border-color .1s; }\n    #tpm-app .room-section.drag-over .room-section-head { background:#dbeafe !important; }\n    \/* Price summary *\/\n    #tpm-app .price-summary { background:linear-gradient(135deg,#f0fdf4,#dcfce7); border:1.5px solid #86efac; border-radius:8px; padding:11px 13px; margin-bottom:11px; }\n    #tpm-app .ps-title { font-size:.72rem; font-weight:700; color:var(--green); text-transform:uppercase; letter-spacing:.5px; margin-bottom:5px; }\n    #tpm-app .ps-row  { display:flex; justify-content:space-between; font-size:.81rem; color:var(--gray-700); margin-bottom:2px; }\n    #tpm-app .ps-indented { padding-left:10px; font-size:.79rem; }\n    #tpm-app .ps-room-head { font-size:.73rem; font-weight:700; color:#92400e; margin:6px 0 3px; padding-bottom:2px; border-bottom:1px solid #fde68a; display:flex; align-items:center; gap:6px; }\n    #tpm-app .ps-total { display:flex; justify-content:space-between; font-size:.92rem; font-weight:700; color:var(--green); border-top:1px solid #86efac; margin-top:5px; padding-top:5px; }\n    #tpm-app .tier-badge { display:inline-block; padding:1px 7px; border-radius:9px; font-size:.68rem; font-weight:700; background:#dbeafe; color:#1d4ed8; margin-left:5px; }\n    #tpm-app .type-pill { display:inline-block; padding:2px 7px; border-radius:9px; font-size:.69rem; font-weight:700; }\n    #tpm-app .t-adult  { background:#dbeafe; color:#1d4ed8; }\n    #tpm-app .t-infant { background:#d1fae5; color:#065f46; }\n    #tpm-app .t-csame  { background:#fef3c7; color:#92400e; }\n    #tpm-app .t-csep   { background:#ede9fe; color:#5b21b6; }\n    #tpm-app .room-pill { display:inline-block; padding:2px 8px; border-radius:9px; font-size:.69rem; font-weight:700; }\n    #tpm-app .r-single     { background:#dbeafe; color:#1d4ed8; }\n    #tpm-app .r-double     { background:#d1fae5; color:#065f46; }\n    #tpm-app .r-twin       { background:#fce7f3; color:#9d174d; }\n    #tpm-app .r-triple     { background:#fef3c7; color:#92400e; }\n    #tpm-app .r-connection { background:#ede9fe; color:#5b21b6; }\n    #tpm-app .r-dbl-infant { background:#fff0f6; color:#9d174d; border:1px solid #fbcfe8; }\n    #tpm-app .offer-pill { display:inline-block; padding:2px 8px; border-radius:9px; font-size:.69rem; font-weight:700; background:#e0f2fe; color:#0369a1; }\n    \/* Table *\/\n    #tpm-app .table-wrap { overflow-x:auto; }\n    #tpm-app table { width:100%; border-collapse:collapse; font-size:.82rem; }\n    #tpm-app thead tr { background:var(--gray-50); }\n    #tpm-app th { padding:9px 11px; text-align:left; font-size:.7rem; font-weight:700; color:var(--gray-600); text-transform:uppercase; letter-spacing:.5px; border-bottom:2px solid var(--gray-200); white-space:nowrap; }\n    #tpm-app td { padding:9px 11px; border-bottom:1px solid var(--gray-100); color:var(--gray-700); vertical-align:middle; }\n    #tpm-app .group-hdr td { background:#fff7ed; border-top:2px solid #fed7aa; border-bottom:1px solid #fde68a; padding:8px 11px; }\n    #tpm-app .ghdr-main { display:flex; align-items:center; gap:7px; flex-wrap:wrap; font-size:.82rem; font-weight:700; color:#92400e; }\n    #tpm-app .ghdr-total { font-size:.92rem; font-weight:800; color:var(--green); }\n    #tpm-app .ghdr-note { font-size:.77rem; font-weight:400; color:var(--gray-600); }\n    \/* Room sub-header in table *\/\n    #tpm-app .room-hdr td { background:#fffbeb; border-top:1px solid #fef08a; border-bottom:1px solid #fef08a; padding:6px 11px 6px 28px; }\n    #tpm-app .rhdr-main { display:flex; align-items:center; gap:6px; font-size:.77rem; font-weight:700; color:#b45309; }\n    #tpm-app .rhdr-total { font-size:.82rem; font-weight:700; color:var(--green); }\n    #tpm-app .group-mem td { background:#fffbf5; padding-left:22px; }\n    #tpm-app .group-mem.in-sub td { padding-left:36px; }\n    #tpm-app .group-mem:last-of-type td { border-bottom:2px solid #fed7aa; }\n    #tpm-app .group-hdr:hover td, #tpm-app .group-mem:hover td, #tpm-app .room-hdr:hover td { filter:brightness(.97); }\n    #tpm-app .empty-state { text-align:center; padding:44px 20px; color:var(--gray-400); }\n    #tpm-app .empty-state p { font-size:.86rem; margin-top:10px; }\n    #tpm-app .offer-filter { display:flex; align-items:center; gap:8px; margin-bottom:12px; flex-wrap:wrap; }\n    #tpm-app .filter-label { font-size:.71rem; font-weight:700; color:var(--gray-500); text-transform:uppercase; letter-spacing:.4px; white-space:nowrap; }\n    #tpm-app .ftab { padding:4px 13px; border-radius:20px; font-size:.74rem; font-weight:600; cursor:pointer; border:2px solid transparent; background:var(--gray-100); color:var(--gray-600); transition:all .15s; }\n    #tpm-app .ftab.all-on { background:var(--blue); border-color:var(--blue); color:white; }\n    #tpm-app .ftab.on     { background:#0369a1; border-color:#0369a1; color:white; }\n    #tpm-app .stats { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px; }\n    #tpm-app .stat-chip { background:var(--gray-50); border:1px solid var(--gray-200); border-radius:6px; padding:4px 11px; font-size:.75rem; color:var(--gray-600); }\n    #tpm-app .stat-chip strong { color:var(--gray-800); }\n    #tpm-app .toolbar { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:7px; margin-bottom:11px; }\n    \/* Modals *\/\n    #tpm-app .modal-bg { display:none; position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:100; align-items:center; justify-content:center; padding:16px; }\n    #tpm-app .modal-bg.open { display:flex; }\n    #tpm-app .modal { background:white; border-radius:var(--radius); max-width:95vw; box-shadow:0 10px 30px rgba(0,0,0,.2); }\n    #tpm-app .modal-head { background:var(--gray-50); border-bottom:1px solid var(--gray-200); padding:12px 18px; font-weight:700; font-size:.95rem; display:flex; align-items:center; justify-content:space-between; border-radius:var(--radius) var(--radius) 0 0; }\n    #tpm-app .modal-body { padding:18px; }\n    #tpm-app .modal-foot { padding:12px 18px; border-top:1px solid var(--gray-200); display:flex; justify-content:flex-end; gap:8px; border-radius:0 0 var(--radius) var(--radius); }\n    #tpm-app .modal-close-btn { background:none; border:none; cursor:pointer; color:var(--gray-400); font-size:1.15rem; line-height:1; padding:2px; }\n    #tpm-app .modal-close-btn:hover { color:var(--gray-700); }\n    #tpm-app #toast { position:fixed; bottom:22px; right:22px; background:var(--gray-800); color:white; padding:9px 16px; border-radius:var(--radius); font-size:.83rem; font-weight:500; opacity:0; pointer-events:none; transition:opacity .3s; z-index:999; }\n    #tpm-app #toast.show { opacity:1; }\n    #tpm-app .fac-label { display:inline-flex; align-items:center; gap:6px; cursor:pointer; font-size:.82rem; font-weight:600; color:var(--gray-700); user-select:none; }\n    #tpm-app .fac-label input[type=checkbox] { width:16px; height:16px; cursor:pointer; accent-color:var(--purple); }\n    #tpm-app .fac-yes { color:#7c3aed; font-weight:700; }\n    #tpm-app table.fac-disabled .col-fac { display:none !important; }\n    #tpm-app table.hide-city .col-city { display:none !important; }\n    #tpm-app .col-paxphone { min-width:110px; }\n    \/* Tour modal sections *\/\n    #tpm-app .tm-section { border:1.5px solid var(--gray-200); border-radius:8px; padding:13px; }\n    #tpm-app .tm-section + .tm-section { margin-top:12px; }\n    #tpm-app .tm-section-head { font-size:.78rem; font-weight:700; color:var(--gray-700); margin-bottom:10px; display:flex; align-items:center; justify-content:space-between; }\n    #tpm-app .offer-card { background:var(--gray-50); border:1.5px solid var(--gray-200); border-radius:7px; padding:11px; margin-bottom:9px; }\n    #tpm-app .offer-card:last-child { margin-bottom:0; }\n    #tpm-app .tm-price-table { width:100%; border-collapse:collapse; margin-top:8px; }\n    #tpm-app .tm-price-table th { font-size:.66rem; color:var(--gray-500); text-transform:uppercase; font-weight:700; padding:4px 7px; background:var(--gray-100); border:1px solid var(--gray-200); }\n    #tpm-app .tm-price-table td { padding:4px 7px; border:1px solid var(--gray-200); font-size:.78rem; }\n    #tpm-app .tm-price-table input { padding:4px 7px; font-size:.8rem; border:1.5px solid var(--gray-300); border-radius:4px; width:70px; }\n    #tpm-app .type-check-pill { display:inline-flex; align-items:center; gap:6px; background:var(--gray-50); border:1.5px solid var(--gray-200); border-radius:20px; padding:5px 12px; cursor:pointer; font-size:.8rem; font-weight:600; transition:all .15s; }\n    #tpm-app .type-check-pill.active { background:#eff6ff; border-color:var(--blue); color:var(--blue); }\n    #tpm-app .type-check-pill input { width:14px; height:14px; margin:0; cursor:pointer; }\n\n    \/* \u2550\u2550\u2550\u2550 PRINT \u2550\u2550\u2550\u2550 *\/\n    @media print {\n      #tpm-app * { -webkit-print-color-adjust:exact !important; print-color-adjust:exact !important; }\n      #tpm-app { background:white; font-size:10pt; }\n      #tpm-app header, #tpm-app .tour-bar, #tpm-app .toolbar, #tpm-app #toast,\n      #tpm-app .modal-bg, #tpm-app .offer-filter, #tpm-app .stats, #tpm-app .no-print { display:none !important; }\n      #tpm-app .container { padding:0; max-width:100%; }\n      #tpm-app #listCard { box-shadow:none; border:none; border-radius:0; }\n      #tpm-app #listCard .card-header { display:none !important; }\n      #tpm-app #listCard .card-body { padding:8px 0 0 0; }\n      #tpm-app .table-wrap { overflow:visible; }\n      #tpm-app table { font-size:9.5pt; width:100%; }\n      #tpm-app th { background:#eeeeee !important; color:#333 !important; border-bottom:2px solid #999; padding:6px 8px; }\n      #tpm-app td { padding:6px 8px; border-bottom:1px solid #ddd; }\n      #tpm-app .group-hdr td { background:#fef3c7 !important; border-top:2px solid #d97706 !important; border-bottom:1px solid #fbbf24 !important; }\n      #tpm-app .room-hdr td { background:#fffde7 !important; border-top:1px solid #fde68a !important; border-bottom:1px solid #fde68a !important; padding-left:16px !important; }\n      #tpm-app .group-mem td { background:#fffff8 !important; padding-left:16px; }\n      #tpm-app .group-mem.in-sub td { padding-left:28px; }\n      #tpm-app .group-mem:last-of-type td { border-bottom:2px solid #d97706 !important; }\n      #tpm-app .room-pill, #tpm-app .type-pill, #tpm-app .offer-pill { border:1px solid #666 !important; background:white !important; color:#333 !important; }\n      #tpm-app #printHeader { display:block !important; text-align:center; margin-bottom:16px; padding-bottom:10px; border-bottom:2px solid #333; }\n      #tpm-app.hotel-print .col-city,\n      #tpm-app.hotel-print .col-price,\n      #tpm-app.hotel-print .col-fac { display:none !important; }\n      #tpm-app.hotel-print .col-paxtype { display:table-cell !important; }\n      #tpm-app.hotel-print .hotel-no-print { display:none !important; }\n      #tpm-app #printTitle  { font-size:15pt; font-weight:bold; display:block; }\n      #tpm-app #printMeta   { font-size:9pt; color:#555; display:block; margin-top:2px; }\n      #tpm-app #printFilter { font-size:9pt; color:#0369a1; font-weight:bold; display:block; margin-top:2px; }\n    }\n    #tpm-app #printHeader { display:none; }\n  <\/style>\n<\/head>\n<body>\n<div id=\"tpm-app\">\n\n<header>\n  <svg width=\"28\" height=\"28\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"white\" stroke-width=\"1.8\">\n    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18zM3.6 9h16.8M3.6 15h16.8\"\/>\n    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18\"\/>\n  <\/svg>\n  <div><h1>Tour Passenger Manager<\/h1><p>Smart pricing \u00b7 Multi-room groups \u00b7 Print &amp; Export<\/p><\/div>\n<\/header>\n\n<div class=\"container\">\n  <div class=\"tour-bar\">\n    <label for=\"tourSel\">Active Tour:<\/label>\n    <select id=\"tourSel\" style=\"max-width:250px\" onchange=\"switchTour()\">\n      <option value=\"\">\u2014 Select a tour \u2014<\/option>\n    <\/select>\n    <button class=\"btn btn-outline btn-sm\" onclick=\"openTourModal()\">\n      <svg width=\"11\" height=\"11\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"\/><\/svg>New Tour\n    <\/button>\n    <button class=\"btn btn-outline btn-sm no-print\" id=\"editTourBtn\" onclick=\"openEditTourModal()\" style=\"display:none\">\n      <svg width=\"11\" height=\"11\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\/><\/svg>Edit Tour\n    <\/button>\n    <button class=\"btn btn-danger btn-sm no-print\" id=\"delTourBtn\" onclick=\"deleteTour()\" style=\"display:none\">Delete Tour<\/button>\n    <span id=\"tourBadge\"><\/span>\n  <\/div>\n\n  <!-- Full-width list -->\n  <div class=\"card\" id=\"listCard\">\n    <div class=\"card-header\">\n      <svg width=\"14\" height=\"14\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"\/><\/svg>\n      Passenger List\n    <\/div>\n    <div class=\"card-body\">\n      <div id=\"printHeader\">\n        <span id=\"printTitle\"><\/span>\n        <span id=\"printMeta\"><\/span>\n        <span id=\"printFilter\"><\/span>\n      <\/div>\n      <div class=\"stats\" id=\"statsBar\"><\/div>\n      <div class=\"offer-filter no-print\" id=\"offerFilterBar\"><\/div>\n      <div class=\"toolbar no-print\">\n        <div style=\"display:flex;align-items:center;gap:7px\">\n          <input type=\"text\" id=\"srch\" placeholder=\"Search\u2026\" style=\"width:190px;padding:6px 10px;font-size:.8rem\" oninput=\"renderTable()\"\/>\n          <button class=\"btn btn-primary btn-sm\" id=\"addGroupBtn\" onclick=\"openGroupModal()\">\n            <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"\/><\/svg>\n            <span id=\"addGroupBtnLabel\">Add Group<\/span>\n          <\/button>\n        <\/div>\n        <div style=\"display:flex;gap:6px\">\n          <button class=\"btn btn-success btn-sm\" onclick=\"printList()\">\n            <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z\"\/><\/svg>Print\n          <\/button>\n          <button class=\"btn btn-outline btn-sm\" onclick=\"printHotel()\" style=\"border-color:#7c3aed;color:#7c3aed\">\n            <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4\"\/><\/svg>Hotel\n          <\/button>\n          <button class=\"btn btn-outline btn-sm\" onclick=\"exportCSV()\">\n            <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"\/><\/svg>CSV\n          <\/button>\n        <\/div>\n      <\/div>\n      <div class=\"table-wrap\">\n        <table id=\"mainTable\">\n          <thead>\n            <tr>\n              <th style=\"width:36px\">#<\/th>\n              <th>Full Name<\/th>\n              <th>Date of Birth<\/th>\n              <th>Passport No.<\/th>\n              <th class=\"no-print col-paxtype\">Passenger Type<\/th>\n              <th class=\"no-print hotel-no-print col-paxphone\">Phone<\/th>\n              <th class=\"col-city\">City<\/th>\n              <th class=\"col-price\">Price \/ pp<\/th>\n              <th class=\"col-fac\" style=\"width:90px;text-align:center\">Facultative<\/th>\n              <th class=\"no-print\" style=\"width:110px\">Actions<\/th>\n            <\/tr>\n          <\/thead>\n          <tbody id=\"tBody\"><\/tbody>\n        <\/table>\n        <div class=\"no-print\" style=\"padding:10px 0 4px;text-align:center\" id=\"bottomAddBtn\">\n          <button class=\"btn btn-primary btn-sm\" onclick=\"openGroupModal()\" style=\"gap:5px\">\n            <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"\/><\/svg>\n            <span id=\"bottomAddBtnLabel\">Add Group<\/span>\n          <\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- \u2550\u2550 Group Modal \u2550\u2550 -->\n<div class=\"modal-bg\" id=\"groupModal\">\n  <div class=\"modal\" style=\"width:680px;max-width:97vw;display:flex;flex-direction:column;max-height:92vh\">\n    <div class=\"modal-head\">\n      <span id=\"groupModalTitle\">Add Group \/ Passenger<\/span>\n      <button type=\"button\" class=\"modal-close-btn\" onclick=\"closeGroupModal()\">&#x2715;<\/button>\n    <\/div>\n    <div class=\"modal-body\" style=\"overflow-y:auto;flex:1\">\n      <form id=\"pForm\" onsubmit=\"submitGroup(event)\" action=\"\">\n        <div class=\"slabel\">Offer &amp; Contact<\/div>\n        <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px\">\n          <div class=\"form-group\">\n            <label>Offer *<\/label>\n            <select id=\"f_nights\" required onchange=\"updatePrices()\">\n              <option value=\"\">\u2014 Select \u2014<\/option>\n            <\/select>\n          <\/div>\n          <div class=\"form-group\">\n            <label id=\"f_phone_label\">Group Phone Number<\/label>\n            <input type=\"tel\" id=\"f_phone\" placeholder=\"+1 234 567 8900\"\/>\n          <\/div>\n        <\/div>\n        <div class=\"form-group\">\n          <label>Notes<\/label>\n          <textarea id=\"f_notes\" placeholder=\"Special requests, dietary needs\u2026\" style=\"min-height:40px\"><\/textarea>\n        <\/div>\n\n        <div class=\"slabel\">Rooms &amp; Passengers<\/div>\n        <div id=\"roomList\"><\/div>\n        <button type=\"button\" id=\"addAnotherRoomBtn\" class=\"btn btn-outline btn-sm btn-full\" onclick=\"addRoomSection()\" style=\"margin-bottom:11px;border-style:dashed;color:var(--orange);border-color:#fed7aa\">\n          <svg width=\"11\" height=\"11\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"\/><\/svg>\n          Add Another Room\n        <\/button>\n\n        <div class=\"price-summary\" id=\"priceSummary\" style=\"display:none\">\n          <div class=\"ps-title\">Price Breakdown<\/div>\n          <div id=\"priceRows\"><\/div>\n          <div class=\"ps-total\"><span>Total<\/span><span id=\"priceTotal\"><\/span><\/div>\n        <\/div>\n      <input type=\"hidden\" name=\"trp-form-language\" value=\"mk\"\/><\/form>\n    <\/div>\n    <div class=\"modal-foot\">\n      <button type=\"button\" class=\"btn btn-outline\" onclick=\"closeGroupModal()\">Cancel<\/button>\n      <button type=\"submit\" form=\"pForm\" class=\"btn btn-primary\">\n        <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 13l4 4L19 7\"\/><\/svg>\n        <span id=\"submitLabel\">Add to Tour<\/span>\n      <\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- \u2550\u2550 Tour Modal \u2550\u2550 -->\n<div class=\"modal-bg\" id=\"tourModal\">\n  <div class=\"modal\" style=\"width:740px;max-width:97vw;display:flex;flex-direction:column;max-height:92vh\">\n    <div class=\"modal-head\" id=\"tourModalHead\">\n      <span>New Tour<\/span>\n      <button type=\"button\" class=\"modal-close-btn\" onclick=\"closeTourModal()\">&#x2715;<\/button>\n    <\/div>\n    <div class=\"modal-body\" style=\"overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:12px\">\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">Basic Info<\/div>\n        <div class=\"form-group\"><label>Tour Name *<\/label><input type=\"text\" id=\"tName\" placeholder=\"e.g. Paris Summer 2026\"\/><\/div>\n        <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:9px\">\n          <div class=\"form-group\"><label>Departure Date<\/label><input type=\"date\" id=\"tDate\"\/><\/div>\n          <div class=\"form-group\"><label>Check-in Date<\/label><input type=\"date\" id=\"tCheckin\"\/><\/div>\n        <\/div>\n        <div class=\"form-group\" style=\"margin-top:4px\">\n          <label>Tour Type<\/label>\n          <div style=\"display:flex;gap:10px;margin-top:4px\">\n            <label style=\"display:flex;align-items:center;gap:6px;cursor:pointer;font-weight:500;font-size:.84rem\">\n              <input type=\"radio\" name=\"tTourType\" id=\"tTypeGroup\" value=\"group\" checked style=\"width:15px;height:15px\"\/>\n              Group-based <span style=\"font-size:.75rem;color:var(--gray-500);font-weight:400\">(one booking = multiple rooms)<\/span>\n            <\/label>\n            <label style=\"display:flex;align-items:center;gap:6px;cursor:pointer;font-weight:500;font-size:.84rem\">\n              <input type=\"radio\" name=\"tTourType\" id=\"tTypeRoom\" value=\"room\" style=\"width:15px;height:15px\"\/>\n              Room-based <span style=\"font-size:.75rem;color:var(--gray-500);font-weight:400\">(one booking = one room)<\/span>\n            <\/label>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">\n          <span>Offers &amp; Pricing<\/span>\n          <button type=\"button\" class=\"btn btn-outline btn-sm\" onclick=\"addTMOffer()\">+ Add Offer<\/button>\n        <\/div>\n        <div id=\"tmOffersContainer\"><\/div>\n      <\/div>\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">Features<\/div>\n        <div style=\"display:flex;flex-direction:column;gap:9px\">\n          <label style=\"display:flex;align-items:center;gap:9px;cursor:pointer;font-size:.84rem;font-weight:500\">\n            <input type=\"checkbox\" id=\"tShowCity\" checked style=\"width:15px;height:15px\"\/>\n            <span>Departure city per passenger <span style=\"font-weight:400;color:var(--gray-500);font-size:.76rem\">\u2014 show city field &amp; column<\/span><\/span>\n          <\/label>\n          <label style=\"display:flex;align-items:center;gap:9px;cursor:pointer;font-size:.84rem;font-weight:500\">\n            <input type=\"checkbox\" id=\"tPaxPhone\" style=\"width:15px;height:15px\"\/>\n            <span>Phone number per passenger <span style=\"font-weight:400;color:var(--gray-500);font-size:.76rem\">\u2014 individual contact on each passenger<\/span><\/span>\n          <\/label>\n        <\/div>\n      <\/div>\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">Available Passenger Types<\/div>\n        <div id=\"tmTypesContainer\" style=\"display:flex;flex-wrap:wrap;gap:8px\"><\/div>\n      <\/div>\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">Departure Cities<\/div>\n        <div id=\"tmCitiesContainer\" style=\"display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px\"><\/div>\n        <div style=\"display:flex;gap:8px;align-items:center\">\n          <input type=\"text\" id=\"tmNewCity\" placeholder=\"Add a city\u2026\" style=\"flex:1;padding:5px 9px;font-size:.82rem\"\n            onkeydown=\"if(event.key==='Enter'){event.preventDefault();addTMCity();}\"\/>\n          <button type=\"button\" class=\"btn btn-outline btn-sm\" onclick=\"addTMCity()\" style=\"white-space:nowrap\">+ Add city<\/button>\n        <\/div>\n      <\/div>\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">Available Room Types<\/div>\n        <div id=\"tmRoomsContainer\" style=\"display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px\"><\/div>\n        <div style=\"display:flex;gap:8px;align-items:center\">\n          <input type=\"text\" id=\"tmNewRoom\" placeholder=\"Add a room type\u2026\" style=\"flex:1;padding:5px 9px;font-size:.82rem\"\n            onkeydown=\"if(event.key==='Enter'){event.preventDefault();addTMRoom();}\"\/>\n          <button type=\"button\" class=\"btn btn-outline btn-sm\" onclick=\"addTMRoom()\" style=\"white-space:nowrap\">+ Add room type<\/button>\n        <\/div>\n      <\/div>\n\n      <div class=\"tm-section\">\n        <div class=\"tm-section-head\">Facultative<\/div>\n        <div id=\"tmFacContainer\"><\/div>\n      <\/div>\n\n    <\/div>\n    <div class=\"modal-foot\">\n      <button class=\"btn btn-outline\" onclick=\"closeTourModal()\">Cancel<\/button>\n      <button class=\"btn btn-primary\" id=\"tourModalSaveBtn\" onclick=\"saveTour()\">Create<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- \u2550\u2550 Passenger Edit Modal \u2550\u2550 -->\n<div class=\"modal-bg\" id=\"paxModal\">\n  <div class=\"modal\" style=\"width:460px;max-width:97vw\">\n    <div class=\"modal-head\">\n      <span>Edit Passenger<\/span>\n      <button type=\"button\" class=\"modal-close-btn\" onclick=\"closePaxModal()\">&#x2715;<\/button>\n    <\/div>\n    <div class=\"modal-body\">\n      <div class=\"mgrid\">\n        <div class=\"form-group full\"><label>Full Name *<\/label><input type=\"text\" id=\"pe_name\" placeholder=\"Full name\"\/><\/div>\n        <div class=\"form-group full\" id=\"pe_paxphone_row\" style=\"display:none\"><label>Phone<\/label><input type=\"tel\" id=\"pe_paxphone\" placeholder=\"+1 234 567 8900\"\/><\/div>\n        <div class=\"form-group\"><label>Date of Birth<\/label><input type=\"date\" id=\"pe_dob\"\/><\/div>\n        <div class=\"form-group\"><label>Passport No.<\/label><input type=\"text\" id=\"pe_passport\" placeholder=\"Passport\"\/><\/div>\n        <div class=\"form-group\"><label>Departure City<\/label><select id=\"pe_city\"><\/select><\/div>\n        <div class=\"form-group\"><label>Passenger Type<\/label><select id=\"pe_type\"><\/select><\/div>\n        <div class=\"form-group\"><label>Special Price <span style=\"font-weight:400;color:var(--gray-400)\">(optional \u20ac)<\/span><\/label><input type=\"number\" min=\"0\" step=\"0.01\" id=\"pe_cp\" placeholder=\"\u2014 auto \u2014\" style=\"border-color:#fed7aa\"\/><\/div>\n      <\/div>\n      <div style=\"border-top:1px solid var(--gray-200);margin-top:10px;padding-top:10px\">\n        <div class=\"form-group\" style=\"margin-bottom:6px\">\n          <label>Room Assignment<\/label>\n          <select id=\"pe_room\" onchange=\"onPeRoomChange()\"><\/select>\n        <\/div>\n        <div id=\"pe_newroom_wrap\" style=\"display:none\">\n          <div class=\"form-group\">\n            <label>New Room Type *<\/label>\n            <select id=\"pe_newroom_type\"><\/select>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"modal-foot\">\n      <button type=\"button\" class=\"btn btn-outline\" onclick=\"closePaxModal()\">Cancel<\/button>\n      <button type=\"button\" class=\"btn btn-primary\" onclick=\"savePaxModal()\">\n        <svg width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 13l4 4L19 7\"\/><\/svg>\n        Save\n      <\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<div id=\"toast\"><\/div>\n\n<script>\n\/* \u2500\u2500 State \u2500\u2500 *\/\nvar tours          = JSON.parse(localStorage.getItem('tpm5_tours') || '[]');\nvar passengers     = JSON.parse(localStorage.getItem('tpm5_pax')   || '[]');\nvar activeTourId   = localStorage.getItem('tpm5_tour') || null;\nvar editingTourId  = null;\nvar editingGroupId = null;\nvar activeOfferFilter = '';\nvar memberIdx = 0;\nvar formRoomCounter = 0;\nvar tmOffers = [], tmTypes = [], tmCities = [], tmRooms = [], tmFac = {};\n\nvar ALL_TYPES  = ['adult','child_same','child_sep','infant'];\nvar ALL_CITIES    = ['Skopje','Tetovo','Gostivar','Kumanovo'];\nvar customCities  = JSON.parse(localStorage.getItem('tpm5_cities') || '[]');\nfunction getAllCities() {\n  var all = ALL_CITIES.slice();\n  customCities.forEach(function(c){ if(all.indexOf(c)<0) all.push(c); });\n  return all;\n}\n\nvar ALL_ROOMS    = ['Single','Double','Double + Infant','Twin','Triple','Connection'];\nvar customRooms  = JSON.parse(localStorage.getItem('tpm5_rooms') || '[]');\nfunction getAllRooms() {\n  var all = ALL_ROOMS.slice();\n  customRooms.forEach(function(r){ if(all.indexOf(r)<0) all.push(r); });\n  return all;\n}\nfunction getTourRooms(t) {\n  return (t && t.availableRooms && t.availableRooms.length) ? t.availableRooms : getAllRooms();\n}\n\nvar TYPE_LABELS = {adult:'Adult', infant:'Infant (0\u20132)', child_same:'Child \u2013 same bed', child_sep:'Child \u2013 own bed'};\nvar TYPE_LABELS_LONG = {adult:'Adult', infant:'Infant (0\u20132 yrs)', child_same:'Child (same bed)', child_sep:'Child (own bed)'};\nvar TYPE_CLS    = {adult:'t-adult', infant:'t-infant', child_same:'t-csame', child_sep:'t-csep'};\nvar ROOM_OPTS   = ['Single','Double','Double + Infant','Twin','Triple','Connection'];\nvar ROOM_CLS    = {\n  'Single':'r-single','Double':'r-double','Twin':'r-twin',\n  'Triple':'r-triple','Connection':'r-connection','Double + Infant':'r-dbl-infant'\n};\n\nfunction save() {\n  localStorage.setItem('tpm5_tours', JSON.stringify(tours));\n  localStorage.setItem('tpm5_pax',   JSON.stringify(passengers));\n  localStorage.setItem('tpm5_tour',  activeTourId || '');\n}\n\n\/* \u2500\u2500 Tour helpers \u2500\u2500 *\/\nfunction getActiveTour() {\n  return tours.filter(function(t){ return t.id===activeTourId; })[0] || null;\n}\nfunction getTourOffers(t) {\n  return (t && t.offers && t.offers.length) ? t.offers : defaultTMOffers();\n}\nfunction getTourTypes(t) {\n  return (t && t.enabledTypes && t.enabledTypes.length) ? t.enabledTypes : ALL_TYPES.slice();\n}\nfunction getTourCities(t) {\n  return (t && t.availableCities && t.availableCities.length) ? t.availableCities : getAllCities();\n}\nfunction isFacEnabled() {\n  var t = getActiveTour();\n  if (!t || !t.facultative) return true;\n  return t.facultative.enabled !== false;\n}\nfunction defaultTMOffers() {\n  return [\n    {nights:'2', label:'2 Nights', solo:{adult:150,child_same:50,child_sep:135,infant:0}, group:{adult:100,child_same:50,child_sep:90,infant:0}},\n    {nights:'3', label:'3 Nights', solo:{adult:200,child_same:50,child_sep:180,infant:0}, group:{adult:130,child_same:50,child_sep:117,infant:0}}\n  ];\n}\nfunction defaultTMFac(offers) {\n  var p = {};\n  (offers||[]).forEach(function(o){ if(o.nights) p[o.nights]={adult:40,child_same:20,child_sep:20,infant:0}; });\n  return {enabled:true, prices:p};\n}\n\n\/* \u2500\u2500 Pricing \u2500\u2500 *\/\nfunction getTier(members) {\n  return members.filter(function(m){return m.type==='adult'||m.type==='child_sep';}).length <= 1 ? 'solo' : 'group';\n}\nfunction priceFor(type, nights, tier) {\n  var t = getActiveTour();\n  var offers = getTourOffers(t);\n  var offer = offers.filter(function(o){ return o.nights===nights; })[0];\n  if (offer) {\n    var rates = tier==='solo' ? offer.solo : offer.group;\n    if (rates && rates[type] !== undefined) return Number(rates[type]);\n  }\n  var base = tier==='solo' ? (nights==='2'?150:200) : (nights==='2'?100:130);\n  if (type==='adult')      return base;\n  if (type==='infant')     return 0;\n  if (type==='child_same') return 50;\n  if (type==='child_sep')  return Math.round(base*0.9*100)\/100;\n  return base;\n}\nfunction facPriceFor(pax) {\n  var t = getActiveTour();\n  if (t && t.facultative && t.facultative.enabled!==false && t.facultative.prices && pax.nights) {\n    var op = t.facultative.prices[pax.nights];\n    if (op && op[pax.type] !== undefined) return Number(op[pax.type]);\n  }\n  var age = calcAge(pax.dob);\n  if (age===null || age>=10) return 40;\n  if (age>=6) return 20;\n  return 0;\n}\nfunction fmtFac(pax) { var p=facPriceFor(pax); return p===0?'FREE':'\u20ac'+p; }\nfunction fmtP(n) { return n===0 ? 'FREE' : '\u20ac'+(n===Math.round(n) ? n : n.toFixed(2)); }\n\n\/* \u2500\u2500 Age \/ DOB \u2500\u2500 *\/\nfunction calcAge(dob) {\n  if (!dob) return null;\n  var b=new Date(dob), t=new Date();\n  var a=t.getFullYear()-b.getFullYear();\n  if (t.getMonth()<b.getMonth()||(t.getMonth()===b.getMonth()&&t.getDate()<b.getDate())) a--;\n  return a;\n}\nfunction autoTypeFromDob(idx) {\n  var dobEl = document.getElementById('mdob_'+idx);\n  if (!dobEl) return;\n  var age = calcAge(dobEl.value);\n  if (age===null) return;\n  var sel = document.getElementById('mtype_'+idx);\n  if (!sel) return;\n  var newType = age<2 ? 'infant' : age<=12 ? 'child_same' : 'adult';\n  if (sel.querySelector('option[value=\"'+newType+'\"]')) sel.value = newType;\n  updatePrices();\n}\n\n\/* \u2500\u2500 Form offer select \u2500\u2500 *\/\nfunction renderFormOffers() {\n  var t = getActiveTour();\n  var offers = getTourOffers(t);\n  var sel = document.getElementById('f_nights');\n  var prev = sel.value;\n  sel.innerHTML = '<option value=\"\">\u2014 Select \u2014<\/option>';\n  offers.forEach(function(o) {\n    var opt = document.createElement('option');\n    opt.value = o.nights;\n    opt.textContent = o.label || (o.nights+' Nights');\n    if (o.nights===prev) opt.selected=true;\n    sel.appendChild(opt);\n  });\n  \/\/ Default to first offer when nothing is pre-selected\n  if (!sel.value && offers.length) sel.value = offers[0].nights;\n  updatePrices();\n}\n\n\/* \u2500\u2500 Room sections \u2500\u2500 *\/\nfunction roomTypeOptions(selected) {\n  var t = getActiveTour();\n  var opts = getTourRooms(t);\n  return '<option value=\"\"'+(selected?'':' selected')+'>\u2014 Select \u2014<\/option>' +\n    opts.map(function(r){\n      return '<option value=\"'+r+'\"'+(r===selected?' selected':'')+'>'+r+'<\/option>';\n    }).join('');\n}\n\nfunction addRoomSection(prefillRoom, prefillMembers) {\n  var rsId = formRoomCounter++;\n  var div = document.createElement('div');\n  div.className = 'room-section';\n  div.id = 'rs_' + rsId;\n  div.innerHTML =\n    '<div class=\"room-section-head\">' +\n      '<div style=\"display:flex;align-items:center;gap:8px;flex:1;min-width:0\">' +\n        '<svg width=\"13\" height=\"13\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"#b45309\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z\"\/><\/svg>' +\n        '<span class=\"room-num\">Room 1<\/span>' +\n        '<select id=\"froom_'+rsId+'\" onchange=\"updatePrices()\" style=\"width:155px;padding:4px 7px;font-size:.82rem\">'+roomTypeOptions(prefillRoom||'')+'<\/select>' +\n      '<\/div>' +\n      '<div style=\"display:flex;align-items:center;gap:6px\">' +\n        '<span class=\"room-price-live\" id=\"rpl_'+rsId+'\"><\/span>' +\n        '<button type=\"button\" class=\"room-remove-btn\" id=\"rrem_'+rsId+'\" onclick=\"removeRoom('+rsId+')\" style=\"display:none\">Remove<\/button>' +\n      '<\/div>' +\n    '<\/div>' +\n    '<div class=\"room-section-body\">' +\n      '<div class=\"room-members\" id=\"rm_'+rsId+'\"><\/div>' +\n      '<div style=\"padding:6px 10px 8px\">' +\n        '<button type=\"button\" class=\"btn btn-outline btn-sm\" onclick=\"addMemberToRoom('+rsId+')\" style=\"font-size:.75rem;width:100%\">+ Add Passenger<\/button>' +\n      '<\/div>' +\n    '<\/div>';\n  document.getElementById('roomList').appendChild(div);\n\n  \/\/ Drop zone for this room\n  (function(rsIdLocal, divLocal){\n    divLocal.addEventListener('dragover', function(e){\n      if (!e.dataTransfer.types || [].indexOf.call(e.dataTransfer.types,'text\/plain')<0) return;\n      e.preventDefault(); e.dataTransfer.dropEffect='move';\n      divLocal.classList.add('drag-over');\n    });\n    divLocal.addEventListener('dragleave', function(e){\n      if (!divLocal.contains(e.relatedTarget)) divLocal.classList.remove('drag-over');\n    });\n    divLocal.addEventListener('drop', function(e){\n      e.preventDefault(); divLocal.classList.remove('drag-over');\n      var memberId = e.dataTransfer.getData('text\/plain');\n      if (!memberId) return;\n      var mr = document.getElementById(memberId);\n      if (!mr || mr.closest('.room-section')===divLocal) return;\n      moveMemberToRoom(memberId, rsIdLocal);\n    });\n  })(rsId, div);\n\n  if (prefillMembers && prefillMembers.length) {\n    prefillMembers.forEach(function(m){ addMemberToRoom(rsId, m); });\n  } else {\n    addMemberToRoom(rsId);\n  }\n  renumberRooms();\n  updatePrices();\n}\n\nfunction removeRoom(rsId) {\n  var sections = document.querySelectorAll('#roomList .room-section');\n  if (sections.length <= 1) { toast('At least one room is required.'); return; }\n  var el = document.getElementById('rs_'+rsId);\n  if (el) el.parentNode.removeChild(el);\n  renumberRooms();\n  renumberMembers();\n  updatePrices();\n}\n\nfunction renumberRooms() {\n  var sections = [].slice.call(document.querySelectorAll('#roomList .room-section'));\n  var multi = sections.length > 1;\n  sections.forEach(function(s, i) {\n    var numEl = s.querySelector('.room-num');\n    if (numEl) numEl.textContent = 'Room ' + (i+1);\n    var rsId = s.id.replace('rs_','');\n    var rrem = document.getElementById('rrem_'+rsId);\n    if (rrem) rrem.style.display = multi ? '' : 'none';\n  });\n  refreshMoveButtons();\n}\n\nfunction refreshMoveButtons() {\n  var sections = [].slice.call(document.querySelectorAll('#roomList .room-section'));\n  var multi = sections.length > 1;\n\n  \/\/ Build label map: rsId -> \"Room N\"\n  var roomLabels = {};\n  sections.forEach(function(s, i) { roomLabels[s.id.replace('rs_','')] = 'Room '+(i+1); });\n\n  var allMembers = [].slice.call(document.querySelectorAll('#roomList .member-row'));\n  allMembers.forEach(function(mr) {\n    var currentRsId = String(mr.dataset.roomId);\n    var existing = mr.querySelector('.move-room-ctrl');\n\n    if (!multi) {\n      if (existing) existing.style.display = 'none';\n      return;\n    }\n\n    var opts = '<option value=\"\">Move to\u2026<\/option>' +\n      sections.filter(function(s){ return s.id.replace('rs_','') !== currentRsId; })\n        .map(function(s){\n          var rid = s.id.replace('rs_','');\n          return '<option value=\"'+rid+'\">'+roomLabels[rid]+'<\/option>';\n        }).join('');\n\n    if (existing) {\n      existing.innerHTML = opts;\n      existing.style.display = '';\n    } else {\n      var sel = document.createElement('select');\n      sel.className = 'move-room-ctrl';\n      sel.innerHTML = opts;\n      sel.addEventListener('change', (function(mrEl){ return function(){\n        if (!this.value) return;\n        moveMemberToRoom(mrEl.id, this.value);\n        this.value = '';\n      }; })(mr));\n      var removeBtn = mr.querySelector('.remove-btn');\n      if (removeBtn) removeBtn.parentNode.insertBefore(sel, removeBtn);\n    }\n  });\n}\n\nfunction moveMemberToRoom(memberId, targetRsId) {\n  var mr = document.getElementById(memberId);\n  if (!mr) return;\n  var targetContainer = document.getElementById('rm_'+targetRsId);\n  if (!targetContainer) return;\n  mr.dataset.roomId = targetRsId;\n  targetContainer.appendChild(mr);\n  renumberMembers();\n  refreshMoveButtons();\n  updatePrices();\n}\n\n\/* \u2500\u2500 Member rows \u2500\u2500 *\/\nfunction addMemberToRoom(rsId, prefill) {\n  var idx  = memberIdx++;\n  var type = (prefill && prefill.type) ? prefill.type : 'adult';\n  var div  = document.createElement('div');\n  div.className = 'member-row';\n  div.id = 'mr_' + idx;\n  div.dataset.roomId = rsId;\n  var t = getActiveTour();\n  var enabledTypes = getTourTypes(t);\n  var allTypeOpts = [\n    ['adult',      'Adult'],\n    ['infant',     'Infant (0\u20132 years) \u2014 FREE'],\n    ['child_same', 'Child (2\u201312, same bed)'],\n    ['child_sep',  'Child (2\u201312, own bed) \u2014 10% off']\n  ];\n  var selOpts = allTypeOpts\n    .filter(function(o){ return enabledTypes.indexOf(o[0])>=0; })\n    .map(function(o){ return '<option value=\"'+o[0]+'\"'+(o[0]===type?' selected':'')+'>'+o[1]+'<\/option>'; })\n    .join('');\n  div.innerHTML =\n    '<div class=\"member-row-header\">' +\n      '<div style=\"display:flex;align-items:center;gap:5px\">' +\n        '<span class=\"drag-handle\" title=\"Drag to move to another room\">&#8942;&#8942;<\/span>' +\n        '<span class=\"member-num\">Passenger 1<\/span>' +\n      '<\/div>' +\n      '<div style=\"display:flex;align-items:center;gap:5px\">' +\n        '<span class=\"member-price-live\" id=\"mpl_'+idx+'\"><\/span>' +\n        '<button type=\"button\" class=\"remove-btn\" onclick=\"removeMember(\\'mr_'+idx+'\\','+rsId+')\">&#x2715;<\/button>' +\n      '<\/div>' +\n    '<\/div>' +\n    '<div class=\"mgrid\">' +\n      '<div class=\"form-group full\"><label>Full Name *<\/label><input type=\"text\" id=\"mn_'+idx+'\" placeholder=\"Full name\" value=\"'+esc((prefill&&prefill.name)||'')+'\" oninput=\"updatePrices()\"\/><\/div>' +\n      (function(){var t=getActiveTour();return (t&&t.paxPhone)?'<div class=\"form-group full\"><label>Phone<\/label><input type=\"tel\" id=\"mphone_'+idx+'\" placeholder=\"+1 234 567 8900\" value=\"'+esc((prefill&&prefill.paxPhone)||'')+'\"\/><\/div>':'';})()+\n      '<div class=\"form-group\"><label>Date of Birth<\/label><input type=\"date\" id=\"mdob_'+idx+'\" value=\"'+((prefill&&prefill.dob)||'')+'\" onchange=\"autoTypeFromDob(\\''+idx+'\\')\"\/><\/div>' +\n      '<div class=\"form-group\"><label>Passport No.<\/label><input type=\"text\" id=\"mpass_'+idx+'\" placeholder=\"Passport\" value=\"'+esc((prefill&&prefill.passport)||'')+'\"\/><\/div>' +\n      (function(){\n        var t=getActiveTour();\n        if(t&&t.showCity===false) return '';\n        var cities=getTourCities(t);\n        var sel=prefill&&prefill.city?prefill.city:(cities.length?cities[0]:'');\n        return '<div class=\"form-group\"><label>Departure City *<\/label><select id=\"mcity_'+idx+'\">'+\n          cities.map(function(c){return '<option value=\"'+c+'\"'+(c===sel?' selected':'')+'>'+c+'<\/option>';}).join('')+\n        '<\/select><\/div>';\n      })()+\n      '<div class=\"form-group\"><label>Passenger Type<\/label><select id=\"mtype_'+idx+'\" onchange=\"updatePrices()\">'+selOpts+'<\/select><\/div>' +\n      '<div class=\"form-group\"><label>Special Price <span style=\"font-weight:400;color:var(--gray-400)\">(optional \u20ac)<\/span><\/label><input type=\"number\" min=\"0\" step=\"0.01\" id=\"mcp_'+idx+'\" placeholder=\"\u2014 auto \u2014\" value=\"'+((prefill&&prefill.customPrice!=null)?prefill.customPrice:'')+'\" oninput=\"updatePrices()\" style=\"border-color:#fed7aa\"\/><\/div>' +\n    '<\/div>';\n  document.getElementById('rm_'+rsId).appendChild(div);\n\n  \/\/ Drag source\n  div.setAttribute('draggable', 'true');\n  div.addEventListener('dragstart', function(e){\n    e.dataTransfer.setData('text\/plain', div.id);\n    e.dataTransfer.effectAllowed = 'move';\n    setTimeout(function(){ div.classList.add('dragging'); }, 0);\n  });\n  div.addEventListener('dragend', function(){\n    div.classList.remove('dragging');\n    document.querySelectorAll('.room-section.drag-over').forEach(function(el){ el.classList.remove('drag-over'); });\n  });\n\n  renumberMembers();\n  refreshMoveButtons();\n  updatePrices();\n}\n\nfunction removeMember(id, rsId) {\n  var container = document.getElementById('rm_'+rsId);\n  if (!container) return;\n  if (container.querySelectorAll('.member-row').length <= 1) {\n    toast('Each room needs at least one passenger.');\n    return;\n  }\n  var el = document.getElementById(id);\n  if (el) el.parentNode.removeChild(el);\n  renumberMembers();\n  refreshMoveButtons();\n  updatePrices();\n}\n\nfunction renumberMembers() {\n  var allRows = [].slice.call(document.querySelectorAll('#roomList .member-row'));\n  allRows.forEach(function(row, i) {\n    var n = row.querySelector('.member-num');\n    if (n) n.textContent = 'Passenger ' + (i+1);\n  });\n}\n\nfunction updatePrices() {\n  var nights = document.getElementById('f_nights').value;\n  if (!nights) { document.getElementById('priceSummary').style.display='none'; return; }\n\n  var roomSections = [].slice.call(document.querySelectorAll('#roomList .room-section'));\n  if (!roomSections.length) { document.getElementById('priceSummary').style.display='none'; return; }\n\n  var grandTotal = 0;\n  var html = '';\n  var multiRoom = roomSections.length > 1;\n\n  roomSections.forEach(function(rs, ri) {\n    var rsId = rs.id.replace('rs_','');\n    var froomEl = document.getElementById('froom_'+rsId);\n    var roomType = froomEl ? froomEl.value : '';\n    var memberRows = [].slice.call(rs.querySelectorAll('.member-row'));\n    if (!memberRows.length) return;\n\n    var members = memberRows.map(function(mr) {\n      var idx = mr.id.replace('mr_','');\n      var nameEl = document.getElementById('mn_'+idx), typeEl = document.getElementById('mtype_'+idx), cpEl = document.getElementById('mcp_'+idx);\n      var cpVal = cpEl && cpEl.value.trim() !== '' ? parseFloat(cpEl.value) : null;\n      return { idx:idx, name:(nameEl?nameEl.value.trim():'?'), type:(typeEl?typeEl.value:'adult'), customPrice:cpVal };\n    });\n\n    var tier = getTier(members);\n    var roomTotal = 0;\n\n    if (multiRoom) {\n      html += '<div class=\"ps-room-head\">Room '+(ri+1)+(roomType?' &mdash; '+esc(roomType):'')+\n        ' <span class=\"tier-badge\">'+(tier==='solo'?'Solo':'Group')+' rate<\/span><\/div>';\n    }\n\n    members.forEach(function(m) {\n      var p = (m.customPrice !== null) ? m.customPrice : priceFor(m.type, nights, tier);\n      var isCustom = m.customPrice !== null;\n      roomTotal += p; grandTotal += p;\n      var el = document.getElementById('mpl_'+m.idx);\n      if (el) { el.textContent = fmtP(p); el.style.color = isCustom ? 'var(--orange)' : ''; }\n      html += '<div class=\"ps-row'+(multiRoom?' ps-indented':'')+'\"><span>'+esc(m.name||'\u2014')+' <span style=\"font-size:.68rem;color:var(--gray-500)\">('+TYPE_LABELS[m.type]+')<\/span>'+(isCustom?' <span style=\"font-size:.65rem;background:#fef3c7;color:#92400e;border-radius:4px;padding:1px 4px;font-weight:700\">special<\/span>':'')+'<\/span><span style=\"'+(isCustom?'color:var(--orange);font-weight:700':'')+'\">'+fmtP(p)+'<\/span><\/div>';\n    });\n\n    var rplEl = document.getElementById('rpl_'+rsId);\n    if (rplEl) rplEl.textContent = '\u20ac' + (roomTotal===Math.round(roomTotal)?roomTotal:roomTotal.toFixed(2));\n\n    if (multiRoom) {\n      html += '<div class=\"ps-row\" style=\"font-weight:700;padding-left:10px;border-top:1px dashed #bbf7d0;margin-top:3px;padding-top:3px\"><span>Room '+(ri+1)+' total<\/span><span>\u20ac'+(roomTotal===Math.round(roomTotal)?roomTotal:roomTotal.toFixed(2))+'<\/span><\/div>';\n    }\n  });\n\n  var allMembers = [].slice.call(document.querySelectorAll('#roomList .member-row')).map(function(mr){\n    var idx=mr.id.replace('mr_',''); var typeEl=document.getElementById('mtype_'+idx);\n    return {type:typeEl?typeEl.value:'adult'};\n  });\n  var overallTier = getTier(allMembers);\n  document.getElementById('priceTotal').innerHTML =\n    '\u20ac'+(grandTotal===Math.round(grandTotal)?grandTotal:grandTotal.toFixed(2))+\n    (!multiRoom ? ' <span class=\"tier-badge\">'+(overallTier==='solo'?'Solo':'Group')+' rate<\/span>' : '');\n\n  document.getElementById('priceRows').innerHTML = html;\n  document.getElementById('priceSummary').style.display = '';\n}\n\n\/* \u2500\u2500 Group modal \u2500\u2500 *\/\nfunction isRoomBasedTour() {\n  var t = getActiveTour();\n  return t && t.tourType === 'room';\n}\nfunction applyGroupModalMode(isRoom) {\n  document.getElementById('groupModalTitle').textContent = 'Add Group \/ Passenger';\n  document.getElementById('f_phone_label').textContent = isRoom ? 'Contact Phone' : 'Group Phone Number';\n}\nfunction openGroupModal() {\n  if (!activeTourId) { alert('Please select or create a tour first.'); return; }\n  editingGroupId = null;\n  var isRoom = isRoomBasedTour();\n  applyGroupModalMode(isRoom);\n  document.getElementById('submitLabel').textContent = 'Add to Tour';\n  document.getElementById('f_nights').value = '';\n  document.getElementById('f_phone').value  = '';\n  document.getElementById('f_notes').value  = '';\n  document.getElementById('roomList').innerHTML = '';\n  formRoomCounter = 0; memberIdx = 0;\n  addRoomSection();\n  renderFormOffers();\n  document.getElementById('priceSummary').style.display = 'none';\n  document.getElementById('groupModal').classList.add('open');\n}\n\nfunction closeGroupModal() {\n  document.getElementById('groupModal').classList.remove('open');\n  editingGroupId = null;\n}\n\n\/* \u2500\u2500 Group CRUD \u2500\u2500 *\/\nfunction submitGroup(e) {\n  e.preventDefault();\n  if (!activeTourId) { alert('Please select or create a tour first.'); return; }\n  var nights = document.getElementById('f_nights').value;\n  var phone  = document.getElementById('f_phone').value.trim();\n  var notes  = document.getElementById('f_notes').value.trim();\n  if (!nights) { alert('Please select an offer.'); return; }\n\n  var roomSections = [].slice.call(document.querySelectorAll('#roomList .room-section'));\n  if (!roomSections.length) { alert('Add at least one room.'); return; }\n\n  var groupId = editingGroupId || ('grp_'+Date.now());\n  var ts = Date.now();\n  var newPassengers = [];\n\n  for (var ri = 0; ri < roomSections.length; ri++) {\n    var rs = roomSections[ri];\n    var rsId = rs.id.replace('rs_','');\n    var froomEl = document.getElementById('froom_'+rsId);\n    var roomType = froomEl ? froomEl.value : '';\n    if (!roomType) { alert('Please select a room type for Room '+(ri+1)+'.'); return; }\n\n    var memberRows = [].slice.call(rs.querySelectorAll('.member-row'));\n    if (!memberRows.length) { alert('Room '+(ri+1)+' has no passengers.'); return; }\n\n    var members = [];\n    for (var mi = 0; mi < memberRows.length; mi++) {\n      var mr = memberRows[mi];\n      var idx = mr.id.replace('mr_','');\n      var cpEl = document.getElementById('mcp_'+idx);\n      var cpVal = cpEl && cpEl.value.trim() !== '' ? parseFloat(cpEl.value) : null;\n      var phoneEl = document.getElementById('mphone_'+idx);\n      var member = {\n        name:        (document.getElementById('mn_'+idx)     ? document.getElementById('mn_'+idx).value.trim()     : ''),\n        dob:         (document.getElementById('mdob_'+idx)   ? document.getElementById('mdob_'+idx).value           : ''),\n        passport:    (document.getElementById('mpass_'+idx)  ? document.getElementById('mpass_'+idx).value.trim()  : ''),\n        city:        (document.getElementById('mcity_'+idx)  ? document.getElementById('mcity_'+idx).value         : ''),\n        paxPhone:    (phoneEl ? phoneEl.value.trim() : ''),\n        type:        (document.getElementById('mtype_'+idx)  ? document.getElementById('mtype_'+idx).value         : 'adult'),\n        customPrice: cpVal\n      };\n      if (!member.name) { alert('All passengers must have a name.'); return; }\n      members.push(member);\n    }\n\n    var tier = getTier(members);\n    var roomId = 'room_'+ts+'_'+ri;\n    members.forEach(function(m, i) {\n      var finalPrice = (m.customPrice !== null) ? m.customPrice : priceFor(m.type, nights, tier);\n      newPassengers.push({\n        id:'p_'+ts+'_'+ri+'_'+i, tourId:activeTourId, groupId:groupId, roomId:roomId,\n        name:m.name, dob:m.dob, passport:m.passport, city:m.city, type:m.type,\n        nights:nights, price:finalPrice, customPrice:m.customPrice, tier:tier,\n        room:roomType, phone:phone, notes:notes, paxPhone:m.paxPhone||'', facultative:false\n      });\n    });\n  }\n\n  if (editingGroupId) {\n    var savedFac = {};\n    var insertAt = -1;\n    passengers.forEach(function(p, idx){\n      if (p.groupId===editingGroupId && p.tourId===activeTourId) {\n        if (insertAt < 0) insertAt = idx;\n        savedFac[p.name+'|'+p.dob] = p.facultative;\n      }\n    });\n    passengers = passengers.filter(function(p){return !(p.groupId===editingGroupId&&p.tourId===activeTourId);});\n    newPassengers.forEach(function(p){\n      if (savedFac[p.name+'|'+p.dob] !== undefined) p.facultative = savedFac[p.name+'|'+p.dob];\n    });\n    if (insertAt < 0 || insertAt >= passengers.length) {\n      passengers = passengers.concat(newPassengers);\n    } else {\n      passengers.splice.apply(passengers, [insertAt, 0].concat(newPassengers));\n    }\n  } else {\n    passengers = passengers.concat(newPassengers);\n  }\n  var wasAdding = !editingGroupId;\n  var scrollToId = groupId;\n  save();\n  closeGroupModal();\n  toast(wasAdding ? (newPassengers.length===1?'Passenger added!':'Group of '+newPassengers.length+' added!') : 'Group updated!');\n  renderTable();\n  \/\/ Scroll to the newly added \/ edited group\n  setTimeout(function(){\n    var row = document.querySelector('tr[data-group=\"'+scrollToId+'\"]');\n    if (row) row.scrollIntoView({behavior:'smooth', block:'center'});\n  }, 60);\n}\n\nfunction editGroup(groupId) {\n  var members = passengers.filter(function(p){return p.groupId===groupId&&p.tourId===activeTourId;});\n  if (!members.length) return;\n  editingGroupId = groupId;\n  var first = members[0];\n\n  var isRoom = isRoomBasedTour();\n  applyGroupModalMode(isRoom);\n  document.getElementById('groupModalTitle').textContent = 'Edit Group';\n  document.getElementById('submitLabel').textContent = 'Save Changes';\n  document.getElementById('f_nights').value = first.nights||'';\n  document.getElementById('f_phone').value  = first.phone ||'';\n  document.getElementById('f_notes').value  = first.notes ||'';\n  document.getElementById('roomList').innerHTML = '';\n  formRoomCounter = 0; memberIdx = 0;\n\n  \/\/ Reconstruct rooms grouped by roomId\n  var rooms = {}, roomOrder = [];\n  members.forEach(function(p){\n    var rid = p.roomId || 'default';\n    if (!rooms[rid]) { rooms[rid]=[]; roomOrder.push(rid); }\n    rooms[rid].push(p);\n  });\n  if (!roomOrder.length) {\n    addRoomSection(first.room, members);\n  } else {\n    roomOrder.forEach(function(rid){\n      var rm = rooms[rid];\n      addRoomSection(rm[0].room, rm);\n    });\n  }\n\n  renderFormOffers();\n  \/\/ Re-set the offer selection after renderFormOffers resets it\n  document.getElementById('f_nights').value = first.nights||'';\n  updatePrices();\n  document.getElementById('groupModal').classList.add('open');\n}\n\nfunction deleteGroup(groupId) {\n  var cnt=passengers.filter(function(p){return p.groupId===groupId&&p.tourId===activeTourId;}).length;\n  if (!confirm('Remove this group ('+cnt+' passenger'+(cnt>1?'s':'')+')? This cannot be undone.')) return;\n  passengers=passengers.filter(function(p){return !(p.groupId===groupId&&p.tourId===activeTourId);});\n  save(); renderTable(); toast('Group removed.');\n}\nfunction tableMovePassenger(passengerId, targetRoomId, selectEl) {\n  if (!targetRoomId) return;\n  var pax = passengers.filter(function(p){ return p.id===passengerId; })[0];\n  if (!pax) return;\n  \/\/ Find any member already in target room (may be in a different group)\n  var target = passengers.filter(function(p){\n    return p.tourId===pax.tourId && p.roomId===targetRoomId;\n  })[0];\n  if (!target) return;\n  pax.roomId  = target.roomId;\n  pax.room    = target.room;\n  pax.groupId = target.groupId; \/\/ move to target group if cross-group\n  \/\/ Recalculate tier + price for moved passenger\n  var roomMates = passengers.filter(function(p){ return p.tourId===pax.tourId && p.roomId===pax.roomId; });\n  var adultCount = roomMates.filter(function(p){ return p.type==='adult'||p.type==='child_sep'; }).length;\n  var tier = adultCount >= 2 ? 'group' : 'solo';\n  pax.price = pax.customPrice !== null && pax.customPrice !== undefined\n    ? pax.customPrice\n    : priceFor(pax.type, pax.nights, tier);\n  save(); renderTable(); toast(esc(pax.name)+' moved.');\n}\n\n\/* \u2500\u2500 Render table \u2500\u2500 *\/\nfunction renderOfferFilter() {\n  var t = getActiveTour();\n  var offers = getTourOffers(t);\n  var cont = document.getElementById('offerFilterBar');\n  var html = '<span class=\"filter-label\">Filter:<\/span>';\n  html += '<span class=\"ftab'+(activeOfferFilter===''?' all-on':'')+'\" onclick=\"setOfferFilter(\\'\\')\">All<\/span>';\n  offers.forEach(function(o){\n    html += '<span class=\"ftab'+(activeOfferFilter===o.nights?' on':'')+'\" onclick=\"setOfferFilter(\\''+o.nights+'\\')\">'+esc(o.label||o.nights+' Nights')+'<\/span>';\n  });\n  cont.innerHTML = html;\n}\n\nfunction getGroupRooms(ga) {\n  var rooms={}, order=[];\n  ga.forEach(function(p){\n    var rid = p.roomId||'default';\n    if (!rooms[rid]) { rooms[rid]={roomId:rid, room:p.room, members:[]}; order.push(rid); }\n    rooms[rid].members.push(p);\n  });\n  return order.map(function(rid){ return rooms[rid]; });\n}\n\nfunction renderTable() {\n  var facEnabled = isFacEnabled();\n  var tbl = document.getElementById('mainTable');\n  tbl.classList.toggle('fac-disabled', !facEnabled);\n  var _at = getActiveTour();\n  tbl.classList.toggle('hide-city', !!(_at && _at.showCity===false));\n  var body  = document.getElementById('tBody');\n  var search= document.getElementById('srch').value.toLowerCase();\n  var all   = passengers.filter(function(p){return p.tourId===activeTourId;});\n  var totalEur = all.reduce(function(s,p){return s+p.price;},0);\n  var facCount = facEnabled ? all.filter(function(p){return p.facultative;}).length : 0;\n  var facEur   = facEnabled ? all.filter(function(p){return p.facultative;}).reduce(function(s,p){return s+facPriceFor(p);},0) : 0;\n\n  var t = getActiveTour();\n  var offers = getTourOffers(t);\n  var byNights = {};\n  all.forEach(function(p){ byNights[p.nights]=(byNights[p.nights]||0)+1; });\n  var nightsChips='';\n  offers.forEach(function(o){\n    if(byNights[o.nights]) nightsChips+='<span class=\"stat-chip\"><strong>'+byNights[o.nights]+'<\/strong> on '+esc(o.label||o.nights+' Nights')+'<\/span>';\n  });\n  document.getElementById('statsBar').innerHTML=\n    '<span class=\"stat-chip\">Passengers <strong>'+all.length+'<\/strong><\/span>'+\n    '<span class=\"stat-chip\">Revenue <strong>\u20ac'+(totalEur===Math.round(totalEur)?totalEur:totalEur.toFixed(2))+'<\/strong><\/span>'+\n    (facEnabled&&facCount?'<span class=\"stat-chip\" style=\"border-color:#c4b5fd;background:#f5f3ff\">Facultatives <strong style=\"color:#7c3aed\">'+facCount+' selected &middot; \u20ac'+facEur+'<\/strong><\/span>':'')+\n    nightsChips;\n  renderOfferFilter();\n  if (!activeTourId){body.innerHTML=emptyRow('Select or create a tour to get started.');return;}\n\n  var list=all.slice();\n  if (activeOfferFilter) list=list.filter(function(p){return p.nights===activeOfferFilter;});\n  if (search) list=list.filter(function(p){\n    return [p.name,p.dob,p.passport,p.city,p.room,p.phone,p.notes,TYPE_LABELS[p.type]].join(' ').toLowerCase().indexOf(search)>=0;\n  });\n  if (!list.length){body.innerHTML=emptyRow('No passengers found.');return;}\n\n  \/\/ Pre-pass: assign global sequential room numbers across all groups\n  var globalRoomNumMap = {}; \/\/ roomId -> global room number\n  var allTourRooms = [];     \/\/ [{roomId, roomNum, room, groupId}] for move dropdown\n  var _grn = 0, _seenG = {};\n  all.forEach(function(p){\n    if (_seenG[p.groupId]) return;\n    _seenG[p.groupId] = true;\n    getGroupRooms(all.filter(function(x){return x.groupId===p.groupId;})).forEach(function(rg){\n      _grn++;\n      globalRoomNumMap[rg.roomId] = _grn;\n      allTourRooms.push({roomId:rg.roomId, roomNum:_grn, room:rg.room, groupId:p.groupId});\n    });\n  });\n\n  var html=[], seen={}, rowNum=0;\n  list.forEach(function(p){\n    if (seen[p.groupId]) return;\n    seen[p.groupId]=true;\n    var gm   = list.filter(function(x){return x.groupId===p.groupId;});\n    var ga   = all.filter(function(x){return x.groupId===p.groupId;});\n    var gTotal     = ga.reduce(function(s,x){return s+x.price;},0);\n    var gFacCount  = facEnabled?ga.filter(function(x){return x.facultative;}).length:0;\n    var gFacTotal  = facEnabled?ga.filter(function(x){return x.facultative;}).reduce(function(s,x){return s+facPriceFor(x);},0):0;\n    var gFacPotential = facEnabled?ga.reduce(function(s,x){return s+facPriceFor(x);},0):0;\n\n    var first = ga[0];\n    var offerLabel=(function(){var o=getTourOffers(getActiveTour()).filter(function(o){return o.nights===first.nights;})[0];return o?(o.label||o.nights+' Nights'):first.nights+' Nights';})();\n\n    var tourIsRoom = (getActiveTour()&&getActiveTour().tourType==='room');\n\n    if (!tourIsRoom) {\n      \/\/ Group header \u2014 no room pills, just count + offer + phone\n      html.push(\n        '<tr class=\"group-hdr\" data-group=\"'+p.groupId+'\">'+\n          '<td colspan=\"4\"><div class=\"ghdr-main\">'+\n            '<span>'+(ga.length===1?'&#128100;':'&#128101;')+' <strong>'+(ga.length===1?'1 passenger':ga.length+' passengers')+'<\/strong><\/span>'+\n            '<span class=\"offer-pill\">'+esc(offerLabel)+'<\/span>'+\n            (first.phone?'<span class=\"hotel-no-print\" style=\"font-size:.77rem;color:var(--gray-600);font-weight:500\">&#128222; '+esc(first.phone)+'<\/span>':'')+\n          '<\/div><\/td>'+\n          '<td class=\"no-print col-paxtype\"><\/td>'+\n          '<td class=\"no-print hotel-no-print col-paxphone\"><\/td>'+\n          '<td class=\"col-city\"><\/td>'+\n          '<td class=\"col-price\" style=\"text-align:right\"><span class=\"ghdr-total\">\u20ac'+(gTotal===Math.round(gTotal)?gTotal:gTotal.toFixed(2))+'<\/span> <span style=\"font-size:.7rem;color:var(--gray-500)\">total<\/span>'+(first.notes?'<br\/><span class=\"ghdr-note\">'+esc(first.notes)+'<\/span>':'')+'<\/td>'+\n          '<td class=\"col-fac\" style=\"text-align:center\">'+(gFacCount>0?'<span style=\"font-size:.92rem;font-weight:800;color:#7c3aed\">\u20ac'+gFacTotal+'<\/span> <span style=\"font-size:.7rem;color:var(--gray-500)\">fac<\/span><br\/><span style=\"font-size:.7rem;color:#7c3aed\">'+gFacCount+'\/'+ga.length+' &#10003;<\/span>':'<span style=\"font-size:.92rem;font-weight:800;color:#c4b5fd\">\u20ac'+gFacPotential+'<\/span> <span style=\"font-size:.7rem;color:#c4b5fd\">fac<\/span>')+'<\/td>'+\n          '<td class=\"no-print\" style=\"white-space:nowrap\">'+\n            '<button class=\"btn btn-outline btn-sm\" onclick=\"editGroup(\\''+p.groupId+'\\')\">Edit<\/button>'+\n            '<button class=\"btn btn-danger btn-sm\" style=\"margin-left:3px\" onclick=\"deleteGroup(\\''+p.groupId+'\\')\">Del<\/button>'+\n          '<\/td>'+\n        '<\/tr>'\n      );\n    }\n\n    \/\/ Room sub-headers and members\n    var gmRooms = getGroupRooms(gm);\n    var multiRoomsInGroup = gmRooms.length > 1;\n\n    gmRooms.forEach(function(roomGroup){\n      var rm = roomGroup.members;\n      var rcls = ROOM_CLS[roomGroup.room]||'';\n      var rNum = globalRoomNumMap[roomGroup.roomId] || 1;\n      var rTotal = rm.reduce(function(s,x){return s+x.price;},0);\n      var rFacCount = facEnabled?rm.filter(function(x){return x.facultative;}).length:0;\n      var rFacTotal = facEnabled?rm.filter(function(x){return x.facultative;}).reduce(function(s,x){return s+facPriceFor(x);},0):0;\n\n      \/\/ Room-based tour: room header carries offer, phone, total and edit\/del buttons\n      \/\/ Group-based tour: simple room sub-header as before\n      if (tourIsRoom) {\n        html.push(\n          '<tr class=\"group-hdr\" data-group=\"'+p.groupId+'\">'+\n            '<td colspan=\"4\"><div class=\"ghdr-main\">'+\n              '<svg width=\"13\" height=\"13\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"#b45309\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z\"\/><\/svg>'+\n              '<span style=\"font-weight:800;color:#92400e;font-size:.78rem\">Room '+rNum+'<\/span>'+\n              '<span class=\"room-pill '+rcls+'\">'+esc(roomGroup.room)+'<\/span>'+\n              '<span class=\"offer-pill\">'+esc(offerLabel)+'<\/span>'+\n              (first.phone?'<span class=\"hotel-no-print\" style=\"font-size:.77rem;color:var(--gray-600);font-weight:500\">&#128222; '+esc(first.phone)+'<\/span>':'')+\n            '<\/div><\/td>'+\n            '<td class=\"no-print col-paxtype\"><\/td>'+\n            '<td class=\"no-print hotel-no-print col-paxphone\"><\/td>'+\n            '<td class=\"col-city\"><\/td>'+\n            '<td class=\"col-price\" style=\"text-align:right\"><span class=\"ghdr-total\">\u20ac'+(rTotal===Math.round(rTotal)?rTotal:rTotal.toFixed(2))+'<\/span> <span style=\"font-size:.7rem;color:var(--gray-500)\">total<\/span>'+(first.notes?'<br\/><span class=\"ghdr-note\">'+esc(first.notes)+'<\/span>':'')+'<\/td>'+\n            '<td class=\"col-fac\" style=\"text-align:center\">'+(rFacCount>0?'<span style=\"font-size:.82rem;font-weight:800;color:#7c3aed\">\u20ac'+rFacTotal+'<\/span> <span style=\"font-size:.7rem;color:var(--gray-500)\">fac<\/span>':'')+'<\/td>'+\n            '<td class=\"no-print\" style=\"white-space:nowrap\">'+\n              '<button class=\"btn btn-outline btn-sm\" onclick=\"editGroup(\\''+p.groupId+'\\')\">Edit<\/button>'+\n              '<button class=\"btn btn-danger btn-sm\" style=\"margin-left:3px\" onclick=\"deleteGroup(\\''+p.groupId+'\\')\">Del<\/button>'+\n            '<\/td>'+\n          '<\/tr>'\n        );\n      } else {\n        html.push(\n          '<tr class=\"room-hdr\">'+\n            '<td colspan=\"4\"><div class=\"rhdr-main\">'+\n              '<svg width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z\"\/><\/svg>'+\n              '<span style=\"font-weight:800;color:#92400e;font-size:.78rem\">Room '+rNum+'<\/span>'+\n              '<span class=\"room-pill '+rcls+'\">'+esc(roomGroup.room)+'<\/span>'+\n            '<\/div><\/td>'+\n            '<td class=\"no-print col-paxtype\"><\/td>'+\n            '<td class=\"no-print hotel-no-print col-paxphone\"><\/td>'+\n            '<td class=\"col-city\"><\/td>'+\n            '<td class=\"col-price\" style=\"text-align:right\"><span class=\"rhdr-total\">\u20ac'+(rTotal===Math.round(rTotal)?rTotal:rTotal.toFixed(2))+'<\/span><\/td>'+\n            '<td class=\"col-fac\" style=\"text-align:center\">'+(rFacCount>0?'<span style=\"font-size:.82rem;font-weight:700;color:#7c3aed\">\u20ac'+rFacTotal+' fac<\/span>':'')+'<\/td>'+\n            '<td class=\"no-print\"><\/td>'+\n          '<\/tr>'\n        );\n      }\n\n      rm.forEach(function(m){\n        rowNum++;\n        html.push(\n          '<tr class=\"group-mem in-sub\">'+\n            '<td style=\"color:var(--gray-400);font-weight:600\">'+rowNum+'<\/td>'+\n            '<td><strong>'+esc(m.name)+'<\/strong><\/td>'+\n            '<td>'+fmtDob(m.dob)+'<\/td>'+\n            '<td style=\"font-family:monospace;font-size:.78rem\">'+(esc(m.passport)||dash())+'<\/td>'+\n            '<td class=\"no-print col-paxtype\"><span class=\"type-pill '+(TYPE_CLS[m.type]||'')+'\">'+TYPE_LABELS[m.type]+'<\/span><\/td>'+\n            '<td class=\"no-print hotel-no-print col-paxphone\">'+(m.paxPhone?'<span style=\"font-size:.78rem;color:var(--gray-600)\">'+esc(m.paxPhone)+'<\/span>':'')+'<\/td>'+\n            '<td class=\"col-city\">'+(m.city?'<span style=\"font-size:.78rem;font-weight:600;color:var(--blue)\">'+esc(m.city)+'<\/span>':dash())+'<\/td>'+\n            '<td class=\"col-price\" style=\"font-weight:700;color:'+(m.customPrice!=null?'var(--orange)':'var(--green)')+'\">'+fmtP(m.price)+(m.customPrice!=null?' <span style=\"font-size:.63rem;background:#fef3c7;color:#92400e;border-radius:4px;padding:1px 5px;font-weight:700;vertical-align:middle\">special<\/span>':'')+'<\/td>'+\n            '<td class=\"col-fac\" style=\"text-align:center\"><label class=\"fac-label\"><input type=\"checkbox\" '+(m.facultative?'checked':'')+' onchange=\"toggleFac(\\''+m.id+'\\')\"\/> <span>'+(m.facultative?'<span class=\"fac-yes\">'+fmtFac(m)+'<\/span>':fmtFac(m))+'<\/span><\/label><\/td>'+\n            '<td class=\"no-print\" style=\"white-space:nowrap\"><button class=\"btn btn-outline btn-sm\" onclick=\"openPaxModal(\\''+m.id+'\\')\">Edit<\/button><\/td>'+\n          '<\/tr>'\n        );\n      });\n    });\n  });\n  body.innerHTML=html.join('');\n}\n\n\/* \u2500\u2500 Passenger edit modal \u2500\u2500 *\/\nvar editingPaxId = null;\nfunction buildAllTourRooms() {\n  \/\/ Returns [{roomId, roomNum, room, groupId}] in global order (same as renderTable pre-pass)\n  var result = [], num = 0, seen = {};\n  passengers.filter(function(p){ return p.tourId===activeTourId; }).forEach(function(p){\n    if (seen[p.groupId]) return;\n    seen[p.groupId] = true;\n    getGroupRooms(passengers.filter(function(x){ return x.tourId===activeTourId&&x.groupId===p.groupId; }))\n      .forEach(function(rg){ num++; result.push({roomId:rg.roomId, roomNum:num, room:rg.room, groupId:p.groupId}); });\n  });\n  return result;\n}\nfunction onPeRoomChange() {\n  var val = document.getElementById('pe_room').value;\n  var wrap = document.getElementById('pe_newroom_wrap');\n  wrap.style.display = val === '__new__' ? '' : 'none';\n}\nfunction openPaxModal(paxId) {\n  var pax = passengers.filter(function(p){ return p.id===paxId; })[0];\n  if (!pax) return;\n  editingPaxId = paxId;\n  document.getElementById('pe_name').value     = pax.name     || '';\n  document.getElementById('pe_dob').value      = pax.dob      || '';\n  document.getElementById('pe_passport').value = pax.passport || '';\n  document.getElementById('pe_cp').value       = pax.customPrice != null ? pax.customPrice : '';\n  \/\/ Show \/ hide city and pax-phone fields based on tour settings\n  var _t = getActiveTour();\n  var _showCity = !_t || _t.showCity !== false;\n  var _paxPhone = !!(_t && _t.paxPhone);\n  document.getElementById('pe_city').closest('.form-group').style.display = _showCity ? '' : 'none';\n  var ppRow = document.getElementById('pe_paxphone_row');\n  if (ppRow) ppRow.style.display = _paxPhone ? '' : 'none';\n  if (_paxPhone) document.getElementById('pe_paxphone').value = pax.paxPhone || '';\n  \/\/ City options\n  var cities = getTourCities(getActiveTour());\n  document.getElementById('pe_city').innerHTML = cities.map(function(c){\n    return '<option value=\"'+c+'\"'+(c===pax.city?' selected':'')+'>'+c+'<\/option>';\n  }).join('');\n  \/\/ Type options\n  var types = getTourTypes(getActiveTour());\n  var TYPE_DEFS = [{id:'adult',label:'Adult'},{id:'child_same',label:'Child (same bed)'},{id:'child_sep',label:'Child (own bed)'},{id:'infant',label:'Infant (0\u20132)'}];\n  document.getElementById('pe_type').innerHTML = TYPE_DEFS.filter(function(d){ return types.indexOf(d.id)>=0; }).map(function(d){\n    return '<option value=\"'+d.id+'\"'+(d.id===pax.type?' selected':'')+'>'+d.label+'<\/option>';\n  }).join('');\n  \/\/ Room options\n  var tourRooms = buildAllTourRooms();\n  document.getElementById('pe_room').innerHTML =\n    tourRooms.map(function(r){\n      return '<option value=\"'+r.roomId+'\"'+(r.roomId===pax.roomId?' selected':'')+'>Room '+r.roomNum+' &mdash; '+esc(r.room)+'<\/option>';\n    }).join('') +\n    '<option value=\"__new__\">\uff0b New room&hellip;<\/option>';\n  \/\/ New room type options\n  var roomOpts = getTourRooms(getActiveTour());\n  document.getElementById('pe_newroom_type').innerHTML =\n    '<option value=\"\">\u2014 Select type \u2014<\/option>' +\n    roomOpts.map(function(r){ return '<option value=\"'+r+'\">'+r+'<\/option>'; }).join('');\n  document.getElementById('pe_newroom_wrap').style.display = 'none';\n  document.getElementById('paxModal').classList.add('open');\n  setTimeout(function(){ document.getElementById('pe_name').focus(); }, 50);\n}\nfunction closePaxModal() {\n  document.getElementById('paxModal').classList.remove('open');\n  editingPaxId = null;\n}\nfunction savePaxModal() {\n  var name = document.getElementById('pe_name').value.trim();\n  if (!name) { alert('Name is required.'); return; }\n  var pax = passengers.filter(function(p){ return p.id===editingPaxId; })[0];\n  if (!pax) return;\n  pax.name     = name;\n  pax.dob      = document.getElementById('pe_dob').value;\n  pax.passport = document.getElementById('pe_passport').value.trim();\n  var _cEl = document.getElementById('pe_city');\n  if (_cEl && _cEl.closest('.form-group').style.display !== 'none') pax.city = _cEl.value;\n  var _ppEl = document.getElementById('pe_paxphone');\n  if (_ppEl && document.getElementById('pe_paxphone_row').style.display !== 'none') pax.paxPhone = _ppEl.value.trim();\n  pax.type     = document.getElementById('pe_type').value;\n  var cpRaw    = document.getElementById('pe_cp').value.trim();\n  pax.customPrice = cpRaw !== '' ? parseFloat(cpRaw) : null;\n  \/\/ Room assignment\n  var roomSel = document.getElementById('pe_room').value;\n  if (roomSel === '__new__') {\n    var newRoomType = document.getElementById('pe_newroom_type').value;\n    if (!newRoomType) { alert('Please select a room type for the new room.'); return; }\n    var newRoomId = 'room_'+Date.now()+'_new';\n    pax.roomId  = newRoomId;\n    pax.room    = newRoomType;\n    \/\/ new room stays in the same group\n  } else if (roomSel && roomSel !== pax.roomId) {\n    \/\/ Move to existing room (possibly cross-group)\n    var target = passengers.filter(function(p){ return p.tourId===pax.tourId && p.roomId===roomSel; })[0];\n    if (target) {\n      pax.roomId  = target.roomId;\n      pax.room    = target.room;\n      pax.groupId = target.groupId;\n    }\n  }\n  \/\/ Recalculate tier + price\n  var roomMates = passengers.filter(function(p){ return p.tourId===pax.tourId && p.roomId===pax.roomId && p.id!==pax.id; });\n  roomMates.push(pax);\n  var adultCount = roomMates.filter(function(p){ return p.type==='adult'||p.type==='child_sep'; }).length;\n  var tier = adultCount >= 2 ? 'group' : 'solo';\n  pax.price = pax.customPrice !== null ? pax.customPrice : priceFor(pax.type, pax.nights, tier);\n  save(); closePaxModal(); renderTable(); toast('Passenger updated.');\n}\n\nfunction toggleFac(id){\n  var p=passengers.filter(function(x){return x.id===id;})[0];\n  if(!p)return;\n  p.facultative=!p.facultative;\n  save(); renderTable();\n}\nfunction setOfferFilter(v){activeOfferFilter=v;renderTable();}\nfunction dash(){return '<span style=\"color:var(--gray-300)\">&#8212;<\/span>';}\nfunction fmtDob(d){\n  if(!d)return dash();\n  var parts=d.split('-');\n  if(parts.length!==3)return d;\n  return parts[2]+'\/'+parts[1]+'\/'+parts[0];\n}\nfunction emptyRow(msg){\n  return '<tr><td colspan=\"9\"><div class=\"empty-state\">'+\n    '<svg width=\"34\" height=\"34\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"1.2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0\"\/><\/svg>'+\n    '<p>'+msg+'<\/p><\/div><\/td><\/tr>';\n}\n\n\/* \u2500\u2500 Tour select \u2500\u2500 *\/\nfunction renderTourSelect(){\n  var sel=document.getElementById('tourSel');\n  sel.innerHTML='<option value=\"\">&#8212; Select a tour &#8212;<\/option>';\n  tours.forEach(function(t){\n    var o=document.createElement('option');\n    o.value=t.id; o.textContent=t.name+(t.date?' ('+fmtDob(t.date)+')':'');\n    if(t.id===activeTourId) o.selected=true;\n    sel.appendChild(o);\n  });\n  var badge=document.getElementById('tourBadge'),del=document.getElementById('delTourBtn'),edt=document.getElementById('editTourBtn');\n  if(activeTourId){\n    var t=tours.filter(function(x){return x.id===activeTourId;})[0];\n    if(t){badge.textContent='\\u2708 '+t.name+(t.date?' \\u00b7 '+fmtDob(t.date):'');badge.style.display='';}\n    del.style.display='';edt.style.display='';\n  } else {badge.style.display='none';del.style.display='none';edt.style.display='none';}\n}\nfunction switchTour(){\n  activeTourId=document.getElementById('tourSel').value||null;\n  activeOfferFilter='';\n  save();renderTourSelect();renderFormOffers();renderTable();\n  closeGroupModal();\n}\n\n\/* \u2500\u2500 Tour CRUD \u2500\u2500 *\/\nfunction openTourModal(){\n  editingTourId=null;\n  tmOffers=defaultTMOffers();\n  tmTypes=ALL_TYPES.slice();\n  tmCities=getAllCities().slice();\n  tmRooms=getAllRooms().slice();\n  tmFac=defaultTMFac(tmOffers);\n  document.getElementById('tName').value='';\n  document.getElementById('tDate').value='';\n  document.getElementById('tCheckin').value='';\n  document.getElementById('tTypeGroup').checked=true;\n  document.getElementById('tShowCity').checked=true;\n  document.getElementById('tPaxPhone').checked=false;\n  document.getElementById('tourModalHead').querySelector('span').textContent='New Tour';\n  document.getElementById('tourModalSaveBtn').textContent='Create';\n  renderTMOffers(); renderTMTypes(); renderTMCities(); renderTMRooms(); renderTMFac();\n  document.getElementById('tourModal').classList.add('open');\n  setTimeout(function(){document.getElementById('tName').focus();},50);\n}\nfunction openEditTourModal(){\n  if(!activeTourId)return;\n  var t=tours.filter(function(x){return x.id===activeTourId;})[0];\n  if(!t)return;\n  editingTourId=activeTourId;\n  tmOffers=t.offers?JSON.parse(JSON.stringify(t.offers)):defaultTMOffers();\n  tmTypes=t.enabledTypes?t.enabledTypes.slice():ALL_TYPES.slice();\n  tmCities=t.availableCities?t.availableCities.slice():ALL_CITIES.slice();\n  tmRooms=t.availableRooms?t.availableRooms.slice():getAllRooms().slice();\n  tmFac=t.facultative?JSON.parse(JSON.stringify(t.facultative)):defaultTMFac(tmOffers);\n  document.getElementById('tName').value=t.name||'';\n  document.getElementById('tDate').value=t.date||'';\n  document.getElementById('tCheckin').value=t.checkin||'';\n  document.getElementById(t.tourType==='room'?'tTypeRoom':'tTypeGroup').checked=true;\n  document.getElementById('tShowCity').checked = t.showCity !== false;\n  document.getElementById('tPaxPhone').checked = !!t.paxPhone;\n  document.getElementById('tourModalHead').querySelector('span').textContent='Edit Tour';\n  document.getElementById('tourModalSaveBtn').textContent='Save Changes';\n  renderTMOffers(); renderTMTypes(); renderTMCities(); renderTMRooms(); renderTMFac();\n  document.getElementById('tourModal').classList.add('open');\n  setTimeout(function(){document.getElementById('tName').focus();},50);\n}\nfunction closeTourModal(){\n  document.getElementById('tourModal').classList.remove('open');\n}\nfunction saveTour(){\n  saveTMInputs();\n  var name=document.getElementById('tName').value.trim();\n  var date=document.getElementById('tDate').value;\n  var checkin=document.getElementById('tCheckin').value;\n  if(!name){alert('Tour name is required.');return;}\n  if(!tmOffers.length){alert('At least one offer is required.');return;}\n  for(var i=0;i<tmOffers.length;i++){\n    if(!tmOffers[i].nights){alert('All offers must have a nights value.');return;}\n    if(!tmOffers[i].label){tmOffers[i].label=tmOffers[i].nights+' Nights';}\n  }\n  if(!tmTypes.length){alert('Select at least one passenger type.');return;}\n  if(!tmCities.length){alert('Select at least one departure city.');return;}\n  if(!tmRooms.length){alert('Select at least one room type.');return;}\n  var tourType=document.querySelector('input[name=\"tTourType\"]:checked').value;\n  var showCity=document.getElementById('tShowCity').checked;\n  var paxPhone=document.getElementById('tPaxPhone').checked;\n  var data={name:name,date:date,checkin:checkin,tourType:tourType,showCity:showCity,paxPhone:paxPhone,\n    offers:JSON.parse(JSON.stringify(tmOffers)),\n    enabledTypes:tmTypes.slice(),\n    availableCities:tmCities.slice(),\n    availableRooms:tmRooms.slice(),\n    facultative:JSON.parse(JSON.stringify(tmFac))};\n  if(editingTourId){\n    var t=tours.filter(function(x){return x.id===editingTourId;})[0];\n    if(t){t.name=data.name;t.date=data.date;t.checkin=data.checkin;t.tourType=data.tourType;t.showCity=data.showCity;t.paxPhone=data.paxPhone;t.offers=data.offers;t.enabledTypes=data.enabledTypes;t.availableCities=data.availableCities;t.availableRooms=data.availableRooms;t.facultative=data.facultative;}\n    save();closeTourModal();renderTourSelect();renderFormOffers();renderTable();toast('Tour updated!');\n  } else {\n    var nt=Object.assign({id:'tour_'+Date.now()},data);\n    tours.push(nt);activeTourId=nt.id;\n    save();closeTourModal();renderTourSelect();renderFormOffers();renderTable();toast('Tour \"'+name+'\" created!');\n  }\n}\nfunction deleteTour(){\n  if(!activeTourId)return;\n  var t=tours.filter(function(x){return x.id===activeTourId;})[0];\n  var cnt=passengers.filter(function(p){return p.tourId===activeTourId;}).length;\n  if(!confirm('Delete tour \"'+t.name+'\"?'+(cnt?' Also removes '+cnt+' passenger(s).':'')))return;\n  passengers=passengers.filter(function(p){return p.tourId!==activeTourId;});\n  tours=tours.filter(function(x){return x.id!==activeTourId;});\n  activeTourId=tours.length?tours[0].id:null;\n  save();renderTourSelect();renderFormOffers();renderTable();toast('Tour deleted.');\n}\n\n\/* \u2500\u2500 Tour Modal Rendering \u2500\u2500 *\/\nfunction renderTMOffers(){\n  var cont=document.getElementById('tmOffersContainer');\n  if(!tmOffers.length){\n    cont.innerHTML='<p style=\"color:var(--gray-400);font-size:.8rem;text-align:center;padding:12px\">No offers yet. Add one above.<\/p>';\n    return;\n  }\n  var activeTypes=tmTypes.length?tmTypes:ALL_TYPES;\n  var rows=tmOffers.map(function(o,i){\n    var paxRows=activeTypes.map(function(tp){\n      return '<tr>'+\n        '<td style=\"font-size:.78rem;white-space:nowrap\">'+TYPE_LABELS_LONG[tp]+'<\/td>'+\n        '<td><input type=\"number\" min=\"0\" class=\"tm-price-input\" data-offer=\"'+i+'\" data-tier=\"solo\" data-type=\"'+tp+'\" value=\"'+(o.solo&&o.solo[tp]!==undefined?o.solo[tp]:0)+'\" style=\"width:70px\"\/><\/td>'+\n        '<td><input type=\"number\" min=\"0\" class=\"tm-price-input\" data-offer=\"'+i+'\" data-tier=\"group\" data-type=\"'+tp+'\" value=\"'+(o.group&&o.group[tp]!==undefined?o.group[tp]:0)+'\" style=\"width:70px\"\/><\/td>'+\n      '<\/tr>';\n    }).join('');\n    return '<div class=\"offer-card\">'+\n      '<div style=\"display:flex;align-items:center;gap:8px;margin-bottom:9px;flex-wrap:wrap\">'+\n        '<div style=\"flex:1;min-width:160px;display:flex;align-items:center;gap:7px\">'+\n          '<label style=\"white-space:nowrap;margin:0;font-size:.74rem\">Label:<\/label>'+\n          '<input type=\"text\" class=\"tm-offer-label\" data-offer=\"'+i+'\" value=\"'+esc(o.label||'')+'\" placeholder=\"e.g. 2 Nights\" style=\"flex:1\"\/>'+\n        '<\/div>'+\n        '<div style=\"display:flex;align-items:center;gap:7px\">'+\n          '<label style=\"white-space:nowrap;margin:0;font-size:.74rem\">Nights:<\/label>'+\n          '<input type=\"text\" class=\"tm-offer-nights\" data-offer=\"'+i+'\" value=\"'+esc(o.nights||'')+'\" placeholder=\"2\" style=\"width:52px\"\/>'+\n        '<\/div>'+\n        (tmOffers.length>1?'<button type=\"button\" class=\"btn btn-danger btn-sm\" onclick=\"removeTMOffer('+i+')\">Remove<\/button>':'')+\n      '<\/div>'+\n      '<table class=\"tm-price-table\">'+\n        '<thead><tr><th style=\"text-align:left\">Type<\/th><th>Solo Rate \u20ac<\/th><th>Group Rate \u20ac<\/th><\/tr><\/thead>'+\n        '<tbody>'+paxRows+'<\/tbody>'+\n      '<\/table>'+\n    '<\/div>';\n  }).join('');\n  cont.innerHTML=rows;\n}\nfunction renderTMTypes(){\n  var cont=document.getElementById('tmTypesContainer');\n  var defs=[{id:'adult',label:'Adult'},{id:'child_same',label:'Child (same bed)'},{id:'child_sep',label:'Child (own bed)'},{id:'infant',label:'Infant (0\u20132)'}];\n  cont.innerHTML=defs.map(function(tp){\n    var on=tmTypes.indexOf(tp.id)>=0;\n    return '<span class=\"type-check-pill'+(on?' active':'')+'\" onclick=\"toggleTMType(\\''+tp.id+'\\',this)\" style=\"cursor:pointer\">'+\n      '<input type=\"checkbox\" value=\"'+tp.id+'\" '+(on?'checked':'')+' style=\"pointer-events:none;width:14px;height:14px;margin:0\"\/>'+\n      tp.label+\n    '<\/span>';\n  }).join('');\n}\nfunction toggleTMType(id, el){\n  saveTMInputs();\n  var idx=tmTypes.indexOf(id);\n  if(idx>=0) tmTypes.splice(idx,1); else tmTypes.push(id);\n  el.classList.toggle('active',tmTypes.indexOf(id)>=0);\n  el.querySelector('input').checked=tmTypes.indexOf(id)>=0;\n  renderTMOffers(); renderTMFac();\n}\nfunction renderTMCities(){\n  var cont=document.getElementById('tmCitiesContainer');\n  var custom=customCities;\n  cont.innerHTML=getAllCities().map(function(city){\n    var on=tmCities.indexOf(city)>=0;\n    var isCustom=custom.indexOf(city)>=0;\n    var removeBtn=isCustom\n      ? '<span onclick=\"event.stopPropagation();removeTMCity(\\''+city+'\\')\" title=\"Remove city\" style=\"margin-left:4px;opacity:.6;font-size:.8rem;line-height:1;cursor:pointer\">\u2715<\/span>'\n      : '';\n    return '<span class=\"type-check-pill'+(on?' active':'')+'\" onclick=\"toggleTMCity(\\''+city+'\\',this)\" style=\"cursor:pointer\">'+\n      '<input type=\"checkbox\" value=\"'+city+'\" '+(on?'checked':'')+' style=\"pointer-events:none;width:14px;height:14px;margin:0\"\/>'+\n      city+removeBtn+\n    '<\/span>';\n  }).join('');\n}\nfunction toggleTMCity(city, el){\n  var idx=tmCities.indexOf(city);\n  if(idx>=0) tmCities.splice(idx,1); else tmCities.push(city);\n  el.classList.toggle('active',tmCities.indexOf(city)>=0);\n  el.querySelector('input').checked=tmCities.indexOf(city)>=0;\n}\nfunction addTMCity(){\n  var input=document.getElementById('tmNewCity');\n  var city=input.value.trim();\n  if(!city){return;}\n  if(getAllCities().indexOf(city)>=0){toast('City already in the list.');return;}\n  customCities.push(city);\n  localStorage.setItem('tpm5_cities',JSON.stringify(customCities));\n  if(tmCities.indexOf(city)<0) tmCities.push(city);\n  input.value='';\n  renderTMCities();\n}\nfunction removeTMCity(city){\n  var ci=customCities.indexOf(city);\n  if(ci>=0){ customCities.splice(ci,1); localStorage.setItem('tpm5_cities',JSON.stringify(customCities)); }\n  var ti=tmCities.indexOf(city);\n  if(ti>=0) tmCities.splice(ti,1);\n  renderTMCities();\n}\nfunction renderTMRooms(){\n  var cont=document.getElementById('tmRoomsContainer');\n  cont.innerHTML=getAllRooms().map(function(room){\n    var on=tmRooms.indexOf(room)>=0;\n    var isCustom=customRooms.indexOf(room)>=0;\n    var removeBtn=isCustom\n      ? '<span onclick=\"event.stopPropagation();removeTMRoom(\\''+room.replace(\/'\/g,\"\\\\'\")+'\\')\" title=\"Remove room type\" style=\"margin-left:4px;opacity:.6;font-size:.8rem;line-height:1;cursor:pointer\">\u2715<\/span>'\n      : '';\n    return '<span class=\"type-check-pill'+(on?' active':'')+'\" onclick=\"toggleTMRoom(\\''+room.replace(\/'\/g,\"\\\\'\")+'\\',this)\" style=\"cursor:pointer\">'+\n      '<input type=\"checkbox\" value=\"'+room+'\" '+(on?'checked':'')+' style=\"pointer-events:none;width:14px;height:14px;margin:0\"\/>'+\n      room+removeBtn+\n    '<\/span>';\n  }).join('');\n}\nfunction toggleTMRoom(room, el){\n  var idx=tmRooms.indexOf(room);\n  if(idx>=0) tmRooms.splice(idx,1); else tmRooms.push(room);\n  el.classList.toggle('active',tmRooms.indexOf(room)>=0);\n  el.querySelector('input').checked=tmRooms.indexOf(room)>=0;\n}\nfunction addTMRoom(){\n  var input=document.getElementById('tmNewRoom');\n  var room=input.value.trim();\n  if(!room){return;}\n  if(getAllRooms().indexOf(room)>=0){toast('Room type already in the list.');return;}\n  customRooms.push(room);\n  localStorage.setItem('tpm5_rooms',JSON.stringify(customRooms));\n  if(tmRooms.indexOf(room)<0) tmRooms.push(room);\n  input.value='';\n  renderTMRooms();\n}\nfunction removeTMRoom(room){\n  var ci=customRooms.indexOf(room);\n  if(ci>=0){ customRooms.splice(ci,1); localStorage.setItem('tpm5_rooms',JSON.stringify(customRooms)); }\n  var ti=tmRooms.indexOf(room);\n  if(ti>=0) tmRooms.splice(ti,1);\n  renderTMRooms();\n}\nfunction renderTMFac(){\n  var cont=document.getElementById('tmFacContainer');\n  var enabled=tmFac&&tmFac.enabled!==false;\n  var html='<label style=\"display:flex;align-items:center;gap:8px;cursor:pointer;margin-bottom:10px\">'+\n    '<input type=\"checkbox\" id=\"tmFacEnabled\" '+(enabled?'checked':'')+' onchange=\"toggleTMFac()\" style=\"width:16px;height:16px\"\/>'+\n    '<span style=\"font-size:.85rem;font-weight:600\">Enable facultatives for this tour<\/span>'+\n  '<\/label>';\n  if(enabled&&tmOffers.length){\n    var prices=(tmFac&&tmFac.prices)||{};\n    var headerCols=tmOffers.map(function(o){return '<th>'+esc(o.label||o.nights+' N')+'<\/th>';}).join('');\n    var activeTypes=tmTypes.length?tmTypes:ALL_TYPES;\n    var bodyRows=activeTypes.map(function(tp){\n      var cols=tmOffers.map(function(o){\n        var val=(prices[o.nights]&&prices[o.nights][tp]!==undefined)?prices[o.nights][tp]:0;\n        return '<td><input type=\"number\" min=\"0\" class=\"tm-fac-input\" data-nights=\"'+o.nights+'\" data-type=\"'+tp+'\" value=\"'+val+'\" style=\"width:65px\"\/><\/td>';\n      }).join('');\n      return '<tr><td style=\"font-size:.78rem;white-space:nowrap\">'+TYPE_LABELS_LONG[tp]+'<\/td>'+cols+'<\/tr>';\n    }).join('');\n    html+='<table class=\"tm-price-table\">'+\n      '<thead><tr><th style=\"text-align:left\">Type<\/th>'+headerCols+'<\/tr><\/thead>'+\n      '<tbody>'+bodyRows+'<\/tbody>'+\n    '<\/table>';\n  }\n  cont.innerHTML=html;\n}\nfunction toggleTMFac(){\n  saveTMInputs();\n  if(!tmFac)tmFac={};\n  tmFac.enabled=document.getElementById('tmFacEnabled').checked;\n  if(tmFac.enabled&&(!tmFac.prices||!Object.keys(tmFac.prices).length)){\n    tmFac=defaultTMFac(tmOffers); tmFac.enabled=true;\n  }\n  renderTMFac();\n}\nfunction addTMOffer(){\n  saveTMInputs();\n  tmOffers.push({nights:'',label:'',solo:{adult:0,child_same:0,child_sep:0,infant:0},group:{adult:0,child_same:0,child_sep:0,infant:0}});\n  renderTMOffers(); renderTMFac();\n}\nfunction removeTMOffer(idx){\n  saveTMInputs(); tmOffers.splice(idx,1); renderTMOffers(); renderTMFac();\n}\nfunction saveTMInputs(){\n  document.querySelectorAll('.tm-offer-label').forEach(function(el){\n    var i=parseInt(el.dataset.offer); if(tmOffers[i])tmOffers[i].label=el.value;\n  });\n  document.querySelectorAll('.tm-offer-nights').forEach(function(el){\n    var i=parseInt(el.dataset.offer); if(tmOffers[i])tmOffers[i].nights=el.value;\n  });\n  document.querySelectorAll('.tm-price-input').forEach(function(el){\n    var i=parseInt(el.dataset.offer),tier=el.dataset.tier,type=el.dataset.type;\n    if(tmOffers[i]){if(!tmOffers[i][tier])tmOffers[i][tier]={};tmOffers[i][tier][type]=parseFloat(el.value)||0;}\n  });\n  if(!tmFac)tmFac={};\n  if(!tmFac.prices)tmFac.prices={};\n  document.querySelectorAll('.tm-fac-input').forEach(function(el){\n    var nights=el.dataset.nights,type=el.dataset.type;\n    if(!tmFac.prices[nights])tmFac.prices[nights]={};\n    tmFac.prices[nights][type]=parseFloat(el.value)||0;\n  });\n  var fe=document.getElementById('tmFacEnabled');\n  if(fe)tmFac.enabled=fe.checked;\n}\n\n\/* \u2500\u2500 Print \/ Export \u2500\u2500 *\/\nfunction printList(){\n  if(!activeTourId){alert('Select a tour first.');return;}\n  var t=tours.filter(function(x){return x.id===activeTourId;})[0];\n  document.getElementById('printTitle').textContent=t.name;\n  document.getElementById('printMeta').textContent=t.date?'Departure: '+fmtDob(t.date):'';\n  var offers=getTourOffers(t);\n  var fLabel=activeOfferFilter?(function(){var o=offers.filter(function(o){return o.nights===activeOfferFilter;})[0];return o?o.label:activeOfferFilter+' Nights';})():'';\n  document.getElementById('printFilter').textContent=fLabel?'Showing: '+fLabel+' only':'';\n  window.print();\n}\nfunction printHotel(){\n  if(!activeTourId){alert('Select a tour first.');return;}\n  var t=tours.filter(function(x){return x.id===activeTourId;})[0];\n  document.getElementById('printTitle').textContent=t.name+' \u2014 Hotel List';\n  document.getElementById('printMeta').textContent=t.checkin?'Check-in: '+fmtDob(t.checkin):(t.date?'Departure: '+fmtDob(t.date):'');\n  var offers=getTourOffers(t);\n  var fLabel=activeOfferFilter?(function(){var o=offers.filter(function(o){return o.nights===activeOfferFilter;})[0];return o?o.label:activeOfferFilter+' Nights';})():'';\n  document.getElementById('printFilter').textContent=fLabel?'Showing: '+fLabel+' only':'';\n  document.getElementById('tpm-app').classList.add('hotel-print');\n  window.print();\n  document.getElementById('tpm-app').classList.remove('hotel-print');\n}\nfunction exportCSV(){\n  if(!activeTourId){alert('Select a tour first.');return;}\n  var list=passengers.filter(function(p){return p.tourId===activeTourId;});\n  if(activeOfferFilter) list=list.filter(function(p){return p.nights===activeOfferFilter;});\n  if(!list.length){alert('No passengers to export.');return;}\n  var t=tours.filter(function(x){return x.id===activeTourId;})[0];\n  var offers=getTourOffers(t);\n  var gn={},g=0;\n  list.forEach(function(p){if(!gn[p.groupId])gn[p.groupId]=++g;});\n  var headers=['Group','#','Name','City','DOB','Passport','Type','Offer','Price','Facultative','Room','Phone','Notes'];\n  var rows=list.map(function(p,i){\n    var offerLabel=(function(){var o=offers.filter(function(o){return o.nights===p.nights;})[0];return o?o.label:p.nights+' Nights';})();\n    return [\n      'Group '+gn[p.groupId],i+1,p.name,p.city||'',p.dob?fmtDob(p.dob):'',p.passport,\n      TYPE_LABELS[p.type]||p.type, offerLabel, p.price===0?'FREE':'\u20ac'+p.price,\n      p.facultative?'Yes (\u20ac'+facPriceFor(p)+')':'No',p.room,p.phone,p.notes\n    ].map(function(v){return '\"'+String(v||'').replace(\/\"\/g,'\"\"')+'\"';}).join(',');\n  });\n  var csv=[headers.join(',')].concat(rows).join('\\n');\n  var a=document.createElement('a');\n  a.href='data:text\/csv;charset=utf-8,'+encodeURIComponent(csv);\n  a.download=((t?t.name:'tour').replace(\/\\s+\/g,'_'))+'_passengers.csv';\n  a.click(); toast('CSV exported!');\n}\n\n\/* \u2500\u2500 Utilities \u2500\u2500 *\/\nfunction esc(s){if(!s)return'';return String(s).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');}\nfunction toast(msg){var t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');clearTimeout(t._t);t._t=setTimeout(function(){t.classList.remove('show');},2500);}\n\n\/\/ Close modals on backdrop click\ndocument.getElementById('groupModal').addEventListener('click',function(e){if(e.target.id==='groupModal')closeGroupModal();});\ndocument.getElementById('tourModal').addEventListener('click',function(e){if(e.target.id==='tourModal')closeTourModal();});\ndocument.getElementById('paxModal').addEventListener('click',function(e){if(e.target.id==='paxModal')closePaxModal();});\n\n\/* \u2500\u2500 Init \u2500\u2500 *\/\nrenderTourSelect();\nrenderFormOffers();\nrenderTable();\n<\/script>\n<\/div>\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Tour Passenger Manager Tour Passenger Manager Smart pricing \u00b7 Multi-room groups \u00b7 Print &amp; Export Active Tour: \u2014 Select a tour \u2014 New Tour Edit Tour Delete Tour Passenger List Add Group Print Hotel CSV # Full Name Date of Birth Passport No. Passenger Type Phone City Price \/ pp Facultative Actions Add Group Add [&hellip;]<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"inline_featured_image":false,"footnotes":""},"class_list":["post-3045","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/pages\/3045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/comments?post=3045"}],"version-history":[{"count":19,"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/pages\/3045\/revisions"}],"predecessor-version":[{"id":3068,"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/pages\/3045\/revisions\/3068"}],"wp:attachment":[{"href":"https:\/\/bosfortours.com\/mk\/wp-json\/wp\/v2\/media?parent=3045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}