From 0b495adddcedefea502bf47538161c664c21e0db Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sun, 23 Sep 2018 14:18:59 +0100 Subject: [PATCH] Fix in generated documentation strings! Also, documentation added to repository. --- .gitignore | 2 +- CHANGELOG.md | 4 + doc/adl.main.html | 10 + doc/adl.to-hugsql-queries.html | 17 + doc/adl.to-json-routes.html | 13 + doc/adl.to-psql.html | 32 ++ doc/adl.to-reframe.html | 7 + doc/adl.to-selmer-routes.html | 28 ++ doc/adl.to-selmer-templates.html | 57 ++++ doc/adl.to-swagger.html | 5 + doc/adl.validator.html | 221 +++++++++++++ doc/css/default.css | 551 +++++++++++++++++++++++++++++++ doc/css/highlight.css | 97 ++++++ doc/index.html | 6 + doc/intro.html | 480 +++++++++++++++++++++++++++ doc/intro.md | 12 +- doc/js/highlight.min.js | 2 + doc/js/jquery.min.js | 4 + doc/js/page_effects.js | 112 +++++++ project.clj | 8 +- src/adl/to_hugsql_queries.clj | 2 +- 21 files changed, 1657 insertions(+), 13 deletions(-) create mode 100644 doc/adl.main.html create mode 100644 doc/adl.to-hugsql-queries.html create mode 100644 doc/adl.to-json-routes.html create mode 100644 doc/adl.to-psql.html create mode 100644 doc/adl.to-reframe.html create mode 100644 doc/adl.to-selmer-routes.html create mode 100644 doc/adl.to-selmer-templates.html create mode 100644 doc/adl.to-swagger.html create mode 100644 doc/adl.validator.html create mode 100644 doc/css/default.css create mode 100644 doc/css/highlight.css create mode 100644 doc/index.html create mode 100644 doc/intro.html create mode 100644 doc/js/highlight.min.js create mode 100644 doc/js/jquery.min.js create mode 100644 doc/js/page_effects.js diff --git a/.gitignore b/.gitignore index 851ba7d..96ff9d7 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ node_modules/ generated/ -docs/ + diff --git a/CHANGELOG.md b/CHANGELOG.md index ebded1d..3f0f86a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Change Log All notable changes to this project will be documented in this file. This change log is intended to follow the conventions of [keepachangelog.com](http://keepachangelog.com/). +## Release 1.4.6, 2018-09-22 + +Beta release; improved documentation. + ## Release 1.4.5, 2018-09-20 Generation of skeleton Clojure webapp is now largely complete; this release is not the final 'beta' release of this functionality, but is a dummy run towards that release. diff --git a/doc/adl.main.html b/doc/adl.main.html new file mode 100644 index 0000000..eec240d --- /dev/null +++ b/doc/adl.main.html @@ -0,0 +1,10 @@ + +adl.main documentation

adl.main

Application Description Language - command line invocation.
+

-main

(-main & args)
Parses options and arguments. Expects as args the path-name of one or
+more ADL files.

adl->canonical

A function which takes ADL text as its single argument and returns
+canonicalised ADL text as its result.

canonicalise

(canonicalise filepath)
Canonicalise the ADL document indicated by this `filepath` (if it is not
+already canonical) and return a path to the canonical version.

cli-options

Command-line interface options
+

process

(process options)
Process these parsed `options`.
+

usage

(usage parsed-options)
Show a usage message. `parsed-options` should be options as
+parsed by [clojure.tools.cli](https://github.com/clojure/tools.cli)
\ No newline at end of file diff --git a/doc/adl.to-hugsql-queries.html b/doc/adl.to-hugsql-queries.html new file mode 100644 index 0000000..9d4af91 --- /dev/null +++ b/doc/adl.to-hugsql-queries.html @@ -0,0 +1,17 @@ + +adl.to-hugsql-queries documentation

adl.to-hugsql-queries

Application Description Language - generate HUGSQL queries file.
+

delete-query

(delete-query entity)
Generate an appropriate `delete` query for this `entity`
+

expanded-token

FIXME: write docs

foreign-queries

(foreign-queries entity application)
Generate any foreign entity queries for this `entity` of this `application`.
+

insert-query

(insert-query entity)
Generate an appropriate `insert` query for this `entity`.
+TODO: this depends on the idea that system-unique properties
+are not insertable, which is... dodgy.

list-query

(list-query entity)
Generate a query to list records in the table represented by this `entity`.
+Parameters `:limit` and `:offset` may be supplied. If not present limit defaults
+to 100 and offset to 0.

order-by-clause

(order-by-clause entity)(order-by-clause entity prefix)(order-by-clause entity prefix expanded?)
Generate an appropriate `order by` clause for queries on this `entity`
+

queries

(queries application entity)(queries application)
Generate all standard queries for this `entity` in this `application`; if
+no entity is specified, generate all queries for the application.

search-query

(search-query entity application)
FIXME: write docs

select-query

(select-query entity properties)(select-query entity)
Generate an appropriate `select` query for this `entity`
+

to-hugsql-queries

(to-hugsql-queries application)
Generate all [HugSQL](https://www.hugsql.org/) queries implied by this ADL `application` spec.
+

update-query

(update-query entity)
Generate an appropriate `update` query for this `entity`
+

where-clause

(where-clause entity)(where-clause entity properties)
Generate an appropriate `where` clause for queries on this `entity`;
+if `properties` are passed, filter on those properties, otherwise the key
+properties.
\ No newline at end of file diff --git a/doc/adl.to-json-routes.html b/doc/adl.to-json-routes.html new file mode 100644 index 0000000..53b08d5 --- /dev/null +++ b/doc/adl.to-json-routes.html @@ -0,0 +1,13 @@ + +adl.to-json-routes documentation

adl.to-json-routes

Application Description Language: generate RING routes for REST requests.
+

declarations

(declarations handlers-map)
Generate a forward declaration of all JSON route handlers we're going to
+generate for this `application`.

defroutes

(defroutes handlers-map)
Generate JSON routes for all queries implied by this ADL `application` spec.
+

file-header

(file-header application)
Generate an appropriate file header for JSON routes for this `application`.
+

generate-handler-body

(generate-handler-body query)
Generate and return the function body for the handler for this `query`.
+

generate-handler-src

(generate-handler-src handler-name query-map method doc)
Generate and return the handler for this `query`.
+

handler

(handler query-key queries-map application)
Generate declarations for handlers from query with this `query-key` in this `queries-map`
+taken from within this `application`. This method must follow the structure of
+`to-hugsql-queries/queries` quite closely, because we must generate the same names.

make-handlers-map

(make-handlers-map application)
Analyse this `application` and generate from it a map of the handlers to be output.
+

to-json-routes

(to-json-routes application)
Generate a `/routes/auto-json.clj` file for this `application`.
+
\ No newline at end of file diff --git a/doc/adl.to-psql.html b/doc/adl.to-psql.html new file mode 100644 index 0000000..c795218 --- /dev/null +++ b/doc/adl.to-psql.html @@ -0,0 +1,32 @@ + +adl.to-psql documentation

adl.to-psql

Application Description Language: generate Postgres database definition.
+

compose-convenience-entity-field

(compose-convenience-entity-field field entity application)
FIXME: write docs

compose-convenience-view-select-list

(compose-convenience-view-select-list entity application top-level?)
Compose the body of an SQL `SELECT` statement for a convenience view of this
+`entity` within this `application`, recursively. `top-level?` should be set
+only on first invocation.

compose-convenience-where-clause

(compose-convenience-where-clause entity application top-level?)
Compose an SQL `WHERE` clause for a convenience view of this
+`entity` within this `application`.
+TODO: does not correctly compose links at one stage down the tree.
+See `lv_electors`, `lv_followuprequests` for examples of the problem.

emit-application

(emit-application application)
Emit all SQL declarations required to initialise a Postgres database for
+this `application`.

emit-convenience-entity-field

(emit-convenience-entity-field field entity application)
FIXME: write docs

emit-convenience-view

(emit-convenience-view entity application)
Emit a convenience view of this `entity` of this `application` for use in generating lists,
+menus, et cetera.

emit-defined-field-type

(emit-defined-field-type property application)
Generate appropriate field type and constraints for this `property`
+given this `typedef`.

emit-entity-field-type

(emit-entity-field-type property application)
Emit an appropriate field type for this `property`, expected to reference an entity, in this `application`.
+

emit-field-type

(emit-field-type property entity application key?)
Emit an appropriate field type for this `property`, expected to belong to
+this `entity` within this `application`.

emit-file-header

(emit-file-header application)
Generate an appropriate file header for the Postgres initialisation script
+for this `application`.

emit-group-declaration

(emit-group-declaration group application)
Emit a declaration for this authorisation `group` within this `application`.
+

emit-permissions-grant

(emit-permissions-grant table-name privilege permissions)
Emit an appropriate grant of permissions on this `table-name` at this
+`privilege` level given these `permissions`. `privilege` is expected
+to be one of #{:SELECT :INSERT :UPDATE :DELETE}.
+TODO: more thought needed here.

emit-property

(emit-property property entity application)(emit-property property entity application key?)
Emit a field declaration representing this `property` of this `entity` within this `application`.
+

emit-table

(emit-table entity application doc-comment)(emit-table entity application)
Emit a table declaration for this `entity` of this `application`,
+documented with this `doc-comment` if specified.

field-name

(field-name property)
Return the appropriate field name for this `property`.
+TODO: really belongs in `adl-support.utils`.

to-psql

(to-psql application)
Generate a complete Postgres database initialisation script for this `application`.
+
\ No newline at end of file diff --git a/doc/adl.to-reframe.html b/doc/adl.to-reframe.html new file mode 100644 index 0000000..c6c3830 --- /dev/null +++ b/doc/adl.to-reframe.html @@ -0,0 +1,7 @@ + +adl.to-reframe documentation

adl.to-reframe

Application Description Language: generate re-frame UI. TODO: doesn't even nearly work yet.
+

file-header

(file-header parent-name this-name extra-requires)(file-header parent-name this-name)
Generate an appropriate file header for a re-frame view.
+

generate-form

(generate-form form entity application)
Generate as re-frame this `form` taken from this `entity` of this `application`.
+
+TODO: write it!
\ No newline at end of file diff --git a/doc/adl.to-selmer-routes.html b/doc/adl.to-selmer-routes.html new file mode 100644 index 0000000..a564329 --- /dev/null +++ b/doc/adl.to-selmer-routes.html @@ -0,0 +1,28 @@ + +adl.to-selmer-routes documentation

adl.to-selmer-routes

Application Description Language: generate routes for user interface requests.
+

compose-fetch-auxlist-data

(compose-fetch-auxlist-data auxlist entity application)
Compose Clojure code to fetch data to populate this `auxlist` of a form
+editing a record of this `entity` within this `application`.

compose-fetch-record

(compose-fetch-record e)
Compose Clojure code to retrieve a single record of entity `e`.
+

compose-get-menu-options

(compose-get-menu-options property application)
Compose Clojure code to fetch from the database menu options for this
+`property` within this `application`.

file-header

(file-header application)
FIXME: write docs

generate-handler-resolver

(generate-handler-resolver application)
Dodgy, dodgy, dodgy. Generate code which will look up functions in the
+manual and in this namespace. I'm sure someone who really knew what they
+were doing could write this more elegantly.

handler-name

(handler-name f e a m)
Generate the name of the appropriate handler function for form `f` of
+entity `e` of application `a` for method `m`, where `f`, `e`, and `a`
+are expected to be elements and `m` is expected to be one of the keywords
+`:put` `:get`.

make-defroutes

(make-defroutes application)
Generate a `defroutes` declaration for all routes of all forms, pages and
+lists within this `application`.

make-form-get-handler-content

(make-form-get-handler-content f e a n)
Compose Clojure code to form body of an HTTP `GET` handler for the form
+`f` of the entity `e` within application `a`. The argument `n`
+is not used.

make-form-post-handler-content

(make-form-post-handler-content f e a n)
Generate the body of the post handler for the form `f` of
+entity `e` in application `a`. The argument `n` is bound to the name
+of the function, but is not currently used.
+
+Literally the only thing the post handler has to do is to
+execute the database store operation. Then it can hand off
+to the get handler.

make-get-handler

(make-get-handler f e a)
Generate a Clojure function to handle HTTP `GET` requests for form, list or
+page `f` of entity `e` within application `a`.

make-handlers

(make-handlers e application)
Generate all the Selmer route handlers for all the forms, lists and pages
+of the entity `e` within this `application`.

make-list-get-handler-content

(make-list-get-handler-content f e a n)
Compose Clojure code to form body of an HTTP `GET` handler for the list
+`f` of the entity `e` within application `a`. The argument `n` is ignored.

make-page-get-handler-content

(make-page-get-handler-content f e a n)
Compose Clojure code to form body of an HTTP `GET` handler for the page
+`f` of the entity `e` within application `a`. The argument `n` is ignored.

make-post-handler

(make-post-handler f e a)
Generate an HTTP `POST` handler for the page, form or list `f` of the
+entity `e` of application `a`.

make-route

(make-route m n)
Make a route for method `m` to request the resource with name `n`.
+

to-selmer-routes

(to-selmer-routes application)
Generate a `/routes/auto.clj` file for this `application`.
+
\ No newline at end of file diff --git a/doc/adl.to-selmer-templates.html b/doc/adl.to-selmer-templates.html new file mode 100644 index 0000000..df3440e --- /dev/null +++ b/doc/adl.to-selmer-templates.html @@ -0,0 +1,57 @@ + +adl.to-selmer-templates documentation

adl.to-selmer-templates

Application Description Language - generate Selmer templates for
+the HTML pages implied by an ADL file.

application-to-template

(application-to-template application)
FIXME: write docs

compose-form-auxlist

(compose-form-auxlist auxlist form entity application)
Compose an auxiliary list from this `auxlist` specification of dependent
+records (i.e. the far side of a
+one-to-many link) of the record of this `entity` within this `application`
+being edited in this `form` 

compose-form-auxlists

(compose-form-auxlists form entity application)
Generate all auxiliary lists required for this `form` of this `entity`
+within this `application`.

compose-form-content

(compose-form-content form entity application)
Compose the content for this `form` of this `entity` within this `application`.
+

compose-form-extra-head

(compose-form-extra-head form entity application)
Compose any extra-head declarations (i.e. special Javascript tags) required
+for this `form` of this `entity` within this `application`.

compose-form-extra-tail

(compose-form-extra-tail form entity application)
Compose any extra-tail declarations (i.e. special Javascript tags) required
+for this `form` of this `entity` within this `application`.

compose-if-member-of-tag

(compose-if-member-of-tag privilege & elts)
Generate an appropriate `ifmemberof` tag (see `adl-support.tags`) given this
+`privilege` for the  ADL elements listed in `elts`, which may be fields,
+properties, list, forms, pages or entities.

compose-input-widget-para

(compose-input-widget-para property form entity application widget-name)
Generate an input widget for this `field-or-property` of this `form` for
+this `entity` taken from within this `application`, in context of a para
+also containing its label.

compose-list-search-widget

(compose-list-search-widget field entity)
Compose a list search widget for this `field` referencing a property within
+this `entity`.

compose-readable-or-not-authorised

(compose-readable-or-not-authorised p f e a w)
Compose content to emit if the user is not authorised to write, or
+not authorised to read, property `p` in form, list or page `f` of
+entity `e` within application `a`, while generating a widget with id
+`w`.

compose-widget-para

(compose-widget-para p f e a w content)
Compose a widget paragraph for property `p` in form, list or page `f` of
+entity `e` within application `a`, with id `w` and this `content`.

csrf-widget

(csrf-widget)
For the present, just return the standard cross site scripting protection
+field statement

delete-widget

(delete-widget form entity application)
Return an appropriate 'save' widget for this `form` operating on this
+`entity` taken from this `application`.

embed-script-fragment

(embed-script-fragment resource-path substitutions)(embed-script-fragment resource-path)
Return the content of the file at `resource-path`, with these
+`substitutions` made into it in order. Substitutions should be pairs
+[`pattern` `value`], where `pattern` is a string, a char, or a regular
+expression.

emit-content

(emit-content content)(emit-content filename application k)(emit-content filename spec entity application k)
FIXME: write docs

emit-entity-dd

(emit-entity-dd entity application)
FIXME: write docs

emit-entity-dt

(emit-entity-dt entity application)
FIXME: write docs

entity-to-templates

(entity-to-templates entity application)
Generate one or more templates for editing instances of this
+`entity` in this `application`

file-header

(file-header filename application)(file-header filename spec entity application)
Generate a header for a template file with this `filename` for this `spec`
+of this `entity` within this `application`.

form-to-template

(form-to-template form entity application)
Generate a template as specified by this `form` element for this `entity`,
+taken from this `application`. If `form` is nill, generate a default form
+template for the entity.

get-options

(get-options property form entity application)
Produce template code to get options for this `property` of this `entity`
+taken from this `application`.

get-size-for-widget

(get-size-for-widget property)
Return, as an integer, the fieldwidth for the input widget for this
+`property`.

list-tbody

(list-tbody source list-spec entity application)
Return a table body element for the list view for this `list-spec` of
+this `entity` within this `application`, using data from this `source`.

list-to-template

(list-to-template list-spec entity application)
Generate a template as specified by this `list` element for this `entity`,
+taken from this `application`. If `list` is nill, generate a default list
+template for the entity.

page-to-template

(page-to-template page entity application)
Generate a template as specified by this `page` element for this `entity`,
+taken from this `application`. If `page` is nil, generate a default page
+template for the entity.
+
+TODO: not yet written.

save-widget

(save-widget form entity application)
Return an appropriate 'save' widget for this `form` operating on this
+`entity` taken from this `application`.
+TODO: should be suppressed unless a member of a group which can insert
+or edit.

select-field-name

(select-field-name entity)
FIXME: write docs

select-property

(select-property entity)
Return the property on which we will by default do a user search on this
+`entity`.

select-widget

(select-widget property form entity application)
Generate an HTML `SELECT` widget for this `property` of this `entity` within
+this `application`, to be used in this `form`. TODO: Many selectable things
+are potentially too numerous to be simply represented in a simple static
+SELECT, it needs some asynchronous fetching. See
+[issue 47](https://github.com/simon-brooke/youyesyet/issues/47).

to-selmer-templates

(to-selmer-templates application)
Generate all [Selmer](https://github.com/yogthos/Selmer) templates implied
+by this ADL `application` spec.

widget

(widget field-or-property form entity application)
Generate a widget for this `field-or-property` of this `form` for this
+`entity` taken from within this `application`, in context of a para also
+containing its label.

widget-type

(widget-type property application)(widget-type property application typedef)
Return an appropriate HTML5 input type for this property.
+

wrap-in-if-member-of

(wrap-in-if-member-of content privilege & context)
Wrap this `content` in an if-member-of tag; if `writeable?` is true,
+allow those groups by whom it is writeable, else those by whom it is
+readable. `context` should be a sequence of adl elements from which
+permissions may be obtained.

write-template-file

(write-template-file filename template application)
Write a template file with this `filename` from this `template` in the
+context of this `application`.
\ No newline at end of file diff --git a/doc/adl.to-swagger.html b/doc/adl.to-swagger.html new file mode 100644 index 0000000..69e7c37 --- /dev/null +++ b/doc/adl.to-swagger.html @@ -0,0 +1,5 @@ + +adl.to-swagger documentation

adl.to-swagger

Application Description Language: generate swagger routes.
+

file-header

(file-header application)
TODO: Nothing here works yet.
+
\ No newline at end of file diff --git a/doc/adl.validator.html b/doc/adl.validator.html new file mode 100644 index 0000000..d8770eb --- /dev/null +++ b/doc/adl.validator.html @@ -0,0 +1,221 @@ + +adl.validator documentation

adl.validator

Application Description Language: validator for ADL structure.
+TODO: this is at present largely a failed experiment.

all-data-types

FIXME: write docs

application-validations

FIXME: write docs

auxlist-validations

a subsidiary list, on which entities related to primary
+entities in the enclosing page or list are listed
+
+* `property`:   the property of the enclosing entity that this
+            list displays (obviously, must be of type='list')
+* `onselect`:   the form or page of the listed entity to call
+            when an item from the list is selected
+* `canadd`:     true if the user should be able to add records
+            to this list

cascade-actions

actions which should be cascaded to dependent objects. All these values except
+'manual' are taken from Hibernate and should be passed through the adl2hibernate
+mapping transparently. Relevent only for properties with type='entity', type='link'
+and type='list'
+
+* `all`:       cascade delete, save and update
+* `all-delete-orphan`: see hibernate documentation; relates to transient objects only
+* `delete`:    cascade delete actions, but not save and update
+* `manual`:    cascading will be handled in manually managed code, code to
+            handle cascading should not be generated
+* `save-update`: cascade save and update actions, but not delete.

complex-data-types

data types which are more complex than SimpleDataTypes...
+* `entity` : 		a foreign key link to another entity (i.e. the 'many' end of a
+				    one-to-many link);
+* `list` :			a list of some other entity that links to me (i.e. the 'one' end of
+				    a one-to-many link);
+* `link` : 			a many to many link (via a link table);
+* `defined` : 	a type defined by a typedef.

content

content, for things like pages (i.e. forms, lists, pages)
+

content-validations

FIXME: write docs

defineable-data-types

data types which can be used in a typedef to provide validation -
+e.g. a string can be used with a regexp or a scalar can be used with
+min and max values
+* `string`: 		varchar		java.sql.Types.VARCHAR
+* `integer`:		int			java.sql.Types.INTEGER
+* `real`:			double		java.sql.Types.DOUBLE
+* `money`:			money		java.sql.Types.INTEGER
+* `date`:			date		java.sql.Types.DATE
+* `time`:			time		java.sql.Types.TIME
+* `timestamp`:		timestamp	java.sql.Types.TIMESTAMP
+* `uploadable`:		varchar		java.sql.Types.VARCHAR
+* `image`:			varchar		java.sql.Types.VARCHAR
+
+uploadable is as string but points to an uploaded file; image is as
+uploadable but points to an uploadable graphical image file.

disjunct-valid?

macro

(disjunct-valid? o & validations)
Yes, this is a horrible hack. I should be returning the error structure
+not printing it. But I can't see how to make that work with `bouncer`.
+OK, so: most of the validators will (usually) fail, and that's OK. How
+do we identify the one which ought not to have failed?

documentation-validations

contains documentation on the element which immediately contains it. TODO:
+should HTML markup within a documentation element be allowed? If so, are
+there restrictions?

entity-validations

an entity which has properties and relationships; maps onto a database
+table or a Java serialisable class - or, of course, various other things
+
+ * `name`:         obviously, the name of this entity
+ * `natural-key`:  if present, the name of a property of this entity which forms
+               a natural primary key [NOTE: Only partly implemented. NOTE: much of
+               the present implementation assumes all primary keys will be
+               integers. This needs to be fixed!] DEPRECATED: remove; replace with the
+               'key' element, below.
+ * `table`:        the name of the table in which this entity is stored. Defaults to same
+               as name of entity. Strongly recommend this is not used unless it needs
+               to be different from the name of the entity
+ * `foreign`:      this entity is part of some other system; no code will be generated
+               for it, although code which links to it will be generated

field-stuff

FIXME: write docs

field-validations

a field in a form or page
+
+* `property`:   the property which this field displays/edits.

fieldgroup-validations

a group of fields and other controls within a form or list, which the
+renderer might render as a single pane in a tabbed display, for example.

foot-validations

content to place in the bottom of the body of the generated document;
+this is any HTML block or inline level element.

form-validations

a form through which an entity may be added or edited
+

generator-actions

FIXME: write docs

generator-validations

marks a property which is auto-generated by some part of the system.
+This is based on the Hibernate construct, except that the Hibernate
+implementation folds both its internal generators and custom generators
+onto the same attribute. This separates them onto two attributes so we
+can police values for Hibernate's 'builtin' generators.
+
+* `action`:       one of the supported Hibernate builtin generators, or
+              'manual'. 'native' is strongly recommended in most instances
+* `class`:        if action is 'manual', the name of a manually maintained
+              class conforming to the Hibernate IdentifierGenerator
+              interface, or its equivalent in other languages.

group-validations

a group of people with similar permissions to one another
+
+* `name`: the name of this group
+* `parent`: the name of a group of which this group is subset

head-validations

content to place in the head of the generated document; normally HTML.
+

help-validations

helptext about a property of an entity, or a field of a page, form or
+list, or a typedef. Typically there will be only one of these per property
+ per locale; if there are more than one all those matching the locale may
+ be concatenated, or just one may be used.
+
+* `locale`:			the locale in which to prefer this prompt

ifmissing-validations

helpful text to be shown if a property value is missing, typically when
+ a form is submitted. Typically there will be only one of these per property
+ per locale; if there are more than one all those matching the locale may
+ be concatenated, or just one may be used. Later there may be more sophisticated
+ behaviour here.
+
+* `locale`:			the locale in which to prefer this prompt

in-implementation-validations

information about how to translate a type into types known to different target
+languages. TODO: Once again I'm not wholly comfortable with the name; I'm not
+really comfortable that this belongs in ADL at all.
+
+* `target`:     the target language
+* `value`:      the type to use in that target language
+* `kind`:       OK, I confess I don't understand this, but Andrew needs it... 

key-validations

FIXME: write docs

list-validations

a list on which entities of a given type are listed
+
+* `onselect`:		name of form/page/list to go to when
+				    a selection is made from the list

option-validations

one of an explicit list of optional values a property may have
+NOTE: whether options get encoded at application layer or at database layer
+is UNDEFINED; either behaviour is correct. If at database layer it's also
+UNDEFINED whether they're encoded as a single reference data table or as
+separate reference data tables for each property.
+
+* `value`:	the value of this option.

order-validations

an ordering or records in a list
+* `property`:	the property on which to order
+* `sequence`:	the sequence in which to order

page-content

FIXME: write docs

page-stuff

FIXME: write docs

page-validations

a page on which an entity may be displayed
+

param-validations

A parameter passed to the generator. Again, based on the Hibernate
+implementation.
+
+* `name`:   the name of this parameter.

permission-validations

permissions policy on an entity, a page, form, list or field
+
+* `group`: 			the group to which permission is granted
+* `permission`:		the permission which is granted to that group

permissions

permissions a group may have on an entity, list, page, form or field
+permissions are deemed to increase as you go right. A group cannot
+have greater permission on a field than on the form it is in, or
+greater permission on form than the entity it belongs to
+
+* `none`:			none
+* `read`:			select
+* `insert`:			insert
+* `noedit`:			select, insert
+* `edit`:			select, insert, update
+* `all`:			select, insert, update, delete

pragma-validations

pragmatic advice to generators of lists and forms, in the form of
+name/value pairs which may contain anything. Over time some pragmas
+will become 'well known', but the whole point of having a pragma
+architecture is that it is extensible.

prompt-validations

a prompt for a property or field; used as the prompt text for a widget
+which edits it. Typically there will be only one of these per property
+ per locale; if there are more than one all those matching the locale may
+ be concatenated, or just one may be used.
+
+* `prompt`:			the prompt to use
+* `locale`:			the locale in which to prefer this prompt.

property-validations

a property (field) of an entity (table)
+
+* `name`:			  the name of this property.
+* `type`:			  the type of this property.
+* `default`:		the default value of this property. There will probably be
+				    magic values of this!
+* `typedef`:	  name of the typedef to use, it type = 'defined'.
+* `distinct`:		distinct='system' required that every value in the system
+				    will be distinct (i.e. natural primary key);
+				    distinct='user' implies that the value may be used by users
+				    in distinguishing entities even if values are not formally
+				    unique;
+				    distinct='all' implies that the values are formally unique
+				    /and/ are user friendly (NOTE: not implemented).
+* `entity`:	if type='entity', the name of the entity this property is
+				    a foreign key link to.
+             if type='list', the name of the entity that has a foreign
+             key link to this entity
+* `farkey`:   if type='list', the name of farside key in the listed
+             entity; if type='entity' and the farside field to join to
+             is not the farside primary key, then the name of that
+             farside field
+* `required`:		whether this propery is required (i.e. 'not null').
+* `immutable`:		if true, once a value has been set it cannot be changed.
+* `size`: 			fieldwidth of the property if specified.
+* `concrete`: if set to 'false', this property is not stored in the
+             database but must be computed (manually written code must
+             be provided to support this)
+* `cascade`:  what action(s) on the parent entity should be cascaded to
+             entitie(s) linked on this property. Valid only if type='entity',
+             type='link' or type='list'.
+* `column`:   name of the column in a SQL database table in which this property
+             is stored. TODO: Think about this.
+* `unsaved-value`:
+             of a property whose persistent value is set on first being
+             committed to persistent store, the value which it holds before
+             it has been committed

reference-validations

The 'specification' and 'reference' elements are for documentation only,
+and do not contribute to the engineering of the application described.
+
+A reference element is a reference to a specifying document.
+
+* `abbr`:		The abbreviated name of the specification to which this
+			reference refers
+* `section`:	The 'anchor part' (part following a hash character) which,
+			when appended to the URL, will locate the exact section
+			referenced.
+* `entity`:		A reference to another entity within this ADL document
+* `property`:	A reference to another property within this ADL document;
+			if entity is also specified then of that entity, else of
+			the ancestor entity if any

sequences

FIXME: write docs

simple-data-types

data types which are fairly straightforward translations of JDBC data types
+* `boolean`:		boolean 	java.sql.Types.BIT or char(1)		  java.sql.Types.CHAR
+* `text`:			  text or		  java.sql.Types.LONGVARCHAR
+memo		    java.sql.Types.CLOB

special-data-types

data types which require special handling - which don't simply map onto
+common SQL data types
+* `geopos` :    a latitude/longitude pair (experimental and not yet implemented)
+* `image` :     a raster image file, in jpeg, gif, or png format (experimental, not yet implemented)
+* `message` :   an internationalised message, having different translations for different locales

specification-validations

The 'specification' and 'reference' elements are for documentation only,
+and do not contribute to the engineering of the application described.
+
+A specification element is intended chiefly to declare the reference
+documents which may be used in documentation elements later in the
+document.
+
+* `url`:		The URL from which the document referenced can be retrieved
+* `name`:		The full name (title) given to this document
+* `abbr`:		A convenient abbreviated name.

top-validations

content to place in the top of the body of the generated document;
+this is any HTML block or inline level element.

try-validate

(try-validate o validation)
Pass this `validation` and the object `o` to bouncer
+

typedef-validations

the definition of a defined type. At this stage a defined type is either
+* a string		in which case it must have size and pattern, or
+* a scalar		in which case it must have minimum and/or maximum
+pattern must be a regular expression as interpreted by org.apache.regexp.RE
+minimum and maximum must be of appropriate format for the datatype specified.
+Validation may be done client-side and/or server-side at application layer
+and/or server side at database layer.
+
+ * `name`:     the name of this typedef
+ * `type`:     the simple type on which this defined type is based; must be
+           present unless in-implementation children are supplied
+ * `size`:     the data size of this defined type
+ * `pattern`:  a regular expression which values for this type must match
+ * `minimum`:  the minimum value for this type (if base type is scalar)
+ * `maximum`:  the maximum value for this type (if base type is scalar)

valid-adl?

(valid-adl? src)
Return `true` if `src` is syntactically valid ADL.
+

validate-adl

(validate-adl src)
FIXME: write docs

validate-adl-file

(validate-adl-file filepath)
FIXME: write docs

verb-validations

a verb is something that may be done through a form. Probably the verbs 'store'
+and 'delete' are implied, but maybe they need to be explicitly declared. The 'verb'
+attribute of the verb is what gets returned to the controller
+
+* `verb`  what gets returned to the controller when this verb is selected
+* `dangerous`  true if this verb causes a destructive change.
\ No newline at end of file diff --git a/doc/css/default.css b/doc/css/default.css new file mode 100644 index 0000000..33f78fe --- /dev/null +++ b/doc/css/default.css @@ -0,0 +1,551 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 15px; +} + +pre, code { + font-family: Monaco, DejaVu Sans Mono, Consolas, monospace; + font-size: 9pt; + margin: 15px 0; +} + +h1 { + font-weight: normal; + font-size: 29px; + margin: 10px 0 2px 0; + padding: 0; +} + +h2 { + font-weight: normal; + font-size: 25px; +} + +h5.license { + margin: 9px 0 22px 0; + color: #555; + font-weight: normal; + font-size: 12px; + font-style: italic; +} + +.document h1, .namespace-index h1 { + font-size: 32px; + margin-top: 12px; +} + +#header, #content, .sidebar { + position: fixed; +} + +#header { + top: 0; + left: 0; + right: 0; + height: 22px; + color: #f5f5f5; + padding: 5px 7px; +} + +#content { + top: 32px; + right: 0; + bottom: 0; + overflow: auto; + background: #fff; + color: #333; + padding: 0 18px; +} + +.sidebar { + position: fixed; + top: 32px; + bottom: 0; + overflow: auto; +} + +.sidebar.primary { + background: #e2e2e2; + border-right: solid 1px #cccccc; + left: 0; + width: 250px; +} + +.sidebar.secondary { + background: #f2f2f2; + border-right: solid 1px #d7d7d7; + left: 251px; + width: 200px; +} + +#content.namespace-index, #content.document { + left: 251px; +} + +#content.namespace-docs { + left: 452px; +} + +#content.document { + padding-bottom: 10%; +} + +#header { + background: #3f3f3f; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); + z-index: 100; +} + +#header h1 { + margin: 0; + padding: 0; + font-size: 18px; + font-weight: lighter; + text-shadow: -1px -1px 0px #333; +} + +#header h1 .project-version { + font-weight: normal; +} + +.project-version { + padding-left: 0.15em; +} + +#header a, .sidebar a { + display: block; + text-decoration: none; +} + +#header a { + color: #f5f5f5; +} + +.sidebar a { + color: #333; +} + +#header h2 { + float: right; + font-size: 9pt; + font-weight: normal; + margin: 4px 3px; + padding: 0; + color: #bbb; +} + +#header h2 a { + display: inline; +} + +.sidebar h3 { + margin: 0; + padding: 10px 13px 0 13px; + font-size: 19px; + font-weight: lighter; +} + +.sidebar h3 a { + color: #444; +} + +.sidebar h3.no-link { + color: #636363; +} + +.sidebar ul { + padding: 7px 0 6px 0; + margin: 0; +} + +.sidebar ul.index-link { + padding-bottom: 4px; +} + +.sidebar li { + display: block; + vertical-align: middle; +} + +.sidebar li a, .sidebar li .no-link { + border-left: 3px solid transparent; + padding: 0 10px; + white-space: nowrap; +} + +.sidebar li .no-link { + display: block; + color: #777; + font-style: italic; +} + +.sidebar li .inner { + display: inline-block; + padding-top: 7px; + height: 24px; +} + +.sidebar li a, .sidebar li .tree { + height: 31px; +} + +.depth-1 .inner { padding-left: 2px; } +.depth-2 .inner { padding-left: 6px; } +.depth-3 .inner { padding-left: 20px; } +.depth-4 .inner { padding-left: 34px; } +.depth-5 .inner { padding-left: 48px; } +.depth-6 .inner { padding-left: 62px; } + +.sidebar li .tree { + display: block; + float: left; + position: relative; + top: -10px; + margin: 0 4px 0 0; + padding: 0; +} + +.sidebar li.depth-1 .tree { + display: none; +} + +.sidebar li .tree .top, .sidebar li .tree .bottom { + display: block; + margin: 0; + padding: 0; + width: 7px; +} + +.sidebar li .tree .top { + border-left: 1px solid #aaa; + border-bottom: 1px solid #aaa; + height: 19px; +} + +.sidebar li .tree .bottom { + height: 22px; +} + +.sidebar li.branch .tree .bottom { + border-left: 1px solid #aaa; +} + +.sidebar.primary li.current a { + border-left: 3px solid #a33; + color: #a33; +} + +.sidebar.secondary li.current a { + border-left: 3px solid #33a; + color: #33a; +} + +.namespace-index h2 { + margin: 30px 0 0 0; +} + +.namespace-index h3 { + font-size: 16px; + font-weight: bold; + margin-bottom: 0; +} + +.namespace-index .topics { + padding-left: 30px; + margin: 11px 0 0 0; +} + +.namespace-index .topics li { + padding: 5px 0; +} + +.namespace-docs h3 { + font-size: 18px; + font-weight: bold; +} + +.public h3 { + margin: 0; + float: left; +} + +.usage { + clear: both; +} + +.public { + margin: 0; + border-top: 1px solid #e0e0e0; + padding-top: 14px; + padding-bottom: 6px; +} + +.public:last-child { + margin-bottom: 20%; +} + +.members .public:last-child { + margin-bottom: 0; +} + +.members { + margin: 15px 0; +} + +.members h4 { + color: #555; + font-weight: normal; + font-variant: small-caps; + margin: 0 0 5px 0; +} + +.members .inner { + padding-top: 5px; + padding-left: 12px; + margin-top: 2px; + margin-left: 7px; + border-left: 1px solid #bbb; +} + +#content .members .inner h3 { + font-size: 12pt; +} + +.members .public { + border-top: none; + margin-top: 0; + padding-top: 6px; + padding-bottom: 0; +} + +.members .public:first-child { + padding-top: 0; +} + +h4.type, +h4.dynamic, +h4.added, +h4.deprecated { + float: left; + margin: 3px 10px 15px 0; + font-size: 15px; + font-weight: bold; + font-variant: small-caps; +} + +.public h4.type, +.public h4.dynamic, +.public h4.added, +.public h4.deprecated { + font-size: 13px; + font-weight: bold; + margin: 3px 0 0 10px; +} + +.members h4.type, +.members h4.added, +.members h4.deprecated { + margin-top: 1px; +} + +h4.type { + color: #717171; +} + +h4.dynamic { + color: #9933aa; +} + +h4.added { + color: #508820; +} + +h4.deprecated { + color: #880000; +} + +.namespace { + margin-bottom: 30px; +} + +.namespace:last-child { + margin-bottom: 10%; +} + +.index { + padding: 0; + font-size: 80%; + margin: 15px 0; + line-height: 16px; +} + +.index * { + display: inline; +} + +.index p { + padding-right: 3px; +} + +.index li { + padding-right: 5px; +} + +.index ul { + padding-left: 0; +} + +.type-sig { + clear: both; + color: #088; +} + +.type-sig pre { + padding-top: 10px; + margin: 0; +} + +.usage code { + display: block; + color: #008; + margin: 2px 0; +} + +.usage code:first-child { + padding-top: 10px; +} + +p { + margin: 15px 0; +} + +.public p:first-child, .public pre.plaintext { + margin-top: 12px; +} + +.doc { + margin: 0 0 26px 0; + clear: both; +} + +.public .doc { + margin: 0; +} + +.namespace-index .doc { + margin-bottom: 20px; +} + +.namespace-index .namespace .doc { + margin-bottom: 10px; +} + +.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td { + line-height: 22px; +} + +.markdown li { + padding: 2px 0; +} + +.markdown h2 { + font-weight: normal; + font-size: 25px; + margin: 30px 0 10px 0; +} + +.markdown h3 { + font-weight: normal; + font-size: 20px; + margin: 30px 0 0 0; +} + +.markdown h4 { + font-size: 15px; + margin: 22px 0 -4px 0; +} + +.doc, .public, .namespace .index { + max-width: 680px; + overflow-x: visible; +} + +.markdown pre > code { + display: block; + padding: 10px; +} + +.markdown pre > code, .src-link a { + border: 1px solid #e4e4e4; + border-radius: 2px; +} + +.markdown code:not(.hljs), .src-link a { + background: #f6f6f6; +} + +pre.deps { + display: inline-block; + margin: 0 10px; + border: 1px solid #e4e4e4; + border-radius: 2px; + padding: 10px; + background-color: #f6f6f6; +} + +.markdown hr { + border-style: solid; + border-top: none; + color: #ccc; +} + +.doc ul, .doc ol { + padding-left: 30px; +} + +.doc table { + border-collapse: collapse; + margin: 0 10px; +} + +.doc table td, .doc table th { + border: 1px solid #dddddd; + padding: 4px 6px; +} + +.doc table th { + background: #f2f2f2; +} + +.doc dl { + margin: 0 10px 20px 10px; +} + +.doc dl dt { + font-weight: bold; + margin: 0; + padding: 3px 0; + border-bottom: 1px solid #ddd; +} + +.doc dl dd { + padding: 5px 0; + margin: 0 0 5px 10px; +} + +.doc abbr { + border-bottom: 1px dotted #333; + font-variant: none; + cursor: help; +} + +.src-link { + margin-bottom: 15px; +} + +.src-link a { + font-size: 70%; + padding: 1px 4px; + text-decoration: none; + color: #5555bb; +} diff --git a/doc/css/highlight.css b/doc/css/highlight.css new file mode 100644 index 0000000..d0cdaa3 --- /dev/null +++ b/doc/css/highlight.css @@ -0,0 +1,97 @@ +/* +github.com style (c) Vasily Polovnyov +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..c606f68 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,6 @@ + +Adl 1.4.6-SNAPSHOT

Adl 1.4.6-SNAPSHOT

Released under the GNU Lesser General Public License, version 3.0 or (at your option) any later version

An application to transform an ADL application specification + document into skeleton code for a Clojure web-app.

Installation

To install, add the following dependency to your project or build file:

[adl "1.4.6-SNAPSHOT"]

Topics

Namespaces

adl.main

Application Description Language - command line invocation.

Public variables and functions:

adl.to-json-routes

Application Description Language: generate RING routes for REST requests.

adl.to-reframe

Application Description Language: generate re-frame UI. TODO: doesn't even nearly work yet.

Public variables and functions:

adl.to-swagger

Application Description Language: generate swagger routes.

Public variables and functions:

\ No newline at end of file diff --git a/doc/intro.html b/doc/intro.html new file mode 100644 index 0000000..53570f6 --- /dev/null +++ b/doc/intro.html @@ -0,0 +1,480 @@ + +Introduction

Introduction

+

NOTE: this markdown was automatically generated from adl_user_doc.html, which in turn was taken from the Wiki page on which this documentation was originally written. It is substantially out of date.

+

Application Description Language framework

+

Contents

+
+ +

What is Application Description Language?

+
+

Application Description Language is an XML vocabulary, defined in a Document Type Definition, which declaratively describes the entities in an application domain, their relationships, and their properties. Because ADL is defined in a formal definition which can be parsed by XML editors, any DTD-aware XML editor (such as that built into Visual studio) can provide context-sensitive auto-completion for ADL, making the vocabulary easy to learn and to edit. It would perhaps be desirable to replace this DTD at some future stage with an XML Schema, since it is desirable to be able to mix HTML in with ADL in the same document.

+

ADL is thus a ‘Fourth Generation Language’ as understood in the 1980s - an ultra-high level language for a specific problem domain; but it is a purely declarative 4GL.

+

Current versions

+
+ +

\ What is the Application Description Language Framework?

+

The Application Description Language Framework is principally a set of XSL transforms which transform a single ADL file into all the various source files required to build an application.

+

Why does it matter?

+
+

The average data driven web application comprises pages (lists) which show lists of entities, pages (forms) that edit instances of entities, and pages (inspectors) that show details of instances of entities. That comprises 100% of many applications and 90% of others; traditionally, even with modern tools like Monorail, coding these lists, forms and inspectors has taken 90% of the development effort.

+

I realised about three years ago that I was doing essentially the same job over and over again, and I don’t like doing that. I see my mission in life as being to automate people out of jobs, and that includes me. So the object of the Application Description Language is to raise the level of abstraction with which we define data driven applications one level higher, and automate the process we have thus far done as programmers. This isn’t a new insight; it’s fundamentally the same insight that led machine code programmers to develop the first macro assembler, and led assembly language programmers to write the first high level language compiler. Computers are tools which can be used to mung information from one representation to another, and all we need to do is to work out how to write a powerful enough representation, and how to transform it.

+

The whole purpose of ADL is to increase productivity - mine, and that of anyone else who chooses to follow me down this path. It is pragmatic technology - it is designed to be an 80/20 or 90/10 solution, taking the repetitious grunt-work out of application development so that we can devote more time to the fun, interesting and novel bits. It is not intended to be an academic, perfect, 100% solution - although for many applications it may in practice be a 100% solution.

+

Automated Application Generation

+

Thus to create a new application, all that should be necessary is to create a new ADL file, and to compile it using a single, standardised [NAnt] (or [Ant]) build file using scripts already created as part of the framework. All these scripts (with the exception of the PSQL one, which was pre-existing) have been created as part of the C1873 - SRU - Hospitality contract, but they contain almost no SRU specific material (and what does exist has been designed to be factored out). Prototype 1 of the SRU Hospitality Application contains no hand-written code whatever - all the application code is automatically generated from the single ADL file. The one exception to this rule is the CSS stylesheet which provides look-and-feel and branding.

+

Integration with hand-written code

+

Application-specific procedural code, covering specific business procedures, may still need to be hand written; the code generated by the ADL framework is specifically designed to make it easy to integrate hand-written code. Thus for example the C# entity controller classes generated are intentionally generated as partial classes, so that they may be complemented by other partial classes which may be manually maintained and held in a version control system.

+

High quality auto-generated code

+

One key objective of the framework is that the code which is generated should be as clear and readable - and as well commented - as the best hand-written code. Consider this example:

+
  /// <summary>
+  /// Store the record represented by the parameters passed in an HTTP service
+  /// Without Id -> it's new, I create a new persistent object;
+  /// With Id -> it's existing, I update the existing persistent object
+  /// </summary>
+  \[AccessibleThrough( Verb.Post)\]
+  public void Store()
+  {
+    ISession hibernator =
+      NHibernateHelper.GetCurrentSession( Session\[ NHibernateHelper.USERTOKEN\],
+                                          Session\[NHibernateHelper.PASSTOKEN\]);
+
+    SRU.Hospitality.Entities.Event record;
+
+
+    if ( Params\[ "instance.Date" \] == null)
+    {
+      AddError( "You must supply a value for Date");
+    }
+
+
+    if ( Params\[ "instance.Description" \] == null)
+    {
+      AddError( "You must supply a value for Description");
+    }
+
+
+
+    string id = Params\["instance.EventId"\];
+
+    if ( String.IsNullOrEmpty( id))
+    {
+      /\* it's new, create persistent object */
+      record = new SRU.Hospitality.Entities.Event();
+
+      /\* perform any domain knowledge behaviour on the new record
+       \* after instantiation */
+      record.AfterCreationHook();
+    }
+    else
+    {
+      /\* it's existing, retrieve it */
+      record =
+        hibernator.CreateCriteria(typeof(Event))
+          .Add(Expression.Eq("EventId", Int32.Parse(id)))
+          .UniqueResult<SRU.Hospitality.Entities.Event>();
+    }
+
+    if ( record != null)
+    {
+      /\* perform any domain knowledge behaviour on the record prior to updating */
+      record.BeforeUpdateHook();
+
+      /\* actually update the record */
+      BindObjectInstance( record, ParamStore.Form, "instance");
+
+
+
+      /\* write the record to the database, in order to guarantee we have a valid key */
+      hibernator.Save(record);
+      hibernator.Flush();
+
+      /\* perform any domain knowledge behaviour on the record after updating */
+      record.AfterUpdateHook();
+
+      PropertyBag\["username"\] = Session\[ NHibernateHelper.USERTOKEN\];
+      PropertyBag\["instance"\] = record;
+
+
+      RenderViewWithFailover("edit.vm", "edit.auto.vm");
+    }
+    else
+    {
+      throw new Exception( String.Format( "No record of type Event with key value {0} found", id));
+    }
+  }
+
+

This means that it should be trivial to decide at some point in development of a project to manually modify and maintain auto-generated code.

+

What can the Application Description Language framework now do?

+
+

Currently the framework includes:

+

adl2entityclass.xsl

+

Transforms the ADL file into C# source files for classes which describe the entities in a manner acceptable to NHibernate, a widely used Object/Relational mapping layer.

+

adl2mssql.xsl

+

Transforms the ADL file into an SQL script in Microsoft SQL Server 2000 syntax which initialises the database required by the application, with all relationships, permissions, referential integrity constraints and so on.

+

adl2views.xsl

+

Transforms the ADL file into Velocity template files as used by the Monorail framework, one template each for all the lists, forms and inspectors described in the ADL.

+

adl2controllerclasses.xsl

+

Transforms the ADL file into a series of C# source files for classes which are controllers as used by the Monorail framework.

+

adl2hibernate.xsl

+

Transforms the ADL file into a Hibernate mapping file, used by the Hibernate (Java) and NHibernate (C#) Object/Relational mapping layers. This transform is relatively trivial, since ADL is not greatly different from being a superset of the Hibernate vocabulary - it describes the same sorts of things but in more detail.

+

adl2pgsql.xsl

+

Transforms the ADL file into an SQL script in Postgres 7 syntax which initialises the database required by the application, with all relationships, permissions, referential integrity constraints and so on.

+

So is ADL a quick way to build Monorail applications?

+
+

Yes and no.

+

ADL is a quick way to build Monorail applications, because it seemed to me that as Monorail/NHibernate are technologies that the company is adopting and it would be better to work with technologies with which we already have expertise - it’s no good doing these things if other people can’t maintain them afterwards.

+

However ADL wasn’t originally conceived with Monorail in mind. It was originally intended to generated LISP for CLHTTPD, and I have a half-finished set of scripts to generate Java as part of the Jacquard2 project which I never finished. Because ADL is at a level of abstraction considerably above any 3GL, it is inherently agnostic to what 3GL it is compiled down to - so that it would be as easy to write transforms that compiled ADL to Struts or Ruby on Rails as to C#/Monorail. More importantly, ADL isn’t inherently limited to Web applications - it doesn’t actually know anything about the Web. It should be possible to write transforms which compile ADL down to Windows native applications or to native applications for mobile phones (and, indeed, if we did have those transforms then we could make all our applications platform agnostic).

+

Limitations on ADL

+
+

Current limitations

+

Although I’ve built experimental systems before using ADL, the SRU project is the first time I’ve really used it in anger. There are some features I need which it can’t yet represent.

+

Authentication model

+

For SRU, I have implemented an authentication model which authenticates the user against real database user accounts. I’ve done this because I think, in general, this is the correct solution, and because without this sort of authentication you cannot implement table-layer security. However most web applications use application layer authentication rather than database layer authentication, and I have not yet written controller-layer code to deal with this. So unless you do so, ADL applications can currently only authenticate at database layer.

+

ADL defines field-level permissions, but the current controller generator does not implement this.

+

Alternative Verbs

+

Generically, with an entity form, one needs to be able to save the record being edited, and one (often) needs to be able to delete it. But sometimes one needs to be able to do other things. With SRU, for example, there is a need to be able to export event data to Perfect Table Plan, and to reimport data from Perfect Table Plan. This will need custom buttons on the event entity form, and will also need hand-written code at the controller layer to respond to those buttons.

+

Also, a person will have, over the course of their interaction with the SRU, potentially many invitations. In order to access those invitations it will be necessary to associate lists of dependent records with forms. Currently ADL cannot represent these.

+

Inherent limitations

+

At this stage I doubt whether there is much point in extending ADL to include a vocabulary to describe business processes. It would make the language much more complicated, and would be unlikely to be able to offer a significantly higher level of abstraction than current 3GLs. If using ADL does not save work, it isn’t worth doing it in ADL; remember this is conceived as an 80/20 solution, and you need to be prepared to write the 20 in something else.

+

ADL Vocabulary

+
+

This section of this document presents and comments on the existing ADL document type definition (DTD).

+

Basic definitions

+

The DTD starts with some basic definitions

+

<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --> <!-- Before we start: some useful definitions –> <!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->

+

<!-- boolean means true or false –> <!ENTITY % Boolean “(true|false)” >

+

<!-- Locale is a string comprising an ISO 639 language code followed by a space followed by an ISO 3166 country code, or else the string ‘default’. See: <URL:http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt <URL:http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html –> <!ENTITY % Locale “CDATA” >

+

Permissions

+

Key to any data driven application is who has authority to do what to what: ‘permissions’.

+

<!-- permissions a group may have on an entity, list, page, form or field permissions are deemed to increase as you go right. A group cannot have greater permission on a field than on the form it is in, or greater permission on form than the entity it belongs to

+
    none:                   none
+    read:                   select
+    insert:                 insert
+    noedit:                 select, insert
+    edit:                   select, insert, update
+    all:                    select, insert, update, delete
+
+

–> <!ENTITY % Permissions “none|read|insert|noedit|edit|all” >

+

Data types

+

ADL needs to know what type of data can be stored on different properties of different entities. The data types were originally based on JDBC data types:

+

<!-- data types which can be used in a definition to provide validation - e.g. a string can be used with a regexp or a scalar can be used with min and max values string: varchar java.sql.Types.VARCHAR integer: int java.sql.Types.INTEGER real: double java.sql.Types.DOUBLE money: money java.sql.Types.INTEGER date: date java.sql.Types.DATE time: time java.sql.Types.TIME timestamp: timestamp java.sql.Types.TIMESTAMP –>

+

Definable data types

+

However, in order to be able to do data validation, it’s useful to associate rules with data types. ADL has the concept of definable data types, to allow data validation code to be generated from the declarative description. These definable data types are used in the ADL application, for example, to define derived types for phone numbers, email addresses, postcodes, and range types.

+

<!ENTITY % DefinableDataTypes “string|integer|real|money|date|time|timestamp” >

+

<!-- data types which are fairly straightforward translations of JDBC data types boolean: boolean or java.sql.Types.BIT char(1) java.sql.Types.CHAR text: text or java.sql.Types.LONGVARCHAR memo java.sql.Types.CLOB –> <!ENTITY % SimpleDataTypes “%DefinableDataTypes;|boolean|text” >

+

<!-- data types which are more complex than SimpleDataTypes… entity : a foreign key link to another entity; link : a many to many link (via a link table); defined : a type defined by a definition. –> <!ENTITY % ComplexDataTypes “entity|link|defined” >

+

<!-- all data types –> <!ENTITY % AllDataTypes “%ComplexDataTypes;|%SimpleDataTypes;” >

+

Page content

+

Pages in applications typically have common, often largely static, sections above, below, to the left or right of the main content which incorporates things like branding, navigation, and so on. This can be defined globally or per page. The intention is that the head, top and foot elements in ADL should be allowed to contain arbitrary HTML, but currently I don’t have enough skill with DTD design to know how to specify this.

+

<!-- content, for things like pages (i.e. forms, lists, pages) –> <!ENTITY % Content “head|top|foot” >

+

<!ENTITY % PageContent “%Content;|field” >

+

<!ENTITY % PageStuff “%PageContent;|permission|pragma” >

+

<!ENTITY % PageAttrs “name CDATA #REQUIRED properties (all|listed) #REQUIRED” >

+

The Elements

+

Application

+

The top level element of an Application Description Language file is the application element:

+

<!-- the application that the document describes: required top level element –> <!ELEMENT application ( content?, definition*, group*, entity*)> <!ATTLIST application name CDATA #REQUIRED version CDATA #IMPLIED>

+

Definition

+

In order to be able to use defined types, you need to be able to provide definitions of these types:

+

<!-- the definition of a defined type. At this stage a defined type is either a string in which case it must have size and pattern, or a scalar in which case it must have minimum and/or maximum pattern must be a regular expression as interpreted by org.apache.regexp.RE minimum and maximum must be of appropriate format for the datatype specified. Validation may be done client-side and/or server-side at application layer and/or server side at database layer. –> <!ELEMENT definition (help*) > <!ATTLIST definition name CDATA #REQUIRED type (%DefinableDataTypes;) #REQUIRED size CDATA #IMPLIED pattern CDATA #IMPLIED minimum CDATA #IMPLIED maximum CDATA #IMPLIED>

+

Groups

+

In order to be able to user permissions, we need to define who has those permissions. Groups in ADL map directly onto groups/roles at SQL level, but the intention with ADL is that groups should be defined hierarchically.

+

<!-- a group of people with similar permissions to one another –> <!ELEMENT group EMPTY> <!-- the name of this group –> <!ATTLIST group name CDATA #REQUIRED> <!-- the name of a group of which this group is subset –> <!ATTLIST group parent CDATA #IMPLIED>

+

Enities and Properties

+

A thing-in-the-domain has properties. Things in the domain fall into regularities, groups of things which share similar collections of properties, such that the values of these properties may have are constrained. This is a representation of the world which is not perfect, but which is sufficiently useful to be recognised by the software technologies which ADL abstracts, so we need to be able to define these. Hence we have entities and properties/

+

<!-- an entity which has properties and relationships; maps onto a database table or a Java serialisable class - or, of course, various other things –> <!ELEMENT entity ( content?, property*, permission*, (form | page | list)*)> <!ATTLIST entity name CDATA #REQUIRED>

+

<!-- a property (field) of an entity (table)

+
    name:                   the name of this property.
+    type:                   the type of this property.
+
+    default:                the default value of this property. There will probably be
+                                    magic values of this!
+    definition:             name of the definition to use, it type = 'defined'.
+    distinct:               distinct='system' required that every value in the system
+                                    will be distinct (i.e. natural primary key);
+                                    distinct='user' implies that the value may be used by users
+                                    in distinguishing entities even if values are not formally
+                                    unique;
+                                    distinct='all' implies that the values are formally unique
+                                    /and/ are user friendly.
+    entity:                 if type='entity', the name of the entity this property is
+                                    a foreign key link to.
+    required:               whether this propery is required (i.e. 'not null').
+    size:                   fieldwidth of the property if specified.
+
+

–> <!ELEMENT property ( option*, prompt*, help*, ifmissing*)>

+

<!ATTLIST property name CDATA #REQUIRED type (%AllDataTypes;) #REQUIRED default CDATA #IMPLIED definition CDATA #IMPLIED distinct (none|all|user|system) #IMPLIED entity CDATA #IMPLIED required %Boolean; #IMPLIED size CDATA #IMPLIED>

+

Options

+

Sometimes a property has a constrained list of specific values; this is represented for example in the enumerated types supported by many programming languages. Again, we need to be able to represent this.

+

<!-- one of an explicit list of optional values a property may have NOTE: whether options get encoded at application layer or at database layer is UNDEFINED; either behaviour is correct. If at database layer it’s also UNDEFINED whether they’re encoded as a single reference data table or as separate reference data tables for each property. –> <!ELEMENT option (prompt*)> <!-- if the value is different from the prompt the user sees, specify it –> <!ATTLIST option value CDATA #IMPLIED>

+

Permissions

+

Permissions define policies to allow groups of users to access forms, pages, fields (not yet implemented) or entities. Only entity permissions are enforced at database layer, and field protection is not yet implemented at controller layer. But the ADL allows it to be described, and future implementations of the controller generating transform will do this.

+

<!-- permissions policy on an entity, a page, form, list or field

+
    group:                  the group to which permission is granted
+    permission:             the permission which is granted to that group
+
+

–> <!ELEMENT permission EMPTY> <!ATTLIST permission group CDATA #REQUIRED permission (%Permissions;) #REQUIRED>

+

Pragmas

+

Pragmas are currently not used at all. They are there as a possible means to provide additional controls on forms, but may not be the correct solutions for that.

+ +

<!ELEMENT pragma EMPTY> <!ATTLIST pragma name CDATA #REQUIRED value CDATA #REQUIRED>

+

Prompts, helptexts and error texts

+

When soliciting a value for a property from the user, we need to be able to offer the user a prompt to describe what we’re asking for, and we need to be able to offer that in the user’s preferred natural language. Prompts are typically brief. Sometimes, however, we need to give the user a more extensive description of what is being solicited - ‘help text’. Finally, if the data offered by the user isn’t adequate for some reason, we need ways of feeding that back. Currently the only error text which is carried in the ADL is ‘ifmissing’, text to be shown if the value for a required property is missing. All prompts, helptexts and error texts have locale information, so that it should be possible to generate variants of all pages for different natural languages from the same ADL.

+

<!-- a prompt for a property or field; used as the prompt text for a widget which edits it. Typically there will be only one of these per property per locale; if there are more than one all those matching the locale may be concatenated, or just one may be used.

+
    prompt:                 the prompt to use
+
+    locale:                 the locale in which to prefer this prompt
+
+

–> <!ELEMENT prompt EMPTY> <!ATTLIST prompt prompt CDATA #REQUIRED locale %Locale; #IMPLIED >

+

<!-- helptext about a property of an entity, or a field of a page, form or list, or a definition. Typically there will be only one of these per property per locale; if there are more than one all those matching the locale may be concatenated, or just one may be used.

+
    locale:                 the locale in which to prefer this prompt
+
+

–> <!ELEMENT help (#PCDATA)> <!ATTLIST help locale %Locale; #IMPLIED >

+ +

<!ELEMENT ifmissing (#PCDATA)> <!ATTLIST ifmissing locale %Locale; #IMPLIED>

+

Forms, Pages and Lists

+

The basic pages of the user interface. Pages and Forms by default show fields for all the properties of the entity they describe, or they may show only a listed subset. Currently lists show fields for only those properties which are ‘user distinct’. Forms, pages and lists may each have their own head, top and foot content, or they may inherit the content defined for the application.

+

<!-- a form through which an entity may be added or edited –> <!ELEMENT form ( %PageStuff;)*> <!ATTLIST form %PageAttrs;>

+

<!-- a page on which an entity may be displayed –> <!ELEMENT page ( %PageStuff;)*> <!ATTLIST page %PageAttrs;>

+

<!-- a list on which entities of a given type are listed

+
    onselect:               name of form/page/list to go to when
+                            a selection is made from the list
+
+

–> <!ELEMENT list ( %PageStuff;)*> <!ATTLIST list %PageAttrs; onselect CDATA #IMPLIED >

+

<!-- a field in a form or page –> <!ELEMENT field (prompt*, help*, permission*) > <!ATTLIST field property CDATA #REQUIRED >

+

<!-- a container for global content –> <!ELEMENT content (%Content;)*>

+

<!-- content to place in the head of the generated document; this is #PCDATA because it will almost certainly belong to a different namespace (usually HTML) –> <!ELEMENT head (#PCDATA) >

+

<!-- content to place in the top of the body of the generated document; this is #PCDATA because it will almost certainly belong to a different namespace (usually HTML) –> <!ELEMENT top (#PCDATA) >

+

<!-- content to place at the foot of the body of the generated document; this is #PCDATA because it will almost certainly belong to a different namespace (usually HTML) –> <!ELEMENT foot (#PCDATA) >

+

Using ADL in your project

+
+

Selecting the version

+

Current versions of ADL are given at the top of this document. Historical versions are as follows:

+
    +
  • Version 0.1: Used by the SRU Hospitality application only. The Hospitality Application will be upgraded to the current version whenever it has further work done on it. +
      +
    • You cannot access Version 1.0 at all, as nothing in current development should be using it. It is in CVS as part of the SRU Hospitality application
    • +
    • As soon as SRU Hospitality has been updated to stable, version 0.1 will be unmaintained.
    • +
    +
  • +
  • Version 0.3: Identical to Version 1.0, except that the obsolete transforms01 directory has not been removed. + +
  • +
  • Version 1.0: Identical to Version 3.0, except tidied up. +
      +
    • +
        +
      • the obsolete transforms01 directory has been removed.
      • +
      +
        +
      • adl2entityclass.xslt has been renamed to adl2entityclasses.xslt, for consistency
      • +
      +
    • +
    • This is the current stable branch; it is the HEAD branch in CVS.
    • +
    • If there are bugs, I (sb) will fix them.
    • +
    • If you want new functionality, it belongs in ‘unstable’.
    • +
    • You can access 1.0 here: http://libs.cygnets.co.uk/adl/1.0/ADL/
    • +
    • Projects using ADL 1.0 should be built with the 1.0 version of CygnetToolkit
    • +
    +
  • +
  • unstable: this is the current development branch, the branch tagged b_development in CVS. +
      +
    • It should be backwards compatible with 1.0 (i.e. anything which builds satisfactorily with 1.0 should also build with unstable)
    • +
    • It may have additional features
    • +
    • It is not guaranteed to work, and before a final release of a product to a customer we may wish to move changes into a new ‘stable’ branch.
    • +
    • You can access the unstable branch here: http://libs.cygnets.co.uk/adl/unstable/ADL/
    • +
    • The version at that location is automatically updated from CVS every night
    • +
    • Projects using the b_development branch of ADL should be built against the b_development branch of CygnetToolkit.
    • +
    +
  • +
+

Integrating into your build

+

To use ADL, it is currently most convenient to use NAnt. It is probably possible to do this with MSBuild, but as of yet I don’t know how.

+

Properties

+

For the examples given here to work, you will need to set up at least the following properties in your NAnt .build file:

+

+

where, obviously, YourProjectName, YourSourceDir and YourADL.adl.xml stand in for the actual names of your project, your source directory (relative to your solution directory, where the .build file is) and your ADL file, respectively. Note that if it is to be used as an assembly name, the project name should include neither spaces, hyphens nor periods. If it must do so, you should give an assembly name which does not, explicitly.

+

Canonicalisation

+

The first thing you need to do with your ADL file is canonicalise it. You should generally not need to alter this, you should copy and paste it verbatim:

+

+

Generate NHibernate mapping

+

You should generally not need to alter this at all, just copy and paste it verbatim:

+

+

Generate SQL

+

+

Generate C# entity classes (‘POCOs’)

+

Note that for this to work you must have the following:

+
    +
  • Artistic Style’ installed as c:\Program Files\astyle\bin\astyle.exe
  • +
+

+
    <target name="classes" description="creates C# classes for entities in the database"
+                    depends="fetchtasks canonicalise">
+            <loadtasks assembly="${nant-tasks}" />
+
+            <style verbose="true" style="${adl-transforms}/adl2entityclass.xslt"
+                       in="${canonical}"
+                       out="${tmpdir}/classes.auto.cs">
+                    <parameters>
+                            <parameter name="locale" value="en-UK"/>
+                            <parameter name="controllerns" value="${controllerns}"/>
+                            <parameter name="entityns" value="${entityns}"/>
+                    </parameters>
+            </style>
+            <exec program="c:\\Program Files\\astyle\\bin\\astyle.exe"
+                    basedir="."
+                    commandline="--style=java --indent=tab=4 --indent-namespaces ${tmpdir}/classes.auto.cs"/>
+            <split-regex in="${tmpdir}/classes.auto.cs"
+                    destdir="${src.dir}/Entities"
+                    pattern="cut here: next file '(\[a-zA-Z0-9_.\]*)'"/>
+    </target>
+
+

Generate Monorail controller classes

+

Note that for this to work you must have

+
    +
  • Artistic Style’ installed as c:\Program Files\astyle\bin\astyle.exe
  • +
  • The ‘fetchtasks’ target from the ‘entity classes’ stanza, above.
  • +
+

\ No newline at end of file diff --git a/doc/intro.md b/doc/intro.md index 2e730b8..0489874 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -1,6 +1,6 @@ # Introduction -**NOTE**: *this markdown was automatically generated from `adl_user_doc.html`, which in turn was taken from the Wiki page on which this documentation was originally written.* +**NOTE**: *this markdown was automatically generated from `adl_user_doc.html`, which in turn was taken from the Wiki page on which this documentation was originally written.* **It is substantially out of date.** Application Description Language framework ========================================== @@ -8,21 +8,21 @@ Application Description Language framework ## Contents -------- -* [1 What is Application Description Language?](#What_is_Application_Description_Language.3F) +* [1 What is Application Description Language?](#What_is_Application_Description_Language) * [2 Current versions](#Current_versions) -* [3 What is the Application Description Language Framework?](#What_is_the_Application_Description_Language_Framework.3F) -* [4 Why does it matter?](#Why_does_it_matter.3F) +* [3 What is the Application Description Language Framework?](#What_is_the_Application_Description_Language_Framework) +* [4 Why does it matter?](#Why_does_it_matter) * [4.1 Automated Application Generation](#Automated_Application_Generation) * [4.2 Integration with hand-written code](#Integration_with_hand-written_code) * [4.3 High quality auto-generated code](#High_quality_auto-generated_code) -* [5 What can the Application Description Language framework now do?](#What_can_the_Application_Description_Language_framework_now_do.3F) +* [5 What can the Application Description Language framework now do?](#What_can_the_Application_Description_Language_framework_now_do) * [5.1 adl2entityclass.xsl](#adl2entityclass.xsl) * [5.2 adl2mssql.xsl](#adl2mssql.xsl) * [5.3 adl2views.xsl](#adl2views.xsl) * [5.4 adl2controllerclasses.xsl](#adl2controllerclasses.xsl) * [5.5 adl2hibernate.xsl](#adl2hibernate.xsl) * [5.6 adl2pgsql.xsl](#adl2pgsql.xsl) -* [6 So is ADL a quick way to build Monorail applications?](#So_is_ADL_a_quick_way_to_build_Monorail_applications.3F) +* [6 So is ADL a quick way to build Monorail applications?](#So_is_ADL_a_quick_way_to_build_Monorail_applications) * [7 Limitations on ADL](#Limitations_on_ADL) * [7.1 Current limitations](#Current_limitations) * [7.1.1 Authentication model](#Authentication_model) diff --git a/doc/js/highlight.min.js b/doc/js/highlight.min.js new file mode 100644 index 0000000..6486ffd --- /dev/null +++ b/doc/js/highlight.min.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.6.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||R(i))return i}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):E(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":y.classPrefix,i='',i+n+o}function p(){var e,t,r,a;if(!E.k)return n(B);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)a+=n(B.substr(t,r.index-t)),e=g(E,r),e?(M+=e[1],a+=h(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return a+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?B+=n:(a.rE||a.eE||(B+=n),b(),a.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=i||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substr(O,I.index-O),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},a=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"
":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n,t,r,o,s,p=i(e);a(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}});hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"meta",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure"}}]}}); \ No newline at end of file diff --git a/doc/js/jquery.min.js b/doc/js/jquery.min.js new file mode 100644 index 0000000..73f33fb --- /dev/null +++ b/doc/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("