define('domReady',[],function () {
    'use strict';

    var isTop, testDiv, scrollIntervalId,
        isBrowser = typeof window !== "undefined" && window.document,
        isPageLoaded = !isBrowser,
        doc = isBrowser ? document : null,
        readyCalls = [];

    function runCallbacks(callbacks) {
        var i;
        for (i = 0; i < callbacks.length; i += 1) {
            callbacks[i](doc);
        }
    }

    function callReady() {
        var callbacks = readyCalls;

        if (isPageLoaded) {
            //Call the DOM ready callbacks
            if (callbacks.length) {
                readyCalls = [];
                runCallbacks(callbacks);
            }
        }
    }

    /**
     * Sets the page as loaded.
     */
    function pageLoaded() {
        if (!isPageLoaded) {
            isPageLoaded = true;
            if (scrollIntervalId) {
                clearInterval(scrollIntervalId);
            }

            callReady();
        }
    }

    if (isBrowser) {
        if (document.addEventListener) {
            //Standards. Hooray! Assumption here that if standards based,
            //it knows about DOMContentLoaded.
            document.addEventListener("DOMContentLoaded", pageLoaded, false);
            window.addEventListener("load", pageLoaded, false);
        } else if (window.attachEvent) {
            window.attachEvent("onload", pageLoaded);

            testDiv = document.createElement('div');
            try {
                isTop = window.frameElement === null;
            } catch (e) {}

            //DOMContentLoaded approximation that uses a doScroll, as found by
            //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/,
            //but modified by other contributors, including jdalton
            if (testDiv.doScroll && isTop && window.external) {
                scrollIntervalId = setInterval(function () {
                    try {
                        testDiv.doScroll();
                        pageLoaded();
                    } catch (e) {}
                }, 30);
            }
        }

        //Check if document already complete, and if so, just trigger page load
        //listeners. Latest webkit browsers also use "interactive", and
        //will fire the onDOMContentLoaded before "interactive" but not after
        //entering "interactive" or "complete". More details:
        //http://dev.w3.org/html5/spec/the-end.html#the-end
        //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded
        //Hmm, this is more complicated on further use, see "firing too early"
        //bug: https://github.com/requirejs/domReady/issues/1
        //so removing the || document.readyState === "interactive" test.
        //There is still a window.onload binding that should get fired if
        //DOMContentLoaded is missed.
        if (document.readyState === "complete") {
            pageLoaded();
        }
    }

    /** START OF PUBLIC API **/

    /**
     * Registers a callback for DOM ready. If DOM is already ready, the
     * callback is called immediately.
     * @param {Function} callback
     */
    function domReady(callback) {
        if (isPageLoaded) {
            callback(doc);
        } else {
            readyCalls.push(callback);
        }
        return domReady;
    }

    domReady.version = '2.0.1';

    /**
     * Loader Plugin API method
     */
    domReady.load = function (name, req, onLoad, config) {
        if (config.isBuild) {
            onLoad(null);
        } else {
            domReady(onLoad);
        }
    };

    /** END OF PUBLIC API **/

    return domReady;
});

