// source --> https://bisonapp.com/wp-content/plugins/wp-data-access/public/../assets/js/wpda_rest_api.js?ver=5.5.62 
function wpda_rest_api(path, data, callbackOk, callbackError, method = "POST") {
	jQuery.ajax({
		url: wpApiSettings.root + wpdaApiSettings.path + "/" + path,
		method: method,
		beforeSend: function (xhr) {
			xhr.setRequestHeader("X-WP-Nonce", wpApiSettings.nonce);
		},
		data: data
	}).done(function(response) {
		if (callbackOk!==undefined) {
			callbackOk(response)
		} else {
			console.error("Missing API callback. Server response:")
			console.error(response)
		}
	}).fail(function(response) {
		if (callbackError!==undefined) {
			callbackError(response)
		} else {
			console.error("Missing API callback. Server response:")
			console.error(response)
		}
	})
};
// source --> https://bisonapp.com/wp-content/plugins/elementor/assets/lib/font-awesome/js/v4-shims.min.js?ver=3.33.1 
/*!
 * Font Awesome Free 5.15.1 by @fontawesome - https://fontawesome.com
 * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
 */
(function(){var l,a;l=this,a=function(){"use strict";var l={},a={};try{"undefined"!=typeof window&&(l=window),"undefined"!=typeof document&&(a=document)}catch(l){}var e=(l.navigator||{}).userAgent,r=void 0===e?"":e,n=l,o=a,u=(n.document,!!o.documentElement&&!!o.head&&"function"==typeof o.addEventListener&&o.createElement,~r.indexOf("MSIE")||r.indexOf("Trident/"),"___FONT_AWESOME___"),t=function(){try{return"production"===process.env.NODE_ENV}catch(l){return!1}}();var f=n||{};f[u]||(f[u]={}),f[u].styles||(f[u].styles={}),f[u].hooks||(f[u].hooks={}),f[u].shims||(f[u].shims=[]);var i=f[u],s=[["glass",null,"glass-martini"],["meetup","fab",null],["star-o","far","star"],["remove",null,"times"],["close",null,"times"],["gear",null,"cog"],["trash-o","far","trash-alt"],["file-o","far","file"],["clock-o","far","clock"],["arrow-circle-o-down","far","arrow-alt-circle-down"],["arrow-circle-o-up","far","arrow-alt-circle-up"],["play-circle-o","far","play-circle"],["repeat",null,"redo"],["rotate-right",null,"redo"],["refresh",null,"sync"],["list-alt","far",null],["dedent",null,"outdent"],["video-camera",null,"video"],["picture-o","far","image"],["photo","far","image"],["image","far","image"],["pencil",null,"pencil-alt"],["map-marker",null,"map-marker-alt"],["pencil-square-o","far","edit"],["share-square-o","far","share-square"],["check-square-o","far","check-square"],["arrows",null,"arrows-alt"],["times-circle-o","far","times-circle"],["check-circle-o","far","check-circle"],["mail-forward",null,"share"],["expand",null,"expand-alt"],["compress",null,"compress-alt"],["eye","far",null],["eye-slash","far",null],["warning",null,"exclamation-triangle"],["calendar",null,"calendar-alt"],["arrows-v",null,"arrows-alt-v"],["arrows-h",null,"arrows-alt-h"],["bar-chart","far","chart-bar"],["bar-chart-o","far","chart-bar"],["twitter-square","fab",null],["facebook-square","fab",null],["gears",null,"cogs"],["thumbs-o-up","far","thumbs-up"],["thumbs-o-down","far","thumbs-down"],["heart-o","far","heart"],["sign-out",null,"sign-out-alt"],["linkedin-square","fab","linkedin"],["thumb-tack",null,"thumbtack"],["external-link",null,"external-link-alt"],["sign-in",null,"sign-in-alt"],["github-square","fab",null],["lemon-o","far","lemon"],["square-o","far","square"],["bookmark-o","far","bookmark"],["twitter","fab",null],["facebook","fab","facebook-f"],["facebook-f","fab","facebook-f"],["github","fab",null],["credit-card","far",null],["feed",null,"rss"],["hdd-o","far","hdd"],["hand-o-right","far","hand-point-right"],["hand-o-left","far","hand-point-left"],["hand-o-up","far","hand-point-up"],["hand-o-down","far","hand-point-down"],["arrows-alt",null,"expand-arrows-alt"],["group",null,"users"],["chain",null,"link"],["scissors",null,"cut"],["files-o","far","copy"],["floppy-o","far","save"],["navicon",null,"bars"],["reorder",null,"bars"],["pinterest","fab",null],["pinterest-square","fab",null],["google-plus-square","fab",null],["google-plus","fab","google-plus-g"],["money","far","money-bill-alt"],["unsorted",null,"sort"],["sort-desc",null,"sort-down"],["sort-asc",null,"sort-up"],["linkedin","fab","linkedin-in"],["rotate-left",null,"undo"],["legal",null,"gavel"],["tachometer",null,"tachometer-alt"],["dashboard",null,"tachometer-alt"],["comment-o","far","comment"],["comments-o","far","comments"],["flash",null,"bolt"],["clipboard","far",null],["paste","far","clipboard"],["lightbulb-o","far","lightbulb"],["exchange",null,"exchange-alt"],["cloud-download",null,"cloud-download-alt"],["cloud-upload",null,"cloud-upload-alt"],["bell-o","far","bell"],["cutlery",null,"utensils"],["file-text-o","far","file-alt"],["building-o","far","building"],["hospital-o","far","hospital"],["tablet",null,"tablet-alt"],["mobile",null,"mobile-alt"],["mobile-phone",null,"mobile-alt"],["circle-o","far","circle"],["mail-reply",null,"reply"],["github-alt","fab",null],["folder-o","far","folder"],["folder-open-o","far","folder-open"],["smile-o","far","smile"],["frown-o","far","frown"],["meh-o","far","meh"],["keyboard-o","far","keyboard"],["flag-o","far","flag"],["mail-reply-all",null,"reply-all"],["star-half-o","far","star-half"],["star-half-empty","far","star-half"],["star-half-full","far","star-half"],["code-fork",null,"code-branch"],["chain-broken",null,"unlink"],["shield",null,"shield-alt"],["calendar-o","far","calendar"],["maxcdn","fab",null],["html5","fab",null],["css3","fab",null],["ticket",null,"ticket-alt"],["minus-square-o","far","minus-square"],["level-up",null,"level-up-alt"],["level-down",null,"level-down-alt"],["pencil-square",null,"pen-square"],["external-link-square",null,"external-link-square-alt"],["compass","far",null],["caret-square-o-down","far","caret-square-down"],["toggle-down","far","caret-square-down"],["caret-square-o-up","far","caret-square-up"],["toggle-up","far","caret-square-up"],["caret-square-o-right","far","caret-square-right"],["toggle-right","far","caret-square-right"],["eur",null,"euro-sign"],["euro",null,"euro-sign"],["gbp",null,"pound-sign"],["usd",null,"dollar-sign"],["dollar",null,"dollar-sign"],["inr",null,"rupee-sign"],["rupee",null,"rupee-sign"],["jpy",null,"yen-sign"],["cny",null,"yen-sign"],["rmb",null,"yen-sign"],["yen",null,"yen-sign"],["rub",null,"ruble-sign"],["ruble",null,"ruble-sign"],["rouble",null,"ruble-sign"],["krw",null,"won-sign"],["won",null,"won-sign"],["btc","fab",null],["bitcoin","fab","btc"],["file-text",null,"file-alt"],["sort-alpha-asc",null,"sort-alpha-down"],["sort-alpha-desc",null,"sort-alpha-down-alt"],["sort-amount-asc",null,"sort-amount-down"],["sort-amount-desc",null,"sort-amount-down-alt"],["sort-numeric-asc",null,"sort-numeric-down"],["sort-numeric-desc",null,"sort-numeric-down-alt"],["youtube-square","fab",null],["youtube","fab",null],["xing","fab",null],["xing-square","fab",null],["youtube-play","fab","youtube"],["dropbox","fab",null],["stack-overflow","fab",null],["instagram","fab",null],["flickr","fab",null],["adn","fab",null],["bitbucket","fab",null],["bitbucket-square","fab","bitbucket"],["tumblr","fab",null],["tumblr-square","fab",null],["long-arrow-down",null,"long-arrow-alt-down"],["long-arrow-up",null,"long-arrow-alt-up"],["long-arrow-left",null,"long-arrow-alt-left"],["long-arrow-right",null,"long-arrow-alt-right"],["apple","fab",null],["windows","fab",null],["android","fab",null],["linux","fab",null],["dribbble","fab",null],["skype","fab",null],["foursquare","fab",null],["trello","fab",null],["gratipay","fab",null],["gittip","fab","gratipay"],["sun-o","far","sun"],["moon-o","far","moon"],["vk","fab",null],["weibo","fab",null],["renren","fab",null],["pagelines","fab",null],["stack-exchange","fab",null],["arrow-circle-o-right","far","arrow-alt-circle-right"],["arrow-circle-o-left","far","arrow-alt-circle-left"],["caret-square-o-left","far","caret-square-left"],["toggle-left","far","caret-square-left"],["dot-circle-o","far","dot-circle"],["vimeo-square","fab",null],["try",null,"lira-sign"],["turkish-lira",null,"lira-sign"],["plus-square-o","far","plus-square"],["slack","fab",null],["wordpress","fab",null],["openid","fab",null],["institution",null,"university"],["bank",null,"university"],["mortar-board",null,"graduation-cap"],["yahoo","fab",null],["google","fab",null],["reddit","fab",null],["reddit-square","fab",null],["stumbleupon-circle","fab",null],["stumbleupon","fab",null],["delicious","fab",null],["digg","fab",null],["pied-piper-pp","fab",null],["pied-piper-alt","fab",null],["drupal","fab",null],["joomla","fab",null],["spoon",null,"utensil-spoon"],["behance","fab",null],["behance-square","fab",null],["steam","fab",null],["steam-square","fab",null],["automobile",null,"car"],["envelope-o","far","envelope"],["spotify","fab",null],["deviantart","fab",null],["soundcloud","fab",null],["file-pdf-o","far","file-pdf"],["file-word-o","far","file-word"],["file-excel-o","far","file-excel"],["file-powerpoint-o","far","file-powerpoint"],["file-image-o","far","file-image"],["file-photo-o","far","file-image"],["file-picture-o","far","file-image"],["file-archive-o","far","file-archive"],["file-zip-o","far","file-archive"],["file-audio-o","far","file-audio"],["file-sound-o","far","file-audio"],["file-video-o","far","file-video"],["file-movie-o","far","file-video"],["file-code-o","far","file-code"],["vine","fab",null],["codepen","fab",null],["jsfiddle","fab",null],["life-ring","far",null],["life-bouy","far","life-ring"],["life-buoy","far","life-ring"],["life-saver","far","life-ring"],["support","far","life-ring"],["circle-o-notch",null,"circle-notch"],["rebel","fab",null],["ra","fab","rebel"],["resistance","fab","rebel"],["empire","fab",null],["ge","fab","empire"],["git-square","fab",null],["git","fab",null],["hacker-news","fab",null],["y-combinator-square","fab","hacker-news"],["yc-square","fab","hacker-news"],["tencent-weibo","fab",null],["qq","fab",null],["weixin","fab",null],["wechat","fab","weixin"],["send",null,"paper-plane"],["paper-plane-o","far","paper-plane"],["send-o","far","paper-plane"],["circle-thin","far","circle"],["header",null,"heading"],["sliders",null,"sliders-h"],["futbol-o","far","futbol"],["soccer-ball-o","far","futbol"],["slideshare","fab",null],["twitch","fab",null],["yelp","fab",null],["newspaper-o","far","newspaper"],["paypal","fab",null],["google-wallet","fab",null],["cc-visa","fab",null],["cc-mastercard","fab",null],["cc-discover","fab",null],["cc-amex","fab",null],["cc-paypal","fab",null],["cc-stripe","fab",null],["bell-slash-o","far","bell-slash"],["trash",null,"trash-alt"],["copyright","far",null],["eyedropper",null,"eye-dropper"],["area-chart",null,"chart-area"],["pie-chart",null,"chart-pie"],["line-chart",null,"chart-line"],["lastfm","fab",null],["lastfm-square","fab",null],["ioxhost","fab",null],["angellist","fab",null],["cc","far","closed-captioning"],["ils",null,"shekel-sign"],["shekel",null,"shekel-sign"],["sheqel",null,"shekel-sign"],["meanpath","fab","font-awesome"],["buysellads","fab",null],["connectdevelop","fab",null],["dashcube","fab",null],["forumbee","fab",null],["leanpub","fab",null],["sellsy","fab",null],["shirtsinbulk","fab",null],["simplybuilt","fab",null],["skyatlas","fab",null],["diamond","far","gem"],["intersex",null,"transgender"],["facebook-official","fab","facebook"],["pinterest-p","fab",null],["whatsapp","fab",null],["hotel",null,"bed"],["viacoin","fab",null],["medium","fab",null],["y-combinator","fab",null],["yc","fab","y-combinator"],["optin-monster","fab",null],["opencart","fab",null],["expeditedssl","fab",null],["battery-4",null,"battery-full"],["battery",null,"battery-full"],["battery-3",null,"battery-three-quarters"],["battery-2",null,"battery-half"],["battery-1",null,"battery-quarter"],["battery-0",null,"battery-empty"],["object-group","far",null],["object-ungroup","far",null],["sticky-note-o","far","sticky-note"],["cc-jcb","fab",null],["cc-diners-club","fab",null],["clone","far",null],["hourglass-o","far","hourglass"],["hourglass-1",null,"hourglass-start"],["hourglass-2",null,"hourglass-half"],["hourglass-3",null,"hourglass-end"],["hand-rock-o","far","hand-rock"],["hand-grab-o","far","hand-rock"],["hand-paper-o","far","hand-paper"],["hand-stop-o","far","hand-paper"],["hand-scissors-o","far","hand-scissors"],["hand-lizard-o","far","hand-lizard"],["hand-spock-o","far","hand-spock"],["hand-pointer-o","far","hand-pointer"],["hand-peace-o","far","hand-peace"],["registered","far",null],["creative-commons","fab",null],["gg","fab",null],["gg-circle","fab",null],["tripadvisor","fab",null],["odnoklassniki","fab",null],["odnoklassniki-square","fab",null],["get-pocket","fab",null],["wikipedia-w","fab",null],["safari","fab",null],["chrome","fab",null],["firefox","fab",null],["opera","fab",null],["internet-explorer","fab",null],["television",null,"tv"],["contao","fab",null],["500px","fab",null],["amazon","fab",null],["calendar-plus-o","far","calendar-plus"],["calendar-minus-o","far","calendar-minus"],["calendar-times-o","far","calendar-times"],["calendar-check-o","far","calendar-check"],["map-o","far","map"],["commenting",null,"comment-dots"],["commenting-o","far","comment-dots"],["houzz","fab",null],["vimeo","fab","vimeo-v"],["black-tie","fab",null],["fonticons","fab",null],["reddit-alien","fab",null],["edge","fab",null],["credit-card-alt",null,"credit-card"],["codiepie","fab",null],["modx","fab",null],["fort-awesome","fab",null],["usb","fab",null],["product-hunt","fab",null],["mixcloud","fab",null],["scribd","fab",null],["pause-circle-o","far","pause-circle"],["stop-circle-o","far","stop-circle"],["bluetooth","fab",null],["bluetooth-b","fab",null],["gitlab","fab",null],["wpbeginner","fab",null],["wpforms","fab",null],["envira","fab",null],["wheelchair-alt","fab","accessible-icon"],["question-circle-o","far","question-circle"],["volume-control-phone",null,"phone-volume"],["asl-interpreting",null,"american-sign-language-interpreting"],["deafness",null,"deaf"],["hard-of-hearing",null,"deaf"],["glide","fab",null],["glide-g","fab",null],["signing",null,"sign-language"],["viadeo","fab",null],["viadeo-square","fab",null],["snapchat","fab",null],["snapchat-ghost","fab",null],["snapchat-square","fab",null],["pied-piper","fab",null],["first-order","fab",null],["yoast","fab",null],["themeisle","fab",null],["google-plus-official","fab","google-plus"],["google-plus-circle","fab","google-plus"],["font-awesome","fab",null],["fa","fab","font-awesome"],["handshake-o","far","handshake"],["envelope-open-o","far","envelope-open"],["linode","fab",null],["address-book-o","far","address-book"],["vcard",null,"address-card"],["address-card-o","far","address-card"],["vcard-o","far","address-card"],["user-circle-o","far","user-circle"],["user-o","far","user"],["id-badge","far",null],["drivers-license",null,"id-card"],["id-card-o","far","id-card"],["drivers-license-o","far","id-card"],["quora","fab",null],["free-code-camp","fab",null],["telegram","fab",null],["thermometer-4",null,"thermometer-full"],["thermometer",null,"thermometer-full"],["thermometer-3",null,"thermometer-three-quarters"],["thermometer-2",null,"thermometer-half"],["thermometer-1",null,"thermometer-quarter"],["thermometer-0",null,"thermometer-empty"],["bathtub",null,"bath"],["s15",null,"bath"],["window-maximize","far",null],["window-restore","far",null],["times-rectangle",null,"window-close"],["window-close-o","far","window-close"],["times-rectangle-o","far","window-close"],["bandcamp","fab",null],["grav","fab",null],["etsy","fab",null],["imdb","fab",null],["ravelry","fab",null],["eercast","fab","sellcast"],["snowflake-o","far","snowflake"],["superpowers","fab",null],["wpexplorer","fab",null],["cab",null,"taxi"]];return function(l){try{l()}catch(l){if(!t)throw l}}(function(){var l;"function"==typeof i.hooks.addShims?i.hooks.addShims(s):(l=i.shims).push.apply(l,s)}),s},"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):l["fontawesome-free-shims"]=a();})();
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/43016.js?v=2192 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Mar 11 2026 | 12:36:31 */
class CandlestickChart {
  constructor(canvasId, period, type) {
    this.lang =  document.documentElement.lang.split('-')[0] || 'en';
    this.canvas = jQuery("#" + canvasId)[0];
    this.historyData = {};
    this.ctx = this.canvas.getContext("2d");
    this.ctx.canvas.width = 1000;
    this.ctx.canvas.height = 400;
    this.gradient = this.ctx.createLinearGradient(0, 0, 0, 400);
    this.gradient.addColorStop(0, "rgba(106, 212, 230, 0.4)");
    this.gradient.addColorStop(0.7, "rgba(106, 212, 230, 0)");
    this.type = type;
    this.pair = jQuery("#" + canvasId).data("currency") || "btceur";
    this.graphBg = "gradient";
    this.borderColor = "rgba(7, 149, 172, 1)";
    this.period = period;
    this.oldPrices = {};
    this.newPrice = 0;
    this.historyData = [];
    this.lastPrice = 0;
    this.pairToLabel = {};
    this.intervals = [
      {
        duration: "3H",
        periods: "30s",
      },
      {
        duration: "24H",
        periods: "5m",
      },
      {
        duration: "7D",
        periods: "30m",
      },
      {
        duration: "30D",
        periods: "2h",
      },
      {
        duration: "12M",
        periods: "1d",
      },
      {
        duration: "MAX",
        periods: "1w",
      },
    ];

    this.legendText = {
      de: {
        currentPrice: "Aktueller Preis",
        last: "Letzte",
      },
      en: {
        currentPrice: "Current Price",
        last: "Last",
      },
    };

    this.chart = this.initChart();
    this.loadData(this.pair, this.period, this.type);
    this.startPriceUpdates();
	this.onResize = () => {
		this.chart.options.scales.x.ticks.maxTicksLimit = window.innerWidth < 768 ? 2 : 8;;
		this.chart.update('none');
	};

	window.addEventListener('resize', this.onResize, { passive: true });  
  }
  buildChartConfig(type) {
    const isOHLC = type === "ohlc";

    return {
      type: isOHLC ? "candlestick" : "line",
      data: {
        datasets: [
          {
            label: "Chart",
            height: 300,
            fill: !isOHLC,
            backgroundColor: this.gradient,
            borderColor: this.borderColor,
            pointRadius: 0,
            pointHitRadius: 1,
            borderWidth: 1,
            pointStyle: "none",
            // colors only used by financial controller
            backgroundColors: {
              up: "#00854D",
              down: "#BF0030",
              unchanged: "gray",
            },
          },
        ],
      },
      options: {
        interaction: { intersect: false, mode: "index", axis: "x" },
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          tooltip: {
            bodyFont: { family: "monospace", size: 12 },
            titleFont: { family: "monospace", size: 13, weight: "bold" },
            displayColors: false,
            callbacks: {
                    title(context) {
                	return new Date(context[0].parsed.x).toLocaleString();
              },
              label: (context) => {
                // IMPORTANT: read current type from chart config, not a closed-over var
                const nowIsOHLC = context.chart.config.type === "candlestick";
                const d = context.raw;
                const pad = (label, val) =>
                  label.padEnd(10) + String(val).padStart(10);
                return nowIsOHLC
                  ? [
                      pad("Open:", d.o.toFixed(6)),
                      pad("High:", d.h.toFixed(6)),
                      pad("Low:", d.l.toFixed(6)),
                      pad("Close:", d.c.toFixed(6)),
                    ]
                  : [pad("Close:", d.y.toFixed(6))];
              },
            },
          },
          legend: { display: false },
        },
        scales: {
          x: {
            grid: { display: false },
            type: "linear",
            ticks: {
              autoSkip: true,
              maxTicksLimit: window.innerWidth < 768 ? 2 : 8,
              callback: (value) => 
				    this.intervals.findIndex(i => i.periods === this.period) > this.intervals.findIndex(i => i.periods === "5m")					
					? `${new Date(value).getDate()}/${new Date(value).getMonth()+1}/${new Date(value).getFullYear()} ${String(new Date(value).getHours()).padStart(2,"0")}:${String(new Date(value).getSeconds()).padStart(2,"0")}`
					: `${String(new Date(value).getHours()).padStart(2,"0")}:${String(new Date(value).getMinutes()).padStart(2,"0")}`
				
            },
            offset: false,
            beginAtZero: false,
          },
          y: {
            grid: { display: false },
            type: "linear",
            offset: false,
            beginAtZero: false,
          },
        },
      },
    };
  }

  bindUIOnce() {
    if (this._uiBound) return;
    const self = this;
    jQuery(".graph-switch").on("click", function () {
      const newPeriod = jQuery(this).data("period");
      self.setPeriod(newPeriod);
      self.period = newPeriod;
      jQuery(".graph-switch").removeClass("active");
      jQuery(this).addClass("active");
      // self.updateLabels();
    });
    jQuery(".line-switch").on("click", function () {
      const lineType = jQuery(this).data("linetype");
      self.setType(lineType); // will rebuild chart
      self.type = lineType;
      jQuery(".line-switch").removeClass("active");
      jQuery(this).addClass("active");
    });
    this._uiBound = true;
  }
  initChart() {
    this.bindUIOnce();

    let charType = this.type;
    let pairToLabel = this.pairToLabel;
    jQuery.ajax({
      url: `${location.protocol}//${location.host}/wp-content/static/coins.json`,
      headers: [],
      success: function (result) {
        //result  = JSON.parse(result)
        for (var i = 0; i < Object.keys(result).length; i++) {
          pairToLabel[Object.keys(result)[i] + "eur"] =
            result[Object.keys(result)[i]]["name"] +
            " (" +
            Object.keys(result)[i].toUpperCase() +
            ")";
        }
      },
    });
    return new Chart(this.ctx, {
      type: this.type === "ohlc" ? "candlestick" : "line",
      data: {
        datasets: [
          {
            label: "Chart",
            height: 300,
            fill: true,
            backgroundColor: this.gradient,
            borderColor: this.borderColor,
            pointRadius: 0,
            pointHitRadius: 1,
            borderWidth: 1,
            autoSkip: true,
            pointStyle: "none",
            showLines: false,
            data: [],
            hidden: false,
            backgroundColors: {
              up: "#00854D",
              down: "#BF0030",
              unchanged: "gray",
            },
          },
        ],
      },
      options: {
        interaction: {
          intersect: false, // disable point-only intersect
          mode: "index", // look at index match on X
          axis: "x", // only consider X axis for matching
        },
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          interaction: {
            intersect: false, // disable point-only intersect
            mode: "index", // look at index match on X
            axis: "x", // only consider X axis for matching
          },
          tooltip: {
            bodyFont: {
              family: "monospace",
              size: 12,
            },
            titleFont: {
              family: "monospace",
              size: 13,
              weight: "bold",
            },
            displayColors: false,
			  autoskip:false,
            callbacks: {
              title(context) {
                return new Date(context[0].parsed.x).toLocaleString();
              },
              label(context, type) {
                const d = context.raw;
                const pad = (label, val) =>
                  label.padEnd(10) + String(val).padStart(10);
                return charType === "ohlc"
                  ? [
                      pad("Open:", d.o.toFixed(6)),
                      pad("High:", d.h.toFixed(6)),
                      pad("Low:", d.l.toFixed(6)),
                      pad("Close:", d.c.toFixed(6)),
                    ]
                  : [pad("Close:", d.y.toFixed(6))];
              },
            },
          },
          legend: {
            display: false,
          },
        },
        scales: {
          x: {
            grid: {
              display: false,
            },
            type: "time",
            ticks: {
              maxTicksLimit: window.innerWidth < 768 ? 2 : 6,
              pointStyle: "none",
              callback: (value) =>  {
				   return this.intervals.findIndex(i => i.periods === this.period) > this.intervals.findIndex(i => i.periods === "5m")
					? `${new Date(value).getDate()}/${new Date(value).getMonth()+1}/${new Date(value).getFullYear()} ${String(new Date(value).getHours()).padStart(2,"0")}:${String(new Date(value).getSeconds()).padStart(2,"0")}`
					: `${String(new Date(value).getHours()).padStart(2,"0")}:${String(new Date(value).getMinutes()).padStart(2,"0")}`
				 
				}
			},
            offset: false,
            beginAtZero: false,
          },
          y: {
            grid: {
              display: false,
            },
            type: "linear",
            offset: false,
            beginAtZero: false,
          },
        },
      },
    });
  }
  updateLabels() {
    const currencyData = this.historyData;
    const pair = this.pair;
    const currentData = currencyData.find(function (el) {
      return el.pair == pair;
    });
    const oldPrices = this.oldPrices;
    const formatFunc = this.formatCryptoPrice;
    const legendText = this.legendText;
    const intervals = this.intervals;
    const period = this.period;
    let lastPrice = this.lastPrice;
    let percent = 0;
    let lang = this.lang;

    if (currencyData && currentData) {
      let formattedPrice =
        formatFunc(
          currentData.price - this.lastPrice,
          lang === "de" ? "," : ".",
          lang === "de" ? "." : ","
        ) + " €";
      let currentPrice =
        formatFunc(
          currentData.price,
          lang === "de" ? "," : ".",
          lang === "de" ? "." : ","
        ) + " €";
      jQuery(".currency").html(this.pairToLabel[currentData.pair]);

      let decreaseValue = currentData.price - lastPrice;
      if (lastPrice) {
         percent = (decreaseValue / lastPrice) * 100;
      }

      let priceClass = percent > 0 ? "green" : percent < 0 ? "red" : "";

      jQuery(".price").html(
        this.legendText[lang].currentPrice + " " + currentPrice
      );
      jQuery(".price-change").html(
        '<span class="' +
          priceClass +
          '">' +
          formattedPrice +
          "  (" +
          percent.toFixed(2) +
          "%)</span> " +
          legendText[lang].last +
          " " +
          intervals.find((el) => el.periods === period).duration
      );
      jQuery(".current-price").each(function () {
		
        const currentPair = jQuery(this).data("pair");
        const current = currencyData.find((el) => el.pair === currentPair);
        let trend = " ";
		let priceClass = "";
        if (oldPrices[currentPair]) {
          trend = oldPrices[currentPair] > current.price ? "<span class=\"trend\"> ▼</span>" : "<span class=\"trend\"> ▲</span>";
		  priceClass = oldPrices[currentPair] > current.price ? "price-fall" : "price-rise"
        }

        if (current) {
          let formattedPrice =
            formatFunc(
              current.price,
              lang === "de" ? "," : ".",
              lang === "de" ? "." : ","
            ) + " €";

          jQuery(this).html(formattedPrice + trend).removeClass("price-fall price-rise").addClass(priceClass);
          if (oldPrices[currentPair] !== current.price) {
            oldPrices[currentPair] = current.price;
          }
        }
      });
    }
  }

  updateCurrentPrice() {
    const url = `${location.protocol}//${location.host}/wp-content/static/read.php?type=legacy&v=${Math.random()
      .toString(36)
      .substring(2)}`;
    jQuery.ajax({
      url: url,
      success: (result) => {
        const currentData = result;
        this.historyData = currentData;
        this.updateLabels();
      },
    });
  }

  startPriceUpdates() {
    this.updateCurrentPrice(); // initial call
    this.priceInterval = setInterval(() => this.updateCurrentPrice(), 5000);
  }
  loadData(pair, period, type) {
    const dataSet = type === "ohlc" ? "candle" : "history";
    const url = `${location.protocol}//${location.host}/wp-content/static/read.php?type=${dataSet}&cur=${pair}&period=${period}&v=${Math.random()
      .toString(36)
      .substring(2)}`;
    jQuery.ajax({
      url: url,
      success: (result) => {
        if (type === "ohlc") {
          this.lastPrice = result.items.length ? result.items[0].c : null;
          this.newPrice = result.items.length
            ? result.items[result.items.length - 1].c
            : null;
          const formatted = result.items.map((el) => {
            return {
              x: new Date(el.time).getTime(),
              o: el.o,
              h: el.h,
              l: el.l,
              c: el.c,
            };
          });
          this.updateData(formatted);
        } else {
          this.lastPrice = result[0].items.length
            ? result[0].items[0].close
            : null;
          this.newPrice = result[0].items.length
            ? result[0].items[result[0].items.length - 1].close
            : null;
          const formatted = result[0].items.map((el) => ({
            x: new Date(el.closeTime).getTime(),
            y: el.close,
          }));

          this.updateData(formatted);
        }
      },
    });
  }
  downsample(data, maxPoints, charType) {
    if (data.length <= maxPoints) return data;

    const bucketSize = Math.floor(data.length / maxPoints);
    const downsampled = [];

    for (let i = 0; i < maxPoints; i++) {
      const start = i * bucketSize;
      const end = (i + 1) * bucketSize;
      const chunk = data.slice(start, end);

      if (chunk.length === 0) continue;
      if (charType === "ohlc") {
        const o = chunk[0].o;
        const c = chunk[chunk.length - 1].c;
        const h = Math.max(...chunk.map((d) => d.h));
        const l = Math.min(...chunk.map((d) => d.l));
        const x = chunk[Math.floor(chunk.length / 2)].x; // or use avg timestamp
        downsampled.push({ x, o, h, l, c });
      } else {
        const y = chunk[0].y;
        const x = chunk[Math.floor(chunk.length / 2)].x; // or use avg timestamp
        downsampled.push({ x, y });
      }
    }

    return downsampled;
  }

formatCryptoPrice(value, decimalSeparator = ".", thousandSeparator = ",") {
  if (value === 0) return "0";

  const absValue = Math.abs(value);

  let decimals;
  if (absValue >= 1) {
    decimals = 2;
  } else if (absValue >= 0.01) {
    decimals = 4;
  } else if (absValue >= 0.0001) {
    decimals = 6;
  } else {
    decimals = 8;
  }

  const parts = value.toFixed(decimals).split(".");

  let integerPart = parts[0];
  let decimalPart = parts[1] || "";

  // Add thousand separator
  integerPart = integerPart.replace(
    /\B(?=(\d{3})+(?!\d))/g,
    thousandSeparator
  );

  return decimalPart
    ? integerPart + decimalSeparator + decimalPart
    : integerPart;
}
  updateData(data) {
    if (this.type === "ohlc") {
      data = this.downsample(data, 100, this.type);
    }

    this.chart.data.datasets[0].data = data;

    if (data.length > 0) {
      const allX = data.map((d) => d.x);
      const min = Math.min(...allX);
      const max = Math.max(...allX);
      const candleSpacing = allX.length > 1 ? allX[1] - allX[0] : 1;
      this.chart.options.scales.x.min = min - candleSpacing / 2;
      this.chart.options.scales.x.max = max + candleSpacing / 2;
    }

    this.chart.update("none");
    this.updateLabels();
  }

  setPeriod(period) {
    // Update the period
    this.period = period;

    // Keep the currently shown data for a smoother transition
    const currentData =
      (this.chart && this.chart.data && this.chart.data.datasets[0].data) || [];

    // Destroy the existing chart instance if it exists
    if (this.chart) {
      // this.chart.destroy();
    }

    // Rebuild the chart with the current type
    // this.chart = new Chart(this.ctx, this.buildChartConfig(this.type));

    // Restore the preserved data
    this.chart.data.datasets[0].data = currentData;

    // Update the chart instantly
    this.chart.update("none");

    // Reload with data appropriate to the new period
    this.loadData(this.pair, this.period, this.type);
  }
  setType(lineType) {
    // keep the currently shown data so the switch feels instant
    const currentData =
      (this.chart && this.chart.data && this.chart.data.datasets[0].data) || [];
    this.type = lineType;

    if (this.chart) {
      this.chart.destroy();
    }
    this.chart = new Chart(this.ctx, this.buildChartConfig(this.type));
    this.chart.data.datasets[0].data = currentData;
    this.chart.update("none"); // render immediately

    // (Re)load with correctly shaped data for the new controller
    this.loadData(this.pair, this.period, this.type);
  }
}

