diff --git a/framework/assets/pjax/jquery.pjax.js b/framework/assets/pjax/jquery.pjax.js
index 9b11ce4..1934d80 100644
--- a/framework/assets/pjax/jquery.pjax.js
+++ b/framework/assets/pjax/jquery.pjax.js
@@ -27,15 +27,15 @@
 // 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)
-  })
-}
+	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
 //
@@ -56,47 +56,48 @@ function fnPjax(selector, container, options) {
 //  })
 //
 // Returns nothing.
-function handleClick(event, container, options) {
-  options = optionsFor(container, options)
+	function handleClick(event, container, options) {
+		options = optionsFor(container, options)
 
-  var link = event.currentTarget
+		var link = event.currentTarget
 
-  if (link.tagName.toUpperCase() !== 'A')
-    throw "$.fn.pjax or $.pjax.click requires an anchor element"
+		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
+		// 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 cross origin links
+		if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
+			return
 
-  // Ignore anchors on the same page
-  if (link.hash && link.href.replace(link.hash, '') ===
-       location.href.replace(location.hash, ''))
-    return
+		// Ignore anchors on the same page
+		if (link.hash && link.href.replace(link.hash, '') ===
+			location.href.replace(location.hash, ''))
+			return
 
-  // Ignore empty anchor "foo.html#"
-  if (link.href === location.href + '#')
-    return
+		// Ignore empty anchor "foo.html#"
+		if (link.href === location.href + '#')
+			return
 
-  var defaults = {
-    url: link.href,
-    container: $(link).attr('data-pjax'),
-    target: link
-  }
+		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])
+		var opts = $.extend({}, defaults, options)
+		var clickEvent = $.Event('pjax:click')
+		$(link).trigger(clickEvent, [opts])
 
-  if (!clickEvent.isDefaultPrevented()) {
-    pjax(opts)
-    event.preventDefault()
-  }
-}
+		if (!clickEvent.isDefaultPrevented()) {
+			pjax(opts)
+			event.preventDefault()
+			$(link).trigger('pjax:clicked', [opts])
+		}
+	}
 
 // Public: pjax on form submit handler
 //
