diff --git a/README.rst b/README.rst index 1eb2a50..f39f3b1 100644 --- a/README.rst +++ b/README.rst @@ -42,7 +42,7 @@ Installation com.github.mfatihercik dsm - 1.0.2 + 1.0.3 @@ -50,7 +50,7 @@ Installation .. code-block:: xml - compile ('com.github.mfatihercik:dsm:1.0.2') + compile ('com.github.mfatihercik:dsm:1.0.3') ============================================================= `Documentation `_. diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle new file mode 100644 index 0000000..31ac141 Binary files /dev/null and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree new file mode 100644 index 0000000..fcad9dd Binary files /dev/null and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/doctrees/quick-start-guide.doctree b/docs/build/doctrees/quick-start-guide.doctree new file mode 100644 index 0000000..68f8a84 Binary files /dev/null and b/docs/build/doctrees/quick-start-guide.doctree differ diff --git a/docs/build/doctrees/specification/AbsoluteTagPath.doctree b/docs/build/doctrees/specification/AbsoluteTagPath.doctree new file mode 100644 index 0000000..37908ab Binary files /dev/null and b/docs/build/doctrees/specification/AbsoluteTagPath.doctree differ diff --git a/docs/build/doctrees/specification/DefaultObject.doctree b/docs/build/doctrees/specification/DefaultObject.doctree new file mode 100644 index 0000000..166ec0d Binary files /dev/null and b/docs/build/doctrees/specification/DefaultObject.doctree differ diff --git a/docs/build/doctrees/specification/Expressions.doctree b/docs/build/doctrees/specification/Expressions.doctree new file mode 100644 index 0000000..dff9d2f Binary files /dev/null and b/docs/build/doctrees/specification/Expressions.doctree differ diff --git a/docs/build/doctrees/specification/FieldAssignmentOrder.doctree b/docs/build/doctrees/specification/FieldAssignmentOrder.doctree new file mode 100644 index 0000000..d2587de Binary files /dev/null and b/docs/build/doctrees/specification/FieldAssignmentOrder.doctree differ diff --git a/docs/build/doctrees/specification/MergeOfDocument.doctree b/docs/build/doctrees/specification/MergeOfDocument.doctree new file mode 100644 index 0000000..a470d25 Binary files /dev/null and b/docs/build/doctrees/specification/MergeOfDocument.doctree differ diff --git a/docs/build/doctrees/specification/NodeObject.doctree b/docs/build/doctrees/specification/NodeObject.doctree new file mode 100644 index 0000000..1f6814a Binary files /dev/null and b/docs/build/doctrees/specification/NodeObject.doctree differ diff --git a/docs/build/doctrees/specification/RootObject.doctree b/docs/build/doctrees/specification/RootObject.doctree new file mode 100644 index 0000000..1195347 Binary files /dev/null and b/docs/build/doctrees/specification/RootObject.doctree differ diff --git a/docs/build/doctrees/specification/TransformationElement.doctree b/docs/build/doctrees/specification/TransformationElement.doctree new file mode 100644 index 0000000..fb15d5a Binary files /dev/null and b/docs/build/doctrees/specification/TransformationElement.doctree differ diff --git a/docs/build/doctrees/specification/XMLObject.doctree b/docs/build/doctrees/specification/XMLObject.doctree new file mode 100644 index 0000000..c984798 Binary files /dev/null and b/docs/build/doctrees/specification/XMLObject.doctree differ diff --git a/docs/build/doctrees/specification/index.doctree b/docs/build/doctrees/specification/index.doctree new file mode 100644 index 0000000..63745f9 Binary files /dev/null and b/docs/build/doctrees/specification/index.doctree differ diff --git a/docs/build/doctrees/specification/main.doctree b/docs/build/doctrees/specification/main.doctree new file mode 100644 index 0000000..de40aee Binary files /dev/null and b/docs/build/doctrees/specification/main.doctree differ diff --git a/docs/build/doctrees/specification/parsingElement/fields.doctree b/docs/build/doctrees/specification/parsingElement/fields.doctree new file mode 100644 index 0000000..8e077e6 Binary files /dev/null and b/docs/build/doctrees/specification/parsingElement/fields.doctree differ diff --git a/docs/build/doctrees/specification/parsingElement/filter.doctree b/docs/build/doctrees/specification/parsingElement/filter.doctree new file mode 100644 index 0000000..935c8b8 Binary files /dev/null and b/docs/build/doctrees/specification/parsingElement/filter.doctree differ diff --git a/docs/build/doctrees/specification/parsingElement/main.doctree b/docs/build/doctrees/specification/parsingElement/main.doctree new file mode 100644 index 0000000..6281d4c Binary files /dev/null and b/docs/build/doctrees/specification/parsingElement/main.doctree differ diff --git a/docs/build/doctrees/specification/parsingElement/tagPathAndTagParentPath.doctree b/docs/build/doctrees/specification/parsingElement/tagPathAndTagParentPath.doctree new file mode 100644 index 0000000..d994731 Binary files /dev/null and b/docs/build/doctrees/specification/parsingElement/tagPathAndTagParentPath.doctree differ diff --git a/docs/build/doctrees/specification/parsingElement/tagTypeAndTagTypeParams.doctree b/docs/build/doctrees/specification/parsingElement/tagTypeAndTagTypeParams.doctree new file mode 100644 index 0000000..18fddf1 Binary files /dev/null and b/docs/build/doctrees/specification/parsingElement/tagTypeAndTagTypeParams.doctree differ diff --git a/docs/build/doctrees/specification/schema.doctree b/docs/build/doctrees/specification/schema.doctree new file mode 100644 index 0000000..14b0c69 Binary files /dev/null and b/docs/build/doctrees/specification/schema.doctree differ diff --git a/docs/build/html/.buildinfo b/docs/build/html/.buildinfo new file mode 100644 index 0000000..4b0334a --- /dev/null +++ b/docs/build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 6d7e903a09e56c93182a30b0c665fd08 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/html/_sources/index.rst.txt b/docs/build/html/_sources/index.rst.txt new file mode 100644 index 0000000..a22c2d4 --- /dev/null +++ b/docs/build/html/_sources/index.rst.txt @@ -0,0 +1,25 @@ +Declarative Stream Mapping (DSM) +================================ + + +.. toctree:: + :maxdepth: 5 + :caption: Quick Start Guide: + + Quick Start Guide + + +.. toctree:: + :maxdepth: 5 + :caption: Specification: + + specification/index + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/build/html/_sources/quick-start-guide.rst.txt b/docs/build/html/_sources/quick-start-guide.rst.txt new file mode 100644 index 0000000..45ae6c7 --- /dev/null +++ b/docs/build/html/_sources/quick-start-guide.rst.txt @@ -0,0 +1,290 @@ + + +Introduction +============ + +Declarative Stream Mapping(DSM) is a *stream* deserializer library that makes parsing of **XML and JSON** easy. +DSM allows you to make custom parsing, filtering, +transforming, aggregating, grouping on any +JSON or XML document at stream time(read only once). +DSM uses yaml or json for configuration definitions + +**If you parsing a complex, huge file and +want to have high performance and low memory usage then DSM is for you.** + + +Simple Example +=============== + +**Lets Parse below simple JSON and XML file with DSM** + +File contents are taken from `Swagger Petstore example `_. Slightly changed. + +**Source file** + +.. content-tabs:: + + .. tab-container:: tab1 + :title: JSON + + .. code-block:: json + + { + "id": 1, + "name": "Van Kedisi", + "status": "sold", + "createDate": "01/24/2019", + "category": {"id": 1,"name": "Cats"}, + "tags": [ + {"id": 1,"name": "Cute"}, + {"id": 2,"name": "Popular"} + ], + "photoUrls": ["url1","url2" ] + } + + .. tab-container:: tab2 + :title: XML + + .. code-block:: xml + + + + + Van Kedisi + sold + 01/24/2019 + + 1 + Cats + + + + 1 + Cute + + + 2 + Popular + + + + url1 + url2 + + + + + + +**Those are rules that we want to apply during parsing**. + +- exclude "photoUrls" tag. +- read only "name" field of "tags" tag. +- read only "name" field of "category" tag. +- **add new the "isPopular" field that it's value is true, if "tag.name" has "Popular" value** + + +**DSM config file** + + + +[YAML] + +.. code-block:: yaml + + params: + dateFormat: MM/dd/yyyy + result: + type:object + path: / + xml: + path: /Pet + filter: $self.data.status=='sold' + fields: + id: + dataType: int + xml: + attribute: true + name: string + status: status + createDate: date + category: + path: category/name + isPopular: + default: $self.data.tags.contains("Popular") + tags: + type:array + path: tags/name |tags/tag/name # this is a regex expression. works for both JSON and XML + + + +**Class to deserialize** + +[JAVA] + +.. code-block:: java + + public class Pet { + private int id; + private String name; + private boolean isPopular; + private String status; + private String category; + private Date createDate; + private List tags; + + // getter/setter + } + + + +**Read Data** + +.. code-block:: java + + DSMBuilder builder = new DSMBuilder("dsm-config-file.yaml"); + DSM dsm = builder.setType(DSMBuilder.XML).create(); + Pet pet = dsm.toObject(new File("path/to/xmlFile.xml"),Pet.class); // read data from xml file + + dsm = builder.setType(DSMBuilder.JSON).create(); + pet = dsm.toObject(new File("path/to/jsonFile.json"),Pet.class); // read data from json file + + + + + +Features +============== + + +- **Work** for both **XML** and **JSON** +- **Custom stream parsing** +- **Filtering** by value on any field with very **low cognitive complexity** +- Flexible value **transformation**. +- **Default value assignment** +- Custom **function calling** during parsing +- **Powerful Scripting**(`Apache JEXL `_, Groovy, Javascript and other jsr223 implementations are supported) +- **Multiple inheritance** between DSM config file (DSM file can **extends to another config file**) +- **Reusable fragments support** +- Very **short learning curve** +- **Memory** and **CPU** efficient +- **Partial data extraction** from JSON or XML +- **String manipulation** with expression + + + + +Installation +============== + +.. content-tabs:: + + .. tab-container:: tab1 + :title: Maven + + **Jackson** + + .. code-block:: xml + + + com.github.mfatihercik + dsm + 1.0.3 + + + .. tab-container:: tab2 + :title: Gradle + + **Jackson** + + .. code-block:: xml + + compile ('com.github.mfatihercik:dsm:1.0.3') + + + + + + + +Sample Config File +=================== + +Detailed documentation and all option is `here `_. + +This config file contains some possible option and their short description. + +[header.yaml] + +.. code-block:: yaml + + params: + dateFormat: MM/dd/yyyy # define date format for "date" data type + transformations: + SOLD_STATUS: # value transformation for "isAvailable" property + map: + sold: false + pending: false + available: true + DEFAULT: false + SOLD_STATUS_SKIP: + $ref: $transformations.SOLD_STATUS # extends to "SOLD_STATUS" transformation. + map: + DEFAULT: exclude # exclude default value + onlyIfExist: # make transformation only source value exist in transformation map other wise return as it is + functions: + insertPet: com.example.InsertPet # declare a function to declare at Parsing Element. + + fragments: # create reusable fragment + category: + type:object + fields: + id: int + name: string + type: string + + +[main.yaml] + +.. code-block:: yaml + + $extends: header.yaml # extends to header.yaml config. + result: + type:array # result is an array + path: / | /Pets/Pet # start reading form beginning for json. path is a regex. we can define both for xml and json same time. or we can declare for xml in XML field. + xml: + path: /Pets/Pet # start reading from /Pets/Pet for xml + + filter: $self.data.isAvailable # filter by "isAvailable" property. "self" key word refers to current Node. self.parent refers to parent Node. self.data refers to current node data + + function: insertPet # call "insertPet" function for every element of "result" array + fields: + name: string # read name as string. + id: + dataType: int # read id as int + xml: + attribute: true # id is an attribute on /Pets/Pet tag. + createDate: date # use dateFormat in params then convert string to date + isAvailable: + path: status # read isAvailable as string from "status" tag + dataType: boolean + transformationCode: SOLD_STATUS # user "SOLD_STATUS" transformation to map from "status" to "isAvailable" + category: + $ref: $fragments.category # extends to "fragment.category" + fields: + type: exclude # exclude "type" field from "category" fragment + name: + default: 'Animal' #set default value to 'Animal' if "category/name" tag not exist in source document + isPopular: + default: $self.data.tags.contains("Popular") # set default value of "isPopular" property + + tags: + type:array + path: tags/name + filter: $value.length>15 # filter by length of value. + xml: + path: tags/tag/name + + + + diff --git a/docs/build/html/_sources/specification/AbsoluteTagPath.rst.txt b/docs/build/html/_sources/specification/AbsoluteTagPath.rst.txt new file mode 100644 index 0000000..62af998 --- /dev/null +++ b/docs/build/html/_sources/specification/AbsoluteTagPath.rst.txt @@ -0,0 +1,127 @@ + +.. _absolute: + +********************* +Absolute Path +********************* + +-------------------------------------- + +Absolute Path is found by **joining all tag name from top to bottom with "/"** character until specified tag. + +Below example is json representation of array of Pet object. + +Absolute tag paths are listed below. + +.. code-block:: json + + [ + { + "id": 1, + "category": { + "id": 1, + "name": "Cats" + }, + "name": "PetNameForm", + "photoUrls": [ + "url1", + "url2", + "url3" + ], + "tags": [ + { + "id": 2, + "name": "New" + }, + { + "id": 2, + "name": "Cute" + }, + ], + "status": "sold" + ] + +Absolute tag paths of all field in above json document are listed below. + +.. csv-table:: + :header: Field Name, Absolute Path + :stub-columns: 1 + :delim: | + + | / + Pet:id | /id + Pet:category | /category + Pet:category.id | /category/id + Pet:category.name | /category/name + Pet:name | /name + Pet:photoUrls | /photoUrls + Pet:photoUrls.(item) | /photoUrls + Pet:tags | /tags + Pet:tags.id | /tags/id + Pet.tags.name | /tags/name + Pet.status | /status + + +Same Example for XML: + +.. code-block:: json + + + + + 1589257917030308320 + Cats + + 6598053714149410844 + PetNameForm + + url1 + url2 + url3 + + sold + + + 4250197027829930927 + New + + + 8271965854563266871 + Cute + + + 3487705188883980239 + Popular + + + + + +Absolute tag paths of all field in above XML document are listed below. + +.. csv-table:: + :header: Field Name, Absolute Path + :stub-columns: 1 + :delim: | + + | / + Pets array | /Pets + Pets array item | /Pets/Pet + Pet:id | //Pets/Pet/id + Pet:category | /Pets/Pet/category + Pet:category.id | /Pets/Pet/category/id + Pet:category.name | /Pets/Pet/category/name + Pet:name | /name + Pet:photoUrls | /Pets/Pet/photoUrls + Pet:photoUrls.(item) | /Pets/Pet/photoUrls + Pet:tags | /Pets/Pet/tags + Pet:id | /Pets/Pet/tags/id + Pet:tags.name | /Pets/Pet/tags/name + Pet.status | /Pets/Pet/status + + +.. seealso:: + + path_ + + parentPath_ \ No newline at end of file diff --git a/docs/build/html/_sources/specification/DefaultObject.rst.txt b/docs/build/html/_sources/specification/DefaultObject.rst.txt new file mode 100644 index 0000000..3c487c5 --- /dev/null +++ b/docs/build/html/_sources/specification/DefaultObject.rst.txt @@ -0,0 +1,55 @@ +_`Default Object` +================== + +--------------------- + +Default Object determines how the default_ field is assigned. + +Fields: + .. csv-table:: + :header: Field Name, Type, Description + :stub-columns: 1 + :delim: | + + value_ | string | **REQUIRED** default value that is assigned to current field + force | string | Use the default value, even if the tag specified in the "path_" field is in the source file. + atStart | string | assign default value at start of tag. + +_`value` +------------ + +**REQUIRED** +it holds default value that is assigned to current field + +if the value starts with the "$" character, it is treated as "expression" and is resolved by expression resolver. + +The following objects are available in Expression Context. + + +.. csv-table:: + :header: Name, Data Type, Description, Example + :stub-columns: 1 + :delim: | + + params_ | Map | params_ object. | **params.dateFormat** =='dd.MM.yyyy' + self_ | Node_ | current node object that hold data of current complex type_ | **self.data.foo** => foo field of current node, **self.parent.data.foo** => foo field of parent node, **self.data.bar.foo** => foo field of bar object in current node. + all_ | Map | A map that stores all nodes by the "fieldName" of `Parsing Element Object`_ | **all.bar.data.foo** => foo field of **bar** node, **all.barList.data[0].foo** => *foo* field of first item of *barList* node + +_`force` +---------------- + + +if it's value is true, it means Use the default value, +even if the tag specified in the "path_" field is in the source file. +if force value is true, default value is assigned both start and end of parentPath_. +It is mostly used with filter field or with value in params_. +The default value is false. + +_`atStart` +---------------- + +if atStart_ filed is true, default value is assigned at start of the tag. other wise default value is assigned at the end of the tag. + +.. seealso:: + + default_ \ No newline at end of file diff --git a/docs/build/html/_sources/specification/Expressions.rst.txt b/docs/build/html/_sources/specification/Expressions.rst.txt new file mode 100644 index 0000000..7bbd15c --- /dev/null +++ b/docs/build/html/_sources/specification/Expressions.rst.txt @@ -0,0 +1,279 @@ +.. _expression: + +********************* +_`Expressions` and Scripting +********************* + +------------------------- + + +Expressions makes DSM very flexible. Expression allows a value to be filtered, manipulated, modified etc. +Expressions can access objects in the expression context and do operations by using these objects. + +Expressions can be used at both `source document`_ parsing time and `DSM document`_ loading time. + +Expressions are resolved by one of Scripting language such a Javascript, +Groovy, Apache JEXL or other JSR223 implementations. +Expressions must be written with scripting language syntax. +**Default scripting language is Apache JEXL** + +.. seealso:: + + `Apache JEXL `_ + + + + +There are two type of expression, **Loading Time** and **Parsing Time** expressions. + + +Loading Time Expression +========================== + +--------------------------- + + +Loading Time Expression is expressions that is **only used during loading of `DSM document`.** +It allows you to **modify structure of DSM document.** + +Loading Time Expressions are defined in the `$extends`_ and or `$ref`_ fields. For more detail check `$extends`_ and or `$ref`_ field. + +.. seealso:: + + `$extends`_ + + `$ref`_ + +The following fields are available in the expression context. + +.. csv-table:: + :header: Name, Data Type, Description, Example + :stub-columns: 1 + :delim: | + + params_ | Map | params_ object. | **params.dateFormat** =='dd.MM.yyyy' + + +**Example** +------------ + +------------------------- + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + + .. code-block:: yaml + + version: 1.0 + params: + rootPath: /bar/foo/ + $extends: + - /foo/bar/external.yaml + - $params.rootPath.concat("externalWithExpression.yaml") # use "params" object in expression context to get "rootPath" property + + .. tab-container:: json + :title: JSON + + + .. code-block:: json + + { + "version": 1.0, + "params":{ + "rootPath":"/bar/foo/" + }, + "$extends": ["/foo/bar/external.json","$params.rootPath.concat('externalWithExpression.json')"] + } + + +Parsing Time Expression +========================== + +-------------------------- + +Parsing Time Expression is expressions that is **only used during parsing of `source document`.** +It allows you to change the structure of the output, change the property value, import a specific part of the `source document`_, filter by property , transform a property, and almost all operations that can be done with custom coding. + +The Parsing Time Expressions can be defined in the filter_, default_, and normalize_ fields. + +The following objects are available in the expression context. + + +.. csv-table:: + :header: Name, Data Type, Description, Example + :stub-columns: 1 + :delim: | + + params_ | Map | params_ object. | **params.dateFormat** =='dd.MM.yyyy' + all_ | Map | A map that stores all nodes by the "uniqueName_" of `Parsing Element Object`_ | **all.bar.data.foo** => foo field of **bar** node, **all.barList.data[0].foo** => *foo* field of first item of *barList* node + self_ | Node_ | current node object that hold data of current complex type_ | **self.data.foo** => foo field of current node, **self.parent.data.foo** => foo field of parent node, **self.data.bar.foo** => foo field of bar object in current node. + value | string | (not available in default_ field) The raw string value of the current tag in `source document`_ | **value=='Computer'**,**value.startWith('bar')** + +.. seealso:: + + Node_ , default_, filter_, normalize_, `$extends`_, `$ref`_ + + + + +_`all` +--------- + +------------------------- + +Each complex type_ creates a node_. The created nodes can be accessed using the "all" object in the expressions. +Each node is stored in all_ map with the uniqueName_ of the `Parsing Element`_ that creates the node. + + + + + +.. code-block:: yaml + + result: + type: array + fields: + order: + type: object + fields: + state: string + createDate: date + saleLines: + type: array + fields: + product: + type: object + fields: + id: string + name: string + price: string + quantity: long + unit: string + + company: + type: object + fields: + id: string + name: string + price: string + + +for configuration at above following all_ map is created. + + +.. code-block:: yaml + + result: + parent: null + data: + order: order.data # contains data of the order node + company: company.data + order: + parent: result + data: + orderLines: orderLines.data + company: + parent: result + data: {} + orderLines: + parent: order + data: [{ product:product.data }] # data is array. each item contains product data + product: + parent: orderLines + data: {} + +Example usages: + +:product.parent: is equals orderLine node +:product.parent.data: is equals orderLine.data +:product.parent.parent: is equals order +:product.parent.parent.data: is equals order.data +:product.parent.parent.parent: is equals result +:order.data.orderLine: is equals orderLine.data +:order.data.orderLine[lastIndex].product: is equals product.data + + +_`self` +--------------- + +------------------------- + +current node object that hold data of current complex type_. + +Example usages: + +:self.parent: parent node +:self.data.foo: foo field of current object +:self.data[0]: First element of current array + + +**Example** +------------ + +------------------------------ + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + name: + - filter: $ self.data.categoryType=='foo' # filter expression. + default: + value: foo # force set name to foo with filter + force: true + - path: name + category: + type: object + fields: + id: int + name: + default: self.parent.data.categoryType=='foo'? 'Foo':'Bar' # default value is expression. + categoryType: + default: all.data.categoryType=='foo'? 'Foo':'Bar' # default value is expression. and its is equivalent of expression in category.name property. + productUnit: + default: $ self.data.categoryType=='foo'? 'LT': 'KG' # default value is expression. + categoryType: + default: "foo" # default value a is a string. + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":object", + "path":"/" , + "fields":{ + "name":"string", + "category":{ + "id": "int", + "name": { + "default": "self.parent.data.categoryType=='foo'? 'Foo':'Bar'", + }, + "categoryType": { + "default": "default: all.data.categoryType=='foo'? 'Foo':'Bar'", + } + }, + "productUnit":{ + "default": " $self.data.categoryType=='foo'? 'LT': 'KG'" + }, + "categoryType":{ + "default": "foo" + } + } + } + } + diff --git a/docs/build/html/_sources/specification/FieldAssignmentOrder.rst.txt b/docs/build/html/_sources/specification/FieldAssignmentOrder.rst.txt new file mode 100644 index 0000000..a5c09ee --- /dev/null +++ b/docs/build/html/_sources/specification/FieldAssignmentOrder.rst.txt @@ -0,0 +1,262 @@ +.. _`assignment order`: + +************************** +Property Assignment Order +************************** + +----------------------------------- + +The property assignment order is very important for the correct operation of the expressions in the filter field and in the default field +Referencing a not existing field in "self.data" can cause NullPointerException. + +DSM reads `source document` top to bottom in one pass as a stream. +Once it reads a tag `source document`, it checks whether absolute_ path of the tag match with tagAbsolutePath_ or taParentAbsolutePath_ of any of `Parsing Element`_ +if Parsing Element founds, value of tag is assigned according to `Parsing Element`_ definitions. + +The Property assignment work as follows: + +let's name the tag that is pointed by path_ as **current tag** and the tag that is pointed by parentPath as **parent tag** + +The property is assigned when **current tag** is closed except attribute_ properties for the XML document. +The attribute_ properties is assigned at start of **parent tag** by reading attribute value of **parent tag** + + +Order of the property assignment as follows: + - the closing of `current tag`_ is near to the document header(starting of _`parent tag`" for attribute ) + - deeper `current tag`_ + - Parsing Element definition close to the document header.(**assignment start from top to bottom** ) + +The default_ value of a property is assigned when current tag not exist in source document and **parent tag"** is closed(for all property, include attribute_). + +default_ value is assigned only once except force_ field is true. if force_ field is true default value is assigned at both start and close of **parent tag** + +Order of the default value of property assignment as follows: + - assure the property is not assigned or force field is true + - the closing of `parent tag`_is near to the document header. + - deeper `parent tag`_ + - Parsing Element definition far to the document header.(**assignment start bottom to top** ) + + +Example: + +.. code-block:: xml + + + + + 1 + Cats + + 6598053714149410844 + Van Kedisi + + url1 + url2 + url3 + + sold + + + 1 + New + + + 2 + Cute + + + 3 + Popular + + + + + +.. code-block:: yaml + + result: + type: array + path: / + xml: + path: "/Pets/Pet" + fields: + id:long + name: + status: + isPopular: + default $self.data.tags.stream().anyMatch(s->s.name=='Popular') + category: + type: object + fields: + name: + id: long + photoUrls: + type: array + path: photoUrls + xml: + path: photoUrls/photoUrls + tags: + type: array + path: tags + xml: + path: tags/tag + fields: + id:int + name: + + + +DSM read document top to bottom. + +- it founds **/Pets/Pet** absolute_ path that match with **result** Parsing Element. Then create a **array** and put first item into the array. + +.. code-block:: json + + result=[{}] + +- it founds **/Pets/Pet/category** match with **category** Parsing Element. then it create a **object** and assign it to **category** property + +.. code-block:: json + + result=[{ + "category":{} + }] + + +- it founds **/Pets/Pet/category/id** match with **category.id** Parsing Element. then it assign it to **id** property of **category object**. + +.. code-block:: json + + result=[{ + "category":{ + "id": 3 + } + }] +- it founds **/Pets/Pet/category/name** match with **category.name** Parsing Element. then the value is assigned + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + } + }] + + +- it founds **/Pets/Pet/id** match with **id** then the value is assigned + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + } + "id":1 + }] + + +- it founds **/Pets/Pet/name** match with **name** then the value is assigned + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + }, + "id":1, + "name":"Van Kedisi", + }] + + +- it founds **/Pets/Pet/photoUrls/photoUrl** match with **photoUrls** Parsing Element then the new array is created and assigned + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + }, + "id":1, + "name":"Van Kedisi", + "photoUrls":[] + }] + +- it founds **/Pets/Pet/photoUrls/photoUrl** match with **photoUrls** then the value of **photoUrls** is assigned + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + }, + "id":1, + "name":"Van Kedisi", + "photoUrls":["url1","url2","url3"] + }] + +after reading all fields under **/Pets/Pet** path following result generated. + + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + }, + "id":1, + "name":"Van Kedisi", + "photoUrls":["url1","url2","url3"], + "status":"sold", + "tags":[ + { + "id":1, + "name": "New" + }, + { + "id":1, + "name": "Cute" + }, + { + "id":1, + "name": "Popular" + } + ] + + }] + +- it can't find **/Pets/Pet/isPopular** but **isPopular** property has **default** value. When **/Pets/Pet** (**parent tag**) tag is closed then it's expression is evaluated. The result of expression is assigned to **isPopular** property. + +.. code-block:: json + + result=[{ + "category":{ + "id": 3, + "name": "Cats" + }, + "id":1, + "name":"Van Kedisi", + "photoUrls":["url1","url2",url3"], + "status":"sold", + "tags":[ + { + "id":1, + "name": "New" + }, + { + "id":1, + "name": "Cute" + }, + { + "id":1, + "name": "Popular" + } + ], + "isPopular": true + }] + diff --git a/docs/build/html/_sources/specification/MergeOfDocument.rst.txt b/docs/build/html/_sources/specification/MergeOfDocument.rst.txt new file mode 100644 index 0000000..c549cc1 --- /dev/null +++ b/docs/build/html/_sources/specification/MergeOfDocument.rst.txt @@ -0,0 +1,117 @@ + +.. _merge: +.. _merged: +.. _extended: +.. _extend: +.. _extends: + +************************* +Merge of DSM Document +************************* + +--------------------- + + +`DSM document`_ can extends to another DSM document by using `$extends`_ field. + +`Parsing Element`_ can extends to another Parsing Element by using `$ref`_ field. + +DSM documents and Parsing Elements are merged with each other. + +Before going to explain merge process lets make some definition. + +source: + DSM Document or Parsing Element that we want to extend to another. + +target: + DSM Document or Parsing Element that we want to extend to. + + +Merge process work as follows: + for every field of target do followings: + 1. if field **not exist** in source, **copy** value of target to source. + + 2. if field **exist** in source do followings + + 2.1. if **dataType** of fields is **different** then **skip** this field. + + 2.2. if **dataType** of fields is **same** then do followings + + 2.2.1. if **dataType** is **simpleDataType** (string,number) then **skip** this field (do not copy target to source) + + 2.2.2. if **dataType** is **array** then **add** target values to **start of** the source values + + 2.2.3. if **dataType** is **map** then **start Merge process** for those two map. + +Example merge process of DSM documents: + +external DSM Document:(external.yaml) + +.. code-block:: yaml + + version: 1.0 + params: + dateFormat: dd.MM.yyyy + rootPath: /foo/bar + acceptedCountryCode: [TR,US,FR] + transformations: + COUNTRY_CODE_TO_NAME: + map: + DEFAULT: Other + TR: Turkey + US: United States + result: + fields: + id: string + name: string + price: double + + +current DSM Document: + +.. code-block:: yaml + + version: 1.0 + $extends: $params.rootPath.concat("external.yaml") # resolve expression + params: + rootPath: /DSM/MAIN + acceptedCountryCode: [UK] + transformations: + COUNTRY_CODE_TO_NAME: + map: + UK: United Kingdom + result: + type: object + path: / + fields: + category: string + + +After merge process following configuration will take effect: + + +.. code-block:: yaml + + version: 1.0 + $extends: $params.rootPath.concat("external.yaml") + params: + dateFormat: dd.MM.yyyy # (rule 1) imported from external document + rootPath: /DSM/MAIN # (rule 2.2.1) overwritten by current DSM document + acceptedCountryCode: [TR,US,FR,UK] #(rule 2.2.2) external list element added to start off current list element(UK is only exist in current document and located at the end ) + transformations: #(rule 2.2.3) transformations field exist in both source and target and type is MAP + COUNTRY_CODE_TO_NAME: #(rule 2.2.3) + map: + UK: United Kingdom # only exist in current DSM document + DEFAULT: Other # (rule 1) imported from external document + TR: Turkey # (rule 1) imported from external document + US: United States # (rule 1) imported from external document + + result: + type: object # exist only current DSM document + path: / + fields: + category: string # exist only current DSM document + id: string + name: string # imported from external document + price: double + diff --git a/docs/build/html/_sources/specification/NodeObject.rst.txt b/docs/build/html/_sources/specification/NodeObject.rst.txt new file mode 100644 index 0000000..f4d1f62 --- /dev/null +++ b/docs/build/html/_sources/specification/NodeObject.rst.txt @@ -0,0 +1,77 @@ +.. _node: +.. _nodes: + +Node Object +============ +The node is a data structure used in the DSM to store data and create the hierarchy of the DSM document. +Nodes are created with the complex type_ definition during parsing of source document. +It can be used in the parsing time expressions + +Fields: + +.. csv-table:: + :header: Field Name, Type, Description + :stub-columns: 1 + :delim: | + + parent | Node | parent node. + data | Map, List | holds the value of the current node. + + + +parent +------- + + parent field holds parent of the current node. parent of the result node is null. + + + Example usages: + + :self: point to current node + :self.parent: point to parent of current node. + :self.parent.parent: point to parent of current node. + :self.parent==null: is current node result node. + + +data +----- + + The data field holds the value of the current node. + + if type_ definition of `Parsing Element`_ is an object_, data is a Map that contains properties of the current `Parsing Element`_ definitions. + + Example Usage: + + :self.data: data is map + :self.data.foo: foo property of current node + :self.parent.data.foo: foo property of parent node + :self.data.bar.foo: foo property of the bar object in current node + +If the type_ definition of the current `Parsing Element` is an array: + +and If the parsing element definition has fields, data of one is Array , data of other is Map , two node is created. +parent node holds array, child node holds map. + +self.data is a Map +self.parent.data is Array. + +Example Usage: + + :self.data: data is map + :self.data.foo: foo property of current node + :self.parent[0].data.foo: foo property of first element of current array + :self.parent[self.parent.size()-1].bar: last element of current array + + + +and If there are no fields_ in the `Parsing Element`_ definition,a node which the data field is array is created. + +self.data is Array + + +Example Usage: + + :self.data: data is array + :self.data[0]: first property of array + :self.parent.data.foo: foo property of parent node + :self.parent[self.parent.size()-1].bar: last element of current array diff --git a/docs/build/html/_sources/specification/RootObject.rst.txt b/docs/build/html/_sources/specification/RootObject.rst.txt new file mode 100644 index 0000000..3ac751c --- /dev/null +++ b/docs/build/html/_sources/specification/RootObject.rst.txt @@ -0,0 +1,300 @@ +DSM Object +========== + +This is the root document object of the DSM document. + +Fields: + .. csv-table:: + :header: Field Name, Type, Description + :stub-columns: 1 + :delim: | + + version | string | **REQUIRED**. This string MUST be the semantic version number of the DSM Specification version that the DSM document uses. The DSM field SHOULD be used by tooling specifications and clients to interpret the DSM document + params_ | Map[string,any] | **params_** field is a map that contains parameter definition to configure DSM document and `Parsing Element`_s. + transformations_ | Map[string,`Transformation Element`_] | Deceleration of Map contains transformationCode_ as key, and `Transformation Element`_ as value. `Transformation Element`_ holds lookup table to transform value from `Source Document`_ to destination document. + functions_ | Map[string,Function_] | Deceleration of Map contains function_ name as key, and `function deceleration `_ as value. functions are used for custom parsing or calling services with parsed data. Functions implements FunctionExecutor interface. + fragments_ | Map [String, `Parsing Element`_ ] | A map contains declaration of reusable `Parsing Element`_. The fragment definition can be referenced with $ref_ field while defining `Parsing Element`_. + result_ | `Parsing Element`_ | **REQUIRED**. The entry point of `Parsing Element`_ declarations. The result field defines structure of the output. + `$extends`_ | string | **`$extends`_** field is used for import external DSM document. + + + + + + +_`params` +---------- + +------------------------- + + +params_ field is a map that contains parameter definition to configure DSM document and `Parsing Element`_. The key of params map is string and case sensitive. The value of params map can be any type of json object(int, boolean, object, array) accepted by JSON and YAML specification. + +Example DSM document that contains params. + + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + params: + dateFormat: dd.MM.yyyy + rootPath: fooBar/foo + category: + foo: bar + acceptedCountryCode: [TR,US,FR] + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "params":{ + "dateFormat":"dd.MM.yyyy", + "rootPath":"fooBar/foo", + "category":{ + "foo":"bar" + }, + "acceptedCountryCode": ["TR","US","FR"] + } + } + + + + +_`transformations` +------------------- + +------------------------------- + + +Deceleration of Map contains transformationCode_ as key, and `Transformation Element`_ as value. `Transformation Element`_ holds lookup table to transform value from `Source Document`_ to destination document. + +Example CF document that contains transformations + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + transformations: + COUNTRY_CODE_TO_NAME: + map: + DEFAULT: Other + TR: Turkey + US: United States + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + + "version": 1.0, + "transformations":{ + "COUNTRY_CODE_TO_NAME":{ + "map":{ + "TR":"Turkey", + "US":"United States", + "DEFAULT":"Other" + } + } + } + + } + + + +_`functions` +------------- + +---------------------------- + +Deceleration of Map contains function_ name as key, and `function deceleration `_ as value. functions are used for custom parsing or calling services with parsed data. Functions implements FunctionExecutor interface. + +Example CF document that contains functions + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + functions: + insertProduct: com.example.InsertProduct + approveOrder: com.example.ApproveOrder + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + + "version": 1.0, + "functions":{ + "insertProduct":"com.example.InsertProduct", + "approveOrder":"com.example.ApproveOrder" + } + + } + + +_`fragments` +------------- + +---------------------------- + +A map contains declaration of reusable `Parsing Element`_. The fragment definition can be referenced with `$ref`_ field while defining `Parsing Element`_. + +Example CF document that contains functions + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + fragments: + product: + fields: + id: string + name: string + price: double + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + + "version": 1.0, + "fragments":{ + "product":{ + "fields":{ + "id":"string", + "name":"double", + "price":"double" + } + } + } + } + + + + +_`result` +------------ + +------------------------------- + +**REQUIRED**. The entry point of `Parsing Element`_ declarations. The result field defines structure of the output. + +Example CF document that contains result + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + id: string + name: string + price: double + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + + "version": 1.0, + "result":{ + "type":"object", + "path":"/" + "fields":{ + "id":"string", + "name":"double", + "price":"double" + } + } + } + + + +_`$extends` +--------------- + +----------------------------- + +$extends field is used for import external DSM document to current DSM document. it's value is basically relative path or URI definition of external DSM document. if it's value start with "$" sing, it is accepted as an expression_ and resolved by expression resolver. External DSM document will merged_ into current DSM document. $extends can also be list of path or URI. Merge_ process start from first element to last element. Firstly current DSM document merged_ with first element then result of merge_ process extended to second element etc.. + +Example CF document that contains extends + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + $extends: /foo/bar/external.yaml + + **or** + + .. code-block:: yaml + + version: 1.0 + params: + rootPath: /bar/foo/ + $extends: + - /foo/bar/external.yaml + - $params.rootPath.concat("externalWithExpression.yaml") + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "$extends": "/foo/bar/external.json" + } + + or + + .. code-block:: json + + { + "version": 1.0, + "params":{ + "rootPath":"/bar/foo/" + }, + "$extends": ["/foo/bar/external.json","$params.rootPath.concat('externalWithExpression.json')"] + } diff --git a/docs/build/html/_sources/specification/TransformationElement.rst.txt b/docs/build/html/_sources/specification/TransformationElement.rst.txt new file mode 100644 index 0000000..b534691 --- /dev/null +++ b/docs/build/html/_sources/specification/TransformationElement.rst.txt @@ -0,0 +1,63 @@ +.. _`Transformation Element`: + +_`Transformation Element Object` +=================================== + +------------------------------------------ + +Transformation is a very powerful feature that used to map value of a tag from the `source document`_ to destination document. +Transformation Element holds the mapping and how the mapping will be used with `Parsing Element`_s. +We can consider, transformation as switch-case in programing language. +Every record in the mapping table is a case and DEFAULT record is a default case fo switch-case statement. + +Fields: + .. csv-table:: + :header: Field Name, Type, Description + :stub-columns: 1 + :delim: | + + map | Map | **REQUIRED** mapping table from source to destination + onlyIfExist | boolean | transform source value only if exist in mapping table. if not exist use as is. + `$ref`_ | string | ref field is used to extends_ current Transformation Element to another Transformation Element. it is an expression. + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + transformations: + COUNTRY_CODE_TO_NAME: + map: + DEFAULT: Other + TR: Turkey + US: United States + COUNTRY_CODe_TO_NAME_IF_EXIST: + $ref: $transformations.COUNTRY_CODE_TO_NAME + onlyIfExist: true + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1, + "transformations": { + "COUNTRY_CODE_TO_NAME": { + "map": { + "DEFAULT": "Other", + "TR": "Turkey", + "US": "United States" + } + }, + "COUNTRY_CODe_TO_NAME_IF_EXIST": { + "$ref": "$transformations.COUNTRY_CODE_TO_NAME", + "onlyIfExist": true + } + } + } + diff --git a/docs/build/html/_sources/specification/XMLObject.rst.txt b/docs/build/html/_sources/specification/XMLObject.rst.txt new file mode 100644 index 0000000..7c24646 --- /dev/null +++ b/docs/build/html/_sources/specification/XMLObject.rst.txt @@ -0,0 +1,81 @@ + +_`XML Object` +============== + +--------------- + +XML Object is used to make extra definitions and to change "path_" and "parentPath_" fields for xml format + +Fields: + .. csv-table:: + :header: Field Name, Type, Description + :stub-columns: 1 + :delim: | + + path_ | string | xml specific path_ definition default value is path_ field of `Parsing Element Object`_ + parentPath_ | string | xml specific parentPath_ definition. default value is parentPath_ field of `Parsing Element Object`_ + attribute_ | boolean | attribute field is indicates that the current `Parsing Element Object`_ is an attribute on the tag pointed to by the parentPath field in the xml. + + + +_`attribute` +------------ + +The attribute field is indicates that the current `Parsing Element`_ is an attribute on the tag pointed to by the parentPath_ field in the xml. + + +Examples: + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + xml: + path: /Pets/Pet # xml specific path definition + fields: + id: + dataType: long + xml: + attribute: true # id field is an attribute that is located at /Pets/Pet tag. + name: string + price: long + image: string + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + + "version": 1.0, + "result":{ + "type": "object", + "path": "/" , + "xml":{ + "path": "/Pets/Pet" + } + "fields": { + "id": { + "dataType": "long", + "xml":{ + "attribute": "true" + } + }, + "name": "string", + "price": "long", + "image": "string" + } + } + } + +.. seealso:: + + xml_ \ No newline at end of file diff --git a/docs/build/html/_sources/specification/index.rst.txt b/docs/build/html/_sources/specification/index.rst.txt new file mode 100644 index 0000000..8361bd1 --- /dev/null +++ b/docs/build/html/_sources/specification/index.rst.txt @@ -0,0 +1,6 @@ +.. toctree:: + :maxdepth: 5 + :caption: Documentation: + + main + diff --git a/docs/build/html/_sources/specification/main.rst.txt b/docs/build/html/_sources/specification/main.rst.txt new file mode 100644 index 0000000..30f2661 --- /dev/null +++ b/docs/build/html/_sources/specification/main.rst.txt @@ -0,0 +1,39 @@ + +************* +Introduction +************* + +Declarative Stream Mapping(DSM) is a stream deserializer library that works for both XML and JSON. DSM allows you to make custom parsing, filtering, transforming, aggregating, grouping on any JSON or XML document at stream time(read once). There is no need to writing custom parser. DSM use yaml or json configuration file to parse data. Processed data can be deserialized to java classes. + +************* +Definitions +************* + + +_`DSM Document`: + A document (or set of documents) that defines or describes parsing element definition uses and conforms to the DSM Specification. + +_`Source Document`: + Document(File, Stream, String, HTTP Request Payload) contains JSON or XML data. + + + +************* +Format +************* + +DSM document is a JSON object, which maybe represented either in JSON or YAML format. +All field names in the specification are case sensitive. This includes all fields that are used as keys in a map, except where explicitly noted that keys are case insensitive. + +******************* +Document Structure +******************* + +DSM document may be made up single document or divided into multiple connected parts at the discretion of the user. +In later case, `$extends`_ fields must be used to reference those parts. + +.. include:: schema.rst +.. include:: AbsoluteTagPath.rst +.. include:: Expressions.rst +.. include:: MergeOfDocument.rst +.. include:: FieldAssignmentOrder.rst diff --git a/docs/build/html/_sources/specification/parsingElement/fields.rst.txt b/docs/build/html/_sources/specification/parsingElement/fields.rst.txt new file mode 100644 index 0000000..557cf65 --- /dev/null +++ b/docs/build/html/_sources/specification/parsingElement/fields.rst.txt @@ -0,0 +1,98 @@ + +.. _fields: + +fields +----------- + +------------ + + +The fields field is used to define the properties of complex objects. Only `Parsing Element`_ that has complex type_ can have the "fields" field. + +The fields field is a map that keys are fieldName of `Parsing Element`_ , values are string, `Parsing Element`_ or list of `Parsing Element`_ + + + + +Type of Value Definition +^^^^^^^^^^^^^^^^^^^^^^^^ +The value of the map can be empty, string, `Parsing Element`_ or array of `Parsing Element`_. + +Different value definitions create `Parsing Element`_ with some default values. + +Below explain type of value definition and the default values of the `Parsing Element`_ that it creates. + +empty: + :fieldName_: key of the map. + :dataType_: string + :path_: key of the map (fieldName) + :parentPath_: null + +string: + :fieldName_: key of the map. + :dataType_: value of the map + :path_: key of the map (fieldName) + :parentPath_: null + +`Parsing Element`_: + :fieldName_: key of the map. + other fields are can be defined or initialized with default values. + +Array of `Parsing Element`_: + some fields of objects can be read from the different tag in the source document. By making multiple definitions for one field, the value of different tags can be read. + +Example of different type of value definition: + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + name: # fieldName is "name" and dataType is string and the path is "/name" + category: + price: long # fieldName is "price" and dataType is "long" and the path is "/price" + categoryType: # fieldName is "categoryType" and it is "string" value and the path is "/categoryType" it has extra definition (default) + default: "foo" # default value a is a string. + productUnit: # this field contains two definition. one of that will win depending on the structure of source document. + - path: unit/unit_name # fieldName is "productUnit" and dataType is "long" and the path is "/unit/unit_name" + default: $ self.data.categoryType=='foo'? 'LT': 'KG' + + - path: mainUnit/unit_name # fieldName is "productUnit" and dataType is "long" and the path is "/mainUnit/unit_name" + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type"object", + "path":"/" , + "fields":{ + "name":"", + "category":"", + "price":"long", + "categoryType":{ + "default": "foo" + }, + "productUnit":[ + { "path": "unit/unit_name", + "default": " $self.data.categoryType=='foo'? 'LT': 'KG'" + }, + { + "path": "mainUnit/unit_name", + }, + ], + } + } + } + + diff --git a/docs/build/html/_sources/specification/parsingElement/filter.rst.txt b/docs/build/html/_sources/specification/parsingElement/filter.rst.txt new file mode 100644 index 0000000..bb8feca --- /dev/null +++ b/docs/build/html/_sources/specification/parsingElement/filter.rst.txt @@ -0,0 +1,116 @@ + +_`filter` +------------------------ + +The filter field determines whether the value of a `Parsing Element`_ +(complex or simple type_ does not matter) is added to the object tree. +The filter field is an expression_ that returns true or false. + + +The following objects are available in Expression Context. + +.. seealso:: + + expression_ + +.. csv-table:: + :header: Name, Data Type, Description, Example + :stub-columns: 1 + :delim: | + + params_ | Map | params_ object. | **params.dateFormat** =='dd.MM.yyyy' + self_ | Node_ | current node object that hold data of current complex type_ | **self.data.foo** => foo field of current node, **self.parent.data.foo** => foo field of parent node, **self.data.bar.foo** => foo field of bar object in current node. + all_ | Map | A map that stores all nodes by the "uniqueName_" of `Parsing Element`_ | **all.bar.data.foo** => foo field of **bar** node, **all.barList.data[0].foo** => *foo* field of first item of *barList* node + value | string | value of the current tag in `source document`_ | **value=='Computer'**,**value.startWith('bar')** + + +**Examples**: + + + +**Example 1** + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result + type: array + path:/ + filter: $self.data.category=='Computer' # collect all data that category field is 'Computer' + fields: + name: string + category: string + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"array", + "path":"/" , + "filter": "$self.data.category=='Computer'", + "fields":{ + "name":"string", + "category":"string" + } + } + } + +**Example 2** + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result + type: array + path:/ + fields: + name: string + category: + filter: $value=='Computer' # only assign "category" if "category" is "computer". + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"array", + "path":"/" , + "fields":{ + "name":"string", + "category":{ + "filter": "$value=='Computer'" + } + } + } + } + + + +**Possible Output Of Example 2** + +.. code-block:: json + + [{ + "name":"foo", + "category":"Computer" + }, + { + "name":"foo" + }] diff --git a/docs/build/html/_sources/specification/parsingElement/main.rst.txt b/docs/build/html/_sources/specification/parsingElement/main.rst.txt new file mode 100644 index 0000000..16482d8 --- /dev/null +++ b/docs/build/html/_sources/specification/parsingElement/main.rst.txt @@ -0,0 +1,644 @@ +.. _`Parsing Element`: + +_`Parsing Element Object` +========================= + + +Parsing Element is basic object of DSM. Parsing Element contains set of rules for parsing specific tag of `Source Document`_ + +Fields: + .. csv-table:: + :header: Field Name, Type, Description + :stub-columns: 1 + :delim: | + + fieldName_ | string | **REQUIRED** fieldName_ define the name of the property to expose by current object. the fieldName is unique in object. + dataType_ | string | **REQUIRED**. The data type of exposed field. it may have extra parameter provided with dataTypeParams_ + dataTypeParams_ | Map[string,any] | extra parameters for dataType field need to convert. for example. dateFormat for dataType + type_ | string | the name of the parsing strategy for the current field. the default is STD. + typeParams_ | Map[string,any] | it is used for passing extra parameter to dataType_ converter. typeParams_ field extended_ to params_ field. + path_ | string | The path field specifies the location of a tag in the `source document`_ relative to the path field of the higher-level Parsing Element definition. The default value is the value in the fieldName field. + parentPath_ | string |The parentPath_ field is used in a slightly more complex parsing definitions. it holds path to parent tag of the tag specified in the "path_" field. + default_ | string,`Default Object`_ | default value of the field if path_ not exist in the source document. if default value starts with "$" character it is accepted as expression_ and it is resolved by expression resolver. + filter_ | string | The Filter field determines whether the value of a `Parsing Element Object`_ (complex or simple type_ does not matter) is added to the object tree. The filter field is an expression_ that returns true or false. + transformationCode_ | string | this field refers to the definition of the transformation_ to be used to transform the tag value. + function_ | string | name of the function in functions_ map. + normalize_ | string| this field is used to normalize the value of tag_. İt is an expression. + uniqueName_ | string | When "fieldName" fields of complex `Parsing Element`_ definitions are the same in the DSM document, these definitions are differentiated by using the "uniqueKey" field. + xml_ | Map[string,any] | XML related configuration goes under this tag. + attribute_ | boolean | it is indicates that the current `Parsing Element Object`_ is an attribute on the tag pointed to by the parentPath field in the xml. + overwriteByDefault_| boolean | force using default_ field. Mostly used with filter field. + fields_ | Map[string,String - Parsing Element Object - [Parsing Element Object] ] | fields of the current object. its only valid for object and array type_ + `$ref`_ | string| $ref_ field is used to extends_ current config to given fragment_. it's value is an expression. + + + +_`fieldName` +-------------- + +------------------------------- + +**REQUIRED** The fieldName_ define the name of the property to expose by current object. the fieldName is unique in object.. However, a fieldName may have multiple `Parsing Element`. The fieldName is not explicitly defined. it is defined with fields_ property. The keys of fields_ map are the fieldName of the Parsing Element. + +In blow DSM document, id, name, and price are fieldName_ of the result object. The result_ object exposes id, name and price property + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + result: # fieldName is result + version: 1.0 + path: / + type:object + id: string # fieldName is id + fields: + price: double + name: string # fieldName is name + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" + "fields":{ + "id":"string", + "name":"double", + "price":"double" + } + } + } + + + + + + +_`dataType` +---------- + +------------------------------ + +The dataType field defines data type (string, int, boolean etc.) of the exposed property. it is basicity a converter from string to given dataType type. +it may need extra parameters to convert a string to given data dataType. Extra parameters may be provided with params_ or dataTypeParams_. + +Supported dataType name and their corresponding java class: + +.. csv-table:: + :header: Type Name, Java Type, Extra Parameters + :stub-columns: 1 + :delim: | + + int | int| + float | float | + short | short | + double | double | + long | long | + _`date` | date | dateFormat(required) + boolean | boolean | + char | char | + BigDecimal | BigDecimal | + BigInteger | BigInteger | + + +.. _typeParamsExample: + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + params: + dateFormat: dd.MM.yyyy # default 'dateFormat' for all 'date' dataType + result: + type:object + path: / + fields: + id: string + name: string # implicitly defined dataType. dataType is string + price: + dataType: double # explicitly defined dataType dataType. type is double + createDate: date # implicitly defined the date dataType. and 'dateFormat' is defined in params field. + modifiedTime: + dataType: date # explicitly defined the date dataType. and 'dateFormat' is defined in dataTypeParams field. + dataTypeParams: + dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'" + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "params":{ + "dateFormat": "dd.MM.yyyy" + }, + "result":{ + "type":"object", + "path":"/", + "fields":{ + "id":"string", + "name":"double", + "price":{ + "dataType": "double" + }, + "createDate": "date", + "modifiedTime": { + "dataType": "date", + "dataTypeParams": { + "dateFormat":"yyyy-MM-dd'T'HH:mm:ss'Z'" + } + } + } + } + } + +_`dataTypeParams` +---------------- + +-------------------------------- + +dataTypeParams is used for passing extra parameters to a dataType_ convert. dataTypeParams field extended_ to params_ field. + +Check `example `_ here. + + +.. include:: parsingElement/tagTypeAndTagTypeParams.rst + +.. include:: parsingElement/tagPathAndTagParentPath.rst + +.. include:: parsingElement/fields.rst + +.. include:: parsingElement/filter.rst + + + +_`default` +------------------------ + +------------------ + +The *default* field holds the value to be assigned to a property by default. The default value is assigned when the path_ does not match the absolute_ path of any tag in the `source document`_. +If the value of the default field is a string, +this value is accepted as the value_ field of the `Default Object`_. + +.. seealso:: + + `Default Object`_ + + Expression_ + +`assignment order`_ of the default is from the bottom to up in an object. + +Examples + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + name: + - filter: $ self.data.categoryType=='foo' + default: + value: foo # force set name to foo with filter + force: true + - path: name + category: string + productUnit: + default: $ self.data.categoryType=='foo'? 'LT': 'KG' # default value is expression. this default value is assigned after "categoryType" field assigned. + categoryType: + default: "foo" # default value a is a string. + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "name":"string", + "category":"string", + "productUnit":{ + "default": " $self.data.categoryType=='foo'? 'LT': 'KG'" + }, + "categoryType":{ + "default": "foo" + } + } + } + } + + + + + + + + +_`transformationCode` +---------------------- + +---------- + +*transformationCode* field refers to the definition of the transformation_ to be used to transform the tag value. + +Below definition work as follows: + + - value of tag "/country_code" is read from `source document`_ + - if this value exist in "COUNTRY_CODE_TO_NAME" transformation_ definition, get value that match. + - if not exist, get "DEFAULT" value of "COUNTRY_CODE_TO_NAME" transformation_ definition + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + transformations: + COUNTRY_CODE_TO_NAME: + map: + DEFAULT: Other + TR: Turkey + US: United States + + result: + type: object + path: / + fields: + country: + path: country_code + transformationCode: COUNTRY_CODE_TO_NAME + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "transformations":{ + "COUNTRY_CODE_TO_NAME":{ + "map":{ + "TR":"Turkey", + "US":"United States", + "DEFAULT":"Other" + } + } + }, + "result":{ + "type": "object", + "path": "/", + "fields"{ + "country":{ + "path": "country_code" + "transformationCode": "COUNTRY_CODE_TO_NAME" + } + } + } + } + +.. seealso:: + + Transformations_ + + +_`function` +------------- + +----------------- + +The *function* field refers to the definition of functions_ field to be used for the custom operation. +For more detail about how functions_ works, look at functions_ sections. + +Below definition work as follows: + + - all fields of product are read from `source document`_ + - When the "/product" tag is closed, the "com.example.InsertProduct" function in the "insertProduct" definition is called. + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + functions: + insertProduct: com.example.InsertProduct + + result: + type: object + path: /product + function: insertProduct + fields: + name: string + price: long + image: string + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "functions":{ + "insertProduct":"com.example.InsertProduct" + }, + "result":{ + "type": "object", + "path": "/", + "function": "insertProduct", + "fields": { + "name": "string", + "price": "long", + "image": "string" + } + } + } + + +.. seealso:: + + functions_ + + +_`uniqueName` +------------- + +---------------------- + +When "fieldName" fields of complex `Parsing Element`_ definitions are the same in the DSM document, +these definitions are differentiated by using the "uniqueKey" field. +This field is optional. The default value is the value of the "fieldName" field. +The uniqueName field may need in very complex document parsing. + + +Example Case: + +In the following DSM document, both the users and the orders objects have a category field and the category field is an object. +The uniqueName_ field is used to differentiate the category objects. + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + users: + type: array + fields: + name: string + email: string + category: + type: object + uniqueName: userCategory + fields: + categoryName: string + order: + type: object + fields: + id: string + category: + type: object + uniqueName: orderCategory + fields: + categoryName: string + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1, + "result": { + "type": "object", + "path": "/", + "fields": { + "users": { + "type": "array", + "fields": { + "name": "string", + "email": "string", + "category": { + "type": "object", + "uniqueName": "userCategory", + "fields": { + "categoryName": "string" + } + } + } + }, + "order": { + "type": "object", + "fields": { + "id": "string", + "category": { + "type": "object", + "uniqueName": "orderCategory", + "fields": { + "categoryName": "string" + } + } + } + } + } + } + } + + +_`normalize` +-------------- + +------------------- + +The normalize is used to normalize the value of the tag being read. +Changes can be made to the raw string value of the tag by using normalize field. +The value of this field is an expression. + +The following objects are available in Expression Context. + + +.. csv-table:: + :header: Name, Data Type, Description, Example + :stub-columns: 1 + :delim: | + + params_ | Map | params_ object. | **params.dateFormat** =='dd.MM.yyyy' + self_ | Node_ | current node object that hold data of current complex type_ | **self.data.foo** => foo field of current node, **self.parent.data.foo** => foo field of parent node, **self.data.bar.foo** => foo field of bar object in current node. + all_ | Map | A map that stores all nodes by the "uniqueName_" of `Parsing Element Object`_ | **all.bar.data.foo** => foo field of **bar** node, **all.barList.data[0].foo** => *foo* field of first item of *barList* node + value | string | raw string value of the current tag in `source document`_ | **value=='Computer'**,**value.startWith('bar')** + +.. seealso:: + + `Expression`_ + +_`xml` +-------------- + +----------- + +The xml field is used to make extra definitions and to change "path" and "type" fields for XML format. + +check `XML Object`_ for more detail + +.. seealso:: + + `XML Object`_ + + + +_`$ref` +--------- + +------------------ + +$ref field is used to extends_ `Parsing Element`_ to given fragments_. it's value is a Load Time Expression. +fragments_ can be extends_ another fragments_ but can not extends itself. +Sometimes we don't need parent properties. To exclude parent properties, define dataType_ as "exclude". In example bellow category property is excluded. + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: array + path: / + xml: + path: "/Pets/Pet" + $ref: $fragments.pet + fields: + category: exclude # import all properties of fragments.pet except category property. + isPopular: + default $self.data.tags.stream().anyMatch(s->s.name=='Popular') + fragments: + tag: + type: object + fields: + id: int + name: string + category: + type: object + fields: + id: int + name: string + pet: + type: object + fields: + id: long + name: string + status: string + category: + $ref: $fragments.category + photoUrls: + type: array + path: photoUrls + xml: + path: photoUrls/photoUrls + tags: + type: array + path: tags + xml: + path: tags/tag + $ref: $fragments.tag + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1, + "result": { + "type": "array", + "path": "/", + "xml": { + "path": "/Pets/Pet" + }, + "$ref": "$fragments.pet", + "fields": { + "category": "exclude", + "isPopular": "default $self.data.tags.stream().anyMatch(s->s.name=='Popular')" + } + }, + "fragments": { + "tag": { + "type": "object", + "fields": { + "id": "int", + "name": "string" + } + }, + "category": { + "type": "object", + "fields": { + "id": "int", + "name": "string" + } + }, + "pet": { + "type": "object", + "fields": { + "id": "long", + "name": "string", + "status": "string", + "category": { + "$ref": "$fragments.category" + }, + "photoUrls": { + "type": "array", + "path": "photoUrls", + "xml": { + "path": "photoUrls/photoUrls" + } + }, + "tags": { + "type": "array", + "path": "tags", + "xml": { + "path": "tags/tag" + }, + "$ref": "$fragments.tag" + } + } + } + } + } + + diff --git a/docs/build/html/_sources/specification/parsingElement/tagPathAndTagParentPath.rst.txt b/docs/build/html/_sources/specification/parsingElement/tagPathAndTagParentPath.rst.txt new file mode 100644 index 0000000..ea498ec --- /dev/null +++ b/docs/build/html/_sources/specification/parsingElement/tagPathAndTagParentPath.rst.txt @@ -0,0 +1,134 @@ + +_`path` and _`parentPath` +------------------------------- + +The path and parentPath fields indicate which tags are used in the `source document`_ +during parsing. The value of those fields are regular expressions. + +The **path** field specifies the location of a tag in the `source document`_ +relative to the path field of the higher-level `Parsing Element`_ definition. +The default value is the value in the fieldName_ field. + +The **parentPath** field is used in a slightly more complex parsing definitions. +it holds path to parent tag of the tag specified in the "path" field. + + +The path_ and parentPath_ fields can be defined as the relative path as in unix. +Relative paths are resolved according to the structure in the DSM document, +not by the structure in the source file. + +Some example of relative path: + +:current: ./ + +:parent: ../ + +:parentOfParent: ../../ + +:categoryInParent: ../category + +:categoryInCurrent: ./category + +To find the exact tag path for the current `Parsing Element`_, starting from the result field, +all the *parentPath* and *path* fields from top to bottom are merged with the "/" character. + +**tagParentAbsolutePath** and **tagAbsolutePath** evaluated as follow: + + **currentObject** mean is `Parsing Element`_ that current path and parentPath is defined + **parentObject** mean is parent `Parsing Element`_ of currentObject + + + + - parentObject = if (**parentPath+path**) is relative path then find parentObject by resolving relative path else currentObject.parent + + - **tagParentAbsolutePath** = parentObject.path+"/"+currentObject.parentPath + + - **tagAbsolutePath** = absoluteParentPath+"/"+currentObject.path + + +if **tagAbsolutePath** regex match any absolute_ path of tag, value of this tag evaluated by type_ + + + + +To explain with example: + +.. code-block:: yaml + + result: + path: /orders/order #path = orders/order + #parentPath = "" + #tagAbsolutePath= /orders/order + #tagParentAbsolutePath= / + fields: + defaultName: #path =defaultName (default value is fieldName) + #parentPath = "" + #tagParentAbsolutePath =/orders/order (parent(result) absoluteTagPath)) + #tagAbsolutePath =/orders/order/defaultName + tagPathDefined: + path: status #path =status + #parentPath = "" + #tagParentAbsolutePath =/orders/order (parent(result) absoluteTagPath)) + #tagAbsolutePath =/orders/order/status + tagPathAndParentPath: + path: name #path = name + parentPath: category #parentPath = category + #tagParentAbsolutePath =/orders/order/category + #tagAbsolutePath =/orders/order/category/name + + innerObject: + type: object + path: foo #path = "innerObject" + #parentPath = "" + #tagParentAbsolutePath =/orders/order + #tagAbsolutePath =/orders/order/innerObject + fields: + normalPathInInnerObject: #path = "normalPathInInnerObject" + #parentPath = "" + #tagParentAbsolutePath =/orders/order/innerObject + #tagAbsolutePath =/orders/order/innerObjcet/normalPathInInnerObject + relativeTagPath: + path:./defaultName #path = ../defaultName (only level up) + #parentPath = "" + #tagParentAbsolutePath =/orders/order + #tagAbsolutePath =/orders/order/defaultName + relativeParentPath: + path:defaultName #path = defaultName + parentPath:../ #parentPath = "../" (only level up) + #tagParentAbsolutePath =/orders/order + #tagAbsolutePath =/orders/order/defaultName relativeTagPathAndParentPath: + path:../defaultName #path = defaultName + parentPath:../ #parentPath = "../" (only level up) + #tagParentAbsolutePath =/orders/order + #tagAbsolutePath =/orders/order/../defaultName (relative path of parentPath important. path considered as regex) + + relativePathFromResult: + path:/orders/order/defaultName #path = /orders/order/defaultName + #parentPath = "" + #tagParentAbsolutePath =/orders/order/defaultName + #tagAbsolutePath =/orders/order + + + + + +**tagAbsolutePath and tagParentAbsolutePath**: + + +.. csv-table:: + :header: fieldName, path, parentPath,tagAbsolutePath, tagParentAbsolutePath + :stub-columns: 1 + :align: left + :delim: | + + result | orders/order | | order/simpleOrder | / + result | orders/order | | order/simpleOrder | / + defaultName | defaultName(default value is fieldName) | order/simpleOrder/defaultName | order/simpleOrder + tagPathDefined | status | order/simpleOrder/status | order/simpleOrder + tagPathAndParentPath | status | order/simpleOrder/category/name | order/simpleOrder/category + innerObject | innerObject | order/simpleOrder/innerObject | order/simpleOrder + normalPathInInnerObject | normalPathInInnerObject | order/simpleOrder/innerObject/normalPathInInnerObject | order/simpleOrder/innerObject + relativeTagPath | defaultName | order/simpleOrder/defaultName | order/simpleOrder + relativeParentPath | defaultName | order/simpleOrder/defaultName | order/simpleOrder + relativeTagPathAndParentPath | defaultName | order/simpleOrder/..defaultName (relative path of parentPath important. path considered as regex) | order/simpleOrder + relativePathFromResult | /orders/order/defaultName | order/simpleOrder/defaultName | order/simpleOrder diff --git a/docs/build/html/_sources/specification/parsingElement/tagTypeAndTagTypeParams.rst.txt b/docs/build/html/_sources/specification/parsingElement/tagTypeAndTagTypeParams.rst.txt new file mode 100644 index 0000000..e964f28 --- /dev/null +++ b/docs/build/html/_sources/specification/parsingElement/tagTypeAndTagTypeParams.rst.txt @@ -0,0 +1,573 @@ +_`type` +------------- + +---------------------------------- + +type_ defines how tags in the source document are parsed. it also defines the structure of the output object and hierarchy of the object tree. it may need extra parameters. Extra parameters are provided with typeParams_ field that extended_ to params_ field. +Basically, there are two main "type" categories which are "complex", and "simple". The complex category includes "tagTypes" which exposes complex data dataType such as object or arrays. the simple category includes tagTypes which expose data type in the dataType_ field. + + +Supported type_'s: + +.. csv-table:: + :header: Type Name, Category,Java Type, Extra Parameters + :stub-columns: 1 + :delim: | + + std_ | Simple | dataType_ | default type_ if not defined explicitly + object_ | Complex | Map | + array_ | Complex | List - List | + sum_ | Simple | dataType_ | fields: array of fieldName of current object. + multiply_ | Simple | dataType_ | **fields**: array of fieldName of current object. + divide_ | Simple | dataType_ | **fields**: array of fieldName of current object. + join_ | Simple | dataType_ | **fields**: array of fieldName of current object, **separator**: separator string. default is comma(,) + + + +_`std` +^^^^^^^^ + +------------------ + +std is basic type_ which copy the value of the tag in the source document to the current object. std is the default value of the type_ field. Data dataType_ is defined in dataType_ype_ field. + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + foo: string # tag type is STD + bar: int # tag type is STD + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "foo":"string", + "bar":"int" + } + } + } + + + +_`object` +^^^^^^^^^^^^ + +--------------- + +object type_ is used to expose an object. `Parsing Element`_ which has "object" type_ must have 'fields_' field. + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + id: string + name: string + price: double + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "id":"string", + "name":"string", + "price":"double" + } + } + } + + +Above DSM document generate following output(values are only example) : + +.. code-block:: json + + { + "id":"11111", + "name":"foo", + "price":1111.111 + } + + + + +_`array` +^^^^^^^^^^^^ + +--------------------------- + +array type_ is used to expose an array. Items of the array may be a object or simple dataType_. if `Parsing Element`_ has "fields_" field then the array type_ exposes List. if fields_ field is not defined, the data type of array item decided dataType_ field. + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: array # EXPOSE [Object] array of Object + path: / + fields: + id: string + name: string + price: double + tags: # EXPOSE [string] array of string + type: array + path: tag + type: string + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/", + "fields":{ + "id":"string", + "name":"string", + "price":"double", + "tags":{ + "type": "array", + "path": "tag", + "type": "string" + } + } + } + } + + +Above DSM document generate following output(values are only example) : + +.. code-block:: json + + [{ + "id":"11111", + "name":"foo", + "price":1111.111, + "tags":["foo","bar"] + }] + + + + +_`sum` +^^^^^^^^^^^^^^ + +----------------------------- + + +*sum* type_ is used to sum properties defined with "fields" in **typeParams_**. if one of the properties that defined in *fields* does not exist in the current object, it is accepted as ZERO. + + + +if current property(`Parsing Element`_ that "*sum*" type_ is defined on) is defined in "fields" in **typeParams_**, current property value is added to total result.(sum with self) + +**(Explained with example below)** + +**typeParams**: + +.. csv-table:: + :header: Name, Type,Description + :stub-columns: 1 + :delim: | + + fields | array | **REQUIRED** list of fieldName_ of the properties in parent `Parsing Element`_ to sum. + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + foo: int + bar: bar + fooAndBar: + path: \. # when current object closed + type: sum # declare sum type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar] # sum foo,and bar fields then set to fooAndBar property of current object. + sumWithSelf: + type: sum # declare sum type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar,sumWithSelf] # sum foo, bar and sumWithSelf(current field) fields then set sumWithSelf to total property of current object. + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "foo":"int", + "bar":"int", + "fooAndBar":{ + "path":"\.", + "type": "sum", + "typeParams":{ + "fields":["foo","bar"] + } + }, + "sumWithSelf":{ + "type": "sum", + "type":"int", + "typeParams":{ + "fields":["foo","bar","sumWithSelf"] + } + } + } + } + } + + + + + +_`multiply` +^^^^^^^^^^^^^^ + +-------------------- + +*multiply* type_ is used to multiply properties defined with "fields" in **typeParams_**. if one of the properties that defined in *fields* does not exist in the current object, it is accepted as ONE. + + +if current property(`Parsing Element`_ that "*multiply*" type_ is defined on) is defined in "fields" in **typeParams_**, current property value is multiplied with total result. (multiply with self) + +**(Explained with example below)** + +typeParams_: + +.. csv-table:: + :header: Name, Type,Description + :stub-columns: 1 + :delim: | + + fields | array | **REQUIRED** list of field name of the properties in **current object** to multiply. + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + foo: int + bar: int + fooAndBar: + path: \. # when current object closed + type: multiply # declare multiply type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar] # multiply foo,and bar fields then set it to fooAndBar property of current object. + multiplyWithSelf: + type: multiply # declare multiply type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar,multiplyWithSelf] # multiply foo, bar and multiplyWithSelf(current field) fields then set it to multiplyWithSelf property of current object. + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "foo":"int", + "bar":"int", + "fooAndBar":{ + "path":"\.", + "type": "multiply", + "typeParams":{ + "fields":["foo","bar"] + } + }, + "multiplyWithSelf":{ + "type": "multiply" + "type":"int", + "typeParams":{ + "fields":["foo","bar","multiplyWithSelf"] + } + } + } + } + } + + + +_`divide` +^^^^^^^^^^^^^^ + +------------------------ + +*divide* type_ is used to divide properties defined with "fields" in **typeParams_**. if one of the properties that defined in *fields* does not exist in the current object, it is accepted as ONE. + + +if current property(`Parsing Element`_ that "*divide*" type_ is defined on) is defined in "fields" in **typeParams_**, current property value is divided with total result. (divide with self) + +**(Explained with example below)** + + +typeParams_: + +.. csv-table:: + :header: Name, Type,Description + :stub-columns: 1 + :delim: | + + fields | array | **REQUIRED** list of field name of the properties in **current object** to divide. + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + foo: int + bar: int + fooAndBar: + path: \. # when current object closed + type: divide # declare divide type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar] # divide foo with bar (foo/bar) fields then set it to fooAndBar property of current object. + divideWithSelf: + type: divide # declare divide type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar,divideWithSelf] # divide foo with bar then divide with divideWithSelf(current field) (foo/bar/divideWithSelf) fields then set it to sumWithSelf property of current object. + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "foo":"int", + "bar":"int", + "fooAndBar":{ + "path":"\.", + "type": "divide", + "typeParams":{ + "fields":["foo","bar"] + } + }, + "divideWithSelf":{ + "type": "divide", + "type":"int", + "typeParams":{ + "fields":["foo","bar","divideWithSelf"] + } + } + } + } + } + + + +_`join` +^^^^^^^^^^^^^^^^ + +------------------------- + +*join* type_ is used to join properties defined with "fields" in **typeParams_**. if one of the properties that defined in *fields* does not exist in the current object, it is skipped. + +if current property(`Parsing Element`_ that "*join*" type_ is defined on) is defined in +"fields" in **typeParams_**, current property value is included in to joining (join with self) +Values are separated by *separator* defined in "typeParams_". The default separator is a comma(,) + +typeParams_: + +.. csv-table:: + :header: Name, Type,Description + :stub-columns: 1 + :delim: | + + fields | array | **REQUIRED** list of field name of the properties in **current object** to join. + separator | string | separator string. default is comma(i) + + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + foo: string + bar: string + fooAndBar: + path: \. # when current object closed + type: join # declare join type to sum foo and bar field + type:int + typeParams: + fields:[foo,bar] # join foo and bar (foo,bar) fields then set it to fooAndBar property of current object. + joinWithSelf: + type: join # declare join type to sum foo and bar field + type:int + typeParams: + separator: & + fields:[foo,bar,sumWithSelf] # join foo,bar, and joinWithSelf(current field) (foo&bar&joinWithSelf) fields then set it to joinWithSelf property of current object. + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "foo":"string", + "bar":"string", + "fooAndBar":{ + "path":"\.", + "type": "join", + "typeParams":{ + "fields":["foo","bar"] + } + }, + "joinWithSelf":{ + "type": "join", + "type":"int", + "typeParams":{ + "separator": "&", + "fields":["foo","bar","joinWithSelf"] + } + } + } + } + } + + + +_`typeParams` +---------------------- + +--------------------- + +typeParams is used for passing extra parameters to type_ field. The typeParams field is extended_ to params_ field. + +Examples: + +.. content-tabs:: + + .. tab-container:: yaml + :title: YAML + + .. code-block:: yaml + + version: 1.0 + result: + type: object + path: / + fields: + foo: string + bar: string + fooAndBar: + path: \. # when current object closed + type: join # declare join type to concat foo and bar field + type:int + typeParams: # typeParams is used to pass fields parameter to type + fields:[foo,bar] + + .. tab-container:: json + :title: JSON + + .. code-block:: json + + { + "version": 1.0, + "result":{ + "type":"object", + "path":"/" , + "fields":{ + "foo":"string", + "bar":"string", + "fooAndBar":{ + "path":"\.", + "type": "join", + "typeParams":{ + "fields":["foo","bar"] + } + } + } + } + } + \ No newline at end of file diff --git a/docs/build/html/_sources/specification/schema.rst.txt b/docs/build/html/_sources/specification/schema.rst.txt new file mode 100644 index 0000000..92e067a --- /dev/null +++ b/docs/build/html/_sources/specification/schema.rst.txt @@ -0,0 +1,11 @@ +********** +Schema +********** +In the following description, if a field is not explicitly REQUIRED or described with a MUST or SHALL, it can be considered OPTIONAL. + +.. include:: RootObject.rst +.. include:: parsingElement/main.rst +.. include:: TransformationElement.rst +.. include:: DefaultObject.rst +.. include:: XMLObject.rst + diff --git a/docs/build/html/_static/ajax-loader.gif b/docs/build/html/_static/ajax-loader.gif new file mode 100644 index 0000000..61faf8c Binary files /dev/null and b/docs/build/html/_static/ajax-loader.gif differ diff --git a/docs/build/html/_static/basic.css b/docs/build/html/_static/basic.css new file mode 100644 index 0000000..6f40830 --- /dev/null +++ b/docs/build/html/_static/basic.css @@ -0,0 +1,643 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/build/html/_static/comment-bright.png b/docs/build/html/_static/comment-bright.png new file mode 100644 index 0000000..15e27ed Binary files /dev/null and b/docs/build/html/_static/comment-bright.png differ diff --git a/docs/build/html/_static/comment-close.png b/docs/build/html/_static/comment-close.png new file mode 100644 index 0000000..4d91bcf Binary files /dev/null and b/docs/build/html/_static/comment-close.png differ diff --git a/docs/build/html/_static/comment.png b/docs/build/html/_static/comment.png new file mode 100644 index 0000000..dfbc0cb Binary files /dev/null and b/docs/build/html/_static/comment.png differ diff --git a/docs/build/html/_static/contentui.css b/docs/build/html/_static/contentui.css new file mode 100644 index 0000000..326d3da --- /dev/null +++ b/docs/build/html/_static/contentui.css @@ -0,0 +1,132 @@ +/* + * right column for sphinx_rtd_theme + */ +.clear { + clear: both; +} + +@media screen and (min-width: 1300px) { + .wy-nav-content { + max-width: none; + } + + .with-columns .wy-nav-content { + background: linear-gradient(90deg, #fcfcfc 52%, #eeeeee 52%); + } + + .with-columns .wy-nav-content .wy-breadcrumbs , + .with-columns .section > h1, + .with-columns .section > h2, + .with-columns .section > h3, + .with-columns footer { + width: 50%; + } + + .with-columns .section { + clear: both; + } + + .left-col.container { + float: left; + width: 50%; + margin-right: 4%; + } + + .right-col.container { + float: left; + width: 45%; + } + + /* + * tab selector fixed in top + */ + .with-columns .contenttab-selector.in-right-col { + display: block; + position: fixed; + top: 0; + right: 0; + width: calc(48% - 144px); + background: #444; + padding: 5px 10px; + } + +} + +/** + * + */ +.toggle-tab { + margin-bottom: 40px; +} + +.toggle-header { + display: block; + clear: both; + cursor: pointer; +} +.toggle-header strong {color: #2980b9 } + +.toggle-header:after { + content: " ▼"; +} + +.toggle-header.open:after { + content: " ▲"; +} + +.toggle-content { + display: none; + margin-bottom: 20px; +} + +/* + * tab menu + */ +ul.contenttab-selector { + display:block; + list-style-type: none; + margin: 0 0 10px; + padding: 0; + line-height: normal; + overflow: auto; +} +ul.contenttab-selector li { + display: block; + cursor: pointer; + font-weight: bold; + margin: 0 5px 0 0; + padding: 5px 10px; + float: left; + background-color: #999; + color: #fff; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + -khtml-border-radius: 5px; +} +.rst-content .section ul.contenttab-selector, +.rst-content .toctree-wrapper ul.contenttab-selector, +article ul.contenttab-selector{ + line-height: normal; + margin: 0 0 10px; +} +.rst-content .section ul.contenttab-selector li, +.rst-content .toctree-wrapper ul.contenttab-selector li, +article ul.contenttab-selector li{ + margin-left: 0; +} +ul.contenttab-selector li:hover { + background-color: #777; +} +ul.contenttab-selector li.selected { + background-color: #2980b9; +} +ul.contenttab-selector li.selected:hover { + background-color: #333; +} +.content-tabs { + margin: 10px 0 20px 0; +} +.tab-content { + clear: both; +} diff --git a/docs/build/html/_static/contentui.js b/docs/build/html/_static/contentui.js new file mode 100644 index 0000000..6ecdb2f --- /dev/null +++ b/docs/build/html/_static/contentui.js @@ -0,0 +1,74 @@ + +$(function() { + /* + * Right column logic + */ + if ($(".right-col").length) { + $(".right-col").after('
'); + $(".right-col").parents('body').addClass('with-columns'); + } + + /** + * Toggle logic + */ + $('.toggle-content').hide() + $('.toggle-header').click(function () { + $(this).toggleClass("open"); + $(this).next('.toggle-content').toggle('400'); + }) + + /** + * Dynamic multiple content block. + */ + var top_sel = {} + + $('div.content-tabs').each(function() { + var contenttab_sel = $('
    ', { class: "contenttab-selector" }); + var i = 0; + + if ($(this).hasClass('right-col')){ + contenttab_sel.addClass('in-right-col'); + } + + $('.tab-content', this).each(function() { + var sel_item = $('
  • ', { + class: $(this).attr('id'), + text: $(this).find('.tab-title').text() + }); + $(this).find('.tab-title').remove(); + if (i++) { + $(this).hide(); + } else { + sel_item.addClass('selected'); + } + contenttab_sel.append(sel_item); + $(this).addClass('contenttab'); + }); + + $('.tab-content', this).eq(0).before(contenttab_sel); + contenttab_sel = null; + i = null; + }); + + + $('.contenttab-selector li').click(function(evt) { + evt.preventDefault(); + + if ($(this).parents('.in-right-col').length){ + var tabsblock = $('.right-col'); + }else{ + var tabsblock = $(this).parents('.content-tabs'); + } + + var sel_class = $(this).attr('class'); + $('div.contenttab',tabsblock).hide(); + $('div#' + sel_class,tabsblock).show(); + + $('ul.contenttab-selector li', tabsblock).removeClass('selected'); + $('ul.contenttab-selector li.' + sel_class, tabsblock).addClass('selected'); + + sel_class = null; + }); + +}); + diff --git a/docs/build/html/_static/css/badge_only.css b/docs/build/html/_static/css/badge_only.css new file mode 100644 index 0000000..323730a --- /dev/null +++ b/docs/build/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../fonts/fontawesome-webfont.eot");src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} diff --git a/docs/build/html/_static/css/theme.css b/docs/build/html/_static/css/theme.css new file mode 100644 index 0000000..b19dbfe --- /dev/null +++ b/docs/build/html/_static/css/theme.css @@ -0,0 +1,6 @@ +/* sphinx_rtd_theme version 0.4.2 | MIT license */ +/* Built 20181005 13:10 */ +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:.5cm}p,h2,.rst-content .toctree-wrapper p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.7.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2?v=4.7.0") format("woff2"),url("../fonts/fontawesome-webfont.woff?v=4.7.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.7.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.wy-menu-vertical li span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.rst-content .fa-pull-left.admonition-title,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content dl dt .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.rst-content code.download span.fa-pull-left:first-child,.fa-pull-left.icon{margin-right:.3em}.fa.fa-pull-right,.wy-menu-vertical li span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.rst-content .fa-pull-right.admonition-title,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content dl dt .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.rst-content code.download span.fa-pull-right:first-child,.fa-pull-right.icon{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-vcard:before,.fa-address-card:before{content:""}.fa-vcard-o:before,.fa-address-card-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content table>caption .headerlink,.rst-content table>caption a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content table>caption .headerlink,.rst-content table>caption .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content table>caption .headerlink,.rst-content table>caption .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.admonition{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo,.rst-content .wy-alert-warning.admonition{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title,.rst-content .wy-alert-warning.admonition .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.admonition{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.admonition{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.admonition{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 .3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.3576515979%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.3576515979%;width:48.821174201%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.3576515979%;width:31.7615656014%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type="datetime-local"]{padding:.34375em .625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{position:absolute;content:"";display:block;left:0;top:0;width:36px;height:12px;border-radius:4px;background:#ccc;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27AE60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:.3em;display:block}.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:before,.wy-breadcrumbs:after{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs li code,.wy-breadcrumbs li .rst-content tt,.rst-content .wy-breadcrumbs li tt{padding:5px;border:none;background:none}.wy-breadcrumbs li code.literal,.wy-breadcrumbs li .rst-content tt.literal,.rst-content .wy-breadcrumbs li tt.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a{color:#404040}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980B9;text-align:center;padding:.809em;display:block;color:#fcfcfc;margin-bottom:.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:gray}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:gray}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{width:100%}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:before,.rst-breadcrumbs-buttons:after{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1100px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px 12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;display:block;overflow:auto}.rst-content pre.literal-block,.rst-content div[class^='highlight']{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px 0}.rst-content pre.literal-block div[class^='highlight'],.rst-content div[class^='highlight'] div[class^='highlight']{padding:0px;border:none;margin:0}.rst-content div[class^='highlight'] td.code{width:100%}.rst-content .linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;display:block;overflow:auto}.rst-content div[class^='highlight'] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content pre.literal-block,.rst-content div[class^='highlight'] pre,.rst-content .linenodiv pre{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;font-size:12px;line-height:1.4}@media print{.rst-content .codeblock,.rst-content div[class^='highlight'],.rst-content div[class^='highlight'] pre{white-space:pre-wrap}}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last,.rst-content .admonition .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .section ol p:last-child,.rst-content .section ul p:last-child{margin-bottom:24px}.rst-content .line-block{margin-left:0px;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content .toctree-wrapper p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"";font-family:FontAwesome}.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content .toctree-wrapper p.caption:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:baseline;position:relative;top:-0.4em;line-height:0;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:gray}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.docutils.citation tt,.rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}.rst-content table.docutils td .last,.rst-content table.docutils td .last :last-child{margin-bottom:0}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content tt,.rst-content tt,.rst-content code{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040}.rst-content pre,.rst-content kbd,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold;margin-bottom:12px}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-weight:normal;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child,.rst-content code.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Lato";src:url("../fonts/Lato/lato-regular.eot");src:url("../fonts/Lato/lato-regular.eot?#iefix") format("embedded-opentype"),url("../fonts/Lato/lato-regular.woff2") format("woff2"),url("../fonts/Lato/lato-regular.woff") format("woff"),url("../fonts/Lato/lato-regular.ttf") format("truetype");font-weight:400;font-style:normal}@font-face{font-family:"Lato";src:url("../fonts/Lato/lato-bold.eot");src:url("../fonts/Lato/lato-bold.eot?#iefix") format("embedded-opentype"),url("../fonts/Lato/lato-bold.woff2") format("woff2"),url("../fonts/Lato/lato-bold.woff") format("woff"),url("../fonts/Lato/lato-bold.ttf") format("truetype");font-weight:700;font-style:normal}@font-face{font-family:"Lato";src:url("../fonts/Lato/lato-bolditalic.eot");src:url("../fonts/Lato/lato-bolditalic.eot?#iefix") format("embedded-opentype"),url("../fonts/Lato/lato-bolditalic.woff2") format("woff2"),url("../fonts/Lato/lato-bolditalic.woff") format("woff"),url("../fonts/Lato/lato-bolditalic.ttf") format("truetype");font-weight:700;font-style:italic}@font-face{font-family:"Lato";src:url("../fonts/Lato/lato-italic.eot");src:url("../fonts/Lato/lato-italic.eot?#iefix") format("embedded-opentype"),url("../fonts/Lato/lato-italic.woff2") format("woff2"),url("../fonts/Lato/lato-italic.woff") format("woff"),url("../fonts/Lato/lato-italic.ttf") format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:url("../fonts/RobotoSlab/roboto-slab.eot");src:url("../fonts/RobotoSlab/roboto-slab-v7-regular.eot?#iefix") format("embedded-opentype"),url("../fonts/RobotoSlab/roboto-slab-v7-regular.woff2") format("woff2"),url("../fonts/RobotoSlab/roboto-slab-v7-regular.woff") format("woff"),url("../fonts/RobotoSlab/roboto-slab-v7-regular.ttf") format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:url("../fonts/RobotoSlab/roboto-slab-v7-bold.eot");src:url("../fonts/RobotoSlab/roboto-slab-v7-bold.eot?#iefix") format("embedded-opentype"),url("../fonts/RobotoSlab/roboto-slab-v7-bold.woff2") format("woff2"),url("../fonts/RobotoSlab/roboto-slab-v7-bold.woff") format("woff"),url("../fonts/RobotoSlab/roboto-slab-v7-bold.ttf") format("truetype")} diff --git a/docs/build/html/_static/doctools.js b/docs/build/html/_static/doctools.js new file mode 100644 index 0000000..0c15c00 --- /dev/null +++ b/docs/build/html/_static/doctools.js @@ -0,0 +1,311 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var bbox = span.getBBox(); + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + var parentOfText = node.parentNode.parentNode; + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); \ No newline at end of file diff --git a/docs/build/html/_static/down-pressed.png b/docs/build/html/_static/down-pressed.png new file mode 100644 index 0000000..5756c8c Binary files /dev/null and b/docs/build/html/_static/down-pressed.png differ diff --git a/docs/build/html/_static/down.png b/docs/build/html/_static/down.png new file mode 100644 index 0000000..1b3bdad Binary files /dev/null and b/docs/build/html/_static/down.png differ diff --git a/docs/build/html/_static/file.png b/docs/build/html/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/docs/build/html/_static/file.png differ diff --git a/docs/build/html/_static/fonts/FontAwesome.otf b/docs/build/html/_static/fonts/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/docs/build/html/_static/fonts/FontAwesome.otf differ diff --git a/docs/build/html/_static/fonts/fontawesome-webfont.eot b/docs/build/html/_static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/docs/build/html/_static/fonts/fontawesome-webfont.eot differ diff --git a/docs/build/html/_static/fonts/fontawesome-webfont.svg b/docs/build/html/_static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/docs/build/html/_static/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/build/html/_static/fonts/fontawesome-webfont.ttf b/docs/build/html/_static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/docs/build/html/_static/fonts/fontawesome-webfont.ttf differ diff --git a/docs/build/html/_static/fonts/fontawesome-webfont.woff b/docs/build/html/_static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/docs/build/html/_static/fonts/fontawesome-webfont.woff differ diff --git a/docs/build/html/_static/fonts/fontawesome-webfont.woff2 b/docs/build/html/_static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/docs/build/html/_static/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/build/html/_static/jquery-3.1.0.js b/docs/build/html/_static/jquery-3.1.0.js new file mode 100644 index 0000000..f2fc274 --- /dev/null +++ b/docs/build/html/_static/jquery-3.1.0.js @@ -0,0 +1,10074 @@ +/*eslint-disable no-unused-vars*/ +/*! + * jQuery JavaScript Library v3.1.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2016-07-07T21:44Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + + + + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.1.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); + }, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.0 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-04 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + // Known :disabled false positives: + // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset) + // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Check form elements and option elements for explicit disabling + return "label" in elem && elem.disabled === disabled || + "form" in elem && elem.disabled === disabled || + + // Check non-disabled form elements for fieldset[disabled] ancestors + "form" in elem && elem.disabled === false && ( + // Support: IE6-11+ + // Ancestry is covered for us + elem.isDisabled === disabled || + + // Otherwise, assume any non-