jQuery(document).ready(function () {
  if (jQuery("#intro").length) {
    var glide = new Glide("#intro", {
      autoplay: false,
      type: "slider",
      perView: 4,
      bound: true,
      animationDuration: 50,
      focusAt: 0,
      gap: 0,

      breakpoints: {
        800: {
          perView: 2,
        },
        480: {
          perView: 1,
        },
      },
    });

    glide.mount();
  }

 if (!jQuery("#graph").length) return;
  const load = (url) => jQuery.getScript(url);
  const startChart = () => {
    const type = jQuery("#graph").attr("data-type") || "line";
    const chartInstance = new CandlestickChart("graph", "5m", type);
  };

  if (typeof Chart === "undefined") {
	  load("/wp-content/uploads/custom-css-js/chartLibs.js")
      .then(startChart);
  } else {
    startChart();
  }
});
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/31077.js?v=8145 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Apr 16 2026 | 14:45:46 */
jQuery(document).ready(function ($) {
    var $staking = $('.staking-calculator');
    if (!$staking.length) return;

    var calc = {
        $root: $staking,
        state: {
            type: ($staking.data('type') || '').toLowerCase(),
            change: 'eur',
            price: 1,
            rateNum: parseFloat($staking.find('[name="rate"]').val()) || 0,
            periodNum: parseFloat($staking.find('[name="period"]').val()) || 1,
            assetData: [],
            intervalId: null
        },
        els: {
            eur: $staking.find('[name="eur"]'),
            coin: $staking.find('[name="coin"]'),
            rate: $staking.find('[name="rate"]'),
            period: $staking.find('[name="period"]'),
            pickCoin: $('.pick-coin'),
            outputTotal: $('.output [name="total"]'),
            outputDay: $('.output [name="calc_day"]'),
            outputWeek: $('.output [name="calc_week"]'),
            outputMonth: $('.output [name="calc_month"]'),
            outputYear: $('.output [name="calc_year"]'),
            outputCryptoTotal: $('.output-crypto [name="total"]'),
            outputCryptoDay: $('.output-crypto [name="calc_day"]'),
            outputCryptoWeek: $('.output-crypto [name="calc_week"]'),
            outputCryptoMonth: $('.output-crypto [name="calc_month"]'),
            outputCryptoYear: $('.output-crypto [name="calc_year"]')
        },

        init: function () {
            var self = this;

            self.state.rateNum = parseFloat(self.els.rate.val()) || 0;
            self.state.periodNum = parseFloat(self.els.period.val()) || 1;

            self.fetchAssets()
                .then(function () {
                    return self.fetchApr();
                })
                .then(function () {
                    return self.fetchPrice();
                })
                .then(function () {
                    self.renderInputs();
                    self.updatePrices();
                    self.renderCoinSelector();
                    self.bindEvents();
                    self.startAutoRefresh();
                });
        },

        bindEvents: function () {
            var self = this;

            self.els.eur.on('change paste keyup', function () {
                self.state.change = 'eur';
                self.renderInputs();
                self.updatePrices();
            });

            self.els.coin.on('change paste keyup', function () {
                self.state.change = 'coin';
                self.renderInputs();
                self.updatePrices();
            });

            self.els.period.on('change paste keyup', function () {
                self.state.periodNum = parseFloat(self.els.period.val()) || 1;
                self.renderInputs();
                self.updatePrices();
            });

            self.$root.on('click', '.pick-coin .megamenu-icon', function () {
                $('.coin-selector').toggle();
            });

            self.$root.on('click', '.coin-selector ul li', function () {
                var code = ($(this).data('code') || '').toLowerCase();
                self.setCoin(code, $(this));
            });
        },

        setCoin: function (code, $item) {
            var self = this;
            if (!code) return;

            self.state.type = code;
            self.$root.attr('data-type', code).data('type', code);

            if ($item && $item.length) {
                var icon = $item.find('use').attr('xlink:href');

                $('.coin-selector ul li').removeClass('active');
                $item.addClass('active');

                self.els.pickCoin
                    .attr('data-coin', code.toUpperCase())
                    .find('use')
                    .attr('xlink:href', icon);
            }

            $('.coin-selector').hide();

            self.fetchApr()
                .then(function () {
                    return self.fetchPrice();
                })
                .then(function () {
                    self.renderInputs();
                    self.updatePrices();
                });
        },

        startAutoRefresh: function () {
            var self = this;

            if (self.state.intervalId) {
                window.clearInterval(self.state.intervalId);
            }

            self.state.intervalId = window.setInterval(function () {
                self.fetchApr()
                    .then(function () {
                        return self.fetchPrice();
                    })
                    .then(function () {
                        self.renderInputs();
                        self.updatePrices();
                    });
            }, 5000);
        },

        fetchAssets: function () {
            var self = this;
            var url = location.protocol + '//' + location.host + '/wp-content/static/assets.json';

            return $.ajax({
                url: url,
                headers: ''
            }).then(function (result) {
                self.state.assetData = result.result || [];
            });
        },

        fetchApr: function () {
            var self = this;
            var url = location.protocol + '//' + location.host + '/wp-content/static/read.php?type=apr';

            return $.ajax({
                url: url,
                headers: ''
            }).then(function (result) {
                var key = self.state.type.charAt(0).toUpperCase() + self.state.type.substring(1);
                self.state.rateNum = parseFloat(result.averageAprs[key]) || 0;
                self.els.rate.val(self.formatRate(self.state.rateNum));
            });
        },

        fetchPrice: function () {
            var self = this;
            var url = location.protocol + '//' + location.host + '/wp-content/static/read.php?type=legacy';

            return $.ajax({
                url: url,
                headers: ''
            }).then(function (result) {
                var match = result.find(function (el) {
                    return el.pair === self.state.type + 'eur';
                });

                self.state.price = match ? parseFloat(match.price) : 1;
            });
        },

        getDecimals: function () {
            var self = this;
            var asset = self.state.assetData.find(function (el) {
                return (el.code || '').toLowerCase() === self.state.type;
            });

            return asset ? asset.decimalPlaces : 6;
        },

        renderInputs: function () {
            var self = this;
            var eurVal = parseFloat(String(self.els.eur.val()).replace(',', '.')) || 0;
            var coinVal = parseFloat(String(self.els.coin.val()).replace(',', '.')) || 0;
            var price = self.state.price || 1;
            var decimals = self.getDecimals();

            if (self.state.change === 'eur') {
                self.els.coin.val(
                    (eurVal / price).toFixed(decimals).replace('.', ',')
                );
            } else {
                self.els.eur.val(
                    (coinVal * price).toFixed(2).replace('.', ',')
                );
            }
        },

        updatePrices: function () {
            var self = this;
            var eurVal = parseFloat(String(self.els.eur.val()).replace(',', '.')) || 0;
            var coinVal = parseFloat(String(self.els.coin.val()).replace(',', '.')) || 0;
            var rateNum = parseFloat(self.state.rateNum) || 0;
            var periodNum = parseFloat(self.els.period.val()) || 1;
            var symbol = self.state.type.toUpperCase();

            self.els.outputTotal.html((eurVal / 12 * periodNum * rateNum / 100).toFixed(2).replace('.', ','));
            self.els.outputDay.html(self.formatPrice(eurVal / 365 * rateNum / 100));
            self.els.outputWeek.html(self.formatPrice(eurVal / 365 * 7 * rateNum / 100));
            self.els.outputMonth.html(self.formatPrice(eurVal / 12 * rateNum / 100));
            self.els.outputYear.html(self.formatPrice(eurVal * rateNum / 100));

            self.els.outputCryptoTotal.html((coinVal / 12 * periodNum * rateNum / 100).toFixed(6).replace('.', ','));
            self.els.outputCryptoDay.html((coinVal / 365 * rateNum / 100).toFixed(6).replace('.', ',') + ' ' + symbol);
            self.els.outputCryptoWeek.html((coinVal / 365 * 7 * rateNum / 100).toFixed(6).replace('.', ',') + ' ' + symbol);
            self.els.outputCryptoMonth.html((coinVal / 12 * rateNum / 100).toFixed(6).replace('.', ',') + ' ' + symbol);
            self.els.outputCryptoYear.html((coinVal * rateNum / 100).toFixed(6).replace('.', ',') + ' ' + symbol);
        },

        formatPrice: function (price) {
            return new Intl.NumberFormat('de-DE', {
                style: 'currency',
                currency: 'EUR'
            }).format(price).replace('€', 'EUR');
        },

        formatRate: function (rate) {
            return String(rate).replace('.', ',');
        },

        renderCoinSelector: function () {
            var self = this;
            var url = location.protocol + '//' + location.host + '/wp-content/static/coins.json';

            $.ajax({
                url: url,
                headers: '',
                success: function (result) {
                    var currentCode = self.state.type;

                    var listItems = Object.entries(result)
                        .filter(function (entry) {
                            var coinData = entry[1];
                            return coinData.active && coinData.stakable;
                        })
                        .map(function (entry) {
                            var key = entry[0];
                            var coinData = entry[1];
                            var isActive = key.toLowerCase() === currentCode;
                            var activeClass = isActive ? 'active' : '';

                            if (isActive && self.els.pickCoin.length && !self.els.pickCoin.find('svg').length) {
                                self.els.pickCoin.append(
                                    '<svg class="megamenu-icon"><use xlink:href="#' +
                                    coinData.name.toLowerCase().replace(/\s+/g, '-') +
                                    '"></use></svg>'
                                );
                            }

                            return `
                                <li data-code="${key}" class="${activeClass}">
                                    <svg class="megamenu-icon">
                                        <use xlink:href="#${coinData.name.toLowerCase().replace(/\s+/g, '-')}"></use>
                                    </svg>
                                    ${coinData.name}
                                </li>
                            `;
                        })
                        .join('');

                    var coinList = `<div class="coin-selector"><ul>${listItems}</ul></div>`;

                    if (self.els.pickCoin.length && !self.$root.find('.coin-selector').length) {
                        self.els.pickCoin.after(coinList);
                    }
                }
            });
        }
    };

    calc.init();
});
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/30948.js?v=4392 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Feb 29 2024 | 09:18:53 */
jQuery(document).ready(function( $ ){
	// Set defaults
	window.gtag = function() { dataLayer.push(arguments); }
	window.gtag('consent', 'default', {
	  ad_storage: 'denied',
	  analytics_storage: 'denied',
	  ad_user_data: 'denied',
	  ad_personalization: 'denied',
	  wait_for_update: 500
	});

	// Call this function when consent is granted
	const updateConsent = newConsentStates => {
	  window.gtag('consent', 'update', newConsentStates);
	  writeStatesToStorage(newConsentStates);
	};
    // Your code in here
});
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/30468.js?v=1562 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Apr 02 2025 | 11:09:29 */
jQuery(document).ready(function( $ ) {
    var calc = jQuery('.price-calculator, .bis-buying-coin-form')
	var eur = jQuery('.price-calculator [name="eur"], .bis-buying-coin-form [name="eur"]');
	var coin = jQuery('.price-calculator [name="coin"], .bis-buying-coin-form [name="coin"]');
	var change = "eur"
	var price = 1;
	var decimals = 8;
	if(calc.length) {
		
		fetchCalcAssets(calc, function(newDecimals) {
			decimals = newDecimals
			fetchCalcIcons(calc, eur, coin, change, decimals);
		})
		fetchCalcPrice(calc, eur, coin, change, function(newPrice) {
			price = newPrice
			change === "eur"
				? jQuery(coin).val(parseFloat((jQuery(eur).val().replace(",",".")/price).toFixed(decimals)).toString().replace(".",","))
				: jQuery(eur).val(parseFloat((jQuery(coin).val().replace(",",".") * price).toFixed(8)).toString().replace(".",","))
		})
		var intervalId = window.setInterval(function(){
		  fetchCalcPrice(calc, eur, coin, change, function(newPrice) {
			 const currentValue = change === "eur"
				? parseFloat(jQuery(coin).val().replace(",",".")) : parseFloat(jQuery(eur).val().replace(",","."))
			  const isHigher = newPrice > currentValue;
			  const className = isHigher ? 'green-flash' : 'red-flash';
			  change === "eur"
				? jQuery(coin).addClass(className) : jQuery(eur).addClass(className);

				setTimeout(() => {
				  if (change === "eur") {
					jQuery(coin).removeClass(className);
				  } else {
					jQuery(eur).removeClass(className);
				  }
				}, 500);
 			  
			  price = newPrice
			  if(change === "eur") {
// 				  animateValue(currentValue, newPrice, 500, jQuery(eur)) ;
				  jQuery(coin).val(parseFloat((jQuery(eur).val().replace(",",".") / price).toFixed(decimals)).toString().replace(".",","))
			  } else {
// 				  animateValue(currentValue, newPrice, 500, jQuery(coin)) ;
				  jQuery(eur).val(parseFloat((jQuery(coin).val().replace(",",".") * price).toFixed(8)).toString().replace(".",","))
			  }
//  				? jQuery(coin).val(parseFloat((jQuery(eur).val().replace(",",".") / price).toFixed(decimals)).toString().replace(".",","))
//  				: jQuery(eur).val(parseFloat((jQuery(coin).val().replace(",",".") * price).toFixed(8)).toString().replace(".",","))
		  })
		}, 5000);
		
		
	}
	jQuery(eur).on("change paste keyup", function() {
		change = "eur"
		change === "eur"
				? jQuery(coin).val(parseFloat((jQuery(eur).val().replace(",",".")/price).toFixed(decimals)).toString().replace(".",","))
				: jQuery(eur).val(parseFloat((jQuery(coin).val().replace(",",".") * price).toFixed(8)).toString().replace(".",","))
	});
	jQuery(coin).on("change paste keyup", function() {
		change = "coin"
		change === "eur"
				? jQuery(coin).val(parseFloat((jQuery(eur).val().replace(",",".")/price).toFixed(decimals)).toString().replace(".",","))
				: jQuery(eur).val(parseFloat((jQuery(coin).val().replace(",",".") * price).toFixed(8)).toString().replace(".",","))
	});
	
});
function fetchCalcPrice(calc, eur, coin, change, setPrice) {
	var code = calc.data().type.toLowerCase()
	var url = location.protocol + '//' + location.host + '/wp-content/static/read.php?type=legacy'
	jQuery.ajax({url: url, headers: '', success: function(result) {
		var price = result.find(function(el) {
			return el.pair == code + 'eur'
		}) ? result.find(function(el) {
			return el.pair == code + 'eur'
		}).price : 0
		setPrice(price)
		}
	})
}