@@ -113,26 +114,26 @@ function handleClick(event, container, options) {
 //  })
 //
 // Returns nothing.
-function handleSubmit(event, container, options) {
-  options = optionsFor(container, options)
+	function handleSubmit(event, container, options) {
+		options = optionsFor(container, options)
 
-  var form = event.currentTarget
+		var form = event.currentTarget
 
-  if (form.tagName.toUpperCase() !== 'FORM')
-    throw "$.pjax.submit requires a form element"
+		if (form.tagName.toUpperCase() !== 'FORM')
+			throw "$.pjax.submit requires a form element"
 
-  var defaults = {
-    type: form.method.toUpperCase(),
-    url: form.action,
-    data: $(form).serializeArray(),
-    container: $(form).attr('data-pjax'),
-    target: form
-  }
+		var defaults = {
+			type: form.method.toUpperCase(),
+			url: form.action,
+			data: $(form).serializeArray(),
+			container: $(form).attr('data-pjax'),
+			target: form
+		}
 
-  pjax($.extend({}, defaults, options))
+		pjax($.extend({}, defaults, options))
 
-  event.preventDefault()
-}
+		event.preventDefault()
+	}
 
 // Loads a URL with ajax, puts the response body inside a container,
 // then pushState()'s the loaded URL.
@@ -153,212 +154,212 @@ function handleSubmit(event, container, options) {
 //   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
+	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 = {}
-  options.data._pjax = context.selector
-
-  function fire(type, args) {
-    var event = $.Event(type, { relatedTarget: target })
-    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
-    }
-
-    options.requestUrl = parseURL(settings.url).href
-  }
-
-  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) {
-    // 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)
-
-    // 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)
-    }
-
-    // Clear out any focused controls before inserting new page contents.
-    document.activeElement.blur()
-
-    if (container.title) document.title = container.title
-    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)
-
-    // Scroll to top by default
-    if (typeof options.scrollTo === 'number')
-      $(window).scrollTop(options.scrollTo)
-
-    // If the URL has a hash in it, make sure the browser
-    // knows to navigate to the hash.
-    if ( hash !== '' ) {
-      // Avoid using simple hash set here. Will add another history
-      // entry. Replace the url with replaceState and scroll to target
-      // by hand.
-      //
-      //   window.location.hash = hash
-      var url = parseURL(container.url)
-      url.hash = hash
-
-      pjax.state.url = url.href
-      window.history.replaceState(pjax.state, container.title, url.href)
-
-      var target = $(url.hash)
-      if (target.length) $(window).scrollTop(target.offset().top)
-    }
-
-    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
-  var xhr = pjax.xhr
-  if ( xhr && xhr.readyState < 4) {
-    xhr.onreadystatechange = $.noop
-    xhr.abort()
-  }
-
-  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, context.clone().contents())
-
-      window.history.pushState(null, "", stripPjaxParam(options.requestUrl))
-    }
-
-    fire('pjax:start', [xhr, options])
-    fire('pjax:send', [xhr, options])
-  }
-
-  return pjax.xhr
-}
+		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 = {}
+		options.data._pjax = context.selector
+
+		function fire(type, args) {
+			var event = $.Event(type, { relatedTarget: target })
+			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
+			}
+
+			options.requestUrl = parseURL(settings.url).href
+		}
+
+		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) {
+			// 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)
+
+			// 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)
+			}
+
+			// Clear out any focused controls before inserting new page contents.
+			document.activeElement.blur()
+
+			if (container.title) document.title = container.title
+			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)
+
+			// Scroll to top by default
+			if (typeof options.scrollTo === 'number')
+				$(window).scrollTop(options.scrollTo)
+
+			// If the URL has a hash in it, make sure the browser
+			// knows to navigate to the hash.
+			if ( hash !== '' ) {
+				// Avoid using simple hash set here. Will add another history
+				// entry. Replace the url with replaceState and scroll to target
+				// by hand.
+				//
+				//   window.location.hash = hash
+				var url = parseURL(container.url)
+				url.hash = hash
+
+				pjax.state.url = url.href
+				window.history.replaceState(pjax.state, container.title, url.href)
+
+				var target = $(url.hash)
+				if (target.length) $(window).scrollTop(target.offset().top)
+			}
+
+			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
+		var xhr = pjax.xhr
+		if ( xhr && xhr.readyState < 4) {
+			xhr.onreadystatechange = $.noop
+			xhr.abort()
+		}
+
+		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, context.clone().contents())
+
+				window.history.pushState(null, "", stripPjaxParam(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
-  }
+	function pjaxReload(container, options) {
+		var defaults = {
+			url: window.location.href,
+			push: false,
+			replace: true,
+			scrollTo: false
+		}
 
-  return pjax($.extend(defaults, optionsFor(container, options)))
-}
+		return pjax($.extend(defaults, optionsFor(container, options)))
+	}
 
 // Internal: Hard replace current state with url.
 //
@@ -366,133 +367,133 @@ function pjaxReload(container, options) {
 //   https://bugs.webkit.org/show_bug.cgi?id=93506
 //
 // Returns nothing.
-function locationReplace(url) {
-  window.history.replaceState(null, "", "#")
-  window.location.replace(url)
-}
+	function locationReplace(url) {
+		window.history.replaceState(null, "", "#")
+		window.location.replace(url)
+	}
 
 
-var initialPop = true
-var initialURL = window.location.href
-var initialState = window.history.state
+	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
-}
+	if (initialState && initialState.container) {
+		pjax.state = initialState
+	}
 
 // Non-webkit browsers don't fire an initial popstate event