(function($){

// When called on a container with a selector, fetches the href with
// ajax into the container or with the data-pjax attribute on the link
// itself.
//
// Tries to make sure the back button and ctrl+click work the way
// you'd expect.
//
// Exported as $.fn.pjax
//
// Accepts a jQuery ajax options object that may include these
// pjax specific options:
//
//
// container - Where to stick the response body. Usually a String selector.
//             $(container).html(xhr.responseBody)
//             (default: current jquery context)
//      push - Whether to pushState the URL. Defaults to true (of course).
//   replace - Want to use replaceState instead? That's cool.
//
// For convenience the second parameter can be either the container or
// the options object.
//
// Returns the jQuery object
function fnPjax(selector, container, options) {
  var context = this
  return this.on('click.pjax', selector, function(event) {
    var opts = $.extend({}, optionsFor(container, options))
    if (!opts.container)
      opts.container = $(this).attr('data-pjax') || context
    handleClick(event, opts)
  })
}

// Public: pjax on click handler
//
// Exported as $.pjax.click.
//
// event   - "click" jQuery.Event
// options - pjax options
//
// Examples
//
//   $(document).on('click', 'a', $.pjax.click)
//   // is the same as
//   $(document).pjax('a')
//
//  $(document).on('click', 'a', function(event) {
//    var container = $(this).closest('[data-pjax-container]')
//    $.pjax.click(event, container)
//  })
//
// Returns nothing.
function handleClick(event, container, options) {
  options = optionsFor(container, options)

  var link = event.currentTarget

  if (link.tagName.toUpperCase() !== 'A')
    throw "$.fn.pjax or $.pjax.click requires an anchor element"

  // Middle click, cmd click, and ctrl click should open
  // links in a new tab as normal.
  if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
    return

  // Ignore cross origin links
  if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
    return

  // Ignore case when a hash is being tacked on the current URL
  if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
    return

  // Ignore event with default prevented
  if (event.isDefaultPrevented())
    return

  var defaults = {
    url: link.href,
    container: $(link).attr('data-pjax'),
    target: link
  }

  var opts = $.extend({}, defaults, options)
  var clickEvent = $.Event('pjax:click')
  $(link).trigger(clickEvent, [opts])

  if (!clickEvent.isDefaultPrevented()) {
    pjax(opts)
    event.preventDefault()
    $(link).trigger('pjax:clicked', [opts])
  }
}

// Public: pjax on form submit handler
//
// Exported as $.pjax.submit
//
// event   - "click" jQuery.Event
// options - pjax options
//
// Examples
//
//  $(document).on('submit', 'form', function(event) {
//    var container = $(this).closest('[data-pjax-container]')
//    $.pjax.submit(event, container)
//  })
//
// Returns nothing.
function handleSubmit(event, container, options) {
  options = optionsFor(container, options)

  var form = event.currentTarget
  var $form = $(form)

  if (form.tagName.toUpperCase() !== 'FORM')
    throw "$.pjax.submit requires a form element"

  var defaults = {
    type: ($form.attr('method') || 'GET').toUpperCase(),
    url: $form.attr('action'),
    container: $form.attr('data-pjax'),
    target: form
  }

  if (defaults.type !== 'GET' && window.FormData !== undefined) {
    defaults.data = new FormData(form);
    defaults.processData = false;
    defaults.contentType = false;
  } else {
    // Can't handle file uploads, exit
    if ($(form).find(':file').length) {
      return;
    }

    // Fallback to manually serializing the fields
    defaults.data = $(form).serializeArray();
  }

  pjax($.extend({}, defaults, options))

  event.preventDefault()
}

// Loads a URL with ajax, puts the response body inside a container,
// then pushState()'s the loaded URL.
//
// Works just like $.ajax in that it accepts a jQuery ajax
// settings object (with keys like url, type, data, etc).
//
// Accepts these extra keys:
//
// container - Where to stick the response body.
//             $(container).html(xhr.responseBody)
//      push - Whether to pushState the URL. Defaults to true (of course).
//   replace - Want to use replaceState instead? That's cool.
//
// Use it just like $.ajax:
//
//   var xhr = $.pjax({ url: this.href, container: '#main' })
//   console.log( xhr.readyState )
//
// Returns whatever $.ajax returns.
function pjax(options) {
  options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)

  if ($.isFunction(options.url)) {
    options.url = options.url()
  }

  var target = options.target

  var hash = parseURL(options.url).hash

  var context = options.context = findContainerFor(options.container)

  // We want the browser to maintain two separate internal caches: one
  // for pjax'd partial page loads and one for normal page loads.
  // Without adding this secret parameter, some browsers will often
  // confuse the two.
  if (!options.data) options.data = {}
  if ($.isArray(options.data)) {
    options.data.push({name: '_pjax', value: context.selector})
  } else {
    options.data._pjax = context.selector
  }

  function fire(type, args, props) {
    if (!props) props = {}
    props.relatedTarget = target
    var event = $.Event(type, props)
    context.trigger(event, args)
    return !event.isDefaultPrevented()
  }

  var timeoutTimer

  options.beforeSend = function(xhr, settings) {
    // No timeout for non-GET requests
    // Its not safe to request the resource again with a fallback method.
    if (settings.type !== 'GET') {
      settings.timeout = 0
    }

    xhr.setRequestHeader('X-PJAX', 'true')
    xhr.setRequestHeader('X-PJAX-Container', context.selector)

    if (!fire('pjax:beforeSend', [xhr, settings]))
      return false

    if (settings.timeout > 0) {
      timeoutTimer = setTimeout(function() {
        if (fire('pjax:timeout', [xhr, options]))
          xhr.abort('timeout')
      }, settings.timeout)

      // Clear timeout setting so jquerys internal timeout isn't invoked
      settings.timeout = 0
    }

    var url = parseURL(settings.url)
    if (hash) url.hash = hash
    options.requestUrl = stripInternalParams(url)
  }

  options.complete = function(xhr, textStatus) {
    if (timeoutTimer)
      clearTimeout(timeoutTimer)

    fire('pjax:complete', [xhr, textStatus, options])

    fire('pjax:end', [xhr, options])
  }

  options.error = function(xhr, textStatus, errorThrown) {
    var container = extractContainer("", xhr, options)

    var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
    if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
      locationReplace(container.url)
    }
  }

  options.success = function(data, status, xhr) {
    var previousState = pjax.state;

    // If $.pjax.defaults.version is a function, invoke it first.
    // Otherwise it can be a static string.
    var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
      $.pjax.defaults.version() :
      $.pjax.defaults.version

    var latestVersion = xhr.getResponseHeader('X-PJAX-Version')

    var container = extractContainer(data, xhr, options)

    var url = parseURL(container.url)
    if (hash) {
      url.hash = hash
      container.url = url.href
    }

    // If there is a layout version mismatch, hard load the new url
    if (currentVersion && latestVersion && currentVersion !== latestVersion) {
      locationReplace(container.url)
      return
    }

    // If the new response is missing a body, hard load the page
    if (!container.contents) {
      locationReplace(container.url)
      return
    }

    pjax.state = {
      id: options.id || uniqueId(),
      url: container.url,
      title: container.title,
      container: context.selector,
      fragment: options.fragment,
      timeout: options.timeout
    }

    if (options.push || options.replace) {
      window.history.replaceState(pjax.state, container.title, container.url)
    }

    // Only blur the focus if the focused element is within the container.
    var blurFocus = $.contains(options.container, document.activeElement)

    // Clear out any focused controls before inserting new page contents.
    if (blurFocus) {
      try {
        document.activeElement.blur()
      } catch (e) { }
    }

    if (container.title) document.title = container.title

    fire('pjax:beforeReplace', [container.contents, options], {
      state: pjax.state,
      previousState: previousState
    })
    context.html(container.contents)

    // FF bug: Won't autofocus fields that are inserted via JS.
    // This behavior is incorrect. So if theres no current focus, autofocus
    // the last field.
    //
    // http://www.w3.org/html/wg/drafts/html/master/forms.html
    var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
    if (autofocusEl && document.activeElement !== autofocusEl) {
      autofocusEl.focus();
    }

    executeScriptTags(container.scripts)

    var scrollTo = options.scrollTo

    // Ensure browser scrolls to the element referenced by the URL anchor
    if (hash) {
      var name = decodeURIComponent(hash.slice(1))
      var target = document.getElementById(name) || document.getElementsByName(name)[0]
      if (target) scrollTo = $(target).offset().top
    }

    if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)

    fire('pjax:success', [data, status, xhr, options])
  }


  // Initialize pjax.state for the initial page load. Assume we're
  // using the container and options of the link we're loading for the
  // back button to the initial page. This ensures good back button
  // behavior.
  if (!pjax.state) {
    pjax.state = {
      id: uniqueId(),
      url: window.location.href,
      title: document.title,
      container: context.selector,
      fragment: options.fragment,
      timeout: options.timeout
    }
    window.history.replaceState(pjax.state, document.title)
  }

  // Cancel the current request if we're already pjaxing
  abortXHR(pjax.xhr)

  pjax.options = options
  var xhr = pjax.xhr = $.ajax(options)

  if (xhr.readyState > 0) {
    if (options.push && !options.replace) {
      // Cache current container element before replacing it
      cachePush(pjax.state.id, cloneContents(context))

      window.history.pushState(null, "", options.requestUrl)
    }

    fire('pjax:start', [xhr, options])
    fire('pjax:send', [xhr, options])
  }

  return pjax.xhr
}