function fetchCalcAssets(calc, setAssets) {
	var code = calc.data().type.toLowerCase()
	var url = location.protocol + '//' + location.host + '/wp-content/static/assets.json'
	jQuery.ajax({url: url, headers: '', success: function(result) {
		var decimals = result.result.find(function(el) {
			return el.code.toLowerCase() == code.toLowerCase();
		}) ? result.result.find(function(el) {
			return el.code.toLowerCase() == code.toLowerCase();
		}).decimalPlaces : 0
		setAssets(decimals)
		}
	})
}


function animateValue(start, end, duration = 1000, el) {
	console.log(start)
	start = parseFloat(start)
	end = parseFloat(end)
	const range = end - start;
	const startTime = performance.now();

	function updateValue(now) {
		const elapsed = now - startTime;
		const progress = Math.min(elapsed / duration, 1);
		const value = Math.round(start + range * progress);
		
// 		el.val(value);

		if (progress < 1) {
			requestAnimationFrame(updateValue);
		}
	}

	requestAnimationFrame(updateValue);
}



function fetchCalcIcons(calc, eur, coin, change, decimals) {

			
    var code = calc.data().type.toLowerCase();
    var url = location.protocol + '//' + location.host + '/wp-content/static/coins.json';

    jQuery.ajax({
        url: url,
        headers: '',
        success: function(result) {
            // Generate list with 'active' class for the initially selected coin
			
            var listItems = Object.entries(result).filter(([_, coinData]) => coinData.active).map(([key, coinData]) => {
				if(key.toLowerCase() === code) {
					jQuery('.pick-coin use').attr('xlink:href', '#' + coinData.name.toLowerCase().replace(/\s+/g, "-"));
				}
                var activeClass = key.toLowerCase() === code ? 'active' : '';
                return `<li data-code="${key}" class="${activeClass}">
                            <svg class="megamenu-icon">
                                <use xlink:href="#${coinData.name.toLowerCase().replace(/\s+/g, "-")}"></use>
                            </svg>
                            ${coinData.name}
                        </li>`;
            }).join('');

            var coinList = `<div class="coin-selector"><ul>${listItems}</ul></div>`;

            if (jQuery('.pick-coin').length) {
                jQuery('.pick-coin').after(coinList);

                jQuery(calc).on('click', '.pick-coin', function() {
                    jQuery('.coin-selector').toggle();
                });
            }
			
			
			
            // Handle coin selection with active class update
            jQuery('.coin-selector').on('click', 'ul li', function() {
                var code = jQuery(this).data("code");
				
				var icon = jQuery(this).find('use').attr('xlink:href');

                // 🔥 Update active class
                jQuery('.coin-selector ul li').removeClass('active');
                jQuery(this).addClass('active');

                // Update UI and data attributes
                jQuery('.pick-coin').attr('data-coin', code.toUpperCase()).find('use').attr('xlink:href', icon);

                calc.data("type", code.toLowerCase());
                jQuery('.coin-selector').toggle();

                // Refresh price when coin changes
                fetchCalcPrice(calc, eur, coin, change, function(newPrice) {
                    price = newPrice;
                    change === "eur"
                        ? jQuery(coin).val(parseFloat((jQuery(eur).val().replace(",", ".") / price).toFixed(decimals)).toString().replace(".", ","))
                        : jQuery(eur).val(parseFloat((jQuery(coin).val().replace(",", ".") * price).toFixed(8)).toString().replace(".", ","));
                });
            });
        }
    });
};
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/17326.js?v=2835 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Dec 30 2022 | 08:41:53 */
// --------------------------- uxEnhancerSettings ---------------------------
// generic overall settings of uxEnhancer
// --------------------------------------------------------------------------
var uxEnhancerSettings = {
    eventTagsVersion: "v3.2",
    maxWaitForUxEnhanceBeforeRedirectMsec: 250,
    maxWaitForInitilize: 1000,
    uxEnhanceProdUrl: 'https://cloud.bisonapp.com/api/v1/userexperience/improve',
    uxEnhanceDevUrl: `${atob('aHR0cHM6Ly9jbG91ZC5zb3dhZGV2LmNvbS8=')}api/v1/userexperience/improve`,
    fingerprintUrl: 'https://bisonapp.com/wp-content/uploads/custom-css-js/17572.js',
    consoleLog: localStorage.getItem("consoleLog") ?? false,
    devMode: localStorage.getItem("devMode") ?? false,
};


// --------------------------- uxEnhancerInitializer ---------------------------
// sets up uxEnhancer at startupo and correxctly wires all the evnts
// -----------------------------------------------------------------------------
var uxEnhancerInitializer = {
    startup: async function() {
        uxDataProvider.initilize();

        jQuery(document).ready(async function($) {
            uxEnhancerInitializer.attachEventListeners();
            uxEnhancerInitializer.trackPageLoad();
        });
    },

    attachEventListeners: function() {
        // Form submit event => button click
        jQuery('body').on('submit', "form", async function(e) {
            uxLogger.time("submitForm");
            uxLogger.timeLog("submitForm", "Start");

            let clickLink = jQuery(this).attr("action");
            let clickLinkPreMod = null;
            if (bisonNavigator.isTradeBisonAppHref(clickLink)) {
                clickLinkPreMod = clickLink;
                clickLink = bisonNavigator.enrichNavigationHref(clickLink, uxDataProvider.getSessionId());
                jQuery(this).attr('action', clickLink);
            }
            uxLogger.timeLog("submitForm", "PreAwait");
            const element = e?.originalEvent?.submitter != null ? e?.originalEvent?.submitter : this;
            await uxEnhancer.trackLandingPressButtonCommon("Form", clickLink, clickLinkPreMod, jQuery(element));

            uxLogger.timeLog("submitForm", "PreDone");
            uxLogger.timeEnd("submitForm");
        });
        
        // Link click event => button click
        jQuery('body').on('click', "a", async function(e) {
            uxLogger.time("aClick");
            uxLogger.timeLog("aClick", "Start");

            let clickLink = jQuery(this).attr("href");
            let clickLinkPreMod = null;
            if (bisonNavigator.isTradeBisonAppHref(clickLink)) {
                clickLinkPreMod = clickLink;
                clickLink = bisonNavigator.enrichNavigationHref(clickLink, uxDataProvider.getSessionId());
                jQuery(this).attr('href', clickLink);
            }
            uxLogger.timeLog("aClick", "PreAwait");
            await uxEnhancer.trackLandingPressButtonCommon("Link", clickLink, clickLinkPreMod, jQuery(this));

            uxLogger.timeLog("aClick", "PreDone");
            uxLogger.timeEnd("aClick");
        });
        
        // Other than submit buttons
        jQuery('body').on('click', "input[type=button], button:not([type=submit])", async function(e) {
            uxLogger.time("buttonClick");
            uxLogger.timeLog("buttonClick", "Start");

            uxLogger.timeLog("buttonClick", "PreAwait");
            await uxEnhancer.trackLandingPressButtonCommon("Button", null, null, jQuery(this));

            uxLogger.timeLog("buttonClick", "PreDone");
            uxLogger.timeEnd("buttonClick");
        });

        // Link click event => button click
        if(uxEnhancerSettings.devMode) {
            jQuery('body').on('click', "*:not(a, input, button)", async function(e) {
                uxLogger.log(`---------------------------->>> click anywhere ${uxUtils.generateGuid()}`);
            });
        }
    },

    trackPageLoad: async function() {
        uxLogger.time("trackLandingOpenAny");
        uxLogger.timeLog("trackLandingOpenAny", "Start");
        if (uxDataProvider.getReferrerHostname() === document.location.hostname) {
            // navigation was done within landing page
            await uxEnhancer.trackLandingOpenScreen();
            
        } else {
            // page was opened from the outside
            await uxEnhancer.trackLandingOpenAppLanding(uxDataProvider.getReferrerObj());
        }
        uxLogger.timeLog("trackLandingOpenAny", "PreDone");
        uxLogger.timeEnd("trackLandingOpenAny");
    },
};


