diff --git a/bower.json b/bower.json index ef9ed144c..3941f90ba 100644 --- a/bower.json +++ b/bower.json @@ -1,8 +1,8 @@ { - "name": "mkdocs-material", + "name": "Material", "version": "0.1.0", "description": "A material design theme for MkDocs", - "homepage": "https://github.com/squidfunk/mkdocs-material", + "homepage": "http://squidfunk.github.io/mkdocs-material/", "authors": [ "squidfunk " ], diff --git a/docs/customization.md b/docs/customization.md new file mode 100644 index 000000000..307ef6cff --- /dev/null +++ b/docs/customization.md @@ -0,0 +1,86 @@ +# Customization + +## A good starting point + +Project documentation is as diverse as the projects themselves and the Material +theme is a good starting point for making it look good. However, as you write +your documentation, you may reach some point where some small adjustments are +necessary to preserve the style. + +## Small tweaks + +[MkDocs][] provides a simple way for making small adjustments, that is changing +some margins, centering text, etc. Simply put the CSS and Javascript files that +contain your adjustments in the `docs` directory (ideally in subdirectories of +their own) and include them via the `extra_css` and `extra_javascript` +variables in your `mkdocs.yml`: + +``` yaml +extra_css: ['/stylesheets/extra.css'] +extra_javascript: ['/javascripts/extra.js'] +``` + +Further assistance on including extra CSS and Javascript can be found in the +[MkDocs documentation][]. + +## Fundamental changes + +If you want to make larger adjustments like changing the color palette or +typography, you should check out the repository of the project and compile +the SASS sources with your changes. The project design is very modular, so +most things can be changed by tweaking a few variables. + +### Setup + +In order to compile the project, you need `node`, `bower` and `gulp` up and +running. It's best to use the most recent versions, but it should also work if +your installations are not too dated. The project itself is hosted on GitHub, +so the next thing you should do is clone the project from GitHub: + +``` sh +git clone https://github.com/squidfunk/mkdocs-material +``` + +Then you change the directory and install all dependencies specified in the +`package.json` and `bower.json`: + +``` sh +cd mkdocs-material +npm install && bower install +``` + +### Development + +The asset pipeline is contained in `Gulpfile.js`, which you can start with +`gulp watch`. This will also run `mkdocs serve`, to monitor changes to the +documentation. Point your browser to [localhost:8000](http://localhost:8000) +and you should see this very documentation in front of your eyes. + +``` sh +gulp watch +``` + +For example, changing the color palette is as simple as changing the `$primary` +and `$accent` variables in `src/assets/stylesheets/_palette.scss`: + +``` css +$primary: $red-400; +$accent: $teal-a700; +``` + +### Building + +When you finished making your changes, you can build the theme by invoking: + +``` sh +gulp build --production +``` + +The `production` flag triggers the production-level compilation and +minification of all CSS and Javascript sources. When the command is ready, +the final theme is located in the `material` directory. Add the `theme_dir` +variable pointing to the aforementioned directory in your original +`mkdocs.yml` and you should see your documentation with your changes! + +[MkDocs]: http://www.mkdocs.org +[MkDocs documentation]: http://www.mkdocs.org/user-guide/styling-your-docs/#customising-a-theme \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 000000000..dba642f56 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,223 @@ +# Getting started + +## Installation + +### Installing MkDocs + +In order to install [MkDocs][], Python and `pip` - the Python package manager - +need to be up and running. Assuming you are a developer and have a basic +understanding of how things work and what StackOverflow is, we won't provide +guidelines on setting those up. You can verify if you're already good to go +with the following commands: + +``` sh +python --version +# Python 2.7.2 +pip --version +# pip 1.5.2 +``` + +Installing and verifying MkDocs is as simple as: + +``` sh +pip install mkdocs && mkdocs --version +# mkdocs, version 0.15.2 +``` + +### Installing Material + +Next, assuming you have MkDocs up and running `mkdocs-material` can be +installed with `pip`: + +``` sh +pip install mkdocs-material +``` + +## Usage + +If you haven't already done it, creating a new documentation project is really +simple in MkDocs: + +``` sh +mkdocs new my-project +cd my-project +``` + +MkDocs will create the necessary files and base directory structure inside the +folder `my-project`. In order to enable the theme just add the following line +to the auto-generated `mkdocs.yml`: + +``` yaml +theme: 'material' +``` + +If your project is hosted on GitHub, add the repository link to the +configuration. If the `repo_name` equals **GitHub**, the Material theme will +add a download and star button, and display the number of stars: + +``` yaml +repo_name: 'GitHub' +repo_url: 'https://github.com/my-github-handle/my-project' +``` + +MkDocs includes a development server, so you can view your changes as you go - +very handy. Spin it up with the following command: + +``` sh +mkdocs serve +``` + +Now you can go to [localhost:8000](http://localhost:8000) and the Material +theme should be visible. You can now start writing your documentation, or read +on and customize the theme through some options. + +## Options + +The Material theme adds some extra variables for configuration via your +project's `mkdocs.yml`. See the following section for all available options. + +### Adding a logo + +If your project has a logo, you can add it to the drawer/navigation by defining +the variable `extra.logo`. Ideally, the image of your logo should have +rectangular shape with a minimum resolution of 128x128. The logo will also be +used as a web application icon on iOS. Simply create the folder `docs/images`, +add your image and reference it via: + +``` yaml +extra: + logo: 'images/logo.png' +``` + +### Adding a version + +In order to add the current version next to the project banner inside the +drawer, you can set the variable `extra.version`: + +``` yaml +extra: + version: '0.1.0' +``` + +### Adding a GitHub and Twitter account + +If you have a GitHub and/or Twitter account, you can add links to your +accounts to the drawer by setting the variables `extra.author.github` and +`extra.author.twitter` respectively: + +``` yaml +extra: + author: + github: 'my-github-handle' + twitter: 'my-twitter-handle' +``` + +### More advanced customization + +If you want to change the fonts or colors - you are lucky. The Material theme +is built with a sophisticated asset pipeline. See +[this article](/customization) for more information on advanced customization. + +## Extensions + +MkDocs supports several [Markdown extensions][]. The following extensions are +not enabled by default (see the link for which are enabled by default), so you +have to switch them on explicitly. + +### CodeHilite (recommended) + +This extensions adds code highlighting to fenced code blocks. It might not be +the best code highlighter, but it works without JavaScript and on the server: + +``` yaml +markdown_extensions: + - codehilite(css_class=code) +``` + +If you want more extensive highlighting, you can use a JavaScript library like +[highlight.js][], which is not included in Material. See [this link][extra] for +further instructions + +### Permalinks + +In order to add [permalinks][] to the headers of your article, set the +`markdown_extensions.toc.permalink` variable to a symbol, e.g. `¶`: + +``` yaml +markdown_extensions: + - toc: + permalink: '¶' +``` + +The symbol can be chosen freely, it can even be a WebFont icon. + +### Admonition + +[Admonition][] is a handy extension that adds block-styled side content to your +documentation, for example hints, notes or warnings. It can be enabled by +setting the variable `markdown_extensions.admonition`: + +``` yaml +markdown_extensions: + - admonition +``` + +In order to add a note, use the following syntax inside your article: + +``` markdown +!!! note + Nothing to see here, move along. +``` + +This will print the following: + +!!! note + Nothing to see here, move along. + +The Material template adds a light color for the `note` class and a red color +for the `warning` class. More colors can be freely defined. + +## Full example + +Below is a full example configuration for a mkdocs.yml: + +``` yaml +# Project information +site_name: 'My Project' +site_description: 'A short description of my project' +site_author: 'John Doe' +site_url: 'https://github.com/my-github-handle/my-project' + +# Repository +repo_name: 'GitHub' +repo_url: 'https://github.com/my-github-handle/my-project' + +# Copyright +copyright: 'Copyright (c) 2016 John Doe' + +# Documentation and theme +docs_dir: 'docs' +theme: 'material' + +# Options +extra: + version: '0.1.0' + logo: 'images/logo.png' + author: + github: 'my-github-handle' + twitter: 'my-twitter-handle' + +# Extensions +markdown_extensions: + - codehilite(css_class=code) + - admonition + - toc: + permalink: '¶' +``` + +[MkDocs]: http://www.mkdocs.org +[Markdown extensions]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions +[highlight.js]: https://highlightjs.org/ +[extra]: http://www.mkdocs.org/user-guide/styling-your-docs/#customising-a-theme +[permalinks]: https://en.wikipedia.org/wiki/Permalink +[Admonition]: https://pythonhosted.org/Markdown/extensions/admonition.html \ No newline at end of file diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100644 index 000000000..6faca5f64 Binary files /dev/null and b/docs/images/logo.png differ diff --git a/docs/images/screen.png b/docs/images/screen.png new file mode 100644 index 000000000..cb10504b4 Binary files /dev/null and b/docs/images/screen.png differ diff --git a/docs/index.md b/docs/index.md index 33b49a753..d106ec0fb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1 +1,47 @@ -A material design theme for MkDocs. \ No newline at end of file +# Material for MkDocs + +## Beautiful documentation + +You're currently looking at a full responsive [MkDocs][] theme in the spirit of +Google's [material design][] guidelines. MkDocs is an excellent static site +documentation generator that is meant for building good looking project +documentation. + +![Material Screenshot](/images/screen.png) + +This theme is **optimized for all sorts of devices** and is built from scratch +without any bloated Javascript or CSS Frameworks with **only 24kb of JS and +CSS** (minified, gzipped and excluding Google WebFonts and Analytics). Yet, it +is highly customizable in terms of fonts, colors and gracefully supports older +browsers. + +## Features + +- Beautiful, readable and very user-friendly design based on Google's + **material design** guidelines, packed in a **full responsive** template + with a well-defined color palette, great typography, as well as a beautiful + search interface and footer. + +- Well-tested and **optimized CSS and Javascript**, including a cross-browser + fixed/sticky header, a drawer that even works without Javascript using + the `checkbox:checked` hack with fallbacks, **responsive tables** that scroll + when the screen is too small and **well-defined print styles**. + +- Extra configuration options like **project logo**, links to the authors + **GitHub and Twitter accounts** and display of the **amount of stars** the + project has on GitHub. + +- **Easily extendable and customizable** due to a well-designed asset pipeline + built on-top of [Gulp][] with `npm` and `bower` and modular and abstracted + style definitions built with [SASS][]. + +- **Web application capability** on iOS - when the page is saved to the + homescreen, it behaves and looks like a native application. + +See the [getting started guide](/getting-started) for instructions how to get +it up and running. + +[material design]: https://www.google.com/design/spec/material-design +[MkDocs]: http://www.mkdocs.org +[Gulp]: http://gulpjs.com +[SASS]: http://sass-lang.com/ \ No newline at end of file diff --git a/docs/license.md b/docs/license.md new file mode 100644 index 000000000..7830c45f4 --- /dev/null +++ b/docs/license.md @@ -0,0 +1,21 @@ +# License + +Copyright (c) 2016 Martin Donath + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/material/assets/javascripts/application.js b/material/assets/javascripts/application.js index e3835f516..c08d519a7 100644 --- a/material/assets/javascripts/application.js +++ b/material/assets/javascripts/application.js @@ -1,3618 +1,2 @@ -/* - * classList.js: Cross-browser full element.classList implementation. - * 2014-12-13 - * - * By Eli Grey, http://eligrey.com - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ - -/*global self, document, DOMException */ - -/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */ - -if ("document" in self) { - -// Full polyfill for browsers with no classList support -if (!("classList" in document.createElement("_"))) { - -(function (view) { - -"use strict"; - -if (!('Element' in view)) return; - -var - classListProp = "classList" - , protoProp = "prototype" - , elemCtrProto = view.Element[protoProp] - , objCtr = Object - , strTrim = String[protoProp].trim || function () { - return this.replace(/^\s+|\s+$/g, ""); - } - , arrIndexOf = Array[protoProp].indexOf || function (item) { - var - i = 0 - , len = this.length - ; - for (; i < len; i++) { - if (i in this && this[i] === item) { - return i; - } - } - return -1; - } - // Vendors: please allow content code to instantiate DOMExceptions - , DOMEx = function (type, message) { - this.name = type; - this.code = DOMException[type]; - this.message = message; - } - , checkTokenAndGetIndex = function (classList, token) { - if (token === "") { - throw new DOMEx( - "SYNTAX_ERR" - , "An invalid or illegal string was specified" - ); - } - if (/\s/.test(token)) { - throw new DOMEx( - "INVALID_CHARACTER_ERR" - , "String contains an invalid character" - ); - } - return arrIndexOf.call(classList, token); - } - , ClassList = function (elem) { - var - trimmedClasses = strTrim.call(elem.getAttribute("class") || "") - , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] - , i = 0 - , len = classes.length - ; - for (; i < len; i++) { - this.push(classes[i]); - } - this._updateClassName = function () { - elem.setAttribute("class", this.toString()); - }; - } - , classListProto = ClassList[protoProp] = [] - , classListGetter = function () { - return new ClassList(this); - } -; -// Most DOMException implementations don't allow calling DOMException's toString() -// on non-DOMExceptions. Error's toString() is sufficient here. -DOMEx[protoProp] = Error[protoProp]; -classListProto.item = function (i) { - return this[i] || null; -}; -classListProto.contains = function (token) { - token += ""; - return checkTokenAndGetIndex(this, token) !== -1; -}; -classListProto.add = function () { - var - tokens = arguments - , i = 0 - , l = tokens.length - , token - , updated = false - ; - do { - token = tokens[i] + ""; - if (checkTokenAndGetIndex(this, token) === -1) { - this.push(token); - updated = true; - } - } - while (++i < l); - - if (updated) { - this._updateClassName(); - } -}; -classListProto.remove = function () { - var - tokens = arguments - , i = 0 - , l = tokens.length - , token - , updated = false - , index - ; - do { - token = tokens[i] + ""; - index = checkTokenAndGetIndex(this, token); - while (index !== -1) { - this.splice(index, 1); - updated = true; - index = checkTokenAndGetIndex(this, token); - } - } - while (++i < l); - - if (updated) { - this._updateClassName(); - } -}; -classListProto.toggle = function (token, force) { - token += ""; - - var - result = this.contains(token) - , method = result ? - force !== true && "remove" - : - force !== false && "add" - ; - - if (method) { - this[method](token); - } - - if (force === true || force === false) { - return force; - } else { - return !result; - } -}; -classListProto.toString = function () { - return this.join(" "); -}; - -if (objCtr.defineProperty) { - var classListPropDesc = { - get: classListGetter - , enumerable: true - , configurable: true - }; - try { - objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); - } catch (ex) { // IE 8 doesn't support enumerable:true - if (ex.number === -0x7FF5EC54) { - classListPropDesc.enumerable = false; - objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); - } - } -} else if (objCtr[protoProp].__defineGetter__) { - elemCtrProto.__defineGetter__(classListProp, classListGetter); -} - -}(self)); - -} else { -// There is full or partial native classList support, so just check if we need -// to normalize the add/remove and toggle APIs. - -(function () { - "use strict"; - - var testElement = document.createElement("_"); - - testElement.classList.add("c1", "c2"); - - // Polyfill for IE 10/11 and Firefox <26, where classList.add and - // classList.remove exist but support only one argument at a time. - if (!testElement.classList.contains("c2")) { - var createMethod = function(method) { - var original = DOMTokenList.prototype[method]; - - DOMTokenList.prototype[method] = function(token) { - var i, len = arguments.length; - - for (i = 0; i < len; i++) { - token = arguments[i]; - original.call(this, token); - } - }; - }; - createMethod('add'); - createMethod('remove'); - } - - testElement.classList.toggle("c3", false); - - // Polyfill for IE 10 and Firefox <24, where classList.toggle does not - // support the second argument. - if (testElement.classList.contains("c3")) { - var _toggle = DOMTokenList.prototype.toggle; - - DOMTokenList.prototype.toggle = function(token, force) { - if (1 in arguments && !this.contains(token) === !force) { - return force; - } else { - return _toggle.call(this, token); - } - }; - - } - - testElement = null; -}()); - -} - -} - - -;(function () { - 'use strict'; - - /** - * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs. - * - * @codingstandard ftlabs-jsv2 - * @copyright The Financial Times Limited [All Rights Reserved] - * @license MIT License (see LICENSE.txt) - */ - - /*jslint browser:true, node:true*/ - /*global define, Event, Node*/ - - - /** - * Instantiate fast-clicking listeners on the specified layer. - * - * @constructor - * @param {Element} layer The layer to listen on - * @param {Object} [options={}] The options to override the defaults - */ - function FastClick(layer, options) { - var oldOnClick; - - options = options || {}; - - /** - * Whether a click is currently being tracked. - * - * @type boolean - */ - this.trackingClick = false; - - - /** - * Timestamp for when click tracking started. - * - * @type number - */ - this.trackingClickStart = 0; - - - /** - * The element being tracked for a click. - * - * @type EventTarget - */ - this.targetElement = null; - - - /** - * X-coordinate of touch start event. - * - * @type number - */ - this.touchStartX = 0; - - - /** - * Y-coordinate of touch start event. - * - * @type number - */ - this.touchStartY = 0; - - - /** - * ID of the last touch, retrieved from Touch.identifier. - * - * @type number - */ - this.lastTouchIdentifier = 0; - - - /** - * Touchmove boundary, beyond which a click will be cancelled. - * - * @type number - */ - this.touchBoundary = options.touchBoundary || 10; - - - /** - * The FastClick layer. - * - * @type Element - */ - this.layer = layer; - - /** - * The minimum time between tap(touchstart and touchend) events - * - * @type number - */ - this.tapDelay = options.tapDelay || 200; - - /** - * The maximum time for a tap - * - * @type number - */ - this.tapTimeout = options.tapTimeout || 700; - - if (FastClick.notNeeded(layer)) { - return; - } - - // Some old versions of Android don't have Function.prototype.bind - function bind(method, context) { - return function() { return method.apply(context, arguments); }; - } - - - var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel']; - var context = this; - for (var i = 0, l = methods.length; i < l; i++) { - context[methods[i]] = bind(context[methods[i]], context); - } - - // Set up event handlers as required - if (deviceIsAndroid) { - layer.addEventListener('mouseover', this.onMouse, true); - layer.addEventListener('mousedown', this.onMouse, true); - layer.addEventListener('mouseup', this.onMouse, true); - } - - layer.addEventListener('click', this.onClick, true); - layer.addEventListener('touchstart', this.onTouchStart, false); - layer.addEventListener('touchmove', this.onTouchMove, false); - layer.addEventListener('touchend', this.onTouchEnd, false); - layer.addEventListener('touchcancel', this.onTouchCancel, false); - - // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) - // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick - // layer when they are cancelled. - if (!Event.prototype.stopImmediatePropagation) { - layer.removeEventListener = function(type, callback, capture) { - var rmv = Node.prototype.removeEventListener; - if (type === 'click') { - rmv.call(layer, type, callback.hijacked || callback, capture); - } else { - rmv.call(layer, type, callback, capture); - } - }; - - layer.addEventListener = function(type, callback, capture) { - var adv = Node.prototype.addEventListener; - if (type === 'click') { - adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) { - if (!event.propagationStopped) { - callback(event); - } - }), capture); - } else { - adv.call(layer, type, callback, capture); - } - }; - } - - // If a handler is already declared in the element's onclick attribute, it will be fired before - // FastClick's onClick handler. Fix this by pulling out the user-defined handler function and - // adding it as listener. - if (typeof layer.onclick === 'function') { - - // Android browser on at least 3.2 requires a new reference to the function in layer.onclick - // - the old one won't work if passed to addEventListener directly. - oldOnClick = layer.onclick; - layer.addEventListener('click', function(event) { - oldOnClick(event); - }, false); - layer.onclick = null; - } - } - - /** - * Windows Phone 8.1 fakes user agent string to look like Android and iPhone. - * - * @type boolean - */ - var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0; - - /** - * Android requires exceptions. - * - * @type boolean - */ - var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone; - - - /** - * iOS requires exceptions. - * - * @type boolean - */ - var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone; - - - /** - * iOS 4 requires an exception for select elements. - * - * @type boolean - */ - var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent); - - - /** - * iOS 6.0-7.* requires the target element to be manually derived - * - * @type boolean - */ - var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\d/).test(navigator.userAgent); - - /** - * BlackBerry requires exceptions. - * - * @type boolean - */ - var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0; - - /** - * Determine whether a given element requires a native click. - * - * @param {EventTarget|Element} target Target DOM element - * @returns {boolean} Returns true if the element needs a native click - */ - FastClick.prototype.needsClick = function(target) { - switch (target.nodeName.toLowerCase()) { - - // Don't send a synthetic click to disabled inputs (issue #62) - case 'button': - case 'select': - case 'textarea': - if (target.disabled) { - return true; - } - - break; - case 'input': - - // File inputs need real clicks on iOS 6 due to a browser bug (issue #68) - if ((deviceIsIOS && target.type === 'file') || target.disabled) { - return true; - } - - break; - case 'label': - case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames - case 'video': - return true; - } - - return (/\bneedsclick\b/).test(target.className); - }; - - - /** - * Determine whether a given element requires a call to focus to simulate click into element. - * - * @param {EventTarget|Element} target Target DOM element - * @returns {boolean} Returns true if the element requires a call to focus to simulate native click. - */ - FastClick.prototype.needsFocus = function(target) { - switch (target.nodeName.toLowerCase()) { - case 'textarea': - return true; - case 'select': - return !deviceIsAndroid; - case 'input': - switch (target.type) { - case 'button': - case 'checkbox': - case 'file': - case 'image': - case 'radio': - case 'submit': - return false; - } - - // No point in attempting to focus disabled inputs - return !target.disabled && !target.readOnly; - default: - return (/\bneedsfocus\b/).test(target.className); - } - }; - - - /** - * Send a click event to the specified element. - * - * @param {EventTarget|Element} targetElement - * @param {Event} event - */ - FastClick.prototype.sendClick = function(targetElement, event) { - var clickEvent, touch; - - // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24) - if (document.activeElement && document.activeElement !== targetElement) { - document.activeElement.blur(); - } - - touch = event.changedTouches[0]; - - // Synthesise a click event, with an extra attribute so it can be tracked - clickEvent = document.createEvent('MouseEvents'); - clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); - clickEvent.forwardedTouchEvent = true; - targetElement.dispatchEvent(clickEvent); - }; - - FastClick.prototype.determineEventType = function(targetElement) { - - //Issue #159: Android Chrome Select Box does not open with a synthetic click event - if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') { - return 'mousedown'; - } - - return 'click'; - }; - - - /** - * @param {EventTarget|Element} targetElement - */ - FastClick.prototype.focus = function(targetElement) { - var length; - - // Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724. - if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') { - length = targetElement.value.length; - targetElement.setSelectionRange(length, length); - } else { - targetElement.focus(); - } - }; - - - /** - * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it. - * - * @param {EventTarget|Element} targetElement - */ - FastClick.prototype.updateScrollParent = function(targetElement) { - var scrollParent, parentElement; - - scrollParent = targetElement.fastClickScrollParent; - - // Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the - // target element was moved to another parent. - if (!scrollParent || !scrollParent.contains(targetElement)) { - parentElement = targetElement; - do { - if (parentElement.scrollHeight > parentElement.offsetHeight) { - scrollParent = parentElement; - targetElement.fastClickScrollParent = parentElement; - break; - } - - parentElement = parentElement.parentElement; - } while (parentElement); - } - - // Always update the scroll top tracker if possible. - if (scrollParent) { - scrollParent.fastClickLastScrollTop = scrollParent.scrollTop; - } - }; - - - /** - * @param {EventTarget} targetElement - * @returns {Element|EventTarget} - */ - FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) { - - // On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node. - if (eventTarget.nodeType === Node.TEXT_NODE) { - return eventTarget.parentNode; - } - - return eventTarget; - }; - - - /** - * On touch start, record the position and scroll offset. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onTouchStart = function(event) { - var targetElement, touch, selection; - - // Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111). - if (event.targetTouches.length > 1) { - return true; - } - - targetElement = this.getTargetElementFromEventTarget(event.target); - touch = event.targetTouches[0]; - - if (deviceIsIOS) { - - // Only trusted events will deselect text on iOS (issue #49) - selection = window.getSelection(); - if (selection.rangeCount && !selection.isCollapsed) { - return true; - } - - if (!deviceIsIOS4) { - - // Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23): - // when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched - // with the same identifier as the touch event that previously triggered the click that triggered the alert. - // Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an - // immediately preceeding touch event (issue #52), so this fix is unavailable on that platform. - // Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string, - // which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long, - // random integers, it's safe to to continue if the identifier is 0 here. - if (touch.identifier && touch.identifier === this.lastTouchIdentifier) { - event.preventDefault(); - return false; - } - - this.lastTouchIdentifier = touch.identifier; - - // If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and: - // 1) the user does a fling scroll on the scrollable layer - // 2) the user stops the fling scroll with another tap - // then the event.target of the last 'touchend' event will be the element that was under the user's finger - // when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check - // is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42). - this.updateScrollParent(targetElement); - } - } - - this.trackingClick = true; - this.trackingClickStart = event.timeStamp; - this.targetElement = targetElement; - - this.touchStartX = touch.pageX; - this.touchStartY = touch.pageY; - - // Prevent phantom clicks on fast double-tap (issue #36) - if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { - event.preventDefault(); - } - - return true; - }; - - - /** - * Based on a touchmove event object, check whether the touch has moved past a boundary since it started. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.touchHasMoved = function(event) { - var touch = event.changedTouches[0], boundary = this.touchBoundary; - - if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) { - return true; - } - - return false; - }; - - - /** - * Update the last position. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onTouchMove = function(event) { - if (!this.trackingClick) { - return true; - } - - // If the touch has moved, cancel the click tracking - if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) { - this.trackingClick = false; - this.targetElement = null; - } - - return true; - }; - - - /** - * Attempt to find the labelled control for the given label element. - * - * @param {EventTarget|HTMLLabelElement} labelElement - * @returns {Element|null} - */ - FastClick.prototype.findControl = function(labelElement) { - - // Fast path for newer browsers supporting the HTML5 control attribute - if (labelElement.control !== undefined) { - return labelElement.control; - } - - // All browsers under test that support touch events also support the HTML5 htmlFor attribute - if (labelElement.htmlFor) { - return document.getElementById(labelElement.htmlFor); - } - - // If no for attribute exists, attempt to retrieve the first labellable descendant element - // the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label - return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea'); - }; - - - /** - * On touch end, determine whether to send a click event at once. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onTouchEnd = function(event) { - var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement; - - if (!this.trackingClick) { - return true; - } - - // Prevent phantom clicks on fast double-tap (issue #36) - if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { - this.cancelNextClick = true; - return true; - } - - if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) { - return true; - } - - // Reset to prevent wrong click cancel on input (issue #156). - this.cancelNextClick = false; - - this.lastClickTime = event.timeStamp; - - trackingClickStart = this.trackingClickStart; - this.trackingClick = false; - this.trackingClickStart = 0; - - // On some iOS devices, the targetElement supplied with the event is invalid if the layer - // is performing a transition or scroll, and has to be re-detected manually. Note that - // for this to function correctly, it must be called *after* the event target is checked! - // See issue #57; also filed as rdar://13048589 . - if (deviceIsIOSWithBadTarget) { - touch = event.changedTouches[0]; - - // In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null - targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement; - targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent; - } - - targetTagName = targetElement.tagName.toLowerCase(); - if (targetTagName === 'label') { - forElement = this.findControl(targetElement); - if (forElement) { - this.focus(targetElement); - if (deviceIsAndroid) { - return false; - } - - targetElement = forElement; - } - } else if (this.needsFocus(targetElement)) { - - // Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through. - // Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37). - if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) { - this.targetElement = null; - return false; - } - - this.focus(targetElement); - this.sendClick(targetElement, event); - - // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open. - // Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others) - if (!deviceIsIOS || targetTagName !== 'select') { - this.targetElement = null; - event.preventDefault(); - } - - return false; - } - - if (deviceIsIOS && !deviceIsIOS4) { - - // Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled - // and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42). - scrollParent = targetElement.fastClickScrollParent; - if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) { - return true; - } - } - - // Prevent the actual click from going though - unless the target node is marked as requiring - // real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted. - if (!this.needsClick(targetElement)) { - event.preventDefault(); - this.sendClick(targetElement, event); - } - - return false; - }; - - - /** - * On touch cancel, stop tracking the click. - * - * @returns {void} - */ - FastClick.prototype.onTouchCancel = function() { - this.trackingClick = false; - this.targetElement = null; - }; - - - /** - * Determine mouse events which should be permitted. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onMouse = function(event) { - - // If a target element was never set (because a touch event was never fired) allow the event - if (!this.targetElement) { - return true; - } - - if (event.forwardedTouchEvent) { - return true; - } - - // Programmatically generated events targeting a specific element should be permitted - if (!event.cancelable) { - return true; - } - - // Derive and check the target element to see whether the mouse event needs to be permitted; - // unless explicitly enabled, prevent non-touch click events from triggering actions, - // to prevent ghost/doubleclicks. - if (!this.needsClick(this.targetElement) || this.cancelNextClick) { - - // Prevent any user-added listeners declared on FastClick element from being fired. - if (event.stopImmediatePropagation) { - event.stopImmediatePropagation(); - } else { - - // Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) - event.propagationStopped = true; - } - - // Cancel the event - event.stopPropagation(); - event.preventDefault(); - - return false; - } - - // If the mouse event is permitted, return true for the action to go through. - return true; - }; - - - /** - * On actual clicks, determine whether this is a touch-generated click, a click action occurring - * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or - * an actual click which should be permitted. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onClick = function(event) { - var permitted; - - // It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early. - if (this.trackingClick) { - this.targetElement = null; - this.trackingClick = false; - return true; - } - - // Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target. - if (event.target.type === 'submit' && event.detail === 0) { - return true; - } - - permitted = this.onMouse(event); - - // Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through. - if (!permitted) { - this.targetElement = null; - } - - // If clicks are permitted, return true for the action to go through. - return permitted; - }; - - - /** - * Remove all FastClick's event listeners. - * - * @returns {void} - */ - FastClick.prototype.destroy = function() { - var layer = this.layer; - - if (deviceIsAndroid) { - layer.removeEventListener('mouseover', this.onMouse, true); - layer.removeEventListener('mousedown', this.onMouse, true); - layer.removeEventListener('mouseup', this.onMouse, true); - } - - layer.removeEventListener('click', this.onClick, true); - layer.removeEventListener('touchstart', this.onTouchStart, false); - layer.removeEventListener('touchmove', this.onTouchMove, false); - layer.removeEventListener('touchend', this.onTouchEnd, false); - layer.removeEventListener('touchcancel', this.onTouchCancel, false); - }; - - - /** - * Check whether FastClick is needed. - * - * @param {Element} layer The layer to listen on - */ - FastClick.notNeeded = function(layer) { - var metaViewport; - var chromeVersion; - var blackberryVersion; - var firefoxVersion; - - // Devices that don't support touch don't need FastClick - if (typeof window.ontouchstart === 'undefined') { - return true; - } - - // Chrome version - zero for other browsers - chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1]; - - if (chromeVersion) { - - if (deviceIsAndroid) { - metaViewport = document.querySelector('meta[name=viewport]'); - - if (metaViewport) { - // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89) - if (metaViewport.content.indexOf('user-scalable=no') !== -1) { - return true; - } - // Chrome 32 and above with width=device-width or less don't need FastClick - if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) { - return true; - } - } - - // Chrome desktop doesn't need FastClick (issue #15) - } else { - return true; - } - } - - if (deviceIsBlackBerry10) { - blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/); - - // BlackBerry 10.3+ does not require Fastclick library. - // https://github.com/ftlabs/fastclick/issues/251 - if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) { - metaViewport = document.querySelector('meta[name=viewport]'); - - if (metaViewport) { - // user-scalable=no eliminates click delay. - if (metaViewport.content.indexOf('user-scalable=no') !== -1) { - return true; - } - // width=device-width (or less than device-width) eliminates click delay. - if (document.documentElement.scrollWidth <= window.outerWidth) { - return true; - } - } - } - } - - // IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97) - if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') { - return true; - } - - // Firefox version - zero for other browsers - firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1]; - - if (firefoxVersion >= 27) { - // Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896 - - metaViewport = document.querySelector('meta[name=viewport]'); - if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) { - return true; - } - } - - // IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version - // http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx - if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') { - return true; - } - - return false; - }; - - - /** - * Factory method for creating a FastClick object - * - * @param {Element} layer The layer to listen on - * @param {Object} [options={}] The options to override the defaults - */ - FastClick.attach = function(layer, options) { - return new FastClick(layer, options); - }; - - - if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { - - // AMD. Register as an anonymous module. - define(function() { - return FastClick; - }); - } else if (typeof module !== 'undefined' && module.exports) { - module.exports = FastClick.attach; - module.exports.FastClick = FastClick; - } else { - window.FastClick = FastClick; - } -}()); - -// a url (naming it a, beacause it will be reused to store callbacks) -// xhr placeholder to avoid using var, not to be used -function pegasus(a, xhr) { - xhr = new XMLHttpRequest(); - - // Open url - xhr.open('GET', a); - - // Reuse a to store callbacks - a = []; - - // onSuccess handler - // onError handler - // cb, data placeholder to avoid using var, should not be used - xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb, data) { - - // Test if onSuccess is a function - if (onSuccess && onSuccess.call) a = [,onSuccess, onError]; - - // Test if request is complete - if (xhr.readyState == 4) { - - // index will be: - // 0 if undefined - // 1 if status is between 200 and 399 - // 2 if status is over - cb = a[0|xhr.status / 200]; - - // Safari doesn't support xhr.responseType = 'json' - // so the response is parsed - if (cb) { - try { - data = JSON.parse(xhr.responseText) - } catch (e) { - data = null - } - cb(data, xhr); - } - } - }; - - // Send - xhr.send(); - - // Return request - return xhr; -} - -/** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12 - * Copyright (C) 2015 Oliver Nightingale - * MIT Licensed - * @license - */ - -;(function(){ - -/** - * Convenience function for instantiating a new lunr index and configuring it - * with the default pipeline functions and the passed config function. - * - * When using this convenience function a new index will be created with the - * following functions already in the pipeline: - * - * lunr.StopWordFilter - filters out any stop words before they enter the - * index - * - * lunr.stemmer - stems the tokens before entering the index. - * - * Example: - * - * var idx = lunr(function () { - * this.field('title', 10) - * this.field('tags', 100) - * this.field('body') - * - * this.ref('cid') - * - * this.pipeline.add(function () { - * // some custom pipeline function - * }) - * - * }) - * - * @param {Function} config A function that will be called with the new instance - * of the lunr.Index as both its context and first parameter. It can be used to - * customize the instance of new lunr.Index. - * @namespace - * @module - * @returns {lunr.Index} - * - */ -var lunr = function (config) { - var idx = new lunr.Index - - idx.pipeline.add( - lunr.trimmer, - lunr.stopWordFilter, - lunr.stemmer - ) - - if (config) config.call(idx, idx) - - return idx -} - -lunr.version = "0.5.12" -/*! - * lunr.utils - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * A namespace containing utils for the rest of the lunr library - */ -lunr.utils = {} - -/** - * Print a warning message to the console. - * - * @param {String} message The message to be printed. - * @memberOf Utils - */ -lunr.utils.warn = (function (global) { - return function (message) { - if (global.console && console.warn) { - console.warn(message) - } - } -})(this) - -/*! - * lunr.EventEmitter - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers. - * - * @constructor - */ -lunr.EventEmitter = function () { - this.events = {} -} - -/** - * Binds a handler function to a specific event(s). - * - * Can bind a single function to many different events in one call. - * - * @param {String} [eventName] The name(s) of events to bind this function to. - * @param {Function} fn The function to call when an event is fired. - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.addListener = function () { - var args = Array.prototype.slice.call(arguments), - fn = args.pop(), - names = args - - if (typeof fn !== "function") throw new TypeError ("last argument must be a function") - - names.forEach(function (name) { - if (!this.hasHandler(name)) this.events[name] = [] - this.events[name].push(fn) - }, this) -} - -/** - * Removes a handler function from a specific event. - * - * @param {String} eventName The name of the event to remove this function from. - * @param {Function} fn The function to remove from an event. - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.removeListener = function (name, fn) { - if (!this.hasHandler(name)) return - - var fnIndex = this.events[name].indexOf(fn) - this.events[name].splice(fnIndex, 1) - - if (!this.events[name].length) delete this.events[name] -} - -/** - * Calls all functions bound to the given event. - * - * Additional data can be passed to the event handler as arguments to `emit` - * after the event name. - * - * @param {String} eventName The name of the event to emit. - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.emit = function (name) { - if (!this.hasHandler(name)) return - - var args = Array.prototype.slice.call(arguments, 1) - - this.events[name].forEach(function (fn) { - fn.apply(undefined, args) - }) -} - -/** - * Checks whether a handler has ever been stored against an event. - * - * @param {String} eventName The name of the event to check. - * @private - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.hasHandler = function (name) { - return name in this.events -} - -/*! - * lunr.tokenizer - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * A function for splitting a string into tokens ready to be inserted into - * the search index. - * - * @module - * @param {String} obj The string to convert into tokens - * @returns {Array} - */ -lunr.tokenizer = function (obj) { - if (!arguments.length || obj == null || obj == undefined) return [] - if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() }) - - return obj.toString().trim().toLowerCase().split(/[\s\-]+/) -} - -/*! - * lunr.Pipeline - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.Pipelines maintain an ordered list of functions to be applied to all - * tokens in documents entering the search index and queries being ran against - * the index. - * - * An instance of lunr.Index created with the lunr shortcut will contain a - * pipeline with a stop word filter and an English language stemmer. Extra - * functions can be added before or after either of these functions or these - * default functions can be removed. - * - * When run the pipeline will call each function in turn, passing a token, the - * index of that token in the original list of all tokens and finally a list of - * all the original tokens. - * - * The output of functions in the pipeline will be passed to the next function - * in the pipeline. To exclude a token from entering the index the function - * should return undefined, the rest of the pipeline will not be called with - * this token. - * - * For serialisation of pipelines to work, all functions used in an instance of - * a pipeline should be registered with lunr.Pipeline. Registered functions can - * then be loaded. If trying to load a serialised pipeline that uses functions - * that are not registered an error will be thrown. - * - * If not planning on serialising the pipeline then registering pipeline functions - * is not necessary. - * - * @constructor - */ -lunr.Pipeline = function () { - this._stack = [] -} - -lunr.Pipeline.registeredFunctions = {} - -/** - * Register a function with the pipeline. - * - * Functions that are used in the pipeline should be registered if the pipeline - * needs to be serialised, or a serialised pipeline needs to be loaded. - * - * Registering a function does not add it to a pipeline, functions must still be - * added to instances of the pipeline for them to be used when running a pipeline. - * - * @param {Function} fn The function to check for. - * @param {String} label The label to register this function with - * @memberOf Pipeline - */ -lunr.Pipeline.registerFunction = function (fn, label) { - if (label in this.registeredFunctions) { - lunr.utils.warn('Overwriting existing registered function: ' + label) - } - - fn.label = label - lunr.Pipeline.registeredFunctions[fn.label] = fn -} - -/** - * Warns if the function is not registered as a Pipeline function. - * - * @param {Function} fn The function to check for. - * @private - * @memberOf Pipeline - */ -lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { - var isRegistered = fn.label && (fn.label in this.registeredFunctions) - - if (!isRegistered) { - lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) - } -} - -/** - * Loads a previously serialised pipeline. - * - * All functions to be loaded must already be registered with lunr.Pipeline. - * If any function from the serialised data has not been registered then an - * error will be thrown. - * - * @param {Object} serialised The serialised pipeline to load. - * @returns {lunr.Pipeline} - * @memberOf Pipeline - */ -lunr.Pipeline.load = function (serialised) { - var pipeline = new lunr.Pipeline - - serialised.forEach(function (fnName) { - var fn = lunr.Pipeline.registeredFunctions[fnName] - - if (fn) { - pipeline.add(fn) - } else { - throw new Error('Cannot load un-registered function: ' + fnName) - } - }) - - return pipeline -} - -/** - * Adds new functions to the end of the pipeline. - * - * Logs a warning if the function has not been registered. - * - * @param {Function} functions Any number of functions to add to the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.add = function () { - var fns = Array.prototype.slice.call(arguments) - - fns.forEach(function (fn) { - lunr.Pipeline.warnIfFunctionNotRegistered(fn) - this._stack.push(fn) - }, this) -} - -/** - * Adds a single function after a function that already exists in the - * pipeline. - * - * Logs a warning if the function has not been registered. - * - * @param {Function} existingFn A function that already exists in the pipeline. - * @param {Function} newFn The new function to add to the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.after = function (existingFn, newFn) { - lunr.Pipeline.warnIfFunctionNotRegistered(newFn) - - var pos = this._stack.indexOf(existingFn) - if (pos == -1) { - throw new Error('Cannot find existingFn') - } - - pos = pos + 1 - this._stack.splice(pos, 0, newFn) -} - -/** - * Adds a single function before a function that already exists in the - * pipeline. - * - * Logs a warning if the function has not been registered. - * - * @param {Function} existingFn A function that already exists in the pipeline. - * @param {Function} newFn The new function to add to the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.before = function (existingFn, newFn) { - lunr.Pipeline.warnIfFunctionNotRegistered(newFn) - - var pos = this._stack.indexOf(existingFn) - if (pos == -1) { - throw new Error('Cannot find existingFn') - } - - this._stack.splice(pos, 0, newFn) -} - -/** - * Removes a function from the pipeline. - * - * @param {Function} fn The function to remove from the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.remove = function (fn) { - var pos = this._stack.indexOf(fn) - if (pos == -1) { - return - } - - this._stack.splice(pos, 1) -} - -/** - * Runs the current list of functions that make up the pipeline against the - * passed tokens. - * - * @param {Array} tokens The tokens to run through the pipeline. - * @returns {Array} - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.run = function (tokens) { - var out = [], - tokenLength = tokens.length, - stackLength = this._stack.length - - for (var i = 0; i < tokenLength; i++) { - var token = tokens[i] - - for (var j = 0; j < stackLength; j++) { - token = this._stack[j](token, i, tokens) - if (token === void 0) break - }; - - if (token !== void 0) out.push(token) - }; - - return out -} - -/** - * Resets the pipeline by removing any existing processors. - * - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.reset = function () { - this._stack = [] -} - -/** - * Returns a representation of the pipeline ready for serialisation. - * - * Logs a warning if the function has not been registered. - * - * @returns {Array} - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.toJSON = function () { - return this._stack.map(function (fn) { - lunr.Pipeline.warnIfFunctionNotRegistered(fn) - - return fn.label - }) -} -/*! - * lunr.Vector - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.Vectors implement vector related operations for - * a series of elements. - * - * @constructor - */ -lunr.Vector = function () { - this._magnitude = null - this.list = undefined - this.length = 0 -} - -/** - * lunr.Vector.Node is a simple struct for each node - * in a lunr.Vector. - * - * @private - * @param {Number} The index of the node in the vector. - * @param {Object} The data at this node in the vector. - * @param {lunr.Vector.Node} The node directly after this node in the vector. - * @constructor - * @memberOf Vector - */ -lunr.Vector.Node = function (idx, val, next) { - this.idx = idx - this.val = val - this.next = next -} - -/** - * Inserts a new value at a position in a vector. - * - * @param {Number} The index at which to insert a value. - * @param {Object} The object to insert in the vector. - * @memberOf Vector. - */ -lunr.Vector.prototype.insert = function (idx, val) { - this._magnitude = undefined; - var list = this.list - - if (!list) { - this.list = new lunr.Vector.Node (idx, val, list) - return this.length++ - } - - if (idx < list.idx) { - this.list = new lunr.Vector.Node (idx, val, list) - return this.length++ - } - - var prev = list, - next = list.next - - while (next != undefined) { - if (idx < next.idx) { - prev.next = new lunr.Vector.Node (idx, val, next) - return this.length++ - } - - prev = next, next = next.next - } - - prev.next = new lunr.Vector.Node (idx, val, next) - return this.length++ -} - -/** - * Calculates the magnitude of this vector. - * - * @returns {Number} - * @memberOf Vector - */ -lunr.Vector.prototype.magnitude = function () { - if (this._magnitude) return this._magnitude - var node = this.list, - sumOfSquares = 0, - val - - while (node) { - val = node.val - sumOfSquares += val * val - node = node.next - } - - return this._magnitude = Math.sqrt(sumOfSquares) -} - -/** - * Calculates the dot product of this vector and another vector. - * - * @param {lunr.Vector} otherVector The vector to compute the dot product with. - * @returns {Number} - * @memberOf Vector - */ -lunr.Vector.prototype.dot = function (otherVector) { - var node = this.list, - otherNode = otherVector.list, - dotProduct = 0 - - while (node && otherNode) { - if (node.idx < otherNode.idx) { - node = node.next - } else if (node.idx > otherNode.idx) { - otherNode = otherNode.next - } else { - dotProduct += node.val * otherNode.val - node = node.next - otherNode = otherNode.next - } - } - - return dotProduct -} - -/** - * Calculates the cosine similarity between this vector and another - * vector. - * - * @param {lunr.Vector} otherVector The other vector to calculate the - * similarity with. - * @returns {Number} - * @memberOf Vector - */ -lunr.Vector.prototype.similarity = function (otherVector) { - return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude()) -} -/*! - * lunr.SortedSet - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.SortedSets are used to maintain an array of uniq values in a sorted - * order. - * - * @constructor - */ -lunr.SortedSet = function () { - this.length = 0 - this.elements = [] -} - -/** - * Loads a previously serialised sorted set. - * - * @param {Array} serialisedData The serialised set to load. - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.load = function (serialisedData) { - var set = new this - - set.elements = serialisedData - set.length = serialisedData.length - - return set -} - -/** - * Inserts new items into the set in the correct position to maintain the - * order. - * - * @param {Object} The objects to add to this set. - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.add = function () { - var i, element - - for (i = 0; i < arguments.length; i++) { - element = arguments[i] - if (~this.indexOf(element)) continue - this.elements.splice(this.locationFor(element), 0, element) - } - - this.length = this.elements.length -} - -/** - * Converts this sorted set into an array. - * - * @returns {Array} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.toArray = function () { - return this.elements.slice() -} - -/** - * Creates a new array with the results of calling a provided function on every - * element in this sorted set. - * - * Delegates to Array.prototype.map and has the same signature. - * - * @param {Function} fn The function that is called on each element of the - * set. - * @param {Object} ctx An optional object that can be used as the context - * for the function fn. - * @returns {Array} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.map = function (fn, ctx) { - return this.elements.map(fn, ctx) -} - -/** - * Executes a provided function once per sorted set element. - * - * Delegates to Array.prototype.forEach and has the same signature. - * - * @param {Function} fn The function that is called on each element of the - * set. - * @param {Object} ctx An optional object that can be used as the context - * @memberOf SortedSet - * for the function fn. - */ -lunr.SortedSet.prototype.forEach = function (fn, ctx) { - return this.elements.forEach(fn, ctx) -} - -/** - * Returns the index at which a given element can be found in the - * sorted set, or -1 if it is not present. - * - * @param {Object} elem The object to locate in the sorted set. - * @returns {Number} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.indexOf = function (elem) { - var start = 0, - end = this.elements.length, - sectionLength = end - start, - pivot = start + Math.floor(sectionLength / 2), - pivotElem = this.elements[pivot] - - while (sectionLength > 1) { - if (pivotElem === elem) return pivot - - if (pivotElem < elem) start = pivot - if (pivotElem > elem) end = pivot - - sectionLength = end - start - pivot = start + Math.floor(sectionLength / 2) - pivotElem = this.elements[pivot] - } - - if (pivotElem === elem) return pivot - - return -1 -} - -/** - * Returns the position within the sorted set that an element should be - * inserted at to maintain the current order of the set. - * - * This function assumes that the element to search for does not already exist - * in the sorted set. - * - * @param {Object} elem The elem to find the position for in the set - * @returns {Number} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.locationFor = function (elem) { - var start = 0, - end = this.elements.length, - sectionLength = end - start, - pivot = start + Math.floor(sectionLength / 2), - pivotElem = this.elements[pivot] - - while (sectionLength > 1) { - if (pivotElem < elem) start = pivot - if (pivotElem > elem) end = pivot - - sectionLength = end - start - pivot = start + Math.floor(sectionLength / 2) - pivotElem = this.elements[pivot] - } - - if (pivotElem > elem) return pivot - if (pivotElem < elem) return pivot + 1 -} - -/** - * Creates a new lunr.SortedSet that contains the elements in the intersection - * of this set and the passed set. - * - * @param {lunr.SortedSet} otherSet The set to intersect with this set. - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.intersect = function (otherSet) { - var intersectSet = new lunr.SortedSet, - i = 0, j = 0, - a_len = this.length, b_len = otherSet.length, - a = this.elements, b = otherSet.elements - - while (true) { - if (i > a_len - 1 || j > b_len - 1) break - - if (a[i] === b[j]) { - intersectSet.add(a[i]) - i++, j++ - continue - } - - if (a[i] < b[j]) { - i++ - continue - } - - if (a[i] > b[j]) { - j++ - continue - } - }; - - return intersectSet -} - -/** - * Makes a copy of this set - * - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.clone = function () { - var clone = new lunr.SortedSet - - clone.elements = this.toArray() - clone.length = clone.elements.length - - return clone -} - -/** - * Creates a new lunr.SortedSet that contains the elements in the union - * of this set and the passed set. - * - * @param {lunr.SortedSet} otherSet The set to union with this set. - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.union = function (otherSet) { - var longSet, shortSet, unionSet - - if (this.length >= otherSet.length) { - longSet = this, shortSet = otherSet - } else { - longSet = otherSet, shortSet = this - } - - unionSet = longSet.clone() - - unionSet.add.apply(unionSet, shortSet.toArray()) - - return unionSet -} - -/** - * Returns a representation of the sorted set ready for serialisation. - * - * @returns {Array} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.toJSON = function () { - return this.toArray() -} -/*! - * lunr.Index - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.Index is object that manages a search index. It contains the indexes - * and stores all the tokens and document lookups. It also provides the main - * user facing API for the library. - * - * @constructor - */ -lunr.Index = function () { - this._fields = [] - this._ref = 'id' - this.pipeline = new lunr.Pipeline - this.documentStore = new lunr.Store - this.tokenStore = new lunr.TokenStore - this.corpusTokens = new lunr.SortedSet - this.eventEmitter = new lunr.EventEmitter - - this._idfCache = {} - - this.on('add', 'remove', 'update', (function () { - this._idfCache = {} - }).bind(this)) -} - -/** - * Bind a handler to events being emitted by the index. - * - * The handler can be bound to many events at the same time. - * - * @param {String} [eventName] The name(s) of events to bind the function to. - * @param {Function} fn The serialised set to load. - * @memberOf Index - */ -lunr.Index.prototype.on = function () { - var args = Array.prototype.slice.call(arguments) - return this.eventEmitter.addListener.apply(this.eventEmitter, args) -} - -/** - * Removes a handler from an event being emitted by the index. - * - * @param {String} eventName The name of events to remove the function from. - * @param {Function} fn The serialised set to load. - * @memberOf Index - */ -lunr.Index.prototype.off = function (name, fn) { - return this.eventEmitter.removeListener(name, fn) -} - -/** - * Loads a previously serialised index. - * - * Issues a warning if the index being imported was serialised - * by a different version of lunr. - * - * @param {Object} serialisedData The serialised set to load. - * @returns {lunr.Index} - * @memberOf Index - */ -lunr.Index.load = function (serialisedData) { - if (serialisedData.version !== lunr.version) { - lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version) - } - - var idx = new this - - idx._fields = serialisedData.fields - idx._ref = serialisedData.ref - - idx.documentStore = lunr.Store.load(serialisedData.documentStore) - idx.tokenStore = lunr.TokenStore.load(serialisedData.tokenStore) - idx.corpusTokens = lunr.SortedSet.load(serialisedData.corpusTokens) - idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline) - - return idx -} - -/** - * Adds a field to the list of fields that will be searchable within documents - * in the index. - * - * An optional boost param can be passed to affect how much tokens in this field - * rank in search results, by default the boost value is 1. - * - * Fields should be added before any documents are added to the index, fields - * that are added after documents are added to the index will only apply to new - * documents added to the index. - * - * @param {String} fieldName The name of the field within the document that - * should be indexed - * @param {Number} boost An optional boost that can be applied to terms in this - * field. - * @returns {lunr.Index} - * @memberOf Index - */ -lunr.Index.prototype.field = function (fieldName, opts) { - var opts = opts || {}, - field = { name: fieldName, boost: opts.boost || 1 } - - this._fields.push(field) - return this -} - -/** - * Sets the property used to uniquely identify documents added to the index, - * by default this property is 'id'. - * - * This should only be changed before adding documents to the index, changing - * the ref property without resetting the index can lead to unexpected results. - * - * @param {String} refName The property to use to uniquely identify the - * documents in the index. - * @param {Boolean} emitEvent Whether to emit add events, defaults to true - * @returns {lunr.Index} - * @memberOf Index - */ -lunr.Index.prototype.ref = function (refName) { - this._ref = refName - return this -} - -/** - * Add a document to the index. - * - * This is the way new documents enter the index, this function will run the - * fields from the document through the index's pipeline and then add it to - * the index, it will then show up in search results. - * - * An 'add' event is emitted with the document that has been added and the index - * the document has been added to. This event can be silenced by passing false - * as the second argument to add. - * - * @param {Object} doc The document to add to the index. - * @param {Boolean} emitEvent Whether or not to emit events, default true. - * @memberOf Index - */ -lunr.Index.prototype.add = function (doc, emitEvent) { - var docTokens = {}, - allDocumentTokens = new lunr.SortedSet, - docRef = doc[this._ref], - emitEvent = emitEvent === undefined ? true : emitEvent - - this._fields.forEach(function (field) { - var fieldTokens = this.pipeline.run(lunr.tokenizer(doc[field.name])) - - docTokens[field.name] = fieldTokens - lunr.SortedSet.prototype.add.apply(allDocumentTokens, fieldTokens) - }, this) - - this.documentStore.set(docRef, allDocumentTokens) - lunr.SortedSet.prototype.add.apply(this.corpusTokens, allDocumentTokens.toArray()) - - for (var i = 0; i < allDocumentTokens.length; i++) { - var token = allDocumentTokens.elements[i] - var tf = this._fields.reduce(function (memo, field) { - var fieldLength = docTokens[field.name].length - - if (!fieldLength) return memo - - var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length - - return memo + (tokenCount / fieldLength * field.boost) - }, 0) - - this.tokenStore.add(token, { ref: docRef, tf: tf }) - }; - - if (emitEvent) this.eventEmitter.emit('add', doc, this) -} - -/** - * Removes a document from the index. - * - * To make sure documents no longer show up in search results they can be - * removed from the index using this method. - * - * The document passed only needs to have the same ref property value as the - * document that was added to the index, they could be completely different - * objects. - * - * A 'remove' event is emitted with the document that has been removed and the index - * the document has been removed from. This event can be silenced by passing false - * as the second argument to remove. - * - * @param {Object} doc The document to remove from the index. - * @param {Boolean} emitEvent Whether to emit remove events, defaults to true - * @memberOf Index - */ -lunr.Index.prototype.remove = function (doc, emitEvent) { - var docRef = doc[this._ref], - emitEvent = emitEvent === undefined ? true : emitEvent - - if (!this.documentStore.has(docRef)) return - - var docTokens = this.documentStore.get(docRef) - - this.documentStore.remove(docRef) - - docTokens.forEach(function (token) { - this.tokenStore.remove(token, docRef) - }, this) - - if (emitEvent) this.eventEmitter.emit('remove', doc, this) -} - -/** - * Updates a document in the index. - * - * When a document contained within the index gets updated, fields changed, - * added or removed, to make sure it correctly matched against search queries, - * it should be updated in the index. - * - * This method is just a wrapper around `remove` and `add` - * - * An 'update' event is emitted with the document that has been updated and the index. - * This event can be silenced by passing false as the second argument to update. Only - * an update event will be fired, the 'add' and 'remove' events of the underlying calls - * are silenced. - * - * @param {Object} doc The document to update in the index. - * @param {Boolean} emitEvent Whether to emit update events, defaults to true - * @see Index.prototype.remove - * @see Index.prototype.add - * @memberOf Index - */ -lunr.Index.prototype.update = function (doc, emitEvent) { - var emitEvent = emitEvent === undefined ? true : emitEvent - - this.remove(doc, false) - this.add(doc, false) - - if (emitEvent) this.eventEmitter.emit('update', doc, this) -} - -/** - * Calculates the inverse document frequency for a token within the index. - * - * @param {String} token The token to calculate the idf of. - * @see Index.prototype.idf - * @private - * @memberOf Index - */ -lunr.Index.prototype.idf = function (term) { - var cacheKey = "@" + term - if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey] - - var documentFrequency = this.tokenStore.count(term), - idf = 1 - - if (documentFrequency > 0) { - idf = 1 + Math.log(this.documentStore.length / documentFrequency) - } - - return this._idfCache[cacheKey] = idf -} - -/** - * Searches the index using the passed query. - * - * Queries should be a string, multiple words are allowed and will lead to an - * AND based query, e.g. `idx.search('foo bar')` will run a search for - * documents containing both 'foo' and 'bar'. - * - * All query tokens are passed through the same pipeline that document tokens - * are passed through, so any language processing involved will be run on every - * query term. - * - * Each query term is expanded, so that the term 'he' might be expanded to - * 'hello' and 'help' if those terms were already included in the index. - * - * Matching documents are returned as an array of objects, each object contains - * the matching document ref, as set for this index, and the similarity score - * for this document against the query. - * - * @param {String} query The query to search the index with. - * @returns {Object} - * @see Index.prototype.idf - * @see Index.prototype.documentVector - * @memberOf Index - */ -lunr.Index.prototype.search = function (query) { - var queryTokens = this.pipeline.run(lunr.tokenizer(query)), - queryVector = new lunr.Vector, - documentSets = [], - fieldBoosts = this._fields.reduce(function (memo, f) { return memo + f.boost }, 0) - - var hasSomeToken = queryTokens.some(function (token) { - return this.tokenStore.has(token) - }, this) - - if (!hasSomeToken) return [] - - queryTokens - .forEach(function (token, i, tokens) { - var tf = 1 / tokens.length * this._fields.length * fieldBoosts, - self = this - - var set = this.tokenStore.expand(token).reduce(function (memo, key) { - var pos = self.corpusTokens.indexOf(key), - idf = self.idf(key), - similarityBoost = 1, - set = new lunr.SortedSet - - // if the expanded key is not an exact match to the token then - // penalise the score for this key by how different the key is - // to the token. - if (key !== token) { - var diff = Math.max(3, key.length - token.length) - similarityBoost = 1 / Math.log(diff) - } - - // calculate the query tf-idf score for this token - // applying an similarityBoost to ensure exact matches - // these rank higher than expanded terms - if (pos > -1) queryVector.insert(pos, tf * idf * similarityBoost) - - // add all the documents that have this key into a set - Object.keys(self.tokenStore.get(key)).forEach(function (ref) { set.add(ref) }) - - return memo.union(set) - }, new lunr.SortedSet) - - documentSets.push(set) - }, this) - - var documentSet = documentSets.reduce(function (memo, set) { - return memo.intersect(set) - }) - - return documentSet - .map(function (ref) { - return { ref: ref, score: queryVector.similarity(this.documentVector(ref)) } - }, this) - .sort(function (a, b) { - return b.score - a.score - }) -} - -/** - * Generates a vector containing all the tokens in the document matching the - * passed documentRef. - * - * The vector contains the tf-idf score for each token contained in the - * document with the passed documentRef. The vector will contain an element - * for every token in the indexes corpus, if the document does not contain that - * token the element will be 0. - * - * @param {Object} documentRef The ref to find the document with. - * @returns {lunr.Vector} - * @private - * @memberOf Index - */ -lunr.Index.prototype.documentVector = function (documentRef) { - var documentTokens = this.documentStore.get(documentRef), - documentTokensLength = documentTokens.length, - documentVector = new lunr.Vector - - for (var i = 0; i < documentTokensLength; i++) { - var token = documentTokens.elements[i], - tf = this.tokenStore.get(token)[documentRef].tf, - idf = this.idf(token) - - documentVector.insert(this.corpusTokens.indexOf(token), tf * idf) - }; - - return documentVector -} - -/** - * Returns a representation of the index ready for serialisation. - * - * @returns {Object} - * @memberOf Index - */ -lunr.Index.prototype.toJSON = function () { - return { - version: lunr.version, - fields: this._fields, - ref: this._ref, - documentStore: this.documentStore.toJSON(), - tokenStore: this.tokenStore.toJSON(), - corpusTokens: this.corpusTokens.toJSON(), - pipeline: this.pipeline.toJSON() - } -} - -/** - * Applies a plugin to the current index. - * - * A plugin is a function that is called with the index as its context. - * Plugins can be used to customise or extend the behaviour the index - * in some way. A plugin is just a function, that encapsulated the custom - * behaviour that should be applied to the index. - * - * The plugin function will be called with the index as its argument, additional - * arguments can also be passed when calling use. The function will be called - * with the index as its context. - * - * Example: - * - * var myPlugin = function (idx, arg1, arg2) { - * // `this` is the index to be extended - * // apply any extensions etc here. - * } - * - * var idx = lunr(function () { - * this.use(myPlugin, 'arg1', 'arg2') - * }) - * - * @param {Function} plugin The plugin to apply. - * @memberOf Index - */ -lunr.Index.prototype.use = function (plugin) { - var args = Array.prototype.slice.call(arguments, 1) - args.unshift(this) - plugin.apply(this, args) -} -/*! - * lunr.Store - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.Store is a simple key-value store used for storing sets of tokens for - * documents stored in index. - * - * @constructor - * @module - */ -lunr.Store = function () { - this.store = {} - this.length = 0 -} - -/** - * Loads a previously serialised store - * - * @param {Object} serialisedData The serialised store to load. - * @returns {lunr.Store} - * @memberOf Store - */ -lunr.Store.load = function (serialisedData) { - var store = new this - - store.length = serialisedData.length - store.store = Object.keys(serialisedData.store).reduce(function (memo, key) { - memo[key] = lunr.SortedSet.load(serialisedData.store[key]) - return memo - }, {}) - - return store -} - -/** - * Stores the given tokens in the store against the given id. - * - * @param {Object} id The key used to store the tokens against. - * @param {Object} tokens The tokens to store against the key. - * @memberOf Store - */ -lunr.Store.prototype.set = function (id, tokens) { - if (!this.has(id)) this.length++ - this.store[id] = tokens -} - -/** - * Retrieves the tokens from the store for a given key. - * - * @param {Object} id The key to lookup and retrieve from the store. - * @returns {Object} - * @memberOf Store - */ -lunr.Store.prototype.get = function (id) { - return this.store[id] -} - -/** - * Checks whether the store contains a key. - * - * @param {Object} id The id to look up in the store. - * @returns {Boolean} - * @memberOf Store - */ -lunr.Store.prototype.has = function (id) { - return id in this.store -} - -/** - * Removes the value for a key in the store. - * - * @param {Object} id The id to remove from the store. - * @memberOf Store - */ -lunr.Store.prototype.remove = function (id) { - if (!this.has(id)) return - - delete this.store[id] - this.length-- -} - -/** - * Returns a representation of the store ready for serialisation. - * - * @returns {Object} - * @memberOf Store - */ -lunr.Store.prototype.toJSON = function () { - return { - store: this.store, - length: this.length - } -} - -/*! - * lunr.stemmer - * Copyright (C) 2015 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ - -/** - * lunr.stemmer is an english language stemmer, this is a JavaScript - * implementation of the PorterStemmer taken from http://tartarus.org/~martin - * - * @module - * @param {String} str The string to stem - * @returns {String} - * @see lunr.Pipeline - */ -lunr.stemmer = (function(){ - var step2list = { - "ational" : "ate", - "tional" : "tion", - "enci" : "ence", - "anci" : "ance", - "izer" : "ize", - "bli" : "ble", - "alli" : "al", - "entli" : "ent", - "eli" : "e", - "ousli" : "ous", - "ization" : "ize", - "ation" : "ate", - "ator" : "ate", - "alism" : "al", - "iveness" : "ive", - "fulness" : "ful", - "ousness" : "ous", - "aliti" : "al", - "iviti" : "ive", - "biliti" : "ble", - "logi" : "log" - }, - - step3list = { - "icate" : "ic", - "ative" : "", - "alize" : "al", - "iciti" : "ic", - "ical" : "ic", - "ful" : "", - "ness" : "" - }, - - c = "[^aeiou]", // consonant - v = "[aeiouy]", // vowel - C = c + "[^aeiouy]*", // consonant sequence - V = v + "[aeiou]*", // vowel sequence - - mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 - meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 - mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 - s_v = "^(" + C + ")?" + v; // vowel in stem - - var re_mgr0 = new RegExp(mgr0); - var re_mgr1 = new RegExp(mgr1); - var re_meq1 = new RegExp(meq1); - var re_s_v = new RegExp(s_v); - - var re_1a = /^(.+?)(ss|i)es$/; - var re2_1a = /^(.+?)([^s])s$/; - var re_1b = /^(.+?)eed$/; - var re2_1b = /^(.+?)(ed|ing)$/; - var re_1b_2 = /.$/; - var re2_1b_2 = /(at|bl|iz)$/; - var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$"); - var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - - var re_1c = /^(.+?[^aeiou])y$/; - var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - - var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - - var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - var re2_4 = /^(.+?)(s|t)(ion)$/; - - var re_5 = /^(.+?)e$/; - var re_5_1 = /ll$/; - var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - - var porterStemmer = function porterStemmer(w) { - var stem, - suffix, - firstch, - re, - re2, - re3, - re4; - - if (w.length < 3) { return w; } - - firstch = w.substr(0,1); - if (firstch == "y") { - w = firstch.toUpperCase() + w.substr(1); - } - - // Step 1a - re = re_1a - re2 = re2_1a; - - if (re.test(w)) { w = w.replace(re,"$1$2"); } - else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } - - // Step 1b - re = re_1b; - re2 = re2_1b; - if (re.test(w)) { - var fp = re.exec(w); - re = re_mgr0; - if (re.test(fp[1])) { - re = re_1b_2; - w = w.replace(re,""); - } - } else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = re_s_v; - if (re2.test(stem)) { - w = stem; - re2 = re2_1b_2; - re3 = re3_1b_2; - re4 = re4_1b_2; - if (re2.test(w)) { w = w + "e"; } - else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); } - else if (re4.test(w)) { w = w + "e"; } - } - } - - // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say) - re = re_1c; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - w = stem + "i"; - } - - // Step 2 - re = re_2; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = re_mgr0; - if (re.test(stem)) { - w = stem + step2list[suffix]; - } - } - - // Step 3 - re = re_3; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = re_mgr0; - if (re.test(stem)) { - w = stem + step3list[suffix]; - } - } - - // Step 4 - re = re_4; - re2 = re2_4; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = re_mgr1; - if (re.test(stem)) { - w = stem; - } - } else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = re_mgr1; - if (re2.test(stem)) { - w = stem; - } - } - - // Step 5 - re = re_5; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = re_mgr1; - re2 = re_meq1; - re3 = re3_5; - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { - w = stem; - } - } - - re = re_5_1; - re2 = re_mgr1; - if (re.test(w) && re2.test(w)) { - re = re_1b_2; - w = w.replace(re,""); - } - - // and turn initial Y back to y - - if (firstch == "y") { - w = firstch.toLowerCase() + w.substr(1); - } - - return w; - }; - - return porterStemmer; -})(); - -lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') -/*! - * lunr.stopWordFilter - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.stopWordFilter is an English language stop word list filter, any words - * contained in the list will not be passed through the filter. - * - * This is intended to be used in the Pipeline. If the token does not pass the - * filter then undefined will be returned. - * - * @module - * @param {String} token The token to pass through the filter - * @returns {String} - * @see lunr.Pipeline - */ -lunr.stopWordFilter = function (token) { - if (token && lunr.stopWordFilter.stopWords[token] !== token) return token; -} - -lunr.stopWordFilter.stopWords = { - 'a': 'a', - 'able': 'able', - 'about': 'about', - 'across': 'across', - 'after': 'after', - 'all': 'all', - 'almost': 'almost', - 'also': 'also', - 'am': 'am', - 'among': 'among', - 'an': 'an', - 'and': 'and', - 'any': 'any', - 'are': 'are', - 'as': 'as', - 'at': 'at', - 'be': 'be', - 'because': 'because', - 'been': 'been', - 'but': 'but', - 'by': 'by', - 'can': 'can', - 'cannot': 'cannot', - 'could': 'could', - 'dear': 'dear', - 'did': 'did', - 'do': 'do', - 'does': 'does', - 'either': 'either', - 'else': 'else', - 'ever': 'ever', - 'every': 'every', - 'for': 'for', - 'from': 'from', - 'get': 'get', - 'got': 'got', - 'had': 'had', - 'has': 'has', - 'have': 'have', - 'he': 'he', - 'her': 'her', - 'hers': 'hers', - 'him': 'him', - 'his': 'his', - 'how': 'how', - 'however': 'however', - 'i': 'i', - 'if': 'if', - 'in': 'in', - 'into': 'into', - 'is': 'is', - 'it': 'it', - 'its': 'its', - 'just': 'just', - 'least': 'least', - 'let': 'let', - 'like': 'like', - 'likely': 'likely', - 'may': 'may', - 'me': 'me', - 'might': 'might', - 'most': 'most', - 'must': 'must', - 'my': 'my', - 'neither': 'neither', - 'no': 'no', - 'nor': 'nor', - 'not': 'not', - 'of': 'of', - 'off': 'off', - 'often': 'often', - 'on': 'on', - 'only': 'only', - 'or': 'or', - 'other': 'other', - 'our': 'our', - 'own': 'own', - 'rather': 'rather', - 'said': 'said', - 'say': 'say', - 'says': 'says', - 'she': 'she', - 'should': 'should', - 'since': 'since', - 'so': 'so', - 'some': 'some', - 'than': 'than', - 'that': 'that', - 'the': 'the', - 'their': 'their', - 'them': 'them', - 'then': 'then', - 'there': 'there', - 'these': 'these', - 'they': 'they', - 'this': 'this', - 'tis': 'tis', - 'to': 'to', - 'too': 'too', - 'twas': 'twas', - 'us': 'us', - 'wants': 'wants', - 'was': 'was', - 'we': 'we', - 'were': 'were', - 'what': 'what', - 'when': 'when', - 'where': 'where', - 'which': 'which', - 'while': 'while', - 'who': 'who', - 'whom': 'whom', - 'why': 'why', - 'will': 'will', - 'with': 'with', - 'would': 'would', - 'yet': 'yet', - 'you': 'you', - 'your': 'your' -} - -lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') -/*! - * lunr.trimmer - * Copyright (C) 2015 Oliver Nightingale - */ - -/** - * lunr.trimmer is a pipeline function for trimming non word - * characters from the begining and end of tokens before they - * enter the index. - * - * This implementation may not work correctly for non latin - * characters and should either be removed or adapted for use - * with languages with non-latin characters. - * - * @module - * @param {String} token The token to pass through the filter - * @returns {String} - * @see lunr.Pipeline - */ -lunr.trimmer = function (token) { - var result = token.replace(/^\W+/, '') - .replace(/\W+$/, '') - return result === '' ? undefined : result -} - -lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') -/*! - * lunr.stemmer - * Copyright (C) 2015 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ - -/** - * lunr.TokenStore is used for efficient storing and lookup of the reverse - * index of token to document ref. - * - * @constructor - */ -lunr.TokenStore = function () { - this.root = { docs: {} } - this.length = 0 -} - -/** - * Loads a previously serialised token store - * - * @param {Object} serialisedData The serialised token store to load. - * @returns {lunr.TokenStore} - * @memberOf TokenStore - */ -lunr.TokenStore.load = function (serialisedData) { - var store = new this - - store.root = serialisedData.root - store.length = serialisedData.length - - return store -} - -/** - * Adds a new token doc pair to the store. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to store the doc under - * @param {Object} doc The doc to store against the token - * @param {Object} root An optional node at which to start looking for the - * correct place to enter the doc, by default the root of this lunr.TokenStore - * is used. - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.add = function (token, doc, root) { - var root = root || this.root, - key = token[0], - rest = token.slice(1) - - if (!(key in root)) root[key] = {docs: {}} - - if (rest.length === 0) { - root[key].docs[doc.ref] = doc - this.length += 1 - return - } else { - return this.add(rest, doc, root[key]) - } -} - -/** - * Checks whether this key is contained within this lunr.TokenStore. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to check for - * @param {Object} root An optional node at which to start - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.has = function (token) { - if (!token) return false - - var node = this.root - - for (var i = 0; i < token.length; i++) { - if (!node[token[i]]) return false - - node = node[token[i]] - } - - return true -} - -/** - * Retrieve a node from the token store for a given token. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to get the node for. - * @param {Object} root An optional node at which to start. - * @returns {Object} - * @see TokenStore.prototype.get - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.getNode = function (token) { - if (!token) return {} - - var node = this.root - - for (var i = 0; i < token.length; i++) { - if (!node[token[i]]) return {} - - node = node[token[i]] - } - - return node -} - -/** - * Retrieve the documents for a node for the given token. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to get the documents for. - * @param {Object} root An optional node at which to start. - * @returns {Object} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.get = function (token, root) { - return this.getNode(token, root).docs || {} -} - -lunr.TokenStore.prototype.count = function (token, root) { - return Object.keys(this.get(token, root)).length -} - -/** - * Remove the document identified by ref from the token in the store. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to get the documents for. - * @param {String} ref The ref of the document to remove from this token. - * @param {Object} root An optional node at which to start. - * @returns {Object} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.remove = function (token, ref) { - if (!token) return - var node = this.root - - for (var i = 0; i < token.length; i++) { - if (!(token[i] in node)) return - node = node[token[i]] - } - - delete node.docs[ref] -} - -/** - * Find all the possible suffixes of the passed token using tokens - * currently in the store. - * - * @param {String} token The token to expand. - * @returns {Array} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.expand = function (token, memo) { - var root = this.getNode(token), - docs = root.docs || {}, - memo = memo || [] - - if (Object.keys(docs).length) memo.push(token) - - Object.keys(root) - .forEach(function (key) { - if (key === 'docs') return - - memo.concat(this.expand(token + key, memo)) - }, this) - - return memo -} - -/** - * Returns a representation of the token store ready for serialisation. - * - * @returns {Object} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.toJSON = function () { - return { - root: this.root, - length: this.length - } -} - - - /** - * export the module via AMD, CommonJS or as a browser global - * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js - */ - ;(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(factory) - } else if (typeof exports === 'object') { - /** - * Node. Does not work with strict CommonJS, but - * only CommonJS-like enviroments that support module.exports, - * like Node. - */ - module.exports = factory() - } else { - // Browser globals (root is window) - root.lunr = factory() - } - }(this, function () { - /** - * Just return a value to define the module export. - * This example returns an object, but the module - * can return a function as the exported value. - */ - return lunr - })) -})(); - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* Hey, there's your missing semicolon, lunr.js! */ -; - -/* Truncate a string after the given number of characters */ -String.prototype.truncate = function(n) { - if (this.length > n) { - while (this[n] != ' ' && --n > 0); - return this.substring(0, n) + '…'; - } - return this; -} - -/* Wrap an HTMLElement around each element in an HTMLElement array */ -HTMLElement.prototype.wrap = function (elms) { - if (!elms.length) elms = [elms]; - for (var i = elms.length - 1; i >= 0; i--) { - var child = (i > 0) ? this.cloneNode(true) : this; - var el = elms[i]; - - /* Cache current parent and sibling */ - var parent = el.parentNode, - sibling = el.nextSibling; - - /* Wrap the element and remove it from its current parent */ - child.appendChild(el); - if (sibling) { - parent.insertBefore(child, sibling); - } else { - parent.appendChild(child); - } - } -} - -/* ---------------------------------------------------------------------------- - * Application logic - * ------------------------------------------------------------------------- */ - -/* Initialize application upon DOM ready */ -document.addEventListener('DOMContentLoaded', function() { - 'use strict'; - - /* Test for iOS */ - Modernizr.addTest('ios', function() { - return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g); - }); - - /* Test for web application context */ - Modernizr.addTest('standalone', function() { - return !!navigator.standalone; - }); - - /* Attack FastClick to mitigate 300ms delay on touch devices */ - FastClick.attach(document.body); - - /* Grab relevant elements from the DOM */ - var toggle = document.getElementById('toggle-search'), - reset = document.getElementById('reset-search'), - drawer = document.querySelector('.drawer'), - anchors = document.querySelectorAll('.anchor'), - search = document.querySelector('.search .field'), - query = document.querySelector('.query'), - meta = document.querySelector('.results .meta'); - -/* ---------------------------------------------------------------------------- - * Initialize drawer - * ------------------------------------------------------------------------- */ - - /* Automatically close drawer when anchors are clicked */ - Array.prototype.forEach.call(anchors, function(item) { - item.querySelector('a').addEventListener('click', function() { - document.getElementById('toggle-drawer').checked = false; - document.body.classList.remove('toggle-drawer'); - }); - }); - - /* Align drawer to window offset */ - var pageYOffsetLast = window.pageYOffset; - var align = function() { - var boundary = window.pageYOffset + window.innerHeight; - var clipping = Math.max(0, window.innerHeight - drawer.offsetHeight); - - /* Ensure alignment with footer if at end of document */ - if (boundary > document.body.clientHeight - (96 - clipping)) { - if (drawer.style.position != 'absolute') { - drawer.style.position = 'absolute'; - drawer.style.top = null; - drawer.style.bottom = 0; - } - - /* Pin drawer to top, if window is higher than drawer */ - } else if (drawer.offsetHeight < window.innerHeight) { - if (drawer.style.position != 'fixed') { - drawer.style.position = 'fixed'; - drawer.style.top = 0; - drawer.style.bottom = null; - } - - /* If the drawer is not pinned, check if we need to pin it */ - } else if (drawer.style.position != 'fixed') { - - /* Pin drawer to bottom of window */ - if (boundary > drawer.offsetTop + drawer.offsetHeight) { - drawer.style.position = 'fixed'; - drawer.style.top = null; - drawer.style.bottom = -96 + 'px'; - - /* Pin drawer to top of window */ - } else if (window.pageYOffset < drawer.offsetTop) { - drawer.style.position = 'fixed'; - drawer.style.top = 0; - drawer.style.bottom = null; - } - - /* If the drawer is pinned, check if we have to unpin it */ - } else { - if (window.pageYOffset > pageYOffsetLast) { - if (drawer.style.top) { - drawer.style.position = 'absolute'; - drawer.style.top = Math.max(0, pageYOffsetLast) + 'px'; - drawer.style.bottom = null; - } - } else if (drawer.style.bottom) { - drawer.style.position = 'absolute'; - drawer.style.top = (boundary - drawer.offsetHeight) + 'px'; - drawer.style.bottom = null; - } - } - - /* Update last offset (mitigiate negative offsets in Safari) */ - pageYOffsetLast = Math.max(0, window.pageYOffset); - } - - /* Check for media query events */ - var check = function() { - var main = document.querySelector('.main'); - window.removeEventListener('scroll', align); - - /* Reset drawer position when entering collapsed mode */ - if (matchMedia("only screen and (max-width: 959px)").matches) { - drawer.style.position = null; - drawer.style.top = null; - drawer.style.bottom = null; - - /* Check if the scroll handler needs to be registered */ - } else if (drawer.offsetHeight + 96 < main.offsetHeight) { - window.addEventListener('scroll', align); - align(); - } - } - - /* Register resize handler and fire once */ - if (!Modernizr.ios) { - window.addEventListener('resize', check); - check(); - } - -/* ---------------------------------------------------------------------------- - * Initialize search index - * ------------------------------------------------------------------------- */ - - /* Initialize index */ - var initialize = function() { - pegasus(base_url + '/mkdocs/search_index.json').then( - - /* Request successful, we got the index */ - function(data, xhr) { - - /* Create index */ - var index = lunr(function() { - this.field('title', { boost: 10 }); - this.field('text'); - this.ref('location'); - }); - - /* Index articles */ - var articles = {}; - data.docs.map(function(article) { - articles.location = base_url + article.location; - articles[article.location] = article; - index.add(article); - }); - - /* Register keyhandler to execute search on key up */ - query.addEventListener('keyup', function() { - var container = document.querySelector('.results .list'); - while (container.firstChild) - container.removeChild(container.firstChild); - - /* Abort, if the query is empty */ - var bar = document.querySelector('.bar.search'); - if (!query.value.length) { - while (meta.firstChild) - meta.removeChild(meta.firstChild); - - /* Restore state */ - bar.classList.remove('non-empty'); - return; - } - - /* Show reset button */ - bar.classList.add('non-empty'); - - /* Execute search */ - var results = index.search(query.value); - results.map(function(result) { - var article = articles[result.ref]; - - /* Create article container */ - var teaser = document.createElement('article'); - teaser.classList.add('result'); - - /* Create title element */ - var title = document.createElement('h1'); - title.innerHTML = article.title; - teaser.appendChild(title); - - /* Create url element */ - var url = document.createElement('span'); - url.innerHTML = window.location.host - + article.location.split('#')[0]; - teaser.appendChild(url); - - // /* Create text element */ - // var text = document.createElement('p'); - // text.innerHTML = article.text.truncate(140); - // teaser.appendChild(text); - - /* Create a link referring to the article */ - var link = document.createElement('a'); - link.href = article.location; - link.appendChild(teaser); - - /* Close search and jump to anchor when on same page */ - var parts = article.location.split('#'); - if (parts[0] == window.location.pathname) { - link.addEventListener('click', function(e) { - document.body.classList.remove('toggle-search'); - document.body.classList.remove('locked'); - toggle.checked = false; - - /* Don't catch anchors if the search doesn't cover the page */ - if (matchMedia('only screen and (min-width: 960px)').matches) - return; - - /* Prevent default to intercept scroll-to behaviour and - stop propagation, as this interferes with the link-lock in - the web application context, which opens all internal links - inside the same context */ - e.preventDefault(); - e.stopPropagation(); - - /* Scroll to chapter, if given */ - if (parts.length != 1) { - var chapter = document.getElementById(parts[1]); - if (chapter) { - - /* Scroll to chapter, but wait for 100ms to prevent flashes - on iOS. A short timeout seems to do the trick */ - setTimeout(function() { - chapter.scrollIntoView && chapter.scrollIntoView() || - window.scrollTo(0, chapter.offsetTop); - }, 100); - } - } - }); - } - - /* Add article to search results */ - container.appendChild(link); - }); - - /* Show number of search results */ - var number = document.createElement('strong'); - number.innerHTML = results.length + ' search result' - + (results.length != 1 ? 's' : ''); - - /* Update number */ - while (meta.firstChild) - meta.removeChild(meta.firstChild); - meta.appendChild(number); - }); - }, - - /* Handle error */ - function(data, xhr) { - console.error(data, xhr.status); - } - ); - - /* Remove listener, as we only have to initialize once */ - toggle.removeEventListener('click', initialize); - }; - - /* Initialize on first click */ - toggle.addEventListener('click', initialize); - -/* ---------------------------------------------------------------------------- - * Initialize search modal - * ------------------------------------------------------------------------- */ - - /* Intercept click on search mode toggle */ - var offset = 0; - toggle.addEventListener('click', function(e) { - var list = document.body.classList; - var lock = !matchMedia('only screen and (min-width: 960px)').matches; - - /* Exiting search mode */ - if (list.contains('locked')) { - list.remove('locked'); - - /* Scroll to former position, but wait for 100ms to prevent flashes - on iOS. A short timeout seems to do the trick */ - if (lock) - setTimeout(function() { - window.scrollTo(0, offset); - }, 100); - - /* Entering search mode */ - } else { - offset = window.scrollY; - - /* First timeout: scroll to top after transition, to omit flickering */ - if (lock) - setTimeout(function(){ - window.scrollTo(0, 0); - }, 400); - - /* Second timeout: Lock body after finishing transition and scrolling to - top and focus input field. Sadly, the focus event is not dispatched - on iOS Safari and there's nothing we can do about it. */ - setTimeout(function() { - - /* This additional check is necessary to handle fast subsequent clicks - on the toggle and the timeout to lock the body must be cancelled */ - if (this.checked) { - if (lock) - list.add('locked'); - setTimeout(function() { - query.focus(); - }, 200); - } - }.bind(this), 450); - } - }); - - /* Dispatch input focus on touch of search section */ - search.addEventListener('touchstart', function() { - query.focus(); - }); - - /* Exit search mode when pressing ESC */ - window.addEventListener('keyup', function(e) { - var code = e.keyCode || e.which; - if (code == 27) { - document.body.classList.remove('toggle-search'); - document.body.classList.remove('locked'); - toggle.checked = false; - } - }); - - /* Delete search results upon click on "x" */ - var empty = document.getElementById('reset-search'); - empty.addEventListener('click', function() { - var container = document.querySelector('.results .list'); - while (container.firstChild) - container.removeChild(container.firstChild); - - /* Hide search button */ - var bar = document.querySelector('.bar.search'); - bar.classList.remove('non-empty'); - - /* Reset number of search results */ - meta.innerHTML = ''; - - /* Empty search input */ - query.value = ''; - query.focus(); - }); - -/* ---------------------------------------------------------------------------- - * Initialize scroll spy - * ------------------------------------------------------------------------- */ - - /* Retrieve vertical offset of article chapters */ - var chapters = document.querySelectorAll('h2'); - chapters = Array.prototype.map.call(chapters, function(item) { - return item.offsetTop; - }); - - /* Update currently active chapter, if the new chapter is two thirds - into the viewport - account for iOS web application context */ - var visible = null; - document.addEventListener('scroll', function() { - var offset = window.scrollY + (window.innerHeight / 3), - active = chapters.length - 1; - for (var c = 0; c < active; c++) - if (offset < chapters[c + 1]) - active = c; - - /* Update anchors, if a new chapter became visible */ - if (active != visible) { - visible = active; - Array.prototype.forEach.call(anchors, function(item, index) { - var link = item.querySelector('a'); - if (index != visible || link.classList.add('current')) - link.classList.remove('current'); - }); - } - }); - -/* ---------------------------------------------------------------------------- - * Fix syntax highlighting - * ------------------------------------------------------------------------- */ - - /* Fix highlighting for function calls */ - var functions = document.querySelectorAll('.n + .p'); - Array.prototype.forEach.call(functions, function(item) { - var text = item.innerText || item.textContent; - if (text && text[0] == '(') - item.previousSibling.classList.add('f'); - }); - -/* ---------------------------------------------------------------------------- - * Progressive structure enhancement - * ------------------------------------------------------------------------- */ - - /* Wrap all data tables */ - var tables = document.querySelectorAll('table'); - Array.prototype.forEach.call(tables, function(item) { - var wrapper = document.createElement('div'); - wrapper.classList.add('data'); - wrapper.wrap(item); - }); - -/* ---------------------------------------------------------------------------- - * Fix overflow scrolling on iOS - * ------------------------------------------------------------------------- */ - - /* Force 1px scroll offset to trigger overflow scrolling */ - if (Modernizr.ios) { - var scrollable = document.querySelectorAll( - '.scrollable, .standalone .article'); - Array.prototype.forEach.call(scrollable, function(item) { - item.addEventListener('touchstart', function() { - var top = this.scrollTop; - - /* We're at the top of the container */ - if (top == 0) { - this.scrollTop = 1; - - /* We're at the bottom of the container */ - } else if (top + this.offsetHeight == this.scrollHeight) { - this.scrollTop = top - 1; - } - }); - }); - } - - /* Prevent scrolling on project, overlay and header */ - var prevented = document.querySelectorAll('.project, .overlay, .header'); - Array.prototype.forEach.call(prevented, function(item) { - item.addEventListener('touchmove', function(e) { - e.preventDefault(); - }); - }); - -/* ---------------------------------------------------------------------------- - * Fallback for browsers that don't support :checked - * ------------------------------------------------------------------------- */ - - /* Set representative class on body for active toggle */ - var toggles = document.querySelectorAll('.toggle'); - Array.prototype.forEach.call(toggles, function(item) { - item.addEventListener('click', function() { - document.body.classList.toggle(this.id); - }); - }); - -/* ---------------------------------------------------------------------------- - * Initialize GitHub star button - * ------------------------------------------------------------------------- */ - - /* Get Stars for current repository */ - pegasus('https://api.github.com/repos/' + repo_id).then( - - /* Request successful, we got the stars */ - function(data, xhr) { - var count = data.stargazers_count; - if (count > 10000) - count = (count / 1000).toFixed(0) + "k"; - else if (count > 1000) - count = (count / 1000).toFixed(1) + "k"; - - /* Set number of stars */ - var stars = document.querySelector('.repo-stars .count'); - stars.innerHTML = count; - }, - - /* Handle error */ - function(data, xhr) { - console.error(data, xhr.status); - } - ); -}); -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Taken and adapted from https://gist.github.com/kylebarrow/1042026 - * ------------------------------------------------------------------------- */ - -/* Detect standalone mode */ -if (('standalone' in window.navigator) && window.navigator.standalone) { - - /* If you want to prevent remote links in standalone web apps opening - Mobile Safari, change 'remotes' to true */ - var node, remotes = false; - - /* Bind to document */ - document.addEventListener('click', function(event) { - node = event.target; - - /* Bubble up until we hit link or top HTML element. Warning: BODY element - is not compulsory so better to stop on HTML */ - while (node.nodeName !== 'A' && node.nodeName !== 'HTML') { - node = node.parentNode; - } - if ('href' in node && node.href.indexOf('http') !== -1 && ( - node.href.indexOf(document.location.host) !== -1 || remotes)) { - event.preventDefault(); - document.location.href = node.href; - } - }, false); -} \ No newline at end of file +function pegasus(e,t){return t=new XMLHttpRequest,t.open("GET",e),e=[],t.onreadystatechange=t.then=function(n,o,i,r){if(n&&n.call&&(e=[,n,o]),4==t.readyState&&(i=e[0|t.status/200])){try{r=JSON.parse(t.responseText)}catch(s){r=null}i(r,t)}},t.send(),t}if("document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var n,o=arguments.length;for(n=0;o>n;n++)e=arguments[n],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:n.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",n="prototype",o=e.Element[n],i=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},s=Array[n].indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return s.call(e,t)},l=function(e){for(var t=r.call(e.getAttribute("class")||""),n=t?t.split(/\s+/):[],o=0,i=n.length;i>o;o++)this.push(n[o]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[n]=[],h=function(){return new l(this)};if(a[n]=Error[n],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,n=0,o=t.length,i=!1;do e=t[n]+"",-1===c(this,e)&&(this.push(e),i=!0);while(++nc;c++)a[s[c]]=i(a[s[c]],a);n&&(t.addEventListener("mouseover",this.onMouse,!0),t.addEventListener("mousedown",this.onMouse,!0),t.addEventListener("mouseup",this.onMouse,!0)),t.addEventListener("click",this.onClick,!0),t.addEventListener("touchstart",this.onTouchStart,!1),t.addEventListener("touchmove",this.onTouchMove,!1),t.addEventListener("touchend",this.onTouchEnd,!1),t.addEventListener("touchcancel",this.onTouchCancel,!1),Event.prototype.stopImmediatePropagation||(t.removeEventListener=function(e,n,o){var i=Node.prototype.removeEventListener;"click"===e?i.call(t,e,n.hijacked||n,o):i.call(t,e,n,o)},t.addEventListener=function(e,n,o){var i=Node.prototype.addEventListener;"click"===e?i.call(t,e,n.hijacked||(n.hijacked=function(e){e.propagationStopped||n(e)}),o):i.call(t,e,n,o)}),"function"==typeof t.onclick&&(r=t.onclick,t.addEventListener("click",function(e){r(e)},!1),t.onclick=null)}}var t=navigator.userAgent.indexOf("Windows Phone")>=0,n=navigator.userAgent.indexOf("Android")>0&&!t,o=/iP(ad|hone|od)/.test(navigator.userAgent)&&!t,i=o&&/OS 4_\d(_\d)?/.test(navigator.userAgent),r=o&&/OS [6-7]_\d/.test(navigator.userAgent),s=navigator.userAgent.indexOf("BB10")>0;e.prototype.needsClick=function(e){switch(e.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(e.disabled)return!0;break;case"input":if(o&&"file"===e.type||e.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(e.className)},e.prototype.needsFocus=function(e){switch(e.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!n;case"input":switch(e.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!e.disabled&&!e.readOnly;default:return/\bneedsfocus\b/.test(e.className)}},e.prototype.sendClick=function(e,t){var n,o;document.activeElement&&document.activeElement!==e&&document.activeElement.blur(),o=t.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(e),!0,!0,window,1,o.screenX,o.screenY,o.clientX,o.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,e.dispatchEvent(n)},e.prototype.determineEventType=function(e){return n&&"select"===e.tagName.toLowerCase()?"mousedown":"click"},e.prototype.focus=function(e){var t;o&&e.setSelectionRange&&0!==e.type.indexOf("date")&&"time"!==e.type&&"month"!==e.type?(t=e.value.length,e.setSelectionRange(t,t)):e.focus()},e.prototype.updateScrollParent=function(e){var t,n;if(t=e.fastClickScrollParent,!t||!t.contains(e)){n=e;do{if(n.scrollHeight>n.offsetHeight){t=n,e.fastClickScrollParent=n;break}n=n.parentElement}while(n)}t&&(t.fastClickLastScrollTop=t.scrollTop)},e.prototype.getTargetElementFromEventTarget=function(e){return e.nodeType===Node.TEXT_NODE?e.parentNode:e},e.prototype.onTouchStart=function(e){var t,n,r;if(e.targetTouches.length>1)return!0;if(t=this.getTargetElementFromEventTarget(e.target),n=e.targetTouches[0],o){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!i){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return e.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(t)}}return this.trackingClick=!0,this.trackingClickStart=e.timeStamp,this.targetElement=t,this.touchStartX=n.pageX,this.touchStartY=n.pageY,e.timeStamp-this.lastClickTimen||Math.abs(t.pageY-this.touchStartY)>n?!0:!1},e.prototype.onTouchMove=function(e){return this.trackingClick?((this.targetElement!==this.getTargetElementFromEventTarget(e.target)||this.touchHasMoved(e))&&(this.trackingClick=!1,this.targetElement=null),!0):!0},e.prototype.findControl=function(e){return void 0!==e.control?e.control:e.htmlFor?document.getElementById(e.htmlFor):e.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},e.prototype.onTouchEnd=function(e){var t,s,a,c,l,u=this.targetElement;if(!this.trackingClick)return!0;if(e.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=e.timeStamp,s=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,r&&(l=e.changedTouches[0],u=document.elementFromPoint(l.pageX-window.pageXOffset,l.pageY-window.pageYOffset)||u,u.fastClickScrollParent=this.targetElement.fastClickScrollParent),a=u.tagName.toLowerCase(),"label"===a){if(t=this.findControl(u)){if(this.focus(u),n)return!1;u=t}}else if(this.needsFocus(u))return e.timeStamp-s>100||o&&window.top!==window&&"input"===a?(this.targetElement=null,!1):(this.focus(u),this.sendClick(u,e),o&&"select"===a||(this.targetElement=null,e.preventDefault()),!1);return o&&!i&&(c=u.fastClickScrollParent,c&&c.fastClickLastScrollTop!==c.scrollTop)?!0:(this.needsClick(u)||(e.preventDefault(),this.sendClick(u,e)),!1)},e.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},e.prototype.onMouse=function(e){return this.targetElement?e.forwardedTouchEvent?!0:e.cancelable&&(!this.needsClick(this.targetElement)||this.cancelNextClick)?(e.stopImmediatePropagation?e.stopImmediatePropagation():e.propagationStopped=!0,e.stopPropagation(),e.preventDefault(),!1):!0:!0},e.prototype.onClick=function(e){var t;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===e.target.type&&0===e.detail?!0:(t=this.onMouse(e),t||(this.targetElement=null),t)},e.prototype.destroy=function(){var e=this.layer;n&&(e.removeEventListener("mouseover",this.onMouse,!0),e.removeEventListener("mousedown",this.onMouse,!0),e.removeEventListener("mouseup",this.onMouse,!0)),e.removeEventListener("click",this.onClick,!0),e.removeEventListener("touchstart",this.onTouchStart,!1),e.removeEventListener("touchmove",this.onTouchMove,!1),e.removeEventListener("touchend",this.onTouchEnd,!1),e.removeEventListener("touchcancel",this.onTouchCancel,!1)},e.notNeeded=function(e){var t,o,i,r;if("undefined"==typeof window.ontouchstart)return!0;if(o=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!n)return!0;if(t=document.querySelector("meta[name=viewport]")){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(o>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(s&&(i=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),i[1]>=10&&i[2]>=3&&(t=document.querySelector("meta[name=viewport]")))){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===e.style.msTouchAction||"manipulation"===e.style.touchAction?!0:(r=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],r>=27&&(t=document.querySelector("meta[name=viewport]"),t&&(-1!==t.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))?!0:"none"===e.style.touchAction||"manipulation"===e.style.touchAction?!0:!1)},e.attach=function(t,n){return new e(t,n)},"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return e}):"undefined"!=typeof module&&module.exports?(module.exports=e.attach,module.exports.FastClick=e):window.FastClick=e}(),function(){var e=function(t){var n=new e.Index;return n.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),t&&t.call(n,n),n};e.version="0.5.12",e.utils={},e.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),e.EventEmitter=function(){this.events={}},e.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},e.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);this.events[e].splice(n,1),this.events[e].length||delete this.events[e]}},e.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)})}},e.EventEmitter.prototype.hasHandler=function(e){return e in this.events},e.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return e.toLowerCase()}):e.toString().trim().toLowerCase().split(/[\s\-]+/):[]},e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions={},e.Pipeline.registerFunction=function(t,n){n in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+n),t.label=n,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var n=t.label&&t.label in this.registeredFunctions;n||e.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",t)},e.Pipeline.load=function(t){var n=new e.Pipeline;return t.forEach(function(t){var o=e.Pipeline.registeredFunctions[t];if(!o)throw new Error("Cannot load un-registered function: "+t);n.add(o)}),n},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(t){e.Pipeline.warnIfFunctionNotRegistered(t),this._stack.push(t)},this)},e.Pipeline.prototype.after=function(t,n){e.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(t);if(-1==o)throw new Error("Cannot find existingFn");o+=1,this._stack.splice(o,0,n)},e.Pipeline.prototype.before=function(t,n){e.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(t);if(-1==o)throw new Error("Cannot find existingFn");this._stack.splice(o,0,n)},e.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},e.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,o=this._stack.length,i=0;n>i;i++){for(var r=e[i],s=0;o>s&&(r=this._stack[s](r,i,e),void 0!==r);s++);void 0!==r&&t.push(r)}return t},e.Pipeline.prototype.reset=function(){this._stack=[]},e.Pipeline.prototype.toJSON=function(){return this._stack.map(function(t){return e.Pipeline.warnIfFunctionNotRegistered(t),t.label})},e.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},e.Vector.Node=function(e,t,n){this.idx=e,this.val=t,this.next=n},e.Vector.prototype.insert=function(t,n){this._magnitude=void 0;var o=this.list;if(!o)return this.list=new e.Vector.Node(t,n,o),this.length++;if(tn.idx?n=n.next:(o+=t.val*n.val,t=t.next,n=n.next);return o},e.Vector.prototype.similarity=function(e){return this.dot(e)/(this.magnitude()*e.magnitude())},e.SortedSet=function(){this.length=0,this.elements=[]},e.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},e.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return i;e>r&&(t=i),r>e&&(n=i),o=n-t,i=t+Math.floor(o/2),r=this.elements[i]}return r===e?i:-1},e.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,o=n-t,i=t+Math.floor(o/2),r=this.elements[i];o>1;)e>r&&(t=i),r>e&&(n=i),o=n-t,i=t+Math.floor(o/2),r=this.elements[i];return r>e?i:e>r?i+1:void 0},e.SortedSet.prototype.intersect=function(t){for(var n=new e.SortedSet,o=0,i=0,r=this.length,s=t.length,a=this.elements,c=t.elements;;){if(o>r-1||i>s-1)break;a[o]!==c[i]?a[o]c[i]&&i++:(n.add(a[o]),o++,i++)}return n},e.SortedSet.prototype.clone=function(){var t=new e.SortedSet;return t.elements=this.toArray(),t.length=t.elements.length,t},e.SortedSet.prototype.union=function(e){var t,n,o;return this.length>=e.length?(t=this,n=e):(t=e,n=this),o=t.clone(),o.add.apply(o,n.toArray()),o},e.SortedSet.prototype.toJSON=function(){return this.toArray()},e.Index=function(){this._fields=[],this._ref="id",this.pipeline=new e.Pipeline,this.documentStore=new e.Store,this.tokenStore=new e.TokenStore,this.corpusTokens=new e.SortedSet,this.eventEmitter=new e.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},e.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},e.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},e.Index.load=function(t){t.version!==e.version&&e.utils.warn("version mismatch: current "+e.version+" importing "+t.version);var n=new this;return n._fields=t.fields,n._ref=t.ref,n.documentStore=e.Store.load(t.documentStore),n.tokenStore=e.TokenStore.load(t.tokenStore),n.corpusTokens=e.SortedSet.load(t.corpusTokens),n.pipeline=e.Pipeline.load(t.pipeline),n},e.Index.prototype.field=function(e,t){var t=t||{},n={name:e,boost:t.boost||1};return this._fields.push(n),this},e.Index.prototype.ref=function(e){return this._ref=e,this},e.Index.prototype.add=function(t,n){var o={},i=new e.SortedSet,r=t[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(e.tokenizer(t[n.name]));o[n.name]=r,e.SortedSet.prototype.add.apply(i,r)},this),this.documentStore.set(r,i),e.SortedSet.prototype.add.apply(this.corpusTokens,i.toArray());for(var s=0;s0&&(o=1+Math.log(this.documentStore.length/n)),this._idfCache[t]=o},e.Index.prototype.search=function(t){var n=this.pipeline.run(e.tokenizer(t)),o=new e.Vector,i=[],r=this._fields.reduce(function(e,t){return e+t.boost},0),s=n.some(function(e){return this.tokenStore.has(e)},this);if(!s)return[];n.forEach(function(t,n,s){var a=1/s.length*this._fields.length*r,c=this,l=this.tokenStore.expand(t).reduce(function(n,i){var r=c.corpusTokens.indexOf(i),s=c.idf(i),l=1,u=new e.SortedSet;if(i!==t){var h=Math.max(3,i.length-t.length);l=1/Math.log(h)}return r>-1&&o.insert(r,a*s*l),Object.keys(c.tokenStore.get(i)).forEach(function(e){u.add(e)}),n.union(u)},new e.SortedSet);i.push(l)},this);var a=i.reduce(function(e,t){return e.intersect(t)});return a.map(function(e){return{ref:e,score:o.similarity(this.documentVector(e))}},this).sort(function(e,t){return t.score-e.score})},e.Index.prototype.documentVector=function(t){for(var n=this.documentStore.get(t),o=n.length,i=new e.Vector,r=0;o>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[t].tf,c=this.idf(s);i.insert(this.corpusTokens.indexOf(s),a*c)}return i},e.Index.prototype.toJSON=function(){return{version:e.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},e.Index.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},e.Store=function(){this.store={},this.length=0},e.Store.load=function(t){var n=new this;return n.length=t.length,n.store=Object.keys(t.store).reduce(function(n,o){return n[o]=e.SortedSet.load(t.store[o]),n},{}),n},e.Store.prototype.set=function(e,t){this.has(e)||this.length++,this.store[e]=t},e.Store.prototype.get=function(e){return this.store[e]},e.Store.prototype.has=function(e){return e in this.store},e.Store.prototype.remove=function(e){this.has(e)&&(delete this.store[e],this.length--)},e.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},e.stemmer=function(){var e={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},t={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",o="[aeiouy]",i=n+"[^aeiouy]*",r=o+"[aeiou]*",s="^("+i+")?"+r+i,a="^("+i+")?"+r+i+"("+r+")?$",c="^("+i+")?"+r+i+r+i,l="^("+i+")?"+o,u=new RegExp(s),h=new RegExp(c),d=new RegExp(a),f=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,g=/^(.+?)(ed|ing)$/,y=/.$/,w=/(at|bl|iz)$/,S=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+i+o+"[^aeiouwxy]$"),E=/^(.+?[^aeiou])y$/,x=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,b=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,T=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,C=/^(.+?)(s|t)(ion)$/,L=/^(.+?)e$/,_=/ll$/,O=new RegExp("^"+i+o+"[^aeiouwxy]$"),A=function(n){var o,i,r,s,a,c,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=g,s.test(n)){var A=s.exec(n);s=u,s.test(A[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var A=a.exec(n);o=A[1],a=f,a.test(o)&&(n=o,a=w,c=S,l=k,a.test(n)?n+="e":c.test(n)?(s=y,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=E,s.test(n)){var A=s.exec(n);o=A[1],n=o+"i"}if(s=x,s.test(n)){var A=s.exec(n);o=A[1],i=A[2],s=u,s.test(o)&&(n=o+e[i])}if(s=b,s.test(n)){var A=s.exec(n);o=A[1],i=A[2],s=u,s.test(o)&&(n=o+t[i])}if(s=T,a=C,s.test(n)){var A=s.exec(n);o=A[1],s=h,s.test(o)&&(n=o)}else if(a.test(n)){var A=a.exec(n);o=A[1]+A[2],a=h,a.test(o)&&(n=o)}if(s=L,s.test(n)){var A=s.exec(n);o=A[1],s=h,a=d,c=O,(s.test(o)||a.test(o)&&!c.test(o))&&(n=o)}return s=_,a=h,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return A}(),e.Pipeline.registerFunction(e.stemmer,"stemmer"),e.stopWordFilter=function(t){return t&&e.stopWordFilter.stopWords[t]!==t?t:void 0},e.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},e.Pipeline.registerFunction(e.stopWordFilter,"stopWordFilter"),e.trimmer=function(e){var t=e.replace(/^\W+/,"").replace(/\W+$/,"");return""===t?void 0:t},e.Pipeline.registerFunction(e.trimmer,"trimmer"),e.TokenStore=function(){this.root={docs:{}},this.length=0},e.TokenStore.load=function(e){var t=new this;return t.root=e.root,t.length=e.length,t},e.TokenStore.prototype.add=function(e,t,n){var n=n||this.root,o=e[0],i=e.slice(1);return o in n||(n[o]={docs:{}}),0===i.length?(n[o].docs[t.ref]=t,void(this.length+=1)):this.add(i,t,n[o])},e.TokenStore.prototype.has=function(e){if(!e)return!1;for(var t=this.root,n=0;ne){for(;" "!=this[e]&&--e>0;);return this.substring(0,e)+"…"}return this},HTMLElement.prototype.wrap=function(e){e.length||(e=[e]);for(var t=e.length-1;t>=0;t--){var n=t>0?this.cloneNode(!0):this,o=e[t],i=o.parentNode,r=o.nextSibling;n.appendChild(o),r?i.insertBefore(n,r):i.appendChild(n)}},document.addEventListener("DOMContentLoaded",function(){"use strict";Modernizr.addTest("ios",function(){return!!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)}),Modernizr.addTest("standalone",function(){return!!navigator.standalone}),FastClick.attach(document.body);var e=document.getElementById("toggle-search"),t=(document.getElementById("reset-search"),document.querySelector(".drawer")),n=document.querySelectorAll(".anchor"),o=document.querySelector(".search .field"),i=document.querySelector(".query"),r=document.querySelector(".results .meta");Array.prototype.forEach.call(n,function(e){e.querySelector("a").addEventListener("click",function(){document.getElementById("toggle-drawer").checked=!1,document.body.classList.remove("toggle-drawer")})});var s=window.pageYOffset,a=function(){var e=window.pageYOffset+window.innerHeight,n=Math.max(0,window.innerHeight-t.offsetHeight);e>document.body.clientHeight-(96-n)?"absolute"!=t.style.position&&(t.style.position="absolute",t.style.top=null,t.style.bottom=0):t.offsetHeightt.offsetTop+t.offsetHeight?(t.style.position="fixed",t.style.top=null,t.style.bottom="-96px"):window.pageYOffsets?t.style.top&&(t.style.position="absolute",t.style.top=Math.max(0,s)+"px",t.style.bottom=null):t.style.bottom&&(t.style.position="absolute",t.style.top=e-t.offsetHeight+"px",t.style.bottom=null),s=Math.max(0,window.pageYOffset)},c=function(){var e=document.querySelector(".main");window.removeEventListener("scroll",a),matchMedia("only screen and (max-width: 959px)").matches?(t.style.position=null,t.style.top=null,t.style.bottom=null):t.offsetHeight+96o;o++)e1e4?n=(n/1e3).toFixed(0)+"k":n>1e3&&(n=(n/1e3).toFixed(1)+"k");var o=document.querySelector(".repo-stars .count");o.innerHTML=n},function(e,t){console.error(e,t.status)})}),"standalone"in window.navigator&&window.navigator.standalone){var node,remotes=!1;document.addEventListener("click",function(e){for(node=e.target;"A"!==node.nodeName&&"HTML"!==node.nodeName;)node=node.parentNode;"href"in node&&-1!==node.href.indexOf("http")&&(-1!==node.href.indexOf(document.location.host)||remotes)&&(e.preventDefault(),document.location.href=node.href); +},!1)} \ No newline at end of file diff --git a/material/assets/javascripts/modernizr.js b/material/assets/javascripts/modernizr.js index 255e68fd9..1bc9082d4 100644 --- a/material/assets/javascripts/modernizr.js +++ b/material/assets/javascripts/modernizr.js @@ -1,2208 +1 @@ -/*! - * modernizr v3.3.0 - * Build http://modernizr.com/download?-checked-contains-csstransforms3d-fontface-json-search-svg-target-addtest-fnbind-printshiv-setclasses-testprop-dontmin - * - * Copyright (c) - * Faruk Ates - * Paul Irish - * Alex Sexton - * Ryan Seddon - * Patrick Kettner - * Stu Cox - * Richard Herrera - - * MIT License - */ - -/* - * Modernizr tests which native CSS3 and HTML5 features are available in the - * current UA and makes the results available to you in two ways: as properties on - * a global `Modernizr` object, and as classes on the `` element. This - * information allows you to progressively enhance your pages with a granular level - * of control over the experience. -*/ - -;(function(window, document, undefined){ - var tests = []; - - - /** - * - * ModernizrProto is the constructor for Modernizr - * - * @class - * @access public - */ - - var ModernizrProto = { - // The current version, dummy - _version: '3.3.0', - - // Any settings that don't work as separate modules - // can go in here as configuration. - _config: { - 'classPrefix': '', - 'enableClasses': true, - 'enableJSClass': true, - 'usePrefixes': true - }, - - // Queue of tests - _q: [], - - // Stub these for people who are listening - on: function(test, cb) { - // I don't really think people should do this, but we can - // safe guard it a bit. - // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests. - // This is in case people listen to synchronous tests. I would leave it out, - // but the code to *disallow* sync tests in the real version of this - // function is actually larger than this. - var self = this; - setTimeout(function() { - cb(self[test]); - }, 0); - }, - - addTest: function(name, fn, options) { - tests.push({name: name, fn: fn, options: options}); - }, - - addAsyncTest: function(fn) { - tests.push({name: null, fn: fn}); - } - }; - - - - // Fake some of Object.create so we can force non test results to be non "own" properties. - var Modernizr = function() {}; - Modernizr.prototype = ModernizrProto; - - // Leak modernizr globally when you `require` it rather than force it here. - // Overwrite name so constructor name is nicer :D - Modernizr = new Modernizr(); - - - - var classes = []; - - - /** - * is returns a boolean if the typeof an obj is exactly type. - * - * @access private - * @function is - * @param {*} obj - A thing we want to check the type of - * @param {string} type - A string to compare the typeof against - * @returns {boolean} - */ - - function is(obj, type) { - return typeof obj === type; - } - ; - - /** - * Run through all tests and detect their support in the current UA. - * - * @access private - */ - - function testRunner() { - var featureNames; - var feature; - var aliasIdx; - var result; - var nameIdx; - var featureName; - var featureNameSplit; - - for (var featureIdx in tests) { - if (tests.hasOwnProperty(featureIdx)) { - featureNames = []; - feature = tests[featureIdx]; - // run the test, throw the return value into the Modernizr, - // then based on that boolean, define an appropriate className - // and push it into an array of classes we'll join later. - // - // If there is no name, it's an 'async' test that is run, - // but not directly added to the object. That should - // be done with a post-run addTest call. - if (feature.name) { - featureNames.push(feature.name.toLowerCase()); - - if (feature.options && feature.options.aliases && feature.options.aliases.length) { - // Add all the aliases into the names list - for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) { - featureNames.push(feature.options.aliases[aliasIdx].toLowerCase()); - } - } - } - - // Run the test, or use the raw value if it's not a function - result = is(feature.fn, 'function') ? feature.fn() : feature.fn; - - - // Set each of the names on the Modernizr object - for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) { - featureName = featureNames[nameIdx]; - // Support dot properties as sub tests. We don't do checking to make sure - // that the implied parent tests have been added. You must call them in - // order (either in the test, or make the parent test a dependency). - // - // Cap it to TWO to make the logic simple and because who needs that kind of subtesting - // hashtag famous last words - featureNameSplit = featureName.split('.'); - - if (featureNameSplit.length === 1) { - Modernizr[featureNameSplit[0]] = result; - } else { - // cast to a Boolean, if not one already - /* jshint -W053 */ - if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { - Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); - } - - Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result; - } - - classes.push((result ? '' : 'no-') + featureNameSplit.join('-')); - } - } - } - } - ; - - /** - * docElement is a convenience wrapper to grab the root element of the document - * - * @access private - * @returns {HTMLElement|SVGElement} The root element of the document - */ - - var docElement = document.documentElement; - - - /** - * A convenience helper to check if the document we are running in is an SVG document - * - * @access private - * @returns {boolean} - */ - - var isSVG = docElement.nodeName.toLowerCase() === 'svg'; - - - /** - * setClasses takes an array of class names and adds them to the root element - * - * @access private - * @function setClasses - * @param {string[]} classes - Array of class names - */ - - // Pass in an and array of class names, e.g.: - // ['no-webp', 'borderradius', ...] - function setClasses(classes) { - var className = docElement.className; - var classPrefix = Modernizr._config.classPrefix || ''; - - if (isSVG) { - className = className.baseVal; - } - - // Change `no-js` to `js` (independently of the `enableClasses` option) - // Handle classPrefix on this too - if (Modernizr._config.enableJSClass) { - var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)'); - className = className.replace(reJS, '$1' + classPrefix + 'js$2'); - } - - if (Modernizr._config.enableClasses) { - // Add the new classes - className += ' ' + classPrefix + classes.join(' ' + classPrefix); - isSVG ? docElement.className.baseVal = className : docElement.className = className; - } - - } - - ; - - /** - * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support - * - * @author kangax - * @access private - * @function hasOwnProp - * @param {object} object - The object to check for a property - * @param {string} property - The property to check for - * @returns {boolean} - */ - - // hasOwnProperty shim by kangax needed for Safari 2.0 support - var hasOwnProp; - - (function() { - var _hasOwnProperty = ({}).hasOwnProperty; - /* istanbul ignore else */ - /* we have no way of testing IE 5.5 or safari 2, - * so just assume the else gets hit */ - if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) { - hasOwnProp = function(object, property) { - return _hasOwnProperty.call(object, property); - }; - } - else { - hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ - return ((property in object) && is(object.constructor.prototype[property], 'undefined')); - }; - } - })(); - - - - - // _l tracks listeners for async tests, as well as tests that execute after the initial run - ModernizrProto._l = {}; - - /** - * Modernizr.on is a way to listen for the completion of async tests. Being - * asynchronous, they may not finish before your scripts run. As a result you - * will get a possibly false negative `undefined` value. - * - * @memberof Modernizr - * @name Modernizr.on - * @access public - * @function on - * @param {string} feature - String name of the feature detect - * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not - * @example - * - * ```js - * Modernizr.on('flash', function( result ) { - * if (result) { - * // the browser has flash - * } else { - * // the browser does not have flash - * } - * }); - * ``` - */ - - ModernizrProto.on = function(feature, cb) { - // Create the list of listeners if it doesn't exist - if (!this._l[feature]) { - this._l[feature] = []; - } - - // Push this test on to the listener list - this._l[feature].push(cb); - - // If it's already been resolved, trigger it on next tick - if (Modernizr.hasOwnProperty(feature)) { - // Next Tick - setTimeout(function() { - Modernizr._trigger(feature, Modernizr[feature]); - }, 0); - } - }; - - /** - * _trigger is the private function used to signal test completion and run any - * callbacks registered through [Modernizr.on](#modernizr-on) - * - * @memberof Modernizr - * @name Modernizr._trigger - * @access private - * @function _trigger - * @param {string} feature - string name of the feature detect - * @param {function|boolean} [res] - A feature detection function, or the boolean = - * result of a feature detection function - */ - - ModernizrProto._trigger = function(feature, res) { - if (!this._l[feature]) { - return; - } - - var cbs = this._l[feature]; - - // Force async - setTimeout(function() { - var i, cb; - for (i = 0; i < cbs.length; i++) { - cb = cbs[i]; - cb(res); - } - }, 0); - - // Don't trigger these again - delete this._l[feature]; - }; - - /** - * addTest allows you to define your own feature detects that are not currently - * included in Modernizr (under the covers it's the exact same code Modernizr - * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result - * will be added onto the Modernizr object, as well as an appropriate className set on - * the html element when configured to do so - * - * @memberof Modernizr - * @name Modernizr.addTest - * @optionName Modernizr.addTest() - * @optionProp addTest - * @access public - * @function addTest - * @param {string|object} feature - The string name of the feature detect, or an - * object of feature detect names and test - * @param {function|boolean} test - Function returning true if feature is supported, - * false if not. Otherwise a boolean representing the results of a feature detection - * @example - * - * The most common way of creating your own feature detects is by calling - * `Modernizr.addTest` with a string (preferably just lowercase, without any - * punctuation), and a function you want executed that will return a boolean result - * - * ```js - * Modernizr.addTest('itsTuesday', function() { - * var d = new Date(); - * return d.getDay() === 2; - * }); - * ``` - * - * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday, - * and to `false` every other day of the week. One thing to notice is that the names of - * feature detect functions are always lowercased when added to the Modernizr object. That - * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will. - * - * - * Since we only look at the returned value from any feature detection function, - * you do not need to actually use a function. For simple detections, just passing - * in a statement that will return a boolean value works just fine. - * - * ```js - * Modernizr.addTest('hasJquery', 'jQuery' in window); - * ``` - * - * Just like before, when the above runs `Modernizr.hasjquery` will be true if - * jQuery has been included on the page. Not using a function saves a small amount - * of overhead for the browser, as well as making your code much more readable. - * - * Finally, you also have the ability to pass in an object of feature names and - * their tests. This is handy if you want to add multiple detections in one go. - * The keys should always be a string, and the value can be either a boolean or - * function that returns a boolean. - * - * ```js - * var detects = { - * 'hasjquery': 'jQuery' in window, - * 'itstuesday': function() { - * var d = new Date(); - * return d.getDay() === 2; - * } - * } - * - * Modernizr.addTest(detects); - * ``` - * - * There is really no difference between the first methods and this one, it is - * just a convenience to let you write more readable code. - */ - - function addTest(feature, test) { - - if (typeof feature == 'object') { - for (var key in feature) { - if (hasOwnProp(feature, key)) { - addTest(key, feature[ key ]); - } - } - } else { - - feature = feature.toLowerCase(); - var featureNameSplit = feature.split('.'); - var last = Modernizr[featureNameSplit[0]]; - - // Again, we don't check for parent test existence. Get that right, though. - if (featureNameSplit.length == 2) { - last = last[featureNameSplit[1]]; - } - - if (typeof last != 'undefined') { - // we're going to quit if you're trying to overwrite an existing test - // if we were to allow it, we'd do this: - // var re = new RegExp("\\b(no-)?" + feature + "\\b"); - // docElement.className = docElement.className.replace( re, '' ); - // but, no rly, stuff 'em. - return Modernizr; - } - - test = typeof test == 'function' ? test() : test; - - // Set the value (this is the magic, right here). - if (featureNameSplit.length == 1) { - Modernizr[featureNameSplit[0]] = test; - } else { - // cast to a Boolean, if not one already - /* jshint -W053 */ - if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { - Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); - } - - Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test; - } - - // Set a single class (either `feature` or `no-feature`) - /* jshint -W041 */ - setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]); - /* jshint +W041 */ - - // Trigger the event - Modernizr._trigger(feature, test); - } - - return Modernizr; // allow chaining. - } - - // After all the tests are run, add self to the Modernizr prototype - Modernizr._q.push(function() { - ModernizrProto.addTest = addTest; - }); - - - - - /** - * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill. - * - * @access private - * @function fnBind - * @param {function} fn - a function you want to change `this` reference to - * @param {object} that - the `this` you want to call the function with - * @returns {function} The wrapped version of the supplied function - */ - - function fnBind(fn, that) { - return function() { - return fn.apply(that, arguments); - }; - } - - ; - -/** - * @optionName html5printshiv - * @optionProp html5printshiv - */ - - // Take the html5 variable out of the html5shiv scope so we can return it. - var html5; - if (!isSVG) { - - /** - * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed - */ - ;(function(window, document) { - /*jshint evil:true */ - /** version */ - var version = '3.7.3'; - - /** Preset options */ - var options = window.html5 || {}; - - /** Used to skip problem elements */ - var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; - - /** Not all elements can be cloned in IE **/ - var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; - - /** Detect whether the browser supports default html5 styles */ - var supportsHtml5Styles; - - /** Name of the expando, to work with multiple documents or to re-shiv one document */ - var expando = '_html5shiv'; - - /** The id for the the documents expando */ - var expanID = 0; - - /** Cached data for each document */ - var expandoData = {}; - - /** Detect whether the browser supports unknown elements */ - var supportsUnknownElements; - - (function() { - try { - var a = document.createElement('a'); - a.innerHTML = ''; - //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles - supportsHtml5Styles = ('hidden' in a); - - supportsUnknownElements = a.childNodes.length == 1 || (function() { - // assign a false positive if unable to shiv - (document.createElement)('a'); - var frag = document.createDocumentFragment(); - return ( - typeof frag.cloneNode == 'undefined' || - typeof frag.createDocumentFragment == 'undefined' || - typeof frag.createElement == 'undefined' - ); - }()); - } catch(e) { - // assign a false positive if detection fails => unable to shiv - supportsHtml5Styles = true; - supportsUnknownElements = true; - } - - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a style sheet with the given CSS text and adds it to the document. - * @private - * @param {Document} ownerDocument The document. - * @param {String} cssText The CSS text. - * @returns {StyleSheet} The style element. - */ - function addStyleSheet(ownerDocument, cssText) { - var p = ownerDocument.createElement('p'), - parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; - - p.innerHTML = 'x'; - return parent.insertBefore(p.lastChild, parent.firstChild); - } - - /** - * Returns the value of `html5.elements` as an array. - * @private - * @returns {Array} An array of shived element node names. - */ - function getElements() { - var elements = html5.elements; - return typeof elements == 'string' ? elements.split(' ') : elements; - } - - /** - * Extends the built-in list of html5 elements - * @memberOf html5 - * @param {String|Array} newElements whitespace separated list or array of new element names to shiv - * @param {Document} ownerDocument The context document. - */ - function addElements(newElements, ownerDocument) { - var elements = html5.elements; - if(typeof elements != 'string'){ - elements = elements.join(' '); - } - if(typeof newElements != 'string'){ - newElements = newElements.join(' '); - } - html5.elements = elements +' '+ newElements; - shivDocument(ownerDocument); - } - - /** - * Returns the data associated to the given document - * @private - * @param {Document} ownerDocument The document. - * @returns {Object} An object of data. - */ - function getExpandoData(ownerDocument) { - var data = expandoData[ownerDocument[expando]]; - if (!data) { - data = {}; - expanID++; - ownerDocument[expando] = expanID; - expandoData[expanID] = data; - } - return data; - } - - /** - * returns a shived element for the given nodeName and document - * @memberOf html5 - * @param {String} nodeName name of the element - * @param {Document} ownerDocument The context document. - * @returns {Object} The shived element. - */ - function createElement(nodeName, ownerDocument, data){ - if (!ownerDocument) { - ownerDocument = document; - } - if(supportsUnknownElements){ - return ownerDocument.createElement(nodeName); - } - if (!data) { - data = getExpandoData(ownerDocument); - } - var node; - - if (data.cache[nodeName]) { - node = data.cache[nodeName].cloneNode(); - } else if (saveClones.test(nodeName)) { - node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); - } else { - node = data.createElem(nodeName); - } - - // Avoid adding some elements to fragments in IE < 9 because - // * Attributes like `name` or `type` cannot be set/changed once an element - // is inserted into a document/fragment - // * Link elements with `src` attributes that are inaccessible, as with - // a 403 response, will cause the tab/window to crash - // * Script elements appended to fragments will execute when their `src` - // or `text` property is set - return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; - } - - /** - * returns a shived DocumentFragment for the given document - * @memberOf html5 - * @param {Document} ownerDocument The context document. - * @returns {Object} The shived DocumentFragment. - */ - function createDocumentFragment(ownerDocument, data){ - if (!ownerDocument) { - ownerDocument = document; - } - if(supportsUnknownElements){ - return ownerDocument.createDocumentFragment(); - } - data = data || getExpandoData(ownerDocument); - var clone = data.frag.cloneNode(), - i = 0, - elems = getElements(), - l = elems.length; - for(;i+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'), - replacement = '$1' + shivNamespace + '\\:$2'; - - while (index--) { - pair = parts[index] = parts[index].split('}'); - pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement); - parts[index] = pair.join('}'); - } - return parts.join('{'); - } - - /** - * Removes the given wrappers, leaving the original elements. - * @private - * @params {Array} wrappers An array of printable wrappers. - */ - function removeWrappers(wrappers) { - var index = wrappers.length; - while (index--) { - wrappers[index].removeNode(); - } - } - - /*--------------------------------------------------------------------------*/ - - /** - * Shivs the given document for print. - * @memberOf html5 - * @param {Document} ownerDocument The document to shiv. - * @returns {Document} The shived document. - */ - function shivPrint(ownerDocument) { - var shivedSheet, - wrappers, - data = getExpandoData(ownerDocument), - namespaces = ownerDocument.namespaces, - ownerWindow = ownerDocument.parentWindow; - - if (!supportsShivableSheets || ownerDocument.printShived) { - return ownerDocument; - } - if (typeof namespaces[shivNamespace] == 'undefined') { - namespaces.add(shivNamespace); - } - - function removeSheet() { - clearTimeout(data._removeSheetTimer); - if (shivedSheet) { - shivedSheet.removeNode(true); - } - shivedSheet= null; - } - - ownerWindow.attachEvent('onbeforeprint', function() { - - removeSheet(); - - var imports, - length, - sheet, - collection = ownerDocument.styleSheets, - cssText = [], - index = collection.length, - sheets = Array(index); - - // convert styleSheets collection to an array - while (index--) { - sheets[index] = collection[index]; - } - // concat all style sheet CSS text - while ((sheet = sheets.pop())) { - // IE does not enforce a same origin policy for external style sheets... - // but has trouble with some dynamically created stylesheets - if (!sheet.disabled && reMedia.test(sheet.media)) { - - try { - imports = sheet.imports; - length = imports.length; - } catch(er){ - length = 0; - } - - for (index = 0; index < length; index++) { - sheets.push(imports[index]); - } - - try { - cssText.push(sheet.cssText); - } catch(er){} - } - } - - // wrap all HTML5 elements with printable elements and add the shived style sheet - cssText = shivCssText(cssText.reverse().join('')); - wrappers = addWrappers(ownerDocument); - shivedSheet = addStyleSheet(ownerDocument, cssText); - - }); - - ownerWindow.attachEvent('onafterprint', function() { - // remove wrappers, leaving the original elements, and remove the shived style sheet - removeWrappers(wrappers); - clearTimeout(data._removeSheetTimer); - data._removeSheetTimer = setTimeout(removeSheet, 500); - }); - - ownerDocument.printShived = true; - return ownerDocument; - } - - /*--------------------------------------------------------------------------*/ - - // expose API - html5.type += ' print'; - html5.shivPrint = shivPrint; - - // shiv for print - shivPrint(document); - - if(typeof module == 'object' && module.exports){ - module.exports = html5; - } - - }(typeof window !== "undefined" ? window : this, document)); - } - - ; - - - /** - * contains checks to see if a string contains another string - * - * @access private - * @function contains - * @param {string} str - The string we want to check for substrings - * @param {string} substr - The substring we want to search the first string for - * @returns {boolean} - */ - - function contains(str, substr) { - return !!~('' + str).indexOf(substr); - } - - ; - - /** - * createElement is a convenience wrapper around document.createElement. Since we - * use createElement all over the place, this allows for (slightly) smaller code - * as well as abstracting away issues with creating elements in contexts other than - * HTML documents (e.g. SVG documents). - * - * @access private - * @function createElement - * @returns {HTMLElement|SVGElement} An HTML or SVG element - */ - - function createElement() { - if (typeof document.createElement !== 'function') { - // This is the case in IE7, where the type of createElement is "object". - // For this reason, we cannot call apply() as Object is not a Function. - return document.createElement(arguments[0]); - } else if (isSVG) { - return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]); - } else { - return document.createElement.apply(document, arguments); - } - } - - ; - - /** - * Create our "modernizr" element that we do most feature tests on. - * - * @access private - */ - - var modElem = { - elem: createElement('modernizr') - }; - - // Clean up this element - Modernizr._q.push(function() { - delete modElem.elem; - }); - - - - var mStyle = { - style: modElem.elem.style - }; - - // kill ref for gc, must happen before mod.elem is removed, so we unshift on to - // the front of the queue. - Modernizr._q.unshift(function() { - delete mStyle.style; - }); - - - - /** - * getBody returns the body of a document, or an element that can stand in for - * the body if a real body does not exist - * - * @access private - * @function getBody - * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an - * artificially created element that stands in for the body - */ - - function getBody() { - // After page load injecting a fake body doesn't work so check if body exists - var body = document.body; - - if (!body) { - // Can't use the real body create a fake one. - body = createElement(isSVG ? 'svg' : 'body'); - body.fake = true; - } - - return body; - } - - ; - - /** - * injectElementWithStyles injects an element with style element and some CSS rules - * - * @access private - * @function injectElementWithStyles - * @param {string} rule - String representing a css rule - * @param {function} callback - A function that is used to test the injected element - * @param {number} [nodes] - An integer representing the number of additional nodes you want injected - * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes - * @returns {boolean} - */ - - function injectElementWithStyles(rule, callback, nodes, testnames) { - var mod = 'modernizr'; - var style; - var ret; - var node; - var docOverflow; - var div = createElement('div'); - var body = getBody(); - - if (parseInt(nodes, 10)) { - // In order not to give false positives we create a node for each test - // This also allows the method to scale for unspecified uses - while (nodes--) { - node = createElement('div'); - node.id = testnames ? testnames[nodes] : mod + (nodes + 1); - div.appendChild(node); - } - } - - style = createElement('style'); - style.type = 'text/css'; - style.id = 's' + mod; - - // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. - // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 - (!body.fake ? div : body).appendChild(style); - body.appendChild(div); - - if (style.styleSheet) { - style.styleSheet.cssText = rule; - } else { - style.appendChild(document.createTextNode(rule)); - } - div.id = mod; - - if (body.fake) { - //avoid crashing IE8, if background image is used - body.style.background = ''; - //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible - body.style.overflow = 'hidden'; - docOverflow = docElement.style.overflow; - docElement.style.overflow = 'hidden'; - docElement.appendChild(body); - } - - ret = callback(div, rule); - // If this is done after page load we don't want to remove the body so check if body exists - if (body.fake) { - body.parentNode.removeChild(body); - docElement.style.overflow = docOverflow; - // Trigger layout so kinetic scrolling isn't disabled in iOS6+ - docElement.offsetHeight; - } else { - div.parentNode.removeChild(div); - } - - return !!ret; - - } - - ; - - /** - * domToCSS takes a camelCase string and converts it to kebab-case - * e.g. boxSizing -> box-sizing - * - * @access private - * @function domToCSS - * @param {string} name - String name of camelCase prop we want to convert - * @returns {string} The kebab-case version of the supplied name - */ - - function domToCSS(name) { - return name.replace(/([A-Z])/g, function(str, m1) { - return '-' + m1.toLowerCase(); - }).replace(/^ms-/, '-ms-'); - } - ; - - /** - * nativeTestProps allows for us to use native feature detection functionality if available. - * some prefixed form, or false, in the case of an unsupported rule - * - * @access private - * @function nativeTestProps - * @param {array} props - An array of property names - * @param {string} value - A string representing the value we want to check via @supports - * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise - */ - - // Accepts a list of property names and a single value - // Returns `undefined` if native detection not available - function nativeTestProps(props, value) { - var i = props.length; - // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface - if ('CSS' in window && 'supports' in window.CSS) { - // Try every prefixed variant of the property - while (i--) { - if (window.CSS.supports(domToCSS(props[i]), value)) { - return true; - } - } - return false; - } - // Otherwise fall back to at-rule (for Opera 12.x) - else if ('CSSSupportsRule' in window) { - // Build a condition string for every prefixed variant - var conditionText = []; - while (i--) { - conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')'); - } - conditionText = conditionText.join(' or '); - return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) { - return getComputedStyle(node, null).position == 'absolute'; - }); - } - return undefined; - } - ; - - /** - * cssToDOM takes a kebab-case string and converts it to camelCase - * e.g. box-sizing -> boxSizing - * - * @access private - * @function cssToDOM - * @param {string} name - String name of kebab-case prop we want to convert - * @returns {string} The camelCase version of the supplied name - */ - - function cssToDOM(name) { - return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) { - return m1 + m2.toUpperCase(); - }).replace(/^-/, ''); - } - ; - - // testProps is a generic CSS / DOM property test. - - // In testing support for a given CSS property, it's legit to test: - // `elem.style[styleName] !== undefined` - // If the property is supported it will return an empty string, - // if unsupported it will return undefined. - - // We'll take advantage of this quick test and skip setting a style - // on our modernizr element, but instead just testing undefined vs - // empty string. - - // Property names can be provided in either camelCase or kebab-case. - - function testProps(props, prefixed, value, skipValueTest) { - skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest; - - // Try native detect first - if (!is(value, 'undefined')) { - var result = nativeTestProps(props, value); - if (!is(result, 'undefined')) { - return result; - } - } - - // Otherwise do it properly - var afterInit, i, propsLength, prop, before; - - // If we don't have a style element, that means we're running async or after - // the core tests, so we'll need to create our own elements to use - - // inside of an SVG element, in certain browsers, the `style` element is only - // defined for valid tags. Therefore, if `modernizr` does not have one, we - // fall back to a less used element and hope for the best. - var elems = ['modernizr', 'tspan']; - while (!mStyle.style) { - afterInit = true; - mStyle.modElem = createElement(elems.shift()); - mStyle.style = mStyle.modElem.style; - } - - // Delete the objects if we created them. - function cleanElems() { - if (afterInit) { - delete mStyle.style; - delete mStyle.modElem; - } - } - - propsLength = props.length; - for (i = 0; i < propsLength; i++) { - prop = props[i]; - before = mStyle.style[prop]; - - if (contains(prop, '-')) { - prop = cssToDOM(prop); - } - - if (mStyle.style[prop] !== undefined) { - - // If value to test has been passed in, do a set-and-check test. - // 0 (integer) is a valid property value, so check that `value` isn't - // undefined, rather than just checking it's truthy. - if (!skipValueTest && !is(value, 'undefined')) { - - // Needs a try catch block because of old IE. This is slow, but will - // be avoided in most cases because `skipValueTest` will be used. - try { - mStyle.style[prop] = value; - } catch (e) {} - - // If the property value has changed, we assume the value used is - // supported. If `value` is empty string, it'll fail here (because - // it hasn't changed), which matches how browsers have implemented - // CSS.supports() - if (mStyle.style[prop] != before) { - cleanElems(); - return prefixed == 'pfx' ? prop : true; - } - } - // Otherwise just return true, or the property name if this is a - // `prefixed()` call - else { - cleanElems(); - return prefixed == 'pfx' ? prop : true; - } - } - } - cleanElems(); - return false; - } - - ; - - /** - * testProp() investigates whether a given style property is recognized - * Property names can be provided in either camelCase or kebab-case. - * - * @memberof Modernizr - * @name Modernizr.testProp - * @access public - * @optionName Modernizr.testProp() - * @optionProp testProp - * @function testProp - * @param {string} prop - Name of the CSS property to check - * @param {string} [value] - Name of the CSS value to check - * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported - * @returns {boolean} - * @example - * - * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed - * version of the string. - * - * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing) - * - * ```js - * Modernizr.testProp('pointerEvents') // true - * ``` - * - * You can also provide a value as an optional second argument to check if a - * specific value is supported - * - * ```js - * Modernizr.testProp('pointerEvents', 'none') // true - * Modernizr.testProp('pointerEvents', 'penguin') // false - * ``` - */ - - var testProp = ModernizrProto.testProp = function(prop, value, useValue) { - return testProps([prop], undefined, value, useValue); - }; - - - /** - * Modernizr.hasEvent() detects support for a given event - * - * @memberof Modernizr - * @name Modernizr.hasEvent - * @optionName Modernizr.hasEvent() - * @optionProp hasEvent - * @access public - * @function hasEvent - * @param {string|*} eventName - the name of an event to test for (e.g. "resize") - * @param {Element|string} [element=HTMLDivElement] - is the element|document|window|tagName to test on - * @returns {boolean} - * @example - * `Modernizr.hasEvent` lets you determine if the browser supports a supplied event. - * By default, it does this detection on a div element - * - * ```js - * hasEvent('blur') // true; - * ``` - * - * However, you are able to give an object as a second argument to hasEvent to - * detect an event on something other than a div. - * - * ```js - * hasEvent('devicelight', window) // true; - * ``` - * - */ - - var hasEvent = (function() { - - // Detect whether event support can be detected via `in`. Test on a DOM element - // using the "blur" event b/c it should always exist. bit.ly/event-detection - var needsFallback = !('onblur' in document.documentElement); - - function inner(eventName, element) { - - var isSupported; - if (!eventName) { return false; } - if (!element || typeof element === 'string') { - element = createElement(element || 'div'); - } - - // Testing via the `in` operator is sufficient for modern browsers and IE. - // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and - // "resize", whereas `in` "catches" those. - eventName = 'on' + eventName; - isSupported = eventName in element; - - // Fallback technique for old Firefox - bit.ly/event-detection - if (!isSupported && needsFallback) { - if (!element.setAttribute) { - // Switch to generic element if it lacks `setAttribute`. - // It could be the `document`, `window`, or something else. - element = createElement('div'); - } - - element.setAttribute(eventName, ''); - isSupported = typeof element[eventName] === 'function'; - - if (element[eventName] !== undefined) { - // If property was created, "remove it" by setting value to `undefined`. - element[eventName] = undefined; - } - element.removeAttribute(eventName); - } - - return isSupported; - } - return inner; - })(); - - - ModernizrProto.hasEvent = hasEvent; - -/*! -{ - "name": "input[search] search event", - "property": "search", - "tags": ["input","search"], - "authors": ["Calvin Webster"], - "notes": [{ - "name": "Wufoo demo", - "href": "http://www.wufoo.com/html5/types/5-search.html?" - }, { - "name": "CSS Tricks", - "href": "http://css-tricks.com/webkit-html5-search-inputs/" - }] -} -!*/ -/* DOC -There is a custom `search` event implemented in webkit browsers when using an `input[search]` element. -*/ - - Modernizr.addTest('inputsearchevent', hasEvent('search')); - -/*! -{ - "name": "SVG", - "property": "svg", - "caniuse": "svg", - "tags": ["svg"], - "authors": ["Erik Dahlstrom"], - "polyfills": [ - "svgweb", - "raphael", - "amplesdk", - "canvg", - "svg-boilerplate", - "sie", - "dojogfx", - "fabricjs" - ] -} -!*/ -/* DOC -Detects support for SVG in `` or `` elements. -*/ - - Modernizr.addTest('svg', !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect); - - - /** - * testStyles injects an element with style element and some CSS rules - * - * @memberof Modernizr - * @name Modernizr.testStyles - * @optionName Modernizr.testStyles() - * @optionProp testStyles - * @access public - * @function testStyles - * @param {string} rule - String representing a css rule - * @param {function} callback - A function that is used to test the injected element - * @param {number} [nodes] - An integer representing the number of additional nodes you want injected - * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes - * @returns {boolean} - * @example - * - * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page - * along with (possibly multiple) DOM elements. This lets you check for features - * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules). - * - * ```js - * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) { - * // elem is the first DOM node in the page (by default #modernizr) - * // rule is the first argument you supplied - the CSS rule in string form - * - * addTest('widthworks', elem.style.width === '9px') - * }); - * ``` - * - * If your test requires multiple nodes, you can include a third argument - * indicating how many additional div elements to include on the page. The - * additional nodes are injected as children of the `elem` that is returned as - * the first argument to the callback. - * - * ```js - * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) { - * document.getElementById('modernizr').style.width === '1px'; // true - * document.getElementById('modernizr2').style.width === '2px'; // true - * elem.firstChild === document.getElementById('modernizr2'); // true - * }, 1); - * ``` - * - * By default, all of the additional elements have an ID of `modernizr[n]`, where - * `n` is its index (e.g. the first additional, second overall is `#modernizr2`, - * the second additional is `#modernizr3`, etc.). - * If you want to have more meaningful IDs for your function, you can provide - * them as the fourth argument, as an array of strings - * - * ```js - * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) { - * elem.firstChild === document.getElementById('foo'); // true - * elem.lastChild === document.getElementById('bar'); // true - * }, 2, ['foo', 'bar']); - * ``` - * - */ - - var testStyles = ModernizrProto.testStyles = injectElementWithStyles; - -/*! -{ - "name": "@font-face", - "property": "fontface", - "authors": ["Diego Perini", "Mat Marquis"], - "tags": ["css"], - "knownBugs": [ - "False Positive: WebOS http://github.com/Modernizr/Modernizr/issues/342", - "False Postive: WP7 http://github.com/Modernizr/Modernizr/issues/538" - ], - "notes": [{ - "name": "@font-face detection routine by Diego Perini", - "href": "http://javascript.nwbox.com/CSSSupport/" - },{ - "name": "Filament Group @font-face compatibility research", - "href": "https://docs.google.com/presentation/d/1n4NyG4uPRjAA8zn_pSQ_Ket0RhcWC6QlZ6LMjKeECo0/edit#slide=id.p" - },{ - "name": "Filament Grunticon/@font-face device testing results", - "href": "https://docs.google.com/spreadsheet/ccc?key=0Ag5_yGvxpINRdHFYeUJPNnZMWUZKR2ItMEpRTXZPdUE#gid=0" - },{ - "name": "CSS fonts on Android", - "href": "http://stackoverflow.com/questions/3200069/css-fonts-on-android" - },{ - "name": "@font-face and Android", - "href": "http://archivist.incutio.com/viewlist/css-discuss/115960" - }] -} -!*/ - - var blacklist = (function() { - var ua = navigator.userAgent; - var wkvers = ua.match(/applewebkit\/([0-9]+)/gi) && parseFloat(RegExp.$1); - var webos = ua.match(/w(eb)?osbrowser/gi); - var wppre8 = ua.match(/windows phone/gi) && ua.match(/iemobile\/([0-9])+/gi) && parseFloat(RegExp.$1) >= 9; - var oldandroid = wkvers < 533 && ua.match(/android/gi); - return webos || oldandroid || wppre8; - }()); - if (blacklist) { - Modernizr.addTest('fontface', false); - } else { - testStyles('@font-face {font-family:"font";src:url("https://")}', function(node, rule) { - var style = document.getElementById('smodernizr'); - var sheet = style.sheet || style.styleSheet; - var cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : ''; - var bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0; - Modernizr.addTest('fontface', bool); - }); - } -; - - /** - * If the browsers follow the spec, then they would expose vendor-specific style as: - * elem.style.WebkitBorderRadius - * instead of something like the following, which would be technically incorrect: - * elem.style.webkitBorderRadius - - * Webkit ghosts their properties in lowercase but Opera & Moz do not. - * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ - * erik.eae.net/archives/2008/03/10/21.48.10/ - - * More here: github.com/Modernizr/Modernizr/issues/issue/21 - * - * @access private - * @returns {string} The string representing the vendor-specific style properties - */ - - var omPrefixes = 'Moz O ms Webkit'; - - - var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []); - ModernizrProto._cssomPrefixes = cssomPrefixes; - - - /** - * List of JavaScript DOM values used for tests - * - * @memberof Modernizr - * @name Modernizr._domPrefixes - * @optionName Modernizr._domPrefixes - * @optionProp domPrefixes - * @access public - * @example - * - * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather - * than kebab-case properties, all properties are their Capitalized variant - * - * ```js - * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ]; - * ``` - */ - - var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []); - ModernizrProto._domPrefixes = domPrefixes; - - - /** - * testDOMProps is a generic DOM property test; if a browser supports - * a certain property, it won't return undefined for it. - * - * @access private - * @function testDOMProps - * @param {array.} props - An array of properties to test for - * @param {object} obj - An object or Element you want to use to test the parameters again - * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check - */ - function testDOMProps(props, obj, elem) { - var item; - - for (var i in props) { - if (props[i] in obj) { - - // return the property name as a string - if (elem === false) { - return props[i]; - } - - item = obj[props[i]]; - - // let's bind a function - if (is(item, 'function')) { - // bind to obj unless overriden - return fnBind(item, elem || obj); - } - - // return the unbound function or obj or value - return item; - } - } - return false; - } - - ; - - /** - * testPropsAll tests a list of DOM properties we want to check against. - * We specify literally ALL possible (known and/or likely) properties on - * the element including the non-vendor prefixed one, for forward- - * compatibility. - * - * @access private - * @function testPropsAll - * @param {string} prop - A string of the property to test for - * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip - * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against - * @param {string} [value] - A string of a css value - * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set - */ - function testPropsAll(prop, prefixed, elem, value, skipValueTest) { - - var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), - props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); - - // did they call .prefixed('boxSizing') or are we just testing a prop? - if (is(prefixed, 'string') || is(prefixed, 'undefined')) { - return testProps(props, prefixed, value, skipValueTest); - - // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) - } else { - props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); - return testDOMProps(props, prefixed, elem); - } - } - - // Modernizr.testAllProps() investigates whether a given style property, - // or any of its vendor-prefixed variants, is recognized - // - // Note that the property names must be provided in the camelCase variant. - // Modernizr.testAllProps('boxSizing') - ModernizrProto.testAllProps = testPropsAll; - - - - /** - * testAllProps determines whether a given CSS property is supported in the browser - * - * @memberof Modernizr - * @name Modernizr.testAllProps - * @optionName Modernizr.testAllProps() - * @optionProp testAllProps - * @access public - * @function testAllProps - * @param {string} prop - String naming the property to test (either camelCase or kebab-case) - * @param {string} [value] - String of the value to test - * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection - * @example - * - * testAllProps determines whether a given CSS property, in some prefixed form, - * is supported by the browser. - * - * ```js - * testAllProps('boxSizing') // true - * ``` - * - * It can optionally be given a CSS value in string form to test if a property - * value is valid - * - * ```js - * testAllProps('display', 'block') // true - * testAllProps('display', 'penguin') // false - * ``` - * - * A boolean can be passed as a third parameter to skip the value check when - * native detection (@supports) isn't available. - * - * ```js - * testAllProps('shapeOutside', 'content-box', true); - * ``` - */ - - function testAllProps(prop, value, skipValueTest) { - return testPropsAll(prop, undefined, undefined, value, skipValueTest); - } - ModernizrProto.testAllProps = testAllProps; - -/*! -{ - "name": "CSS Supports", - "property": "supports", - "caniuse": "css-featurequeries", - "tags": ["css"], - "builderAliases": ["css_supports"], - "notes": [{ - "name": "W3 Spec", - "href": "http://dev.w3.org/csswg/css3-conditional/#at-supports" - },{ - "name": "Related Github Issue", - "href": "github.com/Modernizr/Modernizr/issues/648" - },{ - "name": "W3 Info", - "href": "http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface" - }] -} -!*/ - - var newSyntax = 'CSS' in window && 'supports' in window.CSS; - var oldSyntax = 'supportsCSS' in window; - Modernizr.addTest('supports', newSyntax || oldSyntax); - -/*! -{ - "name": "CSS Transforms 3D", - "property": "csstransforms3d", - "caniuse": "transforms3d", - "tags": ["css"], - "warnings": [ - "Chrome may occassionally fail this test on some systems; more info: https://code.google.com/p/chromium/issues/detail?id=129004" - ] -} -!*/ - - Modernizr.addTest('csstransforms3d', function() { - var ret = !!testAllProps('perspective', '1px', true); - var usePrefix = Modernizr._config.usePrefixes; - - // Webkit's 3D transforms are passed off to the browser's own graphics renderer. - // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in - // some conditions. As a result, Webkit typically recognizes the syntax but - // will sometimes throw a false positive, thus we must do a more thorough check: - if (ret && (!usePrefix || 'webkitPerspective' in docElement.style)) { - var mq; - var defaultStyle = '#modernizr{width:0;height:0}'; - // Use CSS Conditional Rules if available - if (Modernizr.supports) { - mq = '@supports (perspective: 1px)'; - } else { - // Otherwise, Webkit allows this media query to succeed only if the feature is enabled. - // `@media (transform-3d),(-webkit-transform-3d){ ... }` - mq = '@media (transform-3d)'; - if (usePrefix) { - mq += ',(-webkit-transform-3d)'; - } - } - - mq += '{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}'; - - testStyles(defaultStyle + mq, function(elem) { - ret = elem.offsetWidth === 7 && elem.offsetHeight === 18; - }); - } - - return ret; - }); - -/*! -{ - "name": "JSON", - "property": "json", - "caniuse": "json", - "notes": [{ - "name": "MDN documentation", - "href": "http://developer.mozilla.org/en/JSON" - }], - "polyfills": ["json2"] -} -!*/ -/* DOC -Detects native support for JSON handling functions. -*/ - - // this will also succeed if you've loaded the JSON2.js polyfill ahead of time - // ... but that should be obvious. :) - - Modernizr.addTest('json', 'JSON' in window && 'parse' in JSON && 'stringify' in JSON); - -/*! -{ - "name": "CSS :checked pseudo-selector", - "caniuse": "css-sel3", - "property": "checked", - "tags": ["css"], - "notes": [{ - "name": "Related Github Issue", - "href": "https://github.com/Modernizr/Modernizr/pull/879" - }] -} -!*/ - - Modernizr.addTest('checked', function() { - return testStyles('#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}', function(elem) { - var cb = createElement('input'); - cb.setAttribute('type', 'checkbox'); - cb.setAttribute('checked', 'checked'); - elem.appendChild(cb); - return cb.offsetLeft === 20; - }); - }); - -/*! -{ - "name": "CSS :target pseudo-class", - "caniuse": "css-sel3", - "property": "target", - "tags": ["css"], - "notes": [{ - "name": "MDN documentation", - "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/:target" - }], - "authors": ["@zachleat"], - "warnings": ["Opera Mini supports :target but doesn't update the hash for anchor links."] -} -!*/ -/* DOC -Detects support for the ':target' CSS pseudo-class. -*/ - - // querySelector - Modernizr.addTest('target', function() { - var doc = window.document; - if (!('querySelectorAll' in doc)) { - return false; - } - - try { - doc.querySelectorAll(':target'); - return true; - } catch (e) { - return false; - } - }); - -/*! -{ - "name": "ES5 String.prototype.contains", - "property": "contains", - "authors": ["Robert Kowalski"], - "tags": ["es6"] -} -!*/ -/* DOC -Check if browser implements ECMAScript 6 `String.prototype.contains` per specification. -*/ - - Modernizr.addTest('contains', is(String.prototype.contains, 'function')); - - - // Run each test - testRunner(); - - // Remove the "no-js" class if it exists - setClasses(classes); - - delete ModernizrProto.addTest; - delete ModernizrProto.addAsyncTest; - - // Run the things that are supposed to run after the tests - for (var i = 0; i < Modernizr._q.length; i++) { - Modernizr._q[i](); - } - - // Leak Modernizr namespace - window.Modernizr = Modernizr; - - -; - -})(window, document); -/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ -/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ -(function(w) { - "use strict"; - w.matchMedia = w.matchMedia || function(doc, undefined) { - var bool, docElem = doc.documentElement, refNode = docElem.firstElementChild || docElem.firstChild, fakeBody = doc.createElement("body"), div = doc.createElement("div"); - div.id = "mq-test-1"; - div.style.cssText = "position:absolute;top:-100em"; - fakeBody.style.background = "none"; - fakeBody.appendChild(div); - return function(q) { - div.innerHTML = '­'; - docElem.insertBefore(fakeBody, refNode); - bool = div.offsetWidth === 42; - docElem.removeChild(fakeBody); - return { - matches: bool, - media: q - }; - }; - }(w.document); -})(this); - -/*! Respond.js v1.4.0: min/max-width media query polyfill. (c) Scott Jehl. MIT Lic. j.mp/respondjs */ -(function(w) { - "use strict"; - var respond = {}; - w.respond = respond; - respond.update = function() {}; - var requestQueue = [], xmlHttp = function() { - var xmlhttpmethod = false; - try { - xmlhttpmethod = new w.XMLHttpRequest(); - } catch (e) { - xmlhttpmethod = new w.ActiveXObject("Microsoft.XMLHTTP"); - } - return function() { - return xmlhttpmethod; - }; - }(), ajax = function(url, callback) { - var req = xmlHttp(); - if (!req) { - return; - } - req.open("GET", url, true); - req.onreadystatechange = function() { - if (req.readyState !== 4 || req.status !== 200 && req.status !== 304) { - return; - } - callback(req.responseText); - }; - if (req.readyState === 4) { - return; - } - req.send(null); - }; - respond.ajax = ajax; - respond.queue = requestQueue; - respond.regex = { - media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi, - keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi, - urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, - findStyles: /@media *([^\{]+)\{([\S\s]+?)$/, - only: /(only\s+)?([a-zA-Z]+)\s?/, - minw: /\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/, - maxw: /\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ - }; - respond.mediaQueriesSupported = w.matchMedia && w.matchMedia("only all") !== null && w.matchMedia("only all").matches; - if (respond.mediaQueriesSupported) { - return; - } - var doc = w.document, docElem = doc.documentElement, mediastyles = [], rules = [], appendedEls = [], parsedSheets = {}, resizeThrottle = 30, head = doc.getElementsByTagName("head")[0] || docElem, base = doc.getElementsByTagName("base")[0], links = head.getElementsByTagName("link"), lastCall, resizeDefer, eminpx, getEmValue = function() { - var ret, div = doc.createElement("div"), body = doc.body, originalHTMLFontSize = docElem.style.fontSize, originalBodyFontSize = body && body.style.fontSize, fakeUsed = false; - div.style.cssText = "position:absolute;font-size:1em;width:1em"; - if (!body) { - body = fakeUsed = doc.createElement("body"); - body.style.background = "none"; - } - docElem.style.fontSize = "100%"; - body.style.fontSize = "100%"; - body.appendChild(div); - if (fakeUsed) { - docElem.insertBefore(body, docElem.firstChild); - } - ret = div.offsetWidth; - if (fakeUsed) { - docElem.removeChild(body); - } else { - body.removeChild(div); - } - docElem.style.fontSize = originalHTMLFontSize; - if (originalBodyFontSize) { - body.style.fontSize = originalBodyFontSize; - } - ret = eminpx = parseFloat(ret); - return ret; - }, applyMedia = function(fromResize) { - var name = "clientWidth", docElemProp = docElem[name], currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[name] || docElemProp, styleBlocks = {}, lastLink = links[links.length - 1], now = new Date().getTime(); - if (fromResize && lastCall && now - lastCall < resizeThrottle) { - w.clearTimeout(resizeDefer); - resizeDefer = w.setTimeout(applyMedia, resizeThrottle); - return; - } else { - lastCall = now; - } - for (var i in mediastyles) { - if (mediastyles.hasOwnProperty(i)) { - var thisstyle = mediastyles[i], min = thisstyle.minw, max = thisstyle.maxw, minnull = min === null, maxnull = max === null, em = "em"; - if (!!min) { - min = parseFloat(min) * (min.indexOf(em) > -1 ? eminpx || getEmValue() : 1); - } - if (!!max) { - max = parseFloat(max) * (max.indexOf(em) > -1 ? eminpx || getEmValue() : 1); - } - if (!thisstyle.hasquery || (!minnull || !maxnull) && (minnull || currWidth >= min) && (maxnull || currWidth <= max)) { - if (!styleBlocks[thisstyle.media]) { - styleBlocks[thisstyle.media] = []; - } - styleBlocks[thisstyle.media].push(rules[thisstyle.rules]); - } - } - } - for (var j in appendedEls) { - if (appendedEls.hasOwnProperty(j)) { - if (appendedEls[j] && appendedEls[j].parentNode === head) { - head.removeChild(appendedEls[j]); - } - } - } - appendedEls.length = 0; - for (var k in styleBlocks) { - if (styleBlocks.hasOwnProperty(k)) { - var ss = doc.createElement("style"), css = styleBlocks[k].join("\n"); - ss.type = "text/css"; - ss.media = k; - head.insertBefore(ss, lastLink.nextSibling); - if (ss.styleSheet) { - ss.styleSheet.cssText = css; - } else { - ss.appendChild(doc.createTextNode(css)); - } - appendedEls.push(ss); - } - } - }, translate = function(styles, href, media) { - var qs = styles.replace(respond.regex.keyframes, "").match(respond.regex.media), ql = qs && qs.length || 0; - href = href.substring(0, href.lastIndexOf("/")); - var repUrls = function(css) { - return css.replace(respond.regex.urls, "$1" + href + "$2$3"); - }, useMedia = !ql && media; - if (href.length) { - href += "/"; - } - if (useMedia) { - ql = 1; - } - for (var i = 0; i < ql; i++) { - var fullq, thisq, eachq, eql; - if (useMedia) { - fullq = media; - rules.push(repUrls(styles)); - } else { - fullq = qs[i].match(respond.regex.findStyles) && RegExp.$1; - rules.push(RegExp.$2 && repUrls(RegExp.$2)); - } - eachq = fullq.split(","); - eql = eachq.length; - for (var j = 0; j < eql; j++) { - thisq = eachq[j]; - mediastyles.push({ - media: thisq.split("(")[0].match(respond.regex.only) && RegExp.$2 || "all", - rules: rules.length - 1, - hasquery: thisq.indexOf("(") > -1, - minw: thisq.match(respond.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""), - maxw: thisq.match(respond.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "") - }); - } - } - applyMedia(); - }, makeRequests = function() { - if (requestQueue.length) { - var thisRequest = requestQueue.shift(); - ajax(thisRequest.href, function(styles) { - translate(styles, thisRequest.href, thisRequest.media); - parsedSheets[thisRequest.href] = true; - w.setTimeout(function() { - makeRequests(); - }, 0); - }); - } - }, ripCSS = function() { - for (var i = 0; i < links.length; i++) { - var sheet = links[i], href = sheet.href, media = sheet.media, isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; - if (!!href && isCSS && !parsedSheets[href]) { - if (sheet.styleSheet && sheet.styleSheet.rawCssText) { - translate(sheet.styleSheet.rawCssText, href, media); - parsedSheets[href] = true; - } else { - if (!/^([a-zA-Z:]*\/\/)/.test(href) && !base || href.replace(RegExp.$1, "").split("/")[0] === w.location.host) { - if (href.substring(0, 2) === "//") { - href = w.location.protocol + href; - } - requestQueue.push({ - href: href, - media: media - }); - } - } - } - } - makeRequests(); - }; - ripCSS(); - respond.update = ripCSS; - respond.getEmValue = getEmValue; - function callMedia() { - applyMedia(true); - } - if (w.addEventListener) { - w.addEventListener("resize", callMedia, false); - } else if (w.attachEvent) { - w.attachEvent("onresize", callMedia); - } -})(this); \ No newline at end of file +!function(e,t,n){function r(e,t){return typeof e===t}function i(){var e,t,n,i,o,a,s;for(var l in x)if(x.hasOwnProperty(l)){if(e=[],t=x[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;nf;f++)if(h=e[f],g=_.style[h],l(h,"-")&&(h=m(h)),_.style[h]!==n){if(o||r(i,"undefined"))return a(),"pfx"==t?h:!0;try{_.style[h]=i}catch(y){}if(_.style[h]!=g)return a(),"pfx"==t?h:!0}return a(),!1}function g(e,t,n){var i;for(var o in e)if(e[o]in t)return n===!1?e[o]:(i=t[e[o]],r(i,"function")?s(i,n||t):i);return!1}function v(e,t,n,i,o){var a=e.charAt(0).toUpperCase()+e.slice(1),s=(e+" "+P.join(a+" ")+a).split(" ");return r(t,"string")||r(t,"undefined")?h(s,t,i,o):(s=(e+" "+R.join(a+" ")+a).split(" "),g(s,t,n))}function y(e,t,r){return v(e,n,n,t,r)}var x=[],E={_version:"3.3.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){x.push({name:e,fn:t,options:n})},addAsyncTest:function(e){x.push({name:null,fn:e})}},S=function(){};S.prototype=E,S=new S;var w,b=[],T=t.documentElement,C="svg"===T.nodeName.toLowerCase();!function(){var e={}.hasOwnProperty;w=r(e,"undefined")||r(e.call,"undefined")?function(e,t){return t in e&&r(e.constructor.prototype[t],"undefined")}:function(t,n){return e.call(t,n)}}(),E._l={},E.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),S.hasOwnProperty(e)&&setTimeout(function(){S._trigger(e,S[e])},0)},E._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e,r;for(e=0;e",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=T.elements;return"string"==typeof e?e.split(" "):e}function i(e,t){var n=T.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),T.elements=n+" "+e,u(t)}function o(e){var t=b[e[S]];return t||(t={},w++,e[S]=w,b[w]=t),t}function a(e,n,r){if(n||(n=t),g)return n.createElement(e);r||(r=o(n));var i;return i=r.cache[e]?r.cache[e].cloneNode():E.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!i.canHaveChildren||x.test(e)||i.tagUrn?i:r.frag.appendChild(i)}function s(e,n){if(e||(e=t),g)return e.createDocumentFragment();n=n||o(e);for(var i=n.frag.cloneNode(),a=0,s=r(),l=s.length;l>a;a++)i.createElement(s[a]);return i}function l(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return T.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(T,t.frag)}function u(e){e||(e=t);var r=o(e);return!T.shivCSS||h||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),g||l(e,r),e}function c(e){for(var t,n=e.getElementsByTagName("*"),i=n.length,o=RegExp("^(?:"+r().join("|")+")$","i"),a=[];i--;)t=n[i],o.test(t.nodeName)&&a.push(t.applyElement(f(t)));return a}function f(e){for(var t,n=e.attributes,r=n.length,i=e.ownerDocument.createElement(N+":"+e.nodeName);r--;)t=n[r],t.specified&&i.setAttribute(t.nodeName,t.nodeValue);return i.style.cssText=e.style.cssText,i}function d(e){for(var t,n=e.split("{"),i=n.length,o=RegExp("(^|[\\s,>+~])("+r().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),a="$1"+N+"\\:$2";i--;)t=n[i]=n[i].split("}"),t[t.length-1]=t[t.length-1].replace(o,a),n[i]=t.join("}");return n.join("{")}function p(e){for(var t=e.length;t--;)e[t].removeNode()}function m(e){function t(){clearTimeout(a._removeSheetTimer),r&&r.removeNode(!0),r=null}var r,i,a=o(e),s=e.namespaces,l=e.parentWindow;return!_||e.printShived?e:("undefined"==typeof s[N]&&s.add(N),l.attachEvent("onbeforeprint",function(){t();for(var o,a,s,l=e.styleSheets,u=[],f=l.length,p=Array(f);f--;)p[f]=l[f];for(;s=p.pop();)if(!s.disabled&&C.test(s.media)){try{o=s.imports,a=o.length}catch(m){a=0}for(f=0;a>f;f++)p.push(o[f]);try{u.push(s.cssText)}catch(m){}}u=d(u.reverse().join("")),i=c(e),r=n(e,u)}),l.attachEvent("onafterprint",function(){p(i),clearTimeout(a._removeSheetTimer),a._removeSheetTimer=setTimeout(t,500)}),e.printShived=!0,e)}var h,g,v="3.7.3",y=e.html5||{},x=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,E=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,S="_html5shiv",w=0,b={};!function(){try{var e=t.createElement("a");e.innerHTML="",h="hidden"in e,g=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){h=!0,g=!0}}();var T={elements:y.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:v,shivCSS:y.shivCSS!==!1,supportsUnknownElements:g,shivMethods:y.shivMethods!==!1,type:"default",shivDocument:u,createElement:a,createDocumentFragment:s,addElements:i};e.html5=T,u(t);var C=/^$|\b(?:all|print)\b/,N="html5shiv",_=!g&&function(){var n=t.documentElement;return!("undefined"==typeof t.namespaces||"undefined"==typeof t.parentWindow||"undefined"==typeof n.applyElement||"undefined"==typeof n.removeNode||"undefined"==typeof e.attachEvent)}();T.type+=" print",T.shivPrint=m,m(t),"object"==typeof module&&module.exports&&(module.exports=T)}("undefined"!=typeof e?e:this,t);var N={elem:u("modernizr")};S._q.push(function(){delete N.elem});var _={style:N.elem.style};S._q.unshift(function(){delete _.style});var z=(E.testProp=function(e,t,r){return h([e],n,t,r)},function(){function e(e,t){var i;return e?(t&&"string"!=typeof t||(t=u(t||"div")),e="on"+e,i=e in t,!i&&r&&(t.setAttribute||(t=u("div")),t.setAttribute(e,""),i="function"==typeof t[e],t[e]!==n&&(t[e]=n),t.removeAttribute(e)),i):!1}var r=!("onblur"in t.documentElement);return e}());E.hasEvent=z,S.addTest("inputsearchevent",z("search")),S.addTest("svg",!!t.createElementNS&&!!t.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect);var k=E.testStyles=f,$=function(){var e=navigator.userAgent,t=e.match(/applewebkit\/([0-9]+)/gi)&&parseFloat(RegExp.$1),n=e.match(/w(eb)?osbrowser/gi),r=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9,i=533>t&&e.match(/android/gi);return n||i||r}();$?S.addTest("fontface",!1):k('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),i=r.sheet||r.styleSheet,o=i?i.cssRules&&i.cssRules[0]?i.cssRules[0].cssText:i.cssText||"":"",a=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);S.addTest("fontface",a)});var j="Moz O ms Webkit",P=E._config.usePrefixes?j.split(" "):[];E._cssomPrefixes=P;var R=E._config.usePrefixes?j.toLowerCase().split(" "):[];E._domPrefixes=R,E.testAllProps=v,E.testAllProps=y;var A="CSS"in e&&"supports"in e.CSS,F="supportsCSS"in e;S.addTest("supports",A||F),S.addTest("csstransforms3d",function(){var e=!!y("perspective","1px",!0),t=S._config.usePrefixes;if(e&&(!t||"webkitPerspective"in T.style)){var n,r="#modernizr{width:0;height:0}";S.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",k(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),S.addTest("json","JSON"in e&&"parse"in JSON&&"stringify"in JSON),S.addTest("checked",function(){return k("#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}",function(e){var t=u("input");return t.setAttribute("type","checkbox"),t.setAttribute("checked","checked"),e.appendChild(t),20===t.offsetLeft})}),S.addTest("target",function(){var t=e.document;if(!("querySelectorAll"in t))return!1;try{return t.querySelectorAll(":target"),!0}catch(n){return!1}}),S.addTest("contains",r(String.prototype.contains,"function")),i(),o(b),delete E.addTest,delete E.addAsyncTest;for(var M=0;M #mq-test-1 { width: 42px; }',r.insertBefore(o,i),n=42===a.offsetWidth,r.removeChild(o),{matches:n,media:e}}}(e.document)}(this),function(e){"use strict";function t(){E(!0)}var n={};e.respond=n,n.update=function(){};var r=[],i=function(){var t=!1;try{t=new e.XMLHttpRequest}catch(n){t=new e.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}(),o=function(e,t){var n=i();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))};if(n.ajax=o,n.queue=r,n.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},n.mediaQueriesSupported=e.matchMedia&&null!==e.matchMedia("only all")&&e.matchMedia("only all").matches,!n.mediaQueriesSupported){var a,s,l,u=e.document,c=u.documentElement,f=[],d=[],p=[],m={},h=30,g=u.getElementsByTagName("head")[0]||c,v=u.getElementsByTagName("base")[0],y=g.getElementsByTagName("link"),x=function(){var e,t=u.createElement("div"),n=u.body,r=c.style.fontSize,i=n&&n.style.fontSize,o=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||(n=o=u.createElement("body"),n.style.background="none"),c.style.fontSize="100%",n.style.fontSize="100%",n.appendChild(t),o&&c.insertBefore(n,c.firstChild),e=t.offsetWidth,o?c.removeChild(n):n.removeChild(t),c.style.fontSize=r,i&&(n.style.fontSize=i),e=l=parseFloat(e)},E=function(t){var n="clientWidth",r=c[n],i="CSS1Compat"===u.compatMode&&r||u.body[n]||r,o={},m=y[y.length-1],v=(new Date).getTime();if(t&&a&&h>v-a)return e.clearTimeout(s),void(s=e.setTimeout(E,h));a=v;for(var S in f)if(f.hasOwnProperty(S)){var w=f[S],b=w.minw,T=w.maxw,C=null===b,N=null===T,_="em";b&&(b=parseFloat(b)*(b.indexOf(_)>-1?l||x():1)),T&&(T=parseFloat(T)*(T.indexOf(_)>-1?l||x():1)),w.hasquery&&(C&&N||!(C||i>=b)||!(N||T>=i))||(o[w.media]||(o[w.media]=[]),o[w.media].push(d[w.rules]))}for(var z in p)p.hasOwnProperty(z)&&p[z]&&p[z].parentNode===g&&g.removeChild(p[z]);p.length=0;for(var k in o)if(o.hasOwnProperty(k)){var $=u.createElement("style"),j=o[k].join("\n");$.type="text/css",$.media=k,g.insertBefore($,m.nextSibling),$.styleSheet?$.styleSheet.cssText=j:$.appendChild(u.createTextNode(j)),p.push($)}},S=function(e,t,r){var i=e.replace(n.regex.keyframes,"").match(n.regex.media),o=i&&i.length||0;t=t.substring(0,t.lastIndexOf("/"));var a=function(e){return e.replace(n.regex.urls,"$1"+t+"$2$3")},s=!o&&r;t.length&&(t+="/"),s&&(o=1);for(var l=0;o>l;l++){var u,c,p,m;s?(u=r,d.push(a(e))):(u=i[l].match(n.regex.findStyles)&&RegExp.$1,d.push(RegExp.$2&&a(RegExp.$2))),p=u.split(","),m=p.length;for(var h=0;m>h;h++)c=p[h],f.push({media:c.split("(")[0].match(n.regex.only)&&RegExp.$2||"all",rules:d.length-1,hasquery:c.indexOf("(")>-1,minw:c.match(n.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:c.match(n.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}E()},w=function(){if(r.length){var t=r.shift();o(t.href,function(n){S(n,t.href,t.media),m[t.href]=!0,e.setTimeout(function(){w()},0)})}},b=function(){for(var t=0;tcode,.drawer .toc li a,.repo li,.stretch .title{white-space:nowrap}html{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;font-size:62.5%;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;height:100%}*,:after,:before{box-sizing:inherit;-moz-box-sizing:inherit;-webkit-box-sizing:inherit}ul{list-style:none}table{border-collapse:collapse;border-spacing:0}td{text-align:left;font-weight:400;vertical-align:middle}button{padding:0;background:0 0;font-size:inherit}input{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}a{text-decoration:none;color:inherit;-webkit-transition:color .25s;transition:color .25s}a,button,input,label{-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-tap-highlight-color:transparent}h1,h2,h3,h4,h5,h6{font-weight:inherit}.icon,body,input{font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{color:#e84e40}pre{background:rgba(0,0,0,.05)}pre,pre code{color:rgba(0,0,0,.87)}.c,.c1,.cm,.o{color:rgba(0,0,0,.54)}.k,.kn{color:#A71D5D}.kd,.kt,.n.f{color:#0086B3}.s{color:#183691}.bp,.mi{color:#9575CD}@font-face{font-family:Icon;src:url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.eot?52m981);src:url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.eot?#iefix52m981) format("embedded-opentype"),url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.woff?52m981) format("woff"),url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.ttf?52m981) format("truetype"),url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.svg?52m981#icon) format("svg");font-weight:400;font-style:normal}.icon{speak:none;font-style:normal;font-variant:normal;text-transform:none;line-height:1}.icon-search:before{content:"\e600"}.icon-back:before{content:"\e601"}.icon-link:before{content:"\e602"}.icon-close:before{content:"\e603"}.icon-menu:before{content:"\e604"}.icon-forward:before{content:"\e605"}.icon-twitter:before{content:"\e606"}.icon-github:before{content:"\e607"}.icon-download:before{content:"\e608"}.icon-star:before{content:"\e609"}.article:after,.backdrop-paper:after,.repo a .count:before{content:" "}.overlay{-webkit-transition:opacity .25s,width 0s .25s,height 0s .25s;transition:opacity .25s,width 0s .25s,height 0s .25s}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{-webkit-transition:opacity .25s,width 0s,height 0s;transition:opacity .25s,width 0s,height 0s}.js .header{-webkit-transition:background .6s,color .6s;transition:background .6s,color .6s}.js .header:before{-webkit-transition:background .6s;transition:background .6s}.button .icon{-webkit-transition:background .25s;transition:background .25s}body{color:rgba(0,0,0,.87);position:relative;min-height:100%}.backdrop,.scrollable{position:absolute;left:0;bottom:0;right:0}@supports (-webkit-appearance:none){body{background:#e84e40}}.backdrop,.backdrop-paper:after,.ios body{background:#fff}hr{border-top:1px solid rgba(0,0,0,.12);display:block;height:1px}.backdrop-paper,.locked,.scrollable .wrapper{height:100%}.toggle-button{cursor:pointer;color:inherit}.overlay{background:rgba(0,0,0,.54);opacity:0}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{opacity:1}.header{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}.ios.standalone .header:before{background:rgba(0,0,0,.12)}.bar .path{color:rgba(255,255,255,.7)}.button .icon:active{background:rgba(255,255,255,.12)}.locked{overflow:hidden}.scrollable{top:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios .scrollable .wrapper{margin-bottom:2px}.toggle{display:none}.toggle-button{display:block}.backdrop{top:0;z-index:-1}.header,.overlay{position:fixed;top:0}.backdrop-paper{max-width:1200px;margin-left:auto;margin-right:auto}.backdrop-paper:after{display:block;height:100%;margin-left:262px}.overlay{width:0;height:0;z-index:4}.header{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;left:0;z-index:3;height:56px;padding:4px;overflow:hidden}.ios.standalone .header{position:absolute}.bar{display:table;max-width:1184px;margin-left:auto;margin-right:auto}.bar a{display:block}.no-js .bar .button-search{display:none}.bar .path .icon:before{vertical-align:-1.5px}.button{display:table-cell;vertical-align:top;width:1%}.button button{margin:0;padding:0}.button button:active:before{position:relative;top:0;left:0}.button .icon{border-radius:100%;display:inline-block;font-size:24px;padding:8px;margin:4px}.stretch{display:table;table-layout:fixed;width:100%}.header .stretch{padding:0 20px}.stretch .title{display:table-cell;overflow:hidden}.drawer .section,.no-csstransforms3d #toggle-drawer:checked~.main .drawer,.no-csstransforms3d .toggle-drawer .drawer,.project{display:block}.header .stretch .title{font-size:18px;padding:13px 0}.main{max-width:1200px;margin-left:auto;margin-right:auto}body,input{font-family:Ubuntu,'Helvetica Neue',Helvetica,Arial,sans-serif}.no-fontface body,.no-fontface input{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif}code,pre{font-family:'Ubuntu Mono','Courier New',Courier,monospace}.no-fontface code,.no-fontface pre{font-family:'Courier New',Courier,monospace}#toggle-drawer:checked~.main .drawer,.toggle-drawer .drawer{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.project{-webkit-transition:none;transition:none}.project .logo img{-webkit-transition:box-shadow .4s;transition:box-shadow .4s}.drawer .toc a.current{color:#e84e40}.drawer .toc a:focus,.drawer .toc a:hover{color:#00bfa5}.drawer .section{color:rgba(0,0,0,.54)}.ios.standalone .project:before{background:rgba(0,0,0,.12)}.project .logo img{background:#fff;border-radius:100%}.project:focus .logo img,.project:hover .logo img{box-shadow:0 7px 10px rgba(0,0,0,.3),0 10px 50px rgba(0,0,0,.12)}.repo a{-webkit-transition:box-shadow .4s,opacity .4s;transition:box-shadow .4s,opacity .4s;box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#00bfa5;color:#fff;border-radius:3px}.repo a:focus,.repo a:hover{box-shadow:0 7px 10px rgba(0,0,0,.3),0 10px 50px rgba(0,0,0,.12);opacity:.8}.drawer{width:262px;font-size:13px;line-height:1em}.ios .drawer{overflow:scroll;-webkit-overflow-scrolling:touch}.drawer .toc li a{display:block;padding:14.5px 24px;overflow:hidden;font-weight:700}.drawer .toc li.anchor a{padding:10px 24px 10px 48px;font-weight:400}.article h3,.repo a .count{font-weight:700}.drawer .section{font-size:11px;padding:14.5px 24px}.drawer .scrollable{top:104px;z-index:-1}.drawer .scrollable .wrapper{height:auto;min-height:100%}.drawer .scrollable .wrapper hr{margin:12px auto 12px 0}.drawer .scrollable .wrapper .toc{margin:12px 0}.project .banner{display:table;width:100%;height:104px;padding:20px}.project .logo{display:table-cell;width:64px;padding-right:12px}.project .logo img{display:block;width:64px;height:64px}.project .name{display:table-cell;padding-left:4px;font-size:14px;line-height:1.25em;vertical-align:middle}.repo a,.repo a .count,.repo li{display:inline-block}.project .logo+.name,.repo a{font-size:12px}.repo{margin:24px 0;text-align:center}.repo li{padding-right:12px}.repo li:last-child{padding-right:0}.repo a{padding:0 10px 0 6px;line-height:30px;height:30px}.repo a .icon{font-size:18px;vertical-align:-3px}.repo a .count{background:rgba(0,0,0,.26);color:#fff;border-radius:0 3px 3px 0;position:relative;padding:0 8px 0 4px;margin:0 -10px 0 8px;font-size:12px}.article a,.article h1,.article h2{color:#e84e40}.repo a .count:before{border-width:15px 5px 15px 0;border-color:transparent rgba(0,0,0,.26);border-style:solid;display:block;position:absolute;top:0;left:-5px}.article h1,.results .list a{border-bottom:1px solid rgba(0,0,0,.12)}.no-js .repo a .count{display:none}.drawer .section,.repo a{text-transform:uppercase;font-weight:700}.repo a .count{text-transform:none}.copyright a,pre span{-webkit-transition:color .25s;transition:color .25s}.ios.standalone .article{background:-webkit-linear-gradient(top,#fff 50%,#e84e40 50%);background:linear-gradient(to bottom,#fff 50%,#e84e40 50%);position:absolute;top:56px;right:0;bottom:0;left:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios.standalone .article .wrapper{background:-webkit-linear-gradient(top,#fff 50%,#fff 50%);background:linear-gradient(to bottom,#fff 50%,#fff 50%)}.article a:focus,.article a:hover{color:#00bfa5}.article table th{background:#ee7a70;color:#fff}.article table th:first-child{border-top-left-radius:3px}.article table th:last-child{border-top-right-radius:3px}.footer{background:#e84e40;color:#fff}.copyright{color:rgba(0,0,0,.54)}.pagination a,.pagination a:focus,.pagination a:hover{color:inherit}.pagination .direction{color:rgba(255,255,255,.7)}.admonition{background:#e6f6fe}.admonition pre{background:rgba(255,255,255,.3)}.admonition.warning{background:#fce8e9}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{color:rgba(0,0,0,.26)}.article{font-size:14px;line-height:1.7em}.article:after{display:block;clear:both}.article .wrapper{padding:116px 16px 92px}.ios.standalone .article .wrapper{position:relative;min-height:100%;padding-top:60px;margin-bottom:2px}.article h1{font-size:24px;line-height:1.333334em;padding:20px 0 42px}.article h2{font-size:20px;line-height:1.4em;padding-top:92px;margin-top:-56px}.ios.standalone .article h2{padding-top:36px;margin:0}.article h3,.article h4{font-size:14px;padding-top:76px;margin-top:-56px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article ol,.article p,.article ul{margin-top:1.5em}.article li{margin-top:.75em;margin-left:18px}.article li p{display:inline}.article ul li:before{content:"\e602";display:block;float:left;font-size:16px;width:1.2em;margin-left:-1.2em;vertical-align:-.1em}.article hr{margin-top:1.5em}.article img{max-width:100%}.article pre{padding:16px;margin:1.5em -16px 0;line-height:1.5em;overflow:auto;-webkit-overflow-scrolling:touch}.article table td,.article table th{padding:12px 16px;white-space:nowrap}.article table{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);border-radius:3px;margin:3em 0 1.5em;font-size:13px}.no-js .article table{display:inline-block;max-width:100%;overflow:auto;-webkit-overflow-scrolling:touch}.article table th{min-width:100px;font-size:12px;text-align:left}.article table td{border-top:1px solid rgba(0,0,0,.05)}.article .data{margin:1.5em -16px;padding:1.5em 0;overflow:auto;-webkit-overflow-scrolling:touch;text-align:center}.article .data table{display:inline-block;margin:0 16px;text-align:left}.footer{position:absolute;bottom:0;left:0;right:0;padding:0 4px}.copyright{margin:1.5em 0}.pagination{max-width:1184px;height:92px;padding:4px 0;margin-left:auto;margin-right:auto;overflow:hidden}.pagination a{display:block;height:100%}.pagination .next,.pagination .previous{position:relative;float:left;height:100%}.pagination .previous{width:25%}.pagination .previous .direction,.pagination .previous .stretch{display:none}.pagination .next{width:75%;text-align:right}.pagination .page{display:table;position:absolute;bottom:4px}.pagination .direction{display:block;position:absolute;bottom:40px;width:100%;font-size:15px;line-height:20px;padding:0 52px}.pagination .stretch{padding:0 4px}.pagination .stretch .title{font-size:18px;padding:11px 0 13px}.admonition{margin:20px -16px 0;padding:20px 16px}.admonition>:first-child{margin-top:0}.article h1 a{display:none}.article h4{font-weight:400;font-style:italic}.admonition-title{font-weight:700}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{float:right;margin-left:20px;font-weight:400;font-style:normal}.bar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1)}#toggle-search:checked~.header .bar,.toggle-search .bar{-webkit-transform:translate3d(0,-56px,0);transform:translate3d(0,-56px,0)}.bar.search .button-reset{-webkit-transform:scale(.5,.5);transform:scale(.5,.5);-webkit-transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1);opacity:0}.bar.search.non-empty .button-reset{-webkit-transform:scale(1,1);transform:scale(1,1);opacity:1}.results{-webkit-transition:opacity .3s .1s,width 0s .4s,height 0s .4s;transition:opacity .3s .1s,width 0s .4s,height 0s .4s}#toggle-search:checked~.main .results,.toggle-search .results{-webkit-transition:opacity .4s,width 0s,height 0s;transition:opacity .4s,width 0s,height 0s}.results .list a{-webkit-transition:background .25s;transition:background .25s}.no-csstransforms3d .bar.default{display:table}.no-csstransforms3d .bar.search{display:none;margin-top:0}.no-csstransforms3d #toggle-search:checked~.header .bar.default,.no-csstransforms3d .toggle-search .bar.default{display:none}.no-csstransforms3d #toggle-search:checked~.header .bar.search,.no-csstransforms3d .toggle-search .bar.search{display:table}.bar.search{opacity:0;margin-top:8px}.bar.search .query{background:0 0;color:rgba(0,0,0,.87);font-size:18px;padding:13px 0;margin:0;width:100%;height:48px}.result,.results .meta strong{max-width:1200px;margin-left:auto;margin-right:auto}.bar.search .query::-webkit-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .query::-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-ms-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .button .icon:active{background:rgba(0,0,0,.12)}.results{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05);background:#fff;color:rgba(0,0,0,.87);opacity:0;position:fixed;top:0;left:0;width:0;height:100%;z-index:2;overflow-y:scroll;-webkit-overflow-scrolling:touch}#toggle-search:checked~.main .results,.toggle-search .results{opacity:1;width:100%;overflow-y:visible}.result h1,.result span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.results .meta{background:#e84e40;color:#fff;font-weight:700}.results .list a:last-child{border-bottom:none}.results .list a:active{background:rgba(0,0,0,.12)}#toggle-search:checked~.header,.toggle-search .header{background:#fff;color:rgba(0,0,0,.54)}#toggle-search:checked~.header:before,.toggle-search .header:before{background:rgba(0,0,0,.54)}#toggle-search:checked~.header .bar.default,.toggle-search .header .bar.default{opacity:0}#toggle-search:checked~.header .bar.search,.toggle-search .header .bar.search{opacity:1}.bar.search .query::-ms-clear{display:none}.results .scrollable{top:56px}.results .meta strong{display:block;font-size:11px;padding:16px}.results .list a{display:block}.result{padding:12px 16px 16px}.result h1{line-height:24px}.result span{color:rgba(0,0,0,.54);font-size:12px}.no-csstransforms3d .results{display:none}.no-csstransforms3d #toggle-search:checked~.main .results,.no-csstransforms3d .toggle-search .results{display:block;overflow:auto}.meta{text-transform:uppercase;font-weight:700}@media only screen and (min-width:960px){.drawer,.drawer .scrollable{position:static}.backdrop{background:#f2f2f2}.backdrop-paper:after{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05)}.button-menu{display:none}.drawer{float:left;height:auto;margin-bottom:96px;padding-top:80px}.article{margin-left:262px}.footer{z-index:5}.copyright{margin-bottom:64px}.results{height:auto;top:64px}.results .scrollable{position:static;max-height:413px}}@media only screen and (max-width:959px){#toggle-search:checked~.main .results,.drawer,.toggle-search .results{height:100%}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{width:100%;height:100%}.drawer{-webkit-transform:translate3d(-262px,0,0);transform:translate3d(-262px,0,0);-webkit-transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1);position:fixed;z-index:5}.no-csstransforms3d .drawer{display:none}.drawer,.drawer .wrapper{background:#f2f2f2}.project{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}}@media only screen and (min-width:720px){.header{height:64px;padding:8px}.header .stretch{padding:0 16px}.header .stretch .title{font-size:20px;padding:12px 0}.project .name{margin:26px 0 0 5px}.article .wrapper{padding:128px 24px 96px}.article .data{margin:1.5em -24px}.article .data table{margin:0 24px}.article h2{padding-top:100px;margin-top:-64px}.ios.standalone .article h2{padding-top:28px;margin-top:8px}.article h3,.article h4{padding-top:84px;margin-top:-64px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article pre{padding:1.5em 24px;margin:1.5em -24px 0}.footer{padding:0 8px}.pagination{height:96px;padding:8px 0}.pagination .direction{padding:0 56px;bottom:40px}.pagination .stretch{padding:0 8px}.admonition{margin:20px -24px 0;padding:20px 24px}.bar.search .query{font-size:20px;padding:12px 0}.results .scrollable{top:64px}.results .meta strong{padding:16px 24px}.result{padding:16px 24px 20px}}@media only screen and (min-width:1200px){.header{width:100%}.drawer .scrollable .wrapper hr{width:48px}}@media only screen and (orientation:portrait){.ios.standalone .header{height:76px;padding-top:24px}.ios.standalone .header:before,.ios.standalone .project:before{content:" ";z-index:4;width:100%;height:20px;position:absolute;left:0}.ios.standalone .header:before{top:0}.ios.standalone .drawer .scrollable{top:124px}.ios.standalone .project{padding-top:20px}.ios.standalone .project:before{top:0}.ios.standalone .article{position:absolute;top:76px;right:0;bottom:0;left:0}.ios.standalone .results .scrollable{top:76px}}@media only screen and (orientation:portrait) and (min-width:720px){.ios.standalone .header{height:84px;padding-top:28px}.ios.standalone .results .scrollable{top:84px}}@media only screen and (max-width:719px){.bar .path{display:none}}@media only screen and (max-width:479px){.button-github,.button-twitter{display:none}}@media only screen and (min-width:720px) and (max-width:959px){.header .stretch{padding:0 24px}}@media only screen and (min-width:480px){.pagination .next,.pagination .previous{width:50%}.pagination .previous .direction{display:block}.pagination .previous .stretch{display:table}}@media print{.footer,.header,.project{display:none}.article pre,.article pre *{color:rgba(0,0,0,.87)!important}.article table{border-radius:none;box-shadow:none}.article table th{color:#e84e40}} \ No newline at end of file diff --git a/material/assets/stylesheets/application-9ec7095f.css b/material/assets/stylesheets/application-9ec7095f.css deleted file mode 100644 index 33da7d8fb..000000000 --- a/material/assets/stylesheets/application-9ec7095f.css +++ /dev/null @@ -1 +0,0 @@ -button,input{outline:0;border:none}.article ul li:before,.icon{font-family:Icon}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,html,i,iframe,img,ins,kbd,label,legend,li,main,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{border:0;padding:0;margin:0}.drawer .toc li a,.stretch .title{text-overflow:ellipsis;white-space:nowrap}.article p>code,.drawer .toc li a,.repo li,.stretch .title{white-space:nowrap}html{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;font-size:62.5%;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;height:100%}*,:after,:before{box-sizing:inherit;-moz-box-sizing:inherit;-webkit-box-sizing:inherit}ul{list-style:none}table{border-collapse:collapse;border-spacing:0}td{text-align:left;font-weight:400;vertical-align:middle}button{padding:0;background:0 0;font-size:inherit}input{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}a{text-decoration:none;color:inherit;-webkit-transition:color .25s;transition:color .25s}a,button,input,label{-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-tap-highlight-color:transparent}h1,h2,h3,h4,h5,h6{font-weight:inherit}.icon,body,input{font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{color:#3f51b5}pre{background:rgba(0,0,0,.05)}pre,pre code{color:rgba(0,0,0,.87)}.c,.c1,.cm,.o{color:rgba(0,0,0,.54)}.k,.kn{color:#A71D5D}.kd,.kt,.n.f{color:#0086B3}.s{color:#183691}.bp,.mi{color:#9575CD}@font-face{font-family:Icon;src:url(/assets/fonts/icon.eot?52m981);src:url(/assets/fonts/icon.eot?#iefix52m981) format("embedded-opentype"),url(/assets/fonts/icon.woff?52m981) format("woff"),url(/assets/fonts/icon.ttf?52m981) format("truetype"),url(/assets/fonts/icon.svg?52m981#icon) format("svg");font-weight:400;font-style:normal}.icon{speak:none;font-style:normal;font-variant:normal;text-transform:none;line-height:1}.icon-search:before{content:"\e600"}.icon-back:before{content:"\e601"}.icon-link:before{content:"\e602"}.icon-close:before{content:"\e603"}.icon-menu:before{content:"\e604"}.icon-forward:before{content:"\e605"}.icon-twitter:before{content:"\e606"}.icon-github:before{content:"\e607"}.icon-download:before{content:"\e608"}.icon-star:before{content:"\e609"}.article:after,.backdrop-paper:after,.repo a .count:before{content:" "}.overlay{-webkit-transition:opacity .25s,width 0s .25s,height 0s .25s;transition:opacity .25s,width 0s .25s,height 0s .25s}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{-webkit-transition:opacity .25s,width 0s,height 0s;transition:opacity .25s,width 0s,height 0s}.js .header{-webkit-transition:background .6s,color .6s;transition:background .6s,color .6s}.js .header:before{-webkit-transition:background .6s;transition:background .6s}.button .icon{-webkit-transition:background .25s;transition:background .25s}body{color:rgba(0,0,0,.87);position:relative;min-height:100%}.backdrop,.scrollable{position:absolute;left:0;bottom:0;right:0}@supports (-webkit-appearance:none){body{background:#3f51b5}}.backdrop,.backdrop-paper:after,.ios body{background:#fff}hr{border-top:1px solid rgba(0,0,0,.12);display:block;height:1px}.backdrop-paper,.locked,.scrollable .wrapper{height:100%}.toggle-button{cursor:pointer;color:inherit}.overlay{background:rgba(0,0,0,.54);opacity:0}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{opacity:1}.header{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#3f51b5;color:#fff}.ios.standalone .header:before{background:rgba(0,0,0,.12)}.bar .path{color:rgba(255,255,255,.7)}.button .icon:active{background:rgba(255,255,255,.12)}.locked{overflow:hidden}.scrollable{top:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios .scrollable .wrapper{margin-bottom:2px}.toggle{display:none}.toggle-button{display:block}.backdrop{top:0;z-index:-1}.header,.overlay{position:fixed;top:0}.backdrop-paper{max-width:1200px;margin-left:auto;margin-right:auto}.backdrop-paper:after{display:block;height:100%;margin-left:262px}.overlay{width:0;height:0;z-index:4}.header{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;left:0;z-index:3;height:56px;padding:4px;overflow:hidden}.ios.standalone .header{position:absolute}.bar{display:table;max-width:1184px;margin-left:auto;margin-right:auto}.bar a{display:block}.no-js .bar .button-search{display:none}.bar .path .icon:before{vertical-align:-1.5px}.button{display:table-cell;vertical-align:top;width:1%}.button button{margin:0;padding:0}.button button:active:before{position:relative;top:0;left:0}.button .icon{border-radius:100%;display:inline-block;font-size:24px;padding:8px;margin:4px}.stretch{display:table;table-layout:fixed;width:100%}.header .stretch{padding:0 20px}.stretch .title{display:table-cell;overflow:hidden}.drawer .section,.no-csstransforms3d #toggle-drawer:checked~.main .drawer,.no-csstransforms3d .toggle-drawer .drawer,.project{display:block}.header .stretch .title{font-size:18px;padding:13px 0}.main{max-width:1200px;margin-left:auto;margin-right:auto}body,input{font-family:Ubuntu,'Helvetica Neue',Helvetica,Arial,sans-serif}.no-fontface body,.no-fontface input{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif}code,pre{font-family:'Ubuntu Mono','Courier New',Courier,monospace}.no-fontface code,.no-fontface pre{font-family:'Courier New',Courier,monospace}#toggle-drawer:checked~.main .drawer,.toggle-drawer .drawer{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.project{-webkit-transition:none;transition:none}.project .logo img{-webkit-transition:box-shadow .4s;transition:box-shadow .4s}.drawer .toc a.current{color:#3f51b5}.drawer .toc a:focus,.drawer .toc a:hover{color:#009688}.drawer .section{color:rgba(0,0,0,.54)}.ios.standalone .project:before{background:rgba(0,0,0,.12)}.project .logo img{background:#fff;border-radius:100%}.project:focus .logo img,.project:hover .logo img{box-shadow:0 7px 10px rgba(0,0,0,.3),0 10px 50px rgba(0,0,0,.12)}.article table,.repo a{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05)}.repo a{-webkit-transition:box-shadow .4s,opacity .4s;transition:box-shadow .4s,opacity .4s;background:#009688;color:#fff;border-radius:3px}.repo a:focus,.repo a:hover{box-shadow:0 7px 10px rgba(0,0,0,.3),0 10px 50px rgba(0,0,0,.12);opacity:.8}.drawer{width:262px;font-size:13px;line-height:1em}.ios .drawer{overflow:scroll;-webkit-overflow-scrolling:touch}.drawer .toc li a{display:block;padding:14.5px 24px;overflow:hidden;font-weight:700}.drawer .toc li.anchor a{padding:10px 24px 10px 48px;font-weight:400}.article h3,.repo a .count{font-weight:700}.drawer .section{font-size:11px;padding:14.5px 24px}.drawer .scrollable{top:104px;z-index:-1}.drawer .scrollable .wrapper{height:auto;min-height:100%}.drawer .scrollable .wrapper hr{margin:12px auto 12px 0}.drawer .scrollable .wrapper .toc{margin:12px 0}.project .banner{display:table;width:100%;height:104px;padding:20px}.project .logo{display:table-cell;width:64px;padding-right:12px}.project .logo img{display:block;width:64px;height:64px}.project .name{display:table-cell;padding-left:4px;font-size:14px;line-height:1.25em;vertical-align:middle}.repo a,.repo a .count,.repo li{display:inline-block}.project .logo+.name,.repo a{font-size:12px}.repo{margin:24px 0;text-align:center}.repo li{padding-right:12px}.repo li:last-child{padding-right:0}.repo a{padding:0 10px 0 6px;line-height:30px;height:30px}.repo a .icon{font-size:18px;vertical-align:-3px}.repo a .count{background:rgba(0,0,0,.26);color:#fff;border-radius:0 3px 3px 0;position:relative;padding:0 8px 0 4px;margin:0 -10px 0 8px;font-size:12px}.article a,.article h1,.article h2{color:#3f51b5}.repo a .count:before{border-width:15px 5px 15px 0;border-color:transparent rgba(0,0,0,.26);border-style:solid;display:block;position:absolute;top:0;left:-5px}.article h1,.results .list a{border-bottom:1px solid rgba(0,0,0,.12)}.no-js .repo a .count{display:none}.drawer .section,.repo a{text-transform:uppercase;font-weight:700}.repo a .count{text-transform:none}.copyright a,pre span{-webkit-transition:color .25s;transition:color .25s}.ios.standalone .article{background:-webkit-linear-gradient(top,#fff 50%,#3f51b5 50%);background:linear-gradient(to bottom,#fff 50%,#3f51b5 50%)}.ios.standalone .article .wrapper{background:-webkit-linear-gradient(top,#fff 50%,#fff 50%);background:linear-gradient(to bottom,#fff 50%,#fff 50%)}.article a:focus,.article a:hover{color:#009688}.article table th{background:#6f7dc8;color:#fff}.article table th:first-child{border-top-left-radius:3px}.article table th:last-child{border-top-right-radius:3px}.footer{background:#3f51b5;color:#fff}.copyright{color:rgba(0,0,0,.54)}.pagination a,.pagination a:focus,.pagination a:hover{color:inherit}.pagination .direction{color:rgba(255,255,255,.7)}.admonition{background:#eceef8}.admonition pre{background:rgba(255,255,255,.3)}.admonition.warning{background:#fce8e9}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{color:rgba(0,0,0,.26)}.article{font-size:14px;line-height:1.7em;overflow-x:hidden}.article:after{display:block;clear:both}.article .wrapper{padding:116px 16px 92px}.ios.standalone .article{position:absolute;top:56px;right:0;bottom:0;left:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios.standalone .article .wrapper{position:relative;min-height:100%;padding-top:60px;margin-bottom:2px}.article h1{font-size:24px;line-height:1.333334em;padding:20px 0 42px}.article h2{font-size:20px;line-height:1.4em;padding-top:92px;margin-top:-56px}.ios.standalone .article h2{padding-top:36px;margin:0}.article h3,.article h4{font-size:14px;padding-top:76px;margin-top:-56px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article ol,.article p,.article ul{margin-top:1.5em}.article li{margin-top:.75em;margin-left:18px}.article li p{display:inline}.article ul li:before{content:"\e602";display:inline-block;font-size:16px;width:1.2em;margin-left:-1.2em;vertical-align:-.1em}.article hr{margin-top:1.5em}.article img{max-width:100%}.article pre{padding:16px;margin:1.5em -16px 0;line-height:1.5em;overflow:auto;-webkit-overflow-scrolling:touch}.article table td,.article table th{padding:12px 16px;white-space:nowrap}.article table{border-radius:3px;margin:3em 0 1.5em;font-size:13px}.no-js .article table{display:inline-block;max-width:100%;overflow:auto;-webkit-overflow-scrolling:touch}.article table th{min-width:100px;font-size:12px;text-align:left}.article table td{border-top:1px solid rgba(0,0,0,.05)}.article .data{margin:1.5em -16px;padding:1.5em 0;overflow:auto;-webkit-overflow-scrolling:touch;text-align:center}.article .data table{display:inline-block;margin:0 16px;text-align:left}.footer{position:absolute;bottom:0;left:0;right:0;padding:0 4px}.copyright{margin:20px 0}.pagination{max-width:1184px;height:92px;padding:4px 0;margin-left:auto;margin-right:auto;overflow:hidden}.pagination a{display:block;height:100%}.pagination .next,.pagination .previous{position:relative;float:left;height:100%}.pagination .previous{width:25%}.pagination .previous .direction,.pagination .previous .stretch{display:none}.pagination .next{width:75%;text-align:right}.pagination .page{display:table;position:absolute;bottom:4px}.pagination .direction{display:block;position:absolute;bottom:40px;width:100%;font-size:15px;line-height:20px;padding:0 52px}.pagination .stretch{padding:0 4px}.pagination .stretch .title{font-size:18px;padding:11px 0 13px}.admonition{margin:20px -16px 0;padding:20px 16px}.admonition>:first-child{margin-top:0}.article h1 a{display:none}.article h4{font-weight:400;font-style:italic}.admonition-title{font-weight:700}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{float:right;margin-left:20px;font-weight:400;font-style:normal}.bar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1)}#toggle-search:checked~.header .bar,.toggle-search .bar{-webkit-transform:translate3d(0,-56px,0);transform:translate3d(0,-56px,0)}.bar.search .button-reset{-webkit-transform:scale(.5,.5);transform:scale(.5,.5);-webkit-transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1);opacity:0}.bar.search.non-empty .button-reset{-webkit-transform:scale(1,1);transform:scale(1,1);opacity:1}.results{-webkit-transition:opacity .3s .1s,width 0s .4s,height 0s .4s;transition:opacity .3s .1s,width 0s .4s,height 0s .4s}#toggle-search:checked~.main .results,.toggle-search .results{-webkit-transition:opacity .4s,width 0s,height 0s;transition:opacity .4s,width 0s,height 0s}.results .list a{-webkit-transition:background .25s;transition:background .25s}.no-csstransforms3d .bar.default{display:table}.no-csstransforms3d .bar.search{display:none;margin-top:0}.no-csstransforms3d #toggle-search:checked~.header .bar.default,.no-csstransforms3d .toggle-search .bar.default{display:none}.no-csstransforms3d #toggle-search:checked~.header .bar.search,.no-csstransforms3d .toggle-search .bar.search{display:table}.bar.search{opacity:0;margin-top:8px}.bar.search .query{background:0 0;color:rgba(0,0,0,.87);font-size:18px;padding:13px 0;margin:0;width:100%;height:48px}.result,.results .meta strong{max-width:1200px;margin-left:auto;margin-right:auto}.bar.search .query::-webkit-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .query::-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-ms-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .button .icon:active{background:rgba(0,0,0,.12)}.results{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05);background:#fff;color:rgba(0,0,0,.87);opacity:0;position:fixed;top:0;left:0;width:0;height:100%;z-index:2;overflow-y:scroll;-webkit-overflow-scrolling:touch}#toggle-search:checked~.main .results,.toggle-search .results{opacity:1;width:100%;overflow-y:visible}.result h1,.result span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.results .meta{background:#3f51b5;color:#fff;font-weight:700}.results .list a:last-child{border-bottom:none}.results .list a:active{background:rgba(0,0,0,.12)}#toggle-search:checked~.header,.toggle-search .header{background:#fff;color:rgba(0,0,0,.54)}#toggle-search:checked~.header:before,.toggle-search .header:before{background:rgba(0,0,0,.54)}#toggle-search:checked~.header .bar.default,.toggle-search .header .bar.default{opacity:0}#toggle-search:checked~.header .bar.search,.toggle-search .header .bar.search{opacity:1}.bar.search .query::-ms-clear{display:none}.results .scrollable{top:56px}.results .meta strong{display:block;font-size:11px;padding:16px}.results .list a{display:block}.result{padding:12px 16px 16px}.result h1{line-height:24px}.result span{color:rgba(0,0,0,.54);font-size:12px}.no-csstransforms3d .results{display:none}.no-csstransforms3d #toggle-search:checked~.main .results,.no-csstransforms3d .toggle-search .results{display:block;overflow:auto}.meta{text-transform:uppercase;font-weight:700}@media only screen and (min-width:960px){.drawer,.drawer .scrollable{position:static}.backdrop{background:#f2f2f2}.backdrop-paper:after{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05)}.button-menu{display:none}.drawer{float:left;height:auto;margin-bottom:96px;padding-top:80px}.article{margin-left:262px}.footer{z-index:5}.copyright{margin-bottom:64px}.results{height:auto;top:64px}.results .scrollable{position:static;max-height:413px}}@media only screen and (max-width:959px){#toggle-search:checked~.main .results,.drawer,.toggle-search .results{height:100%}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{width:100%;height:100%}.drawer{-webkit-transform:translate3d(-262px,0,0);transform:translate3d(-262px,0,0);-webkit-transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1);position:fixed;z-index:5}.no-csstransforms3d .drawer{display:none}.drawer,.drawer .wrapper{background:#f2f2f2}.project{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#3f51b5;color:#fff}}@media only screen and (min-width:720px){.header{height:64px;padding:8px}.header .stretch{padding:0 16px}.header .stretch .title{font-size:20px;padding:12px 0}.project .name{margin:26px 0 0 5px}.article .wrapper{padding:128px 24px 96px}.article .data{margin:1.5em -24px}.article .data table{margin:0 24px}.article h2{padding-top:100px;margin-top:-64px}.ios.standalone .article h2{padding-top:28px;margin-top:8px}.article h3,.article h4{padding-top:84px;margin-top:-64px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article pre{padding:1.5em 24px;margin:1.5em -24px 0}.footer{padding:0 8px}.pagination{height:96px;padding:8px 0}.pagination .direction{padding:0 56px;bottom:40px}.pagination .stretch{padding:0 8px}.admonition{margin:20px -24px 0;padding:20px 24px}.bar.search .query{font-size:20px;padding:12px 0}.results .scrollable{top:64px}.results .meta strong{padding:16px 24px}.result{padding:16px 24px 20px}}@media only screen and (min-width:1200px){.header{width:100%}.drawer .scrollable .wrapper hr{width:48px}}@media only screen and (orientation:portrait){.ios.standalone .header{height:76px;padding-top:24px}.ios.standalone .header:before,.ios.standalone .project:before{content:" ";z-index:4;width:100%;height:20px;position:absolute;left:0}.ios.standalone .header:before{top:0}.ios.standalone .drawer .scrollable{top:124px}.ios.standalone .project{padding-top:20px}.ios.standalone .project:before{top:0}.ios.standalone .article{position:absolute;top:76px;right:0;bottom:0;left:0}.ios.standalone .results .scrollable{top:76px}}@media only screen and (orientation:portrait) and (min-width:720px){.ios.standalone .header{height:84px;padding-top:28px}.ios.standalone .results .scrollable{top:84px}}@media only screen and (max-width:719px){.bar .path{display:none}}@media only screen and (max-width:479px){.button-github,.button-twitter{display:none}}@media only screen and (min-width:720px) and (max-width:959px){.header .stretch{padding:0 24px}}@media only screen and (min-width:480px){.pagination .next,.pagination .previous{width:50%}.pagination .previous .direction{display:block}.pagination .previous .stretch{display:table}}@media print{.footer,.header,.project{display:none}.article pre,.article pre *{color:rgba(0,0,0,.87)!important}.article table{border-radius:none;box-shadow:none}.article table th{color:#3f51b5}} \ No newline at end of file diff --git a/material/assets/stylesheets/application.css b/material/assets/stylesheets/application.css index 3b9b5f8be..40a260ebf 100644 --- a/material/assets/stylesheets/application.css +++ b/material/assets/stylesheets/application.css @@ -1,2665 +1 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Dependencies - * ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Resets - * ------------------------------------------------------------------------- */ -/* - * Enfore correct box model - the prefixed versions are necessary for older - * browsers, i.e. Chrome < 10, Firefox < 29, Safari < 6 and Android < 4 - */ -html { - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; } - -/* - * All elements shall inherit the document default - */ -*, *:before, *:after { - box-sizing: inherit; - -moz-box-sizing: inherit; - -webkit-box-sizing: inherit; } - -/* - * 16px --> 10px, browser default - */ -html { - font-size: 62.5%; - -webkit-text-size-adjust: none; - -ms-text-size-adjust: none; - text-size-adjust: none; } - -/* - * Reset spacing and borders for all tags - */ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, main, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; } - -/* - * Reset list styles - */ -ul { - list-style: none; } - -/* - * Reset table styles - */ -table { - border-collapse: collapse; - border-spacing: 0; } - -/* - * Reset table cell styles - */ -td { - text-align: left; - font-weight: normal; - vertical-align: middle; } - -/* - * Reset (native) button styles - */ -button { - outline: 0; - padding: 0; - background: transparent; - border: none; - font-size: inherit; } - -/* - * Reset (native) input styles - */ -input { - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - -o-appearance: none; - appearance: none; - outline: none; - border: none; } - -/* - * Reset link styles - */ -a { - text-decoration: none; - color: inherit; } - -/* - * Reset tap outlines on iOS and Android - */ -a, button, label, input { - -webkit-tap-highlight-color: rgba(255, 255, 255, 0); - -webkit-tap-highlight-color: transparent; } - -/* - * Reset headlines - */ -h1, h2, h3, h4, h5, h6 { - font-weight: inherit; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Palette - * ------------------------------------------------------------------------- */ -/* - * Primary and accent color - */ -/* - * Black opacities - */ -/* - * White opacities - */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Code highlighter - * ------------------------------------------------------------------------- */ -/* - * Inline code - */ -code { - color: #3f51b5; } - -/* - * Code block - */ -pre { - background: rgba(0, 0, 0, 0.05); - /* - * Ensure correct color - */ } - pre, pre code { - color: rgba(0, 0, 0, 0.87); } - -/* - * Operators and comments - */ -.o, .c, .c1, .cm { - color: rgba(0, 0, 0, 0.54); } - -/* - * Keywords - */ -.k, .kn { - color: #A71D5D; } - -/* - * Types and functions - */ -.kt, .kd, .n.f { - color: #0086B3; } - -/* - * Strings - */ -.s { - color: #183691; } - -/* - * Constants and numbers - */ -.mi, .bp { - color: #9575CD; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Font faces - * ------------------------------------------------------------------------- */ -/* - * Icon font - */ -@font-face { - font-family: 'Icon'; - src: url("/assets/fonts/icon.eot?52m981"); - src: url("/assets/fonts/icon.eot?#iefix52m981") format("embedded-opentype"), url("/assets/fonts/icon.woff?52m981") format("woff"), url("/assets/fonts/icon.ttf?52m981") format("truetype"), url("/assets/fonts/icon.svg?52m981#icon") format("svg"); - font-weight: normal; - font-style: normal; } - -/* ---------------------------------------------------------------------------- - * Representational classes - * ------------------------------------------------------------------------- */ -/* - * Base icon class - */ -.icon { - font-family: 'Icon'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - /* Better Font Rendering */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } - -/* - * Magnifying glass - */ -.icon-search:before { - content: "\e600"; } - -/* - * Back arrow - */ -.icon-back:before { - content: "\e601"; } - -/* - * Link indicator - */ -.icon-link:before { - content: "\e602"; } - -/* - * Close button - */ -.icon-close:before { - content: "\e603"; } - -/* - * Hamburger icon - */ -.icon-menu:before { - content: "\e604"; } - -/* - * Forward arrow - */ -.icon-forward:before { - content: "\e605"; } - -/* - * Twitter icon - */ -.icon-twitter:before { - content: "\e606"; } - -/* - * GitHub icon - */ -.icon-github:before { - content: "\e607"; } - -/* - * Download icon - */ -.icon-download:before { - content: "\e608"; } - -/* - * Star icon - */ -.icon-star:before { - content: "\e609"; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Defaults - * ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ -/* - * Choose minimum and maximum device widths. - */ -/* - * Select minimum and maximum widths for a device breakpoint. - */ -/* ---------------------------------------------------------------------------- - * Mixins for numeric breakpoints - * ------------------------------------------------------------------------- */ -/* - * A minimum-maximum media query breakpoint. - */ -/* - * An orientation media query breakpoint. - */ -/* - * A maximum-aspect-ratio media query breakpoint. - */ -/* ---------------------------------------------------------------------------- - * Mixins for device breakpoints - * ------------------------------------------------------------------------- */ -/* - * A minimum-maximum media query device breakpoint. - */ -/* - * A minimum media query device breakpoint. - */ -/* - * A maximum media query device breakpoint. - */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Base animation - * ------------------------------------------------------------------------- */ -/* - * Animate color on hover - */ -a { - -webkit-transition: color .25s; - transition: color .25s; } - -/* - * Overlay - */ -.overlay { - -webkit-transition: opacity .25s, width .0s .25s, height .0s .25s; - transition: opacity .25s, width .0s .25s, height .0s .25s; - /* - * Expanded drawer - */ } - #toggle-drawer:checked ~ .overlay, - .toggle-drawer .overlay { - -webkit-transition: opacity .25s, width .0s, height .0s; - transition: opacity .25s, width .0s, height .0s; } - -/* - * Application header - check for javascript to omit flashing - */ -.js .header { - -webkit-transition: background .6s, color .6s; - transition: background .6s, color .6s; - /* - * Status bar - */ } - .js .header:before { - -webkit-transition: background .6s; - transition: background .6s; } - -/* - * Extended visible touch area on icon - */ -.button .icon { - -webkit-transition: background .25s; - transition: background .25s; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Base appearance - * ------------------------------------------------------------------------- */ -/* - * Device specific background hacks related to rubberband - */ -body { - color: rgba(0, 0, 0, 0.87); - /* Hack [Chrome, Opera]: Set background color in Chrome and Opera */ - /* - * Don't tint menu bar on iOS - */ } - @supports (-webkit-appearance: none) { - body { - background: #3f51b5; } } - .ios body { - background: white; } - -/* - * Horizontal separators - */ -hr { - border: 0; - border-top: 1px solid rgba(0, 0, 0, 0.12); } - -/* - * Toggle button - */ -.toggle-button { - cursor: pointer; - color: inherit; } - -/* - * Backdrop - */ -.backdrop { - background: white; - /* [tablet landscape+]: Introduce paper with shadow */ } - -/* - * Backdrop paper with shadow - */ -.backdrop-paper:after { - background: white; - /* [tablet landscape+]: Add drop shadow */ } - -/* - * Overlay - */ -.overlay { - background: rgba(0, 0, 0, 0.54); - opacity: 0; - /* - * Expanded drawer - */ } - #toggle-drawer:checked ~ .overlay, - .toggle-drawer .overlay { - opacity: 1; } - -/* - * Application header - */ -.header { - box-shadow: 0 1.5px 3px rgba(0, 0, 0, 0.24), 0 3px 8px rgba(0, 0, 0, 0.05); - background: #3f51b5; - color: white; - /* - * Add status bar overlay for iOS web application - */ } - .ios.standalone .header:before { - background: rgba(0, 0, 0, 0.12); } - -/* - * Navigation path within header bar - */ -.bar .path { - color: rgba(255, 255, 255, 0.7); } - -/* - * Draw round area around icon on touch - */ -.button .icon { - border-radius: 100%; } - -/* - * Pushed/clicked icon - */ -.button .icon:active { - background: rgba(255, 255, 255, 0.12); } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Base layout - * ------------------------------------------------------------------------- */ -/* - * Stretch container to viewport - */ -html { - height: 100%; } - -/* - * Stretch body to container and leave room for sticky footer. - */ -body { - position: relative; - min-height: 100%; } - -/* - * Horizontal separators - */ -hr { - display: block; - height: 1px; - padding: 0; - margin: 0; } - -/* - * Lock body (e.g. in search mode) - */ -.locked { - height: 100%; - overflow: hidden; } - -/* - * Scrollable container - */ -.scrollable { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - overflow: auto; - -webkit-overflow-scrolling: touch; - /* - * Content wrapper - */ } - .scrollable .wrapper { - height: 100%; - /* Hack [iOS]: Force overflow scrolling */ } - .ios .scrollable .wrapper { - margin-bottom: 2px; } - -/* - * Toggle states and button - */ -.toggle { - display: none; - /* - * Toggle button - */ } - .toggle-button { - display: block; } - -/* - * Backdrop - */ -.backdrop { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: -1; } - -/* - * Backdrop paper container - */ -.backdrop-paper { - max-width: 1200px; - height: 100%; - margin-left: auto; - margin-right: auto; - /* - * Actual paper - */ } - .backdrop-paper:after { - content: " "; - display: block; - height: 100%; - margin-left: 262px; } - -/* - * Overlay - */ -.overlay { - position: fixed; - top: 0; - width: 0; - height: 0; - z-index: 4; - /* [tablet landscape-]: Trigger overlay */ } - -/* - * Application header stays always on top - */ -.header { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: fixed; - top: 0; - left: 0; - z-index: 3; - height: 56px; - padding: 4px; - overflow: hidden; - /* [tablet portait+]: Larger header bar */ - /* [screen+]: Stretch to screen */ - /* - * Absolute positioning in iOS web application - */ } - .ios.standalone .header { - position: absolute; - /* [orientation: portrait]: Account for status bar in portrait mode */ } - -/* - * Header bar - */ -.bar { - display: table; - max-width: 1184px; - margin-left: auto; - margin-right: auto; - /* - * Links should span icons entirely - */ - /* - * Hide search button, in case javascript is not available. - */ - /* - * Navigation path - */ } - .bar a { - display: block; } - .no-js .bar .button-search { - display: none; } - .bar .path { - /* - * Correct icon alignment - */ - /* [tablet portait-]: Hide path */ } - .bar .path .icon:before { - vertical-align: -1.5px; } - -/* - * Buttons - */ -.button { - display: table-cell; - vertical-align: top; - width: 1%; - /* - * Remove native spacing on button - */ - /* - * Button icons - */ } - .button button { - margin: 0; - padding: 0; - /* Hack [IE]: Remove button offset in active state */ } - .button button:active:before { - position: relative; - top: 0; - left: 0; } - .button .icon { - display: inline-block; - font-size: 24px; - padding: 8px; - margin: 4px; } - -/* - * Hide source and twitter button - */ -.button-github, -.button-twitter { - /* [mobile landscape-]: Hide button */ } - -/* - * Hide menu button - */ -.button-menu { - /* [tablet landscape+]: Hide button */ } - -/* - * Stretch content to remaining space - */ -.stretch { - display: table; - table-layout: fixed; - width: 100%; - /* - * Set vertical spacing for header - */ - /* - * Title with ellipsis on overflow - */ } - .header .stretch { - padding: 0 20px; - /* [tablet portait]: Increase vertical spacing */ - /* [tablet portait+]: Account for missing menu icon */ } - .stretch .title { - display: table-cell; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - /* - * Increase header font size - */ } - .header .stretch .title { - font-size: 18px; - padding: 13px 0; - /* [tablet portait+]: Slightly larger typography in header */ } - -/* - * Main content - */ -.main { - max-width: 1200px; - margin-left: auto; - margin-right: auto; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Base typography - * ------------------------------------------------------------------------- */ -/* - * Default font styles - */ -body, input { - font-family: 'Ubuntu', 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-weight: 400; - /* Enable font-smoothing in Webkit and FF */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - /* - * Use system fonts, if browser doesn't support webfonts - */ } - .no-fontface body, .no-fontface input { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } - -/* - * Proportional fonts - */ -pre, code { - font-family: 'Ubuntu Mono', 'Courier New', 'Courier', monospace; - /* - * Use system fonts, if browser doesn't support webfonts - */ } - .no-fontface pre, .no-fontface code { - font-family: 'Courier New', 'Courier', monospace; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Drawer animation - * ------------------------------------------------------------------------- */ -/* - * Drawer container - */ -.drawer { - /* [tablet landscape-]: Hide menu */ - /* - * Expanded drawer - */ } - #toggle-drawer:checked ~ .main .drawer, - .toggle-drawer .drawer { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - /* - * Just show drawer, if browser doesn't support 3D transforms - */ } - .no-csstransforms3d #toggle-drawer:checked ~ .main .drawer, .no-csstransforms3d - .toggle-drawer .drawer { - display: block; } - -/* - * No color transition for project link - */ -.project { - -webkit-transition: none; - transition: none; } - -/* - * Project logo image - */ -.project .logo img { - -webkit-transition: box-shadow .4s; - transition: box-shadow .4s; } - -/* - * Repository buttons - */ -.repo a { - -webkit-transition: box-shadow .4s, opacity .4s; - transition: box-shadow .4s, opacity .4s; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Drawer appearance - * ------------------------------------------------------------------------- */ -/* - * Drawer container - */ -.drawer { - /* [tablet landscape-]: Light gray background */ - /* - * Color links - */ - /* - * Main sections - */ - /* - * Content wrapper - */ } - .drawer .toc a { - /* - * Current active element - */ - /* - * Hovered link - */ } - .drawer .toc a.current { - color: #3f51b5; } - .drawer .toc a:hover, .drawer .toc a:focus { - color: #009688; } - .drawer .section { - color: rgba(0, 0, 0, 0.54); } - .drawer .wrapper { - /* [tablet landscape-]: Light gray background */ } - -/* - * Project information - */ -.project { - /* [tablet landscape-]: Add drop shadow */ - /* - * Add status bar overlay for iOS web application - */ - /* - * Project logo - */ - /* - * Scale logo on hover - */ } - .ios.standalone .project:before { - background: rgba(0, 0, 0, 0.12); } - .project .logo img { - background: white; - border-radius: 100%; } - .project:hover .logo img, - .project:focus .logo img { - box-shadow: 0 7px 10px rgba(0, 0, 0, 0.3), 0 10px 50px rgba(0, 0, 0, 0.12); } - -/* - * Repository buttons - */ -.repo a { - box-shadow: 0 1.5px 3px rgba(0, 0, 0, 0.24), 0 3px 8px rgba(0, 0, 0, 0.05); - background: #009688; - color: white; - border-radius: 3px; - /* - * Hovered button - */ - /* - * Stars - */ } - .repo a:hover, .repo a:focus { - box-shadow: 0 7px 10px rgba(0, 0, 0, 0.3), 0 10px 50px rgba(0, 0, 0, 0.12); - opacity: 0.8; } - .repo a .count { - background: rgba(0, 0, 0, 0.26); - color: white; - border-radius: 0px 3px 3px 0px; - /* - * Star bubble - */ } - .repo a .count:before { - border-width: 15px 5px 15px 0; - border-color: transparent rgba(0, 0, 0, 0.26); - border-style: solid; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Drawer layout - * ------------------------------------------------------------------------- */ -/* - * Drawer container - */ -.drawer { - width: 262px; - font-size: 13px; - line-height: 1.0em; - /* [tablet landscape-]: Fixed positioning */ - /* [tablet landscape+]: Inline with content */ - /* Hack [iOS]: Mitigate scrolling of parent container on boundaries */ - /* - * Links to articles - */ - /* - * Links to chapters inside the current article - */ - /* - * Main sections - */ - /* - * Scrollable container - */ } - .ios .drawer { - overflow: scroll; - -webkit-overflow-scrolling: touch; } - .drawer .toc li a { - display: block; - padding: 14.5px 24px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; } - .drawer .toc li.anchor a { - padding: 10px 24px 10px 48px; } - .drawer .section { - display: block; - font-size: 11px; - padding: 14.5px 24px; } - .drawer .scrollable { - top: 104px; - z-index: -1; - /* [tablet landscape+]: Revert fixed positioning */ - /* - * Leave room for status bar in iOS web application - */ - /* - * Content wrapper - */ } - .ios.standalone .drawer .scrollable { - /* [orientation: portrait]: Account for status bar in portrait mode */ } - .drawer .scrollable .wrapper { - height: auto; - min-height: 100%; - /* - * Add spacing at top and bottom of separator - */ - /* - * Add spacing at top and bottom of top level navigation - */ } - .drawer .scrollable .wrapper hr { - margin: 12px 0; - /* [screen+]: Shorten separator */ - /* Hack [IE]: Left-align horizontal rule */ - margin-right: auto; } - .drawer .scrollable .wrapper .toc { - margin: 12px 0; } - -/* - * Project information - */ -.project { - display: block; - /* - * Leave room for status bar in iOS web application - */ - /* - * Project banner - */ - /* - * Project logo - */ - /* - * Project name - */ - /* - * Shrink font, if a logo is given. - */ } - .ios.standalone .project { - /* [orientation: portrait]: Account for status bar in portrait mode */ } - .project .banner { - display: table; - width: 100%; - height: 104px; - padding: 20px; } - .project .logo { - display: table-cell; - width: 64px; - padding-right: 12px; - /* - * Project logo image - */ } - .project .logo img { - display: block; - width: 64px; - height: 64px; } - .project .name { - display: table-cell; - padding-left: 4px; - font-size: 14px; - line-height: 1.25em; - vertical-align: middle; - /* [tablet portait+]: Slightly larger project name */ } - .project .logo + .name { - font-size: 12px; } - -/* - * Repository - */ -.repo { - margin: 24px 0; - text-align: center; - /* - * Inline buttons - */ - /* - * Buttons - */ } - .repo li { - display: inline-block; - padding-right: 12px; - white-space: nowrap; - /* - * No padding on last button - */ } - .repo li:last-child { - padding-right: 0; } - .repo a { - display: inline-block; - padding: 0px 10px 0px 6px; - font-size: 12px; - line-height: 30px; - height: 30px; - /* - * Slightly larger icons - */ - /* - * Stars - */ } - .repo a .icon { - font-size: 18px; - vertical-align: -3px; } - .repo a .count { - display: inline-block; - position: relative; - padding: 0px 8px 0 4px; - margin: 0 -10px 0 8px; - font-size: 12px; - /* - * Star bubble - */ - /* - * Hide count, in case javascript is not available. - */ } - .repo a .count:before { - content: " "; - display: block; - position: absolute; - top: 0px; - left: -5px; } - .no-js .repo a .count { - display: none; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Drawer typography - * ------------------------------------------------------------------------- */ -/* - * Drawer container - */ -.drawer { - /* - * Links to articles - */ - /* - * Links to chapters inside the current article - */ - /* - * Main sections - */ } - .drawer .toc li a { - font-weight: 700; } - .drawer .toc li.anchor a { - font-weight: 400; } - .drawer .section { - text-transform: uppercase; - font-weight: 700; } - -/* - * Repository buttons - */ -.repo a { - text-transform: uppercase; - font-weight: 700; - /* - * Stars - */ } - .repo a .count { - text-transform: none; - font-weight: 700; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Article animation - * ------------------------------------------------------------------------- */ -/* - * Fade color after highlighting - */ -pre span { - -webkit-transition: color .25s; - transition: color .25s; } - -/* - * Copyright and theme information - */ -.copyright { - /* - * Animate color on hover - */ } - .copyright a { - -webkit-transition: color .25s; - transition: color .25s; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Article appearance - * ------------------------------------------------------------------------- */ -/* - * Article - */ -.article { - /* - * Differing top and bottom rubberband backgrounds in iOS web application - */ - /* - * Headlines and chapters in primary color - */ - /* - * Lower border for main headline - */ - /* - * Color links - */ - /* - * Data tables - */ } - .ios.standalone .article { - background: -webkit-linear-gradient(top, white 50%, #3f51b5 50%); - background: linear-gradient(to bottom, white 50%, #3f51b5 50%); - /* Hack [iOS]: Mitigate black bounding box with linear gradient */ } - .ios.standalone .article .wrapper { - background: -webkit-linear-gradient(top, white 50%, white 50%); - background: linear-gradient(to bottom, white 50%, white 50%); } - .article h1, .article h2 { - color: #3f51b5; } - .article h1 { - border-bottom: 1px solid rgba(0, 0, 0, 0.12); } - .article a { - color: #3f51b5; - /* - * Hovered link - */ } - .article a:hover, .article a:focus { - color: #009688; } - .article table { - box-shadow: 0 1.5px 3px rgba(0, 0, 0, 0.24), 0 3px 8px rgba(0, 0, 0, 0.05); - border-radius: 3px; - /* - * Table heading - */ - /* - * Table cell - */ } - .article table th { - background: #6f7dc8; - color: white; - /* - * Round upper left border - */ - /* - * Round upper right border - */ } - .article table th:first-child { - border-top-left-radius: 3px; } - .article table th:last-child { - border-top-right-radius: 3px; } - .article table td { - border-top: 1px solid rgba(0, 0, 0, 0.05); } - -/* - * Article footer - */ -.footer { - background: #3f51b5; - color: white; } - -/* - * Copyright and theme information - */ -.copyright { - color: rgba(0, 0, 0, 0.54); } - -/* - * Pagination - */ -.pagination { - /* - * Inherit color for links - */ - /* - * Smaller font size for direction - */ } - .pagination a, - .pagination a:hover, - .pagination a:focus { - color: inherit; } - .pagination .direction { - color: rgba(255, 255, 255, 0.7); } - -/* - * Admonition support - */ -.admonition { - background: #eceef8; - /* - * Embedded code blocks - */ - /* - * A warning hint - */ } - .admonition pre { - background: rgba(255, 255, 255, 0.3); } - .admonition.warning { - background: #fce8e9; } - -/* - * Permalink support - */ -.article h2 a, .article h3 a, .article h4 a, .article h5 a, .article h6 a { - color: rgba(0, 0, 0, 0.26); } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Article layout - * ------------------------------------------------------------------------- */ -/* - * Article - */ -.article { - font-size: 14px; - line-height: 1.7em; - overflow-x: hidden; - /* [tablet landscape+]: Indent to account for drawer */ - /* - * Clearfix - */ - /* - * Article wrapper - */ - /* - * Enable overflow scrolling in iOS web application - */ - /* - * Article headline - */ - /* - * Article chapters - */ - /* - * Sub headlines - */ - /* - * Paragraphs and section titles - */ - /* - * List elements - */ - /* - * Add icon for elements of an unordered list - */ - /* - * Inline code snippets must not wrap - */ - /* - * Add spacing at top of separator - */ - /* - * Limit images to article container - */ - /* - * Code listing container - */ - /* - * Data tables - */ - /* - * Data table wrapper, in case javascript is available - */ - /* [tablet portait+]: Increase spacing */ } - .article:after { - content: " "; - display: block; - clear: both; } - .article .wrapper { - padding: 116px 16px 92px; - /* [tablet portait+]: Increase top spacing */ } - .ios.standalone .article { - position: absolute; - top: 56px; - right: 0; - bottom: 0; - left: 0; - overflow: auto; - -webkit-overflow-scrolling: touch; - /* [orientation: portrait]: Account for status bar in portrait mode */ - /* - * Article wrapper - */ } - .ios.standalone .article .wrapper { - position: relative; - min-height: 100%; - padding-top: 60px; - margin-bottom: 2px; } - .article h1 { - font-size: 24px; - line-height: 1.333334em; - padding: 20px 0 42px; } - .article h2 { - font-size: 20px; - line-height: 1.4em; - padding-top: 92px; - margin-top: -56px; - /* - * No offset correction in iOS web application - */ } - .ios.standalone .article h2 { - padding-top: 36px; - margin: 0; } - .article h3, .article h4 { - font-size: 14px; - padding-top: 76px; - margin-top: -56px; - /* - * No offset correction in iOS web application - */ } - .ios.standalone .article h3, .ios.standalone .article h4 { - padding-top: 20px; - margin-top: 0; } - .article p, .article ul, .article ol { - margin-top: 1.5em; } - .article li { - margin-top: 0.75em; - margin-left: 18px; - /* - * Inline paragraphs in list elements - */ } - .article li p { - display: inline; } - .article ul li:before { - content: "\e602"; - display: inline-block; - font-family: 'Icon'; - font-size: 16px; - width: 1.2em; - margin-left: -1.2em; - vertical-align: -0.1em; } - .article p > code { - white-space: nowrap; } - .article hr { - margin-top: 1.5em; } - .article img { - max-width: 100%; } - .article pre { - padding: 16px; - margin: 1.5em -16px 0; - line-height: 1.5em; - overflow: auto; - -webkit-overflow-scrolling: touch; } - .article table { - margin: 3.0em 0 1.5em; - font-size: 13px; - /* - * The semi-cool solution, in case javascript is not available - */ - /* - * Table heading - */ - /* - * Table cell - */ } - .no-js .article table { - display: inline-block; - max-width: 100%; - overflow: auto; - -webkit-overflow-scrolling: touch; } - .article table th { - min-width: 100px; - padding: 12px 16px; - font-size: 12px; - text-align: left; - white-space: nowrap; } - .article table td { - padding: 12px 16px; - white-space: nowrap; } - .article .data { - margin: 1.5em -16px; - padding: 1.5em 0; - overflow: auto; - -webkit-overflow-scrolling: touch; - text-align: center; - /* - * Data table - */ - /* [tablet portait+]: Increase spacing */ } - .article .data table { - display: inline-block; - margin: 0 16px; - text-align: left; } - -/* - * Article footer - */ -.footer { - position: absolute; - bottom: 0; - left: 0; - right: 0; - padding: 0 4px; - /* [tablet portait+]: Larger spacing */ - /* [tablet landscape+]: Stretch footer to viewport */ } - -/* - * Copyright and theme information - */ -.copyright { - margin: 20px 0; - /* [tablet landscape+]: Add bottom spacing */ } - -/* - * Pagination - */ -.pagination { - max-width: 1184px; - height: 92px; - padding: 4px 0; - margin-left: auto; - margin-right: auto; - overflow: hidden; - /* [tablet portait+]: Larger pagination and spacing */ - /* - * Links should span icons entirely - */ - /* - * Previous and next page - */ - /* - * Previous page - */ - /* - * Next page - */ - /* - * Link to page - */ - /* - * Put direction over page title - */ - /* - * Decrease indent for stretching content - */ - /* [mobile landscape+]: Proportional width for pagination */ - /* [tablet portrait+]: Increase vertical spacing */ } - .pagination a { - display: block; - height: 100%; } - .pagination .previous, - .pagination .next { - position: relative; - float: left; - height: 100%; } - .pagination .previous { - width: 25%; - /* - * Hide direction - */ - /* - * Hide title - */ } - .pagination .previous .direction { - display: none; } - .pagination .previous .stretch { - display: none; } - .pagination .next { - width: 75%; - text-align: right; } - .pagination .page { - display: table; - position: absolute; - bottom: 4px; } - .pagination .direction { - display: block; - position: absolute; - bottom: 40px; - width: 100%; - font-size: 15px; - line-height: 20px; - padding: 0 52px; } - .pagination .stretch { - padding: 0 4px; - /* - * Correct vertical spacing - */ } - .pagination .stretch .title { - font-size: 18px; - padding: 11px 0 13px; } - -/* - * Admonition support - */ -.admonition { - margin: 20px -16px 0; - padding: 20px 16px; - /* - * Remove redundant margin of first child - */ - /* [tablet portait+]: Increase horizontal spacing */ } - .admonition > :first-child { - margin-top: 0; } - -/* - * Permalink support - */ -.article { - /* - * Hide link to main headline - */ - /* - * Align permalinks on the right - */ } - .article h1 a { - display: none; } - .article h2 a, .article h3 a, .article h4 a, .article h5 a, .article h6 a { - float: right; - margin-left: 20px; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Article typography - * ------------------------------------------------------------------------- */ -/* - * Article - */ -.article { - /* - * Third-level headlines should be bold - */ - /* - * Fourth-level headlines should be italic - */ } - .article h3 { - font-weight: 700; } - .article h4 { - font-weight: 400; - font-style: italic; } - -/* - * Admonition support - */ -.admonition-title { - font-weight: 700; } - -/* - * Permalink support - */ -.article h2 a, .article h3 a, .article h4 a, .article h5 a, .article h6 a { - font-weight: 400; - font-style: normal; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Search animation - * ------------------------------------------------------------------------- */ -/* - * Animate header bar in offset and opacity - */ -.bar { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - -webkit-transition: opacity 0.2s cubic-bezier(0.75, 0, 0.25, 1), -webkit-transform 0.4s cubic-bezier(0.75, 0, 0.25, 1); - transition: opacity 0.2s cubic-bezier(0.75, 0, 0.25, 1), transform 0.4s cubic-bezier(0.75, 0, 0.25, 1); - /* - * Active search mode - */ - /* - * Search animations - */ } - #toggle-search:checked ~ .header .bar, - .toggle-search .bar { - -webkit-transform: translate3d(0, -56px, 0); - transform: translate3d(0, -56px, 0); } - .bar.search { - /* - * Hide reset button by default - */ - /* - * Show reset button if search is not empty - */ } - .bar.search .button-reset { - -webkit-transform: scale(0.5, 0.5); - transform: scale(0.5, 0.5); - -webkit-transition: opacity 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); - transition: opacity 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); - opacity: 0; } - .bar.search.non-empty .button-reset { - -webkit-transform: scale(1, 1); - transform: scale(1, 1); - opacity: 1; } - -/* - * Search results - */ -.results { - -webkit-transition: opacity .3s .1s, width .0s .4s, height .0s .4s; - transition: opacity .3s .1s, width .0s .4s, height .0s .4s; - /* - * Active search mode - */ - /* - * Search result item link - */ } - #toggle-search:checked ~ .main .results, - .toggle-search .results { - -webkit-transition: opacity .4s, width .0s, height .0s; - transition: opacity .4s, width .0s, height .0s; } - .results .list a { - -webkit-transition: background .25s; - transition: background .25s; } - -/* - * Just hide and show bars, if browser doesn't support 3D transforms - */ -.no-csstransforms3d { - /* - * Show default bar - */ - /* - * Hide search bar - */ - /* - * Active search mode - */ } - .no-csstransforms3d .bar.default { - display: table; } - .no-csstransforms3d .bar.search { - display: none; - margin-top: 0; } - .no-csstransforms3d #toggle-search:checked ~ .header, - .no-csstransforms3d .toggle-search { - /* - * Hide default bar - */ - /* - * Show search bar - */ } - .no-csstransforms3d #toggle-search:checked ~ .header .bar.default, - .no-csstransforms3d .toggle-search .bar.default { - display: none; } - .no-csstransforms3d #toggle-search:checked ~ .header .bar.search, - .no-csstransforms3d .toggle-search .bar.search { - display: table; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Search appearance - * ------------------------------------------------------------------------- */ -/* - * Search bar - */ -.bar.search { - opacity: 0; - /* - * Search input - */ - /* - * Pushed/clicked icon - */ } - .bar.search .query { - background: transparent; - color: rgba(0, 0, 0, 0.87); - /* - * Search input placeholder - */ } - .bar.search .query::-webkit-input-placeholder { - color: rgba(0, 0, 0, 0.26); } - .bar.search .query::-moz-placeholder { - color: rgba(0, 0, 0, 0.26); } - .bar.search .query:-moz-placeholder { - color: rgba(0, 0, 0, 0.26); } - .bar.search .query:-ms-input-placeholder { - color: rgba(0, 0, 0, 0.26); } - .bar.search .button .icon:active { - background: rgba(0, 0, 0, 0.12); } - -/* - * Search results - */ -.results { - box-shadow: 0 4px 7px rgba(0, 0, 0, 0.23), 0 8px 25px rgba(0, 0, 0, 0.05); - background: white; - color: rgba(0, 0, 0, 0.87); - opacity: 0; - /* - * Active search mode - */ - /* - * Search meta data - */ - /* - * Search result item link - */ } - #toggle-search:checked ~ .main .results, - .toggle-search .results { - opacity: 1; } - .results .meta { - background: #3f51b5; - color: white; } - .results .list a { - border-bottom: 1px solid rgba(0, 0, 0, 0.12); - /* - * Remove border on last element - */ - /* - * Active item link - */ } - .results .list a:last-child { - border-bottom: none; } - .results .list a:active { - background: rgba(0, 0, 0, 0.12); } - -/* - * Article link - */ -.result span { - color: rgba(0, 0, 0, 0.54); } - -/* - * Active search bar - */ -#toggle-search:checked ~ .header, -.toggle-search .header { - background: white; - color: rgba(0, 0, 0, 0.54); - /* - * Add darker status bar overlay in search mode - */ - /* - * Fade out default header bar - */ - /* - * Fade in search header bar - */ } - #toggle-search:checked ~ .header:before, - .toggle-search .header:before { - background: rgba(0, 0, 0, 0.54); } - #toggle-search:checked ~ .header .bar.default, - .toggle-search .header .bar.default { - opacity: 0; } - #toggle-search:checked ~ .header .bar.search, - .toggle-search .header .bar.search { - opacity: 1; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Search layout - * ------------------------------------------------------------------------- */ -/* - * Search bar - */ -.bar.search { - margin-top: 8px; - /* - * Search input - */ } - .bar.search .query { - font-size: 18px; - padding: 13px 0; - margin: 0; - width: 100%; - height: 48px; - /* [tablet portait+]: Slightly larger typo */ - /* Hack [IE]: Hide redundant clear button */ } - .bar.search .query::-ms-clear { - display: none; } - -/* - * Search results - */ -.results { - position: fixed; - top: 0; - left: 0; - width: 0; - height: 100%; - z-index: 2; - overflow-y: scroll; - -webkit-overflow-scrolling: touch; - /* [tablet landscape+]: Limit results to five entries */ - /* - * Scrollable container - */ - /* - * Active search mode - */ - /* - * Search meta data - */ - /* - * Search result item link - */ } - .results .scrollable { - top: 56px; - /* [tablet portait+]: Increase vertical spacing */ - /* [tablet landscape+]: Limit results to five entries */ - /* - * Leave room for status bar in iOS web application - */ } - .ios.standalone .results .scrollable { - /* [orientation: portrait]: Account for status bar in portrait mode */ } - #toggle-search:checked ~ .main .results, - .toggle-search .results { - width: 100%; - /* Hack [Firefox]: div doesn't collapse, unless this is applied */ - overflow-y: visible; - /* [tablet portait+]: Stretch to viewport */ } - .results .meta { - font-weight: 700; - /* - * Number of results - */ } - .results .meta strong { - display: block; - font-size: 11px; - max-width: 1200px; - margin-left: auto; - margin-right: auto; - padding: 16px; - /* [tablet portait+]: Increase vertical spacing */ } - .results .list a { - display: block; } - -/* - * Search result item - */ -.result { - max-width: 1200px; - margin-left: auto; - margin-right: auto; - padding: 12px 16px 16px; - /* [tablet portait+]: Increase vertical spacing */ - /* - * Article title - */ - /* - * Article link - */ } - .result h1 { - line-height: 24px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; } - .result span { - font-size: 12px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; } - -/* - * Switch visibility, if browser doesn't support 3D transforms - */ -.no-csstransforms3d { - /* - * Hide search results - */ - /* - * Active search mode - */ } - .no-csstransforms3d .results { - display: none; } - .no-csstransforms3d #toggle-search:checked ~ .main, - .no-csstransforms3d .toggle-search { - /* - * Show search results - */ } - .no-csstransforms3d #toggle-search:checked ~ .main .results, - .no-csstransforms3d .toggle-search .results { - display: block; - overflow: auto; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* - * Search meta data - */ -.meta { - text-transform: uppercase; - font-weight: 700; } - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Print overrides - * ------------------------------------------------------------------------- */ -/* - * Print styles - */ - -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -/* ---------------------------------------------------------------------------- - * Nothing to see here, move along - * ------------------------------------------------------------------------- */ -@media only screen and (min-width: 960px) { - .backdrop { - background: #f2f2f2; } - .backdrop-paper:after { - box-shadow: 0 1.5px 3px rgba(0, 0, 0, 0.24), 0 3px 8px rgba(0, 0, 0, 0.05); } - .button-menu { - display: none; } - .drawer { - position: static; - float: left; - height: auto; - margin-bottom: 96px; - padding-top: 80px; } - .drawer .scrollable { - position: static; } - .article { - margin-left: 262px; } - .footer { - z-index: 5; } - .copyright { - margin-bottom: 64px; } - .results { - height: auto; - top: 64px; } - .results .scrollable { - position: static; - max-height: 413px; } } -@media only screen and (max-width: 959px) { - .overlay {/* - * Expanded drawer - */ } - #toggle-drawer:checked ~ .overlay, - .toggle-drawer .overlay { - width: 100%; - height: 100%; } - .drawer { - -webkit-transform: translate3d(-262px, 0, 0); - transform: translate3d(-262px, 0, 0); - -webkit-transition: -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); - transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);/* - * Just hide drawer, if browser doesn't support 3D transforms - */ } - .no-csstransforms3d .drawer { - display: none; } - .drawer { - background: #f2f2f2; } - .drawer .wrapper { - background: #f2f2f2; } - .project { - box-shadow: 0 1.5px 3px rgba(0, 0, 0, 0.24), 0 3px 8px rgba(0, 0, 0, 0.05); - background: #3f51b5; - color: white; } - .drawer { - position: fixed; - z-index: 5; - height: 100%; } - #toggle-search:checked ~ .main .results, - .toggle-search .results { - height: 100%; } } -@media only screen and (min-width: 720px) { - .header { - height: 64px; - padding: 8px; } - .header .stretch { - padding: 0 16px 0 16px; } - .header .stretch .title { - font-size: 20px; - padding: 12px 0; } - .project .name { - margin: 26px 0 0 5px; } - .article .wrapper { - padding: 128px 24px 96px; } - .article .data { - margin: 1.5em -24px;/* - * Data table - */ } - .article .data table { - margin: 0 24px; } - .article {/* - * Account for larged header bar and anchors - *//* - * Sub headlines - *//* - * Increase spacing for code blocks - */ } - .article h2 { - padding-top: 100px; - margin-top: -64px;/* - * No offset correction in iOS web application - */ } - .ios.standalone .article h2 { - padding-top: 28px; - margin-top: 8px; } - .article h3, .article h4 { - padding-top: 84px; - margin-top: -64px;/* - * No offset correction in iOS web application - */ } - .ios.standalone .article h3, .ios.standalone .article h4 { - padding-top: 20px; - margin-top: 0; } - .article pre { - padding: 1.5em 24px; - margin: 1.5em -24px 0; } - .footer { - padding: 0 8px; } - .pagination { - height: 96px; - padding: 8px 0; } - .pagination {/* - * Increase vertical spacing - *//* - * Increase vertical spacing - */ } - .pagination .direction { - padding: 0 56px; - bottom: 40px; } - .pagination .stretch { - padding: 0 8px; } - .admonition { - margin: 20px -24px 0; - padding: 20px 24px; } - .bar.search .query { - font-size: 20px; - padding: 12px 0; } - .results .scrollable { - top: 64px; } - .results .meta strong { - padding: 16px 24px; } - .result { - padding: 16px 24px 20px; } } -@media only screen and (min-width: 1200px) { - .header { - width: 100%; } - .drawer .scrollable .wrapper hr { - width: 48px; } } -@media only screen and (orientation: portrait) { - .ios.standalone .header { - height: 76px; - padding-top: 24px;/* [tablet portait+]: Larger header bar *//* - * Add status bar overlay - */ } - .ios.standalone .header:before { - content: " "; - position: absolute; - top: 0; - left: 0; - z-index: 4; - width: 100%; - height: 20px; } - .ios.standalone .drawer .scrollable { - top: 124px; } - .ios.standalone .project { - padding-top: 20px;/* - * Add status bar overlay - */ } - .ios.standalone .project:before { - content: " "; - position: absolute; - top: 0; - left: 0; - z-index: 4; - width: 100%; - height: 20px; } - .ios.standalone .article { - position: absolute; - top: 76px; - right: 0; - bottom: 0; - left: 0; } - .ios.standalone .results .scrollable { - top: 76px;/* [tablet portait+]: Increase vertical spacing */ } } -@media only screen and (orientation: portrait) and (min-width: 720px) { - .ios.standalone .header { - height: 84px; - padding-top: 28px; } - .ios.standalone .results .scrollable { - top: 84px; } } -@media only screen and (max-width: 719px) { - .bar .path { - display: none; } } -@media only screen and (max-width: 479px) { - .button-github, - .button-twitter { - display: none; } } -@media only screen and (min-width: 720px) and (max-width: 959px) { - .header .stretch { - padding: 0 24px; } } -@media only screen and (min-width: 480px) { - .pagination {/* - * Previous and next page - *//* - * Previous page - */ } - .pagination .previous, - .pagination .next { - width: 50%; } - .pagination .previous { - width: 50%;/* - * Show direction - *//* - * Show title - */ } - .pagination .previous .direction { - display: block; } - .pagination .previous .stretch { - display: table; } } -@media print {/* - * Hide non-relevant elements - */ - .header, .project, .footer { - display: none; }/* - * Article - */ - .article {/* - * Remove color in all code blocks - *//* - * Border-radius makes this table entirely black on paper, so scrap it - */ } - .article pre, .article pre * { - color: rgba(0, 0, 0, 0.87) !important; } - .article table { - border-radius: none; - box-shadow: none;/* - * Color header - */ } - .article table th { - color: #3f51b5; } } +button,input{outline:0;border:none}.article ul li:before,.icon{font-family:Icon}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,html,i,iframe,img,ins,kbd,label,legend,li,main,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{border:0;padding:0;margin:0}.drawer .toc li a,.stretch .title{text-overflow:ellipsis;white-space:nowrap}.article p>code,.drawer .toc li a,.repo li,.stretch .title{white-space:nowrap}html{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;font-size:62.5%;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;height:100%}*,:after,:before{box-sizing:inherit;-moz-box-sizing:inherit;-webkit-box-sizing:inherit}ul{list-style:none}table{border-collapse:collapse;border-spacing:0}td{text-align:left;font-weight:400;vertical-align:middle}button{padding:0;background:0 0;font-size:inherit}input{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}a{text-decoration:none;color:inherit;-webkit-transition:color .25s;transition:color .25s}a,button,input,label{-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-tap-highlight-color:transparent}h1,h2,h3,h4,h5,h6{font-weight:inherit}.icon,body,input{font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{color:#e84e40}pre{background:rgba(0,0,0,.05)}pre,pre code{color:rgba(0,0,0,.87)}.c,.c1,.cm,.o{color:rgba(0,0,0,.54)}.k,.kn{color:#A71D5D}.kd,.kt,.n.f{color:#0086B3}.s{color:#183691}.bp,.mi{color:#9575CD}@font-face{font-family:Icon;src:url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.eot?52m981);src:url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.eot?#iefix52m981) format("embedded-opentype"),url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.woff?52m981) format("woff"),url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.ttf?52m981) format("truetype"),url(http://squidfunk.github.io/mkdocs-material//assets/fonts/icon.svg?52m981#icon) format("svg");font-weight:400;font-style:normal}.icon{speak:none;font-style:normal;font-variant:normal;text-transform:none;line-height:1}.icon-search:before{content:"\e600"}.icon-back:before{content:"\e601"}.icon-link:before{content:"\e602"}.icon-close:before{content:"\e603"}.icon-menu:before{content:"\e604"}.icon-forward:before{content:"\e605"}.icon-twitter:before{content:"\e606"}.icon-github:before{content:"\e607"}.icon-download:before{content:"\e608"}.icon-star:before{content:"\e609"}.article:after,.backdrop-paper:after,.repo a .count:before{content:" "}.overlay{-webkit-transition:opacity .25s,width 0s .25s,height 0s .25s;transition:opacity .25s,width 0s .25s,height 0s .25s}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{-webkit-transition:opacity .25s,width 0s,height 0s;transition:opacity .25s,width 0s,height 0s}.js .header{-webkit-transition:background .6s,color .6s;transition:background .6s,color .6s}.js .header:before{-webkit-transition:background .6s;transition:background .6s}.button .icon{-webkit-transition:background .25s;transition:background .25s}body{color:rgba(0,0,0,.87);position:relative;min-height:100%}.backdrop,.scrollable{position:absolute;left:0;bottom:0;right:0}@supports (-webkit-appearance:none){body{background:#e84e40}}.backdrop,.backdrop-paper:after,.ios body{background:#fff}hr{border-top:1px solid rgba(0,0,0,.12);display:block;height:1px}.backdrop-paper,.locked,.scrollable .wrapper{height:100%}.toggle-button{cursor:pointer;color:inherit}.overlay{background:rgba(0,0,0,.54);opacity:0}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{opacity:1}.header{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}.ios.standalone .header:before{background:rgba(0,0,0,.12)}.bar .path{color:rgba(255,255,255,.7)}.button .icon:active{background:rgba(255,255,255,.12)}.locked{overflow:hidden}.scrollable{top:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios .scrollable .wrapper{margin-bottom:2px}.toggle{display:none}.toggle-button{display:block}.backdrop{top:0;z-index:-1}.header,.overlay{position:fixed;top:0}.backdrop-paper{max-width:1200px;margin-left:auto;margin-right:auto}.backdrop-paper:after{display:block;height:100%;margin-left:262px}.overlay{width:0;height:0;z-index:4}.header{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;left:0;z-index:3;height:56px;padding:4px;overflow:hidden}.ios.standalone .header{position:absolute}.bar{display:table;max-width:1184px;margin-left:auto;margin-right:auto}.bar a{display:block}.no-js .bar .button-search{display:none}.bar .path .icon:before{vertical-align:-1.5px}.button{display:table-cell;vertical-align:top;width:1%}.button button{margin:0;padding:0}.button button:active:before{position:relative;top:0;left:0}.button .icon{border-radius:100%;display:inline-block;font-size:24px;padding:8px;margin:4px}.stretch{display:table;table-layout:fixed;width:100%}.header .stretch{padding:0 20px}.stretch .title{display:table-cell;overflow:hidden}.drawer .section,.no-csstransforms3d #toggle-drawer:checked~.main .drawer,.no-csstransforms3d .toggle-drawer .drawer,.project{display:block}.header .stretch .title{font-size:18px;padding:13px 0}.main{max-width:1200px;margin-left:auto;margin-right:auto}body,input{font-family:Ubuntu,'Helvetica Neue',Helvetica,Arial,sans-serif}.no-fontface body,.no-fontface input{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif}code,pre{font-family:'Ubuntu Mono','Courier New',Courier,monospace}.no-fontface code,.no-fontface pre{font-family:'Courier New',Courier,monospace}#toggle-drawer:checked~.main .drawer,.toggle-drawer .drawer{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.project{-webkit-transition:none;transition:none}.project .logo img{-webkit-transition:box-shadow .4s;transition:box-shadow .4s}.drawer .toc a.current{color:#e84e40}.drawer .toc a:focus,.drawer .toc a:hover{color:#00bfa5}.drawer .section{color:rgba(0,0,0,.54)}.ios.standalone .project:before{background:rgba(0,0,0,.12)}.project .logo img{background:#fff;border-radius:100%}.project:focus .logo img,.project:hover .logo img{box-shadow:0 7px 10px rgba(0,0,0,.3),0 10px 50px rgba(0,0,0,.12)}.repo a{-webkit-transition:box-shadow .4s,opacity .4s;transition:box-shadow .4s,opacity .4s;box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#00bfa5;color:#fff;border-radius:3px}.repo a:focus,.repo a:hover{box-shadow:0 7px 10px rgba(0,0,0,.3),0 10px 50px rgba(0,0,0,.12);opacity:.8}.drawer{width:262px;font-size:13px;line-height:1em}.ios .drawer{overflow:scroll;-webkit-overflow-scrolling:touch}.drawer .toc li a{display:block;padding:14.5px 24px;overflow:hidden;font-weight:700}.drawer .toc li.anchor a{padding:10px 24px 10px 48px;font-weight:400}.article h3,.repo a .count{font-weight:700}.drawer .section{font-size:11px;padding:14.5px 24px}.drawer .scrollable{top:104px;z-index:-1}.drawer .scrollable .wrapper{height:auto;min-height:100%}.drawer .scrollable .wrapper hr{margin:12px auto 12px 0}.drawer .scrollable .wrapper .toc{margin:12px 0}.project .banner{display:table;width:100%;height:104px;padding:20px}.project .logo{display:table-cell;width:64px;padding-right:12px}.project .logo img{display:block;width:64px;height:64px}.project .name{display:table-cell;padding-left:4px;font-size:14px;line-height:1.25em;vertical-align:middle}.repo a,.repo a .count,.repo li{display:inline-block}.project .logo+.name,.repo a{font-size:12px}.repo{margin:24px 0;text-align:center}.repo li{padding-right:12px}.repo li:last-child{padding-right:0}.repo a{padding:0 10px 0 6px;line-height:30px;height:30px}.repo a .icon{font-size:18px;vertical-align:-3px}.repo a .count{background:rgba(0,0,0,.26);color:#fff;border-radius:0 3px 3px 0;position:relative;padding:0 8px 0 4px;margin:0 -10px 0 8px;font-size:12px}.article a,.article h1,.article h2{color:#e84e40}.repo a .count:before{border-width:15px 5px 15px 0;border-color:transparent rgba(0,0,0,.26);border-style:solid;display:block;position:absolute;top:0;left:-5px}.article h1,.results .list a{border-bottom:1px solid rgba(0,0,0,.12)}.no-js .repo a .count{display:none}.drawer .section,.repo a{text-transform:uppercase;font-weight:700}.repo a .count{text-transform:none}.copyright a,pre span{-webkit-transition:color .25s;transition:color .25s}.ios.standalone .article{background:-webkit-linear-gradient(top,#fff 50%,#e84e40 50%);background:linear-gradient(to bottom,#fff 50%,#e84e40 50%);position:absolute;top:56px;right:0;bottom:0;left:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios.standalone .article .wrapper{background:-webkit-linear-gradient(top,#fff 50%,#fff 50%);background:linear-gradient(to bottom,#fff 50%,#fff 50%)}.article a:focus,.article a:hover{color:#00bfa5}.article table th{background:#ee7a70;color:#fff}.article table th:first-child{border-top-left-radius:3px}.article table th:last-child{border-top-right-radius:3px}.footer{background:#e84e40;color:#fff}.copyright{color:rgba(0,0,0,.54)}.pagination a,.pagination a:focus,.pagination a:hover{color:inherit}.pagination .direction{color:rgba(255,255,255,.7)}.admonition{background:#e6f6fe}.admonition pre{background:rgba(255,255,255,.3)}.admonition.warning{background:#fce8e9}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{color:rgba(0,0,0,.26)}.article{font-size:14px;line-height:1.7em}.article:after{display:block;clear:both}.article .wrapper{padding:116px 16px 92px}.ios.standalone .article .wrapper{position:relative;min-height:100%;padding-top:60px;margin-bottom:2px}.article h1{font-size:24px;line-height:1.333334em;padding:20px 0 42px}.article h2{font-size:20px;line-height:1.4em;padding-top:92px;margin-top:-56px}.ios.standalone .article h2{padding-top:36px;margin:0}.article h3,.article h4{font-size:14px;padding-top:76px;margin-top:-56px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article ol,.article p,.article ul{margin-top:1.5em}.article li{margin-top:.75em;margin-left:18px}.article li p{display:inline}.article ul li:before{content:"\e602";display:block;float:left;font-size:16px;width:1.2em;margin-left:-1.2em;vertical-align:-.1em}.article hr{margin-top:1.5em}.article img{max-width:100%}.article pre{padding:16px;margin:1.5em -16px 0;line-height:1.5em;overflow:auto;-webkit-overflow-scrolling:touch}.article table td,.article table th{padding:12px 16px;white-space:nowrap}.article table{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);border-radius:3px;margin:3em 0 1.5em;font-size:13px}.no-js .article table{display:inline-block;max-width:100%;overflow:auto;-webkit-overflow-scrolling:touch}.article table th{min-width:100px;font-size:12px;text-align:left}.article table td{border-top:1px solid rgba(0,0,0,.05)}.article .data{margin:1.5em -16px;padding:1.5em 0;overflow:auto;-webkit-overflow-scrolling:touch;text-align:center}.article .data table{display:inline-block;margin:0 16px;text-align:left}.footer{position:absolute;bottom:0;left:0;right:0;padding:0 4px}.copyright{margin:1.5em 0}.pagination{max-width:1184px;height:92px;padding:4px 0;margin-left:auto;margin-right:auto;overflow:hidden}.pagination a{display:block;height:100%}.pagination .next,.pagination .previous{position:relative;float:left;height:100%}.pagination .previous{width:25%}.pagination .previous .direction,.pagination .previous .stretch{display:none}.pagination .next{width:75%;text-align:right}.pagination .page{display:table;position:absolute;bottom:4px}.pagination .direction{display:block;position:absolute;bottom:40px;width:100%;font-size:15px;line-height:20px;padding:0 52px}.pagination .stretch{padding:0 4px}.pagination .stretch .title{font-size:18px;padding:11px 0 13px}.admonition{margin:20px -16px 0;padding:20px 16px}.admonition>:first-child{margin-top:0}.article h1 a{display:none}.article h4{font-weight:400;font-style:italic}.admonition-title{font-weight:700}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{float:right;margin-left:20px;font-weight:400;font-style:normal}.bar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1)}#toggle-search:checked~.header .bar,.toggle-search .bar{-webkit-transform:translate3d(0,-56px,0);transform:translate3d(0,-56px,0)}.bar.search .button-reset{-webkit-transform:scale(.5,.5);transform:scale(.5,.5);-webkit-transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1);opacity:0}.bar.search.non-empty .button-reset{-webkit-transform:scale(1,1);transform:scale(1,1);opacity:1}.results{-webkit-transition:opacity .3s .1s,width 0s .4s,height 0s .4s;transition:opacity .3s .1s,width 0s .4s,height 0s .4s}#toggle-search:checked~.main .results,.toggle-search .results{-webkit-transition:opacity .4s,width 0s,height 0s;transition:opacity .4s,width 0s,height 0s}.results .list a{-webkit-transition:background .25s;transition:background .25s}.no-csstransforms3d .bar.default{display:table}.no-csstransforms3d .bar.search{display:none;margin-top:0}.no-csstransforms3d #toggle-search:checked~.header .bar.default,.no-csstransforms3d .toggle-search .bar.default{display:none}.no-csstransforms3d #toggle-search:checked~.header .bar.search,.no-csstransforms3d .toggle-search .bar.search{display:table}.bar.search{opacity:0;margin-top:8px}.bar.search .query{background:0 0;color:rgba(0,0,0,.87);font-size:18px;padding:13px 0;margin:0;width:100%;height:48px}.result,.results .meta strong{max-width:1200px;margin-left:auto;margin-right:auto}.bar.search .query::-webkit-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .query::-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-ms-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .button .icon:active{background:rgba(0,0,0,.12)}.results{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05);background:#fff;color:rgba(0,0,0,.87);opacity:0;position:fixed;top:0;left:0;width:0;height:100%;z-index:2;overflow-y:scroll;-webkit-overflow-scrolling:touch}#toggle-search:checked~.main .results,.toggle-search .results{opacity:1;width:100%;overflow-y:visible}.result h1,.result span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.results .meta{background:#e84e40;color:#fff;font-weight:700}.results .list a:last-child{border-bottom:none}.results .list a:active{background:rgba(0,0,0,.12)}#toggle-search:checked~.header,.toggle-search .header{background:#fff;color:rgba(0,0,0,.54)}#toggle-search:checked~.header:before,.toggle-search .header:before{background:rgba(0,0,0,.54)}#toggle-search:checked~.header .bar.default,.toggle-search .header .bar.default{opacity:0}#toggle-search:checked~.header .bar.search,.toggle-search .header .bar.search{opacity:1}.bar.search .query::-ms-clear{display:none}.results .scrollable{top:56px}.results .meta strong{display:block;font-size:11px;padding:16px}.results .list a{display:block}.result{padding:12px 16px 16px}.result h1{line-height:24px}.result span{color:rgba(0,0,0,.54);font-size:12px}.no-csstransforms3d .results{display:none}.no-csstransforms3d #toggle-search:checked~.main .results,.no-csstransforms3d .toggle-search .results{display:block;overflow:auto}.meta{text-transform:uppercase;font-weight:700}@media only screen and (min-width:960px){.drawer,.drawer .scrollable{position:static}.backdrop{background:#f2f2f2}.backdrop-paper:after{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05)}.button-menu{display:none}.drawer{float:left;height:auto;margin-bottom:96px;padding-top:80px}.article{margin-left:262px}.footer{z-index:5}.copyright{margin-bottom:64px}.results{height:auto;top:64px}.results .scrollable{position:static;max-height:413px}}@media only screen and (max-width:959px){#toggle-search:checked~.main .results,.drawer,.toggle-search .results{height:100%}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{width:100%;height:100%}.drawer{-webkit-transform:translate3d(-262px,0,0);transform:translate3d(-262px,0,0);-webkit-transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1);position:fixed;z-index:5}.no-csstransforms3d .drawer{display:none}.drawer,.drawer .wrapper{background:#f2f2f2}.project{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}}@media only screen and (min-width:720px){.header{height:64px;padding:8px}.header .stretch{padding:0 16px}.header .stretch .title{font-size:20px;padding:12px 0}.project .name{margin:26px 0 0 5px}.article .wrapper{padding:128px 24px 96px}.article .data{margin:1.5em -24px}.article .data table{margin:0 24px}.article h2{padding-top:100px;margin-top:-64px}.ios.standalone .article h2{padding-top:28px;margin-top:8px}.article h3,.article h4{padding-top:84px;margin-top:-64px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article pre{padding:1.5em 24px;margin:1.5em -24px 0}.footer{padding:0 8px}.pagination{height:96px;padding:8px 0}.pagination .direction{padding:0 56px;bottom:40px}.pagination .stretch{padding:0 8px}.admonition{margin:20px -24px 0;padding:20px 24px}.bar.search .query{font-size:20px;padding:12px 0}.results .scrollable{top:64px}.results .meta strong{padding:16px 24px}.result{padding:16px 24px 20px}}@media only screen and (min-width:1200px){.header{width:100%}.drawer .scrollable .wrapper hr{width:48px}}@media only screen and (orientation:portrait){.ios.standalone .header{height:76px;padding-top:24px}.ios.standalone .header:before,.ios.standalone .project:before{content:" ";z-index:4;width:100%;height:20px;position:absolute;left:0}.ios.standalone .header:before{top:0}.ios.standalone .drawer .scrollable{top:124px}.ios.standalone .project{padding-top:20px}.ios.standalone .project:before{top:0}.ios.standalone .article{position:absolute;top:76px;right:0;bottom:0;left:0}.ios.standalone .results .scrollable{top:76px}}@media only screen and (orientation:portrait) and (min-width:720px){.ios.standalone .header{height:84px;padding-top:28px}.ios.standalone .results .scrollable{top:84px}}@media only screen and (max-width:719px){.bar .path{display:none}}@media only screen and (max-width:479px){.button-github,.button-twitter{display:none}}@media only screen and (min-width:720px) and (max-width:959px){.header .stretch{padding:0 24px}}@media only screen and (min-width:480px){.pagination .next,.pagination .previous{width:50%}.pagination .previous .direction{display:block}.pagination .previous .stretch{display:table}}@media print{.footer,.header,.project{display:none}.article pre,.article pre *{color:rgba(0,0,0,.87)!important}.article table{border-radius:none;box-shadow:none}.article table th{color:#e84e40}} \ No newline at end of file diff --git a/material/base.html b/material/base.html index 9accfd581..91c3d71ab 100644 --- a/material/base.html +++ b/material/base.html @@ -28,11 +28,15 @@ - - + {% if config.extra.logo %} + + {% endif %} + {% set icon = icon | default('assets/images/favicon-e565ddfa.ico') %} + + - + {% for path in extra_css %} {% endfor %} @@ -90,13 +94,13 @@ - + {% set repo_id = repo_url | replace('https://github.com/', '') %} - + {% for path in extra_javascript %} {% endfor %} diff --git a/material/drawer.html b/material/drawer.html index 270e0fef4..043e2c1df 100644 --- a/material/drawer.html +++ b/material/drawer.html @@ -6,7 +6,7 @@