// Public: Reload current page with pjax.
//
// Returns whatever $.pjax returns.
function pjaxReload(container, options) {
  var defaults = {
    url: window.location.href,
    push: false,
    replace: true,
    scrollTo: false
  }

  return pjax($.extend(defaults, optionsFor(container, options)))
}

// Internal: Hard replace current state with url.
//
// Work for around WebKit
//   https://bugs.webkit.org/show_bug.cgi?id=93506
//
// Returns nothing.
function locationReplace(url) {
  window.history.replaceState(null, "", pjax.state.url)
  window.location.replace(url)
}


var initialPop = true
var initialURL = window.location.href
var initialState = window.history.state

// Initialize $.pjax.state if possible
// Happens when reloading a page and coming forward from a different
// session history.
if (initialState && initialState.container) {
  pjax.state = initialState
}

// Non-webkit browsers don't fire an initial popstate event
if ('state' in window.history) {
  initialPop = false
}

// popstate handler takes care of the back and forward buttons
//
// You probably shouldn't use pjax on pages with other pushState
// stuff yet.
function onPjaxPopstate(event) {

  // Hitting back or forward should override any pending PJAX request.
  if (!initialPop) {
    abortXHR(pjax.xhr)
  }

  var previousState = pjax.state
  var state = event.state
  var direction

  if (state && state.container) {
    // When coming forward from a separate history session, will get an
    // initial pop with a state we are already at. Skip reloading the current
    // page.
    if (initialPop && initialURL == state.url) return

    if (previousState) {
      // If popping back to the same state, just skip.
      // Could be clicking back from hashchange rather than a pushState.
      if (previousState.id === state.id) return

      // Since state IDs always increase, we can deduce the navigation direction
      direction = previousState.id < state.id ? 'forward' : 'back'
    }

    var cache = cacheMapping[state.id] || []
    var container = $(cache[0] || state.container), contents = cache[1]

    if (container.length) {
      if (previousState) {
        // Cache current container before replacement and inform the
        // cache which direction the history shifted.
        cachePop(direction, previousState.id, cloneContents(container))
      }

      var popstateEvent = $.Event('pjax:popstate', {
        state: state,
        direction: direction
      })
      container.trigger(popstateEvent)

      var options = {
        id: state.id,
        url: state.url,
        container: container,
        push: false,
        fragment: state.fragment,
        timeout: state.timeout,
        scrollTo: false
      }

      if (contents) {
        container.trigger('pjax:start', [null, options])

        pjax.state = state
        if (state.title) document.title = state.title
        var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
          state: state,
          previousState: previousState
        })
        container.trigger(beforeReplaceEvent, [contents, options])
        container.html(contents)

        container.trigger('pjax:end', [null, options])
      } else {
        pjax(options)
      }

      // Force reflow/relayout before the browser tries to restore the
      // scroll position.
      container[0].offsetHeight
    } else {
      locationReplace(location.href)
    }
  }
  initialPop = false
}

// Fallback version of main pjax function for browsers that don't
// support pushState.
//
// Returns nothing since it retriggers a hard form submission.
function fallbackPjax(options) {
  var url = $.isFunction(options.url) ? options.url() : options.url,
      method = options.type ? options.type.toUpperCase() : 'GET'

  var form = $('<form>', {
    method: method === 'GET' ? 'GET' : 'POST',
    action: url,
    style: 'display:none'
  })

  if (method !== 'GET' && method !== 'POST') {
    form.append($('<input>', {
      type: 'hidden',
      name: '_method',
      value: method.toLowerCase()
    }))
  }

  var data = options.data
  if (typeof data === 'string') {
    $.each(data.split('&'), function(index, value) {
      var pair = value.split('=')
      form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
    })
  } else if ($.isArray(data)) {
    $.each(data, function(index, value) {
      form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
    })
  } else if (typeof data === 'object') {
    var key
    for (key in data)
      form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
  }

  $(document.body).append(form)
  form.submit()
}

// Internal: Abort an XmlHttpRequest if it hasn't been completed,
// also removing its event handlers.
function abortXHR(xhr) {
  if ( xhr && xhr.readyState < 4) {
    xhr.onreadystatechange = $.noop
    xhr.abort()
  }
}

// Internal: Generate unique id for state object.
//
// Use a timestamp instead of a counter since ids should still be
// unique across page loads.
//
// Returns Number.
function uniqueId() {
  return (new Date).getTime()
}

function cloneContents(container) {
  var cloned = container.clone()
  // Unmark script tags as already being eval'd so they can get executed again
  // when restored from cache. HAXX: Uses jQuery internal method.
  cloned.find('script').each(function(){
    if (!this.src) jQuery._data(this, 'globalEval', false)
  })
  return [container.selector, cloned.contents()]
}