// --------------------------- uxEnhancer ---------------------------
// improve ux by reporting anonimized patterns of page usage
// ------------------------------------------------------------------
var uxEnhancer = {

    trackLandingPressButtonCommon: async function(objectType, navigateTo, navigateToPreMod, element) {
        const hierachy = element.parent().parent().parent().parent().parent().parent().index().toString() +
            element.parent().parent().parent().parent().parent().index().toString() +
            element.parent().parent().parent().parent().index().toString() +
            element.parent().parent().parent().index().toString() +
            element.parent().parent().index().toString() +
            element.parent().index().toString() +
            element.index().toString();

        const objectId = [objectType, hierachy, element.attr("class"), element.attr("id"), element.parents().length].join('|');

        uxEnhancer.trackLandingPressButton(
             objectId,
             objectType,
             element.attr('value'),
             element.text()?.trim(),
             element.attr('id'),
             element.prop('nodeName'),
             element.attr('class'),
             element.parents()?.length,
             hierachy,
             uxUtils.href2Object(navigateTo),
             navigateToPreMod != null ? uxUtils.href2Object(navigateToPreMod) : null,
        );
    },

    // DO NOT MANUALLY REGENERATE THE BELOW BLOCK

    // -------------- Landing page --------------

    // Users comes to the landing page from outside on any screen on any screen
    trackLandingOpenAppLanding: async function(referrer) {
      const screenId = uxDataProvider.getScreenId();
      const customProperties = {
        referrer,
      };
      await uxEnhancer.logEvent('Landing', 'Open', 'App', 'Landing', screenId, customProperties);
    },

    // User opens a screen on the lading page via internal navigation on any screen
    trackLandingOpenScreen: async function() {
      const screenId = uxDataProvider.getScreenId();
      const fromScreenId = uxDataProvider.getReferrerPathname();
      await uxEnhancer.logEvent('Landing', 'Open', 'Screen', screenId, fromScreenId, {});
    },

    // User clicks any link/button or other clickable element on the landing page on any screen
    trackLandingPressButton: async function(
      objectId,
      objectType,
      objectValue,
      objectText,
      htmlId,
      htmlType,
      htmlClass,
      htmlHierarIndex,
      htmlHierarId,
      navigateTo,
      navigateToPreMod,
    ) {
      const screenId = uxDataProvider.getScreenId();
      const customProperties = {
        objectType,
        objectValue,
        objectText,
        htmlId,
        htmlType,
        htmlClass,
        htmlHierarIndex,
        htmlHierarId,
        navigateTo,
        navigateToPreMod,
      };
      await uxEnhancer.logEvent('Landing', 'Press', 'Button', objectId, screenId, customProperties);
    },

    // -------------- END OF LIST --------------
        
    logEvent: async function(group, action, object, objectId, screen, properties) {
        uxLogger.time("logEvent");
        
        const event = {
            "time": new Date().toISOString(),
            "group": group,
            "action": action,
            "object": object,
            "objectId": objectId,
            "screen": screen,
            "properties": await uxDataProvider.enrichCustomParameters(properties),
            "id": uxDataProvider.getEventIdAndIncrement()
        };

        const commonProperties = {
            "sessionId": uxDataProvider.getSessionId(),
            "userId": null,
            "userAccountType": null,
            "environment": uxDataProvider.isProduction() ? "production" : "development",
            "app": "BISON_landing_page",
            "appBuild": "WP 6.0.1",
            "appRelease": window.location.hostname,
            "appStartTime": uxDataProvider.getAppStartTime(),
            "deviceID": uxDataProvider.getDeviceId(),
            "deviceLanguage": document.documentElement.lang,
            "deviceModel": null, //TODO
            "deviceOs": navigator.platform,
            "deviceOsName": null, //TODO
            "devicePlatform": null, //TODO
            "deviceBrowser": uxUtils.getBrowser().name,
            "deviceBrowserVersion": uxUtils.getBrowser().version,
            "deviceType": "Web", //TODO
            "deviceBrand": navigator.vendor,
            "deviceFontScale": (window.outerWidth - 8) / window.innerWidth,
            "deviceScreenWidth": screen.width,
            "deviceScreenHeight": screen.height,
            "deviceTimeZoneOffsetSeconds": new Date().getTimezoneOffset(),
            "abTest": uxDataProvider.getAbTest(),
            "eventTags": uxEnhancerSettings.eventTagsVersion,
        };

        const data = {
            commonProperties: commonProperties,
            events: [event],
            sendingTime: new Date().toISOString(),
        };

        uxLogger.timeLog("logEvent", `create time`);
        uxLogger.log("logEvent pre send: " + JSON.stringify(data, null, 4));
        uxLogger.log(data)
        const terminationType = await uxEnhancer.sendData(data);
        uxLogger.timeLog("logEvent", `send exit (terminationType = ${terminationType})`);
        uxLogger.timeEnd("logEvent");
    },

    sendData: async function(data, redirectAfterSend) {
        uxLogger.time("sendData");
        uxLogger.time("sendData.Ajax");
        uxLogger.log("sendData: Start");

        const waitForCompletion = uxUtils.timeoutWithCancel(uxEnhancerSettings.maxWaitForUxEnhanceBeforeRedirectMsec);

        jQuery.ajax({
                type: "POST",
                url: uxDataProvider.isProduction() ? uxEnhancerSettings.uxEnhanceProdUrl: uxEnhancerSettings.uxEnhanceDevUrl,
                data: JSON.stringify(data),
            })
            .always(function(res) {
                uxLogger.log("sendData: Ajax call completed");
                uxLogger.timeEnd("sendData.Ajax");
                waitForCompletion.done();
            });

        await waitForCompletion.promise;
        uxLogger.log("sendData: Done waiting");
        uxLogger.timeEnd("sendData");
        return waitForCompletion.terminationType;
    },
};


// --------------------------- uxDataProvider ---------------------------
// auxiliary class providing various data in a uniform way for uxImprover
// ----------------------------------------------------------------------
var uxDataProvider = {
    initilizePromise: null,
    
    initilize: function() {
        uxDataProvider.initilizePromise = uxUtils.timeoutWithCancel(uxEnhancerSettings.maxWaitForInitilize);
        
        if(localStorage.getItem("deviceFp") === null) {
            uxLogger.log("generating deviceFp");
            try {
                uxLogger.time("fpPromise");
                import (uxEnhancerSettings.fingerprintUrl)
                    .then(FingerprintJS => FingerprintJS.load())
                    .then(fp => fp.get())
                    .then(result => {
                        const visitorId = result.visitorId;
                        uxLogger.log("deviceFp = " + result.visitorId);
                        uxLogger.timeEnd("fpPromise");
                        localStorage.setItem("deviceFp", result.visitorId);
                        uxDataProvider.initilizePromise.done();
                    });
            } catch (error) {
                localStorage.setItem("deviceFp", "error_initialize_fp");
                uxDataProvider.initilizePromise.done();
            }
        } else {
            uxDataProvider.initilizePromise.done();
        }
    },

    getDeviceId: function() {
        return uxUtils.getOrSetStorageVariable(localStorage, "deviceId", () => uxUtils.generateGuid());
    },

    getDeviceFp: async function() {
        await uxDataProvider.initilizePromise.promise;
        return localStorage.getItem("deviceFp") ?? 'not_available_yet';
    },

    getSessionId: function() {
        return uxUtils.getOrSetStorageVariable(sessionStorage, "sessionId", 
            () => `SID_${uxDataProvider.getAppStartTime()}_${uxUtils.generateGuid().replace(/-/g, '')}`.substring(0, 36)
        );
    },

    getAppStartTime: function() {
        return uxUtils.getOrSetStorageVariable(sessionStorage, "appStartTime", () => Date.now());
    },

    getScreenId: function() {
        return document.location.pathname;
    },

    getReferrerHostname: function() {
        if(document.referrer === '') { return null; }
        try {
            return new URL(document.referrer).hostname;
        } catch (error) {
            uxLogger.warn(error, `Referrer cannot be converted to url: '${document.referrer}'`);
            return 'error_getReferrerHostname';
        }
    },

    getReferrerPathname: function() {
        if(document.referrer === '') { return null; }
        try {
            return new URL(document.referrer).pathname;
        } catch (error) {
            uxLogger.warn(error, `Referrer cannot be converted to url: '${document.referrer}'`);
            return 'error_getReferrerPathname';
        }
    },

    getReferrerObj: function() {
        uxLogger.log(`document.referrer = ${document.referrer}`);
        return uxUtils.href2Object(document.referrer);
    },

    getEventIdAndIncrement: function() {
        let eventId = parseInt(uxUtils.getOrSetStorageVariable(localStorage, "eventId", () => "0"));
        localStorage.setItem("eventId", JSON.stringify(eventId + 1));
        return eventId;
    },


    getAbTest: function() {
        try {
            // Find all elemnts which contain either AB test and AB variant data attribute
            let abTestVariantsDict = jQuery('[data-abtest],[data-abvariant]')
                .toArray()
                // Filter our all invisible elements
                .filter(elm => jQuery(elm).css("display") != 'none')
                // Extract all AB test and AB variant attributes from all found elements
                .map(elm => ({
                        key:jQuery(elm).data("abtest") ?? "error_abTestUndefined", 
                        value: jQuery(elm).data("abvariant") ?? "error_abVariantUndefined"
                    })
                )
                // Create a dictionary/map of all AB test definitions
                // skip same AB test-variant pairs but keep different ones for debugging and wrong definition resolution
                .reduce((map, item) => {
                        let keySeq = 0;
                        let key = ()=>item.key+(keySeq==0?"":`_#${keySeq}`);
                        while (map.has(key())) { 
                            if(map.get(key()) == item.value) {
                                // This AB test-variant pair is already present
                               return map;
                            }
                            // Modify the key by attaching sequence version to store additional distinct value
                            keySeq = keySeq + 1;
                        }
                        map.set(key(), item.value);
                        return map;
                    }, 
                    new Map()
                );
             
             return abTestVariantsDict.size == 0
                ? null
                : JSON.stringify(Object.fromEntries(abTestVariantsDict));

        } catch (error) {
            uxLogger.warn(error, "GetAbTest error");
            return 'error_getAbTest'
        }
    },

    isProduction: function() {
        return window.location.hostname === "bisonapp.com"
    },

    enrichCustomParameters: async function(existingCommonParameters) {
        let utmParametersObj = {error: 'error_enrichCustomParameters'};
        let fingerprintObj = {};
        
        try { utmParametersObj = uxUtils.extractUrlSearchParameters(searchParam => searchParam.key.startsWith("utm_")); }
        catch (error) {   }

        try { fingerprintObj = { 'deviceFp':  await uxDataProvider.getDeviceFp() }; }
        catch (error) {   }
        
        return {
            ...existingCommonParameters,
            ...utmParametersObj,
            ...fingerprintObj,
        };
    },
};

// --------------------------- uxUtils ---------------------------
// auxiliary class providing some generic/not domain specific functionality for uxImprover
// ----------------------------------------------------------------------
var uxUtils = {
    getOrSetStorageVariable: function(storage, key, createInitialValueFunct) {
        let value = storage.getItem(key);
        if (value === null) {
            value = createInitialValueFunct();
            storage.setItem(key, value);
        }
        return value;
    },

    generateGuid: function() {
        return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11)
            .replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
    },

    extractUrlSearchParameters: function(urlSearchParamsFilterFunct) {
        const urlParametersArray = Array.from((new URLSearchParams(window.location.search)).entries())
            .map(elem => ({ key: elem[0], value: elem[1] }))
            .filter(searchParam => urlSearchParamsFilterFunct(searchParam));
        return Object.fromEntries(urlParametersArray.map(elem => [elem.key, elem.value]));
    },    

    getBrowser: function() {
        try {
            var ua = navigator.userAgent,
                tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
            if (/trident/i.test(M[1])) {
                tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
                return {
                    name: 'IE',
                    version: (tem[1] || '')
                };
            }
            if (M[1] === 'Chrome') {
                tem = ua.match(/\bOPR|Edge\/(\d+)/)
                if (tem != null) {
                    return {
                        name: 'Opera',
                        version: tem[1]
                    };
                }
            }
            M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
            if ((tem = ua.match(/version\/(\d+)/i)) != null) {
                M.splice(1, 1, tem[1]);
            }
            return {
                name: M[0],
                version: M[1]
            };
        } catch (error) {
            return {
                name: 'error_getBrowser',
                version: 'error_getBrowser'
            };
        }
    },

    href2Object: function(href) {
        try {
            const hrefObj = new URL(href);
            return {
                href: hrefObj.href,
                protocol: hrefObj.protocol,
                hostname: hrefObj.hostname,
                port: hrefObj.port,
                pathname: hrefObj.pathname,
                hash: hrefObj.hash,
                search: Object.fromEntries(hrefObj.searchParams.entries()),
            };
        } catch {
            return {
                href: href
            };
        }
    }, 
            
    timeoutWithCancel: function(ms) {
        uxLogger.time("timeoutWithCancel");
        uxLogger.timeLog("timeoutWithCancel", `Start with ${ms} ms timeout`);

        var timeout, promise, promiseResolve;

        const resultInterface = {
            promise: null,
            promiseResolve: null,
            terminationType: null,
            done: () => resultInterface.internalDone("completed"),
            internalDone: function(terminationType) {
                if(resultInterface.terminationType === null) {
                    clearTimeout(timeout); 
                    resultInterface.terminationType = terminationType;
                    resultInterface.promiseResolve();
                }                
            },
        };

        resultInterface.promise = new Promise(function(resolve, reject) {
                resultInterface.promiseResolve = resolve;
            })
            .then(() => {
                 uxLogger.timeEnd("timeoutWithCancel");
                 resultInterface.done = () => uxLogger.log("timeoutWithCancel done call skipped");
            })

        setTimeout(() => resultInterface.internalDone("timeout"), ms);

        return resultInterface;
    },
};

// --------------------------- uxLogger ---------------------------
// logging to console only in dev environment
// ----------------------------------------------------------------------
var uxLogger = {
    time: function(timerName) { 
        if(uxEnhancerSettings.consoleLog) { console.time(timerName); } 
    },

    timeEnd: function(timerName) { 
        if(uxEnhancerSettings.consoleLog) { console.timeEnd(timerName); } 
    },

    timeLog: function(timerName, message) { 
        if(uxEnhancerSettings.consoleLog) { console.timeLog(timerName, message); } 
    },

    log: function(timerName) { 
        if(uxEnhancerSettings.consoleLog) { console.log(timerName); } 
    },

    warn: function(error, msg) { 
        if(uxEnhancerSettings.consoleLog) { console.warn(error, msg); } 
    },    
};


// --------------------------- bisonNavigator ---------------------------
// managing links going to bison trading page
// ----------------------------------------------------------------------
var bisonNavigator = {
    isTradeBisonAppHref: function(href) {
        try {
            if(!href || href.startsWith('#') || href.startsWith('/')) {
                return false;
            }
            return new URL(href).hostname === "trade.bisonapp.com";
        } catch (error) {
            uxLogger.warn(error, `bisonNavigator.isTradeBisonAppHref: Error is suppressed ` +
                `and code execution continues as if this link '${href}' is not trade BISON location!`);
            return false;
        }
    },

    enrichNavigationHref: function(urlString, sessionId) {
        try {
            const url = new URL(urlString);
            const currentSearchParams = Array.from((new URLSearchParams(window.location.search)).entries());

            // copy all current url search parameters that are not in the new url to the new url
            currentSearchParams.forEach(elem => {
                if (!url.searchParams.has(elem[0])) {
                    url.searchParams.set(elem[0], elem[1])
                }
            });

            // add new utm parameter if none is previously defined
            const hasUtmParams = Array.from(url.searchParams.entries())
                                      .some(elem => elem[0].toLowerCase().startsWith("utm_"));
            if (!hasUtmParams) {
                url.searchParams.set('utm_source', 'bisonapp.com');
            }

            // set landing_sid always
            url.searchParams.set('landing_sid', sessionId);
            return url.toString();

        } catch (error) {
            uxLogger.warn(error, `bisonNavigator.enrichNavigationHref: Error is suppressed ` +
                `and code execution continues with the original url '${urlString}' result!`);
            return urlString;
        }
    },
};


// --------------------------- STARTUP ---------------------------
// initialize thy system and startup
// ---------------------------------------------------------------
uxEnhancerInitializer.startup();
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/10016.js?v=4260 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Sep 07 2021 | 12:45:19 */