-if ('state' in window.history) {
-  initialPop = false
-}
+	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) {
-  var state = event.state
-
-  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 popping back to the same state, just skip.
-    // Could be clicking back from hashchange rather than a pushState.
-    if (pjax.state.id === state.id) return
-
-    var container = $(state.container)
-    if (container.length) {
-      var direction, contents = cacheMapping[state.id]
-
-      if (pjax.state) {
-        // Since state ids always increase, we can deduce the history
-        // direction from the previous state.
-        direction = pjax.state.id < state.id ? 'forward' : 'back'
-
-        // Cache current container before replacement and inform the
-        // cache which direction the history shifted.
-        cachePop(direction, pjax.state.id, container.clone().contents())
-      }
-
-      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])
-
-        if (state.title) document.title = state.title
-        container.html(contents)
-        pjax.state = state
-
-        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
-}
+	function onPjaxPopstate(event) {
+		var state = event.state
+
+		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 popping back to the same state, just skip.
+			// Could be clicking back from hashchange rather than a pushState.
+			if (pjax.state.id === state.id) return
+
+			var container = $(state.container)
+			if (container.length) {
+				var direction, contents = cacheMapping[state.id]
+
+				if (pjax.state) {
+					// Since state ids always increase, we can deduce the history
+					// direction from the previous state.
+					direction = pjax.state.id < state.id ? 'forward' : 'back'
+
+					// Cache current container before replacement and inform the
+					// cache which direction the history shifted.
+					cachePop(direction, pjax.state.id, container.clone().contents())
+				}
+
+				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])
+
+					if (state.title) document.title = state.title
+					container.html(contents)
+					pjax.state = state
+
+					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 (typeof data === 'object') {
-    for (key in data)
-      form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
-  }
-
-  $(document.body).append(form)
-  form.submit()
-}
+	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 (typeof data === 'object') {
+			for (key in data)
+				form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
+		}
+
+		$(document.body).append(form)
+		form.submit()
+	}
 
 // Internal: Generate unique id for state object.
 //
@@ -500,32 +501,32 @@ function fallbackPjax(options) {
 // unique across page loads.
 //
 // Returns Number.
-function uniqueId() {
-  return (new Date).getTime()
-}
+	function uniqueId() {
+		return (new Date).getTime()
+	}
 
 // Internal: Strips _pjax param from url
 //
 // url - String
 //
 // Returns String.
-function stripPjaxParam(url) {
-  return url
-    .replace(/\?_pjax=[^&]+&?/, '?')
-    .replace(/_pjax=[^&]+&?/, '')
-    .replace(/[\?&]$/, '')
-}
+	function stripPjaxParam(url) {
+		return url
+			.replace(/\?_pjax=[^&]+&?/, '?')
+			.replace(/_pjax=[^&]+&?/, '')
+			.replace(/[\?&]$/, '')
+	}
 
 // 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
-}
+	function parseURL(url) {
+		var a = document.createElement('a')
+		a.href = url
+		return a
+	}
 
 // Internal: Build options Object for arguments.
 //
@@ -544,25 +545,25 @@ function parseURL(url) {
 //   // => {container: '#container', push: true}
 //
 // Returns options Object.
-function optionsFor(container, options) {
-  // Both container and options
-  if ( container && options )
-    options.container = container
+	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
+		// First argument is options Object
+		else if ( $.isPlainObject(container) )
+			options = container
 
-  // Only container
-  else
-    options = {container: container}
+		// Only container
+		else
+			options = {container: container}
 
-  // Find and validate container
-  if (options.container)
-    options.container = findContainerFor(options.container)
+		// Find and validate container
+		if (options.container)
+			options.container = findContainerFor(options.container)
 
-  return options
-}
+		return options
+	}
 
 // Internal: Find container element for a variety of inputs.
 //
@@ -572,19 +573,19 @@ function optionsFor(container, options) {
 // 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!"
-  }
-}
+	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.
 //
