var $body = document.body;
var $toggle = document.querySelector(".navbar-toggle");
var $navbar = document.querySelector("#Quanyinblog_navbar");
var $collapse = document.querySelector(".navbar-collapse");
var __QuanyinNav__ = {
    close: function close() {
        $navbar.className = " ";

        setTimeout(function () {

            if ($navbar.className.indexOf("in") < 0) {
                $collapse.style.height = "0px";
            }
        }, 400);
    },
    open: function open() {
        $collapse.style.height = "auto";
        $navbar.className += " in";
    }
};

$toggle.addEventListener("click", function (e) {
    if ($navbar.className.indexOf("in") > 0) {
        __QuanyinNav__.close();
    } else {
        __QuanyinNav__.open();
    }
});

document.addEventListener("click", function (e) {
    if (e.target == $toggle) return;
    if (e.target.className == "icon-bar") return;
    __QuanyinNav__.close();
});
/**
 * SnackBar.js
 *
 * This small component is borrowed from
 * https://codepen.io/wibblymat/pen/avAjq
 */

var createSnackbar = function () {
  // Any snackbar that is already shown
  var previous = null;

  /*
  <div class="paper-snackbar">
    <button class="action">Dismiss</button>
    This is a longer message that won't fit on one line. It is, inevitably, quite a boring thing. Hopefully it is still useful.
  </div>
  */

  return function (config) {
    var message = config.message,
        actionText = config.actionText,
        action = config.action,
        duration = config.duration;

    if (previous) {
      previous.dismiss();
    }
    var snackbar = document.createElement('div');
    snackbar.className = 'paper-snackbar';
    snackbar.dismiss = function () {
      this.style.opacity = 0;
    };
    var text = document.createTextNode(message);
    snackbar.appendChild(text);
    if (actionText) {
      if (!action) {
        action = snackbar.dismiss.bind(snackbar);
      }
      var actionButton = document.createElement('button');
      actionButton.className = 'action';
      actionButton.innerHTML = actionText;
      actionButton.addEventListener('click', action);
      snackbar.appendChild(actionButton);
    }
    setTimeout(function () {
      if (previous === this) {
        previous.dismiss();
      }
    }.bind(snackbar), duration || 5000);

    snackbar.addEventListener('transitionend', function (event, elapsed) {
      if (event.propertyName === 'opacity' && this.style.opacity == 0) {
        this.parentElement.removeChild(this);
        if (previous === this) {
          previous = null;
        }
      }
    }.bind(snackbar));

    previous = snackbar;
    document.body.appendChild(snackbar);
    // In order for the animations to trigger, I have to force the original style to be computed, and then change it.
    getComputedStyle(snackbar).bottom;
    snackbar.style.bottom = '0px';
    snackbar.style.opacity = 1;
  };
}();
/* ===========================================================
 * sw-registration.js
 * ===========================================================
 * Copyright 2017 @Quanyin
 * Licensed under Apache 2.0
 * Register service worker.
 * ========================================================== */

/* SW Version Upgrade Ref: <https://youtu.be/Gb9uI67tqV0> */

function handleRegistration(registration) {
  console.log('Service Worker Registered. ', registration);
  /**
   * ServiceWorkerRegistration.onupdatefound
   * The service worker registration's installing worker changes.
   */
  registration.onupdatefound = function (e) {
    var installingWorker = registration.installing;
    installingWorker.onstatechange = function (e) {
      if (installingWorker.state !== 'installed') return;
      if (navigator.serviceWorker.controller) {
        console.log('SW is updated');
      } else {
        console.log('A Visit without previous SW');
        createSnackbar({
          message: 'App ready for offline use.',
          duration: 3000
        });
      }
    };
  };
}