(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global.Glide = factory());
}(this, (function () { 'use strict';

  var defaults = {
    
    type: 'slider',

    
    startAt: 0,

    
    perView: 1,

    
    focusAt: 0,

    
    gap: 10,

    
    autoplay: false,

    
    hoverpause: true,

    
    keyboard: true,

    
    bound: false,

    
    swipeThreshold: 80,

    
    dragThreshold: 120,

    
    perSwipe: '|',

    
    touchRatio: 0.5,

    
    touchAngle: 45,

    
    animationDuration: 400,

    
    rewind: true,

    
    rewindDuration: 800,

    
    animationTimingFunc: 'cubic-bezier(.165, .840, .440, 1)',

    
    waitForTransition: true,

    
    throttle: 10,

    
    direction: 'ltr',

    
    peek: 0,

    
    breakpoints: {},

    
    classes: {
      swipeable: 'glide--swipeable',
      dragging: 'glide--dragging',
      direction: {
        ltr: 'glide--ltr',
        rtl: 'glide--rtl'
      },
      type: {
        slider: 'glide--slider',
        carousel: 'glide--carousel'
      },
      slide: {
        clone: 'glide__slide--clone',
        active: 'glide__slide--active'
      },
      arrow: {
        disabled: 'glide__arrow--disabled'
      },
      nav: {
        active: 'glide__bullet--active'
      }
    }
  };

  
  function warn(msg) {
    console.error("[Glide warn]: " + msg);
  }

  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
    return typeof obj;
  } : function (obj) {
    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  };

  var classCallCheck = function (instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  };

  var createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();

  var _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];

      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  };

  var get = function get(object, property, receiver) {
    if (object === null) object = Function.prototype;
    var desc = Object.getOwnPropertyDescriptor(object, property);

    if (desc === undefined) {
      var parent = Object.getPrototypeOf(object);

      if (parent === null) {
        return undefined;
      } else {
        return get(parent, property, receiver);
      }
    } else if ("value" in desc) {
      return desc.value;
    } else {
      var getter = desc.get;

      if (getter === undefined) {
        return undefined;
      }

      return getter.call(receiver);
    }
  };

  var inherits = function (subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
      throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }

    subClass.prototype = Object.create(superClass && superClass.prototype, {
      constructor: {
        value: subClass,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  };

  var possibleConstructorReturn = function (self, call) {
    if (!self) {
      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }

    return call && (typeof call === "object" || typeof call === "function") ? call : self;
  };

  
  function toInt(value) {
    return parseInt(value);
  }

  
  function toFloat(value) {
    return parseFloat(value);
  }

  
  function isString(value) {
    return typeof value === 'string';
  }

  
  function isObject(value) {
    var type = typeof value === 'undefined' ? 'undefined' : _typeof(value);

    return type === 'function' || type === 'object' && !!value; // eslint-disable-line no-mixed-operators
  }

  
  function isFunction(value) {
    return typeof value === 'function';
  }

  
  function isUndefined(value) {
    return typeof value === 'undefined';
  }

  
  function isArray(value) {
    return value.constructor === Array;
  }

  
  function mount(glide, extensions, events) {
    var components = {};

    for (var name in extensions) {
      if (isFunction(extensions[name])) {
        components[name] = extensions[name](glide, components, events);
      } else {
        warn('Extension must be a function');
      }
    }

    for (var _name in components) {
      if (isFunction(components[_name].mount)) {
        components[_name].mount();
      }
    }

    return components;
  }

  
  function define(obj, prop, definition) {
    Object.defineProperty(obj, prop, definition);
  }

  
  function sortKeys(obj) {
    return Object.keys(obj).sort().reduce(function (r, k) {
      r[k] = obj[k];

      return r[k], r;
    }, {});
  }

  
  function mergeOptions(defaults, settings) {
    var options = _extends({}, defaults, settings);

    // `Object.assign` do not deeply merge objects, so we
    // have to do it manually for every nested object
    // in options. Although it does not look smart,
    // it's smaller and faster than some fancy
    // merging deep-merge algorithm script.
    if (settings.hasOwnProperty('classes')) {
      options.classes = _extends({}, defaults.classes, settings.classes);

      if (settings.classes.hasOwnProperty('direction')) {
        options.classes.direction = _extends({}, defaults.classes.direction, settings.classes.direction);
      }

      if (settings.classes.hasOwnProperty('type')) {
        options.classes.type = _extends({}, defaults.classes.type, settings.classes.type);
      }

      if (settings.classes.hasOwnProperty('slide')) {
        options.classes.slide = _extends({}, defaults.classes.slide, settings.classes.slide);
      }

      if (settings.classes.hasOwnProperty('arrow')) {
        options.classes.arrow = _extends({}, defaults.classes.arrow, settings.classes.arrow);
      }

      if (settings.classes.hasOwnProperty('nav')) {
        options.classes.nav = _extends({}, defaults.classes.nav, settings.classes.nav);
      }
    }

    if (settings.hasOwnProperty('breakpoints')) {
      options.breakpoints = _extends({}, defaults.breakpoints, settings.breakpoints);
    }

    return options;
  }

  var EventsBus = function () {
    
    function EventsBus() {
      var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      classCallCheck(this, EventsBus);

      this.events = events;
      this.hop = events.hasOwnProperty;
    }

    


    createClass(EventsBus, [{
      key: 'on',
      value: function on(event, handler) {
        if (isArray(event)) {
          for (var i = 0; i < event.length; i++) {
            this.on(event[i], handler);
          }
        }

        // Create the event's object if not yet created
        if (!this.hop.call(this.events, event)) {
          this.events[event] = [];
        }

        // Add the handler to queue
        var index = this.events[event].push(handler) - 1;

        // Provide handle back for removal of event
        return {
          remove: function remove() {
            delete this.events[event][index];
          }
        };
      }

      

    }, {
      key: 'emit',
      value: function emit(event, context) {
        if (isArray(event)) {
          for (var i = 0; i < event.length; i++) {
            this.emit(event[i], context);
          }
        }

        // If the event doesn't exist, or there's no handlers in queue, just leave
        if (!this.hop.call(this.events, event)) {
          return;
        }

        // Cycle through events queue, fire!
        this.events[event].forEach(function (item) {
          item(context || {});
        });
      }
    }]);
    return EventsBus;
  }();

  var Glide = function () {
    
    function Glide(selector) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      classCallCheck(this, Glide);

      this._c = {};
      this._t = [];
      this._e = new EventsBus();

      this.disabled = false;
      this.selector = selector;
      this.settings = mergeOptions(defaults, options);
      this.index = this.settings.startAt;
    }

    


    createClass(Glide, [{
      key: 'mount',
      value: function mount$$1() {
        var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

        this._e.emit('mount.before');

        if (isObject(extensions)) {
          this._c = mount(this, extensions, this._e);
        } else {
          warn('You need to provide a object on `mount()`');
        }

        this._e.emit('mount.after');

        return this;
      }

      

    }, {
      key: 'mutate',
      value: function mutate() {
        var transformers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

        if (isArray(transformers)) {
          this._t = transformers;
        } else {
          warn('You need to provide a array on `mutate()`');
        }

        return this;
      }

      

    }, {
      key: 'update',
      value: function update() {
        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

        this.settings = mergeOptions(this.settings, settings);

        if (settings.hasOwnProperty('startAt')) {
          this.index = settings.startAt;
        }

        this._e.emit('update');

        return this;
      }

      

    }, {
      key: 'go',
      value: function go(pattern) {
        this._c.Run.make(pattern);

        return this;
      }

      

    }, {
      key: 'move',
      value: function move(distance) {
        this._c.Transition.disable();
        this._c.Move.make(distance);

        return this;
      }

      

    }, {
      key: 'destroy',
      value: function destroy() {
        this._e.emit('destroy');

        return this;
      }

      

    }, {
      key: 'play',
      value: function play() {
        var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

        if (interval) {
          this.settings.autoplay = interval;
        }

        this._e.emit('play');

        return this;
      }

      

    }, {
      key: 'pause',
      value: function pause() {
        this._e.emit('pause');

        return this;
      }

      

    }, {
      key: 'disable',
      value: function disable() {
        this.disabled = true;

        return this;
      }

      

    }, {
      key: 'enable',
      value: function enable() {
        this.disabled = false;

        return this;
      }

      

    }, {
      key: 'on',
      value: function on(event, handler) {
        this._e.on(event, handler);

        return this;
      }

      

    }, {
      key: 'isType',
      value: function isType(name) {
        return this.settings.type === name;
      }

      

    }, {
      key: 'settings',
      get: function get$$1() {
        return this._o;
      }

      
      ,
      set: function set$$1(o) {
        if (isObject(o)) {
          this._o = o;
        } else {
          warn('Options must be an `object` instance.');
        }
      }

      

    }, {
      key: 'index',
      get: function get$$1() {
        return this._i;
      }

      
      ,
      set: function set$$1(i) {
        this._i = toInt(i);
      }

      

    }, {
      key: 'type',
      get: function get$$1() {
        return this.settings.type;
      }

      

    }, {
      key: 'disabled',
      get: function get$$1() {
        return this._d;
      }

      
      ,
      set: function set$$1(status) {
        this._d = !!status;
      }
    }]);
    return Glide;
  }();

  function Run (Glide, Components, Events) {
    var Run = {
      
      mount: function mount() {
        this._o = false;
      },


      
      make: function make(move) {
        var _this = this;

        if (!Glide.disabled) {
          !Glide.settings.waitForTransition || Glide.disable();

          this.move = move;

          Events.emit('run.before', this.move);

          this.calculate();

          Events.emit('run', this.move);

          Components.Transition.after(function () {
            if (_this.isStart()) {
              Events.emit('run.start', _this.move);
            }

            if (_this.isEnd()) {
              Events.emit('run.end', _this.move);
            }

            if (_this.isOffset()) {
              _this._o = false;

              Events.emit('run.offset', _this.move);
            }

            Events.emit('run.after', _this.move);

            Glide.enable();
          });
        }
      },


      
      calculate: function calculate() {
        var move = this.move,
            length = this.length;
        var steps = move.steps,
            direction = move.direction;

        // By default assume that size of view is equal to one slide

        var viewSize = 1;

        // While direction is `=` we want jump to
        // a specified index described in steps.
        if (direction === '=') {
          Glide.index = steps;

          return;
        }

        // When pattern is equal to `>>` we want
        // fast forward to the last slide.
        if (direction === '>' && steps === '>') {
          Glide.index = length;

          return;
        }

        // When pattern is equal to `<<` we want
        // fast forward to the first slide.
        if (direction === '<' && steps === '<') {
          Glide.index = 0;

          return;
        }

        // pagination movement
        if (direction === '|') {
          viewSize = Glide.settings.perView || 1;
        }

        // we are moving forward
        if (direction === '>' || direction === '|' && steps === '>') {
          var index = calculateForwardIndex(viewSize);

          if (index > length) {
            this._o = true;
          }

          Glide.index = normalizeForwardIndex(index, viewSize);

          return;
        }

        // we are moving backward
        if (direction === '<' || direction === '|' && steps === '<') {
          var _index = calculateBackwardIndex(viewSize);

          if (_index < 0) {
            this._o = true;
          }

          Glide.index = normalizeBackwardIndex(_index, viewSize);

          return;
        }

        warn('Invalid direction pattern [' + direction + steps + '] has been used');
      },


      
      isStart: function isStart() {
        return Glide.index <= 0;
      },


      
      isEnd: function isEnd() {
        return Glide.index >= this.length;
      },


      
      isOffset: function isOffset() {
        var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;

        if (!direction) {
          return this._o;
        }

        if (!this._o) {
          return false;
        }

        // did we view to the right?
        if (direction === '|>') {
          return this.move.direction === '|' && this.move.steps === '>';
        }

        // did we view to the left?
        if (direction === '|<') {
          return this.move.direction === '|' && this.move.steps === '<';
        }

        return this.move.direction === direction;
      },


      
      isBound: function isBound() {
        return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound;
      }
    };

    
    function calculateForwardIndex(viewSize) {
      var index = Glide.index;


      if (Glide.isType('carousel')) {
        return index + viewSize;
      }

      return index + (viewSize - index % viewSize);
    }

    
    function normalizeForwardIndex(index, viewSize) {
      var length = Run.length;


      if (index <= length) {
        return index;
      }

      if (Glide.isType('carousel')) {
        return index - (length + 1);
      }

      if (Glide.settings.rewind) {
        // bound does funny things with the length, therefor we have to be certain
        // that we are on the last possible index value given by bound
        if (Run.isBound() && !Run.isEnd()) {
          return length;
        }

        return 0;
      }

      if (Run.isBound()) {
        return length;
      }

      return Math.floor(length / viewSize) * viewSize;
    }

    
    function calculateBackwardIndex(viewSize) {
      var index = Glide.index;


      if (Glide.isType('carousel')) {
        return index - viewSize;
      }

      // ensure our back navigation results in the same index as a forward navigation
      // to experience a homogeneous paging
      var view = Math.ceil(index / viewSize);

      return (view - 1) * viewSize;
    }

    
    function normalizeBackwardIndex(index, viewSize) {
      var length = Run.length;


      if (index >= 0) {
        return index;
      }

      if (Glide.isType('carousel')) {
        return index + (length + 1);
      }

      if (Glide.settings.rewind) {
        // bound does funny things with the length, therefor we have to be certain
        // that we are on first possible index value before we to rewind to the length given by bound
        if (Run.isBound() && Run.isStart()) {
          return length;
        }

        return Math.floor(length / viewSize) * viewSize;
      }

      return 0;
    }

    define(Run, 'move', {
      
      get: function get() {
        return this._m;
      },


      
      set: function set(value) {
        var step = value.substr(1);

        this._m = {
          direction: value.substr(0, 1),
          steps: step ? toInt(step) ? toInt(step) : step : 0
        };
      }
    });

    define(Run, 'length', {
      
      get: function get() {
        var settings = Glide.settings;
        var length = Components.Html.slides.length;

        // If the `bound` option is active, a maximum running distance should be
        // reduced by `perView` and `focusAt` settings. Running distance
        // should end before creating an empty space after instance.

        if (this.isBound()) {
          return length - 1 - (toInt(settings.perView) - 1) + toInt(settings.focusAt);
        }

        return length - 1;
      }
    });

    define(Run, 'offset', {
      
      get: function get() {
        return this._o;
      }
    });

    return Run;
  }

  
  function now() {
    return new Date().getTime();
  }

  
  function throttle(func, wait, options) {
    var timeout = void 0,
        context = void 0,
        args = void 0,
        result = void 0;
    var previous = 0;
    if (!options) options = {};

    var later = function later() {
      previous = options.leading === false ? 0 : now();
      timeout = null;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    };

    var throttled = function throttled() {
      var at = now();
      if (!previous && options.leading === false) previous = at;
      var remaining = wait - (at - previous);
      context = this;
      args = arguments;
      if (remaining <= 0 || remaining > wait) {
        if (timeout) {
          clearTimeout(timeout);
          timeout = null;
        }
        previous = at;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      } else if (!timeout && options.trailing !== false) {
        timeout = setTimeout(later, remaining);
      }
      return result;
    };

    throttled.cancel = function () {
      clearTimeout(timeout);
      previous = 0;
      timeout = context = args = null;
    };

    return throttled;
  }

  var MARGIN_TYPE = {
    ltr: ['marginLeft', 'marginRight'],
    rtl: ['marginRight', 'marginLeft']
  };

  function Gaps (Glide, Components, Events) {
    var Gaps = {
      
      apply: function apply(slides) {
        for (var i = 0, len = slides.length; i < len; i++) {
          var style = slides[i].style;
          var direction = Components.Direction.value;

          if (i !== 0) {
            style[MARGIN_TYPE[direction][0]] = this.value / 2 + 'px';
          } else {
            style[MARGIN_TYPE[direction][0]] = '';
          }

          if (i !== slides.length - 1) {
            style[MARGIN_TYPE[direction][1]] = this.value / 2 + 'px';
          } else {
            style[MARGIN_TYPE[direction][1]] = '';
          }
        }
      },


      
      remove: function remove(slides) {
        for (var i = 0, len = slides.length; i < len; i++) {
          var style = slides[i].style;

          style.marginLeft = '';
          style.marginRight = '';
        }
      }
    };

    define(Gaps, 'value', {
      
      get: function get() {
        return toInt(Glide.settings.gap);
      }
    });

    define(Gaps, 'grow', {
      
      get: function get() {
        return Gaps.value * Components.Sizes.length;
      }
    });

    define(Gaps, 'reductor', {
      
      get: function get() {
        var perView = Glide.settings.perView;

        return Gaps.value * (perView - 1) / perView;
      }
    });

    
    Events.on(['build.after', 'update'], throttle(function () {
      Gaps.apply(Components.Html.wrapper.children);
    }, 30));

    
    Events.on('destroy', function () {
      Gaps.remove(Components.Html.wrapper.children);
    });

    return Gaps;
  }

  
  function siblings(node) {
    if (node && node.parentNode) {
      var n = node.parentNode.firstChild;
      var matched = [];

      for (; n; n = n.nextSibling) {
        if (n.nodeType === 1 && n !== node) {
          matched.push(n);
        }
      }

      return matched;
    }

    return [];
  }

  
  function exist(node) {
    if (node && node instanceof window.HTMLElement) {
      return true;
    }

    return false;
  }

  var TRACK_SELECTOR = '[data-glide-el="track"]';

  function Html (Glide, Components) {
    var Html = {
      
      mount: function mount() {
        this.root = Glide.selector;
        this.track = this.root.querySelector(TRACK_SELECTOR);
        this.slides = Array.prototype.slice.call(this.wrapper.children).filter(function (slide) {
          return !slide.classList.contains(Glide.settings.classes.slide.clone);
        });
      }
    };

    define(Html, 'root', {
      
      get: function get() {
        return Html._r;
      },


      
      set: function set(r) {
        if (isString(r)) {
          r = document.querySelector(r);
        }

        if (exist(r)) {
          Html._r = r;
        } else {
          warn('Root element must be a existing Html node');
        }
      }
    });

    define(Html, 'track', {
      
      get: function get() {
        return Html._t;
      },


      
      set: function set(t) {
        if (exist(t)) {
          Html._t = t;
        } else {
          warn('Could not find track element. Please use ' + TRACK_SELECTOR + ' attribute.');
        }
      }
    });

    define(Html, 'wrapper', {
      
      get: function get() {
        return Html.track.children[0];
      }
    });

    return Html;
  }

  function Peek (Glide, Components, Events) {
    var Peek = {
      
      mount: function mount() {
        this.value = Glide.settings.peek;
      }
    };

    define(Peek, 'value', {
      
      get: function get() {
        return Peek._v;
      },


      
      set: function set(value) {
        if (isObject(value)) {
          value.before = toInt(value.before);
          value.after = toInt(value.after);
        } else {
          value = toInt(value);
        }

        Peek._v = value;
      }
    });

    define(Peek, 'reductor', {
      
      get: function get() {
        var value = Peek.value;
        var perView = Glide.settings.perView;

        if (isObject(value)) {
          return value.before / perView + value.after / perView;
        }

        return value * 2 / perView;
      }
    });

    
    Events.on(['resize', 'update'], function () {
      Peek.mount();
    });

    return Peek;
  }

  function Move (Glide, Components, Events) {
    var Move = {
      
      mount: function mount() {
        this._o = 0;
      },


      
      make: function make() {
        var _this = this;

        var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;

        this.offset = offset;

        Events.emit('move', {
          movement: this.value
        });

        Components.Transition.after(function () {
          Events.emit('move.after', {
            movement: _this.value
          });
        });
      }
    };

    define(Move, 'offset', {
      
      get: function get() {
        return Move._o;
      },


      
      set: function set(value) {
        Move._o = !isUndefined(value) ? toInt(value) : 0;
      }
    });

    define(Move, 'translate', {
      
      get: function get() {
        return Components.Sizes.slideWidth * Glide.index;
      }
    });

    define(Move, 'value', {
      
      get: function get() {
        var offset = this.offset;
        var translate = this.translate;

        if (Components.Direction.is('rtl')) {
          return translate + offset;
        }

        return translate - offset;
      }
    });

    
    Events.on(['build.before', 'run'], function () {
      Move.make();
    });

    return Move;
  }

  function Sizes (Glide, Components, Events) {
    var Sizes = {
      
      setupSlides: function setupSlides() {
        var width = this.slideWidth + 'px';
        var slides = Components.Html.slides;

        for (var i = 0; i < slides.length; i++) {
          slides[i].style.width = width;
        }
      },


      
      setupWrapper: function setupWrapper() {
        Components.Html.wrapper.style.width = this.wrapperSize + 'px';
      },


      
      remove: function remove() {
        var slides = Components.Html.slides;

        for (var i = 0; i < slides.length; i++) {
          slides[i].style.width = '';
        }

        Components.Html.wrapper.style.width = '';
      }
    };

    define(Sizes, 'length', {
      
      get: function get() {
        return Components.Html.slides.length;
      }
    });

    define(Sizes, 'width', {
      
      get: function get() {
        return Components.Html.root.offsetWidth;
      }
    });

    define(Sizes, 'wrapperSize', {
      
      get: function get() {
        return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow;
      }
    });

    define(Sizes, 'slideWidth', {
      
      get: function get() {
        return Sizes.width / Glide.settings.perView - Components.Peek.reductor - Components.Gaps.reductor;
      }
    });

    
    Events.on(['build.before', 'resize', 'update'], function () {
      Sizes.setupSlides();
      Sizes.setupWrapper();
    });

    
    Events.on('destroy', function () {
      Sizes.remove();
    });

    return Sizes;
  }

  function Build (Glide, Components, Events) {
    var Build = {
      
      mount: function mount() {
        Events.emit('build.before');

        this.typeClass();
        this.activeClass();

        Events.emit('build.after');
      },


      
      typeClass: function typeClass() {
        Components.Html.root.classList.add(Glide.settings.classes.type[Glide.settings.type]);
      },


      
      activeClass: function activeClass() {
        var classes = Glide.settings.classes;
        var slide = Components.Html.slides[Glide.index];

        if (slide) {
          slide.classList.add(classes.slide.active);

          siblings(slide).forEach(function (sibling) {
            sibling.classList.remove(classes.slide.active);
          });
        }
      },


      
      removeClasses: function removeClasses() {
        var _Glide$settings$class = Glide.settings.classes,
            type = _Glide$settings$class.type,
            slide = _Glide$settings$class.slide;


        Components.Html.root.classList.remove(type[Glide.settings.type]);

        Components.Html.slides.forEach(function (sibling) {
          sibling.classList.remove(slide.active);
        });
      }
    };

    
    Events.on(['destroy', 'update'], function () {
      Build.removeClasses();
    });

    
    Events.on(['resize', 'update'], function () {
      Build.mount();
    });

    
    Events.on('move.after', function () {
      Build.activeClass();
    });

    return Build;
  }

  function Clones (Glide, Components, Events) {
    var Clones = {
      
      mount: function mount() {
        this.items = [];

        if (Glide.isType('carousel')) {
          this.items = this.collect();
        }
      },


      
      collect: function collect() {
        var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
        var slides = Components.Html.slides;
        var _Glide$settings = Glide.settings,
            perView = _Glide$settings.perView,
            classes = _Glide$settings.classes;


        var peekIncrementer = +!!Glide.settings.peek;
        var cloneCount = perView + peekIncrementer + Math.round(perView / 2);
        var append = slides.slice(0, cloneCount).reverse();
        var prepend = slides.slice(cloneCount * -1);

        for (var r = 0; r < Math.max(1, Math.floor(perView / slides.length)); r++) {
          for (var i = 0; i < append.length; i++) {
            var clone = append[i].cloneNode(true);

            clone.classList.add(classes.slide.clone);

            items.push(clone);
          }

          for (var _i = 0; _i < prepend.length; _i++) {
            var _clone = prepend[_i].cloneNode(true);

            _clone.classList.add(classes.slide.clone);

            items.unshift(_clone);
          }
        }

        return items;
      },


      
      append: function append() {
        var items = this.items;
        var _Components$Html = Components.Html,
            wrapper = _Components$Html.wrapper,
            slides = _Components$Html.slides;


        var half = Math.floor(items.length / 2);
        var prepend = items.slice(0, half).reverse();
        var append = items.slice(half * -1).reverse();
        var width = Components.Sizes.slideWidth + 'px';

        for (var i = 0; i < append.length; i++) {
          wrapper.appendChild(append[i]);
        }

        for (var _i2 = 0; _i2 < prepend.length; _i2++) {
          wrapper.insertBefore(prepend[_i2], slides[0]);
        }

        for (var _i3 = 0; _i3 < items.length; _i3++) {
          items[_i3].style.width = width;
        }
      },


      
      remove: function remove() {
        var items = this.items;


        for (var i = 0; i < items.length; i++) {
          Components.Html.wrapper.removeChild(items[i]);
        }
      }
    };

    define(Clones, 'grow', {
      
      get: function get() {
        return (Components.Sizes.slideWidth + Components.Gaps.value) * Clones.items.length;
      }
    });

    
    Events.on('update', function () {
      Clones.remove();
      Clones.mount();
      Clones.append();
    });

    
    Events.on('build.before', function () {
      if (Glide.isType('carousel')) {
        Clones.append();
      }
    });

    
    Events.on('destroy', function () {
      Clones.remove();
    });

    return Clones;
  }

  var EventsBinder = function () {
    
    function EventsBinder() {
      var listeners = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      classCallCheck(this, EventsBinder);

      this.listeners = listeners;
    }

    


    createClass(EventsBinder, [{
      key: 'on',
      value: function on(events, el, closure) {
        var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

        if (isString(events)) {
          events = [events];
        }

        for (var i = 0; i < events.length; i++) {
          this.listeners[events[i]] = closure;

          el.addEventListener(events[i], this.listeners[events[i]], capture);
        }
      }

      

    }, {
      key: 'off',
      value: function off(events, el) {
        var capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

        if (isString(events)) {
          events = [events];
        }

        for (var i = 0; i < events.length; i++) {
          el.removeEventListener(events[i], this.listeners[events[i]], capture);
        }
      }

      

    }, {
      key: 'destroy',
      value: function destroy() {
        delete this.listeners;
      }
    }]);
    return EventsBinder;
  }();

  function Resize (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    var Resize = {
      
      mount: function mount() {
        this.bind();
      },


      
      bind: function bind() {
        Binder.on('resize', window, throttle(function () {
          Events.emit('resize');
        }, Glide.settings.throttle));
      },


      
      unbind: function unbind() {
        Binder.off('resize', window);
      }
    };

    
    Events.on('destroy', function () {
      Resize.unbind();
      Binder.destroy();
    });

    return Resize;
  }

  var VALID_DIRECTIONS = ['ltr', 'rtl'];
  var FLIPED_MOVEMENTS = {
    '>': '<',
    '<': '>',
    '=': '='
  };

  function Direction (Glide, Components, Events) {
    var Direction = {
      
      mount: function mount() {
        this.value = Glide.settings.direction;
      },


      
      resolve: function resolve(pattern) {
        var token = pattern.slice(0, 1);

        if (this.is('rtl')) {
          return pattern.split(token).join(FLIPED_MOVEMENTS[token]);
        }

        return pattern;
      },


      
      is: function is(direction) {
        return this.value === direction;
      },


      
      addClass: function addClass() {
        Components.Html.root.classList.add(Glide.settings.classes.direction[this.value]);
      },


      
      removeClass: function removeClass() {
        Components.Html.root.classList.remove(Glide.settings.classes.direction[this.value]);
      }
    };

    define(Direction, 'value', {
      
      get: function get() {
        return Direction._v;
      },


      
      set: function set(value) {
        if (VALID_DIRECTIONS.indexOf(value) > -1) {
          Direction._v = value;
        } else {
          warn('Direction value must be `ltr` or `rtl`');
        }
      }
    });

    
    Events.on(['destroy', 'update'], function () {
      Direction.removeClass();
    });

    
    Events.on('update', function () {
      Direction.mount();
    });

    
    Events.on(['build.before', 'update'], function () {
      Direction.addClass();
    });

    return Direction;
  }

  
  function Rtl (Glide, Components) {
    return {
      
      modify: function modify(translate) {
        if (Components.Direction.is('rtl')) {
          return -translate;
        }

        return translate;
      }
    };
  }

  
  function Gap (Glide, Components) {
    return {
      
      modify: function modify(translate) {
        var multiplier = Math.floor(translate / Components.Sizes.slideWidth);
        return translate + Components.Gaps.value * multiplier;
      }
    };
  }

  
  function Grow (Glide, Components) {
    return {
      
      modify: function modify(translate) {
        return translate + Components.Clones.grow / 2;
      }
    };
  }

  
  function Peeking (Glide, Components) {
    return {
      
      modify: function modify(translate) {
        if (Glide.settings.focusAt >= 0) {
          var peek = Components.Peek.value;

          if (isObject(peek)) {
            return translate - peek.before;
          }

          return translate - peek;
        }

        return translate;
      }
    };
  }

  
  function Focusing (Glide, Components) {
    return {
      
      modify: function modify(translate) {
        var gap = Components.Gaps.value;
        var width = Components.Sizes.width;
        var focusAt = Glide.settings.focusAt;
        var slideWidth = Components.Sizes.slideWidth;

        if (focusAt === 'center') {
          return translate - (width / 2 - slideWidth / 2);
        }

        return translate - slideWidth * focusAt - gap * focusAt;
      }
    };
  }

  
  function mutator (Glide, Components, Events) {
    
    var TRANSFORMERS = [Gap, Grow, Peeking, Focusing].concat(Glide._t, [Rtl]);

    return {
      
      mutate: function mutate(translate) {
        for (var i = 0; i < TRANSFORMERS.length; i++) {
          var transformer = TRANSFORMERS[i];

          if (isFunction(transformer) && isFunction(transformer().modify)) {
            translate = transformer(Glide, Components, Events).modify(translate);
          } else {
            warn('Transformer should be a function that returns an object with `modify()` method');
          }
        }

        return translate;
      }
    };
  }

  function Translate (Glide, Components, Events) {
    var Translate = {
      
      set: function set(value) {
        var transform = mutator(Glide, Components).mutate(value);

        Components.Html.wrapper.style.transform = 'translate3d(' + -1 * transform + 'px, 0px, 0px)';
      },


      
      remove: function remove() {
        Components.Html.wrapper.style.transform = '';
      },


      
      getStartIndex: function getStartIndex() {
        var length = Components.Sizes.length;
        var index = Glide.index;
        var perView = Glide.settings.perView;

        if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {
          return length + (index - perView);
        }

        // "modulo length" converts an index that equals length to zero
        return (index + perView) % length;
      },


      
      getTravelDistance: function getTravelDistance() {
        var travelDistance = Components.Sizes.slideWidth * Glide.settings.perView;

        if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {
          // reverse travel distance so that we don't have to change subtract operations
          return travelDistance * -1;
        }

        return travelDistance;
      }
    };

    
    Events.on('move', function (context) {
      if (!Glide.isType('carousel') || !Components.Run.isOffset()) {
        return Translate.set(context.movement);
      }

      Components.Transition.after(function () {
        Events.emit('translate.jump');

        Translate.set(Components.Sizes.slideWidth * Glide.index);
      });

      var startWidth = Components.Sizes.slideWidth * Components.Translate.getStartIndex();
      return Translate.set(startWidth - Components.Translate.getTravelDistance());
    });

    
    Events.on('destroy', function () {
      Translate.remove();
    });

    return Translate;
  }

  function Transition (Glide, Components, Events) {
    
    var disabled = false;

    var Transition = {
      
      compose: function compose(property) {
        var settings = Glide.settings;

        if (!disabled) {
          return property + ' ' + this.duration + 'ms ' + settings.animationTimingFunc;
        }

        return property + ' 0ms ' + settings.animationTimingFunc;
      },


      
      set: function set() {
        var property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform';

        Components.Html.wrapper.style.transition = this.compose(property);
      },


      
      remove: function remove() {
        Components.Html.wrapper.style.transition = '';
      },


      
      after: function after(callback) {
        setTimeout(function () {
          callback();
        }, this.duration);
      },


      
      enable: function enable() {
        disabled = false;

        this.set();
      },


      
      disable: function disable() {
        disabled = true;

        this.set();
      }
    };

    define(Transition, 'duration', {
      
      get: function get() {
        var settings = Glide.settings;

        if (Glide.isType('slider') && Components.Run.offset) {
          return settings.rewindDuration;
        }

        return settings.animationDuration;
      }
    });

    
    Events.on('move', function () {
      Transition.set();
    });

    
    Events.on(['build.before', 'resize', 'translate.jump'], function () {
      Transition.disable();
    });

    
    Events.on('run', function () {
      Transition.enable();
    });

    
    Events.on('destroy', function () {
      Transition.remove();
    });

    return Transition;
  }

  

  var supportsPassive = false;

  try {
    var opts = Object.defineProperty({}, 'passive', {
      get: function get() {
        supportsPassive = true;
      }
    });

    window.addEventListener('testPassive', null, opts);
    window.removeEventListener('testPassive', null, opts);
  } catch (e) {}

  var supportsPassive$1 = supportsPassive;

  var START_EVENTS = ['touchstart', 'mousedown'];
  var MOVE_EVENTS = ['touchmove', 'mousemove'];
  var END_EVENTS = ['touchend', 'touchcancel', 'mouseup', 'mouseleave'];
  var MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseleave'];

  function Swipe (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    var swipeSin = 0;
    var swipeStartX = 0;
    var swipeStartY = 0;
    var disabled = false;
    var capture = supportsPassive$1 ? { passive: true } : false;

    var Swipe = {
      
      mount: function mount() {
        this.bindSwipeStart();
      },


      
      start: function start(event) {
        if (!disabled && !Glide.disabled) {
          this.disable();

          var swipe = this.touches(event);

          swipeSin = null;
          swipeStartX = toInt(swipe.pageX);
          swipeStartY = toInt(swipe.pageY);

          this.bindSwipeMove();
          this.bindSwipeEnd();

          Events.emit('swipe.start');
        }
      },


      
      move: function move(event) {
        if (!Glide.disabled) {
          var _Glide$settings = Glide.settings,
              touchAngle = _Glide$settings.touchAngle,
              touchRatio = _Glide$settings.touchRatio,
              classes = _Glide$settings.classes;


          var swipe = this.touches(event);

          var subExSx = toInt(swipe.pageX) - swipeStartX;
          var subEySy = toInt(swipe.pageY) - swipeStartY;
          var powEX = Math.abs(subExSx << 2);
          var powEY = Math.abs(subEySy << 2);
          var swipeHypotenuse = Math.sqrt(powEX + powEY);
          var swipeCathetus = Math.sqrt(powEY);

          swipeSin = Math.asin(swipeCathetus / swipeHypotenuse);

          if (swipeSin * 180 / Math.PI < touchAngle) {
            event.stopPropagation();

            Components.Move.make(subExSx * toFloat(touchRatio));

            Components.Html.root.classList.add(classes.dragging);

            Events.emit('swipe.move');
          } else {
            return false;
          }
        }
      },


      
      end: function end(event) {
        if (!Glide.disabled) {
          var _Glide$settings2 = Glide.settings,
              perSwipe = _Glide$settings2.perSwipe,
              touchAngle = _Glide$settings2.touchAngle,
              classes = _Glide$settings2.classes;


          var swipe = this.touches(event);
          var threshold = this.threshold(event);

          var swipeDistance = swipe.pageX - swipeStartX;
          var swipeDeg = swipeSin * 180 / Math.PI;

          this.enable();

          if (swipeDistance > threshold && swipeDeg < touchAngle) {
            Components.Run.make(Components.Direction.resolve(perSwipe + '<'));
          } else if (swipeDistance < -threshold && swipeDeg < touchAngle) {
            Components.Run.make(Components.Direction.resolve(perSwipe + '>'));
          } else {
            // While swipe don't reach distance apply previous transform.
            Components.Move.make();
          }

          Components.Html.root.classList.remove(classes.dragging);

          this.unbindSwipeMove();
          this.unbindSwipeEnd();

          Events.emit('swipe.end');
        }
      },


      
      bindSwipeStart: function bindSwipeStart() {
        var _this = this;

        var _Glide$settings3 = Glide.settings,
            swipeThreshold = _Glide$settings3.swipeThreshold,
            dragThreshold = _Glide$settings3.dragThreshold;


        if (swipeThreshold) {
          Binder.on(START_EVENTS[0], Components.Html.wrapper, function (event) {
            _this.start(event);
          }, capture);
        }

        if (dragThreshold) {
          Binder.on(START_EVENTS[1], Components.Html.wrapper, function (event) {
            _this.start(event);
          }, capture);
        }
      },


      
      unbindSwipeStart: function unbindSwipeStart() {
        Binder.off(START_EVENTS[0], Components.Html.wrapper, capture);
        Binder.off(START_EVENTS[1], Components.Html.wrapper, capture);
      },


      
      bindSwipeMove: function bindSwipeMove() {
        var _this2 = this;

        Binder.on(MOVE_EVENTS, Components.Html.wrapper, throttle(function (event) {
          _this2.move(event);
        }, Glide.settings.throttle), capture);
      },


      
      unbindSwipeMove: function unbindSwipeMove() {
        Binder.off(MOVE_EVENTS, Components.Html.wrapper, capture);
      },


      
      bindSwipeEnd: function bindSwipeEnd() {
        var _this3 = this;

        Binder.on(END_EVENTS, Components.Html.wrapper, function (event) {
          _this3.end(event);
        });
      },


      
      unbindSwipeEnd: function unbindSwipeEnd() {
        Binder.off(END_EVENTS, Components.Html.wrapper);
      },


      
      touches: function touches(event) {
        if (MOUSE_EVENTS.indexOf(event.type) > -1) {
          return event;
        }

        return event.touches[0] || event.changedTouches[0];
      },


      
      threshold: function threshold(event) {
        var settings = Glide.settings;

        if (MOUSE_EVENTS.indexOf(event.type) > -1) {
          return settings.dragThreshold;
        }

        return settings.swipeThreshold;
      },


      
      enable: function enable() {
        disabled = false;

        Components.Transition.enable();

        return this;
      },


      
      disable: function disable() {
        disabled = true;

        Components.Transition.disable();

        return this;
      }
    };

    
    Events.on('build.after', function () {
      Components.Html.root.classList.add(Glide.settings.classes.swipeable);
    });

    
    Events.on('destroy', function () {
      Swipe.unbindSwipeStart();
      Swipe.unbindSwipeMove();
      Swipe.unbindSwipeEnd();
      Binder.destroy();
    });

    return Swipe;
  }

  function Images (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    var Images = {
      
      mount: function mount() {
        this.bind();
      },


      
      bind: function bind() {
        Binder.on('dragstart', Components.Html.wrapper, this.dragstart);
      },


      
      unbind: function unbind() {
        Binder.off('dragstart', Components.Html.wrapper);
      },


      
      dragstart: function dragstart(event) {
        event.preventDefault();
      }
    };

    
    Events.on('destroy', function () {
      Images.unbind();
      Binder.destroy();
    });

    return Images;
  }

  function Anchors (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    
    var detached = false;

    
    var prevented = false;

    var Anchors = {
      
      mount: function mount() {
        
        this._a = Components.Html.wrapper.querySelectorAll('a');

        this.bind();
      },


      
      bind: function bind() {
        Binder.on('click', Components.Html.wrapper, this.click);
      },


      
      unbind: function unbind() {
        Binder.off('click', Components.Html.wrapper);
      },


      
      click: function click(event) {
        if (prevented) {
          event.stopPropagation();
          event.preventDefault();
        }
      },


      
      detach: function detach() {
        prevented = true;

        if (!detached) {
          for (var i = 0; i < this.items.length; i++) {
            this.items[i].draggable = false;

            this.items[i].setAttribute('data-href', this.items[i].getAttribute('href'));

            this.items[i].removeAttribute('href');
          }

          detached = true;
        }

        return this;
      },


      
      attach: function attach() {
        prevented = false;

        if (detached) {
          for (var i = 0; i < this.items.length; i++) {
            this.items[i].draggable = true;

            this.items[i].setAttribute('href', this.items[i].getAttribute('data-href'));
          }

          detached = false;
        }

        return this;
      }
    };

    define(Anchors, 'items', {
      
      get: function get() {
        return Anchors._a;
      }
    });

    
    Events.on('swipe.move', function () {
      Anchors.detach();
    });

    
    Events.on('swipe.end', function () {
      Components.Transition.after(function () {
        Anchors.attach();
      });
    });

    
    Events.on('destroy', function () {
      Anchors.attach();
      Anchors.unbind();
      Binder.destroy();
    });

    return Anchors;
  }

  var NAV_SELECTOR = '[data-glide-el="controls[nav]"]';
  var CONTROLS_SELECTOR = '[data-glide-el^="controls"]';

  function Controls (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    var capture = supportsPassive$1 ? { passive: true } : false;

    var Controls = {
      
      mount: function mount() {
        
        this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR);

        
        this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR);

        this.addBindings();
      },


      
      setActive: function setActive() {
        for (var i = 0; i < this._n.length; i++) {
          this.addClass(this._n[i].children);
        }
      },


      
      removeActive: function removeActive() {
        for (var i = 0; i < this._n.length; i++) {
          this.removeClass(this._n[i].children);
        }
      },


      
      addClass: function addClass(controls) {
        var settings = Glide.settings;
        var item = controls[Glide.index];

        if (item) {
          item.classList.add(settings.classes.nav.active);

          siblings(item).forEach(function (sibling) {
            sibling.classList.remove(settings.classes.nav.active);
          });
        }
      },


      
      removeClass: function removeClass(controls) {
        var item = controls[Glide.index];

        if (item) {
          item.classList.remove(Glide.settings.classes.nav.active);
        }
      },


      
      addBindings: function addBindings() {
        for (var i = 0; i < this._c.length; i++) {
          this.bind(this._c[i].children);
        }
      },


      
      removeBindings: function removeBindings() {
        for (var i = 0; i < this._c.length; i++) {
          this.unbind(this._c[i].children);
        }
      },


      
      bind: function bind(elements) {
        for (var i = 0; i < elements.length; i++) {
          Binder.on('click', elements[i], this.click);
          Binder.on('touchstart', elements[i], this.click, capture);
        }
      },


      
      unbind: function unbind(elements) {
        for (var i = 0; i < elements.length; i++) {
          Binder.off(['click', 'touchstart'], elements[i]);
        }
      },


      
      click: function click(event) {
        event.preventDefault();

        Components.Run.make(Components.Direction.resolve(event.currentTarget.getAttribute('data-glide-dir')));
      }
    };

    define(Controls, 'items', {
      
      get: function get() {
        return Controls._c;
      }
    });

    
    Events.on(['mount.after', 'move.after'], function () {
      Controls.setActive();
    });

    
    Events.on('destroy', function () {
      Controls.removeBindings();
      Controls.removeActive();
      Binder.destroy();
    });

    return Controls;
  }

  function Keyboard (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    var Keyboard = {
      
      mount: function mount() {
        if (Glide.settings.keyboard) {
          this.bind();
        }
      },


      
      bind: function bind() {
        Binder.on('keyup', document, this.press);
      },


      
      unbind: function unbind() {
        Binder.off('keyup', document);
      },


      
      press: function press(event) {
        if (event.keyCode === 39) {
          Components.Run.make(Components.Direction.resolve('>'));
        }

        if (event.keyCode === 37) {
          Components.Run.make(Components.Direction.resolve('<'));
        }
      }
    };

    
    Events.on(['destroy', 'update'], function () {
      Keyboard.unbind();
    });

    
    Events.on('update', function () {
      Keyboard.mount();
    });

    
    Events.on('destroy', function () {
      Binder.destroy();
    });

    return Keyboard;
  }

  function Autoplay (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    var Autoplay = {
      
      mount: function mount() {
        this.start();

        if (Glide.settings.hoverpause) {
          this.bind();
        }
      },


      
      start: function start() {
        var _this = this;

        if (Glide.settings.autoplay) {
          if (isUndefined(this._i)) {
            this._i = setInterval(function () {
              _this.stop();

              Components.Run.make('>');

              _this.start();
            }, this.time);
          }
        }
      },


      
      stop: function stop() {
        this._i = clearInterval(this._i);
      },


      
      bind: function bind() {
        var _this2 = this;

        Binder.on('mouseover', Components.Html.root, function () {
          _this2.stop();
        });

        Binder.on('mouseout', Components.Html.root, function () {
          _this2.start();
        });
      },


      
      unbind: function unbind() {
        Binder.off(['mouseover', 'mouseout'], Components.Html.root);
      }
    };

    define(Autoplay, 'time', {
      
      get: function get() {
        var autoplay = Components.Html.slides[Glide.index].getAttribute('data-glide-autoplay');

        if (autoplay) {
          return toInt(autoplay);
        }

        return toInt(Glide.settings.autoplay);
      }
    });

    
    Events.on(['destroy', 'update'], function () {
      Autoplay.unbind();
    });

    
    Events.on(['run.before', 'pause', 'destroy', 'swipe.start', 'update'], function () {
      Autoplay.stop();
    });

    
    Events.on(['run.after', 'play', 'swipe.end'], function () {
      Autoplay.start();
    });

    
    Events.on('update', function () {
      Autoplay.mount();
    });

    
    Events.on('destroy', function () {
      Binder.destroy();
    });

    return Autoplay;
  }

  
  function sortBreakpoints(points) {
    if (isObject(points)) {
      return sortKeys(points);
    } else {
      warn('Breakpoints option must be an object');
    }

    return {};
  }

  function Breakpoints (Glide, Components, Events) {
    
    var Binder = new EventsBinder();

    
    var settings = Glide.settings;

    
    var points = sortBreakpoints(settings.breakpoints);

    
    var defaults = _extends({}, settings);

    var Breakpoints = {
      
      match: function match(points) {
        if (typeof window.matchMedia !== 'undefined') {
          for (var point in points) {
            if (points.hasOwnProperty(point)) {
              if (window.matchMedia('(max-width: ' + point + 'px)').matches) {
                return points[point];
              }
            }
          }
        }

        return defaults;
      }
    };

    
    _extends(settings, Breakpoints.match(points));

    
    Binder.on('resize', window, throttle(function () {
      Glide.settings = mergeOptions(settings, Breakpoints.match(points));
    }, Glide.settings.throttle));

    
    Events.on('update', function () {
      points = sortBreakpoints(points);

      defaults = _extends({}, settings);
    });

    
    Events.on('destroy', function () {
      Binder.off('resize', window);
    });

    return Breakpoints;
  }

  var COMPONENTS = {
    // Required
    Html: Html,
    Translate: Translate,
    Transition: Transition,
    Direction: Direction,
    Peek: Peek,
    Sizes: Sizes,
    Gaps: Gaps,
    Move: Move,
    Clones: Clones,
    Resize: Resize,
    Build: Build,
    Run: Run,

    // Optional
    Swipe: Swipe,
    Images: Images,
    Anchors: Anchors,
    Controls: Controls,
    Keyboard: Keyboard,
    Autoplay: Autoplay,
    Breakpoints: Breakpoints
  };

  var Glide$1 = function (_Core) {
    inherits(Glide$$1, _Core);

    function Glide$$1() {
      classCallCheck(this, Glide$$1);
      return possibleConstructorReturn(this, (Glide$$1.__proto__ || Object.getPrototypeOf(Glide$$1)).apply(this, arguments));
    }

    createClass(Glide$$1, [{
      key: 'mount',
      value: function mount() {
        var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

        return get(Glide$$1.prototype.__proto__ || Object.getPrototypeOf(Glide$$1.prototype), 'mount', this).call(this, _extends({}, COMPONENTS, extensions));
      }
    }]);
    return Glide$$1;
  }(Glide);

  return Glide$1;

})));
// source --> //bisonapp.com/wp-content/uploads/custom-css-js/3036.js?v=5987 
/******* Do not edit this file *******
Simple Custom CSS and JS - by Silkypress.com
Saved: Apr 24 2020 | 11:37:02 */