@@ -595,13 +596,13 @@ function findContainerFor(container) {
 // selector - String selector to match
 //
 // Returns a jQuery object.
-function findAll(elems, selector) {
-  return elems.filter(selector).add(elems.find(selector));
-}
+	function findAll(elems, selector) {
+		return elems.filter(selector).add(elems.find(selector));
+	}
 
-function parseHTML(html) {
-  return $.parseHTML(html, document, true)
-}
+	function parseHTML(html) {
+		return $.parseHTML(html, document, true)
+	}
 
 // Internal: Extracts container and metadata from response.
 //
@@ -614,69 +615,69 @@ function parseHTML(html) {
 // options - pjax options Object
 //
 // Returns an Object with url, title, and contents keys.
-function extractContainer(data, xhr, options) {
-  var obj = {}
-
-  // Prefer X-PJAX-URL header if it was set, otherwise fallback to
-  // using the original requested url.
-  obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl)
-
-  // Attempt to parse response html into elements
-  if (/<html/i.test(data)) {
-    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 = $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 (!/<html/i.test(data)) {
-    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
-}
+	function extractContainer(data, xhr, options) {
+		var obj = {}
+
+		// Prefer X-PJAX-URL header if it was set, otherwise fallback to
+		// using the original requested url.
+		obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl)
+
+		// Attempt to parse response html into elements
+		if (/<html/i.test(data)) {
+			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 = $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 (!/<html/i.test(data)) {
+			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.
 //
@@ -686,29 +687,29 @@ function extractContainer(data, xhr, options) {
 // scripts - jQuery object of script Elements
 //
 // Returns nothing.
-function executeScriptTags(scripts) {
-  if (!scripts) return
+	function executeScriptTags(scripts) {
+		if (!scripts) return
 
-  var existingScripts = $('script[src]')
+		var existingScripts = $('script[src]')
 
-  scripts.each(function() {
-    var src = this.src
-    var matchedScripts = existingScripts.filter(function() {
-      return this.src === src
-    })
-    if (matchedScripts.length) return
+		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')
-    script.type = $(this).attr('type')
-    script.src = $(this).attr('src')
-    document.head.appendChild(script)
-  })
-}
+			var script = document.createElement('script')
+			script.type = $(this).attr('type')
+			script.src = $(this).attr('src')
+			document.head.appendChild(script)
+		})
+	}
 
 // Internal: History DOM caching class.
-var cacheMapping      = {}
-var cacheForwardStack = []
-var cacheBackStack    = []
+	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
@@ -718,19 +719,19 @@ var cacheBackStack    = []
 // value - DOM Element to cache
 //
 // Returns nothing.
-function cachePush(id, value) {
-  cacheMapping[id] = value
-  cacheBackStack.push(id)
+	function cachePush(id, value) {
+		cacheMapping[id] = value
+		cacheBackStack.push(id)
 
-  // Remove all entires in forward history stack after pushing
-  // a new page.
-  while (cacheForwardStack.length)
-    delete cacheMapping[cacheForwardStack.shift()]
+		// Remove all entires in forward history stack after pushing
+		// a new page.
+		while (cacheForwardStack.length)
+			delete cacheMapping[cacheForwardStack.shift()]
 
-  // Trim back history stack to max cache length.
-  while (cacheBackStack.length > pjax.defaults.maxCacheLength)
-    delete cacheMapping[cacheBackStack.shift()]
-}
+		// Trim back history stack to max cache length.
+		while (cacheBackStack.length > pjax.defaults.maxCacheLength)
+			delete cacheMapping[cacheBackStack.shift()]
+	}
 
 // Shifts cache from directional history cache. Should be
 // called on `popstate` with the previous state id and container
@@ -741,32 +742,32 @@ function cachePush(id, value) {
 // 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]
-}
+	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]
+	}
 
 // 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')
-}
+	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.
 //
@@ -777,26 +778,26 @@ function findVersion() {
 //     $.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)
-}
+	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.
 //
@@ -809,30 +810,30 @@ function enable() {
 //     $.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() }
+	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)
-}
+		$(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')
+	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]|WebApps\/.+CFNetwork)/)
+	$.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]|WebApps\/.+CFNetwork)/)
 
-$.support.pjax ? enable() : disable()
+	$.support.pjax ? enable() : disable()
 
 })(jQuery);