{"id":9986,"date":"2026-04-11T16:04:01","date_gmt":"2026-04-11T16:04:01","guid":{"rendered":"https:\/\/espacotalassa.com\/?page_id=9986"},"modified":"2026-08-22T10:28:49","modified_gmt":"2026-08-22T10:28:49","slug":"sightings-statistics-2","status":"publish","type":"page","link":"https:\/\/espacotalassa.com\/en\/research-education\/sightings-statistics-2\/","title":{"rendered":"Sightings &amp; Statistics"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>Cetaceans of the Azores<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Around <strong>90 species of cetaceans<\/strong>, whales, dolphins, and porpoises, inhabit our planet\u2019s seas, oceans, and even some rivers.<br>In the <strong>Azores<\/strong>, <strong>29 species<\/strong> have been officially recorded: an impressive number for such a small region in the middle of the Atlantic Ocean.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Every Trip is Unique<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On average, our guests encounter <strong>3 to 4 different species per trip<\/strong> (2024-2025), though record days have included <strong>up to 10 species in just 3 hours<\/strong>.<br>In <strong>99% of our excursions<\/strong>, we encounter cetaceans, a testament to the richness and vitality of Azorean waters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When planning your trip, remember that weekly statistics only offer a small glimpse of the ocean\u2019s reality.<br>Out here, every day is different. And every encounter is unforgettable.<\/p>\n\n\n\n<details class=\"wp-block-details is-layout-flow wp-block-details-is-layout-flow\"><summary>Learn more<\/summary>\n<h3 class=\"wp-block-heading\"><br><strong>Over 30 Years of Observation and Research<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Since <strong>1993<\/strong>, Espa\u00e7o Talassa has been collecting and organizing data from thousands of trips at sea.<br>Yet building precise statistics remains complex \u2014 each species has its own behaviour, preferred habitat, and migratory rhythm.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Sperm whales<\/strong> (Physeter macrocephalus) can be frequently seen just a few miles from the coast, some times very close (less then 3 miles) providing unique and close-up sightings.<\/li>\n\n\n\n<li><strong>Toothed whales<\/strong> (except Sperm whales) tend to prefer deep offshore waters.<\/li>\n\n\n\n<li><strong>Atlantic spotted dolphins<\/strong> (<em>Stenella frontalis<\/em>) return to the archipelago around <strong>June<\/strong>, when sea temperatures reach <strong>20\u00b0C<\/strong>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Sighting Frequency by Species<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Often observed<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Physeter macrocephalus<\/em> \u2013 Sperm whale<\/li>\n\n\n\n<li><em>Delphinus delphis<\/em> \u2013 Common dolphin<\/li>\n\n\n\n<li><em>Grampus griseus<\/em> \u2013 Risso\u2019s dolphin<\/li>\n\n\n\n<li><em>Tursiops truncatus<\/em> \u2013 Bottlenose dolphin<\/li>\n\n\n\n<li><em>Stenella frontalis<\/em> \u2013 Atlantic spotted dolphin<\/li>\n\n\n\n<li><em>Stenella coeruleoalba<\/em> \u2013 Striped dolphin<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Occasionally observed<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Globicephala macrorhynchus<\/em> \u2013 Short-finned pilot whale<\/li>\n\n\n\n<li><em>Balaenoptera borealis<\/em> \u2013 Sei whale<\/li>\n\n\n\n<li><em>Balaenoptera physalus<\/em> \u2013 Fin whale<\/li>\n\n\n\n<li><em>Balaenoptera musculus<\/em> \u2013 Blue whale<\/li>\n\n\n\n<li><em>Mesoplodon bidens<\/em> \u2013 Sowerby\u2019s beaked whale<\/li>\n\n\n\n<li><em>Megaptera novaeangliae<\/em> \u2013 Humpback whale<\/li>\n\n\n\n<li><em>Hyperoodon ampullatus<\/em> \u2013 Northern bottlenose whale<\/li>\n\n\n\n<li><em>Pseudorca crassidens<\/em> \u2013 False killer whale<\/li>\n\n\n\n<li><em>Balaenoptera edeni<\/em> \u2013 Bryde\u2019s whale<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Rarely observed<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Ziphius cavirostris<\/em> \u2013 Cuvier\u2019s beaked whale<\/li>\n\n\n\n<li><em>Kogia breviceps<\/em> \u2013 Pygmy sperm whale<\/li>\n\n\n\n<li><em>Balaenoptera acutorostrata<\/em> \u2013 Minke whale<\/li>\n\n\n\n<li><em>Orcinus orca<\/em> \u2013 Killer whale<\/li>\n\n\n\n<li><em>Mesoplodon densirostris<\/em> \u2013 Blainville\u2019s beaked whale<\/li>\n\n\n\n<li><em>Mesoplodon europaeus<\/em> \u2013 Gervais\u2019 beaked whale<\/li>\n\n\n\n<li><em>Globicephala melas<\/em> \u2013 Long-finned pilot whale<\/li>\n\n\n\n<li><em>Steno bredanensis<\/em> \u2013 Rough-toothed dolphin<\/li>\n\n\n\n<li><em>Lagenodelphis hosei<\/em> \u2013 Fraser\u2019s dolphin<\/li>\n\n\n\n<li><em>Mesoplodon mirus<\/em> \u2013 True\u2019s beaked whale<\/li>\n\n\n\n<li><em>Kogia sima<\/em> \u2013 Dwarf sperm whale<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n<\/details>\n\n\n\n<!-- Espa\u00e7o Talassa \u2014 Sightings Dashboard v2 -->\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Lora:wght@400;600&amp;family=Montserrat:wght@400;500;600&amp;display=swap\" rel=\"stylesheet\">\n\n<div id=\"talassa-root\">\n    <style>\n        #talassa-root {\n            --color-bg: #f7f6f3;\n            --color-shade: #f0ede2;\n            --color-primary: #115eb9;\n            --color-dark: #20242b;\n            --color-primary-dark: #1d3455;\n            --color-text-main: #404040;\n            --color-text-lighter: #5f5e55;\n            --color-text-light: #8c8c8c;\n            --color-border: #d9d9d9;\n            --font-body: \"Montserrat\", sans-serif;\n            --font-heading: \"Lora\", serif;\n            font-family: var(--font-body);\n            color: var(--color-text-main);\n            background: var(--color-bg);\n            padding: 32px 24px;\n            font-size: 14px;\n            line-height: 1.6;\n            max-width: 1200px;\n            margin-left: auto;\n            margin-right: auto;\n        }\n\n        #talassa-root * {\n            box-sizing: border-box;\n            margin: 0;\n            padding: 0;\n        }\n\n        #talassa-root .dash-header {\n            margin-bottom: 32px;\n            border-bottom: 1px solid var(--color-border);\n            padding-bottom: 20px;\n        }\n\n        #talassa-root .dash-header h1 {\n            font-family: var(--font-heading);\n            font-size: 28px;\n            font-weight: 600;\n            color: var(--color-primary-dark);\n            margin-bottom: 6px;\n        }\n\n        #talassa-root .dash-header p {\n            font-size: 13px;\n            color: var(--color-text-light);\n        }\n\n        #talassa-root .tab-bar {\n            display: flex;\n            gap: 0;\n            margin-bottom: 28px;\n            border-bottom: 2px solid var(--color-border);\n        }\n\n        #talassa-root .tab-bar button {\n            padding: 10px 22px;\n            border: none;\n            background: none;\n            font-family: var(--font-body);\n            font-size: 13px;\n            font-weight: 500;\n            color: var(--color-text-light);\n            cursor: pointer;\n            position: relative;\n            bottom: -2px;\n            border-bottom: 2px solid transparent;\n            transition: color 0.15s, border-color 0.15s;\n            letter-spacing: 0.02em;\n        }\n\n        #talassa-root .tab-bar button:hover {\n            color: var(--color-primary);\n        }\n\n        #talassa-root .tab-bar button.active {\n            color: var(--color-primary);\n            border-bottom-color: var(--color-primary);\n            font-weight: 600;\n        }\n\n        #talassa-root .tab-bar button:disabled {\n            opacity: 0.4;\n            cursor: default;\n        }\n\n        #talassa-root #global-loader {\n            display: flex;\n            align-items: center;\n            gap: 16px;\n            padding: 48px 0;\n            color: var(--color-text-lighter);\n            font-size: 14px;\n        }\n\n        #talassa-root .spinner {\n            width: 28px;\n            height: 28px;\n            border: 3px solid var(--color-border);\n            border-top-color: var(--color-primary);\n            border-radius: 50%;\n            animation: t-spin 0.8s linear infinite;\n            flex-shrink: 0;\n        }\n\n        @keyframes t-spin {\n            to {\n                transform: rotate(360deg);\n            }\n        }\n\n        #talassa-root #loader-error {\n            display: none;\n            color: #ee3940;\n            font-size: 13px;\n            background: #fff0f0;\n            border: 1px solid #ffd9e2;\n            border-radius: 6px;\n            padding: 12px 16px;\n            max-width: 560px;\n            margin-top: 12px;\n        }\n\n        #talassa-root #loader-retry {\n            display: none;\n            margin-top: 12px;\n            padding: 8px 20px;\n            background: var(--color-primary);\n            color: #fff;\n            border: none;\n            border-radius: 4px;\n            font-family: var(--font-body);\n            font-size: 13px;\n            cursor: pointer;\n        }\n\n        #talassa-root .tab-panel {\n            display: none;\n        }\n\n        #talassa-root .tab-panel.active {\n            display: block;\n        }\n\n        #talassa-root .filters-bar {\n            display: flex;\n            gap: 24px;\n            align-items: center;\n            flex-wrap: wrap;\n            background: var(--color-shade);\n            padding: 14px 18px;\n            border-radius: 6px;\n            border: 1px solid var(--color-border);\n            margin-bottom: 24px;\n        }\n\n        #talassa-root .filters-bar label {\n            font-size: 12px;\n            font-weight: 600;\n            color: var(--color-text-lighter);\n            text-transform: uppercase;\n            letter-spacing: 0.06em;\n            margin-right: 8px;\n        }\n\n        #talassa-root select {\n            padding: 7px 12px;\n            border-radius: 4px;\n            border: 1px solid var(--color-border);\n            font-size: 13px;\n            font-family: var(--font-body);\n            background: #fff;\n            color: var(--color-text-main);\n            cursor: pointer;\n            outline: none;\n        }\n\n        #talassa-root select:focus {\n            border-color: var(--color-primary);\n        }\n\n        #talassa-root #table-summary {\n            margin-left: auto;\n            font-size: 13px;\n            color: var(--color-text-lighter);\n            font-weight: 500;\n        }\n\n        #talassa-root .table-wrapper {\n            overflow-x: auto;\n            border: 1px solid var(--color-border);\n            border-radius: 6px;\n        }\n\n        #talassa-root #tab-table table {\n            border-collapse: collapse;\n            width: 100%;\n            min-width: 900px;\n            font-size: 11px;\n            table-layout: fixed;\n        }\n\n        #talassa-root #tab-table th {\n            background: var(--color-shade);\n            padding: 8px 4px;\n            font-weight: 600;\n            font-size: 11px;\n            color: var(--color-text-lighter);\n            border: 1px solid var(--color-border);\n            text-align: center;\n        }\n\n        #talassa-root #tab-table td {\n            border: 1px solid #e8e6de;\n            text-align: center;\n        }\n\n        #talassa-root #tab-table tr:last-child td {\n            border-bottom: none;\n        }\n\n        #talassa-root .species-name {\n            text-align: left !important;\n            padding-left: 12px;\n            padding-right: 10px;\n            width: 200px;\n            min-width: 200px;\n            white-space: normal;\n            word-wrap: break-word;\n            position: sticky;\n            left: 0;\n            background: #fff;\n            z-index: 20;\n            transform: translateZ(0);\n            box-shadow: 3px 0 0 #fff;\n            border-right: 2px solid var(--color-border) !important;\n            font-size: 12px;\n            color: var(--color-text-main);\n        }\n\n        #talassa-root th.species-name {\n            background: var(--color-shade) !important;\n            font-family: var(--font-heading);\n            font-size: 12px;\n            color: var(--color-primary-dark);\n        }\n\n        #talassa-root .species-link {\n            color: inherit;\n            text-decoration: none;\n            border-bottom: 1px dashed currentColor;\n            transition: color 0.15s, border-bottom-style 0.15s;\n        }\n\n        #talassa-root .species-link:hover {\n            color: var(--color-primary);\n            border-bottom-style: solid;\n        }\n\n        #talassa-root .day-col {\n            width: 30px;\n        }\n\n        #talassa-root .total-col {\n            width: 42px;\n            min-width: 42px;\n            font-weight: 600;\n            background: #eef3fb !important;\n            position: sticky;\n            right: -1px;\n            z-index: 10;\n            border-left: 2px solid var(--color-border) !important;\n            color: var(--color-primary-dark);\n            transform: translateZ(0);\n            box-shadow: -3px 0 0 #eef3fb;\n        }\n\n        #talassa-root .cell-container {\n            height: 36px;\n            display: flex;\n            flex-direction: column;\n        }\n\n        #talassa-root .row-half {\n            flex: 1;\n            width: 100%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 9px;\n            color: var(--color-text-light);\n        }\n\n        #talassa-root .am-zone {\n            border-bottom: 1px solid #f0ede2;\n        }\n\n        #talassa-root .boats-row td {\n            background: #faf8f0 !important;\n            font-weight: 600;\n        }\n\n        #talassa-root .boats-row .species-name {\n            background: #faf8f0 !important;\n            font-family: var(--font-heading);\n            font-size: 12px;\n            color: var(--color-text-lighter);\n            font-style: italic;\n        }\n\n        #talassa-root .species-swatch {\n            display: inline-block;\n            width: 9px;\n            height: 9px;\n            border-radius: 2px;\n            margin-right: 7px;\n            flex-shrink: 0;\n            vertical-align: middle;\n        }\n\n        #talassa-root .legend-section {\n            margin-top: 24px;\n            padding: 20px;\n            background: #fff;\n            border: 1px solid var(--color-border);\n            border-radius: 6px;\n        }\n\n        #talassa-root .legend-title {\n            font-family: var(--font-heading);\n            font-size: 15px;\n            color: var(--color-primary-dark);\n            margin-bottom: 14px;\n        }\n\n        #talassa-root .species-legend {\n            display: grid;\n            grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));\n            gap: 8px;\n        }\n\n        #talassa-root .species-legend-item {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            font-size: 12px;\n            color: var(--color-text-main);\n        }\n\n        #talassa-root .legend-swatch {\n            width: 12px;\n            height: 12px;\n            border-radius: 2px;\n            flex-shrink: 0;\n        }\n\n        #talassa-root .hm-wrapper {\n            overflow-x: auto;\n            border: 1px solid var(--color-border);\n            border-radius: 6px;\n        }\n\n        #talassa-root #tab-heatmap table {\n            border-collapse: collapse;\n            width: 100%;\n            font-size: 12px;\n        }\n\n        #talassa-root #tab-heatmap th {\n            background: var(--color-shade);\n            padding: 10px 8px;\n            font-size: 11px;\n            font-weight: 600;\n            color: var(--color-text-lighter);\n            border: 1px solid var(--color-border);\n            white-space: nowrap;\n            text-transform: uppercase;\n            letter-spacing: 0.05em;\n        }\n\n        #talassa-root #tab-heatmap td {\n            border: 1px solid #e8e6de;\n            text-align: center;\n        }\n\n        #talassa-root .hm-species-col {\n            text-align: left !important;\n            padding: 0 10px 0 14px;\n            min-width: 180px;\n            width: 180px;\n            max-width: 180px;\n            white-space: normal;\n            word-wrap: break-word;\n            position: sticky;\n            left: 0;\n            background: #fff;\n            z-index: 10;\n            border-right: 2px solid var(--color-border) !important;\n            font-size: 12px;\n            color: var(--color-text-main);\n        }\n\n        #talassa-root th.hm-species-col {\n            background: var(--color-shade) !important;\n            font-family: var(--font-heading);\n            color: var(--color-primary-dark);\n            text-transform: none;\n            font-size: 12px;\n            letter-spacing: 0;\n        }\n\n        #talassa-root .hm-swatch {\n            display: inline-block;\n            width: 8px;\n            height: 8px;\n            border-radius: 2px;\n            margin-right: 7px;\n            vertical-align: middle;\n            flex-shrink: 0;\n        }\n\n        #talassa-root .hm-best-col {\n            min-width: 90px;\n            width: 90px;\n            position: sticky;\n            right: 0;\n            background: #eef3fb;\n            border-left: 2px solid var(--color-border) !important;\n            font-size: 11px;\n            color: var(--color-text-lighter);\n            padding: 0 8px;\n            white-space: nowrap;\n            z-index: 10;\n            transform: translateZ(0);\n            box-shadow: -3px 0 0 #eef3fb;\n        }\n\n        #talassa-root th.hm-best-col {\n            background: var(--color-shade) !important;\n            color: var(--color-primary-dark);\n            font-family: var(--font-heading);\n            text-transform: none;\n            font-size: 12px;\n            letter-spacing: 0;\n            z-index: 20;\n        }\n\n        #talassa-root .heat-cell {\n            width: 72px;\n            min-width: 72px;\n            height: 40px;\n            position: relative;\n            z-index: 0;\n            cursor: default;\n            transition: filter 0.12s;\n        }\n\n        #talassa-root .heat-cell:hover {\n            filter: brightness(0.88);\n        }\n\n        #talassa-root .rate-label {\n            position: absolute;\n            inset: 0;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 11px;\n            font-weight: 600;\n            pointer-events: none;\n        }\n\n\n        #talassa-root .hm-note {\n            font-size: 12px;\n            color: var(--color-text-light);\n            padding: 10px 0 0;\n        }\n\n        #talassa-root .section-heading {\n            font-family: var(--font-heading);\n            font-size: 20px;\n            color: var(--color-primary-dark);\n            margin-bottom: 6px;\n        }\n\n        #talassa-root .section-sub {\n            font-size: 13px;\n            color: var(--color-text-light);\n            margin-bottom: 20px;\n        }\n\n        #talassa-root .stats-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n            gap: 16px;\n            margin-bottom: 28px;\n        }\n\n        #talassa-root .stat-box {\n            background: #fff;\n            padding: 20px;\n            border-radius: 6px;\n            border: 1px solid var(--color-border);\n        }\n\n        #talassa-root .stat-value {\n            font-family: var(--font-heading);\n            font-size: 30px;\n            font-weight: 600;\n            color: var(--color-primary);\n        }\n\n        #talassa-root .stat-label {\n            font-size: 11px;\n            color: var(--color-text-light);\n            text-transform: uppercase;\n            letter-spacing: 0.08em;\n            margin-top: 4px;\n        }\n\n        #talassa-root .chart-card {\n            background: #fff;\n            border-radius: 6px;\n            padding: 24px;\n            border: 1px solid var(--color-border);\n            margin-bottom: 20px;\n        }\n\n        #talassa-root .chart-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 18px;\n            flex-wrap: wrap;\n            gap: 10px;\n        }\n\n        #talassa-root .chart-title {\n            font-family: var(--font-heading);\n            font-size: 17px;\n            color: var(--color-primary-dark);\n        }\n\n        #talassa-root canvas {\n            max-height: 380px;\n        }\n\n        #talassa-root #a-species-chart {\n            max-height: none;\n        }\n\n        #talassa-root .intro-note {\n            font-size: 13px;\n            color: var(--color-text-lighter);\n            background: var(--color-shade);\n            padding: 12px 16px;\n            border-radius: 6px;\n            border-left: 3px solid var(--color-primary);\n            margin-bottom: 20px;\n            line-height: 1.6;\n        }\n\n        @media (max-width: 600px) {\n            #talassa-root {\n                padding: 16px 12px;\n            }\n\n            #talassa-root .dash-header h1 {\n                font-size: 20px;\n            }\n\n            #talassa-root .species-name {\n                width: 90px;\n                min-width: 90px;\n                font-size: 9px;\n                left: 0;\n            }\n\n            #talassa-root .total-col,\n            #talassa-root th.total-col {\n                width: 34px;\n                min-width: 34px;\n                right: 0;\n                background: #eef3fb !important;\n                z-index: 15;\n                transform: translateZ(0);\n                box-shadow: -3px 0 0 #eef3fb;\n            }\n\n            #talassa-root .hm-species-col {\n                width: 120px;\n                min-width: 120px;\n                max-width: 120px;\n                white-space: normal;\n                word-wrap: break-word;\n                font-size: 9px !important;\n                left: 0;\n                background: #fff !important;\n                z-index: 15;\n                transform: translateZ(0);\n                box-shadow: 3px 0 0 #fff;\n            }\n\n            #talassa-root th.hm-species-col {\n                background: var(--color-shade) !important;\n                box-shadow: 3px 0 0 var(--color-shade);\n                z-index: 15;\n            }\n\n            #talassa-root .hm-best-col {\n                position: sticky;\n                min-width: 90px;\n                width: 90px;\n                max-width: 90px;\n                right: 0;\n                background: #eef3fb !important;\n                z-index: 15;\n                transform: translateZ(0);\n                box-shadow: -3px 0 0 #eef3fb;\n            }\n\n            #talassa-root th.hm-best-col {\n                background: var(--color-shade) !important;\n                box-shadow: -3px 0 0 var(--color-shade);\n                z-index: 15;\n            }\n\n            #talassa-root .species-name {\n                background: #fff !important;\n                z-index: 25;\n                transform: translateZ(0);\n                box-shadow: 3px 0 0 #fff;\n            }\n\n            #talassa-root th.species-name {\n                background: var(--color-shade) !important;\n                box-shadow: 3px 0 0 var(--color-shade);\n                z-index: 25;\n            }\n\n            #talassa-root .heat-cell {\n                width: 44px;\n                min-width: 44px;\n            }\n\n            #talassa-root .filters-bar {\n                flex-direction: column;\n                align-items: flex-start;\n                gap: 10px;\n            }\n\n            #talassa-root .table-wrapper,\n            #talassa-root .hm-wrapper {\n                -webkit-overflow-scrolling: touch;\n            }\n\n            #talassa-root .tab-bar button {\n                padding: 10px 14px;\n                font-size: 12px;\n            }\n        }\n\n        #talassa-root .bw-half {\n            background: #e8eaed;\n            color: #999;\n            font-size: 9px;\n            font-weight: 700;\n            letter-spacing: 0.02em;\n        }\n    <\/style>\n\n    <div class=\"dash-header\">\n        <h1>Cetacean Sightings \u2014 Espa\u00e7o Talassa<\/h1>\n        <p>Historical whale and dolphin sighting records from Pico Island, Azores \u00b7 1994\u2013present<\/p>\n    <\/div>\n\n    <div class=\"tab-bar\" id=\"tab-bar\">\n        <button data-tab=\"table\" class=\"active\" disabled=\"\">Sightings Table<\/button>\n        <button data-tab=\"heatmap\" disabled=\"\">Seasonal Heatmap<\/button>\n        <button data-tab=\"analytics\" disabled=\"\">Analytics<\/button>\n    <\/div>\n\n    <div id=\"global-loader\">\n        <div class=\"spinner\"><\/div>\n        <span>Loading sightings data\u2026<\/span>\n    <\/div>\n    <div id=\"loader-error\"><\/div>\n    <button id=\"loader-retry\" onclick=\"location.reload()\">Retry<\/button>\n\n    <div id=\"tab-table\" class=\"tab-panel\">\n        <p class=\"intro-note\">Each row shows a species. Each column is a day of the selected month. Cells are split in\n            two: <strong>top = AM<\/strong> \u00b7 <strong>bottom = PM<\/strong>. A coloured cell means the species was\n            sighted on that departure.<\/p>\n        <div class=\"filters-bar\">\n            <div><label for=\"t-year\">Year<\/label><select id=\"t-year\"><\/select><\/div>\n            <div><label for=\"t-month\">Month<\/label>\n                <select id=\"t-month\">\n                    <option value=\"3\">March<\/option>\n                    <option value=\"4\">April<\/option>\n                    <option value=\"5\">May<\/option>\n                    <option value=\"6\">June<\/option>\n                    <option value=\"7\">July<\/option>\n                    <option value=\"8\">August<\/option>\n                    <option value=\"9\">September<\/option>\n                    <option value=\"10\">October<\/option>\n                <\/select>\n                <script>(function(){var m=new Date().getMonth()+1;if(m<3)m=3;if(m>10)m=10;document.getElementById('t-month').value=m;})();<\/script>\n            <\/div>\n            <div id=\"table-summary\"><\/div>\n        <\/div>\n        <div class=\"table-wrapper\">\n            <table>\n                <thead>\n                    <tr id=\"t-header-row\">\n                        <th class=\"species-name\">Species<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody id=\"t-body\"><\/tbody>\n            <\/table>\n        <\/div>\n        <p class=\"hm-note\"><strong>BW<\/strong> = Bad Weather \u2014 departure cancelled due to sea conditions (not counted as a trip).<\/p>\n\n    <\/div>\n\n    <div id=\"tab-heatmap\" class=\"tab-panel\">\n        <h2 class=\"section-heading\">Seasonal sighting heatmap<\/h2>\n        <p class=\"section-sub\">% of trips on which each species was sighted \u2014 normalised by number of departures\n            per month<\/p>\n        <div class=\"filters-bar\" style=\"margin-top:0;\">\n            <div><label for=\"hm-year\">Year<\/label><select id=\"hm-year\"><\/select><\/div>\n        <\/div>\n        <div class=\"hm-wrapper\">\n            <table id=\"hm-table\"><\/table>\n        <\/div>\n        <p class=\"hm-note\">Colour intensity = sighting rate (% of departures with at least one sighting). White = never\n            recorded. <strong>Best month<\/strong> = highest sighting rate for that species within the selected period.\n        <\/p>\n    <\/div>\n\n    <div id=\"tab-analytics\" class=\"tab-panel\">\n        <div class=\"filters-bar\">\n            <div><label for=\"a-year\">Year<\/label><select id=\"a-year\"><\/select><\/div>\n            <div><label for=\"a-month\">Month<\/label>\n                <select id=\"a-month\">\n                    <option value=\"all\">All months<\/option>\n                    <option value=\"3\">March<\/option>\n                    <option value=\"4\">April<\/option>\n                    <option value=\"5\">May<\/option>\n                    <option value=\"6\">June<\/option>\n                    <option value=\"7\">July<\/option>\n                    <option value=\"8\">August<\/option>\n                    <option value=\"9\">September<\/option>\n                    <option value=\"10\">October<\/option>\n                <\/select>\n            <\/div>\n        <\/div>\n        <p class=\"intro-note\">A departure is counted as <strong>successful<\/strong> if at least one cetacean was\n            sighted. AM and PM are counted separately.<\/p>\n        <div class=\"stats-grid\">\n            <div class=\"stat-box\">\n                <div class=\"stat-value\" id=\"val-success\">&#8211;<\/div>\n                <div class=\"stat-label\">Success Rate<\/div>\n            <\/div>\n            <div class=\"stat-box\">\n                <div class=\"stat-value\" id=\"val-species\">&#8211;<\/div>\n                <div class=\"stat-label\">Avg Species \/ Departure<\/div>\n            <\/div>\n            <div class=\"stat-box\">\n                <div class=\"stat-value\" id=\"val-trips\">&#8211;<\/div>\n                <div class=\"stat-label\">Departures in Period<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"chart-card\">\n            <div class=\"chart-header\">\n                <h3 class=\"chart-title\">Species abundance ranking<\/h3>\n                <div><label for=\"a-topn\" style=\"font-size:12px;color:var(--color-text-light);margin-right:8px;\">Show<\/label>\n                    <select id=\"a-topn\">\n                        <option value=\"5\">Top 5<\/option>\n                        <option value=\"10\" selected=\"\">Top 10<\/option>\n                        <option value=\"15\">Top 15<\/option>\n                        <option value=\"all\">All<\/option>\n                    <\/select>\n                <\/div>\n            <\/div>\n            <canvas id=\"a-species-chart\"><\/canvas>\n        <\/div>\n        <div class=\"chart-card\">\n            <div class=\"chart-header\">\n                <h3 class=\"chart-title\" id=\"a-trend-title\">Species trend<\/h3><select id=\"a-species-filter\"><\/select>\n            <\/div>\n            <canvas id=\"a-trend-chart\"><\/canvas>\n        <\/div>\n        <div class=\"chart-card\">\n            <div class=\"chart-header\">\n                <h3 class=\"chart-title\" id=\"a-success-title\">Sighting success trend<\/h3>\n            <\/div>\n            <canvas id=\"a-success-chart\"><\/canvas>\n        <\/div>\n\n    <\/div>\n\n\n    <div id=\"t-tooltip\" style=\"position:fixed;display:none;background:#20242b;color:#f7f6f3;font-size:11px;font-family:'Montserrat',sans-serif;padding:6px 11px;border-radius:4px;white-space:nowrap;z-index:9999;pointer-events:none;\">\n    <\/div>\n<\/div>\n\n<script>\n    (function () {\n        console.log('[Talassa] bootstrap executing');\n        try {\n            var _b64 = \"KGZ1bmN0aW9uKCkgewogICAgY29uc3QgQ1NWX1VSTCA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC9lLzJQQUNYLTF2U0UzNmp5MGUwZTBSblBJX1dkVnZMU3dDYUQxMTJsbkR4ZWFjZUNrTVV6R3lWVlVrNGM2cUppa01Ld0NqYzVmQjFqV2dPSGE5bFg2MzB2L3B1Yj9naWQ9MTYxMTgxODQzOSZzaW5nbGU9dHJ1ZSZvdXRwdXQ9Y3N2JzsKCiAgICAvLyBQcm92ZSBKUyBpcyBleGVjdXRpbmcgXHUyMDE0IHVwZGF0ZSBsb2FkZXIgdGV4dCBpbW1lZGlhdGVseQogICAgY29uc3QgX2xvYWRlclNwYW4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjdGFsYXNzYS1zaWdodGluZ3Mtcm9vdCAjbG9hZGVyLXJvdyBzcGFuJyk7CiAgICBpZiAoX2xvYWRlclNwYW4pIF9sb2FkZXJTcGFuLnRleHRDb250ZW50ID0gJ0pTIHJ1bm5pbmcgXHUyMDE0IGxvYWRpbmcgZGVwZW5kZW5jaWVzXHUyMDI2JzsKCiAgICAvLyBMb2FkIFBhcGFQYXJzZSArIENoYXJ0LmpzIGR5bmFtaWNhbGx5IHNvIFdvcmRQcmVzcyBjYW5ub3QgZGVmZXIvc3RyaXAgdGhlbQogICAgbGV0IF9kZXBzTG9hZGVkID0gMDsKICAgIGZ1bmN0aW9uIF9vbkRlcExvYWRlZCgpIHsKICAgICAgICBfZGVwc0xvYWRlZCsrOwogICAgICAgIGlmIChfbG9hZGVyU3BhbikgX2xvYWRlclNwYW4udGV4dENvbnRlbnQgPSBgRGVwZW5kZW5jaWVzOiAke19kZXBzTG9hZGVkfS8yIGxvYWRlZFx1MjAyNmA7CiAgICAgICAgaWYgKF9kZXBzTG9hZGVkID09PSAyKSB7IGlmIChfbG9hZGVyU3BhbikgX2xvYWRlclNwYW4udGV4dENvbnRlbnQgPSAnRmV0Y2hpbmcgQ1NWIGRhdGFcdTIwMjYnOyBpbml0KCk7IH0KICAgIH0KICAgIGZ1bmN0aW9uIF9sb2FkU2NyaXB0KHNyYywgY2IpIHsKICAgICAgICBjb25zdCBzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CiAgICAgICAgcy5zcmMgPSBzcmM7CiAgICAgICAgcy5vbmxvYWQgPSBjYjsKICAgICAgICBzLm9uZXJyb3IgPSAoKSA9PiBzaG93RXJyb3IoJ0NvdWxkIG5vdCBsb2FkIHNjcmlwdDogJyArIHNyYyArICcuIENoZWNrIGlmIHlvdXIgYnJvd3NlciBvciBhIHNlY3VyaXR5IHBsdWdpbiBpcyBibG9ja2luZyBleHRlcm5hbCBzY3JpcHRzLicpOwogICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQocyk7CiAgICB9CiAgICBmdW5jdGlvbiBzaG93RXJyb3IobXNnKSB7CiAgICAgICAgY2xlYXJUaW1lb3V0KF9sb2FkVGltZW91dCk7CiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbG9hZGVyLWVycm9yJyk7CiAgICAgICAgZWwudGV4dENvbnRlbnQgPSBtc2c7CiAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvYWRlci1yZXRyeScpLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJzsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbG9hZGVyLXJvdycpLnF1ZXJ5U2VsZWN0b3IoJy5zcGlubmVyJykuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKICAgIH0KCiAgICAvLyAzMC1zZWNvbmQgdGltZW91dDogc2hvdyBlcnJvciBpbnN0ZWFkIG9mIGluZmluaXRlIHNwaW5uZXIKICAgIGNvbnN0IF9sb2FkVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgIHNob3dFcnJvcignRGF0YSBmYWlsZWQgdG8gbG9hZCBhZnRlciAzMCBzZWNvbmRzLiBDaGVjayB5b3VyIGJyb3dzZXIgY29uc29sZSAoRjEyKSBmb3IgZGV0YWlscywgb3IgdHJ5IHJlZnJlc2hpbmcuJyk7CiAgICB9LCAzMDAwMCk7CgogICAgX2xvYWRTY3JpcHQoJ2h0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL1BhcGFQYXJzZS81LjMuMi9wYXBhcGFyc2UubWluLmpzJywgX29uRGVwTG9hZGVkKTsKICAgIF9sb2FkU2NyaXB0KCdodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2NoYXJ0LmpzJywgX29uRGVwTG9hZGVkKTsKCiAgICBmdW5jdGlvbiBpbml0KCkgewoKICAgIGNvbnN0IFNQRUNJRVMgPSBbCiAgICAgICAgeyBuYW1lOiAiU3Blcm0gd2hhbGUiLCAgICAgICAgICAgICAgIGNvbG9yOiAiI0RFMDYwMSIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vc3Blcm0td2hhbGUvIiB9LAogICAgICAgIHsgbmFtZTogIlJpc3NvJ3MgZG9scGhpbiIsICAgICAgICAgICBjb2xvcjogIiMwMDAwOTQiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL3Jpc3Nvcy1kb2xwaGluLyIgfSwKICAgICAgICB7IG5hbWU6ICJDb21tb24gZG9scGhpbiIsICAgICAgICAgICAgY29sb3I6ICIjRTg2ODM1IiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9jb21tb24tZG9scGhpbi8iIH0sCiAgICAgICAgeyBuYW1lOiAiQm90dGxlbm9zZSBkb2xwaGluIiwgICAgICAgIGNvbG9yOiAiIzlDQ0YwMCIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vYm90dGxlbm9zZS1kb2xwaGluLyIgfSwKICAgICAgICB7IG5hbWU6ICJTdHJpcGVkIGRvbHBoaW4iLCAgICAgICAgICAgY29sb3I6ICIjRkY2MTAxIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9zdHJpcHBlZC1kb2xwaGluLyIgfSwKICAgICAgICB7IG5hbWU6ICJBdGxhbnRpYyBzcG90dGVkIGRvbHBoaW4iLCAgY29sb3I6ICIjRkZCNjAxIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9hdGxhbnRpYy1zcG90dGVkLWRvbHBoaW4vIiB9LAogICAgICAgIHsgbmFtZTogIlNob3J0LWZpbm5lZCBwaWxvdCB3aGFsZSIsICBjb2xvcjogIiNDQzg4MDAiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL3Nob3J0LWZpbm5lZC1waWxvdC13aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiRmFsc2Uga2lsbGVyIHdoYWxlIiwgICAgICAgIGNvbG9yOiAiIzAwMDBENiIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vZmFsc2Uta2lsbGVyLXdoYWxlLyIgfSwKICAgICAgICB7IG5hbWU6ICJQeWdteSBzcGVybSB3aGFsZSIsICAgICAgICAgY29sb3I6ICIjODU4Njg0IiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9weWdteS1zcGVybS13aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiRHdhcmYgc3Blcm0gd2hhbGUiLCAgICAgICAgICBjb2xvcjogIiNDMkE4NzgiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL2RyYWZ0LXNwZXJtLXdoYWxlLyIgfSwKICAgICAgICB7IG5hbWU6ICJCbHVlIHdoYWxlIiwgICAgICAgICAgICAgICAgY29sb3I6ICIjOUMzMDMxIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9ibHVlLXdoYWxlLyIgfSwKICAgICAgICB7IG5hbWU6ICJIdW1wYmFjayB3aGFsZSIsICAgICAgICAgICAgY29sb3I6ICIjMjFBQTM5IiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9odW1wYmFjay13aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiRmluIHdoYWxlIiwgICAgICAgICAgICAgICAgIGNvbG9yOiAiIzMwQ0ZDRSIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vZmluLXdoYWxlLyIgfSwKICAgICAgICB7IG5hbWU6ICJNaW5rZSB3aGFsZSIsICAgICAgICAgICAgICAgY29sb3I6ICIjNUE5OTAwIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9taW5rZS13aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiU2VpIHdoYWxlIiwgICAgICAgICAgICAgICAgIGNvbG9yOiAiI0ZGOUVDRSIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vc2VpLXdoYWxlLyIgfSwKICAgICAgICB7IG5hbWU6ICJCcnlkZSdzIHdoYWxlIiwgICAgICAgICAgICAgY29sb3I6ICIjQ0VGRkNFIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9icnlkZXMtd2hhbGUvIiB9LAogICAgICAgIHsgbmFtZTogIk5vcnRoZXJuIGJvdHRsZW5vc2Ugd2hhbGUiLCBjb2xvcjogIiMzMTMwOUMiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL25vcnRoZXJuLWJvdHRsZW5vc2Utd2hhbGUvIiB9LAogICAgICAgIHsgbmFtZTogIlNvd2VyYnkncyBiZWFrZWQgd2hhbGUiLCAgICBjb2xvcjogIiNGRkNGOUMiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL3Nvd2VyYnlzLWJlYWtlZC13aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiQ3V2aWVyJ3MgYmVha2VkIHdoYWxlIiwgICAgIGNvbG9yOiAiIzBEN0EyNCIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vY3V2aWVycy1iZWFrZWQtd2hhbGUvIiB9LAogICAgICAgIHsgbmFtZTogIkJsYWludmlsbGUncyBiZWFrZWQgd2hhbGUiLCBjb2xvcjogIiNGNzk5MDYiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL2JsYWludmlsbGVzLWJlYWtlZC13aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiR2VydmFpcycgYmVha2VkIHdoYWxlIiwgICAgIGNvbG9yOiAiIzdCMjAyMCIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vZ2VydmFpcy1iZWFrZWQtd2hhbGUvIiB9LAogICAgICAgIHsgbmFtZTogIlRydWUncyBiZWFrZWQgd2hhbGUiLCAgICAgICBjb2xvcjogIiM4QTVBODMiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL21lc29wbG9kb24tZGUtdHJ1ZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiVW5pZGVudGlmaWVkIGJlYWtlZCB3aGFsZSIsIGNvbG9yOiAiIzY3OTdDRiIgfSwKICAgICAgICB7IG5hbWU6ICJLaWxsZXIgd2hhbGUiLCAgICAgICAgICAgICAgY29sb3I6ICIjMzE2MUZGIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9raWxsZXJ3aGFsZS8iIH0sCiAgICAgICAgeyBuYW1lOiAiTG9uZy1maW5uZWQgcGlsb3Qgd2hhbGUiLCAgIGNvbG9yOiAiIzk5NjY2NiIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vbG9uZy1maW5uZWQtcGlsb3Qtd2hhbGUvIiB9LAogICAgICAgIHsgbmFtZTogIlJvdWdoLXRvb3RoZWQgZG9scGhpbiIsICAgICBjb2xvcjogIiMwMDg2ODQiLCB1cmw6ICJodHRwczovL2VzcGFjb3RhbGFzc2EuY29tL2VuL2NldGFjZWFuL3JvdWdoLXRvb3RoZWQtZG9scGhpbi8iIH0sCiAgICAgICAgeyBuYW1lOiAiRnJhc2VyJ3MgZG9scGhpbiIsICAgICAgICAgIGNvbG9yOiAiIzk5NjY5OSIsIHVybDogImh0dHBzOi8vZXNwYWNvdGFsYXNzYS5jb20vZW4vY2V0YWNlYW4vZnJhc2Vycy1kb2xwaGluLyIgfSwKICAgICAgICB7IG5hbWU6ICJOb3J0aGVybiByaWdodCB3aGFsZSIsICAgICAgY29sb3I6ICIjMTExMTExIiwgdXJsOiAiaHR0cHM6Ly9lc3BhY290YWxhc3NhLmNvbS9lbi9jZXRhY2Vhbi9ub3J0aGVybi1yaWdodC13aGFsZS8iIH0sCiAgICBdOwoKICAgIGNvbnN0IFNQRUNJRVNfQ09MT1JTID0gT2JqZWN0LmZyb21FbnRyaWVzKFNQRUNJRVMubWFwKHMgPT4gW3MubmFtZSwgcy5jb2xvcl0pKTsKICAgIGNvbnN0IE1PTlRIUyAgICAgPSBbIk1hcmNoIiwiQXByaWwiLCJNYXkiLCJKdW5lIiwiSnVseSIsIkF1Z3VzdCIsIlNlcHRlbWJlciIsIk9jdG9iZXIiXTsKICAgIGNvbnN0IE1PTlRIX05VTVMgPSBbMywgNCwgNSwgNiwgNywgOCwgOSwgMTBdOwoKICAgIGxldCBhbGxEYXRhID0gW107CiAgICBsZXQgYWN0aXZlVGFiID0gJ3RhYmxlJzsKICAgIGxldCBhU3BlY2llc0NoYXJ0ID0gbnVsbCwgYVRyZW5kQ2hhcnQgPSBudWxsLCBhU3VjY2Vzc0NoYXJ0ID0gbnVsbDsKCiAgICBmdW5jdGlvbiBlc2MocykgewogICAgICAgIHJldHVybiBTdHJpbmcocykucmVwbGFjZSgvJi9nLCcmYW1wOycpLnJlcGxhY2UoLyIvZywnJnF1b3Q7JykucmVwbGFjZSgvPC9nLCcmbHQ7JykucmVwbGFjZSgvPi9nLCcmZ3Q7Jyk7CiAgICB9CgogICAgZnVuY3Rpb24gc3BlY2llc0xpbmsobmFtZSkgewogICAgICAgIGNvbnN0IHMgPSBTUEVDSUVTLmZpbmQoeCA9PiB4Lm5hbWUgPT09IG5hbWUpOwogICAgICAgIGNvbnN0IHNhZmUgPSBlc2MobmFtZSk7CiAgICAgICAgcmV0dXJuIChzICYmIHMudXJsKQogICAgICAgICAgICA\/IGA8YSBjbGFzcz0ic3BlY2llcy1saW5rIiBocmVmPSIke3MudXJsfSIgdGFyZ2V0PSJfYmxhbmsiIHJlbD0ibm9vcGVuZXIiPiR7c2FmZX08L2E+YAogICAgICAgICAgICA6IHNhZmU7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHBvcHVsYXRlWWVhclNlbGVjdChlbElkLCBpbmNsdWRlQWxsKSB7CiAgICAgICAgY29uc3QgeXJzID0gWy4uLm5ldyBTZXQoYWxsRGF0YS5tYXAoZCA9PiBkLnllYXIpKV0uc29ydCgoYSxiKSA9PiBiLWEpOwogICAgICAgIGNvbnN0IG1pbllyID0gTWF0aC5taW4oLi4ueXJzKSwgbWF4WXIgPSBNYXRoLm1heCguLi55cnMpOwogICAgICAgIGNvbnN0IHNlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsSWQpOwogICAgICAgIGNvbnN0IGFsbE9wdCA9IGluY2x1ZGVBbGwgPyBgPG9wdGlvbiB2YWx1ZT0iYWxsIj5BbGwgVGltZSAoJHttaW5Zcn1cdTIwMTMke21heFlyfSk8L29wdGlvbj5gIDogJyc7CiAgICAgICAgY29uc3QgeWVhck9wdHMgPSB5cnMubWFwKCh5LCBpKSA9PiBgPG9wdGlvbiB2YWx1ZT0iJHt5fSIkeyghaW5jbHVkZUFsbCAmJiBpPT09MCkgPyAnIHNlbGVjdGVkJyA6ICcnfT4ke3l9PC9vcHRpb24+YCkuam9pbignJyk7CiAgICAgICAgc2VsLmlubmVySFRNTCA9IGFsbE9wdCArIHllYXJPcHRzOwogICAgfQoKICAgIC8vIFx1MjUwMFx1MjUwMCBMb2FkIHZpYSBuYXRpdmUgZmV0Y2ggKG1vcmUgcmVsaWFibGUgdGhhbiBQYXBhUGFyc2UgZG93bmxvYWQgbW9kZSkgXHUyNTAwXHUyNTAwCiAgICBmZXRjaChDU1ZfVVJMKQogICAgICAgIC50aGVuKHIgPT4gewogICAgICAgICAgICBpZiAoIXIub2spIHRocm93IG5ldyBFcnJvcignSFRUUCAnICsgci5zdGF0dXMgKyAnICcgKyByLnN0YXR1c1RleHQpOwogICAgICAgICAgICByZXR1cm4gci50ZXh0KCk7CiAgICAgICAgfSkKICAgICAgICAudGhlbihjc3ZUZXh0ID0+IHsKICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9sb2FkVGltZW91dCk7CiAgICAgICAgICAgIGNvbnN0IHJlcyA9IFBhcGEucGFyc2UoY3N2VGV4dCwgeyBoZWFkZXI6IHRydWUsIGR5bmFtaWNUeXBpbmc6IHRydWUgfSk7CiAgICAgICAgICAgIGFsbERhdGEgPSByZXMuZGF0YS5maWx0ZXIoZCA9PiBkLnllYXIpLm1hcChkID0+ICh7CiAgICAgICAgICAgICAgICAuLi5kLAogICAgICAgICAgICAgICAgX2hhc1NpZ2h0aW5nOiBTUEVDSUVTLnNvbWUocyA9PiBkW3MubmFtZV0gPj0gMSksCiAgICAgICAgICAgICAgICBfaXNCYWRXZWF0aGVyOiBkLmJhZF93ZWF0aGVyID49IDEKICAgICAgICAgICAgfSkpOwoKICAgICAgICAgICAgaWYgKGFsbERhdGEubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICBzaG93RXJyb3IoJ1RoZSBkYXRhIHNvdXJjZSByZXR1cm5lZCAwIHJlY29yZHMuIFRoZSBHb29nbGUgU2hlZXQgbWF5IG5lZWQgdG8gYmUgcmVwdWJsaXNoZWQ6IG9wZW4gdGhlIHNoZWV0IFx1MjE5MiBGaWxlIFx1MjE5MiBTaGFyZSBcdTIxOTIgUHVibGlzaCB0byB3ZWIgXHUyMTkyIHJlcHVibGlzaCB0aGUgIlNpZ2h0aW5ncyIgdGFiIGFzIENTVi4nKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2dsb2JhbC1sb2FkZXInKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwoKICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRhYi1iYXIgYnV0dG9uJykuZm9yRWFjaChiID0+IGIuZGlzYWJsZWQgPSBmYWxzZSk7CgogICAgICAgICAgICBwb3B1bGF0ZVllYXJTZWxlY3QoJ3QteWVhcicsIGZhbHNlKTsKICAgICAgICAgICAgcG9wdWxhdGVZZWFyU2VsZWN0KCdobS15ZWFyJywgdHJ1ZSk7CiAgICAgICAgICAgIHBvcHVsYXRlWWVhclNlbGVjdCgnYS15ZWFyJywgdHJ1ZSk7CgogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndC15ZWFyJykub25jaGFuZ2UgICA9IHJlbmRlclRhYmxlOwogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndC1tb250aCcpLm9uY2hhbmdlICA9IHJlbmRlclRhYmxlOwogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaG0teWVhcicpLm9uY2hhbmdlICA9IHJlbmRlckhlYXRtYXA7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhLXllYXInKS5vbmNoYW5nZSAgID0gcmVmcmVzaEFuYWx5dGljczsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2EtbW9udGgnKS5vbmNoYW5nZSAgPSByZWZyZXNoQW5hbHl0aWNzOwogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS10b3BuJykub25jaGFuZ2UgICA9IHJlZnJlc2hBbmFseXRpY3M7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhLXNwZWNpZXMtZmlsdGVyJykuaW5uZXJIVE1MID0gU1BFQ0lFUy5tYXAocyA9PiBgPG9wdGlvbiB2YWx1ZT0iJHtzLm5hbWV9Ij4ke3MubmFtZX08L29wdGlvbj5gKS5qb2luKCcnKTsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Etc3BlY2llcy1maWx0ZXInKS5vbmNoYW5nZSAgPSByZWZyZXNoQW5hbHl0aWNzOwoKICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRhYi1iYXIgYnV0dG9uJykuZm9yRWFjaChidG4gPT4gewogICAgICAgICAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gc3dpdGNoVGFiKGJ0bi5kYXRhc2V0LnRhYikpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0YWItdGFibGUnKS5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTsKICAgICAgICAgICAgcmVuZGVyVGFibGUoKTsKICAgICAgICB9KQogICAgICAgIC5jYXRjaChlcnIgPT4gewogICAgICAgICAgICBzaG93RXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGRhdGE6ICcgKyAoZXJyLm1lc3NhZ2UgfHwgJ25ldHdvcmsgZXJyb3InKSArICcuIENoZWNrIGJyb3dzZXIgY29uc29sZSAoRjEyKSBOZXR3b3JrIHRhYiBmb3IgZGV0YWlscy4nKTsKICAgICAgICB9KTsKCiAgICAvLyBcdTI1MDBcdTI1MDAgVGFiIHN3aXRjaGluZyBcdTI1MDBcdTI1MDAKICAgIGZ1bmN0aW9uIHN3aXRjaFRhYih0YWIpIHsKICAgICAgICBpZiAodGFiID09PSBhY3RpdmVUYWIpIHJldHVybjsKICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGFiLWJhciBidXR0b24nKS5mb3JFYWNoKGIgPT4gYi5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnLCBiLmRhdGFzZXQudGFiID09PSB0YWIpKTsKICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGFiLXBhbmVsJykuZm9yRWFjaChwID0+IHAuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpOwogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGB0YWItJHt0YWJ9YCkuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7CiAgICAgICAgYWN0aXZlVGFiID0gdGFiOwogICAgICAgIGlmICh0YWIgPT09ICdoZWF0bWFwJykgICByZW5kZXJIZWF0bWFwKCk7CiAgICAgICAgaWYgKHRhYiA9PT0gJ2FuYWx5dGljcycpIHJlZnJlc2hBbmFseXRpY3MoKTsKICAgIH0KCiAgICAvLyBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTAKICAgIC8vIFRBQkxFCiAgICAvLyBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTBcdTI1NTAKICAgIGZ1bmN0aW9uIHJlbmRlclRhYmxlKCkgewogICAgICAgIGNvbnN0IHllYXIgID0gcGFyc2VJbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3QteWVhcicpLnZhbHVlKTsKICAgICAgICBjb25zdCBtb250aCA9IHBhcnNlSW50KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0LW1vbnRoJykudmFsdWUpOwogICAgICAgIGNvbnN0IGJvZHkgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3QtYm9keScpOwogICAgICAgIGNvbnN0IGhlYWQgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3QtaGVhZGVyLXJvdycpOwogICAgICAgIGNvbnN0IHN1bW0gID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RhYmxlLXN1bW1hcnknKTsKCiAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBhbGxEYXRhLmZpbHRlcihkID0+IGQueWVhciA9PT0geWVhciAmJiBkLm1vbnRoID09PSBtb250aCk7CiAgICAgICAgY29uc3QgZGF5cyA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAwKS5nZXREYXRlKCk7CgogICAgICAgIGxldCBoSHRtbCA9ICc8dGggY2xhc3M9InNwZWNpZXMtbmFtZSI+U3BlY2llczwvdGg+JzsKICAgICAgICBmb3IgKGxldCBkID0gMTsgZCA8PSBkYXlzOyBkKyspIGhIdG1sICs9IGA8dGggY2xhc3M9ImRheS1jb2wiPiR7ZH08L3RoPmA7CiAgICAgICAgaEh0bWwgKz0gJzx0aCBjbGFzcz0idG90YWwtY29sIj5UcmlwczwvdGg+JzsKICAgICAgICBoZWFkLmlubmVySFRNTCA9IGhIdG1sOwoKICAgICAgICBpZiAoZmlsdGVyZWQubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgIGJvZHkuaW5uZXJIVE1MID0gYDx0cj48dGQgY29sc3Bhbj0iJHtkYXlzICsgMn0iIHN0eWxlPSJwYWRkaW5nOjMwcHg7dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6Izk5OSI+Tm8gZGF0YSBhdmFpbGFibGUgZm9yIHRoaXMgcGVyaW9kPC90ZD48L3RyPmA7CiAgICAgICAgICAgIHN1bW0udGV4dENvbnRlbnQgPSAnTm8gZGF0YSBhdmFpbGFibGUnOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBjb25zdCBieURheURlcCA9IHt9OwogICAgICAgIGZpbHRlcmVkLmZvckVhY2gociA9PiB7IGJ5RGF5RGVwW2Ake3IuZGF5fV8ke3IuZGVwYXJ0dXJlfWBdID0gcjsgfSk7CgogICAgICAgIGxldCB0b3RhbEJvYXRzID0gMCwgdG90YWxUcmlwcyA9IDA7CiAgICAgICAgbGV0IGJIdG1sID0gYDx0ciBjbGFzcz0iYm9hdHMtcm93Ij48dGQgY2xhc3M9InNwZWNpZXMtbmFtZSI+TnVtYmVyIG9mIGJvYXRzPC90ZD5gOwoKICAgICAgICBmb3IgKGxldCBkID0gMTsgZCA8PSBkYXlzOyBkKyspIHsKICAgICAgICAgICAgY29uc3QgYW0gPSBieURheURlcFtgJHtkfV9BTWBdOwogICAgICAgICAgICBjb25zdCBwbSA9IGJ5RGF5RGVwW2Ake2R9X1BNYF07CiAgICAgICAgICAgIGNvbnN0IGFtQiA9IGFtPy5ib2F0cyB8fCAwOwogICAgICAgICAgICBjb25zdCBwbUIgPSBwbT8uYm9hdHMgfHwgMDsKICAgICAgICAgICAgY29uc3QgYW1CVyA9IGFtPy5faXNCYWRXZWF0aGVyIHx8IGZhbHNlOwogICAgICAgICAgICBjb25zdCBwbUJXID0gcG0\/Ll9pc0JhZFdlYXRoZXIgfHwgZmFsc2U7CiAgICAgICAgICAgIGNvbnN0IGFtU2VlID0gYW0gJiYgU1BFQ0lFUy5zb21lKHMgPT4gYW1bcy5uYW1lXSA9PT0gMSk7CiAgICAgICAgICAgIGNvbnN0IHBtU2VlID0gcG0gJiYgU1BFQ0lFUy5zb21lKHMgPT4gcG1bcy5uYW1lXSA9PT0gMSk7CiAgICAgICAgICAgIGlmICghYW1CVyAmJiAoYW1CID49IDEgfHwgYW1TZWUpKSB0b3RhbFRyaXBzKys7CiAgICAgICAgICAgIGlmICghcG1CVyAmJiAocG1CID49IDEgfHwgcG1TZWUpKSB0b3RhbFRyaXBzKys7CiAgICAgICAgICAgIGlmICghYW1CVykgdG90YWxCb2F0cyArPSBhbUI7CiAgICAgICAgICAgIGlmICghcG1CVykgdG90YWxCb2F0cyArPSBwbUI7CiAgICAgICAgICAgIGJIdG1sICs9IGA8dGQ+PGRpdiBjbGFzcz0iY2VsbC1jb250YWluZXIiPgogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0icm93LWhhbGYgYW0tem9uZSR7YW1CVyA\/ICcgYnctaGFsZicgOiAnJ30iPiR7YW1CVyA\/ICdCVycgOiAoYW1CID4gMCA\/IGFtQiA6ICcnKX08L2Rpdj4KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9InJvdy1oYWxmIHBtLXpvbmUke3BtQlcgPyAnIGJ3LWhhbGYnIDogJyd9Ij4ke3BtQlcgPyAnQlcnIDogKHBtQiA+IDAgPyBwbUIgOiAnJyl9PC9kaXY+CiAgICAgICAgICAgIDwvZGl2PjwvdGQ+YDsKICAgICAgICB9CiAgICAgICAgYkh0bWwgKz0gYDx0ZCBjbGFzcz0idG90YWwtY29sIj4ke3RvdGFsVHJpcHN9PC90ZD48L3RyPmA7CgogICAgICAgIFNQRUNJRVMuZm9yRWFjaChzcCA9PiB7CiAgICAgICAgICAgIGJIdG1sICs9IGA8dHI+PHRkIGNsYXNzPSJzcGVjaWVzLW5hbWUiPjxzcGFuIGNsYXNzPSJzcGVjaWVzLXN3YXRjaCIgc3R5bGU9ImJhY2tncm91bmQ6JHtzcC5jb2xvcn0iPjwvc3Bhbj4ke3NwZWNpZXNMaW5rKHNwLm5hbWUpfTwvdGQ+YDsKICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgZCA9IDE7IGQgPD0gZGF5czsgZCsrKSB7CiAgICAgICAgICAgICAgICBjb25zdCBhbUJXID0gYnlEYXlEZXBbYCR7ZH1fQU1gXT8uX2lzQmFkV2VhdGhlciB8fCBmYWxzZTsKICAgICAgICAgICAgICAgIGNvbnN0IHBtQlcgPSBieURheURlcFtgJHtkfV9QTWBdPy5faXNCYWRXZWF0aGVyIHx8IGZhbHNlOwogICAgICAgICAgICAgICAgY29uc3QgYW0gPSAhYW1CVyAmJiBieURheURlcFtgJHtkfV9BTWBdPy5bc3AubmFtZV0gPT09IDE7CiAgICAgICAgICAgICAgICBjb25zdCBwbSA9ICFwbUJXICYmIGJ5RGF5RGVwW2Ake2R9X1BNYF0\/LltzcC5uYW1lXSA9PT0gMTsKICAgICAgICAgICAgICAgIGlmIChhbSkgdG90YWwrKzsKICAgICAgICAgICAgICAgIGlmIChwbSkgdG90YWwrKzsKICAgICAgICAgICAgICAgIGJIdG1sICs9IGA8dGQ+PGRpdiBjbGFzcz0iY2VsbC1jb250YWluZXIiPgogICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9InJvdy1oYWxmIGFtLXpvbmUiJHthbSA\/IGAgc3R5bGU9ImJhY2tncm91bmQ6JHtzcC5jb2xvcn0iYCA6ICcnfT48L2Rpdj4KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJyb3ctaGFsZiBwbS16b25lIiR7cG0gPyBgIHN0eWxlPSJiYWNrZ3JvdW5kOiR7c3AuY29sb3J9ImAgOiAnJ30+PC9kaXY+CiAgICAgICAgICAgICAgICA8L2Rpdj48L3RkPmA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYkh0bWwgKz0gYDx0ZCBjbGFzcz0idG90YWwtY29sIj4ke3RvdGFsID4gMCA\/IHRvdGFsIDogJyd9PC90ZD48L3RyPmA7CiAgICAgICAgfSk7CgogICAgICAgIGJvZHkuaW5uZXJIVE1MID0gYkh0bWw7CiAgICAgICAgc3VtbS50ZXh0Q29udGVudCA9IGAke3RvdGFsVHJpcHN9IHRyaXBzIHRoaXMgbW9udGggXHUyMDE0ICR7dG90YWxCb2F0c30gdG90YWwgYm9hdCBkZXBsb3ltZW50c2A7CiAgICB9CgogICAgZnVuY3Rpb24gcmVuZGVyVGFibGVMZWdlbmQoKSB7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3QtbGVnZW5kJykuaW5uZXJIVE1MID0gU1BFQ0lFUy5tYXAoc3AgPT4KICAgICAgICAgICAgYDxkaXYgY2xhc3M9InNwZWNpZXMtbGVnZW5kLWl0ZW0iPgogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibGVnZW5kLXN3YXRjaCIgc3R5bGU9ImJhY2tncm91bmQ6JHtzcC5jb2xvcn0iPjwvZGl2PgogICAgICAgICAgICAgICAgPHNwYW4+JHtzcGVjaWVzTGluayhzcC5uYW1lKX08L3NwYW4+CiAgICAgICAgICAgIDwvZGl2PmAKICAgICAgICApLmpvaW4oJycpOwogICAgfQoKICAgIC8vIFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MAogICAgLy8gSEVBVE1BUAogICAgLy8gXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwCiAgICBmdW5jdGlvbiBoZWF0Q29sb3IoaGV4LCBwY3QpIHsKICAgICAgICBpZiAocGN0ID09PSBudWxsIHx8IHBjdCA9PT0gMCkgcmV0dXJuICcjZjVmNWY1JzsKICAgICAgICBjb25zdCByID0gcGFyc2VJbnQoaGV4LnNsaWNlKDEsMyksIDE2KTsKICAgICAgICBjb25zdCBnID0gcGFyc2VJbnQoaGV4LnNsaWNlKDMsNSksIDE2KTsKICAgICAgICBjb25zdCBiID0gcGFyc2VJbnQoaGV4LnNsaWNlKDUsNyksIDE2KTsKICAgICAgICBjb25zdCBibGVuZCA9IDAuMTUgKyBNYXRoLm1pbihwY3QsIDEwMCkgLyAxMDAgKiAwLjg1OwogICAgICAgIHJldHVybiBgcmdiKCR7TWF0aC5yb3VuZCgyNTUrKHItMjU1KSpibGVuZCl9LCR7TWF0aC5yb3VuZCgyNTUrKGctMjU1KSpibGVuZCl9LCR7TWF0aC5yb3VuZCgyNTUrKGItMjU1KSpibGVuZCl9KWA7CiAgICB9CgogICAgZnVuY3Rpb24gaGVhdFRleHRDb2xvcihoZXgsIHBjdCkgewogICAgICAgIGlmIChwY3QgPT09IG51bGwgfHwgcGN0IDwgMzUpIHJldHVybiAnIzU1NSc7CiAgICAgICAgY29uc3QgcjAgPSBwYXJzZUludChoZXguc2xpY2UoMSwzKSwgMTYpOwogICAgICAgIGNvbnN0IGcwID0gcGFyc2VJbnQoaGV4LnNsaWNlKDMsNSksIDE2KTsKICAgICAgICBjb25zdCBiMCA9IHBhcnNlSW50KGhleC5zbGljZSg1LDcpLCAxNik7CiAgICAgICAgY29uc3QgYmxlbmQgPSAwLjE1ICsgTWF0aC5taW4ocGN0LCAxMDApIC8gMTAwICogMC44NTsKICAgICAgICBjb25zdCByID0gTWF0aC5yb3VuZCgyNTUrKHIwLTI1NSkqYmxlbmQpOwogICAgICAgIGNvbnN0IGcgPSBNYXRoLnJvdW5kKDI1NSsoZzAtMjU1KSpibGVuZCk7CiAgICAgICAgY29uc3QgYiA9IE1hdGgucm91bmQoMjU1KyhiMC0yNTUpKmJsZW5kKTsKICAgICAgICByZXR1cm4gKDAuMjk5KnIgKyAwLjU4NypnICsgMC4xMTQqYikgLyAyNTUgPCAwLjQ1ID8gJyNmZmYnIDogJyMzMzMnOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbmRlckhlYXRtYXAoKSB7CiAgICAgICAgY29uc3QgeWVhclZhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdobS15ZWFyJykudmFsdWU7CiAgICAgICAgY29uc3QgZGF0YSA9IHllYXJWYWwgPT09ICdhbGwnID8gYWxsRGF0YSA6IGFsbERhdGEuZmlsdGVyKGQgPT4gZC55ZWFyID09PSBwYXJzZUludCh5ZWFyVmFsKSk7CgogICAgICAgIGNvbnN0IGJ5TW9udGggPSB7fTsKICAgICAgICBNT05USF9OVU1TLmZvckVhY2gobSA9PiB7IGJ5TW9udGhbbV0gPSBkYXRhLmZpbHRlcihkID0+IGQubW9udGggPT09IG0pOyB9KTsKCiAgICAgICAgY29uc3QgbWF0cml4ID0gU1BFQ0lFUy5tYXAoc3AgPT4gKHsKICAgICAgICAgICAgc3AsCiAgICAgICAgICAgIHJhdGVzOiBNT05USF9OVU1TLm1hcChtID0+IHsKICAgICAgICAgICAgICAgIGNvbnN0IG1vbnRoUm93cyA9IGJ5TW9udGhbbV07CiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZFRyaXBzID0gbW9udGhSb3dzLmZpbHRlcihyID0+ICFyLl9pc0JhZFdlYXRoZXIgJiYgKHIuYm9hdHMgPj0gMSB8fCBTUEVDSUVTLnNvbWUocyA9PiByW3MubmFtZV0gPj0gMSkpKTsKICAgICAgICAgICAgICAgIGNvbnN0IHNlZW4gPSB2YWxpZFRyaXBzLmZpbHRlcihyID0+IHJbc3AubmFtZV0gPj0gMSkubGVuZ3RoOwogICAgICAgICAgICAgICAgY29uc3QgcmF0ZSA9IHZhbGlkVHJpcHMubGVuZ3RoID4gMCA\/IHBhcnNlRmxvYXQoKHNlZW4gLyB2YWxpZFRyaXBzLmxlbmd0aCAqIDEwMCkudG9GaXhlZCgxKSkgOiBudWxsOwogICAgICAgICAgICAgICAgcmV0dXJuIHsgbSwgcjogcmF0ZSwgdHJpcHM6IHZhbGlkVHJpcHMubGVuZ3RoLCBzZWVuIH07CiAgICAgICAgICAgIH0pCiAgICAgICAgfSkpOwoKICAgICAgICBsZXQgaHRtbCA9ICc8dGhlYWQ+PHRyPic7CiAgICAgICAgaHRtbCArPSAnPHRoIGNsYXNzPSJobS1zcGVjaWVzLWNvbCI+U3BlY2llczwvdGg+JzsKICAgICAgICBNT05USFMuZm9yRWFjaChtID0+IHsgaHRtbCArPSBgPHRoPiR7bS5zbGljZSgwLDMpfTwvdGg+YDsgfSk7CiAgICAgICAgaHRtbCArPSAnPHRoIGNsYXNzPSJobS1iZXN0LWNvbCI+QmVzdCBNb250aDwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT4nOwoKICAgICAgICBtYXRyaXguZm9yRWFjaCgoeyBzcCwgcmF0ZXMgfSkgPT4gewogICAgICAgICAgICBjb25zdCBiZXN0ID0gcmF0ZXMucmVkdWNlKChiLCBjdXIpID0+IGN1ci5yID09PSBudWxsID8gYiA6ICghYiB8fCBjdXIuciA+IGIuciA\/IGN1ciA6IGIpLCBudWxsKTsKICAgICAgICAgICAgaHRtbCArPSAnPHRyPic7CiAgICAgICAgICAgIGh0bWwgKz0gYDx0ZCBjbGFzcz0iaG0tc3BlY2llcy1jb2wiPjxzcGFuIGNsYXNzPSJobS1zd2F0Y2giIHN0eWxlPSJiYWNrZ3JvdW5kOiR7c3AuY29sb3J9Ij48L3NwYW4+JHtzcGVjaWVzTGluayhzcC5uYW1lKX08L3RkPmA7CiAgICAgICAgICAgIHJhdGVzLmZvckVhY2goKHsgbSwgciwgdHJpcHMsIHNlZW4gfSkgPT4gewogICAgICAgICAgICAgICAgY29uc3QgYmcgID0gaGVhdENvbG9yKHNwLmNvbG9yLCByKTsKICAgICAgICAgICAgICAgIGNvbnN0IGZnICA9IGhlYXRUZXh0Q29sb3Ioc3AuY29sb3IsIHIpOwogICAgICAgICAgICAgICAgY29uc3QgbGJsID0gciAhPT0gbnVsbCAmJiByID4gMCA\/IGAke3J9JWAgOiAnJzsKICAgICAgICAgICAgICAgIGNvbnN0IHRpcCA9IHIgIT09IG51bGwKICAgICAgICAgICAgICAgICAgICA\/IGAke2VzYyhzcC5uYW1lKX0gXHUwMGI3ICR7TU9OVEhTW01PTlRIX05VTVMuaW5kZXhPZihtKV19IFx1MDBiNyAke3J9JSAoJHtzZWVufS8ke3RyaXBzfSB0cmlwcylgCiAgICAgICAgICAgICAgICAgICAgOiBgJHtlc2Moc3AubmFtZSl9IFx1MDBiNyAke01PTlRIU1tNT05USF9OVU1TLmluZGV4T2YobSldfSBcdTAwYjcgbm8gdHJpcHMgcmVjb3JkZWRgOwogICAgICAgICAgICAgICAgaHRtbCArPSBgPHRkIGNsYXNzPSJoZWF0LWNlbGwiIHN0eWxlPSJiYWNrZ3JvdW5kOiR7Ymd9IiBkYXRhLXRpcD0iJHt0aXB9Ij4KICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0icmF0ZS1sYWJlbCIgc3R5bGU9ImNvbG9yOiR7Zmd9Ij4ke2xibH08L3NwYW4+PC90ZD5gOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgaWYgKGJlc3QpIHsKICAgICAgICAgICAgICAgIGh0bWwgKz0gYDx0ZCBjbGFzcz0iaG0tYmVzdC1jb2wiPiR7TU9OVEhTW01PTlRIX05VTVMuaW5kZXhPZihiZXN0Lm0pXS5zbGljZSgwLDMpfSA8c3Ryb25nPiR7YmVzdC5yfSU8L3N0cm9uZz48L3RkPmA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBodG1sICs9IGA8dGQgY2xhc3M9ImhtLWJlc3QtY29sIiBzdHlsZT0iY29sb3I6I2NjYyI+XHUyMDE0PC90ZD5gOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGh0bWwgKz0gJzwvdHI+JzsKICAgICAgICB9KTsKCiAgICAgICAgaHRtbCArPSAnPC90Ym9keT4nOwogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdobS10YWJsZScpLmlubmVySFRNTCA9IGh0bWw7CiAgICB9CgogICAgLy8gXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwXHUyNTUwCiAgICAvLyBBTkFMWVRJQ1MKICAgIC8vIFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MFx1MjU1MAogICAgZnVuY3Rpb24gc2lnaHRpbmdSYXRlKHJvd3MsIHNwZWNpZXNOYW1lKSB7CiAgICAgICAgY29uc3QgdHJpcHMgPSByb3dzLmZpbHRlcihyID0+ICFyLl9pc0JhZFdlYXRoZXIgJiYgKHIuYm9hdHMgPj0gMSB8fCByLl9oYXNTaWdodGluZykpOwogICAgICAgIGlmICh0cmlwcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsOwogICAgICAgIHJldHVybiBwYXJzZUZsb2F0KCh0cmlwcy5maWx0ZXIociA9PiByW3NwZWNpZXNOYW1lXSA+PSAxKS5sZW5ndGggLyB0cmlwcy5sZW5ndGggKiAxMDApLnRvRml4ZWQoMSkpOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlZnJlc2hBbmFseXRpY3MoKSB7CiAgICAgICAgW2FTcGVjaWVzQ2hhcnQsIGFUcmVuZENoYXJ0LCBhU3VjY2Vzc0NoYXJ0XS5mb3JFYWNoKGMgPT4gYyAmJiBjLmRlc3Ryb3koKSk7CiAgICAgICAgYVNwZWNpZXNDaGFydCA9IGFUcmVuZENoYXJ0ID0gYVN1Y2Nlc3NDaGFydCA9IG51bGw7CgogICAgICAgIGNvbnN0IHllYXIgICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhLXllYXInKS52YWx1ZTsKICAgICAgICBjb25zdCBtb250aCAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS1tb250aCcpLnZhbHVlOwogICAgICAgIGNvbnN0IHRvcE5SYXcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS10b3BuJykudmFsdWU7CiAgICAgICAgY29uc3QgdG9wTiAgID0gdG9wTlJhdyA9PT0gJ2FsbCcgPyBTUEVDSUVTLmxlbmd0aCA6IHBhcnNlSW50KHRvcE5SYXcpOwogICAgICAgIGNvbnN0IG1OdW0gICA9IG1vbnRoICE9PSAnYWxsJyA\/IHBhcnNlSW50KG1vbnRoKSA6IG51bGw7CgogICAgICAgIGxldCBmaWx0ZXJlZCA9IHllYXIgPT09ICdhbGwnID8gYWxsRGF0YSA6IGFsbERhdGEuZmlsdGVyKGQgPT4gZC55ZWFyID09PSBwYXJzZUludCh5ZWFyKSk7CiAgICAgICAgaWYgKG1OdW0gIT09IG51bGwpIGZpbHRlcmVkID0gZmlsdGVyZWQuZmlsdGVyKGQgPT4gZC5tb250aCA9PT0gbU51bSk7CgogICAgICAgIGNvbnN0IHJlbGV2YW50ICAgPSBmaWx0ZXJlZC5maWx0ZXIoZCA9PiAhZC5faXNCYWRXZWF0aGVyICYmIChkLmJvYXRzID49IDEgfHwgZC5faGFzU2lnaHRpbmcpKTsKICAgICAgICBjb25zdCB0b3RhbFRyaXBzID0gcmVsZXZhbnQubGVuZ3RoOwogICAgICAgIGNvbnN0IHN1Y2Nlc3NlcyAgPSByZWxldmFudC5maWx0ZXIoZCA9PiBkLl9oYXNTaWdodGluZykubGVuZ3RoOwogICAgICAgIGNvbnN0IHJhdGUgICAgICAgPSB0b3RhbFRyaXBzID4gMCA\/IChzdWNjZXNzZXMgLyB0b3RhbFRyaXBzICogMTAwKS50b0ZpeGVkKDEpIDogJzAuMCc7CiAgICAgICAgbGV0IHRvdGFsQ291bnQgPSAwOwogICAgICAgIHJlbGV2YW50LmZvckVhY2goZCA9PiB7IFNQRUNJRVMuZm9yRWFjaChzID0+IHsgaWYgKGRbcy5uYW1lXSA+PSAxKSB0b3RhbENvdW50Kys7IH0pOyB9KTsKICAgICAgICBjb25zdCBhdmdTcCA9IHRvdGFsVHJpcHMgPiAwID8gKHRvdGFsQ291bnQgLyB0b3RhbFRyaXBzKS50b0ZpeGVkKDEpIDogJzAuMCc7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZhbC1zdWNjZXNzJykuaW5uZXJUZXh0ID0gcmF0ZSArICclJzsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmFsLXNwZWNpZXMnKS5pbm5lclRleHQgPSBhdmdTcDsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmFsLXRyaXBzJykuaW5uZXJUZXh0ICAgPSB0b3RhbFRyaXBzLnRvTG9jYWxlU3RyaW5nKCk7CgogICAgICAgIGNvbnN0IHJhdGVzID0gU1BFQ0lFUy5tYXAocyA9PiAoeyBuYW1lOiBzLm5hbWUsIHJhdGU6IHNpZ2h0aW5nUmF0ZShmaWx0ZXJlZCwgcy5uYW1lKSA\/PyAwIH0pKQogICAgICAgICAgICAuc29ydCgoYSxiKSA9PiBiLnJhdGUgLSBhLnJhdGUpLnNsaWNlKDAsIHRvcE4pOwoKICAgICAgICBjb25zdCBzcGVjaWVzQ2FudmFzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Etc3BlY2llcy1jaGFydCcpOwogICAgICAgIGNvbnN0IGNoYXJ0SGVpZ2h0ID0gTWF0aC5tYXgoMjQwLCByYXRlcy5sZW5ndGggKiAzNCk7CiAgICAgICAgbGV0IHNwZWNpZXNXcmFwcGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Etc3BlY2llcy1jaGFydC13cmFwcGVyJyk7CiAgICAgICAgaWYgKCFzcGVjaWVzV3JhcHBlcikgewogICAgICAgICAgICBzcGVjaWVzV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgICAgICBzcGVjaWVzV3JhcHBlci5pZCA9ICdhLXNwZWNpZXMtY2hhcnQtd3JhcHBlcic7CiAgICAgICAgICAgIHNwZWNpZXNXcmFwcGVyLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJzsKICAgICAgICAgICAgc3BlY2llc0NhbnZhcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzcGVjaWVzV3JhcHBlciwgc3BlY2llc0NhbnZhcyk7CiAgICAgICAgICAgIHNwZWNpZXNXcmFwcGVyLmFwcGVuZENoaWxkKHNwZWNpZXNDYW52YXMpOwogICAgICAgIH0KICAgICAgICBzcGVjaWVzV3JhcHBlci5zdHlsZS5oZWlnaHQgPSBjaGFydEhlaWdodCArICdweCc7CiAgICAgICAgc3BlY2llc0NhbnZhcy5zdHlsZS5oZWlnaHQgPSAnJzsKICAgICAgICBhU3BlY2llc0NoYXJ0ID0gbmV3IENoYXJ0KHNwZWNpZXNDYW52YXMuZ2V0Q29udGV4dCgnMmQnKSwgewogICAgICAgICAgICB0eXBlOiAnYmFyJywKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgICAgbGFiZWxzOiByYXRlcy5tYXAoYyA9PiBjLm5hbWUpLAogICAgICAgICAgICAgICAgZGF0YXNldHM6IFt7IGxhYmVsOiAnJSBvZiB0cmlwcycsIGRhdGE6IHJhdGVzLm1hcChjID0+IGMucmF0ZSksIGJhY2tncm91bmRDb2xvcjogcmF0ZXMubWFwKGMgPT4gU1BFQ0lFU19DT0xPUlNbYy5uYW1lXSB8fCAnIzExNUVCOScpLCBib3JkZXJSYWRpdXM6IDUgfV0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgb3B0aW9uczogewogICAgICAgICAgICAgICAgaW5kZXhBeGlzOiAneScsIHJlc3BvbnNpdmU6IHRydWUsIG1haW50YWluQXNwZWN0UmF0aW86IGZhbHNlLAogICAgICAgICAgICAgICAgcGx1Z2luczogeyBsZWdlbmQ6IHsgZGlzcGxheTogZmFsc2UgfSwgdG9vbHRpcDogeyBjYWxsYmFja3M6IHsgbGFiZWw6IGN0eCA9PiBgICR7Y3R4LnJhd30lIG9mIHRyaXBzYCB9IH0gfSwKICAgICAgICAgICAgICAgIHNjYWxlczogeyB4OiB7IG1pbjogMCwgbWF4OiAxMDAsIHRpY2tzOiB7IGNhbGxiYWNrOiB2ID0+IHYgKyAnJScgfSB9IH0sCiAgICAgICAgICAgICAgICBvbkNsaWNrOiAoZXZ0LCBlbHMpID0+IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWVscy5sZW5ndGgpIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gcmF0ZXNbZWxzWzBdLmluZGV4XS5uYW1lOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHMgPSBTUEVDSUVTLmZpbmQoeCA9PiB4Lm5hbWUgPT09IG5hbWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChzICYmIHMudXJsKSB3aW5kb3cub3BlbihzLnVybCwgJ19ibGFuaycsICdub29wZW5lcicpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG9uSG92ZXI6IChldnQsIGVscykgPT4gewogICAgICAgICAgICAgICAgICAgIGNvbnN0IHRndCA9IGV2dC5uYXRpdmUgJiYgZXZ0Lm5hdGl2ZS50YXJnZXQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0Z3QpIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gZWxzLmxlbmd0aCA\/IHJhdGVzW2Vsc1swXS5pbmRleF0ubmFtZSA6IG51bGw7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IG5hbWUgPyBTUEVDSUVTLmZpbmQoeCA9PiB4Lm5hbWUgPT09IG5hbWUpIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICB0Z3Quc3R5bGUuY3Vyc29yID0gKHMgJiYgcy51cmwpID8gJ3BvaW50ZXInIDogJ2RlZmF1bHQnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIGNvbnN0IHNwICAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Etc3BlY2llcy1maWx0ZXInKS52YWx1ZTsKICAgICAgICBjb25zdCBjb2xvciA9IFNQRUNJRVNfQ09MT1JTW3NwXSB8fCAnIzExNUVCOSc7CiAgICAgICAgbGV0IHRMYWJlbHMgPSBbXSwgdFZhbHVlcyA9IFtdOwoKICAgICAgICBpZiAobW9udGggIT09ICdhbGwnKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhLXRyZW5kLXRpdGxlJykuaW5uZXJIVE1MID0gYCR7c3BlY2llc0xpbmsoc3ApfSBcdTIwMTQgJHtNT05USFNbTU9OVEhfTlVNUy5pbmRleE9mKG1OdW0pXX0gc2lnaHRpbmcgcmF0ZSBieSB5ZWFyYDsKICAgICAgICAgICAgY29uc3QgeWVhcnMgPSBbLi4ubmV3IFNldChhbGxEYXRhLm1hcChkID0+IGQueWVhcikpXS5zb3J0KChhLGIpID0+IGEtYikuZmlsdGVyKHkgPT4geSAhPT0gMTk5Nik7CiAgICAgICAgICAgIHRMYWJlbHMgPSB5ZWFyczsKICAgICAgICAgICAgdFZhbHVlcyA9IHllYXJzLm1hcCh5ID0+IHNpZ2h0aW5nUmF0ZShhbGxEYXRhLmZpbHRlcihkID0+IGQueWVhciA9PT0geSAmJiBkLm1vbnRoID09PSBtTnVtKSwgc3ApKTsKICAgICAgICB9IGVsc2UgaWYgKHllYXIgPT09ICdhbGwnKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhLXRyZW5kLXRpdGxlJykuaW5uZXJIVE1MID0gYCR7c3BlY2llc0xpbmsoc3ApfSBcdTIwMTQgc2lnaHRpbmcgcmF0ZSBieSB5ZWFyYDsKICAgICAgICAgICAgY29uc3QgeWVhcnMgPSBbLi4ubmV3IFNldChhbGxEYXRhLm1hcChkID0+IGQueWVhcikpXS5zb3J0KChhLGIpID0+IGEtYikuZmlsdGVyKHkgPT4geSAhPT0gMTk5Nik7CiAgICAgICAgICAgIHRMYWJlbHMgPSB5ZWFyczsKICAgICAgICAgICAgdFZhbHVlcyA9IHllYXJzLm1hcCh5ID0+IHNpZ2h0aW5nUmF0ZShhbGxEYXRhLmZpbHRlcihkID0+IGQueWVhciA9PT0geSksIHNwKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2EtdHJlbmQtdGl0bGUnKS5pbm5lckhUTUwgPSBgJHtzcGVjaWVzTGluayhzcCl9IFx1MjAxNCAke3llYXJ9IHNpZ2h0aW5nIHJhdGUgYnkgbW9udGhgOwogICAgICAgICAgICBjb25zdCB5ZWFyRGF0YSA9IGFsbERhdGEuZmlsdGVyKGQgPT4gZC55ZWFyID09PSBwYXJzZUludCh5ZWFyKSk7CiAgICAgICAgICAgIHRMYWJlbHMgPSBNT05USFM7CiAgICAgICAgICAgIHRWYWx1ZXMgPSBNT05USFMubWFwKChfbW4sIGlkeCkgPT4gc2lnaHRpbmdSYXRlKHllYXJEYXRhLmZpbHRlcihkID0+IGQubW9udGggPT09IGlkeCArIDMpLCBzcCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGFUcmVuZENoYXJ0KSBhVHJlbmRDaGFydC5kZXN0cm95KCk7CiAgICAgICAgYVRyZW5kQ2hhcnQgPSBuZXcgQ2hhcnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2EtdHJlbmQtY2hhcnQnKS5nZXRDb250ZXh0KCcyZCcpLCB7CiAgICAgICAgICAgIHR5cGU6ICdiYXInLAogICAgICAgICAgICBkYXRhOiB7IGxhYmVsczogdExhYmVscywgZGF0YXNldHM6IFt7IGxhYmVsOiBzcCwgZGF0YTogdFZhbHVlcywgYmFja2dyb3VuZENvbG9yOiBjb2xvcisnY2MnLCBib3JkZXJDb2xvcjogY29sb3IsIGJvcmRlcldpZHRoOiAxLCBib3JkZXJSYWRpdXM6IDQgfV0gfSwKICAgICAgICAgICAgb3B0aW9uczogewogICAgICAgICAgICAgICAgcmVzcG9uc2l2ZTogdHJ1ZSwKICAgICAgICAgICAgICAgIHBsdWdpbnM6IHsgbGVnZW5kOiB7IGRpc3BsYXk6IGZhbHNlIH0sIHRvb2x0aXA6IHsgY2FsbGJhY2tzOiB7IGxhYmVsOiBjdHggPT4gY3R4LnJhdyAhPT0gbnVsbCA\/IGAgJHtjdHgucmF3fSUgb2YgdHJpcHNgIDogJyBubyBkYXRhJyB9IH0gfSwKICAgICAgICAgICAgICAgIHNjYWxlczogeyB5OiB7IGJlZ2luQXRaZXJvOiB0cnVlLCBtYXg6IDEwMCwgdGlja3M6IHsgY2FsbGJhY2s6IHYgPT4gdiArICclJyB9IH0gfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIGxldCBzTGFiZWxzID0gW10sIHNSYXRlcyA9IFtdOwogICAgICAgIGlmIChtb250aCAhPT0gJ2FsbCcpIHsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Etc3VjY2Vzcy10aXRsZScpLmlubmVyVGV4dCA9IGAke01PTlRIU1tNT05USF9OVU1TLmluZGV4T2YobU51bSldfSBcdTIwMTQgSGlzdG9yaWNhbCBTdWNjZXNzIFJhdGVgOwogICAgICAgICAgICBjb25zdCB5ZWFycyA9IFsuLi5uZXcgU2V0KGFsbERhdGEubWFwKGQgPT4gZC55ZWFyKSldLnNvcnQoKGEsYikgPT4gYS1iKS5maWx0ZXIoeSA9PiB5ICE9PSAxOTk2KTsKICAgICAgICAgICAgc0xhYmVscyA9IHllYXJzOwogICAgICAgICAgICBzUmF0ZXMgID0geWVhcnMubWFwKHkgPT4gewogICAgICAgICAgICAgICAgY29uc3QgbURhdGEgPSBhbGxEYXRhLmZpbHRlcihkID0+IGQueWVhciA9PT0geSAmJiBkLm1vbnRoID09PSBtTnVtKTsKICAgICAgICAgICAgICAgIGNvbnN0IHJlbCAgID0gbURhdGEuZmlsdGVyKGQgPT4gIWQuX2lzQmFkV2VhdGhlciAmJiAoZC5ib2F0cyA+PSAxIHx8IGQuX2hhc1NpZ2h0aW5nKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVsLmxlbmd0aCA+IDAgPyBwYXJzZUZsb2F0KChyZWwuZmlsdGVyKHIgPT4gci5faGFzU2lnaHRpbmcpLmxlbmd0aCAvIHJlbC5sZW5ndGggKiAxMDApLnRvRml4ZWQoMSkpIDogbnVsbDsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIGlmICh5ZWFyID09PSAnYWxsJykgewogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS1zdWNjZXNzLXRpdGxlJykuaW5uZXJUZXh0ID0gJ1NpZ2h0aW5nIFN1Y2Nlc3MgT3ZlciBZZWFycyc7CiAgICAgICAgICAgIGNvbnN0IHllYXJzID0gWy4uLm5ldyBTZXQoYWxsRGF0YS5tYXAoZCA9PiBkLnllYXIpKV0uc29ydCgoYSxiKSA9PiBhLWIpLmZpbHRlcih5ID0+IHkgIT09IDE5OTYpOwogICAgICAgICAgICBzTGFiZWxzID0geWVhcnM7CiAgICAgICAgICAgIHNSYXRlcyAgPSB5ZWFycy5tYXAoeSA9PiB7CiAgICAgICAgICAgICAgICBjb25zdCByZWwgPSBhbGxEYXRhLmZpbHRlcihkID0+IGQueWVhciA9PT0geSAmJiAhZC5faXNCYWRXZWF0aGVyICYmIChkLmJvYXRzID49IDEgfHwgZC5faGFzU2lnaHRpbmcpKTsKICAgICAgICAgICAgICAgIHJldHVybiByZWwubGVuZ3RoID4gMCA\/IHBhcnNlRmxvYXQoKHJlbC5maWx0ZXIociA9PiByLl9oYXNTaWdodGluZykubGVuZ3RoIC8gcmVsLmxlbmd0aCAqIDEwMCkudG9GaXhlZCgxKSkgOiBudWxsOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS1zdWNjZXNzLXRpdGxlJykuaW5uZXJUZXh0ID0gYE1vbnRobHkgU2lnaHRpbmcgU3VjY2VzcyAoJHt5ZWFyfSlgOwogICAgICAgICAgICBjb25zdCB5ZWFyRGF0YSA9IGFsbERhdGEuZmlsdGVyKGQgPT4gZC55ZWFyID09PSBwYXJzZUludCh5ZWFyKSk7CiAgICAgICAgICAgIHNMYWJlbHMgPSBNT05USFM7CiAgICAgICAgICAgIHNSYXRlcyAgPSBNT05USFMubWFwKChtLCBpZHgpID0+IHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlbCA9IHllYXJEYXRhLmZpbHRlcihkID0+IGQubW9udGggPT09IGlkeCArIDMgJiYgIWQuX2lzQmFkV2VhdGhlciAmJiAoZC5ib2F0cyA+PSAxIHx8IGQuX2hhc1NpZ2h0aW5nKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVsLmxlbmd0aCA+IDAgPyBwYXJzZUZsb2F0KChyZWwuZmlsdGVyKHIgPT4gci5faGFzU2lnaHRpbmcpLmxlbmd0aCAvIHJlbC5sZW5ndGggKiAxMDApLnRvRml4ZWQoMSkpIDogbnVsbDsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoYVN1Y2Nlc3NDaGFydCkgYVN1Y2Nlc3NDaGFydC5kZXN0cm95KCk7CiAgICAgICAgYVN1Y2Nlc3NDaGFydCA9IG5ldyBDaGFydChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS1zdWNjZXNzLWNoYXJ0JykuZ2V0Q29udGV4dCgnMmQnKSwgewogICAgICAgICAgICB0eXBlOiAnbGluZScsCiAgICAgICAgICAgIGRhdGE6IHsgbGFiZWxzOiBzTGFiZWxzLCBkYXRhc2V0czogW3sgbGFiZWw6ICdTdWNjZXNzIFJhdGUgKCUpJywgZGF0YTogc1JhdGVzLCBib3JkZXJDb2xvcjogJyMxMTVFQjknLCBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDE3LDk0LDE4NSwwLjEpJywgZmlsbDogdHJ1ZSwgdGVuc2lvbjogMC4zLCBzcGFuR2FwczogdHJ1ZSB9XSB9LAogICAgICAgICAgICBvcHRpb25zOiB7CiAgICAgICAgICAgICAgICByZXNwb25zaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgc2NhbGVzOiB7IHk6IHsgYmVnaW5BdFplcm86IGZhbHNlLCBzdWdnZXN0ZWRNaW46IHNSYXRlcy5sZW5ndGggPiAwID8gTWF0aC5tYXgoMCwgTWF0aC5taW4oLi4uc1JhdGVzLmZpbHRlcihyID0+IHIgIT09IG51bGwpKSAtIDUpIDogMCB9IH0sCiAgICAgICAgICAgICAgICBwbHVnaW5zOiB7IGxlZ2VuZDogeyBkaXNwbGF5OiBmYWxzZSB9IH0KICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbmRlckFuYWx5dGljc0xlZ2VuZCgpIHsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYS1sZWdlbmQnKS5pbm5lckhUTUwgPSBTUEVDSUVTLm1hcChzID0+CiAgICAgICAgICAgIGA8ZGl2IGNsYXNzPSJzcGVjaWVzLWxlZ2VuZC1pdGVtIj4KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImxlZ2VuZC1zd2F0Y2giIHN0eWxlPSJiYWNrZ3JvdW5kOiR7cy5jb2xvcn0iPjwvZGl2PgogICAgICAgICAgICAgICAgPHNwYW4+JHtzLm5hbWV9PC9zcGFuPgogICAgICAgICAgICA8L2Rpdj5gCiAgICAgICAgKS5qb2luKCcnKTsKICAgIH0KICAgIH0gLy8gZW5kIGluaXQoKQp9KSgpOw==\";\n            var _s = document.createElement('script');\n            _s.textContent = atob(_b64);\n            document.body.appendChild(_s);\n        } catch (e) {\n            console.error('[Talassa] Bootstrap failed:', e);\n        }\n\n        \/\/ Tooltip for heatmap cells\n        (function () {\n            var tip = document.getElementById('t-tooltip');\n            if (!tip) return;\n            document.addEventListener('mousemove', function (e) {\n                var el = e.target.closest ? e.target.closest('[data-tip]') : null;\n                if (el && el.dataset.tip) {\n                    tip.textContent = el.dataset.tip;\n                    tip.style.display = 'block';\n                    var x = e.clientX, y = e.clientY;\n                    var tw = tip.offsetWidth;\n                    var vw = window.innerWidth;\n                    \/\/ Keep tooltip inside viewport\n                    var left = x - tw \/ 2;\n                    if (left < 8) left = 8;\n                    if (left + tw > vw - 8) left = vw - tw - 8;\n                    tip.style.left = left + 'px';\n                    tip.style.top = (y - tip.offsetHeight - 10) + 'px';\n                } else {\n                    tip.style.display = 'none';\n                }\n            });\n            document.addEventListener('mouseleave', function () { tip.style.display = 'none'; });\n            var loaderError = document.getElementById('loader-error');\n            loaderError.style.display = 'none';\n        })();\n    })();\n<\/script>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cetaceans of the Azores Around 90 species of cetaceans, whales, dolphins, and porpoises, inhabit our planet\u2019s seas, oceans, and even some rivers.In the Azores, 29 species have been officially recorded: an impressive number for such a small region in the middle of the Atlantic Ocean. Every Trip is Unique On average, our guests encounter 3 [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"parent":6214,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"rank_math_title":"","rank_math_description":"Discover Azores cetacean sightings data. Experience 3-4 species per trip with 99% encounter rates. Book your whale watching adventure today.","rank_math_facebook_title":"See Whales & Dolphins in the Azores","rank_math_facebook_description":"99% encounter rate. 3-4 species per trip. Dive into live cetacean sightings statistics from Pico island's premier whale watching operator.","rank_math_facebook_image":"","rank_math_twitter_title":"See Whales & Dolphins in the Azores","rank_math_twitter_description":"99% encounter rate. 3-4 species per trip. Dive into live cetacean sightings statistics from Pico island's premier whale watching operator.","rank_math_focus_keyword":"","rank_math_facebook_image_id":0,"rank_math_robots":[],"footnotes":""},"class_list":["post-9986","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/pages\/9986","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/comments?post=9986"}],"version-history":[{"count":89,"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/pages\/9986\/revisions"}],"predecessor-version":[{"id":35877,"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/pages\/9986\/revisions\/35877"}],"up":[{"embeddable":true,"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/pages\/6214"}],"wp:attachment":[{"href":"https:\/\/espacotalassa.com\/en\/wp-json\/wp\/v2\/media?parent=9986"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}