;(function() {
  'use strict';

  
  var objectTypes = {
    'function': true,
    'object': true
  };

  
  var root = (objectTypes[typeof window] && window) || this;

  
  var oldRoot = root;

  
  var freeExports = objectTypes[typeof exports] && exports;

  
  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;

  
  var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
    root = freeGlobal;
  }

  
  var maxSafeInteger = Math.pow(2, 53) - 1;

  
  var reOpera = /\bOpera/;

  
  var thisBinding = this;

  
  var objectProto = Object.prototype;

  
  var hasOwnProperty = objectProto.hasOwnProperty;

  
  var toString = objectProto.toString;

  

  
  function capitalize(string) {
    string = String(string);
    return string.charAt(0).toUpperCase() + string.slice(1);
  }

  
  function cleanupOS(os, pattern, label) {
    // Platform tokens are defined at:
    // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
    // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
    var data = {
      '10.0': '10',
      '6.4':  '10 Technical Preview',
      '6.3':  '8.1',
      '6.2':  '8',
      '6.1':  'Server 2008 R2 / 7',
      '6.0':  'Server 2008 / Vista',
      '5.2':  'Server 2003 / XP 64-bit',
      '5.1':  'XP',
      '5.01': '2000 SP1',
      '5.0':  '2000',
      '4.0':  'NT',
      '4.90': 'ME'
    };
    // Detect Windows version from platform tokens.
    if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) &&
        (data = data[/[\d.]+$/.exec(os)])) {
      os = 'Windows ' + data;
    }
    // Correct character case and cleanup string.
    os = String(os);

    if (pattern && label) {
      os = os.replace(RegExp(pattern, 'i'), label);
    }

    os = format(
      os.replace(/ ce$/i, ' CE')
        .replace(/\bhpw/i, 'web')
        .replace(/\bMacintosh\b/, 'Mac OS')
        .replace(/_PowerPC\b/i, ' OS')
        .replace(/\b(OS X) [^ \d]+/i, '$1')
        .replace(/\bMac (OS X)\b/, '$1')
        .replace(/\/(\d)/, ' $1')
        .replace(/_/g, '.')
        .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
        .replace(/\bx86\.64\b/gi, 'x86_64')
        .replace(/\b(Windows Phone) OS\b/, '$1')
        .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1')
        .split(' on ')[0]
    );

    return os;
  }

  
  function each(object, callback) {
    var index = -1,
        length = object ? object.length : 0;

    if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
      while (++index < length) {
        callback(object[index], index, object);
      }
    } else {
      forOwn(object, callback);
    }
  }

  
  function format(string) {
    string = trim(string);
    return /^(?:webOS|i(?:OS|P))/.test(string)
      ? string
      : capitalize(string);
  }

  
  function forOwn(object, callback) {
    for (var key in object) {
      if (hasOwnProperty.call(object, key)) {
        callback(object[key], key, object);
      }
    }
  }

  
  function getClassOf(value) {
    return value == null
      ? capitalize(value)
      : toString.call(value).slice(8, -1);
  }

  
  function isHostType(object, property) {
    var type = object != null ? typeof object[property] : 'number';
    return !/^(?:boolean|number|string|undefined)$/.test(type) &&
      (type == 'object' ? !!object[property] : true);
  }

  
  function qualify(string) {
    return String(string).replace(/([ -])(?!$)/g, '$1?');
  }

  
  function reduce(array, callback) {
    var accumulator = null;
    each(array, function(value, index) {
      accumulator = callback(accumulator, value, index, array);
    });
    return accumulator;
  }

  
  function trim(string) {
    return String(string).replace(/^ +| +$/g, '');
  }

  

  
  function parse(ua) {

    
    var context = root;

    
    var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String';

    // Juggle arguments.
    if (isCustomContext) {
      context = ua;
      ua = null;
    }

    
    var nav = context.navigator || {};

    
    var userAgent = nav.userAgent || '';

    ua || (ua = userAgent);

    
    var isModuleScope = isCustomContext || thisBinding == oldRoot;

    
    var likeChrome = isCustomContext
      ? !!nav.likeChrome
      : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString());

    
    var objectClass = 'Object',
        airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject',
        enviroClass = isCustomContext ? objectClass : 'Environment',
        javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java),
        phantomClass = isCustomContext ? objectClass : 'RuntimeObject';

    
    var java = /\bJava/.test(javaClass) && context.java;

    
    var rhino = java && getClassOf(context.environment) == enviroClass;

    
    var alpha = java ? 'a' : '\u03b1';

    
    var beta = java ? 'b' : '\u03b2';

    
    var doc = context.document || {};

    
    var opera = context.operamini || context.opera;

    
    var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera))
      ? operaClass
      : (opera = null);

    

    
    var data;

    
    var arch = ua;

    
    var description = [];

    
    var prerelease = null;

    
    var useFeatures = ua == userAgent;

    
    var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();

    
    var isSpecialCasedOS;

    
    var layout = getLayout([
      { 'label': 'EdgeHTML', 'pattern': '(?:Edge|EdgA|EdgiOS)' },
      'Trident',
      { 'label': 'WebKit', 'pattern': 'AppleWebKit' },
      'iCab',
      'Presto',
      'NetFront',
      'Tasman',
      'KHTML',
      'Gecko'
    ]);

    
    var name = getName([
      'Adobe AIR',
      'Arora',
      'Avant Browser',
      'Breach',
      'Camino',
      'Electron',
      'Epiphany',
      'Fennec',
      'Flock',
      'Galeon',
      'GreenBrowser',
      'iCab',
      'Iceweasel',
      'K-Meleon',
      'Konqueror',
      'Lunascape',
      'Maxthon',
      { 'label': 'Microsoft Edge', 'pattern': '(?:Edge|Edg|EdgA|EdgiOS)' },
      'Midori',
      'Nook Browser',
      'PaleMoon',
      'PhantomJS',
      'Raven',
      'Rekonq',
      'RockMelt',
      { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' },
      'SeaMonkey',
      { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
      'Sleipnir',
      'SlimBrowser',
      { 'label': 'SRWare Iron', 'pattern': 'Iron' },
      'Sunrise',
      'Swiftfox',
      'Waterfox',
      'WebPositive',
      'Opera Mini',
      { 'label': 'Opera Mini', 'pattern': 'OPiOS' },
      'Opera',
      { 'label': 'Opera', 'pattern': 'OPR' },
      'Chrome',
      { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
      { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
      { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' },
      { 'label': 'IE', 'pattern': 'IEMobile' },
      { 'label': 'IE', 'pattern': 'MSIE' },
      'Safari'
    ]);

    
    var product = getProduct([
      { 'label': 'BlackBerry', 'pattern': 'BB10' },
      'BlackBerry',
      { 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
      { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
      { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
      { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
      { 'label': 'Galaxy S5', 'pattern': 'SM-G900' },
      { 'label': 'Galaxy S6', 'pattern': 'SM-G920' },
      { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' },
      { 'label': 'Galaxy S7', 'pattern': 'SM-G930' },
      { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' },
      'Google TV',
      'Lumia',
      'iPad',
      'iPod',
      'iPhone',
      'Kindle',
      { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
      'Nexus',
      'Nook',
      'PlayBook',
      'PlayStation Vita',
      'PlayStation',
      'TouchPad',
      'Transformer',
      { 'label': 'Wii U', 'pattern': 'WiiU' },
      'Wii',
      'Xbox One',
      { 'label': 'Xbox 360', 'pattern': 'Xbox' },
      'Xoom'
    ]);

    
    var manufacturer = getManufacturer({
      'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
      'Archos': {},
      'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
      'Asus': { 'Transformer': 1 },
      'Barnes & Noble': { 'Nook': 1 },
      'BlackBerry': { 'PlayBook': 1 },
      'Google': { 'Google TV': 1, 'Nexus': 1 },
      'HP': { 'TouchPad': 1 },
      'HTC': {},
      'LG': {},
      'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
      'Motorola': { 'Xoom': 1 },
      'Nintendo': { 'Wii U': 1,  'Wii': 1 },
      'Nokia': { 'Lumia': 1 },
      'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
      'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 }
    });

    
    var os = getOS([
      'Windows Phone',
      'Android',
      'CentOS',
      { 'label': 'Chrome OS', 'pattern': 'CrOS' },
      'Debian',
      'Fedora',
      'FreeBSD',
      'Gentoo',
      'Haiku',
      'Kubuntu',
      'Linux Mint',
      'OpenBSD',
      'Red Hat',
      'SuSE',
      'Ubuntu',
      'Xubuntu',
      'Cygwin',
      'Symbian OS',
      'hpwOS',
      'webOS ',
      'webOS',
      'Tablet OS',
      'Tizen',
      'Linux',
      'Mac OS X',
      'Macintosh',
      'Mac',
      'Windows 98;',
      'Windows '
    ]);

    

    
    function getLayout(guesses) {
      return reduce(guesses, function(result, guess) {
        return result || RegExp('\\b' + (
          guess.pattern || qualify(guess)
        ) + '\\b', 'i').exec(ua) && (guess.label || guess);
      });
    }

    
    function getManufacturer(guesses) {
      return reduce(guesses, function(result, value, key) {
        // Lookup the manufacturer by product or scan the UA for the manufacturer.
        return result || (
          value[product] ||
          value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
          RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
        ) && key;
      });
    }

    
    function getName(guesses) {
      return reduce(guesses, function(result, guess) {
        return result || RegExp('\\b' + (
          guess.pattern || qualify(guess)
        ) + '\\b', 'i').exec(ua) && (guess.label || guess);
      });
    }

    
    function getOS(guesses) {
      return reduce(guesses, function(result, guess) {
        var pattern = guess.pattern || qualify(guess);
        if (!result && (result =
              RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
            )) {
          result = cleanupOS(result, pattern, guess.label || guess);
        }
        return result;
      });
    }

    
    function getProduct(guesses) {
      return reduce(guesses, function(result, guess) {
        var pattern = guess.pattern || qualify(guess);
        if (!result && (result =
              RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
              RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) ||
              RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
            )) {
          // Split by forward slash and append product version if needed.
          if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
            result[0] += ' ' + result[1];
          }
          // Correct character case and cleanup string.
          guess = guess.label || guess;
          result = format(result[0]
            .replace(RegExp(pattern, 'i'), guess)
            .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
            .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
        }
        return result;
      });
    }

    
    function getVersion(patterns) {
      return reduce(patterns, function(result, pattern) {
        return result || (RegExp(pattern +
          '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
      });
    }

    
    function toStringPlatform() {
      return this.description || '';
    }

    

    // Convert layout to an array so we can add extra details.
    layout && (layout = [layout]);

    // Detect product names that contain their manufacturer's name.
    if (manufacturer && !product) {
      product = getProduct([manufacturer]);
    }
    // Clean up Google TV.
    if ((data = /\bGoogle TV\b/.exec(product))) {
      product = data[0];
    }
    // Detect simulators.
    if (/\bSimulator\b/i.test(ua)) {
      product = (product ? product + ' ' : '') + 'Simulator';
    }
    // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS.
    if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) {
      description.push('running in Turbo/Uncompressed mode');
    }
    // Detect IE Mobile 11.
    if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) {
      data = parse(ua.replace(/like iPhone OS/, ''));
      manufacturer = data.manufacturer;
      product = data.product;
    }
    // Detect iOS.
    else if (/^iP/.test(product)) {
      name || (name = 'Safari');
      os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
        ? ' ' + data[1].replace(/_/g, '.')
        : '');
    }
    // Detect Kubuntu.
    else if (name == 'Konqueror' && !/buntu/i.test(os)) {
      os = 'Kubuntu';
    }
    // Detect Android browsers.
    else if ((manufacturer && manufacturer != 'Google' &&
        ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) ||
        (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) {
      name = 'Android Browser';
      os = /\bAndroid\b/.test(os) ? os : 'Android';
    }
    // Detect Silk desktop/accelerated modes.
    else if (name == 'Silk') {
      if (!/\bMobi/i.test(ua)) {
        os = 'Android';
        description.unshift('desktop mode');
      }
      if (/Accelerated *= *true/i.test(ua)) {
        description.unshift('accelerated');
      }
    }
    // Detect PaleMoon identifying as Firefox.
    else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) {
      description.push('identifying as Firefox ' + data[1]);
    }
    // Detect Firefox OS and products running Firefox.
    else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) {
      os || (os = 'Firefox OS');
      product || (product = data[1]);
    }
    // Detect false positives for Firefox/Safari.
    else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) {
      // Escape the `/` for Firefox 1.
      if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
        // Clear name of false positives.
        name = null;
      }
      // Reassign a generic name.
      if ((data = product || manufacturer || os) &&
          (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) {
        name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser';
      }
    }
    // Add Chrome version to description for Electron.
    else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) {
      description.push('Chromium ' + data);
    }
    // Detect non-Opera (Presto-based) versions (order is important).
    if (!version) {
      version = getVersion([
        '(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))',
        'Version',
        qualify(name),
        '(?:Firefox|Minefield|NetFront)'
      ]);
    }
    // Detect stubborn layout engines.
    if ((data =
          layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' ||
          /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') ||
          /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' ||
          !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') ||
          layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront'
        )) {
      layout = [data];
    }
    // Detect Windows Phone 7 desktop mode.
    if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
      name += ' Mobile';
      os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x');
      description.unshift('desktop mode');
    }
    // Detect Windows Phone 8.x desktop mode.
    else if (/\bWPDesktop\b/i.test(ua)) {
      name = 'IE Mobile';
      os = 'Windows Phone 8.x';
      description.unshift('desktop mode');
      version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]);
    }
    // Detect IE 11 identifying as other browsers.
    else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) {
      if (name) {
        description.push('identifying as ' + name + (version ? ' ' + version : ''));
      }
      name = 'IE';
      version = data[1];
    }
    // Leverage environment features.
    if (useFeatures) {
      // Detect server-side environments.
      // Rhino has a global function while others have a global object.
      if (isHostType(context, 'global')) {
        if (java) {
          data = java.lang.System;
          arch = data.getProperty('os.arch');
          os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
        }
        if (rhino) {
          try {
            version = context.require('ringo/engine').version.join('.');
            name = 'RingoJS';
          } catch(e) {
            if ((data = context.system) && data.global.system == context.system) {
              name = 'Narwhal';
              os || (os = data[0].os || null);
            }
          }
          if (!name) {
            name = 'Rhino';
          }
        }
        else if (
          typeof context.process == 'object' && !context.process.browser &&
          (data = context.process)
        ) {
          if (typeof data.versions == 'object') {
            if (typeof data.versions.electron == 'string') {
              description.push('Node ' + data.versions.node);
              name = 'Electron';
              version = data.versions.electron;
            } else if (typeof data.versions.nw == 'string') {
              description.push('Chromium ' + version, 'Node ' + data.versions.node);
              name = 'NW.js';
              version = data.versions.nw;
            }
          }
          if (!name) {
            name = 'Node.js';
            arch = data.arch;
            os = data.platform;
            version = /[\d.]+/.exec(data.version);
            version = version ? version[0] : null;
          }
        }
      }
      // Detect Adobe AIR.
      else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
        name = 'Adobe AIR';
        os = data.flash.system.Capabilities.os;
      }
      // Detect PhantomJS.
      else if (getClassOf((data = context.phantom)) == phantomClass) {
        name = 'PhantomJS';
        version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
      }
      // Detect IE compatibility modes.
      else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
        // We're in compatibility mode when the Trident version + 4 doesn't
        // equal the document mode.
        version = [version, doc.documentMode];
        if ((data = +data[1] + 4) != version[1]) {
          description.push('IE ' + version[1] + ' mode');
          layout && (layout[1] = '');
          version[1] = data;
        }
        version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
      }
      // Detect IE 11 masking as other browsers.
      else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) {
        description.push('masking as ' + name + ' ' + version);
        name = 'IE';
        version = '11.0';
        layout = ['Trident'];
        os = 'Windows';
      }
      os = os && format(os);
    }
    // Detect prerelease phases.
    if (version && (data =
          /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
          /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
          /\bMinefield\b/i.test(ua) && 'a'
        )) {
      prerelease = /b/i.test(data) ? 'beta' : 'alpha';
      version = version.replace(RegExp(data + '\\+?$'), '') +
        (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
    }
    // Detect Firefox Mobile.
    if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) {
      name = 'Firefox Mobile';
    }
    // Obscure Maxthon's unreliable version.
    else if (name == 'Maxthon' && version) {
      version = version.replace(/\.[\d.]+/, '.x');
    }
    // Detect Xbox 360 and Xbox One.
    else if (/\bXbox\b/i.test(product)) {
      if (product == 'Xbox 360') {
        os = null;
      }
      if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) {
        description.unshift('mobile mode');
      }
    }
    // Add mobile postfix.
    else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) &&
        (os == 'Windows CE' || /Mobi/i.test(ua))) {
      name += ' Mobile';
    }
    // Detect IE platform preview.
    else if (name == 'IE' && useFeatures) {
      try {
        if (context.external === null) {
          description.unshift('platform preview');
        }
      } catch(e) {
        description.unshift('embedded');
      }
    }
    // Detect BlackBerry OS version.
    // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
    else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data =
          (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
          version
        )) {
      data = [data, /BB10/.test(ua)];
      os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
      version = null;
    }
    // Detect Opera identifying/masking itself as another browser.
    // http://www.opera.com/support/kb/view/843/
    else if (this != forOwn && product != 'Wii' && (
          (useFeatures && opera) ||
          (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
          (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) ||
          (name == 'IE' && (
            (os && !/^Win/.test(os) && version > 5.5) ||
            /\bWindows XP\b/.test(os) && version > 8 ||
            version == 8 && !/\bTrident\b/.test(ua)
          ))
        ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {
      // When "identifying", the UA contains both Opera and the other browser's name.
      data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
      if (reOpera.test(name)) {
        if (/\bIE\b/.test(data) && os == 'Mac OS') {
          os = null;
        }
        data = 'identify' + data;
      }
      // When "masking", the UA contains only the other browser's name.
      else {
        data = 'mask' + data;
        if (operaClass) {
          name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
        } else {
          name = 'Opera';
        }
        if (/\bIE\b/.test(data)) {
          os = null;
        }
        if (!useFeatures) {
          version = null;
        }
      }
      layout = ['Presto'];
      description.push(data);
    }
    // Detect WebKit Nightly and approximate Chrome/Safari versions.
    if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
      // Correct build number for numeric comparison.
      // (e.g. "532.5" becomes "532.05")
      data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
      // Nightly builds are postfixed with a "+".
      if (name == 'Safari' && data[1].slice(-1) == '+') {
        name = 'WebKit Nightly';
        prerelease = 'alpha';
        version = data[1].slice(0, -1);
      }
      // Clear incorrect browser versions.
      else if (version == data[1] ||
          version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
        version = null;
      }
      // Use the full Chrome version when available.
      data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1];
      // Detect Blink layout engine.
      if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') {
        layout = ['Blink'];
      }
      // Detect JavaScriptCore.
      // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
      if (!useFeatures || (!likeChrome && !data[1])) {
        layout && (layout[1] = 'like Safari');
        data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8');
      } else {
        layout && (layout[1] = 'like Chrome');
        data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28');
      }
      // Add the postfix of ".x" or "+" for approximate versions.
      layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'));
      // Obscure version for some Safari 1-2 releases.
      if (name == 'Safari' && (!version || parseInt(version) > 45)) {
        version = data;
      }
    }
    // Detect Opera desktop modes.
    if (name == 'Opera' &&  (data = /\bzbov|zvav$/.exec(os))) {
      name += ' ';
      description.unshift('desktop mode');
      if (data == 'zvav') {
        name += 'Mini';
        version = null;
      } else {
        name += 'Mobile';
      }
      os = os.replace(RegExp(' *' + data + '$'), '');
    }
    // Detect Chrome desktop mode.
    else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) {
      description.unshift('desktop mode');
      name = 'Chrome Mobile';
      version = null;

      if (/\bOS X\b/.test(os)) {
        manufacturer = 'Apple';
        os = 'iOS 4.3+';
      } else {
        os = null;
      }
    }
    // Strip incorrect OS versions.
    if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
        ua.indexOf('/' + data + '-') > -1) {
      os = trim(os.replace(data, ''));
    }
    // Add layout engine.
    if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
        /Browser|Lunascape|Maxthon/.test(name) ||
        name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) ||
        /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) {
      // Don't add layout details to description if they are falsey.
      (data = layout[layout.length - 1]) && description.push(data);
    }
    // Combine contextual information.
    if (description.length) {
      description = ['(' + description.join('; ') + ')'];
    }
    // Append manufacturer to description.
    if (manufacturer && product && product.indexOf(manufacturer) < 0) {
      description.push('on ' + manufacturer);
    }
    // Append product to description.
    if (product) {
      description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product);
    }
    // Parse the OS into an object.
    if (os) {
      data = / ([\d.+]+)$/.exec(os);
      isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/';
      os = {
        'architecture': 32,
        'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os,
        'version': data ? data[1] : null,
        'toString': function() {
          var version = this.version;
          return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
        }
      };
    }
    // Add browser/OS architecture.
    if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
      if (os) {
        os.architecture = 64;
        os.family = os.family.replace(RegExp(' *' + data), '');
      }
      if (
          name && (/\bWOW64\b/i.test(ua) ||
          (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua)))
      ) {
        description.unshift('32-bit');
      }
    }
    // Chrome 39 and above on OS X is always 64-bit.
    else if (
        os && /^OS X/.test(os.family) &&
        name == 'Chrome' && parseFloat(version) >= 39
    ) {
      os.architecture = 64;
    }

    ua || (ua = null);

    

    
    var platform = {};

    
    platform.description = ua;

    
    platform.layout = layout && layout[0];

    
    platform.manufacturer = manufacturer;

    
    platform.name = name;

    
    platform.prerelease = prerelease;

    
    platform.product = product;

    
    platform.ua = ua;

    
    platform.version = name && version;

    
    platform.os = os || {

      
      'architecture': null,

      
      'family': null,

      
      'version': null,

      
      'toString': function() { return 'null'; }
    };

    platform.parse = parse;
    platform.toString = toStringPlatform;

    if (platform.version) {
      description.unshift(version);
    }
    if (platform.name) {
      description.unshift(name);
    }
    if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) {
      description.push(product ? '(' + os + ')' : 'on ' + os);
    }
    if (description.length) {
      platform.description = description.join(' ');
    }
    return platform;
  }

  

  // Export platform.
  var platform = parse();

  // Some AMD build optimizers, like r.js, check for condition patterns like the following:
  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
    // Expose platform on the global object to prevent errors when platform is
    // loaded by a script tag in the presence of an AMD loader.
    // See http://requirejs.org/docs/errors.html#mismatch for more details.
    root.platform = platform;

    // Define as an anonymous module so platform can be aliased through path mapping.
    define(function() {
      return platform;
    });
  }
  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
  else if (freeExports && freeModule) {
    // Export for CommonJS support.
    forOwn(platform, function(value, key) {
      freeExports[key] = value;
    });
  }
  else {
    // Export to the global object.
    root.platform = platform;
  }
}.call(this));