// Internal: Strip internal query params from parsed URL.
//
// Returns sanitized url.href String.
function stripInternalParams(url) {
  url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '')
  return url.href.replace(/\?($|#)/, '$1')
}

// Internal: Parse URL components and returns a Locationish object.
//
// url - String URL
//
// Returns HTMLAnchorElement that acts like Location.
function parseURL(url) {
  var a = document.createElement('a')
  a.href = url
  return a
}

// Internal: Return the `href` component of given URL object with the hash
// portion removed.
//
// location - Location or HTMLAnchorElement
//
// Returns String
function stripHash(location) {
  return location.href.replace(/#.*/, '')
}

// Internal: Build options Object for arguments.
//
// For convenience the first parameter can be either the container or
// the options object.
//
// Examples
//
//   optionsFor('#container')
//   // => {container: '#container'}
//
//   optionsFor('#container', {push: true})
//   // => {container: '#container', push: true}
//
//   optionsFor({container: '#container', push: true})
//   // => {container: '#container', push: true}
//
// Returns options Object.
function optionsFor(container, options) {
  // Both container and options
  if ( container && options )
    options.container = container

  // First argument is options Object
  else if ( $.isPlainObject(container) )
    options = container

  // Only container
  else
    options = {container: container}

  // Find and validate container
  if (options.container)
    options.container = findContainerFor(options.container)

  return options
}

// Internal: Find container element for a variety of inputs.
//
// Because we can't persist elements using the history API, we must be
// able to find a String selector that will consistently find the Element.
//
// container - A selector String, jQuery object, or DOM Element.
//
// Returns a jQuery object whose context is `document` and has a selector.
function findContainerFor(container) {
  container = $(container)

  if ( !container.length ) {
    throw "no pjax container for " + container.selector
  } else if ( container.selector !== '' && container.context === document ) {
    return container
  } else if ( container.attr('id') ) {
    return $('#' + container.attr('id'))
  } else {
    throw "cant get selector for pjax container!"
  }
}

// Internal: Filter and find all elements matching the selector.
//
// Where $.fn.find only matches descendants, findAll will test all the
// top level elements in the jQuery object as well.
//
// elems    - jQuery object of Elements
// selector - String selector to match
//
// Returns a jQuery object.
function findAll(elems, selector) {
  return elems.filter(selector).add(elems.find(selector));
}

function parseHTML(html) {
  return $.parseHTML(html, document, true)
}

// Internal: Extracts container and metadata from response.
//
// 1. Extracts X-PJAX-URL header if set
// 2. Extracts inline <title> tags
// 3. Builds response Element and extracts fragment if set
//
// data    - String response data
// xhr     - XHR response
// options - pjax options Object
//
// Returns an Object with url, title, and contents keys.
function extractContainer(data, xhr, options) {
  var obj = {}, fullDocument = /<html/i.test(data)

  // Prefer X-PJAX-URL header if it was set, otherwise fallback to
  // using the original requested url.
  var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
  obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl

  // Attempt to parse response html into elements
  if (fullDocument) {
    var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
    var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
  } else {
    var $head = $body = $(parseHTML(data))
  }

  // If response data is empty, return fast
  if ($body.length === 0)
    return obj

  // If there's a <title> tag in the header, use it as
  // the page's title.
  obj.title = findAll($head, 'title').last().text()

  if (options.fragment) {
    // If they specified a fragment, look for it in the response
    // and pull it out.
    if (options.fragment === 'body') {
      var $fragment = $body
    } else {
      var $fragment = findAll($body, options.fragment).first()
    }

    if ($fragment.length) {
      obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()

      // If there's no title, look for data-title and title attributes
      // on the fragment
      if (!obj.title)
        obj.title = $fragment.attr('title') || $fragment.data('title')
    }

  } else if (!fullDocument) {
    obj.contents = $body
  }

  // Clean up any <title> tags
  if (obj.contents) {
    // Remove any parent title elements
    obj.contents = obj.contents.not(function() { return $(this).is('title') })

    // Then scrub any titles from their descendants
    obj.contents.find('title').remove()

    // Gather all script[src] elements
    obj.scripts = findAll(obj.contents, 'script[src]').remove()
    obj.contents = obj.contents.not(obj.scripts)
  }

  // Trim any whitespace off the title
  if (obj.title) obj.title = $.trim(obj.title)

  return obj
}

// Load an execute scripts using standard script request.
//
// Avoids jQuery's traditional $.getScript which does a XHR request and
// globalEval.
//
// scripts - jQuery object of script Elements
//
// Returns nothing.
function executeScriptTags(scripts) {
  if (!scripts) return

  var existingScripts = $('script[src]')

  scripts.each(function() {
    var src = this.src
    var matchedScripts = existingScripts.filter(function() {
      return this.src === src
    })
    if (matchedScripts.length) return

    var script = document.createElement('script')
    var type = $(this).attr('type')
    if (type) script.type = type
    script.src = $(this).attr('src')
    document.head.appendChild(script)
  })
}

// Internal: History DOM caching class.
var cacheMapping      = {}
var cacheForwardStack = []
var cacheBackStack    = []

// Push previous state id and container contents into the history
// cache. Should be called in conjunction with `pushState` to save the
// previous container contents.
//
// id    - State ID Number
// value - DOM Element to cache
//
// Returns nothing.
function cachePush(id, value) {
  cacheMapping[id] = value
  cacheBackStack.push(id)

  // Remove all entries in forward history stack after pushing a new page.
  trimCacheStack(cacheForwardStack, 0)

  // Trim back history stack to max cache length.
  trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
}

// Shifts cache from directional history cache. Should be
// called on `popstate` with the previous state id and container
// contents.
//
// direction - "forward" or "back" String
// id        - State ID Number
// value     - DOM Element to cache
//
// Returns nothing.
function cachePop(direction, id, value) {
  var pushStack, popStack
  cacheMapping[id] = value

  if (direction === 'forward') {
    pushStack = cacheBackStack
    popStack  = cacheForwardStack
  } else {
    pushStack = cacheForwardStack
    popStack  = cacheBackStack
  }

  pushStack.push(id)
  if (id = popStack.pop())
    delete cacheMapping[id]

  // Trim whichever stack we just pushed to to max cache length.
  trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
}

// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
// longer than the specified length, deleting cached DOM elements as necessary.
//
// stack  - Array of state IDs
// length - Maximum length to trim to
//
// Returns nothing.
function trimCacheStack(stack, length) {
  while (stack.length > length)
    delete cacheMapping[stack.shift()]
}

// Public: Find version identifier for the initial page load.
//
// Returns String version or undefined.
function findVersion() {
  return $('meta').filter(function() {
    var name = $(this).attr('http-equiv')
    return name && name.toUpperCase() === 'X-PJAX-VERSION'
  }).attr('content')
}

// Install pjax functions on $.pjax to enable pushState behavior.
//
// Does nothing if already enabled.
//
// Examples
//
//     $.pjax.enable()
//
// Returns nothing.
function enable() {
  $.fn.pjax = fnPjax
  $.pjax = pjax
  $.pjax.enable = $.noop
  $.pjax.disable = disable
  $.pjax.click = handleClick
  $.pjax.submit = handleSubmit
  $.pjax.reload = pjaxReload
  $.pjax.defaults = {
    timeout: 650,
    push: true,
    replace: false,
    type: 'GET',
    dataType: 'html',
    scrollTo: 0,
    maxCacheLength: 20,
    version: findVersion
  }
  $(window).on('popstate.pjax', onPjaxPopstate)
}

// Disable pushState behavior.
//
// This is the case when a browser doesn't support pushState. It is
// sometimes useful to disable pushState for debugging on a modern
// browser.
//
// Examples
//
//     $.pjax.disable()
//
// Returns nothing.
function disable() {
  $.fn.pjax = function() { return this }
  $.pjax = fallbackPjax
  $.pjax.enable = enable
  $.pjax.disable = $.noop
  $.pjax.click = $.noop
  $.pjax.submit = $.noop
  $.pjax.reload = function() { window.location.reload() }

  $(window).off('popstate.pjax', onPjaxPopstate)
}


// Add the state property to jQuery's event object so we can use it in
// $(window).bind('popstate')
if ( $.inArray('state', $.event.props) < 0 )
  $.event.props.push('state')

// Is pjax supported by this browser?
$.support.pjax =
  window.history && window.history.pushState && window.history.replaceState &&
  // pushState isn't reliable on iOS until 5.
  !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)

$.support.pjax ? enable() : disable()

})(jQuery);