if (navigator.serviceWorker) {
  /*  For security reasons, a service worker can only control the pages */
  /* that are in the same directory level or below it. That's why we put sw.js at ROOT level. */
  navigator.serviceWorker.register('/sw.min.js').then(function (registration) {
    return handleRegistration(registration);
  }).catch(function (error) {
    console.log('ServiceWorker registration failed: ', error);
  });

  /* register message receiver */
  /*  https://dbwriteups.wordpress.com/2015/11/16/service-workers-part-3-communication-between-sw-and-pages/ */
  navigator.serviceWorker.onmessage = function (e) {
    console.log('SW: SW Broadcasting:', event);
    var data = e.data;

    if (data.command == "UPDATE_FOUND") {
      console.log("UPDATE_FOUND_BY_SW", data);
      createSnackbar({
        message: "Content updated.",
        actionText: "refresh",
        action: function action(e) {
          location.reload();
        }
      });
    }
  };
}
var bszCaller, bszTag;!function () {
  var c,
      d,
      _e,
      a = !1,
      b = [];ready = function ready(c) {
    return a || "interactive" === document.readyState || "complete" === document.readyState ? c.call(document) : b.push(function () {
      return c.call(this);
    }), this;
  }, d = function d() {
    for (var a = 0, c = b.length; c > a; a++) {
      b[a].apply(document);
    }b = [];
  }, _e = function e() {
    a || (a = !0, d.call(window), document.removeEventListener ? document.removeEventListener("DOMContentLoaded", _e, !1) : document.attachEvent && (document.detachEvent("onreadystatechange", _e), window == window.top && (clearInterval(c), c = null)));
  }, document.addEventListener ? document.addEventListener("DOMContentLoaded", _e, !1) : document.attachEvent && (document.attachEvent("onreadystatechange", function () {
    /loaded|complete/.test(document.readyState) && _e();
  }), window == window.top && (c = setInterval(function () {
    try {
      a || document.documentElement.doScroll("left");
    } catch (b) {
      return;
    }_e();
  }, 5)));
}(), bszCaller = { fetch: function fetch(a, b) {
    var c = "BusuanziCallback_" + Math.floor(1099511627776 * Math.random());window[c] = this.evalCall(b), a = a.replace("=BusuanziCallback", "=" + c), scriptTag = document.createElement("SCRIPT"), scriptTag.type = "text/javascript", scriptTag.defer = !0, scriptTag.src = a, document.getElementsByTagName("HEAD")[0].appendChild(scriptTag);
  }, evalCall: function evalCall(a) {
    return function (b) {
      ready(function () {
        try {
          a(b), scriptTag.parentElement.removeChild(scriptTag);
        } catch (c) {
          bszTag.hides();
        }
      });
    };
  } }, bszCaller.fetch("//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback", function (a) {
  bszTag.texts(a), bszTag.shows();
}), bszTag = { bszs: ["site_pv", "page_pv", "site_uv"], texts: function texts(a) {
    this.bszs.map(function (b) {
      var c = document.getElementById("busuanzi_value_" + b);c && (c.innerHTML = a[b]);
    });
  }, hides: function hides() {
    this.bszs.map(function (a) {
      var b = document.getElementById("busuanzi_container_" + a);b && (b.style.display = "none");
    });
  }, shows: function shows() {
    this.bszs.map(function (a) {
      var b = document.getElementById("busuanzi_container_" + a);b && (b.style.display = "inline");
    });
  } };
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
/* This file is meant as a standalone workflow for
- testing support for link[rel=preload]
- enabling async CSS loading in browsers that do not support rel=preload
- applying rel preload css once loaded, whether supported or not.
*/
(function( w ){
    "use strict";
    // rel=preload support test
    if( !w.loadCSS ){
        w.loadCSS = function(){};
    }
    // define on the loadCSS obj
    var rp = loadCSS.relpreload = {};
    // rel=preload feature support test
    // runs once and returns a function for compat purposes
    rp.support = (function(){
        var ret;
        try {
            ret = w.document.createElement( "link" ).relList.supports( "preload" );
        } catch (e) {
            ret = false;
        }
        return function(){
            return ret;
        };
    })();

    // if preload isn't supported, get an asynchronous load by using a non-matching media attribute
    // then change that media back to its intended value on load
    rp.bindMediaToggle = function( link ){
        // remember existing media attr for ultimate state, or default to 'all'
        var finalMedia = link.media || "all";

        function enableStylesheet(){
            link.media = finalMedia;
        }

        // bind load handlers to enable media
        if( link.addEventListener ){
            link.addEventListener( "load", enableStylesheet );
        } else if( link.attachEvent ){
            link.attachEvent( "onload", enableStylesheet );
        }

        // Set rel and non-applicable media type to start an async request
        // note: timeout allows this to happen async to let rendering continue in IE
        setTimeout(function(){
            link.rel = "stylesheet";
            link.media = "only x";
        });
        // also enable media after 3 seconds,
        // which will catch very old browsers (android 2.x, old firefox) that don't support onload on link
        setTimeout( enableStylesheet, 3000 );
    };

    // loop through link elements in DOM
    rp.poly = function(){
        // double check this to prevent external calls from running
        if( rp.support() ){
            return;
        }
        var links = w.document.getElementsByTagName( "link" );
        for( var i = 0; i < links.length; i++ ){
            var link = links[ i ];
            // qualify links to those with rel=preload and as=style attrs
            if( link.rel === "preload" && link.getAttribute( "as" ) === "style" && !link.getAttribute( "data-loadcss" ) ){
                // prevent rerunning on link
                link.setAttribute( "data-loadcss", true );
                // bind listeners to toggle media back
                rp.bindMediaToggle( link );
            }
        }
    };

    // if unsupported, run the polyfill
    if( !rp.support() ){
        // run once at least
        rp.poly();

        // rerun poly on an interval until onload
        var run = w.setInterval( rp.poly, 500 );
        if( w.addEventListener ){
            w.addEventListener( "load", function(){
                rp.poly();
                w.clearInterval( run );
            } );
        } else if( w.attachEvent ){
            w.attachEvent( "onload", function(){
                rp.poly();
                w.clearInterval( run );
            } );
        }
    }


    // commonjs
    if( typeof exports !== "undefined" ){
        exports.loadCSS = loadCSS;
    }
    else {
        w.loadCSS = loadCSS;
    }
}( typeof global !== "undefined" ? global : this ) );
window.onscroll = function () {
    var goTop = document.getElementsByClassName("back2top");
    if (goTop.length > 0) {
        goTop[0].style.display = document.documentElement.scrollTop >= 300 || document.body.scrollTop >= 300 ? 'block' : 'none';
        goTop[0].onclick = function () {
            document.body.scrollTop = 0;
            document.documentElement.scrollTop = 0;
        };
    }
};