function generateUUID(){
	var d = new Date().getTime();
	var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
		var r = (d + Math.random()*16)%16 | 0;
		d = Math.floor(d/16);
		return (c=='x' ? r : (r&0x7|0x8)).toString(16);
	});
	return uuid;
}
var uuidVal = null
var headers = null
var sessionId = null
var appStartTime = 0;
var ttl = 30 * 60 * 1000;
var now = new Date().getTime()
if (window.localStorage.getItem("bisonId") == null || window.localStorage.getItem("bisonIdTime") == null || Number(window.localStorage.getItem("bisonIdTime")) + ttl - now < 0) {
	uuidVal = generateUUID()
  appStartTime = Date.now();
  sessionId = 'SID_' + appStartTime + "_" + uuidVal.replace(/-/g, '');
	window.localStorage.setItem("bisonId", uuidVal);
  window.localStorage.setItem("bisonIdTime", appStartTime);
} else {
	uuidVal = window.localStorage.getItem("bisonId")
  appStartTime = window.localStorage.getItem("bisonIdTime")
  sessionId = 'SID_' + appStartTime  + "_" +  uuidVal.replace(/-/g, '');
}

// alert((Number(appStartTime) + Number(ttl) - Number(now))/ 60 / 1000)
headers = {
		"X-SessionId": sessionId.substr(0,36),
        "X-App-Start-Time": appStartTime,
        "X-App-Build": "latest",
        'X-Device-ID': uuidVal,
        "X-Device-Mode": platform.manufacturer + " " + platform.product,
        "X-OS": platform.os.toString(),
        "X-OS-Name": platform.os.family,
        "X-App": "BISON_landing_page",
};