define("pjax", function(){});

(function(e) {
  var b = "1.4.10",
    f = {
      exclude: [],
      excludeWithin: [],
      offset: 0,
      onclass: "on",
      direction: "top",
      scrollElement: null,
      scrollTarget: null,
      beforeScroll: function() {},
      afterScroll: function() {},
      easing: "swing",
      speed: 400,
      autoCoefficent: 2
    },
    d = function(i) {
      var j = [],
        h = false,
        g = i.dir && i.dir == "left" ? "scrollLeft" : "scrollTop";
      this.each(function() {
        if (this == document || this == window) {
          return
        }
        var k = e(this);
        if (k[g]() > 0) {
          j.push(this)
        } else {
          k[g](1);
          h = k[g]() > 0;
          if (h) {
            j.push(this)
          }
          k[g](0)
        }
      });
      if (!j.length) {
        this.each(function(k) {
          if (this.nodeName === "BODY") {
            j = [this]
          }
        })
      }
      if (i.el === "first" && j.length > 1) {
        j = [j[0]]
      }
      return j
    },
    a = "ontouchend" in document;
  e.fn.extend({
    scrollable: function(g) {
      var h = d.call(this, {
        dir: g
      });
      return this.pushStack(h)
    },
    firstScrollable: function(g) {
      var h = d.call(this, {
        el: "first",
        dir: g
      });
      return this.pushStack(h)
    },
    smoothScroll: function(g) {
      g = g || {};
      var h = e.extend({}, e.fn.smoothScroll.defaults, g),
        i = e.smoothScroll.filterPath(location.pathname);
      this.unbind("click.smoothscroll").bind("click.smoothscroll", function(k) {
        var s = this,
          p = e(this),
          q = h.exclude,
          m = h.excludeWithin,
          u = 0,
          n = 0,
          j = true,
          t = {},
          l = ((location.hostname === s.hostname) || !s.hostname),
          r = h.scrollTarget || (e.smoothScroll.filterPath(s.pathname) || i) === i,
          o = c(s.hash);
        p.siblings("a").removeClass(h.onclass);
        p.addClass(h.onclass);
        if (!h.scrollTarget && (!l || !r || !o)) {
          j = false
        } else {
          while (j && u < q.length) {
            if (p.is(c(q[u++]))) {
              j = false
            }
          }
          while (j && n < m.length) {
            if (p.closest(m[n++]).length) {
              j = false
            }
          }
        }
        if (j) {
          k.preventDefault();
          e.extend(t, h, {
            scrollTarget: h.scrollTarget || o,
            link: s
          });
          e.smoothScroll(t)
        }
      });
      return this
    }
  });
  e.smoothScroll = function(n, q) {
    var g, l, p, j, r = 0,
      k = "offset",
      m = "scrollTop",
      o = {},
      h = {},
      i = [];
    if (typeof n === "number") {
      g = e.fn.smoothScroll.defaults;
      p = n
    } else {
      g = e.extend({}, e.fn.smoothScroll.defaults, n || {});
      if (g.scrollElement) {
        k = "position";
        if (g.scrollElement.css("position") == "static") {
          g.scrollElement.css("position", "relative")
        }
      }
    }
    g = e.extend({
      link: null
    }, g);
    m = g.direction == "left" ? "scrollLeft" : m;
    if (g.scrollElement) {
      l = g.scrollElement;
      r = l[m]()
    } else {
      l = e("html, body").firstScrollable()
    }
    g.beforeScroll.call(l, g);
    p = (typeof n === "number") ? n : q || (e(g.scrollTarget)[k]() && e(g.scrollTarget)[k]()[g.direction]) || 0;
    o[m] = p + r + g.offset;
    j = g.speed;
    if (j === "auto") {
      j = o[m] || l.scrollTop();
      j = j / g.autoCoefficent
    }
    h = {
      duration: j,
      easing: g.easing,
      complete: function() {
        g.afterScroll.call(g.link, g)
      }
    };
    if (g.step) {
      h.step = g.step
    }
    if (l.length) {
      l.stop().animate(o, h)
    } else {
      g.afterScroll.call(g.link, g)
    }
  };
  e.smoothScroll.version = b;
  e.smoothScroll.filterPath = function(g) {
    return g.replace(/^\//, "").replace(/(index|default).[a-zA-Z]{3,4}$/, "").replace(/\/$/, "")
  };
  e.fn.smoothScroll.defaults = f;

  function c(g) {
    return g.replace(/(:|\.)/g, "\\$1")
  }
})(jQuery);

define("smoothscroll", function(){});

define('alertinfo',[], function() {
  var initModule,alertinfo;
  /**
   * 弹窗
   * @param  {[type]} info [description]
   * @param  {[type]} aurl [description]
   * @return {[type]}      [description]
   */
  initModule = function(info, aurl) {
    $('.alert_player').fadeIn();
    $('.alert_player .info').html(info);
    if (aurl === undefined) {} else {
      $('.alert_player .queren_btn,.alert_player .bg').click(function() {
        location.href = aurl;
      })
    }
    $('.alert_player .bg,.alert_player .queren_btn').click(function() {
      $('.alert_player').fadeOut();
    });
  };

  return {
    initModule: initModule
  };
})
;
define('pajax',['pjax', 'smoothscroll','alertinfo'], function(pjax, smoothscroll,alertinfo) {
  var initModule, pageajax, targetelement;
  //console.log(alertinfo);
  /**
   * pajax 页面无刷新
   * @return {[type]} [description]
   */
  pageajax = function(article, start, callbak) {
    if ($.support.pjax) {
      $('body').stop().undelegate('a[data-ajax!=no]', 'click');
      $('body').stop().delegate('a[data-ajax!=no]', 'click', function(event) {
        event.preventDefault();
        var url = $(this).attr("href");
        var container = $(this).attr("data-container");
        var fragment = $(this).attr("data-fragment");
        var istop = $(this).attr('data-istop');
        targetelement = $(this).attr('data-target');
        if(!url){
          alertinfo.initModule('网站维护中...')
        }

        if (container) {
          container = '.' + container;
        } else {
          container = article;
        }
        if (fragment) {
          fragment = '.' + fragment;
        } else {
          fragment = article;
        }
        $('.pjaxcontainer').removeClass('pjaxcontainer');
        $(container).addClass('pjaxcontainer');
        $(container).stop().animate({
          opacity: "1"
        }, 0);
        setTimeout(function() {
          $.pjax({
            url: url,
            container: container,
            fragment: fragment,
            timeout: 8000,
            scrollTo: false
          });
          if (istop) {

          } else {
            if (targetelement && $('article').attr('data-main') == localStorage.mainaction) {

            } else {
              $('html,body').stop().animate({
                scrollTop: 0,
              }, 400);
            }

          }
        }, 0);
        return false;
      });
      $(document).on('pjax:send', function(event) { //pjax链接点击后显示加载动画
        $("#progress").removeClass("done"); //完成，隐藏进度条
        $({
          property: 0
        }).animate({
          property: 100
        }, {
          duration: 1000,
          step: function() {
            var percentage = Math.round(this.property);

            $('#progress').css('width', percentage + "%");

            if (percentage == 100) {
              $("#progress").addClass("done"); //完成，隐藏进度条
            }
          }
        });
      });

      //加载完成后替换title
      $(document).on('pjax:success', function(data, status, xhr, options) {
        $(window).unbind('scroll');
      });
      $(document).on('pjax:complete', function() {
        $("#progress").addClass("done"); //完成，隐藏进度条
      });
      $(document).on('pjax:end', function(data, status, xhr, options) {
        //console.log(data);
        $('title').text(data.currentTarget.title);
        $('.pjaxcontainer').stop().animate({
          opacity: "1"
        }, 300);
        //console.log(xhr.container);
        if (xhr.container != 'main') {
          callbak(targetelement, true);
        } else {
          callbak(targetelement, false);
        }


        //$('title').text(data.relatedTarget.innerText + ' - 润泰');
      });
      $(document).on('pjax:error', function() {
        console.log("加载失败!");
      });
      $(document).on('pjax:popstate', function(data, status, xhr, options) {});
    }
  };

  initModule = function(article, start, callbak) {
    pageajax(article, start, callbak);
  };
  return {
    initModule: initModule
  };
})
;
(function($) {

  var $event = $.event,
    $special,
    resizeTimeout;

  $special = $event.special.debouncedresize = {
    setup: function() {
      $(this).on("resize", $special.handler);
    },
    teardown: function() {
      $(this).off("resize", $special.handler);
    },
    handler: function(event, execAsap) {
      // Save the context
      var context = this,
        args = arguments,
        dispatch = function() {
          // set correct event type
          event.type = "debouncedresize";
          $event.dispatch.apply(context, args);
        };

      if (resizeTimeout) {
        clearTimeout(resizeTimeout);
      }

      execAsap ?
        dispatch() :
        resizeTimeout = setTimeout(dispatch, $special.threshold);
    },
    threshold: 150
  };

})(jQuery);

define("debouncedresize", function(){});

define('router',[], function () {
  var initModule, router, navactive, sub_nav, backtotop;

  /**
   * 回到顶部
   * @return {[type]} [description]
   */
  backtotop = function () {
    // console.log(1);
    var min_height = 500;
    $(window).scroll(function () {
      //获取窗口的滚动条的垂直位置
      var s = $(window).scrollTop();
      //当窗口的滚动条的垂直位置大于页面的最小高度时，让返回顶部元素渐现，否则渐隐
      if (s > min_height) {
        $(".backtotop").fadeIn(100);
      } else {
        $(".backtotop").fadeOut(200);
      };
    });
    $('.backtotop a.totop').on('click', function (event) {
      event.preventDefault();
      $('body,html').animate({
        scrollTop: 0,
      }, 700);
    });
  };
  /**
   * 导航选中状态
   * @param  {[type]} i [description]
   * @return {[type]}   [description]
   */
  navactive = function (i) {
    $('body').undelegate('nav>ul>li>a', 'click');
    $('body').delegate('nav>ul>li>a', 'click', function () {
      //$('nav>ul>li>ul').hide();
      var t = $(this);
      if (t.next('ul').length > 0) {
        if (t.next('ul').is(":hidden")) {
          $('nav>ul>li>ul').slideUp();
          $('nav>ul>li>a').removeClass('on');
          t.addClass('on')
          t.next('ul').slideDown();
        } else {
          $('nav>ul>li>a').removeClass('on');
          t.next('ul').slideUp();
        }
      }else{
        $('nav>ul>li>a').removeClass('on');
        $('nav>ul>li>ul').slideUp();
        $('#myInput').removeAttr("checked");
      }
    })
    $('body').undelegate('nav>ul>li>ul li a', 'click');
    $('body').delegate('nav>ul>li>ul li a', 'click', function () {
      $('nav>ul>li>a').removeClass('on');
      $('nav>ul>li>ul').slideUp();
      $('#myInput').removeAttr("checked");
    });
  };
  /**
   * 二级导航
   * @return {[type]} [description]
   */
  sub_nav = function (i) {

    $('body').undelegate('.er-bar .er-nav a', 'click');
    $('body').delegate('.er-bar .er-nav a', 'click', function () {
      $('.er-bar .er-nav ul').fadeToggle();
      //$('.position a').eq(2).html($(this).html());
      //$("html, body").animate({scrollTop: $(".er-bar-targat").offset().top }, {duration: 500,easing: "swing"});
    });
    $('body').undelegate('.er-bar .er-nav ul a', 'click');
    $('body').delegate('.er-bar .er-nav  ul a', 'click', function () {
      $('.er-bar .er-nav>a').html($(this).html());
      $('.er-bar .er-nav ul').hide();
      $("html, body").stop().animate({scrollTop: $(".er-bar-targat").offset().top }, {duration: 500,easing: "swing"});
    });
    if ($(".er-bar-targat").length > 0) {
      $(window).scroll(function () {
        var navH = $(".er-bar-targat").offset().top;
        //获取滚动条的滑动距离
        var scroH = $(this).scrollTop();
        //滚动条的滑动距离大于等于定位元素距离浏览器顶部的距离，就固定，反之就不固定
        //console.log(scroH+'/'+navH);
        if (scroH >= navH) {
          $(".er-bar").addClass('on');
        } else if (scroH < navH) {
          $(".er-bar").removeClass('on');
        }
      })
    }

  }
  /**
   * 路由设置
   * @return {[type]} [description]
   */
  router = function (article, state) {
    var action = $(article).attr('data-main');
    var eraction = $('.eraction').attr('data-fun');
    //console.log(action);
    //console.log(eraction);
    // 判断主action
    if (action) {
      //判断主二级action
      if (eraction) {
        //判断是否无刷新
        if (state && localStorage.mainaction && localStorage.mainaction == action) {
          //console.log(1)
          require(['./lib/' + action], function (action) {
            var str = "action." + eraction + "(function(a){})";
            eval(str);
            //console.log(str);
            sub_nav();
          });
        } else {
          localStorage.mainaction = action;
          //console.log(2)
          require(['./lib/' + action], function (action) {
            //console.log(action);
            action.initModule(function (a) {
              navactive(a);
              sub_nav();
            });
            var str = "action." + eraction + "(function(a){navactive(a);sub_nav();})"
            //console.log(str);
            eval(str);
          });
        }
      } else {
        localStorage.mainaction = action;
        //console.log(3)
        require(['./lib/' + action], function (action) {
          action.initModule(function (a) {
            navactive(a);
            sub_nav();
          });
        });
      }

    }
  };
  initModule = function (article, state) {

    router(article, state);

  };
  return {
    initModule: initModule
  };
});
define('scroll',[''], function() {
  var initModule, scroll,resetsize;

  /**
   * 滚动条
   * @return {[type]} [description]
   */
  scroll = function(article) {

    $(article).niceScroll({
      cursorcolor: "#4284e2",
      cursorwidth: "5px",


      cursorfixedheight: false,
      cursorminheight: 20,
      enablekeyboard: true,
      horizrailenabled: true,
      bouncescroll: false,
      smoothscroll: true,
      zindex: 999
    });

  };
  initModule = function(article) {
    scroll(article);

  };
  resetsize = function(article){
      $(article).getNiceScroll(0).resize();
  };
  return {
    initModule: initModule,
    resetsize: resetsize
  };
})
;
define('main',['pajax', 'debouncedresize', 'router', 'smoothscroll', 'scroll'], function (pajax, debouncedresize, router, smoothscroll, scroll) {
  var initModule, animated_contents, minheight, alertinfo, msg, exists;
  /**
   * 判断dom是否存在
   * @param  {[type]} selector [description]
   * @return {[type]}          [description]
   */
  exists = function (selector) {
    "use strict";
    return (jQuery(selector).length > 0);
  };

  /**
   * 动画设置
   * @return {[type]} [description]
   */
  animated_contents = function () {
    "use strict";
    if (exists('.animate-element')) {

      $(".animate-element:in-viewport").each(function (i) {

        var $this = $(this);
        if (!$this.hasClass('in-viewport')) {
          setTimeout(function () {
            $this.addClass('in-viewport');
          }, 100 * i);
        }
      });
    }
  }


  /**
   * 弹窗
   * @param  {[type]} info [description]
   * @param  {[type]} aurl [description]
   * @return {[type]}      [description]
   */
  alertinfo = function (info, aurl) {
    $('.alert_player').fadeIn();
    $('.alert_player .info').html(info);
    if (aurl === undefined) {} else {
      $('.alert_player .queren_btn,.alert_player .bg').click(function () {
        location.href = aurl;
      })
    }

  };


  minheight = function () {
    var hh = $('header').height();
    var fh = $('footer').height();
    var mh = $(window).height() - fh;
    $('article').css('min-height', mh + 'px');
  }

  msg = function () {
    $('body').undelegate('.msg a', 'click');
    $('body').delegate('.msg a', 'click', function (event) {
      var name = $('#name').val();
      var tel = $('#tel').val();
      var email = $('#email').val();
      var msg = $('#msg').val();
      var url = $('.msg').attr('data-url');
      if (!name) {
        //用户名不能为空
        alertinfo('Имя пользователя  не может быть пустым！');
      }
      if (!tel) {
        //电话号码不能为空
        alertinfo('номер телефона  не может быть пустым ！');
      }
      if (!email) {
        //邮箱不能为空
        alertinfo('почтовый ящик  не может быть пустым！');
      }
      if (!msg) {
        //内容不能为空
        alertinfo('содержание  не может быть пустым ！');
      }
      arrData = {
        'name': name,
        'tel': tel,
        'email': email,
        'msg': msg
      };
      $.post(url, arrData,
        function (data) {
          if ('118' == data.err_code) {
            alertinfo(data.err_info);
          } else {
            alertinfo(data.err_info);
          }
        }, "json"
      );

    });
  }

  initModule = function () {
    //必须加载模块
    router.initModule('article', false);
    var $ww = $(window).width();
    //scroll.initModule('body');
    msg();
    //parallaxan();
    require(["viewport"], function (viewport) {
      animated_contents();
      $(window).scroll(function (event) {
        /* Act on the event */
        animated_contents();
      });
    });

    $(window).on('debouncedresize', function () {

    });

    pajax.initModule('main', function () {}, function (targetelement, state) {
      router.initModule('article', state);
      msg();
      //scroll.resetsize('body');
      require(["viewport"], function (viewport) {
        animated_contents();
        $(window).scroll(function (event) {
          /* Act on the event */
          animated_contents();
        });
      });
      if (targetelement) {
        //console.log(targetelement);
        setTimeout(function () {
          //console.log($('#' + targetelement).offset().top);
          $.smoothScroll({
            offset: -($('header').height()),
            speed: 500,
            scrollTarget: '#' + targetelement
          });
        }, 500);
      }
    });

    $('.alert_player .bg,.alert_player .queren_btn').click(function () {
      $('.alert_player').fadeOut();
    });
  };

  return {
    initModule: initModule,
    alertinfo: alertinfo
  };
});
require.config({
  urlArgs: "bust=" + (new Date()).getTime(),

  shim: {
    'pajax': ['pjax'],
    //'laydate': ['laydate'],
    //'progress': ['swiper'],
    'BMap': {
      exports: 'BMap'
    },
    'idcode': ['css!./package/idcode/jquery.idcode.css'],
    'litebox': ['css!./package/litebox/css/litebox.css','imagesloaded'],
  },
  paths: {
    domReady: './domReady',
    main: './lib/main',
    pjax: './package/pajax/jquery.pjax',
    pajax: './package/pajax/pajax',
    router: './package/router/router',
    viewport: './package/viewport/jquery.viewport',
    alertinfo: './package/alertinfo/alertinfo',
    css: './package/css/css',
    async: './package/async/async',
    debug: './package/debug/debug',
    smoothscroll: './package/scroll/jquery.smooth-scroll.min',
    scroll: './package/scroll/scroll',
    aspectratio_responsive: './package/media/aspectratio_responsive',
    swiper: './package/swiper/v3/swiper.min',
    debouncedresize: './package/compat/jquery.debouncedresize',
    //  progress:'./package/swiper/v2/idangerous.swiper.progress',
    masonry: './package/pubu/masonry.pkgd.min',
    form: './package/form/form',
    imagesloaded: './package/litebox/js/images-loaded.min',
    litebox: './package/litebox/js/litebox.min',
    idcode: './package/idcode/jquery.idcode',
    loadmore: './package/loadmore/loadmore',
    'BMap': ['http://api.map.baidu.com/api?key=&v=1.1&services=true'],
  }
});
require(["domReady", 'main'], function (domReady, main) {
  domReady(function () {
    main.initModule();
  });
});
define("me", function(){});

