From eced652bb21fe1fbaaf5363b1a9066f904784045 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:04:57 -0500 Subject: [PATCH 01/29] ajax doc --- docs/ajax.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 docs/ajax.js diff --git a/docs/ajax.js b/docs/ajax.js new file mode 100644 index 0000000..9a951eb --- /dev/null +++ b/docs/ajax.js @@ -0,0 +1,50 @@ +// Implement simple cached AJAX functions. + +var _cache = {}; + +/* +* Get a promise for the HTTP get responseText. +*/ +function httpGetPromise(url) { + const promise = new Promise((_resolve, _reject) => { + httpGet(url, (responseText) => { + _resolve(responseText); + }, + (error) => { + _reject(error); + }); + }); + return promise +} + +function httpGet(url, onload, onerror) { + if (_cache[url]) { + _cachedHttpGet(url, onload, onerror); + } + else{ + _httpGet(url, onload, onerror); + } +} + +function _cachedHttpGet(url, onload, onerror) { + setTimeout(() => { onload(_cache[url]) }, 0); +} + +function _httpGet(url, onload, onerror) { + + var xobj = new XMLHttpRequest(); + xobj.open('GET', url, true); // Asynchronous + + xobj.onload = function () { + // add document to cache. + _cache[url] = xobj.responseText; + onload(xobj.responseText); + }; + + xobj.onerror = function (error) { + console.log(error) + onerror(error) + }; + + xobj.send(null); +} From 7043d72c990771e6fa46216e32bd60e476719898 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:05:32 -0500 Subject: [PATCH 02/29] all docs --- docs/all-documents.html | 371 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 docs/all-documents.html diff --git a/docs/all-documents.html b/docs/all-documents.html new file mode 100644 index 0000000..233f2be --- /dev/null +++ b/docs/all-documents.html @@ -0,0 +1,371 @@ + + + + + + + All Documents + + + + + + + + + + + + + + +
+ + + + + +
+ + + + +
+

All Documents

+ +
    +
  • + +
    src
    +
    index.html
    +
    Package
    +
    Package
    +
    PUBLIC
    +
    No package docstring; 1/1 module, 0/1 package documented
    +
  • + +
    src.app
    +
    src.app.html
    +
    Module
    +
    Module
    +
    PUBLIC
    +
    The module app holds the function related to flask app and database.
    +
  • + +
    src.User
    +
    src.User.html
    +
    Package
    +
    Package
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models
    +
    src.User.models.html
    +
    Module
    +
    Module
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.routes
    +
    src.User.routes.html
    +
    Module
    +
    Module
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.app
    +
    src.app.html#app
    +
    Attribute
    +
    Variable
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.mongo_conn
    +
    src.app.html#mongo_conn
    +
    Attribute
    +
    Variable
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.mongo_params
    +
    src.app.html#mongo_params
    +
    Attribute
    +
    Variable
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.mongodb_client
    +
    src.app.html#mongodb_client
    +
    Attribute
    +
    Variable
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.login_required
    +
    src.app.html#login_required
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.sgup
    +
    src.app.html#sgup
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Route: '/' The index function renders the index.html page.
    +
  • + +
    src.app.lgin
    +
    src.app.html#lgin
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Route: '/' The login function renders login.html page.
    +
  • + +
    src.app.index
    +
    src.app.html#index
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Route: '/' The index function renders the index.html page.
    +
  • + +
    src.app.login
    +
    src.app.html#login
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Route: '/login' The index function renders the login.html page.
    +
  • + +
    src.app.search
    +
    src.app.html#search
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.app.add
    +
    src.app.html#add
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    The add function adds the skills column and adds the job data to the database.
    +
  • + +
    src.app.read_from_db
    +
    src.app.html#read_from_db
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    The read_from_db function reads the job details based on the input provided using regex. Returns a DataFrame with the details
    +
  • + +
    src.User.models.User
    +
    src.User.models.User.html
    +
    Class
    +
    Class
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models.User.startSession
    +
    src.User.models.User.html#startSession
    +
    Function
    +
    Method
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models.User.signup
    +
    src.User.models.User.html#signup
    +
    Function
    +
    Method
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models.User.logout
    +
    src.User.models.User.html#logout
    +
    Function
    +
    Method
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models.User.login
    +
    src.User.models.User.html#login
    +
    Function
    +
    Method
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models.User.showProfile
    +
    src.User.models.User.html#showProfile
    +
    Function
    +
    Method
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.models.User.saveResume
    +
    src.User.models.User.html#saveResume
    +
    Function
    +
    Method
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.routes.signup
    +
    src.User.routes.html#signup
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.routes.signout
    +
    src.User.routes.html#signout
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.routes.loginUser
    +
    src.User.routes.html#loginUser
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.routes.showUserProfile
    +
    src.User.routes.html#showUserProfile
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • + +
    src.User.routes.saveResume
    +
    src.User.routes.html#saveResume
    +
    Function
    +
    Function
    +
    PUBLIC
    +
    Undocumented
    +
  • +
+
+ + \ No newline at end of file From cd604e78336b1e68ea72634a0ab0836bb29ce1ad Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:05:51 -0500 Subject: [PATCH 03/29] apidocs --- docs/apidocs.css | 1148 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1148 insertions(+) create mode 100644 docs/apidocs.css diff --git a/docs/apidocs.css b/docs/apidocs.css new file mode 100644 index 0000000..220b2d2 --- /dev/null +++ b/docs/apidocs.css @@ -0,0 +1,1148 @@ +body { + display: flex; + flex-direction: column; + min-height: 100vh; + overflow-y: scroll; +} + +.container-fluid{ + max-width: 1380px; + width: 100%; + flex: auto; +} + +nav.navbar { + width:100%; + margin-bottom: 0; +} + +nav.mainnavbar > div.container-fluid { + display: flex; + flex-wrap: wrap; +} + +nav div.layoutOptions { + display: flex; + flex-wrap: wrap; + align-items: end; + margin-left: auto; + padding-top:11px; +} + +nav.navbar .navbar-header { + float: none; + width: 100%; + position: relative; +} + +.page-header { + margin-top: 22px; + top: 0; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: baseline; + background-color: #fff; + margin-bottom: 3px; + border-bottom: 0; + box-shadow: 0 0 8px 8px #fff; + z-index: 99; +} + +.navbar-brand { + padding: 0; + margin: 0; + height: auto; +} + +.navbar-brand a, .navbar-brand span { + color:#777777; + padding: 15px; + display: inline-block; +} + +.navbar-brand *:first-child { + padding-right: 0; +} + +.navbar-brand *:last-child { + padding-left: 0; + padding-right: 0; +} + +.navbar-brand a:hover { + color: #444444; + text-decoration: none; +} + +a.projecthome:hover { + color: #23527c; +} + +.navlinks { + margin: 0; + display: flex; + flex-wrap: wrap; + align-items: baseline; +} + +.navlinks > a { + padding: 10px 0 10px 15px; +} + + +.navlinks > a:hover { + background-color: transparent; + text-decoration: none; +} + +.page-header h1 { + margin: 0; +} + +.categoryHeader { + font-size: 24px; + color: #777; + margin-bottom: 1.8em; +} + +/* Footer */ + +footer.navbar { + margin: auto 0 0 0; + padding-top: 15px; + padding-bottom: 15px; + background-color: #fff; + border-width: 1px 0 0 0; + border-radius: 0; + text-align: center; +} + +a[name] { + position: relative; + bottom: 10px; + font-size: 0; +} + +ul { + margin-top: 10px; + margin-left: 10px; + padding-left: 10px; +} + +li { + padding-top: 5px; + padding-bottom: 5px; +} + +#summaryTree .compact-modules { + list-style: none; + line-height: 1.8em; +} + +li a { + text-decoration: none; +} + +ul ul { + border-left-color: #e1f5fe; + border-left-width: 1px; + border-left-style: solid; +} + +ul ul ul { + border-left-color: #b3e5fc; +} + +ul ul ul ul { + border-left-color: #81d4fa; +} + +ul ul ul ul ul { + border-left-color: #4fc3f7; +} + +ul ul ul ul ul ul { + border-left-color: #29b6f6; +} + +ul ul ul ul ul ul ul { + border-left-color: #03a9f4; +} + +ul ul ul ul ul ul ul { + border-left-color: #039be5; +} + +.pre { + white-space: pre; +} + +.undocumented { + font-style: italic; + color: #9e9e9e; +} + +.functionBody p { + margin: 0; + padding: 8px 0 6px; +} + +#splitTables > p { + margin-bottom: 5px; +} + +#splitTables > table { + margin-bottom: 20px; + width: 100%; + border: 0; +} + +#splitTables > table tr { + border-bottom-color: #eee; + border-bottom-width: 1px; + border-bottom-style: solid; + width: 100%; +} + +#splitTables > table tr td { + padding: 5px; + border-left-color: #eee; + border-left-width: 1px; + border-left-style: solid; +} + +.fieldTable { + width: 100%; + border: 0; +} + +/* Arg name */ +.fieldArg { + margin-right: 7px; +} + +.fieldArg:before { + margin-right: 6px; + content: "\2022"; + font-size: 14px; +} + +.fieldTable tr:not(.fieldStart) td:first-child, +.valueTable tr:not(.fieldStart) td:first-child{ + padding: 3px 4px 3px 10px; +} + +.fieldTable tr td { + padding: 2px; +} + + +/* Argument name + type column table */ +.fieldTable tr td.fieldArgContainer { + width: 325px; + word-break: break-word; +} + +/* parameters names in parameters table */ +.fieldTable tr td.fieldArgContainer > .fieldArg { + display: inline; +} + +/* parameters types (in parameters table) */ +.fieldTable tr td.fieldArgContainer > code { + /* we don't want word break for the types because we already add tags inside the type HTML, and that should suffice. */ + word-break: normal; + display: inline-flex; + flex-wrap: wrap; +} + +/* Argument description column or return value desc, etc */ +.fieldTable tr td::nth-child(2) { + padding-left: 10px; +} + +/* Kind column table */ +#splitTables > table tr td:first-child { + /* border-left: none; */ + width: 150px; +} + +/* Attr name column table */ +#splitTables > table tr td:nth-child(2) { + width: 240px; + word-break: break-word; +} + +/* Fix proportion size of summary table columns */ +#splitTables > table { + table-layout: fixed; +} + +/* For smaller displays, i.e. half screen */ +@media only screen and (max-width: 1100px) { + + /* Attr name column table */ + #splitTables > table tr td:nth-child(2) { + width: 200px; + } + + /* Summary column table */ + #splitTables > table tr td:nth-child(3) { + width: auto; + } + +} + +@media only screen and (max-width: 820px) { + + /* Kind column table */ + #splitTables > table tr td:first-child { + border-left: none; + width: 20%; + } + + /* Attr name column table */ + #splitTables > table tr td:nth-child(2) { + width: 160px; + } + /* Argument name + type column table */ + .fieldTable tr td.fieldArgContainer { + width: 170px; + } + .fieldTable { + table-layout: fixed; + } +} + +@media only screen and (max-width: 450px) { + /* Attr name column table */ + #splitTables > table tr td:nth-child(2) { + width: 100px; + } + /* Argument name + type column table */ + .fieldTable tr td.fieldArgContainer { + width: 125px; + } +} + +table .package { + background-color: #fff3e0; +} + +table .module { + background-color: #fff8e1; +} + +table .class, table .classvariable, table .baseclassvariable, table .exception { + background-color: #fffde7; +} + +table .instancevariable, table .baseinstancevariable, table .variable, table .attribute, table .property { + background-color: #f3e5f5; +} + +table .interface { + background-color: #fbe9e7; +} + +table .method, table .function, table .basemethod, table .baseclassmethod, table .classmethod { + background-color: #f1f8e9; +} + +table .private { + background-color: #f1f1f1; +} + +.fieldName { + font-weight: bold; +} + + +#childList > div { + margin: 10px; + padding: 10px; + padding-bottom: 5px; + display: block; + border-left-color: #03a9f4; + border-left-width: 1px; + border-left-style: solid; + background: #fafafa; +} + +.functionBody { + margin-left: 5px; +} + +.functionBody > #part { + font-style: italic; +} + +.functionBody > #part > a { + text-decoration: none; +} + +.functionBody .interfaceinfo { + font-style: italic; + margin-bottom: 3px; + margin-top: 3px; +} + +.functionBody > .undocumented { + + margin-top: 6px; + margin-bottom: 6px; +} + +/* +- Links to class/function/etc names are nested like this: + label + +- 'functionHeader' is used for lines like `def func():` and `var =` +*/ +code, .literal, .pre, #childList > div .functionHeader, +#splitTables > table tr td:nth-child(2), .fieldArg { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code, #childList > div .functionHeader, .fieldArg { + color: #222222; +} + +/* Intersphinx links are not red, but simply blue */ +a.intersphinx-link { + color: #03458a; + background-color: #f0ebe694; +} + +/* Links to objects within the system use this special css. +This applies to inline docstring content marked up as code, + for example L{foo} in epytext or `bar` in restructuredtext, + but also to links that are present in summary tables. +*/ +a.internal-link { + color:#c7254e; + background-color:#f9f2f4; +} + +/* top navagation bar */ +.page-header > h1 { + margin-top: 0; +} +.page-header > h1 > code { + color: #971c3a; +} + +/* Bootstart 3.x sets font-size to 17.5px which just + looks ridiculously large, so we unset it here. +*/ +blockquote { + font-size: unset; +} + +/* +This defines the code style, it's black on light gray. +It also overwrite the default values inherited from bootstrap min +*/ +code, .literal { + padding:2px 4px; + background-color: #f4f4f4; + border-radius:4px +} + + +a.sourceLink { + color: #337ab7!important; + font-weight: normal; + background-color: transparent!important; +} + + + + +.moduleDocstring { + margin: 20px; +} + +#partOf { + margin-top: -13px; + margin-bottom: 19px; +} + +.fromInitPy { + font-style: italic; +} + +pre { + padding-left: 0; +} + +/* Private stuff */ + +body.private-hidden #splitTables .private, +body.private-hidden #childList .private, +body.private-hidden #summaryTree .private, +body.private-hidden nav.sidebar .private, +body.private-hidden #search-results .private, +body.private-hidden .container > .private { + display: none!important; +} + +/* Show private and other options */ + +#showPrivate:hover { + text-decoration: none; +} + +#showPrivate button { + padding: 5px; + padding-bottom: 15px; +} + +#showPrivate button:hover { + text-decoration: none; +} + +#current-docs-container { + font-style: italic; + padding-top: 11px; +} + +/* Deprecation stuff */ + +.deprecationNotice { + margin: 10px; +} + +/* Syntax highlighting for source code */ + +.py-string { + color: #337ab7; +} +.py-comment { + color: #309078; + font-style: italic; +} +.py-keyword { + font-weight: bold; +} +.py-defname { + color: #a947b8; + font-weight: bold; +} +.py-builtin { + color: #fc7844; + font-weight: bold; +} + +/* Doctest */ + +pre.py-doctest { + padding: .5em; +} +.py-prompt, .py-more { + color: #a8a8a8; +} +.py-output { + color: #c7254e; +} + +/* Admonitions */ + +div.rst-admonition p.rst-admonition-title:after { + content: ":"; +} + +div.rst-admonition p.rst-admonition-title { + margin: 0; + padding: 0.1em 0 0.35em 0em; + font-weight: bold; +} + +div.rst-admonition p.rst-admonition-title { + color: #333333; +} + +div.rst-admonition { + padding: 8px; + margin-bottom: 20px; + background-color: #EEE; + border: 1px solid #CCC; + border-radius: 4px; +} + +div.warning, div.attention, div.danger, div.error, div.caution { + background-color: #ffcf9cb0; + border: 1px solid #ffbbaa; +} + +div.danger p.rst-admonition-title, div.error p.rst-admonition-title, div.caution p.rst-admonition-title { + color: #b94a48; +} + +div.tip p.rst-admonition-title, div.hint p.rst-admonition-title, div.important p.rst-admonition-title{ + color: #3a87ad; +} + +div.tip, div.hint, div.important { + background-color: #d9edf7; + border-color: #bce8f1; +} + +.sidebarcontainer { + width: 297px; /* Set the width of the sidebar: 290px + 2px for the border + 5px for the padding */ + max-height: 100vh; /* Full-height: remove this if you want "auto" height */ + float: left; + padding: 10px 0px 10px 5px; + margin:24px 20px 20px 0; + border: 1px solid; + border-radius: 4px; + display: flex; + position: sticky; + top: 0; + overflow-wrap: break-word; + overflow-x: none; + overflow-y: scroll; + background-color: #fbfbfb; + border-color: #e7e7e7; + scrollbar-width: thin; + scrollbar-color: rgb(194,194,194) rgb(249,249,249); +} + +.sidebarcontainer::-webkit-scrollbar { + width: 10px; /* Scrollbar width on Chromium-based browsers */ + border: solid 1px rgb(229,229,229); + background-color: rgb(249,249,249); +} + +.sidebarcontainer::-webkit-scrollbar:horizontal { + display: none; +} + +.sidebarcontainer::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px 5px transparent; + border: solid 1px transparent; +} + +.sidebarcontainer::-webkit-scrollbar-thumb { + box-shadow: inset 0 0 5px 5px rgb(194,194,194); + border: solid 2px transparent; + border-radius: 5px; +} + + +/* The sidebar menu */ + +.sidebar { + /*! padding-bottom: 10px; */ + width: 100%; +} + +.sidebar > div { + width: 100%; + padding-top: 7px; +} + +.sidebar > div:first-child { + padding-top: 0; + margin-top: -4px; +} + +.sidebar > div:last-child { + padding-bottom: 15px; +} + +.sidebar > div:nth-child(2) { + background-color: RGBA(0,10,10, 0.03); + box-shadow: -5px 5px 0px 10px RGBA(0,10,10, 0.03); + margin-top: 20px; +} + +.sidebar ul { + display: block; + margin: 0 0 5px 0; + padding: 0 0 0 10px; + width: 100%; +} + +.sidebar li { + width: 100%; + padding: 0; + display: flex; + overflow: hidden; + flex-wrap: wrap; + word-break: break-word; +} + +.sidebar li p { + margin: 0; + width: 100%; +} + +.sidebar li ul { + margin: 0 0 2px 0; + padding: 0 0 0 7px; + border: 0; +} + +/* Generated TOC */ +.sidebar ul.rst-simple, .sidebar ul.rst-simple ul { + margin: 0 0 5px 0; + padding: 0 0 0 15px; + margin: 0; + border-left: 1px solid #e7e7e7; +} + +.sidebar li a { + display: inline-block; + width: 100%; + padding-top: 3px; + padding-bottom: 3px; + color: #414141; +} + +.sidebar li a:hover { + color: #C7354E; +} + +.sidebar > div ul > li > .itemName > code, .sidebar > div ul > li > .itemName > code > a { + background-color: transparent; +} + +.sidebar ul > li > .itemName { + width: 100%; +} + +.sidebar > div ul > li > .itemName > code { + padding: 0; + width: 100%; +} + +.sidebar .thingTitle { + margin-bottom: 7px; + margin-top: 7px; + overflow: hidden; + color: #555; + font-size: 18px; + display: flex; + flex-wrap: wrap; + align-items: baseline; + word-break: break-word; + padding: 0 15px 3px 1px; + box-shadow: -10px 12px 0px -11px #888; +} + +.sidebar .thingTitle > span { + margin-right: 7px; +} + +.sidebar .thingTitle > code { + font-size: 16px; + color: #555; + background-color: transparent; + padding-left: 0; + padding-right: 0; + display: flex; +} + +.sidebar .thingTitle > code a { + background-color: transparent; +} + +.sidebar .childrenKindTitle { + color: #414141; + margin-left: 4px; + margin-bottom: 3px; + font-size: 15px; + /*! border-bottom: solid 1px #9d9d9d; */ + box-shadow: -11px 11px 0px -10px #aeaeaec4; + font-style: italic; +} + + +/* Style page content */ +#main { + + /* Same as the width of the sidebar + 20px*/ + display: flex; + flex-direction: column; +} + +/* Special case for the --nosidebar option */ +.nosidebar { + margin-left: 10px!important; +} + +/* For bigger displays, i.e. full screen */ +@media only screen and (min-width: 1330px) { + .sidebarcontainer { + width: 317px; /* Set the width of the sidebar: 310px + 2px for the border + 5px for the scrollbar */ + } +} + +/* For smaller displays, i.e. half screen */ +@media only screen and (max-width: 1100px) { + .sidebarcontainer { + width: 257px; /* Set the width of the sidebar: 250px + 2px for the border + 5px for the scrollbar */ + } +} + +/* For smaller displays mobile phone */ +@media only screen and (max-width: 900px) { + .sidebarcontainer { + width: 207px; /* Set the width of the sidebar: 200px + 2px for the border + 5px for the scrollbar */ + } +} + + +nav.foot { + margin-top: 20px; + background-color: #fff; + text-align: center; + border-width: 1px 0 0 0; + border-radius: 0; +} + +nav.foot address { + padding-top: 15px; + text-align: center; +} + +#collapseSideBar { + border-radius: 4px; + color: rgb(68, 68, 68); + font-size: 1.2em; + display: block; + float: left; + width: 0; + padding: 0; + margin: 0; + position: sticky; + top: 0; + right: 0; +} + +#collapseSideBar > a:hover{ + background-color: #e1e1e1; + text-decoration: none; +} + +#collapseSideBar > a { + height: 42px; + width: 15px; + font-size: 1.2em; + color: #333; + padding: 1px; + background-color: #e7e7e7; + border-radius: 0 4px 0 4px; + margin: -11px 0 0 -15px; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + border: solid 1px #e7e7e7; +} + +/* collapsed */ + +body.sidebar-collapsed .sidebar { + display: none; +} + +body.sidebar-collapsed .sidebarcontainer { + border: none; + padding: 0; + width: 5px; + overflow: visible; + background-color: transparent; +} + +body.sidebar-collapsed #main { + margin: 0 0 0 25px!important; +} + +body.sidebar-collapsed #collapseSideBar { + left: 1px; +} + +body.sidebar-collapsed #collapseSideBar > a { + margin-top: -1px; + margin-left: 0; + border-radius: 4px; + background-color: #f8f8f8; +} + +body.sidebar-collapsed #collapseSideBar > a:hover { + background-color: #e7e7e7; +} + +/* On smaller screens, where width is less than 650px, simply hide sidebar */ +@media screen and (max-width: 650px) { + .sidebar { + display: none; + } + #main { + margin: 0; + } + .sidebarcontainer { + display: none!important; + } + #collapseSideBar { + display: none; + } +} + +/* Style for expandable content */ + +input.tocChildrenToggle { + display: none; + } + +.lbl-toggle { + display: block; + width: 18px; + font-weight: bold; + font-family: monospace; + font-size: 12px; + text-transform: uppercase; + text-align: center; + color: #333; + /* background: #0069ff; */ + cursor: pointer; + border-radius: 7px; + transition: all 0.1s ease-out; + margin: 0 0 0 0; + padding: 5px 2px 0 2px; + color: rgb(163, 163, 163); + position: absolute; +} + +.lbl-toggle::before { + content: " "; + display: inline-block; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid currentColor; + vertical-align: middle; + margin-right: 0.7rem; + transform: translateY(-2px); + } + +.lbl-toggle:hover { + color: #333; + } + +.tocChildrenToggle:checked + .lbl-toggle::before { + transform: rotate(90deg) translateX(-3px); + } + +.expandableContent { + height: 0px; + overflow: hidden; + flex-basis: 100%; + padding: 0 0 0 8px; + margin-left: 5px; + border-left: 1px solid #e7e7e7; +} + +.expandableContent > div { + margin-top: 5px; +} + +.tocChildrenToggle:checked ~ .expandableContent { + height: auto; +} + +.tocChildrenToggle:not(:checked) ~ .expandableContent .lbl-toggle { + position: relative; +} + +.tocChildrenToggle:checked + .lbl-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + color: #333; + } + +.expandableContent .childrenKindTitle { + font-size: 14px; + /* margin-left: 5px; */ +} + +.expandableItem { + display: flex; + flex-wrap: wrap; +} + +.expandableItem > code { + width: calc(100% - 20px)!important; + margin-left: 18px; +} + +/* Special cases to display the current object name in the sidebar */ +.thisobject a { + font-weight: bold; +} +.expandableItem label.notExpandable { + cursor: not-allowed; +} +/* Version modified style */ +.rst-versionmodified { + display: block; + font-weight: bold; +} + +/* Search */ + +/* clears the ‘X’ from search input for Chrome */ +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { display: none; } + +.navlinks > #search-box-container { + padding: 0 0 8px 15px; + align-self: flex-end; + margin-left: auto; + display: none; +} + +#search-results { + margin-top: 5px; +} + +#search-results tr{ + display:block; + border-bottom: 0.5px solid #CCC; +} + +#search-results tr { + border-bottom: 1px #ddd solid; + padding-bottom: 1px; +} + +#search-results tr td { + border-left: 1px #ddd solid; + padding: 2px; +} + +#search-results tr td:first-child { + width: 120px; +} + +#search-results tr:last-child{ + border-bottom: none; +} + +#search-results tr article, #search-results tr article *{ + display:inline; +} + +#search-results section { + padding: 5px 0 0 8px; +} + +.search-help-hidden #search-help-box{ + display: none!important; +} + +#search-help-button{ + background-color: #e6e6e6; +} + +.search-help-hidden #search-help-button{ + background-color: rgb(255, 255, 255); +} + +.search-help-hidden #search-help-button:hover { + background-color: #e6e6e6; +} + +#search-results-container { + padding: 10px; + width: 100%; + max-width: 850px; + max-height: calc(100vh - 70px); + right: 0; + position: absolute; + overflow-x: hidden; + overflow-y: scroll; + background-color: #fbfbfb; + border: 1px solid #CCC; + border-radius: 4px; + z-index: 500; + margin-top: -9px; + word-break: break-word; +} + +#search-status{ + padding-bottom:2px; +} + +#search-buttons{ + float: right; +} + +#search-buttons > span { + padding: 0.3em 0.4em 0.4em; +} + +#toggle-search-in-docstrings-checkbox{ + margin-top: -2.5px; + cursor: pointer; +} + +/* Constant values repr */ +pre.constant-value { padding: .5em; } +.rst-variable-linewrap { color: #604000; font-weight: bold; } +.rst-variable-ellipsis { color: #604000; font-weight: bold; } +.rst-variable-quote { color: #604000; font-weight: bold; } + +/* Those two are currently not used */ +.rst-variable-group { color: #000000; } +.rst-variable-op { color: #000000; } + +.rst-variable-string { color: #337ab7; } +.rst-variable-unknown { color: #a00000; font-weight: bold; } +.rst-re { color: #000000; } +.rst-re-char { color: #337ab7; } +.rst-re-op { color: #fc7844; } +.rst-re-group { color: #309078; } +.rst-re-ref { color: #890000; } + +/* highlight the targeted item with "#" */ +#childList a:target ~ .functionHeader, #childList a:target ~ .functionBody{ + background-color: rgb(253, 255, 223); +} +#childList a:target ~ .functionHeader{ + box-shadow: 0px 0px 0px 10px rgb(253, 255, 223); +} +#childList a:target ~ .functionBody{ + box-shadow: -2px -8px 0px 13px rgb(253 255 223); +} + +/* deprecations uses a orange text */ +.rst-deprecated > .rst-versionmodified{ + color:#aa6708; +} + +/* CSS for anchor links */ +.headerLink{ + display:none; + color:black; + float:right; + margin-left:5px; + padding-left:5px; + padding-right:5px; +} +@media (hover) { + /* See https://css-tricks.com/annoying-mobile-double-tap-link-issue/ */ + .headerLink:hover{ + text-decoration:none; + background-color: #ccc; + } + #childList > div:hover .headerLink{ + display:inline-block; + } +} +#childList a:target ~ .functionHeader .headerLink{ + display: inline-block +} From 845aa4df2d997a1a8ecf7f51633e6f20ab2a42e8 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:06:36 -0500 Subject: [PATCH 04/29] css --- docs/bootstrap.min.css | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/bootstrap.min.css diff --git a/docs/bootstrap.min.css b/docs/bootstrap.min.css new file mode 100644 index 0000000..cd1c616 --- /dev/null +++ b/docs/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px)and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px)and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px)and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file From 22d337fcabe09af88fae99f73f018459bb9764b8 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:06:59 -0500 Subject: [PATCH 05/29] class index doc --- docs/classIndex.html | 167 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 docs/classIndex.html diff --git a/docs/classIndex.html b/docs/classIndex.html new file mode 100644 index 0000000..1542720 --- /dev/null +++ b/docs/classIndex.html @@ -0,0 +1,167 @@ + + + + + + + + Class Hierarchy + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + \ No newline at end of file From f3c35b92b253e8cd12a92134a739645f87751e02 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:07:19 -0500 Subject: [PATCH 06/29] css --- docs/extra.css | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/extra.css diff --git a/docs/extra.css b/docs/extra.css new file mode 100644 index 0000000..e69de29 From 3920a46da91e4d0439e3966e4772e8e5a650e92d Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:07:49 -0500 Subject: [PATCH 07/29] fonts --- docs/fonts/info.svg | 4 ++++ docs/fonts/x-circle.svg | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 docs/fonts/info.svg create mode 100644 docs/fonts/x-circle.svg diff --git a/docs/fonts/info.svg b/docs/fonts/info.svg new file mode 100644 index 0000000..8f48f86 --- /dev/null +++ b/docs/fonts/info.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/fonts/x-circle.svg b/docs/fonts/x-circle.svg new file mode 100644 index 0000000..ce37cdc --- /dev/null +++ b/docs/fonts/x-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 2d4ab782682e3ce83620bbf9ca0e00df87f3722e Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:08:11 -0500 Subject: [PATCH 08/29] search index json doc --- docs/fullsearchindex.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/fullsearchindex.json diff --git a/docs/fullsearchindex.json b/docs/fullsearchindex.json new file mode 100644 index 0000000..2099a36 --- /dev/null +++ b/docs/fullsearchindex.json @@ -0,0 +1 @@ +{"version": "2.3.9", "fields": ["name", "names", "qname", "docstring", "kind"], "fieldVectors": [["name/src", [0, 17.187]], ["names/src", [0, 9.763]], ["qname/src", [0, 4.297]], ["docstring/src", []], ["kind/src", [1, -4.97]], ["name/src.app", [2, 13.572]], ["names/src.app", [2, 7.709]], ["qname/src.app", [3, 5.991]], ["docstring/src.app", [2, 2.53, 4, 2.69, 5, 2.69, 6, 0.342, 7, 2.69, 8, 2.69, 9, 2.231]], ["kind/src.app", [10, -4.297]], ["name/src.User", [11, 12.235]], ["names/src.User", [11, 6.95]], ["qname/src.User", [12, 5.991]], ["docstring/src.User", []], ["kind/src.User", [1, -4.97]], ["name/src.User.models", [13, 23.966]], ["names/src.User.models", [14, 13.613]], ["qname/src.User.models", [15, 5.991]], ["docstring/src.User.models", []], ["kind/src.User.models", [10, -4.297]], ["name/src.User.routes", [16, 23.966]], ["names/src.User.routes", [17, 7.709]], ["qname/src.User.routes", [18, 5.991]], ["docstring/src.User.routes", []], ["kind/src.User.routes", [10, -4.297]], ["name/src.app.app", [2, 6.786]], ["names/src.app.app", [2, 3.854]], ["qname/src.app.app", [19, 2.996]], ["docstring/src.app.app", []], ["kind/src.app.app", [20, -1.897]], ["name/src.app.mongo_conn", [21, 11.983]], ["names/src.app.mongo_conn", [22, 4.249, 23, 5.123]], ["qname/src.app.mongo_conn", [24, 2.996]], ["docstring/src.app.mongo_conn", []], ["kind/src.app.mongo_conn", [20, -1.897]], ["name/src.app.mongo_params", [25, 11.983]], ["names/src.app.mongo_params", [22, 4.249, 26, 5.123]], ["qname/src.app.mongo_params", [27, 2.996]], ["docstring/src.app.mongo_params", []], ["kind/src.app.mongo_params", [20, -1.897]], ["name/src.app.mongodb_client", [28, 11.983]], ["names/src.app.mongodb_client", [29, 5.123, 30, 5.123]], ["qname/src.app.mongodb_client", [31, 2.996]], ["docstring/src.app.mongodb_client", []], ["kind/src.app.mongodb_client", [20, -1.897]], ["name/src.app.login_required", [32, 11.983]], ["names/src.app.login_required", [33, 2.156, 34, 5.123]], ["qname/src.app.login_required", [35, 2.996]], ["docstring/src.app.login_required", []], ["kind/src.app.login_required", [6, -0.381]], ["name/src.app.sgup", [36, 9.94]], ["names/src.app.sgup", [36, 5.646]], ["qname/src.app.sgup", [37, 2.996]], ["docstring/src.app.sgup", [6, 0.188, 17, 0.839, 38, 1.062, 39, 0.839, 40, 0.938, 41, 1.228, 42, 0.938]], ["kind/src.app.sgup", [6, -0.381]], ["name/src.app.lgin", [43, 9.94]], ["names/src.app.lgin", [43, 5.646]], ["qname/src.app.lgin", [44, 2.996]], ["docstring/src.app.lgin", [6, 0.188, 17, 0.839, 33, 0.623, 38, 1.062, 40, 0.938, 42, 0.938, 45, 1.228]], ["kind/src.app.lgin", [6, -0.381]], ["name/src.app.index", [39, 6.786]], ["names/src.app.index", [39, 3.854]], ["qname/src.app.index", [46, 2.996]], ["docstring/src.app.index", [6, 0.188, 17, 0.839, 38, 1.062, 39, 0.839, 40, 0.938, 41, 1.228, 42, 0.938]], ["kind/src.app.index", [6, -0.381]], ["name/src.app.login", [33, 5.045]], ["names/src.app.login", [33, 2.865]], ["qname/src.app.login", [47, 2.996]], ["docstring/src.app.login", [6, 0.188, 17, 0.839, 33, 0.623, 39, 0.839, 40, 0.938, 42, 0.938, 45, 1.228]], ["kind/src.app.login", [6, -0.381]], ["name/src.app.search", [48, 9.94]], ["names/src.app.search", [48, 5.646]], ["qname/src.app.search", [49, 2.996]], ["docstring/src.app.search", []], ["kind/src.app.search", [6, -0.381]], ["name/src.app.add", [50, 8.594]], ["names/src.app.add", [50, 4.881]], ["qname/src.app.add", [51, 2.996]], ["docstring/src.app.add", [6, 0.157, 9, 1.022, 50, 1.929, 52, 1.232, 53, 1.232, 54, 1.022, 55, 1.232]], ["kind/src.app.add", [6, -0.381]], ["name/src.app.read_from_db", [56, 9.94]], ["names/src.app.read_from_db", [57, 4.249, 58, 5.123]], ["qname/src.app.read_from_db", [59, 2.996]], ["docstring/src.app.read_from_db", [6, 0.117, 54, 0.765, 56, 0.765, 57, 0.765, 60, 1.617, 61, 0.922, 62, 0.922, 63, 0.922, 64, 0.922, 65, 0.922, 66, 0.922, 67, 0.922]], ["kind/src.app.read_from_db", [6, -0.381]], ["name/src.User.models.User", [11, 12.235]], ["names/src.User.models.User", [11, 6.95]], ["qname/src.User.models.User", [68, 5.991]], ["docstring/src.User.models.User", []], ["kind/src.User.models.User", [69, -5.991]], ["name/src.User.models.User.startSession", [70, 11.983]], ["names/src.User.models.User.startSession", [71, 5.123, 72, 5.123]], ["qname/src.User.models.User.startSession", [73, 2.996]], ["docstring/src.User.models.User.startSession", []], ["kind/src.User.models.User.startSession", [74, -1.529]], ["name/src.User.models.User.signup", [75, 7.588]], ["names/src.User.models.User.signup", [75, 4.31]], ["qname/src.User.models.User.signup", [76, 2.996]], ["docstring/src.User.models.User.signup", []], ["kind/src.User.models.User.signup", [74, -1.529]], ["name/src.User.models.User.logout", [77, 9.94]], ["names/src.User.models.User.logout", [77, 5.646]], ["qname/src.User.models.User.logout", [78, 2.996]], ["docstring/src.User.models.User.logout", []], ["kind/src.User.models.User.logout", [74, -1.529]], ["name/src.User.models.User.login", [33, 5.045]], ["names/src.User.models.User.login", [33, 2.865]], ["qname/src.User.models.User.login", [79, 2.996]], ["docstring/src.User.models.User.login", []], ["kind/src.User.models.User.login", [74, -1.529]], ["name/src.User.models.User.showProfile", [80, 11.983]], ["names/src.User.models.User.showProfile", [81, 4.249, 82, 4.249]], ["qname/src.User.models.User.showProfile", [83, 2.996]], ["docstring/src.User.models.User.showProfile", []], ["kind/src.User.models.User.showProfile", [74, -1.529]], ["name/src.User.models.User.saveResume", [84, 9.94]], ["names/src.User.models.User.saveResume", [85, 4.249, 86, 4.249]], ["qname/src.User.models.User.saveResume", [87, 2.996]], ["docstring/src.User.models.User.saveResume", []], ["kind/src.User.models.User.saveResume", [74, -1.529]], ["name/src.User.routes.signup", [75, 7.588]], ["names/src.User.routes.signup", [75, 4.31]], ["qname/src.User.routes.signup", [88, 2.996]], ["docstring/src.User.routes.signup", []], ["kind/src.User.routes.signup", [6, -0.381]], ["name/src.User.routes.signout", [89, 9.94]], ["names/src.User.routes.signout", [89, 5.646]], ["qname/src.User.routes.signout", [90, 2.996]], ["docstring/src.User.routes.signout", []], ["kind/src.User.routes.signout", [6, -0.381]], ["name/src.User.routes.loginUser", [91, 11.983]], ["names/src.User.routes.loginUser", [11, 2.615, 33, 2.156]], ["qname/src.User.routes.loginUser", [92, 2.996]], ["docstring/src.User.routes.loginUser", []], ["kind/src.User.routes.loginUser", [6, -0.381]], ["name/src.User.routes.showUserProfile", [93, 11.983]], ["names/src.User.routes.showUserProfile", [11, 2.097, 81, 3.406, 82, 3.406]], ["qname/src.User.routes.showUserProfile", [94, 2.996]], ["docstring/src.User.routes.showUserProfile", []], ["kind/src.User.routes.showUserProfile", [6, -0.381]], ["name/src.User.routes.saveResume", [84, 9.94]], ["names/src.User.routes.saveResume", [85, 4.249, 86, 4.249]], ["qname/src.User.routes.saveResume", [95, 2.996]], ["docstring/src.User.routes.saveResume", []], ["kind/src.User.routes.saveResume", [6, -0.381]]], "invertedIndex": [["'/'", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.sgup": {}, "src.app.lgin": {}, "src.app.index": {}}, "kind": {}, "_index": 38}], ["add", {"name": {"src.app.add": {}}, "names": {"src.app.add": {}}, "qname": {}, "docstring": {"src.app.add": {}}, "kind": {}, "_index": 50}], ["app", {"name": {"src.app": {}, "src.app.app": {}}, "names": {"src.app": {}, "src.app.app": {}}, "qname": {}, "docstring": {"src.app": {}}, "kind": {}, "_index": 2}], ["base", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 61}], ["class", {"name": {}, "names": {}, "qname": {}, "docstring": {}, "kind": {"src.User.models.User": {}}, "_index": 69}], ["client", {"name": {}, "names": {"src.app.mongodb_client": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 30}], ["column", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.add": {}}, "kind": {}, "_index": 53}], ["conn", {"name": {}, "names": {"src.app.mongo_conn": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 23}], ["data", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.add": {}}, "kind": {}, "_index": 55}], ["databas", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app": {}, "src.app.add": {}}, "kind": {}, "_index": 9}], ["datafram", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 67}], ["db", {"name": {}, "names": {"src.app.read_from_db": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 58}], ["detail", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 60}], ["flask", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app": {}}, "kind": {}, "_index": 8}], ["function", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app": {}, "src.app.sgup": {}, "src.app.lgin": {}, "src.app.index": {}, "src.app.login": {}, "src.app.add": {}, "src.app.read_from_db": {}}, "kind": {"src.app.login_required": {}, "src.app.sgup": {}, "src.app.lgin": {}, "src.app.index": {}, "src.app.login": {}, "src.app.search": {}, "src.app.add": {}, "src.app.read_from_db": {}, "src.User.routes.signup": {}, "src.User.routes.signout": {}, "src.User.routes.loginUser": {}, "src.User.routes.showUserProfile": {}, "src.User.routes.saveResume": {}}, "_index": 6}], ["hold", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app": {}}, "kind": {}, "_index": 5}], ["index", {"name": {"src.app.index": {}}, "names": {"src.app.index": {}}, "qname": {}, "docstring": {"src.app.sgup": {}, "src.app.index": {}, "src.app.login": {}}, "kind": {}, "_index": 39}], ["index.html", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.sgup": {}, "src.app.index": {}}, "kind": {}, "_index": 41}], ["input", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 62}], ["job", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.add": {}, "src.app.read_from_db": {}}, "kind": {}, "_index": 54}], ["lgin", {"name": {"src.app.lgin": {}}, "names": {"src.app.lgin": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 43}], ["login", {"name": {"src.app.login": {}, "src.User.models.User.login": {}}, "names": {"src.app.login_required": {}, "src.app.login": {}, "src.User.models.User.login": {}, "src.User.routes.loginUser": {}}, "qname": {}, "docstring": {"src.app.lgin": {}, "src.app.login": {}}, "kind": {}, "_index": 33}], ["login.html", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.lgin": {}, "src.app.login": {}}, "kind": {}, "_index": 45}], ["login_required", {"name": {"src.app.login_required": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 32}], ["loginuser", {"name": {"src.User.routes.loginUser": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 91}], ["logout", {"name": {"src.User.models.User.logout": {}}, "names": {"src.User.models.User.logout": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 77}], ["method", {"name": {}, "names": {}, "qname": {}, "docstring": {}, "kind": {"src.User.models.User.startSession": {}, "src.User.models.User.signup": {}, "src.User.models.User.logout": {}, "src.User.models.User.login": {}, "src.User.models.User.showProfile": {}, "src.User.models.User.saveResume": {}}, "_index": 74}], ["model", {"name": {}, "names": {"src.User.models": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 14}], ["models", {"name": {"src.User.models": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 13}], ["modul", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app": {}}, "kind": {}, "_index": 4}], ["module", {"name": {}, "names": {}, "qname": {}, "docstring": {}, "kind": {"src.app": {}, "src.User.models": {}, "src.User.routes": {}}, "_index": 10}], ["mongo", {"name": {}, "names": {"src.app.mongo_conn": {}, "src.app.mongo_params": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 22}], ["mongo_conn", {"name": {"src.app.mongo_conn": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 21}], ["mongo_params", {"name": {"src.app.mongo_params": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 25}], ["mongodb", {"name": {}, "names": {"src.app.mongodb_client": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 29}], ["mongodb_client", {"name": {"src.app.mongodb_client": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 28}], ["package", {"name": {}, "names": {}, "qname": {}, "docstring": {}, "kind": {"src": {}, "src.User": {}}, "_index": 1}], ["page", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.sgup": {}, "src.app.lgin": {}, "src.app.index": {}, "src.app.login": {}}, "kind": {}, "_index": 42}], ["param", {"name": {}, "names": {"src.app.mongo_params": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 26}], ["profil", {"name": {}, "names": {"src.User.models.User.showProfile": {}, "src.User.routes.showUserProfile": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 82}], ["provid", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 63}], ["read", {"name": {}, "names": {"src.app.read_from_db": {}}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 57}], ["read_from_db", {"name": {"src.app.read_from_db": {}}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 56}], ["regex", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 65}], ["relat", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app": {}}, "kind": {}, "_index": 7}], ["render", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.sgup": {}, "src.app.lgin": {}, "src.app.index": {}, "src.app.login": {}}, "kind": {}, "_index": 40}], ["requir", {"name": {}, "names": {"src.app.login_required": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 34}], ["resum", {"name": {}, "names": {"src.User.models.User.saveResume": {}, "src.User.routes.saveResume": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 86}], ["return", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 66}], ["rout", {"name": {}, "names": {"src.User.routes": {}}, "qname": {}, "docstring": {"src.app.sgup": {}, "src.app.lgin": {}, "src.app.index": {}, "src.app.login": {}}, "kind": {}, "_index": 17}], ["routes", {"name": {"src.User.routes": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 16}], ["save", {"name": {}, "names": {"src.User.models.User.saveResume": {}, "src.User.routes.saveResume": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 85}], ["saveresume", {"name": {"src.User.models.User.saveResume": {}, "src.User.routes.saveResume": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 84}], ["search", {"name": {"src.app.search": {}}, "names": {"src.app.search": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 48}], ["session", {"name": {}, "names": {"src.User.models.User.startSession": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 72}], ["sgup", {"name": {"src.app.sgup": {}}, "names": {"src.app.sgup": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 36}], ["show", {"name": {}, "names": {"src.User.models.User.showProfile": {}, "src.User.routes.showUserProfile": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 81}], ["showprofile", {"name": {"src.User.models.User.showProfile": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 80}], ["showuserprofile", {"name": {"src.User.routes.showUserProfile": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 93}], ["signout", {"name": {"src.User.routes.signout": {}}, "names": {"src.User.routes.signout": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 89}], ["signup", {"name": {"src.User.models.User.signup": {}, "src.User.routes.signup": {}}, "names": {"src.User.models.User.signup": {}, "src.User.routes.signup": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 75}], ["skill", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.add": {}}, "kind": {}, "_index": 52}], ["src", {"name": {"src": {}}, "names": {"src": {}}, "qname": {"src": {}}, "docstring": {}, "kind": {}, "_index": 0}], ["src.app", {"name": {}, "names": {}, "qname": {"src.app": {}}, "docstring": {}, "kind": {}, "_index": 3}], ["src.app.add", {"name": {}, "names": {}, "qname": {"src.app.add": {}}, "docstring": {}, "kind": {}, "_index": 51}], ["src.app.app", {"name": {}, "names": {}, "qname": {"src.app.app": {}}, "docstring": {}, "kind": {}, "_index": 19}], ["src.app.index", {"name": {}, "names": {}, "qname": {"src.app.index": {}}, "docstring": {}, "kind": {}, "_index": 46}], ["src.app.lgin", {"name": {}, "names": {}, "qname": {"src.app.lgin": {}}, "docstring": {}, "kind": {}, "_index": 44}], ["src.app.login", {"name": {}, "names": {}, "qname": {"src.app.login": {}}, "docstring": {}, "kind": {}, "_index": 47}], ["src.app.login_required", {"name": {}, "names": {}, "qname": {"src.app.login_required": {}}, "docstring": {}, "kind": {}, "_index": 35}], ["src.app.mongo_conn", {"name": {}, "names": {}, "qname": {"src.app.mongo_conn": {}}, "docstring": {}, "kind": {}, "_index": 24}], ["src.app.mongo_params", {"name": {}, "names": {}, "qname": {"src.app.mongo_params": {}}, "docstring": {}, "kind": {}, "_index": 27}], ["src.app.mongodb_client", {"name": {}, "names": {}, "qname": {"src.app.mongodb_client": {}}, "docstring": {}, "kind": {}, "_index": 31}], ["src.app.read_from_db", {"name": {}, "names": {}, "qname": {"src.app.read_from_db": {}}, "docstring": {}, "kind": {}, "_index": 59}], ["src.app.search", {"name": {}, "names": {}, "qname": {"src.app.search": {}}, "docstring": {}, "kind": {}, "_index": 49}], ["src.app.sgup", {"name": {}, "names": {}, "qname": {"src.app.sgup": {}}, "docstring": {}, "kind": {}, "_index": 37}], ["src.user", {"name": {}, "names": {}, "qname": {"src.User": {}}, "docstring": {}, "kind": {}, "_index": 12}], ["src.user.models", {"name": {}, "names": {}, "qname": {"src.User.models": {}}, "docstring": {}, "kind": {}, "_index": 15}], ["src.user.models.user", {"name": {}, "names": {}, "qname": {"src.User.models.User": {}}, "docstring": {}, "kind": {}, "_index": 68}], ["src.user.models.user.login", {"name": {}, "names": {}, "qname": {"src.User.models.User.login": {}}, "docstring": {}, "kind": {}, "_index": 79}], ["src.user.models.user.logout", {"name": {}, "names": {}, "qname": {"src.User.models.User.logout": {}}, "docstring": {}, "kind": {}, "_index": 78}], ["src.user.models.user.saveresume", {"name": {}, "names": {}, "qname": {"src.User.models.User.saveResume": {}}, "docstring": {}, "kind": {}, "_index": 87}], ["src.user.models.user.showprofile", {"name": {}, "names": {}, "qname": {"src.User.models.User.showProfile": {}}, "docstring": {}, "kind": {}, "_index": 83}], ["src.user.models.user.signup", {"name": {}, "names": {}, "qname": {"src.User.models.User.signup": {}}, "docstring": {}, "kind": {}, "_index": 76}], ["src.user.models.user.startsession", {"name": {}, "names": {}, "qname": {"src.User.models.User.startSession": {}}, "docstring": {}, "kind": {}, "_index": 73}], ["src.user.routes", {"name": {}, "names": {}, "qname": {"src.User.routes": {}}, "docstring": {}, "kind": {}, "_index": 18}], ["src.user.routes.loginuser", {"name": {}, "names": {}, "qname": {"src.User.routes.loginUser": {}}, "docstring": {}, "kind": {}, "_index": 92}], ["src.user.routes.saveresume", {"name": {}, "names": {}, "qname": {"src.User.routes.saveResume": {}}, "docstring": {}, "kind": {}, "_index": 95}], ["src.user.routes.showuserprofile", {"name": {}, "names": {}, "qname": {"src.User.routes.showUserProfile": {}}, "docstring": {}, "kind": {}, "_index": 94}], ["src.user.routes.signout", {"name": {}, "names": {}, "qname": {"src.User.routes.signout": {}}, "docstring": {}, "kind": {}, "_index": 90}], ["src.user.routes.signup", {"name": {}, "names": {}, "qname": {"src.User.routes.signup": {}}, "docstring": {}, "kind": {}, "_index": 88}], ["start", {"name": {}, "names": {"src.User.models.User.startSession": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 71}], ["startsession", {"name": {"src.User.models.User.startSession": {}}, "names": {}, "qname": {}, "docstring": {}, "kind": {}, "_index": 70}], ["us", {"name": {}, "names": {}, "qname": {}, "docstring": {"src.app.read_from_db": {}}, "kind": {}, "_index": 64}], ["user", {"name": {"src.User": {}, "src.User.models.User": {}}, "names": {"src.User": {}, "src.User.models.User": {}, "src.User.routes.loginUser": {}, "src.User.routes.showUserProfile": {}}, "qname": {}, "docstring": {}, "kind": {}, "_index": 11}], ["variable", {"name": {}, "names": {}, "qname": {}, "docstring": {}, "kind": {"src.app.app": {}, "src.app.mongo_conn": {}, "src.app.mongo_params": {}, "src.app.mongodb_client": {}}, "_index": 20}]], "pipeline": []} \ No newline at end of file From 0742d812bb85d1db46d415901b9a41d77449950d Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:08:47 -0500 Subject: [PATCH 09/29] index --- docs/index.html | 278 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 docs/index.html diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..49f474b --- /dev/null +++ b/docs/index.html @@ -0,0 +1,278 @@ + + + + + + + + src + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ package documentation +
+ +
+ +

+
+ +
+

Undocumented

+
+ +
+ + + + + + + + + + + + + + +
ModuleappThe module app holds the function related to flask app and database.
PackageUserUndocumented
+ + + +
+ +
+ +
+ +
+
+ + + + + + + \ No newline at end of file From 3d56f1f9c76c46aed97b1ba29f54fdaf5d75ce7b Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:09:21 -0500 Subject: [PATCH 10/29] docs --- docs/lunr.js | 3475 +++++++++++++++++++++++++++++++++++++++++ docs/moduleIndex.html | 166 ++ 2 files changed, 3641 insertions(+) create mode 100644 docs/lunr.js create mode 100644 docs/moduleIndex.html diff --git a/docs/lunr.js b/docs/lunr.js new file mode 100644 index 0000000..6768f2a --- /dev/null +++ b/docs/lunr.js @@ -0,0 +1,3475 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ + + ;(function(){ + + /** + * A convenience function for configuring and constructing + * a new lunr Index. + * + * A lunr.Builder instance is created and the pipeline setup + * with a trimmer, stop word filter and stemmer. + * + * This builder object is yielded to the configuration function + * that is passed as a parameter, allowing the list of fields + * and other builder parameters to be customised. + * + * All documents _must_ be added within the passed config function. + * + * @example + * var idx = lunr(function () { + * this.field('title') + * this.field('body') + * this.ref('id') + * + * documents.forEach(function (doc) { + * this.add(doc) + * }, this) + * }) + * + * @see {@link lunr.Builder} + * @see {@link lunr.Pipeline} + * @see {@link lunr.trimmer} + * @see {@link lunr.stopWordFilter} + * @see {@link lunr.stemmer} + * @namespace {function} lunr + */ + var lunr = function (config) { + var builder = new lunr.Builder + + builder.pipeline.add( + lunr.trimmer, + lunr.stopWordFilter, + lunr.stemmer + ) + + builder.searchPipeline.add( + lunr.stemmer + ) + + config.call(builder, builder) + return builder.build() + } + + lunr.version = "2.3.9" + /*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * A namespace containing utils for the rest of the lunr library + * @namespace lunr.utils + */ + lunr.utils = {} + + /** + * Print a warning message to the console. + * + * @param {String} message The message to be printed. + * @memberOf lunr.utils + * @function + */ + lunr.utils.warn = (function (global) { + /* eslint-disable no-console */ + return function (message) { + if (global.console && console.warn) { + console.warn(message) + } + } + /* eslint-enable no-console */ + })(this) + + /** + * Convert an object to a string. + * + * In the case of `null` and `undefined` the function returns + * the empty string, in all other cases the result of calling + * `toString` on the passed object is returned. + * + * @param {Any} obj The object to convert to a string. + * @return {String} string representation of the passed object. + * @memberOf lunr.utils + */ + lunr.utils.asString = function (obj) { + if (obj === void 0 || obj === null) { + return "" + } else { + return obj.toString() + } + } + + /** + * Clones an object. + * + * Will create a copy of an existing object such that any mutations + * on the copy cannot affect the original. + * + * Only shallow objects are supported, passing a nested object to this + * function will cause a TypeError. + * + * Objects with primitives, and arrays of primitives are supported. + * + * @param {Object} obj The object to clone. + * @return {Object} a clone of the passed object. + * @throws {TypeError} when a nested object is passed. + * @memberOf Utils + */ + lunr.utils.clone = function (obj) { + if (obj === null || obj === undefined) { + return obj + } + + var clone = Object.create(null), + keys = Object.keys(obj) + + for (var i = 0; i < keys.length; i++) { + var key = keys[i], + val = obj[key] + + if (Array.isArray(val)) { + clone[key] = val.slice() + continue + } + + if (typeof val === 'string' || + typeof val === 'number' || + typeof val === 'boolean') { + clone[key] = val + continue + } + + throw new TypeError("clone is not deep and does not support nested objects") + } + + return clone + } + lunr.FieldRef = function (docRef, fieldName, stringValue) { + this.docRef = docRef + this.fieldName = fieldName + this._stringValue = stringValue + } + + lunr.FieldRef.joiner = "/" + + lunr.FieldRef.fromString = function (s) { + var n = s.indexOf(lunr.FieldRef.joiner) + + if (n === -1) { + throw "malformed field ref string" + } + + var fieldRef = s.slice(0, n), + docRef = s.slice(n + 1) + + return new lunr.FieldRef (docRef, fieldRef, s) + } + + lunr.FieldRef.prototype.toString = function () { + if (this._stringValue == undefined) { + this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef + } + + return this._stringValue + } + /*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * A lunr set. + * + * @constructor + */ + lunr.Set = function (elements) { + this.elements = Object.create(null) + + if (elements) { + this.length = elements.length + + for (var i = 0; i < this.length; i++) { + this.elements[elements[i]] = true + } + } else { + this.length = 0 + } + } + + /** + * A complete set that contains all elements. + * + * @static + * @readonly + * @type {lunr.Set} + */ + lunr.Set.complete = { + intersect: function (other) { + return other + }, + + union: function () { + return this + }, + + contains: function () { + return true + } + } + + /** + * An empty set that contains no elements. + * + * @static + * @readonly + * @type {lunr.Set} + */ + lunr.Set.empty = { + intersect: function () { + return this + }, + + union: function (other) { + return other + }, + + contains: function () { + return false + } + } + + /** + * Returns true if this set contains the specified object. + * + * @param {object} object - Object whose presence in this set is to be tested. + * @returns {boolean} - True if this set contains the specified object. + */ + lunr.Set.prototype.contains = function (object) { + return !!this.elements[object] + } + + /** + * Returns a new set containing only the elements that are present in both + * this set and the specified set. + * + * @param {lunr.Set} other - set to intersect with this set. + * @returns {lunr.Set} a new set that is the intersection of this and the specified set. + */ + + lunr.Set.prototype.intersect = function (other) { + var a, b, elements, intersection = [] + + if (other === lunr.Set.complete) { + return this + } + + if (other === lunr.Set.empty) { + return other + } + + if (this.length < other.length) { + a = this + b = other + } else { + a = other + b = this + } + + elements = Object.keys(a.elements) + + for (var i = 0; i < elements.length; i++) { + var element = elements[i] + if (element in b.elements) { + intersection.push(element) + } + } + + return new lunr.Set (intersection) + } + + /** + * Returns a new set combining the elements of this and the specified set. + * + * @param {lunr.Set} other - set to union with this set. + * @return {lunr.Set} a new set that is the union of this and the specified set. + */ + + lunr.Set.prototype.union = function (other) { + if (other === lunr.Set.complete) { + return lunr.Set.complete + } + + if (other === lunr.Set.empty) { + return this + } + + return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements))) + } + /** + * A function to calculate the inverse document frequency for + * a posting. This is shared between the builder and the index + * + * @private + * @param {object} posting - The posting for a given term + * @param {number} documentCount - The total number of documents. + */ + lunr.idf = function (posting, documentCount) { + var documentsWithTerm = 0 + + for (var fieldName in posting) { + if (fieldName == '_index') continue // Ignore the term index, its not a field + documentsWithTerm += Object.keys(posting[fieldName]).length + } + + var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5) + + return Math.log(1 + Math.abs(x)) + } + + /** + * A token wraps a string representation of a token + * as it is passed through the text processing pipeline. + * + * @constructor + * @param {string} [str=''] - The string token being wrapped. + * @param {object} [metadata={}] - Metadata associated with this token. + */ + lunr.Token = function (str, metadata) { + this.str = str || "" + this.metadata = metadata || {} + } + + /** + * Returns the token string that is being wrapped by this object. + * + * @returns {string} + */ + lunr.Token.prototype.toString = function () { + return this.str + } + + /** + * A token update function is used when updating or optionally + * when cloning a token. + * + * @callback lunr.Token~updateFunction + * @param {string} str - The string representation of the token. + * @param {Object} metadata - All metadata associated with this token. + */ + + /** + * Applies the given function to the wrapped string token. + * + * @example + * token.update(function (str, metadata) { + * return str.toUpperCase() + * }) + * + * @param {lunr.Token~updateFunction} fn - A function to apply to the token string. + * @returns {lunr.Token} + */ + lunr.Token.prototype.update = function (fn) { + this.str = fn(this.str, this.metadata) + return this + } + + /** + * Creates a clone of this token. Optionally a function can be + * applied to the cloned token. + * + * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token. + * @returns {lunr.Token} + */ + lunr.Token.prototype.clone = function (fn) { + fn = fn || function (s) { return s } + return new lunr.Token (fn(this.str, this.metadata), this.metadata) + } + /*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * A function for splitting a string into tokens ready to be inserted into + * the search index. Uses `lunr.tokenizer.separator` to split strings, change + * the value of this property to change how strings are split into tokens. + * + * This tokenizer will convert its parameter to a string by calling `toString` and + * then will split this string on the character in `lunr.tokenizer.separator`. + * Arrays will have their elements converted to strings and wrapped in a lunr.Token. + * + * Optional metadata can be passed to the tokenizer, this metadata will be cloned and + * added as metadata to every token that is created from the object to be tokenized. + * + * @static + * @param {?(string|object|object[])} obj - The object to convert into tokens + * @param {?object} metadata - Optional metadata to associate with every token + * @returns {lunr.Token[]} + * @see {@link lunr.Pipeline} + */ + lunr.tokenizer = function (obj, metadata) { + if (obj == null || obj == undefined) { + return [] + } + + if (Array.isArray(obj)) { + return obj.map(function (t) { + return new lunr.Token( + lunr.utils.asString(t).toLowerCase(), + lunr.utils.clone(metadata) + ) + }) + } + + var str = obj.toString().toLowerCase(), + len = str.length, + tokens = [] + + for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) { + var char = str.charAt(sliceEnd), + sliceLength = sliceEnd - sliceStart + + if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) { + + if (sliceLength > 0) { + var tokenMetadata = lunr.utils.clone(metadata) || {} + tokenMetadata["position"] = [sliceStart, sliceLength] + tokenMetadata["index"] = tokens.length + + tokens.push( + new lunr.Token ( + str.slice(sliceStart, sliceEnd), + tokenMetadata + ) + ) + } + + sliceStart = sliceEnd + 1 + } + + } + + return tokens + } + + /** + * The separator used to split a string into tokens. Override this property to change the behaviour of + * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens. + * + * @static + * @see lunr.tokenizer + */ + lunr.tokenizer.separator = /[\s\-]+/ + /*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * lunr.Pipelines maintain an ordered list of functions to be applied to all + * tokens in documents entering the search index and queries being ran against + * the index. + * + * An instance of lunr.Index created with the lunr shortcut will contain a + * pipeline with a stop word filter and an English language stemmer. Extra + * functions can be added before or after either of these functions or these + * default functions can be removed. + * + * When run the pipeline will call each function in turn, passing a token, the + * index of that token in the original list of all tokens and finally a list of + * all the original tokens. + * + * The output of functions in the pipeline will be passed to the next function + * in the pipeline. To exclude a token from entering the index the function + * should return undefined, the rest of the pipeline will not be called with + * this token. + * + * For serialisation of pipelines to work, all functions used in an instance of + * a pipeline should be registered with lunr.Pipeline. Registered functions can + * then be loaded. If trying to load a serialised pipeline that uses functions + * that are not registered an error will be thrown. + * + * If not planning on serialising the pipeline then registering pipeline functions + * is not necessary. + * + * @constructor + */ + lunr.Pipeline = function () { + this._stack = [] + } + + lunr.Pipeline.registeredFunctions = Object.create(null) + + /** + * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token + * string as well as all known metadata. A pipeline function can mutate the token string + * or mutate (or add) metadata for a given token. + * + * A pipeline function can indicate that the passed token should be discarded by returning + * null, undefined or an empty string. This token will not be passed to any downstream pipeline + * functions and will not be added to the index. + * + * Multiple tokens can be returned by returning an array of tokens. Each token will be passed + * to any downstream pipeline functions and all will returned tokens will be added to the index. + * + * Any number of pipeline functions may be chained together using a lunr.Pipeline. + * + * @interface lunr.PipelineFunction + * @param {lunr.Token} token - A token from the document being processed. + * @param {number} i - The index of this token in the complete list of tokens for this document/field. + * @param {lunr.Token[]} tokens - All tokens for this document/field. + * @returns {(?lunr.Token|lunr.Token[])} + */ + + /** + * Register a function with the pipeline. + * + * Functions that are used in the pipeline should be registered if the pipeline + * needs to be serialised, or a serialised pipeline needs to be loaded. + * + * Registering a function does not add it to a pipeline, functions must still be + * added to instances of the pipeline for them to be used when running a pipeline. + * + * @param {lunr.PipelineFunction} fn - The function to check for. + * @param {String} label - The label to register this function with + */ + lunr.Pipeline.registerFunction = function (fn, label) { + if (label in this.registeredFunctions) { + lunr.utils.warn('Overwriting existing registered function: ' + label) + } + + fn.label = label + lunr.Pipeline.registeredFunctions[fn.label] = fn + } + + /** + * Warns if the function is not registered as a Pipeline function. + * + * @param {lunr.PipelineFunction} fn - The function to check for. + * @private + */ + lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { + var isRegistered = fn.label && (fn.label in this.registeredFunctions) + + if (!isRegistered) { + lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) + } + } + + /** + * Loads a previously serialised pipeline. + * + * All functions to be loaded must already be registered with lunr.Pipeline. + * If any function from the serialised data has not been registered then an + * error will be thrown. + * + * @param {Object} serialised - The serialised pipeline to load. + * @returns {lunr.Pipeline} + */ + lunr.Pipeline.load = function (serialised) { + var pipeline = new lunr.Pipeline + + serialised.forEach(function (fnName) { + var fn = lunr.Pipeline.registeredFunctions[fnName] + + if (fn) { + pipeline.add(fn) + } else { + throw new Error('Cannot load unregistered function: ' + fnName) + } + }) + + return pipeline + } + + /** + * Adds new functions to the end of the pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline. + */ + lunr.Pipeline.prototype.add = function () { + var fns = Array.prototype.slice.call(arguments) + + fns.forEach(function (fn) { + lunr.Pipeline.warnIfFunctionNotRegistered(fn) + this._stack.push(fn) + }, this) + } + + /** + * Adds a single function after a function that already exists in the + * pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline. + * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline. + */ + lunr.Pipeline.prototype.after = function (existingFn, newFn) { + lunr.Pipeline.warnIfFunctionNotRegistered(newFn) + + var pos = this._stack.indexOf(existingFn) + if (pos == -1) { + throw new Error('Cannot find existingFn') + } + + pos = pos + 1 + this._stack.splice(pos, 0, newFn) + } + + /** + * Adds a single function before a function that already exists in the + * pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline. + * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline. + */ + lunr.Pipeline.prototype.before = function (existingFn, newFn) { + lunr.Pipeline.warnIfFunctionNotRegistered(newFn) + + var pos = this._stack.indexOf(existingFn) + if (pos == -1) { + throw new Error('Cannot find existingFn') + } + + this._stack.splice(pos, 0, newFn) + } + + /** + * Removes a function from the pipeline. + * + * @param {lunr.PipelineFunction} fn The function to remove from the pipeline. + */ + lunr.Pipeline.prototype.remove = function (fn) { + var pos = this._stack.indexOf(fn) + if (pos == -1) { + return + } + + this._stack.splice(pos, 1) + } + + /** + * Runs the current list of functions that make up the pipeline against the + * passed tokens. + * + * @param {Array} tokens The tokens to run through the pipeline. + * @returns {Array} + */ + lunr.Pipeline.prototype.run = function (tokens) { + var stackLength = this._stack.length + + for (var i = 0; i < stackLength; i++) { + var fn = this._stack[i] + var memo = [] + + for (var j = 0; j < tokens.length; j++) { + var result = fn(tokens[j], j, tokens) + + if (result === null || result === void 0 || result === '') continue + + if (Array.isArray(result)) { + for (var k = 0; k < result.length; k++) { + memo.push(result[k]) + } + } else { + memo.push(result) + } + } + + tokens = memo + } + + return tokens + } + + /** + * Convenience method for passing a string through a pipeline and getting + * strings out. This method takes care of wrapping the passed string in a + * token and mapping the resulting tokens back to strings. + * + * @param {string} str - The string to pass through the pipeline. + * @param {?object} metadata - Optional metadata to associate with the token + * passed to the pipeline. + * @returns {string[]} + */ + lunr.Pipeline.prototype.runString = function (str, metadata) { + var token = new lunr.Token (str, metadata) + + return this.run([token]).map(function (t) { + return t.toString() + }) + } + + /** + * Resets the pipeline by removing any existing processors. + * + */ + lunr.Pipeline.prototype.reset = function () { + this._stack = [] + } + + /** + * Returns a representation of the pipeline ready for serialisation. + * + * Logs a warning if the function has not been registered. + * + * @returns {Array} + */ + lunr.Pipeline.prototype.toJSON = function () { + return this._stack.map(function (fn) { + lunr.Pipeline.warnIfFunctionNotRegistered(fn) + + return fn.label + }) + } + /*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * A vector is used to construct the vector space of documents and queries. These + * vectors support operations to determine the similarity between two documents or + * a document and a query. + * + * Normally no parameters are required for initializing a vector, but in the case of + * loading a previously dumped vector the raw elements can be provided to the constructor. + * + * For performance reasons vectors are implemented with a flat array, where an elements + * index is immediately followed by its value. E.g. [index, value, index, value]. This + * allows the underlying array to be as sparse as possible and still offer decent + * performance when being used for vector calculations. + * + * @constructor + * @param {Number[]} [elements] - The flat list of element index and element value pairs. + */ + lunr.Vector = function (elements) { + this._magnitude = 0 + this.elements = elements || [] + } + + + /** + * Calculates the position within the vector to insert a given index. + * + * This is used internally by insert and upsert. If there are duplicate indexes then + * the position is returned as if the value for that index were to be updated, but it + * is the callers responsibility to check whether there is a duplicate at that index + * + * @param {Number} insertIdx - The index at which the element should be inserted. + * @returns {Number} + */ + lunr.Vector.prototype.positionForIndex = function (index) { + // For an empty vector the tuple can be inserted at the beginning + if (this.elements.length == 0) { + return 0 + } + + var start = 0, + end = this.elements.length / 2, + sliceLength = end - start, + pivotPoint = Math.floor(sliceLength / 2), + pivotIndex = this.elements[pivotPoint * 2] + + while (sliceLength > 1) { + if (pivotIndex < index) { + start = pivotPoint + } + + if (pivotIndex > index) { + end = pivotPoint + } + + if (pivotIndex == index) { + break + } + + sliceLength = end - start + pivotPoint = start + Math.floor(sliceLength / 2) + pivotIndex = this.elements[pivotPoint * 2] + } + + if (pivotIndex == index) { + return pivotPoint * 2 + } + + if (pivotIndex > index) { + return pivotPoint * 2 + } + + if (pivotIndex < index) { + return (pivotPoint + 1) * 2 + } + } + + /** + * Inserts an element at an index within the vector. + * + * Does not allow duplicates, will throw an error if there is already an entry + * for this index. + * + * @param {Number} insertIdx - The index at which the element should be inserted. + * @param {Number} val - The value to be inserted into the vector. + */ + lunr.Vector.prototype.insert = function (insertIdx, val) { + this.upsert(insertIdx, val, function () { + throw "duplicate index" + }) + } + + /** + * Inserts or updates an existing index within the vector. + * + * @param {Number} insertIdx - The index at which the element should be inserted. + * @param {Number} val - The value to be inserted into the vector. + * @param {function} fn - A function that is called for updates, the existing value and the + * requested value are passed as arguments + */ + lunr.Vector.prototype.upsert = function (insertIdx, val, fn) { + this._magnitude = 0 + var position = this.positionForIndex(insertIdx) + + if (this.elements[position] == insertIdx) { + this.elements[position + 1] = fn(this.elements[position + 1], val) + } else { + this.elements.splice(position, 0, insertIdx, val) + } + } + + /** + * Calculates the magnitude of this vector. + * + * @returns {Number} + */ + lunr.Vector.prototype.magnitude = function () { + if (this._magnitude) return this._magnitude + + var sumOfSquares = 0, + elementsLength = this.elements.length + + for (var i = 1; i < elementsLength; i += 2) { + var val = this.elements[i] + sumOfSquares += val * val + } + + return this._magnitude = Math.sqrt(sumOfSquares) + } + + /** + * Calculates the dot product of this vector and another vector. + * + * @param {lunr.Vector} otherVector - The vector to compute the dot product with. + * @returns {Number} + */ + lunr.Vector.prototype.dot = function (otherVector) { + var dotProduct = 0, + a = this.elements, b = otherVector.elements, + aLen = a.length, bLen = b.length, + aVal = 0, bVal = 0, + i = 0, j = 0 + + while (i < aLen && j < bLen) { + aVal = a[i], bVal = b[j] + if (aVal < bVal) { + i += 2 + } else if (aVal > bVal) { + j += 2 + } else if (aVal == bVal) { + dotProduct += a[i + 1] * b[j + 1] + i += 2 + j += 2 + } + } + + return dotProduct + } + + /** + * Calculates the similarity between this vector and another vector. + * + * @param {lunr.Vector} otherVector - The other vector to calculate the + * similarity with. + * @returns {Number} + */ + lunr.Vector.prototype.similarity = function (otherVector) { + return this.dot(otherVector) / this.magnitude() || 0 + } + + /** + * Converts the vector to an array of the elements within the vector. + * + * @returns {Number[]} + */ + lunr.Vector.prototype.toArray = function () { + var output = new Array (this.elements.length / 2) + + for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) { + output[j] = this.elements[i] + } + + return output + } + + /** + * A JSON serializable representation of the vector. + * + * @returns {Number[]} + */ + lunr.Vector.prototype.toJSON = function () { + return this.elements + } + /* eslint-disable */ + /*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + + /** + * lunr.stemmer is an english language stemmer, this is a JavaScript + * implementation of the PorterStemmer taken from http://tartarus.org/~martin + * + * @static + * @implements {lunr.PipelineFunction} + * @param {lunr.Token} token - The string to stem + * @returns {lunr.Token} + * @see {@link lunr.Pipeline} + * @function + */ + lunr.stemmer = (function(){ + var step2list = { + "ational" : "ate", + "tional" : "tion", + "enci" : "ence", + "anci" : "ance", + "izer" : "ize", + "bli" : "ble", + "alli" : "al", + "entli" : "ent", + "eli" : "e", + "ousli" : "ous", + "ization" : "ize", + "ation" : "ate", + "ator" : "ate", + "alism" : "al", + "iveness" : "ive", + "fulness" : "ful", + "ousness" : "ous", + "aliti" : "al", + "iviti" : "ive", + "biliti" : "ble", + "logi" : "log" + }, + + step3list = { + "icate" : "ic", + "ative" : "", + "alize" : "al", + "iciti" : "ic", + "ical" : "ic", + "ful" : "", + "ness" : "" + }, + + c = "[^aeiou]", // consonant + v = "[aeiouy]", // vowel + C = c + "[^aeiouy]*", // consonant sequence + V = v + "[aeiou]*", // vowel sequence + + mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 + meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 + mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 + s_v = "^(" + C + ")?" + v; // vowel in stem + + var re_mgr0 = new RegExp(mgr0); + var re_mgr1 = new RegExp(mgr1); + var re_meq1 = new RegExp(meq1); + var re_s_v = new RegExp(s_v); + + var re_1a = /^(.+?)(ss|i)es$/; + var re2_1a = /^(.+?)([^s])s$/; + var re_1b = /^(.+?)eed$/; + var re2_1b = /^(.+?)(ed|ing)$/; + var re_1b_2 = /.$/; + var re2_1b_2 = /(at|bl|iz)$/; + var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$"); + var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + + var re_1c = /^(.+?[^aeiou])y$/; + var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + + var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + + var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + var re2_4 = /^(.+?)(s|t)(ion)$/; + + var re_5 = /^(.+?)e$/; + var re_5_1 = /ll$/; + var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + + var porterStemmer = function porterStemmer(w) { + var stem, + suffix, + firstch, + re, + re2, + re3, + re4; + + if (w.length < 3) { return w; } + + firstch = w.substr(0,1); + if (firstch == "y") { + w = firstch.toUpperCase() + w.substr(1); + } + + // Step 1a + re = re_1a + re2 = re2_1a; + + if (re.test(w)) { w = w.replace(re,"$1$2"); } + else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } + + // Step 1b + re = re_1b; + re2 = re2_1b; + if (re.test(w)) { + var fp = re.exec(w); + re = re_mgr0; + if (re.test(fp[1])) { + re = re_1b_2; + w = w.replace(re,""); + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = re_s_v; + if (re2.test(stem)) { + w = stem; + re2 = re2_1b_2; + re3 = re3_1b_2; + re4 = re4_1b_2; + if (re2.test(w)) { w = w + "e"; } + else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); } + else if (re4.test(w)) { w = w + "e"; } + } + } + + // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say) + re = re_1c; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem + "i"; + } + + // Step 2 + re = re_2; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = re_mgr0; + if (re.test(stem)) { + w = stem + step2list[suffix]; + } + } + + // Step 3 + re = re_3; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = re_mgr0; + if (re.test(stem)) { + w = stem + step3list[suffix]; + } + } + + // Step 4 + re = re_4; + re2 = re2_4; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = re_mgr1; + if (re.test(stem)) { + w = stem; + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = re_mgr1; + if (re2.test(stem)) { + w = stem; + } + } + + // Step 5 + re = re_5; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = re_mgr1; + re2 = re_meq1; + re3 = re3_5; + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { + w = stem; + } + } + + re = re_5_1; + re2 = re_mgr1; + if (re.test(w) && re2.test(w)) { + re = re_1b_2; + w = w.replace(re,""); + } + + // and turn initial Y back to y + + if (firstch == "y") { + w = firstch.toLowerCase() + w.substr(1); + } + + return w; + }; + + return function (token) { + return token.update(porterStemmer); + } + })(); + + lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') + /*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * lunr.generateStopWordFilter builds a stopWordFilter function from the provided + * list of stop words. + * + * The built in lunr.stopWordFilter is built using this generator and can be used + * to generate custom stopWordFilters for applications or non English languages. + * + * @function + * @param {Array} token The token to pass through the filter + * @returns {lunr.PipelineFunction} + * @see lunr.Pipeline + * @see lunr.stopWordFilter + */ + lunr.generateStopWordFilter = function (stopWords) { + var words = stopWords.reduce(function (memo, stopWord) { + memo[stopWord] = stopWord + return memo + }, {}) + + return function (token) { + if (token && words[token.toString()] !== token.toString()) return token + } + } + + /** + * lunr.stopWordFilter is an English language stop word list filter, any words + * contained in the list will not be passed through the filter. + * + * This is intended to be used in the Pipeline. If the token does not pass the + * filter then undefined will be returned. + * + * @function + * @implements {lunr.PipelineFunction} + * @params {lunr.Token} token - A token to check for being a stop word. + * @returns {lunr.Token} + * @see {@link lunr.Pipeline} + */ + lunr.stopWordFilter = lunr.generateStopWordFilter([ + 'a', + 'able', + 'about', + 'across', + 'after', + 'all', + 'almost', + 'also', + 'am', + 'among', + 'an', + 'and', + 'any', + 'are', + 'as', + 'at', + 'be', + 'because', + 'been', + 'but', + 'by', + 'can', + 'cannot', + 'could', + 'dear', + 'did', + 'do', + 'does', + 'either', + 'else', + 'ever', + 'every', + 'for', + 'from', + 'get', + 'got', + 'had', + 'has', + 'have', + 'he', + 'her', + 'hers', + 'him', + 'his', + 'how', + 'however', + 'i', + 'if', + 'in', + 'into', + 'is', + 'it', + 'its', + 'just', + 'least', + 'let', + 'like', + 'likely', + 'may', + 'me', + 'might', + 'most', + 'must', + 'my', + 'neither', + 'no', + 'nor', + 'not', + 'of', + 'off', + 'often', + 'on', + 'only', + 'or', + 'other', + 'our', + 'own', + 'rather', + 'said', + 'say', + 'says', + 'she', + 'should', + 'since', + 'so', + 'some', + 'than', + 'that', + 'the', + 'their', + 'them', + 'then', + 'there', + 'these', + 'they', + 'this', + 'tis', + 'to', + 'too', + 'twas', + 'us', + 'wants', + 'was', + 'we', + 'were', + 'what', + 'when', + 'where', + 'which', + 'while', + 'who', + 'whom', + 'why', + 'will', + 'with', + 'would', + 'yet', + 'you', + 'your' + ]) + + lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') + /*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * lunr.trimmer is a pipeline function for trimming non word + * characters from the beginning and end of tokens before they + * enter the index. + * + * This implementation may not work correctly for non latin + * characters and should either be removed or adapted for use + * with languages with non-latin characters. + * + * @static + * @implements {lunr.PipelineFunction} + * @param {lunr.Token} token The token to pass through the filter + * @returns {lunr.Token} + * @see lunr.Pipeline + */ + lunr.trimmer = function (token) { + return token.update(function (s) { + return s.replace(/^\W+/, '').replace(/\W+$/, '') + }) + } + + lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') + /*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * A token set is used to store the unique list of all tokens + * within an index. Token sets are also used to represent an + * incoming query to the index, this query token set and index + * token set are then intersected to find which tokens to look + * up in the inverted index. + * + * A token set can hold multiple tokens, as in the case of the + * index token set, or it can hold a single token as in the + * case of a simple query token set. + * + * Additionally token sets are used to perform wildcard matching. + * Leading, contained and trailing wildcards are supported, and + * from this edit distance matching can also be provided. + * + * Token sets are implemented as a minimal finite state automata, + * where both common prefixes and suffixes are shared between tokens. + * This helps to reduce the space used for storing the token set. + * + * @constructor + */ + lunr.TokenSet = function () { + this.final = false + this.edges = {} + this.id = lunr.TokenSet._nextId + lunr.TokenSet._nextId += 1 + } + + /** + * Keeps track of the next, auto increment, identifier to assign + * to a new tokenSet. + * + * TokenSets require a unique identifier to be correctly minimised. + * + * @private + */ + lunr.TokenSet._nextId = 1 + + /** + * Creates a TokenSet instance from the given sorted array of words. + * + * @param {String[]} arr - A sorted array of strings to create the set from. + * @returns {lunr.TokenSet} + * @throws Will throw an error if the input array is not sorted. + */ + lunr.TokenSet.fromArray = function (arr) { + var builder = new lunr.TokenSet.Builder + + for (var i = 0, len = arr.length; i < len; i++) { + builder.insert(arr[i]) + } + + builder.finish() + return builder.root + } + + /** + * Creates a token set from a query clause. + * + * @private + * @param {Object} clause - A single clause from lunr.Query. + * @param {string} clause.term - The query clause term. + * @param {number} [clause.editDistance] - The optional edit distance for the term. + * @returns {lunr.TokenSet} + */ + lunr.TokenSet.fromClause = function (clause) { + if ('editDistance' in clause) { + return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance) + } else { + return lunr.TokenSet.fromString(clause.term) + } + } + + /** + * Creates a token set representing a single string with a specified + * edit distance. + * + * Insertions, deletions, substitutions and transpositions are each + * treated as an edit distance of 1. + * + * Increasing the allowed edit distance will have a dramatic impact + * on the performance of both creating and intersecting these TokenSets. + * It is advised to keep the edit distance less than 3. + * + * @param {string} str - The string to create the token set from. + * @param {number} editDistance - The allowed edit distance to match. + * @returns {lunr.Vector} + */ + lunr.TokenSet.fromFuzzyString = function (str, editDistance) { + var root = new lunr.TokenSet + + var stack = [{ + node: root, + editsRemaining: editDistance, + str: str + }] + + while (stack.length) { + var frame = stack.pop() + + // no edit + if (frame.str.length > 0) { + var char = frame.str.charAt(0), + noEditNode + + if (char in frame.node.edges) { + noEditNode = frame.node.edges[char] + } else { + noEditNode = new lunr.TokenSet + frame.node.edges[char] = noEditNode + } + + if (frame.str.length == 1) { + noEditNode.final = true + } + + stack.push({ + node: noEditNode, + editsRemaining: frame.editsRemaining, + str: frame.str.slice(1) + }) + } + + if (frame.editsRemaining == 0) { + continue + } + + // insertion + if ("*" in frame.node.edges) { + var insertionNode = frame.node.edges["*"] + } else { + var insertionNode = new lunr.TokenSet + frame.node.edges["*"] = insertionNode + } + + if (frame.str.length == 0) { + insertionNode.final = true + } + + stack.push({ + node: insertionNode, + editsRemaining: frame.editsRemaining - 1, + str: frame.str + }) + + // deletion + // can only do a deletion if we have enough edits remaining + // and if there are characters left to delete in the string + if (frame.str.length > 1) { + stack.push({ + node: frame.node, + editsRemaining: frame.editsRemaining - 1, + str: frame.str.slice(1) + }) + } + + // deletion + // just removing the last character from the str + if (frame.str.length == 1) { + frame.node.final = true + } + + // substitution + // can only do a substitution if we have enough edits remaining + // and if there are characters left to substitute + if (frame.str.length >= 1) { + if ("*" in frame.node.edges) { + var substitutionNode = frame.node.edges["*"] + } else { + var substitutionNode = new lunr.TokenSet + frame.node.edges["*"] = substitutionNode + } + + if (frame.str.length == 1) { + substitutionNode.final = true + } + + stack.push({ + node: substitutionNode, + editsRemaining: frame.editsRemaining - 1, + str: frame.str.slice(1) + }) + } + + // transposition + // can only do a transposition if there are edits remaining + // and there are enough characters to transpose + if (frame.str.length > 1) { + var charA = frame.str.charAt(0), + charB = frame.str.charAt(1), + transposeNode + + if (charB in frame.node.edges) { + transposeNode = frame.node.edges[charB] + } else { + transposeNode = new lunr.TokenSet + frame.node.edges[charB] = transposeNode + } + + if (frame.str.length == 1) { + transposeNode.final = true + } + + stack.push({ + node: transposeNode, + editsRemaining: frame.editsRemaining - 1, + str: charA + frame.str.slice(2) + }) + } + } + + return root + } + + /** + * Creates a TokenSet from a string. + * + * The string may contain one or more wildcard characters (*) + * that will allow wildcard matching when intersecting with + * another TokenSet. + * + * @param {string} str - The string to create a TokenSet from. + * @returns {lunr.TokenSet} + */ + lunr.TokenSet.fromString = function (str) { + var node = new lunr.TokenSet, + root = node + + /* + * Iterates through all characters within the passed string + * appending a node for each character. + * + * When a wildcard character is found then a self + * referencing edge is introduced to continually match + * any number of any characters. + */ + for (var i = 0, len = str.length; i < len; i++) { + var char = str[i], + final = (i == len - 1) + + if (char == "*") { + node.edges[char] = node + node.final = final + + } else { + var next = new lunr.TokenSet + next.final = final + + node.edges[char] = next + node = next + } + } + + return root + } + + /** + * Converts this TokenSet into an array of strings + * contained within the TokenSet. + * + * This is not intended to be used on a TokenSet that + * contains wildcards, in these cases the results are + * undefined and are likely to cause an infinite loop. + * + * @returns {string[]} + */ + lunr.TokenSet.prototype.toArray = function () { + var words = [] + + var stack = [{ + prefix: "", + node: this + }] + + while (stack.length) { + var frame = stack.pop(), + edges = Object.keys(frame.node.edges), + len = edges.length + + if (frame.node.final) { + /* In Safari, at this point the prefix is sometimes corrupted, see: + * https://github.com/olivernn/lunr.js/issues/279 Calling any + * String.prototype method forces Safari to "cast" this string to what + * it's supposed to be, fixing the bug. */ + frame.prefix.charAt(0) + words.push(frame.prefix) + } + + for (var i = 0; i < len; i++) { + var edge = edges[i] + + stack.push({ + prefix: frame.prefix.concat(edge), + node: frame.node.edges[edge] + }) + } + } + + return words + } + + /** + * Generates a string representation of a TokenSet. + * + * This is intended to allow TokenSets to be used as keys + * in objects, largely to aid the construction and minimisation + * of a TokenSet. As such it is not designed to be a human + * friendly representation of the TokenSet. + * + * @returns {string} + */ + lunr.TokenSet.prototype.toString = function () { + // NOTE: Using Object.keys here as this.edges is very likely + // to enter 'hash-mode' with many keys being added + // + // avoiding a for-in loop here as it leads to the function + // being de-optimised (at least in V8). From some simple + // benchmarks the performance is comparable, but allowing + // V8 to optimize may mean easy performance wins in the future. + + if (this._str) { + return this._str + } + + var str = this.final ? '1' : '0', + labels = Object.keys(this.edges).sort(), + len = labels.length + + for (var i = 0; i < len; i++) { + var label = labels[i], + node = this.edges[label] + + str = str + label + node.id + } + + return str + } + + /** + * Returns a new TokenSet that is the intersection of + * this TokenSet and the passed TokenSet. + * + * This intersection will take into account any wildcards + * contained within the TokenSet. + * + * @param {lunr.TokenSet} b - An other TokenSet to intersect with. + * @returns {lunr.TokenSet} + */ + lunr.TokenSet.prototype.intersect = function (b) { + var output = new lunr.TokenSet, + frame = undefined + + var stack = [{ + qNode: b, + output: output, + node: this + }] + + while (stack.length) { + frame = stack.pop() + + // NOTE: As with the #toString method, we are using + // Object.keys and a for loop instead of a for-in loop + // as both of these objects enter 'hash' mode, causing + // the function to be de-optimised in V8 + var qEdges = Object.keys(frame.qNode.edges), + qLen = qEdges.length, + nEdges = Object.keys(frame.node.edges), + nLen = nEdges.length + + for (var q = 0; q < qLen; q++) { + var qEdge = qEdges[q] + + for (var n = 0; n < nLen; n++) { + var nEdge = nEdges[n] + + if (nEdge == qEdge || qEdge == '*') { + var node = frame.node.edges[nEdge], + qNode = frame.qNode.edges[qEdge], + final = node.final && qNode.final, + next = undefined + + if (nEdge in frame.output.edges) { + // an edge already exists for this character + // no need to create a new node, just set the finality + // bit unless this node is already final + next = frame.output.edges[nEdge] + next.final = next.final || final + + } else { + // no edge exists yet, must create one + // set the finality bit and insert it + // into the output + next = new lunr.TokenSet + next.final = final + frame.output.edges[nEdge] = next + } + + stack.push({ + qNode: qNode, + output: next, + node: node + }) + } + } + } + } + + return output + } + lunr.TokenSet.Builder = function () { + this.previousWord = "" + this.root = new lunr.TokenSet + this.uncheckedNodes = [] + this.minimizedNodes = {} + } + + lunr.TokenSet.Builder.prototype.insert = function (word) { + var node, + commonPrefix = 0 + + if (word < this.previousWord) { + throw new Error ("Out of order word insertion") + } + + for (var i = 0; i < word.length && i < this.previousWord.length; i++) { + if (word[i] != this.previousWord[i]) break + commonPrefix++ + } + + this.minimize(commonPrefix) + + if (this.uncheckedNodes.length == 0) { + node = this.root + } else { + node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child + } + + for (var i = commonPrefix; i < word.length; i++) { + var nextNode = new lunr.TokenSet, + char = word[i] + + node.edges[char] = nextNode + + this.uncheckedNodes.push({ + parent: node, + char: char, + child: nextNode + }) + + node = nextNode + } + + node.final = true + this.previousWord = word + } + + lunr.TokenSet.Builder.prototype.finish = function () { + this.minimize(0) + } + + lunr.TokenSet.Builder.prototype.minimize = function (downTo) { + for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) { + var node = this.uncheckedNodes[i], + childKey = node.child.toString() + + if (childKey in this.minimizedNodes) { + node.parent.edges[node.char] = this.minimizedNodes[childKey] + } else { + // Cache the key for this node since + // we know it can't change anymore + node.child._str = childKey + + this.minimizedNodes[childKey] = node.child + } + + this.uncheckedNodes.pop() + } + } + /*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * An index contains the built index of all documents and provides a query interface + * to the index. + * + * Usually instances of lunr.Index will not be created using this constructor, instead + * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be + * used to load previously built and serialized indexes. + * + * @constructor + * @param {Object} attrs - The attributes of the built search index. + * @param {Object} attrs.invertedIndex - An index of term/field to document reference. + * @param {Object} attrs.fieldVectors - Field vectors + * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens. + * @param {string[]} attrs.fields - The names of indexed document fields. + * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms. + */ + lunr.Index = function (attrs) { + this.invertedIndex = attrs.invertedIndex + this.fieldVectors = attrs.fieldVectors + this.tokenSet = attrs.tokenSet + this.fields = attrs.fields + this.pipeline = attrs.pipeline + } + + /** + * A result contains details of a document matching a search query. + * @typedef {Object} lunr.Index~Result + * @property {string} ref - The reference of the document this result represents. + * @property {number} score - A number between 0 and 1 representing how similar this document is to the query. + * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match. + */ + + /** + * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple + * query language which itself is parsed into an instance of lunr.Query. + * + * For programmatically building queries it is advised to directly use lunr.Query, the query language + * is best used for human entered text rather than program generated text. + * + * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported + * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello' + * or 'world', though those that contain both will rank higher in the results. + * + * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can + * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding + * wildcards will increase the number of documents that will be found but can also have a negative + * impact on query performance, especially with wildcards at the beginning of a term. + * + * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term + * hello in the title field will match this query. Using a field not present in the index will lead + * to an error being thrown. + * + * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term + * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported + * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2. + * Avoid large values for edit distance to improve query performance. + * + * Each term also supports a presence modifier. By default a term's presence in document is optional, however + * this can be changed to either required or prohibited. For a term's presence to be required in a document the + * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and + * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not + * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'. + * + * To escape special characters the backslash character '\' can be used, this allows searches to include + * characters that would normally be considered modifiers, e.g. `foo\~2` will search for a term "foo~2" instead + * of attempting to apply a boost of 2 to the search term "foo". + * + * @typedef {string} lunr.Index~QueryString + * @example Simple single term query + * hello + * @example Multiple term query + * hello world + * @example term scoped to a field + * title:hello + * @example term with a boost of 10 + * hello^10 + * @example term with an edit distance of 2 + * hello~2 + * @example terms with presence modifiers + * -foo +bar baz + */ + + /** + * Performs a search against the index using lunr query syntax. + * + * Results will be returned sorted by their score, the most relevant results + * will be returned first. For details on how the score is calculated, please see + * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}. + * + * For more programmatic querying use lunr.Index#query. + * + * @param {lunr.Index~QueryString} queryString - A string containing a lunr query. + * @throws {lunr.QueryParseError} If the passed query string cannot be parsed. + * @returns {lunr.Index~Result[]} + */ + lunr.Index.prototype.search = function (queryString) { + return this.query(function (query) { + var parser = new lunr.QueryParser(queryString, query) + parser.parse() + }) + } + + /** + * A query builder callback provides a query object to be used to express + * the query to perform on the index. + * + * @callback lunr.Index~queryBuilder + * @param {lunr.Query} query - The query object to build up. + * @this lunr.Query + */ + + /** + * Performs a query against the index using the yielded lunr.Query object. + * + * If performing programmatic queries against the index, this method is preferred + * over lunr.Index#search so as to avoid the additional query parsing overhead. + * + * A query object is yielded to the supplied function which should be used to + * express the query to be run against the index. + * + * Note that although this function takes a callback parameter it is _not_ an + * asynchronous operation, the callback is just yielded a query object to be + * customized. + * + * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query. + * @returns {lunr.Index~Result[]} + */ + lunr.Index.prototype.query = function (fn) { + // for each query clause + // * process terms + // * expand terms from token set + // * find matching documents and metadata + // * get document vectors + // * score documents + + var query = new lunr.Query(this.fields), + matchingFields = Object.create(null), + queryVectors = Object.create(null), + termFieldCache = Object.create(null), + requiredMatches = Object.create(null), + prohibitedMatches = Object.create(null) + + /* + * To support field level boosts a query vector is created per + * field. An empty vector is eagerly created to support negated + * queries. + */ + for (var i = 0; i < this.fields.length; i++) { + queryVectors[this.fields[i]] = new lunr.Vector + } + + fn.call(query, query) + + for (var i = 0; i < query.clauses.length; i++) { + /* + * Unless the pipeline has been disabled for this term, which is + * the case for terms with wildcards, we need to pass the clause + * term through the search pipeline. A pipeline returns an array + * of processed terms. Pipeline functions may expand the passed + * term, which means we may end up performing multiple index lookups + * for a single query term. + */ + var clause = query.clauses[i], + terms = null, + clauseMatches = lunr.Set.empty + + if (clause.usePipeline) { + terms = this.pipeline.runString(clause.term, { + fields: clause.fields + }) + } else { + terms = [clause.term] + } + + for (var m = 0; m < terms.length; m++) { + var term = terms[m] + + /* + * Each term returned from the pipeline needs to use the same query + * clause object, e.g. the same boost and or edit distance. The + * simplest way to do this is to re-use the clause object but mutate + * its term property. + */ + clause.term = term + + /* + * From the term in the clause we create a token set which will then + * be used to intersect the indexes token set to get a list of terms + * to lookup in the inverted index + */ + var termTokenSet = lunr.TokenSet.fromClause(clause), + expandedTerms = this.tokenSet.intersect(termTokenSet).toArray() + + /* + * If a term marked as required does not exist in the tokenSet it is + * impossible for the search to return any matches. We set all the field + * scoped required matches set to empty and stop examining any further + * clauses. + */ + if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) { + for (var k = 0; k < clause.fields.length; k++) { + var field = clause.fields[k] + requiredMatches[field] = lunr.Set.empty + } + + break + } + + for (var j = 0; j < expandedTerms.length; j++) { + /* + * For each term get the posting and termIndex, this is required for + * building the query vector. + */ + var expandedTerm = expandedTerms[j], + posting = this.invertedIndex[expandedTerm], + termIndex = posting._index + + for (var k = 0; k < clause.fields.length; k++) { + /* + * For each field that this query term is scoped by (by default + * all fields are in scope) we need to get all the document refs + * that have this term in that field. + * + * The posting is the entry in the invertedIndex for the matching + * term from above. + */ + var field = clause.fields[k], + fieldPosting = posting[field], + matchingDocumentRefs = Object.keys(fieldPosting), + termField = expandedTerm + "/" + field, + matchingDocumentsSet = new lunr.Set(matchingDocumentRefs) + + /* + * if the presence of this term is required ensure that the matching + * documents are added to the set of required matches for this clause. + * + */ + if (clause.presence == lunr.Query.presence.REQUIRED) { + clauseMatches = clauseMatches.union(matchingDocumentsSet) + + if (requiredMatches[field] === undefined) { + requiredMatches[field] = lunr.Set.complete + } + } + + /* + * if the presence of this term is prohibited ensure that the matching + * documents are added to the set of prohibited matches for this field, + * creating that set if it does not yet exist. + */ + if (clause.presence == lunr.Query.presence.PROHIBITED) { + if (prohibitedMatches[field] === undefined) { + prohibitedMatches[field] = lunr.Set.empty + } + + prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet) + + /* + * Prohibited matches should not be part of the query vector used for + * similarity scoring and no metadata should be extracted so we continue + * to the next field + */ + continue + } + + /* + * The query field vector is populated using the termIndex found for + * the term and a unit value with the appropriate boost applied. + * Using upsert because there could already be an entry in the vector + * for the term we are working with. In that case we just add the scores + * together. + */ + queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b }) + + /** + * If we've already seen this term, field combo then we've already collected + * the matching documents and metadata, no need to go through all that again + */ + if (termFieldCache[termField]) { + continue + } + + for (var l = 0; l < matchingDocumentRefs.length; l++) { + /* + * All metadata for this term/field/document triple + * are then extracted and collected into an instance + * of lunr.MatchData ready to be returned in the query + * results + */ + var matchingDocumentRef = matchingDocumentRefs[l], + matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field), + metadata = fieldPosting[matchingDocumentRef], + fieldMatch + + if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) { + matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata) + } else { + fieldMatch.add(expandedTerm, field, metadata) + } + + } + + termFieldCache[termField] = true + } + } + } + + /** + * If the presence was required we need to update the requiredMatches field sets. + * We do this after all fields for the term have collected their matches because + * the clause terms presence is required in _any_ of the fields not _all_ of the + * fields. + */ + if (clause.presence === lunr.Query.presence.REQUIRED) { + for (var k = 0; k < clause.fields.length; k++) { + var field = clause.fields[k] + requiredMatches[field] = requiredMatches[field].intersect(clauseMatches) + } + } + } + + /** + * Need to combine the field scoped required and prohibited + * matching documents into a global set of required and prohibited + * matches + */ + var allRequiredMatches = lunr.Set.complete, + allProhibitedMatches = lunr.Set.empty + + for (var i = 0; i < this.fields.length; i++) { + var field = this.fields[i] + + if (requiredMatches[field]) { + allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field]) + } + + if (prohibitedMatches[field]) { + allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field]) + } + } + + var matchingFieldRefs = Object.keys(matchingFields), + results = [], + matches = Object.create(null) + + /* + * If the query is negated (contains only prohibited terms) + * we need to get _all_ fieldRefs currently existing in the + * index. This is only done when we know that the query is + * entirely prohibited terms to avoid any cost of getting all + * fieldRefs unnecessarily. + * + * Additionally, blank MatchData must be created to correctly + * populate the results. + */ + if (query.isNegated()) { + matchingFieldRefs = Object.keys(this.fieldVectors) + + for (var i = 0; i < matchingFieldRefs.length; i++) { + var matchingFieldRef = matchingFieldRefs[i] + var fieldRef = lunr.FieldRef.fromString(matchingFieldRef) + matchingFields[matchingFieldRef] = new lunr.MatchData + } + } + + for (var i = 0; i < matchingFieldRefs.length; i++) { + /* + * Currently we have document fields that match the query, but we + * need to return documents. The matchData and scores are combined + * from multiple fields belonging to the same document. + * + * Scores are calculated by field, using the query vectors created + * above, and combined into a final document score using addition. + */ + var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]), + docRef = fieldRef.docRef + + if (!allRequiredMatches.contains(docRef)) { + continue + } + + if (allProhibitedMatches.contains(docRef)) { + continue + } + + var fieldVector = this.fieldVectors[fieldRef], + score = queryVectors[fieldRef.fieldName].similarity(fieldVector), + docMatch + + if ((docMatch = matches[docRef]) !== undefined) { + docMatch.score += score + docMatch.matchData.combine(matchingFields[fieldRef]) + } else { + var match = { + ref: docRef, + score: score, + matchData: matchingFields[fieldRef] + } + matches[docRef] = match + results.push(match) + } + } + + /* + * Sort the results objects by score, highest first. + */ + return results.sort(function (a, b) { + return b.score - a.score + }) + } + + /** + * Prepares the index for JSON serialization. + * + * The schema for this JSON blob will be described in a + * separate JSON schema file. + * + * @returns {Object} + */ + lunr.Index.prototype.toJSON = function () { + var invertedIndex = Object.keys(this.invertedIndex) + .sort() + .map(function (term) { + return [term, this.invertedIndex[term]] + }, this) + + var fieldVectors = Object.keys(this.fieldVectors) + .map(function (ref) { + return [ref, this.fieldVectors[ref].toJSON()] + }, this) + + return { + version: lunr.version, + fields: this.fields, + fieldVectors: fieldVectors, + invertedIndex: invertedIndex, + pipeline: this.pipeline.toJSON() + } + } + + /** + * Loads a previously serialized lunr.Index + * + * @param {Object} serializedIndex - A previously serialized lunr.Index + * @returns {lunr.Index} + */ + lunr.Index.load = function (serializedIndex) { + var attrs = {}, + fieldVectors = {}, + serializedVectors = serializedIndex.fieldVectors, + invertedIndex = Object.create(null), + serializedInvertedIndex = serializedIndex.invertedIndex, + tokenSetBuilder = new lunr.TokenSet.Builder, + pipeline = lunr.Pipeline.load(serializedIndex.pipeline) + + if (serializedIndex.version != lunr.version) { + lunr.utils.warn("Version mismatch when loading serialised index. Current version of lunr '" + lunr.version + "' does not match serialized index '" + serializedIndex.version + "'") + } + + for (var i = 0; i < serializedVectors.length; i++) { + var tuple = serializedVectors[i], + ref = tuple[0], + elements = tuple[1] + + fieldVectors[ref] = new lunr.Vector(elements) + } + + for (var i = 0; i < serializedInvertedIndex.length; i++) { + var tuple = serializedInvertedIndex[i], + term = tuple[0], + posting = tuple[1] + + tokenSetBuilder.insert(term) + invertedIndex[term] = posting + } + + tokenSetBuilder.finish() + + attrs.fields = serializedIndex.fields + + attrs.fieldVectors = fieldVectors + attrs.invertedIndex = invertedIndex + attrs.tokenSet = tokenSetBuilder.root + attrs.pipeline = pipeline + + return new lunr.Index(attrs) + } + /*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + */ + + /** + * lunr.Builder performs indexing on a set of documents and + * returns instances of lunr.Index ready for querying. + * + * All configuration of the index is done via the builder, the + * fields to index, the document reference, the text processing + * pipeline and document scoring parameters are all set on the + * builder before indexing. + * + * @constructor + * @property {string} _ref - Internal reference to the document reference field. + * @property {string[]} _fields - Internal reference to the document fields to index. + * @property {object} invertedIndex - The inverted index maps terms to document fields. + * @property {object} documentTermFrequencies - Keeps track of document term frequencies. + * @property {object} documentLengths - Keeps track of the length of documents added to the index. + * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing. + * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing. + * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index. + * @property {number} documentCount - Keeps track of the total number of documents indexed. + * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75. + * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2. + * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space. + * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index. + */ + lunr.Builder = function () { + this._ref = "id" + this._fields = Object.create(null) + this._documents = Object.create(null) + this.invertedIndex = Object.create(null) + this.fieldTermFrequencies = {} + this.fieldLengths = {} + this.tokenizer = lunr.tokenizer + this.pipeline = new lunr.Pipeline + this.searchPipeline = new lunr.Pipeline + this.documentCount = 0 + this._b = 0.75 + this._k1 = 1.2 + this.termIndex = 0 + this.metadataWhitelist = [] + } + + /** + * Sets the document field used as the document reference. Every document must have this field. + * The type of this field in the document should be a string, if it is not a string it will be + * coerced into a string by calling toString. + * + * The default ref is 'id'. + * + * The ref should _not_ be changed during indexing, it should be set before any documents are + * added to the index. Changing it during indexing can lead to inconsistent results. + * + * @param {string} ref - The name of the reference field in the document. + */ + lunr.Builder.prototype.ref = function (ref) { + this._ref = ref + } + + /** + * A function that is used to extract a field from a document. + * + * Lunr expects a field to be at the top level of a document, if however the field + * is deeply nested within a document an extractor function can be used to extract + * the right field for indexing. + * + * @callback fieldExtractor + * @param {object} doc - The document being added to the index. + * @returns {?(string|object|object[])} obj - The object that will be indexed for this field. + * @example Extracting a nested field + * function (doc) { return doc.nested.field } + */ + + /** + * Adds a field to the list of document fields that will be indexed. Every document being + * indexed should have this field. Null values for this field in indexed documents will + * not cause errors but will limit the chance of that document being retrieved by searches. + * + * All fields should be added before adding documents to the index. Adding fields after + * a document has been indexed will have no effect on already indexed documents. + * + * Fields can be boosted at build time. This allows terms within that field to have more + * importance when ranking search results. Use a field boost to specify that matches within + * one field are more important than other fields. + * + * @param {string} fieldName - The name of a field to index in all documents. + * @param {object} attributes - Optional attributes associated with this field. + * @param {number} [attributes.boost=1] - Boost applied to all terms within this field. + * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document. + * @throws {RangeError} fieldName cannot contain unsupported characters '/' + */ + lunr.Builder.prototype.field = function (fieldName, attributes) { + if (/\//.test(fieldName)) { + throw new RangeError ("Field '" + fieldName + "' contains illegal character '/'") + } + + this._fields[fieldName] = attributes || {} + } + + /** + * A parameter to tune the amount of field length normalisation that is applied when + * calculating relevance scores. A value of 0 will completely disable any normalisation + * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b + * will be clamped to the range 0 - 1. + * + * @param {number} number - The value to set for this tuning parameter. + */ + lunr.Builder.prototype.b = function (number) { + if (number < 0) { + this._b = 0 + } else if (number > 1) { + this._b = 1 + } else { + this._b = number + } + } + + /** + * A parameter that controls the speed at which a rise in term frequency results in term + * frequency saturation. The default value is 1.2. Setting this to a higher value will give + * slower saturation levels, a lower value will result in quicker saturation. + * + * @param {number} number - The value to set for this tuning parameter. + */ + lunr.Builder.prototype.k1 = function (number) { + this._k1 = number + } + + /** + * Adds a document to the index. + * + * Before adding fields to the index the index should have been fully setup, with the document + * ref and all fields to index already having been specified. + * + * The document must have a field name as specified by the ref (by default this is 'id') and + * it should have all fields defined for indexing, though null or undefined values will not + * cause errors. + * + * Entire documents can be boosted at build time. Applying a boost to a document indicates that + * this document should rank higher in search results than other documents. + * + * @param {object} doc - The document to add to the index. + * @param {object} attributes - Optional attributes associated with this document. + * @param {number} [attributes.boost=1] - Boost applied to all terms within this document. + */ + lunr.Builder.prototype.add = function (doc, attributes) { + var docRef = doc[this._ref], + fields = Object.keys(this._fields) + + this._documents[docRef] = attributes || {} + this.documentCount += 1 + + for (var i = 0; i < fields.length; i++) { + var fieldName = fields[i], + extractor = this._fields[fieldName].extractor, + field = extractor ? extractor(doc) : doc[fieldName], + tokens = this.tokenizer(field, { + fields: [fieldName] + }), + terms = this.pipeline.run(tokens), + fieldRef = new lunr.FieldRef (docRef, fieldName), + fieldTerms = Object.create(null) + + this.fieldTermFrequencies[fieldRef] = fieldTerms + this.fieldLengths[fieldRef] = 0 + + // store the length of this field for this document + this.fieldLengths[fieldRef] += terms.length + + // calculate term frequencies for this field + for (var j = 0; j < terms.length; j++) { + var term = terms[j] + + if (fieldTerms[term] == undefined) { + fieldTerms[term] = 0 + } + + fieldTerms[term] += 1 + + // add to inverted index + // create an initial posting if one doesn't exist + if (this.invertedIndex[term] == undefined) { + var posting = Object.create(null) + posting["_index"] = this.termIndex + this.termIndex += 1 + + for (var k = 0; k < fields.length; k++) { + posting[fields[k]] = Object.create(null) + } + + this.invertedIndex[term] = posting + } + + // add an entry for this term/fieldName/docRef to the invertedIndex + if (this.invertedIndex[term][fieldName][docRef] == undefined) { + this.invertedIndex[term][fieldName][docRef] = Object.create(null) + } + + // store all whitelisted metadata about this token in the + // inverted index + for (var l = 0; l < this.metadataWhitelist.length; l++) { + var metadataKey = this.metadataWhitelist[l], + metadata = term.metadata[metadataKey] + + if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) { + this.invertedIndex[term][fieldName][docRef][metadataKey] = [] + } + + this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata) + } + } + + } + } + + /** + * Calculates the average document length for this index + * + * @private + */ + lunr.Builder.prototype.calculateAverageFieldLengths = function () { + + var fieldRefs = Object.keys(this.fieldLengths), + numberOfFields = fieldRefs.length, + accumulator = {}, + documentsWithField = {} + + for (var i = 0; i < numberOfFields; i++) { + var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]), + field = fieldRef.fieldName + + documentsWithField[field] || (documentsWithField[field] = 0) + documentsWithField[field] += 1 + + accumulator[field] || (accumulator[field] = 0) + accumulator[field] += this.fieldLengths[fieldRef] + } + + var fields = Object.keys(this._fields) + + for (var i = 0; i < fields.length; i++) { + var fieldName = fields[i] + accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName] + } + + this.averageFieldLength = accumulator + } + + /** + * Builds a vector space model of every document using lunr.Vector + * + * @private + */ + lunr.Builder.prototype.createFieldVectors = function () { + var fieldVectors = {}, + fieldRefs = Object.keys(this.fieldTermFrequencies), + fieldRefsLength = fieldRefs.length, + termIdfCache = Object.create(null) + + for (var i = 0; i < fieldRefsLength; i++) { + var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]), + fieldName = fieldRef.fieldName, + fieldLength = this.fieldLengths[fieldRef], + fieldVector = new lunr.Vector, + termFrequencies = this.fieldTermFrequencies[fieldRef], + terms = Object.keys(termFrequencies), + termsLength = terms.length + + + var fieldBoost = this._fields[fieldName].boost || 1, + docBoost = this._documents[fieldRef.docRef].boost || 1 + + for (var j = 0; j < termsLength; j++) { + var term = terms[j], + tf = termFrequencies[term], + termIndex = this.invertedIndex[term]._index, + idf, score, scoreWithPrecision + + if (termIdfCache[term] === undefined) { + idf = lunr.idf(this.invertedIndex[term], this.documentCount) + termIdfCache[term] = idf + } else { + idf = termIdfCache[term] + } + + score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf) + score *= fieldBoost + score *= docBoost + scoreWithPrecision = Math.round(score * 1000) / 1000 + // Converts 1.23456789 to 1.234. + // Reducing the precision so that the vectors take up less + // space when serialised. Doing it now so that they behave + // the same before and after serialisation. Also, this is + // the fastest approach to reducing a number's precision in + // JavaScript. + + fieldVector.insert(termIndex, scoreWithPrecision) + } + + fieldVectors[fieldRef] = fieldVector + } + + this.fieldVectors = fieldVectors + } + + /** + * Creates a token set of all tokens in the index using lunr.TokenSet + * + * @private + */ + lunr.Builder.prototype.createTokenSet = function () { + this.tokenSet = lunr.TokenSet.fromArray( + Object.keys(this.invertedIndex).sort() + ) + } + + /** + * Builds the index, creating an instance of lunr.Index. + * + * This completes the indexing process and should only be called + * once all documents have been added to the index. + * + * @returns {lunr.Index} + */ + lunr.Builder.prototype.build = function () { + this.calculateAverageFieldLengths() + this.createFieldVectors() + this.createTokenSet() + + return new lunr.Index({ + invertedIndex: this.invertedIndex, + fieldVectors: this.fieldVectors, + tokenSet: this.tokenSet, + fields: Object.keys(this._fields), + pipeline: this.searchPipeline + }) + } + + /** + * Applies a plugin to the index builder. + * + * A plugin is a function that is called with the index builder as its context. + * Plugins can be used to customise or extend the behaviour of the index + * in some way. A plugin is just a function, that encapsulated the custom + * behaviour that should be applied when building the index. + * + * The plugin function will be called with the index builder as its argument, additional + * arguments can also be passed when calling use. The function will be called + * with the index builder as its context. + * + * @param {Function} plugin The plugin to apply. + */ + lunr.Builder.prototype.use = function (fn) { + var args = Array.prototype.slice.call(arguments, 1) + args.unshift(this) + fn.apply(this, args) + } + /** + * Contains and collects metadata about a matching document. + * A single instance of lunr.MatchData is returned as part of every + * lunr.Index~Result. + * + * @constructor + * @param {string} term - The term this match data is associated with + * @param {string} field - The field in which the term was found + * @param {object} metadata - The metadata recorded about this term in this field + * @property {object} metadata - A cloned collection of metadata associated with this document. + * @see {@link lunr.Index~Result} + */ + lunr.MatchData = function (term, field, metadata) { + var clonedMetadata = Object.create(null), + metadataKeys = Object.keys(metadata || {}) + + // Cloning the metadata to prevent the original + // being mutated during match data combination. + // Metadata is kept in an array within the inverted + // index so cloning the data can be done with + // Array#slice + for (var i = 0; i < metadataKeys.length; i++) { + var key = metadataKeys[i] + clonedMetadata[key] = metadata[key].slice() + } + + this.metadata = Object.create(null) + + if (term !== undefined) { + this.metadata[term] = Object.create(null) + this.metadata[term][field] = clonedMetadata + } + } + + /** + * An instance of lunr.MatchData will be created for every term that matches a + * document. However only one instance is required in a lunr.Index~Result. This + * method combines metadata from another instance of lunr.MatchData with this + * objects metadata. + * + * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one. + * @see {@link lunr.Index~Result} + */ + lunr.MatchData.prototype.combine = function (otherMatchData) { + var terms = Object.keys(otherMatchData.metadata) + + for (var i = 0; i < terms.length; i++) { + var term = terms[i], + fields = Object.keys(otherMatchData.metadata[term]) + + if (this.metadata[term] == undefined) { + this.metadata[term] = Object.create(null) + } + + for (var j = 0; j < fields.length; j++) { + var field = fields[j], + keys = Object.keys(otherMatchData.metadata[term][field]) + + if (this.metadata[term][field] == undefined) { + this.metadata[term][field] = Object.create(null) + } + + for (var k = 0; k < keys.length; k++) { + var key = keys[k] + + if (this.metadata[term][field][key] == undefined) { + this.metadata[term][field][key] = otherMatchData.metadata[term][field][key] + } else { + this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key]) + } + + } + } + } + } + + /** + * Add metadata for a term/field pair to this instance of match data. + * + * @param {string} term - The term this match data is associated with + * @param {string} field - The field in which the term was found + * @param {object} metadata - The metadata recorded about this term in this field + */ + lunr.MatchData.prototype.add = function (term, field, metadata) { + if (!(term in this.metadata)) { + this.metadata[term] = Object.create(null) + this.metadata[term][field] = metadata + return + } + + if (!(field in this.metadata[term])) { + this.metadata[term][field] = metadata + return + } + + var metadataKeys = Object.keys(metadata) + + for (var i = 0; i < metadataKeys.length; i++) { + var key = metadataKeys[i] + + if (key in this.metadata[term][field]) { + this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key]) + } else { + this.metadata[term][field][key] = metadata[key] + } + } + } + /** + * A lunr.Query provides a programmatic way of defining queries to be performed + * against a {@link lunr.Index}. + * + * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method + * so the query object is pre-initialized with the right index fields. + * + * @constructor + * @property {lunr.Query~Clause[]} clauses - An array of query clauses. + * @property {string[]} allFields - An array of all available fields in a lunr.Index. + */ + lunr.Query = function (allFields) { + this.clauses = [] + this.allFields = allFields + } + + /** + * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause. + * + * This allows wildcards to be added to the beginning and end of a term without having to manually do any string + * concatenation. + * + * The wildcard constants can be bitwise combined to select both leading and trailing wildcards. + * + * @constant + * @default + * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour + * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists + * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists + * @see lunr.Query~Clause + * @see lunr.Query#clause + * @see lunr.Query#term + * @example query term with trailing wildcard + * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING }) + * @example query term with leading and trailing wildcard + * query.term('foo', { + * wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING + * }) + */ + + lunr.Query.wildcard = new String ("*") + lunr.Query.wildcard.NONE = 0 + lunr.Query.wildcard.LEADING = 1 + lunr.Query.wildcard.TRAILING = 2 + + /** + * Constants for indicating what kind of presence a term must have in matching documents. + * + * @constant + * @enum {number} + * @see lunr.Query~Clause + * @see lunr.Query#clause + * @see lunr.Query#term + * @example query term with required presence + * query.term('foo', { presence: lunr.Query.presence.REQUIRED }) + */ + lunr.Query.presence = { + /** + * Term's presence in a document is optional, this is the default value. + */ + OPTIONAL: 1, + + /** + * Term's presence in a document is required, documents that do not contain + * this term will not be returned. + */ + REQUIRED: 2, + + /** + * Term's presence in a document is prohibited, documents that do contain + * this term will not be returned. + */ + PROHIBITED: 3 + } + + /** + * A single clause in a {@link lunr.Query} contains a term and details on how to + * match that term against a {@link lunr.Index}. + * + * @typedef {Object} lunr.Query~Clause + * @property {string[]} fields - The fields in an index this clause should be matched against. + * @property {number} [boost=1] - Any boost that should be applied when matching this clause. + * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be. + * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline. + * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended. + * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents. + */ + + /** + * Adds a {@link lunr.Query~Clause} to this query. + * + * Unless the clause contains the fields to be matched all fields will be matched. In addition + * a default boost of 1 is applied to the clause. + * + * @param {lunr.Query~Clause} clause - The clause to add to this query. + * @see lunr.Query~Clause + * @returns {lunr.Query} + */ + lunr.Query.prototype.clause = function (clause) { + if (!('fields' in clause)) { + clause.fields = this.allFields + } + + if (!('boost' in clause)) { + clause.boost = 1 + } + + if (!('usePipeline' in clause)) { + clause.usePipeline = true + } + + if (!('wildcard' in clause)) { + clause.wildcard = lunr.Query.wildcard.NONE + } + + if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) { + clause.term = "*" + clause.term + } + + if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) { + clause.term = "" + clause.term + "*" + } + + if (!('presence' in clause)) { + clause.presence = lunr.Query.presence.OPTIONAL + } + + this.clauses.push(clause) + + return this + } + + /** + * A negated query is one in which every clause has a presence of + * prohibited. These queries require some special processing to return + * the expected results. + * + * @returns boolean + */ + lunr.Query.prototype.isNegated = function () { + for (var i = 0; i < this.clauses.length; i++) { + if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) { + return false + } + } + + return true + } + + /** + * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause} + * to the list of clauses that make up this query. + * + * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion + * to a token or token-like string should be done before calling this method. + * + * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an + * array, each term in the array will share the same options. + * + * @param {object|object[]} term - The term(s) to add to the query. + * @param {object} [options] - Any additional properties to add to the query clause. + * @returns {lunr.Query} + * @see lunr.Query#clause + * @see lunr.Query~Clause + * @example adding a single term to a query + * query.term("foo") + * @example adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard + * query.term("foo", { + * fields: ["title"], + * boost: 10, + * wildcard: lunr.Query.wildcard.TRAILING + * }) + * @example using lunr.tokenizer to convert a string to tokens before using them as terms + * query.term(lunr.tokenizer("foo bar")) + */ + lunr.Query.prototype.term = function (term, options) { + if (Array.isArray(term)) { + term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this) + return this + } + + var clause = options || {} + clause.term = term.toString() + + this.clause(clause) + + return this + } + lunr.QueryParseError = function (message, start, end) { + this.name = "QueryParseError" + this.message = message + this.start = start + this.end = end + } + + lunr.QueryParseError.prototype = new Error + lunr.QueryLexer = function (str) { + this.lexemes = [] + this.str = str + this.length = str.length + this.pos = 0 + this.start = 0 + this.escapeCharPositions = [] + } + + lunr.QueryLexer.prototype.run = function () { + var state = lunr.QueryLexer.lexText + + while (state) { + state = state(this) + } + } + + lunr.QueryLexer.prototype.sliceString = function () { + var subSlices = [], + sliceStart = this.start, + sliceEnd = this.pos + + for (var i = 0; i < this.escapeCharPositions.length; i++) { + sliceEnd = this.escapeCharPositions[i] + subSlices.push(this.str.slice(sliceStart, sliceEnd)) + sliceStart = sliceEnd + 1 + } + + subSlices.push(this.str.slice(sliceStart, this.pos)) + this.escapeCharPositions.length = 0 + + return subSlices.join('') + } + + lunr.QueryLexer.prototype.emit = function (type) { + this.lexemes.push({ + type: type, + str: this.sliceString(), + start: this.start, + end: this.pos + }) + + this.start = this.pos + } + + lunr.QueryLexer.prototype.escapeCharacter = function () { + this.escapeCharPositions.push(this.pos - 1) + this.pos += 1 + } + + lunr.QueryLexer.prototype.next = function () { + if (this.pos >= this.length) { + return lunr.QueryLexer.EOS + } + + var char = this.str.charAt(this.pos) + this.pos += 1 + return char + } + + lunr.QueryLexer.prototype.width = function () { + return this.pos - this.start + } + + lunr.QueryLexer.prototype.ignore = function () { + if (this.start == this.pos) { + this.pos += 1 + } + + this.start = this.pos + } + + lunr.QueryLexer.prototype.backup = function () { + this.pos -= 1 + } + + lunr.QueryLexer.prototype.acceptDigitRun = function () { + var char, charCode + + do { + char = this.next() + charCode = char.charCodeAt(0) + } while (charCode > 47 && charCode < 58) + + if (char != lunr.QueryLexer.EOS) { + this.backup() + } + } + + lunr.QueryLexer.prototype.more = function () { + return this.pos < this.length + } + + lunr.QueryLexer.EOS = 'EOS' + lunr.QueryLexer.FIELD = 'FIELD' + lunr.QueryLexer.TERM = 'TERM' + lunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE' + lunr.QueryLexer.BOOST = 'BOOST' + lunr.QueryLexer.PRESENCE = 'PRESENCE' + + lunr.QueryLexer.lexField = function (lexer) { + lexer.backup() + lexer.emit(lunr.QueryLexer.FIELD) + lexer.ignore() + return lunr.QueryLexer.lexText + } + + lunr.QueryLexer.lexTerm = function (lexer) { + if (lexer.width() > 1) { + lexer.backup() + lexer.emit(lunr.QueryLexer.TERM) + } + + lexer.ignore() + + if (lexer.more()) { + return lunr.QueryLexer.lexText + } + } + + lunr.QueryLexer.lexEditDistance = function (lexer) { + lexer.ignore() + lexer.acceptDigitRun() + lexer.emit(lunr.QueryLexer.EDIT_DISTANCE) + return lunr.QueryLexer.lexText + } + + lunr.QueryLexer.lexBoost = function (lexer) { + lexer.ignore() + lexer.acceptDigitRun() + lexer.emit(lunr.QueryLexer.BOOST) + return lunr.QueryLexer.lexText + } + + lunr.QueryLexer.lexEOS = function (lexer) { + if (lexer.width() > 0) { + lexer.emit(lunr.QueryLexer.TERM) + } + } + + // This matches the separator used when tokenising fields + // within a document. These should match otherwise it is + // not possible to search for some tokens within a document. + // + // It is possible for the user to change the separator on the + // tokenizer so it _might_ clash with any other of the special + // characters already used within the search string, e.g. :. + // + // This means that it is possible to change the separator in + // such a way that makes some words unsearchable using a search + // string. + lunr.QueryLexer.termSeparator = lunr.tokenizer.separator + + lunr.QueryLexer.lexText = function (lexer) { + while (true) { + var char = lexer.next() + + if (char == lunr.QueryLexer.EOS) { + return lunr.QueryLexer.lexEOS + } + + // Escape character is '\' + if (char.charCodeAt(0) == 92) { + lexer.escapeCharacter() + continue + } + + if (char == ":") { + return lunr.QueryLexer.lexField + } + + if (char == "~") { + lexer.backup() + if (lexer.width() > 0) { + lexer.emit(lunr.QueryLexer.TERM) + } + return lunr.QueryLexer.lexEditDistance + } + + if (char == "^") { + lexer.backup() + if (lexer.width() > 0) { + lexer.emit(lunr.QueryLexer.TERM) + } + return lunr.QueryLexer.lexBoost + } + + // "+" indicates term presence is required + // checking for length to ensure that only + // leading "+" are considered + if (char == "+" && lexer.width() === 1) { + lexer.emit(lunr.QueryLexer.PRESENCE) + return lunr.QueryLexer.lexText + } + + // "-" indicates term presence is prohibited + // checking for length to ensure that only + // leading "-" are considered + if (char == "-" && lexer.width() === 1) { + lexer.emit(lunr.QueryLexer.PRESENCE) + return lunr.QueryLexer.lexText + } + + if (char.match(lunr.QueryLexer.termSeparator)) { + return lunr.QueryLexer.lexTerm + } + } + } + + lunr.QueryParser = function (str, query) { + this.lexer = new lunr.QueryLexer (str) + this.query = query + this.currentClause = {} + this.lexemeIdx = 0 + } + + lunr.QueryParser.prototype.parse = function () { + this.lexer.run() + this.lexemes = this.lexer.lexemes + + var state = lunr.QueryParser.parseClause + + while (state) { + state = state(this) + } + + return this.query + } + + lunr.QueryParser.prototype.peekLexeme = function () { + return this.lexemes[this.lexemeIdx] + } + + lunr.QueryParser.prototype.consumeLexeme = function () { + var lexeme = this.peekLexeme() + this.lexemeIdx += 1 + return lexeme + } + + lunr.QueryParser.prototype.nextClause = function () { + var completedClause = this.currentClause + this.query.clause(completedClause) + this.currentClause = {} + } + + lunr.QueryParser.parseClause = function (parser) { + var lexeme = parser.peekLexeme() + + if (lexeme == undefined) { + return + } + + switch (lexeme.type) { + case lunr.QueryLexer.PRESENCE: + return lunr.QueryParser.parsePresence + case lunr.QueryLexer.FIELD: + return lunr.QueryParser.parseField + case lunr.QueryLexer.TERM: + return lunr.QueryParser.parseTerm + default: + var errorMessage = "expected either a field or a term, found " + lexeme.type + + if (lexeme.str.length >= 1) { + errorMessage += " with value '" + lexeme.str + "'" + } + + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + } + + lunr.QueryParser.parsePresence = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + switch (lexeme.str) { + case "-": + parser.currentClause.presence = lunr.Query.presence.PROHIBITED + break + case "+": + parser.currentClause.presence = lunr.Query.presence.REQUIRED + break + default: + var errorMessage = "unrecognised presence operator'" + lexeme.str + "'" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + var errorMessage = "expecting term or field, found nothing" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.FIELD: + return lunr.QueryParser.parseField + case lunr.QueryLexer.TERM: + return lunr.QueryParser.parseTerm + default: + var errorMessage = "expecting term or field, found '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } + } + + lunr.QueryParser.parseField = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + if (parser.query.allFields.indexOf(lexeme.str) == -1) { + var possibleFields = parser.query.allFields.map(function (f) { return "'" + f + "'" }).join(', '), + errorMessage = "unrecognised field '" + lexeme.str + "', possible fields: " + possibleFields + + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + parser.currentClause.fields = [lexeme.str] + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + var errorMessage = "expecting term, found nothing" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + return lunr.QueryParser.parseTerm + default: + var errorMessage = "expecting term, found '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } + } + + lunr.QueryParser.parseTerm = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + parser.currentClause.term = lexeme.str.toLowerCase() + + if (lexeme.str.indexOf("*") != -1) { + parser.currentClause.usePipeline = false + } + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + parser.nextClause() + return + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + parser.nextClause() + return lunr.QueryParser.parseTerm + case lunr.QueryLexer.FIELD: + parser.nextClause() + return lunr.QueryParser.parseField + case lunr.QueryLexer.EDIT_DISTANCE: + return lunr.QueryParser.parseEditDistance + case lunr.QueryLexer.BOOST: + return lunr.QueryParser.parseBoost + case lunr.QueryLexer.PRESENCE: + parser.nextClause() + return lunr.QueryParser.parsePresence + default: + var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } + } + + lunr.QueryParser.parseEditDistance = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + var editDistance = parseInt(lexeme.str, 10) + + if (isNaN(editDistance)) { + var errorMessage = "edit distance must be numeric" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + parser.currentClause.editDistance = editDistance + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + parser.nextClause() + return + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + parser.nextClause() + return lunr.QueryParser.parseTerm + case lunr.QueryLexer.FIELD: + parser.nextClause() + return lunr.QueryParser.parseField + case lunr.QueryLexer.EDIT_DISTANCE: + return lunr.QueryParser.parseEditDistance + case lunr.QueryLexer.BOOST: + return lunr.QueryParser.parseBoost + case lunr.QueryLexer.PRESENCE: + parser.nextClause() + return lunr.QueryParser.parsePresence + default: + var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } + } + + lunr.QueryParser.parseBoost = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + var boost = parseInt(lexeme.str, 10) + + if (isNaN(boost)) { + var errorMessage = "boost must be numeric" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + parser.currentClause.boost = boost + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + parser.nextClause() + return + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + parser.nextClause() + return lunr.QueryParser.parseTerm + case lunr.QueryLexer.FIELD: + parser.nextClause() + return lunr.QueryParser.parseField + case lunr.QueryLexer.EDIT_DISTANCE: + return lunr.QueryParser.parseEditDistance + case lunr.QueryLexer.BOOST: + return lunr.QueryParser.parseBoost + case lunr.QueryLexer.PRESENCE: + parser.nextClause() + return lunr.QueryParser.parsePresence + default: + var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } + } + + /** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ + ;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like enviroments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + root.lunr = factory() + } + }(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return lunr + })) + })(); diff --git a/docs/moduleIndex.html b/docs/moduleIndex.html new file mode 100644 index 0000000..329b834 --- /dev/null +++ b/docs/moduleIndex.html @@ -0,0 +1,166 @@ + + + + + + + + Module Index + + + + + + + + + + + + + + + + +
+ + + +
  • src - No package docstring; 1/1 module, 0/1 package documented
    • app - The module app holds the function related to flask app and database.
    • User - Undocumented
+ +
+ + + + + + + \ No newline at end of file From bf0db15a7e5874c3324dafe6e3548ccb133927e5 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:09:44 -0500 Subject: [PATCH 11/29] nameIndex doc --- docs/nameIndex.html | 230 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 docs/nameIndex.html diff --git a/docs/nameIndex.html b/docs/nameIndex.html new file mode 100644 index 0000000..7719ff2 --- /dev/null +++ b/docs/nameIndex.html @@ -0,0 +1,230 @@ + + + + + + + + Index of Names + + + + + + + + + + + + + + + + +
+ + + + + + + +

A

+ + + + + + +

I

+ + + + + + +

L

+ + + + + + +

M

+ + + + + + +

R

+ + + + + + +

S

+ + + + + + +

U

+ + + + +
+ + + + + + + + \ No newline at end of file From 3b4d0c760f2f5df1ccecb66d0ad1a9e8b6bd9d55 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:10:19 -0500 Subject: [PATCH 12/29] objects.inv --- docs/objects.inv | Bin 0 -> 460 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/objects.inv diff --git a/docs/objects.inv b/docs/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..a3a114c957b589b2ad685d8d8b362e07025bb9fb GIT binary patch literal 460 zcmV;-0WNERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGk&a$^c3 zAXa5^b7^mGIv@%oAXI2&AaZ4MbRchLAarPHb0B7EY-J#6b0A}HZE$jBb8}^6Aa`kW zXdrrQX<{x4c$|%r&u)Yu5Qp!53X?tWCcXA4nl?Qf7DgpeumkkZ+ZV(wh=SY{zTXGK zj6&MXzb}(yW`ySY+;G9*=QikRY_3lV>5a_umRJ`P=D`uIk>8Epp%(`Pe3GJHSv{91nl0@k%Q0`iogcRD0?nigipf}n3HryP|c;-ITAEDRBz^Dasi?< zt*3mF0|LLavl#G1Qq_4eaScF_4&^F55={#$KbYGOGy-95hjMD!y%^hoKL4Qr_XF%! z;|X5=Edry;zo{b**&X#j6XAM{Zx?AirNxcHDNXw#+D!vyv}(17)UqX-Gs)v~K{pq4Jx%xmcG& z>(YTw!v}qf9Ba?2BuU5C?dAO+Gk)p`^uc}X%e()mVdwWsG6&X8v(ANar~UvWF@euG CXwuRE literal 0 HcmV?d00001 From d9ddbbe01694fa8e31b75cfa6bd569b6981f0704 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:11:35 -0500 Subject: [PATCH 13/29] pydoctor.js doc --- docs/pydoctor.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/pydoctor.js diff --git a/docs/pydoctor.js b/docs/pydoctor.js new file mode 100644 index 0000000..e75269c --- /dev/null +++ b/docs/pydoctor.js @@ -0,0 +1,35 @@ +// Toogle private view + +function initPrivate() { + var params = (new URL(document.location)).searchParams; + if (!params || !parseInt(params.get('private'))) { + var show = false; + var hash = document.location.hash; + + if (hash != '') { + var anchor = document.querySelector('a[name="' + hash.substring(1) + '"]'); + show = anchor && anchor.parentNode.classList.contains('private'); + } + + if (!show) { + document.body.classList.add("private-hidden"); + } + } + updatePrivate(); +} + +function togglePrivate() { + document.body.classList.toggle("private-hidden"); + updatePrivate(); +} +function updatePrivate() { + var hidden = document.body.classList.contains('private-hidden'); + document.querySelector('#showPrivate button').innerText = + hidden ? 'Show Private API' : 'Hide Private API'; + if (history) { + var search = hidden ? document.location.pathname : '?private=1'; + history.replaceState(null, '', search + document.location.hash); + } +} + +initPrivate(); From 24b1f85b6e4a7ec47d51610457c73896d854f6ae Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:12:05 -0500 Subject: [PATCH 14/29] search --- docs/search.js | 487 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 docs/search.js diff --git a/docs/search.js b/docs/search.js new file mode 100644 index 0000000..5396c84 --- /dev/null +++ b/docs/search.js @@ -0,0 +1,487 @@ +// This file contains the code that drives the search system UX. +// It's included in every HTML file. +// Depends on library files searchlib.js and ajax.js (and of course lunr.js) + +// Ideas for improvments: +// - Include filtering buttons: +// - search only in the current module +// - have a query frontend that helps build complex queries +// - Filter out results that have score > 0.001 by default and show them on demand. +// - Should we change the default term presence to be MUST and not SHOULD ? +// -> Hack something like 'name index -value' -> '+name +index -value' +// -> 'name ?index -value' -> '+name index -value' +// - Highlight can use https://github.com/bep/docuapi/blob/5bfdc7d366ef2de58dc4e52106ad474d06410907/assets/js/helpers/highlight.js#L1 +// Better: Add support for AND and OR with parenthesis, ajust this code https://stackoverflow.com/a/20374128 + +//////// GLOBAL VARS ///////// + +let input = document.getElementById('search-box'); +let results_container = document.getElementById('search-results-container'); +let results_list = document.getElementById('search-results'); +let searchInDocstringsButton = document.getElementById('search-docstrings-button'); +let searchInDocstringsCheckbox = document.getElementById('toggle-search-in-docstrings-checkbox'); +var isSearchReadyPromise = null; + +// setTimeout variable to warn when a search takes too long +var _setLongSearchInfosTimeout = null; + +//////// UI META INFORMATIONS FUNCTIONS ///////// + +// Taken from https://stackoverflow.com/a/14130005 +// For security. +function htmlEncode(str) { + return String(str).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} + +function _setInfos(message, box_id, text_id) { + document.getElementById(text_id).textContent = message; + if (message.length>0){ + document.getElementById(box_id).style.display = 'block'; + } + else{ + document.getElementById(box_id).style.display = 'none'; + } +} + +/** + * Set the search status. + */ +function setStatus(message) { + document.getElementById('search-status').textContent = message; +} + +/** + * Show a warning, hide warning box if empty string. + */ +function setWarning(message) { + _setInfos(message, 'search-warn-box', 'search-warn'); +} + +/** + * Say that Something went wrong. + */ +function setErrorStatus() { + resetLongSearchTimerInfo() + setStatus("Something went wrong."); + setErrorInfos(); +} + +/** + * Show additional error infos (used to show query parser errors infos) or tell to go check the console. + * @param message: (optional) string + */ +function setErrorInfos(message) { + if (message != undefined){ + setWarning(message); + } + else{ + setWarning("Error: See development console for details."); + } +} + +/** + * Reset the long search timer warning. + */ +function resetLongSearchTimerInfo(){ + if (_setLongSearchInfosTimeout){ + clearTimeout(_setLongSearchInfosTimeout); + } +} +function launchLongSearchTimerInfo(){ + // After 10 seconds of searching, warn that this is taking more time than usual. + _setLongSearchInfosTimeout = setTimeout(setLongSearchInfos, 10000); +} + +/** + * Say that this search is taking longer than usual. + */ +function setLongSearchInfos(){ + setWarning("This is taking longer than usual... You can keep waiting for the search to complete, or retry the search with other terms."); +} + +//////// UI SHOW/HIDE FUNCTIONS ///////// + +function hideResultContainer(){ + results_container.style.display = 'none'; + if (!document.body.classList.contains("search-help-hidden")){ + document.body.classList.add("search-help-hidden"); + } +} + +function showResultContainer(){ + results_container.style.display = 'block'; + updateClearSearchBtn(); +} + +function toggleSearchHelpText() { + document.body.classList.toggle("search-help-hidden"); + if (document.body.classList.contains("search-help-hidden") && input.value.length==0){ + hideResultContainer(); + } + else{ + showResultContainer(); + } +} + +function resetResultList(){ + resetLongSearchTimerInfo(); + results_list.innerHTML = ''; + setWarning(''); + setStatus(''); +} + +function clearSearch(){ + stopSearching(); + + input.value = ''; + updateClearSearchBtn(); +} + +function stopSearching(){ + // UI + hideResultContainer(); + resetResultList(); + + // NOT UI + _stopSearchingProcess(); +} + +function _stopSearchingProcess(){ + abortSearch(); + restartSearchWorker(); +} + +/** + * Show and hide the (X) button depending on the current search input. + * We do not show the (X) button when there is no search going on. + */ + function updateClearSearchBtn(){ + + if (input.value.length>0){ + document.getElementById('search-clear-button').style.display = 'inline-block'; + } + else{ + document.getElementById('search-clear-button').style.display = 'none'; + } +} + +//////// SEARCH WARPPER FUNCTIONS ///////// + +// Values configuring the search-as-you-type feature. +const SEARCH_DEFAULT_DELAY = 100; // in miliseconds +const SEARCH_INCREASED_DELAY = 200; +const SEARCH_INDEX_SIZE_TRESH_INCREASE_DELAY = 10; // in MB +const SEARCH_INDEX_SIZE_TRESH_DISABLE_SEARCH_AS_YOU_TYPE = 20; + +// Search delay depends on index size. +function _getIndexSizePromise(indexURL){ + return httpGetPromise(indexURL).then((responseText) => { + if (responseText==null){ + return 0; + } + let indexSizeApprox = responseText.length / 1000000; // in MB + return indexSizeApprox; + }); +} +function _getSearchDelayPromise(indexURL){ // -> Promise of a Search delay number. + return _getIndexSizePromise(indexURL).then((size) => { + var searchDelay = SEARCH_DEFAULT_DELAY; + if (size===0){ + return searchDelay; + } + if (size>SEARCH_INDEX_SIZE_TRESH_INCREASE_DELAY){ + // For better UX + searchDelay = SEARCH_INCREASED_DELAY; // in miliseconds, this avoids searching several times when typing several leters very rapidly + } + return searchDelay; + }); +} + +function _getIsSearchReadyPromise(){ + return Promise.all([ + httpGetPromise("all-documents.html"), + httpGetPromise("searchindex.json"), + httpGetPromise("fullsearchindex.json"), + httpGetPromise("lunr.js"), + ]); +} + +// Launch search as user types if the size of the index is small enought, +// else say "Press 'Enter' to search". +function searchAsYouType(){ + if (input.value.length>0){ + showResultContainer(); + } + _getIndexSizePromise("searchindex.json").then((indexSizeApprox) => { + if (indexSizeApprox > SEARCH_INDEX_SIZE_TRESH_DISABLE_SEARCH_AS_YOU_TYPE){ + // Not searching as we type if "default" index size if greater than 20MB. + if (input.value.length===0){ // No actual query, this only resets some UI components. + launchSearch(); + } + else{ + setTimeout(() => { + _stopSearchingProcess(); + resetResultList(); + setStatus("Press 'Enter' to search."); + }); + } + } + else{ + launchSearch(); + } + }); +} + +searchEventsEnv.addEventListener("searchStarted", (ev) => { + setStatus("Searching..."); +}); + +var _lastSearchStartTime = null; +var _lastSearchInput = null; +/** + * Do the actual searching business + * Main entrypoint to [re]launch the search. + * Called everytime the search bar is edited. +*/ +function launchSearch(noDelay){ + let _searchStartTime = performance.now(); + + // Get the query terms + let _query = input.value; + + // In chrome, two events are triggered simultaneously for the input event. + // So we discard consecutive (within the same 0.001s) requests that have the same search query. + if (( + (_searchStartTime-_lastSearchStartTime) < (0.001*1000) + ) && (_query === _lastSearchInput) ){ + return; + } + + updateClearSearchBtn(); + + // Setup query meta infos. + _lastSearchStartTime = _searchStartTime + _lastSearchInput = _query; + + if (_query.length===0){ + stopSearching(); + return; + } + + if (!window.Worker) { + setStatus("Cannot search: JavaScript Worker API is not supported in your browser. "); + return; + } + + resetResultList(); + showResultContainer(); + setStatus("..."); + + // Determine indexURL + let indexURL = _isSearchInDocstringsEnabled() ? "fullsearchindex.json" : "searchindex.json"; + + // If search in docstring is enabled: + // -> customize query function to include docstring for clauses applicable for all fields + let _fields = _isSearchInDocstringsEnabled() ? ["name", "names", "qname", "docstring"] : ["name", "names", "qname"]; + + resetLongSearchTimerInfo(); + launchLongSearchTimerInfo(); + + // Get search delay, wait the all search resources to be cached and actually launch the search + return _getSearchDelayPromise(indexURL).then((searchDelay) => { + if (isSearchReadyPromise==null){ + isSearchReadyPromise = _getIsSearchReadyPromise() + } + return isSearchReadyPromise.then((r)=>{ + return lunrSearch(_query, indexURL, _fields, "lunr.js", !noDelay?searchDelay:0).then((lunrResults) => { + + // outdated query results + if (_searchStartTime != _lastSearchStartTime){return;} + + if (!lunrResults){ + setErrorStatus(); + throw new Error("No data to show"); + } + + if (lunrResults.length == 0){ + setStatus('No results matches "' + htmlEncode(_query) + '"'); + resetLongSearchTimerInfo(); + return; + } + + setStatus("One sec..."); + + // Get result data + return fetchResultsData(lunrResults, "all-documents.html").then((documentResults) => { + + // outdated query results + if (_searchStartTime != _lastSearchStartTime){return;} + + // Edit DOM + resetLongSearchTimerInfo(); + displaySearchResults(_query, documentResults, lunrResults) + + // Log stats + console.log('Search for "' + _query + '" took ' + + ((performance.now() - _searchStartTime)/1000).toString() + ' seconds.') + + // End + }) + }); // lunrResults promise resolved + }); + }).catch((err) => {_handleErr(err);}); + +} // end search() function + +function _handleErr(err){ + console.dir(err); + setStatus('') + if (err.message){ + resetLongSearchTimerInfo(); + setWarning(err.message) // Here we show the error because it's likely a query parser error. + } + else{ + setErrorStatus(); + } +} + +/** + * Given the query string, documentResults and lunrResults as used in search(), + * edit the DOM to add them in the search results list. + */ +function displaySearchResults(_query, documentResults, lunrResults){ + resetResultList(); + documentResults.forEach((dobj) => { + results_list.appendChild(buildSearchResult(dobj)); + }); + + if (lunrResults[0].score <= 5){ + if (lunrResults.length > 500){ + setWarning("Your search yielded a lot of results! and there aren't many great matches. Maybe try with other terms?"); + } + else{ + setWarning("Unfortunately, it looks like there aren't many great matches for your search. Maybe try with other terms?"); + } + } + else { + if (lunrResults.length > 500){ + setWarning("Your search yielded a lot of results! Maybe try with other terms?"); + } + } + + let publicResults = documentResults.filter(function(value){ + return !value.querySelector('.privacy').innerHTML.includes("PRIVATE"); + }) + + if (publicResults.length==0){ + setStatus('No results matches "' + htmlEncode(_query) + '". Some private objects matches your search though.'); + } + else{ + setStatus( + 'Search for "' + htmlEncode(_query) + '" yielded ' + publicResults.length + ' ' + + (publicResults.length === 1 ? 'result' : 'results') + '.'); + } +} + +function _isSearchInDocstringsEnabled() { + return searchInDocstringsCheckbox.checked; +} + +function toggleSearchInDocstrings() { + if (searchInDocstringsCheckbox.checked){ + searchInDocstringsButton.classList.add('label-success') + } + else{ + if (searchInDocstringsButton.classList.contains('label-success')){ + searchInDocstringsButton.classList.remove('label-success') + } + } + if (input.value.length>0){ + launchSearch(true) + } +} + +////// SETUP ////// + +// Attach launchSearch() to search text field update events. + +input.oninput = (event) => { + setTimeout(() =>{ + searchAsYouType(); + }, 0); +}; +input.onkeyup = (event) => { + if (event.key === 'Enter') { + launchSearch(true); + } +}; +input.onfocus = (event) => { + // Ensure the search bar is set-up. + // Load fullsearchindex.json, searchindex.json and all-documents.html to have them in the cache asap. + isSearchReadyPromise = _getIsSearchReadyPromise(); +} +document.onload = (event) => { + // Set-up search bar. + setTimeout(() =>{ + isSearchReadyPromise = _getIsSearchReadyPromise(); + }, 500); +} + +// Close the dropdown if the user clicks on echap key +document.addEventListener('keyup', (evt) => { + evt = evt || window.event; + if (evt.key === "Escape" || evt.key === "Esc") { + hideResultContainer(); + } +}); + +// Init search and help text. +// search box is not visible by default because +// we don't want to show it if the browser do not support JS. +window.addEventListener('load', (event) => { + document.getElementById('search-box-container').style.display = 'block'; + document.getElementById('search-help-box').style.display = 'block'; + hideResultContainer(); +}); + +// This listener does 3 things. +window.addEventListener("click", (event) => { + if (event){ + // 1. Hide the dropdown if the user clicks outside of it + if (!event.target.closest('#search-results-container') + && !event.target.closest('#search-box') + && !event.target.closest('#search-help-button')){ + hideResultContainer(); + return; + } + + // 2. Show the dropdown if the user clicks inside the search box + if (event.target.closest('#search-box')){ + if (input.value.length>0){ + showResultContainer(); + return; + } + } + + // 3.Hide the dropdown if the user clicks on a link that brings them to the same page. + // This includes links in summaries. + link = event.target.closest('#search-results a') + if (link){ + page_parts = document.location.pathname.split('/') + current_page = page_parts[page_parts.length-1] + href = link.getAttribute("href"); + + if (!href.startsWith(current_page)){ + // The link points to something not in the same page, so don't hide the dropdown. + // The page will be reloaded anyway, but this ensure that if we go back, the dropdown will + // still be expanded. + return; + } + if (event.ctrlKey || event.shiftKey || event.metaKey){ + // The link is openned in a new window/tab so don't hide the dropdown. + return; + } + hideResultContainer(); + } + } +}); From 1304d2b4e051e10f9b4dc847e7249c26845a641d Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:12:21 -0500 Subject: [PATCH 15/29] searchindex --- docs/searchindex.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/searchindex.json diff --git a/docs/searchindex.json b/docs/searchindex.json new file mode 100644 index 0000000..8a4e3f9 --- /dev/null +++ b/docs/searchindex.json @@ -0,0 +1 @@ +{"version": "2.3.9", "fields": ["name", "names", "qname"], "fieldVectors": [["name/src", [0, 17.187]], ["names/src", [0, 9.763]], ["qname/src", [0, 4.297]], ["name/src.app", [1, 15.177]], ["names/src.app", [1, 8.621]], ["qname/src.app", [2, 5.991]], ["name/src.User", [3, 12.235]], ["names/src.User", [3, 6.95]], ["qname/src.User", [4, 5.991]], ["name/src.User.models", [5, 23.966]], ["names/src.User.models", [6, 13.613]], ["qname/src.User.models", [7, 5.991]], ["name/src.User.routes", [8, 23.966]], ["names/src.User.routes", [9, 13.613]], ["qname/src.User.routes", [10, 5.991]], ["name/src.app.app", [1, 7.588]], ["names/src.app.app", [1, 4.31]], ["qname/src.app.app", [11, 2.996]], ["name/src.app.mongo_conn", [12, 11.983]], ["names/src.app.mongo_conn", [13, 4.249, 14, 5.123]], ["qname/src.app.mongo_conn", [15, 2.996]], ["name/src.app.mongo_params", [16, 11.983]], ["names/src.app.mongo_params", [13, 4.249, 17, 5.123]], ["qname/src.app.mongo_params", [18, 2.996]], ["name/src.app.mongodb_client", [19, 11.983]], ["names/src.app.mongodb_client", [20, 5.123, 21, 5.123]], ["qname/src.app.mongodb_client", [22, 2.996]], ["name/src.app.login_required", [23, 11.983]], ["names/src.app.login_required", [24, 2.615, 25, 5.123]], ["qname/src.app.login_required", [26, 2.996]], ["name/src.app.sgup", [27, 9.94]], ["names/src.app.sgup", [27, 5.646]], ["qname/src.app.sgup", [28, 2.996]], ["name/src.app.lgin", [29, 9.94]], ["names/src.app.lgin", [29, 5.646]], ["qname/src.app.lgin", [30, 2.996]], ["name/src.app.index", [31, 9.94]], ["names/src.app.index", [31, 5.646]], ["qname/src.app.index", [32, 2.996]], ["name/src.app.login", [24, 6.118]], ["names/src.app.login", [24, 3.475]], ["qname/src.app.login", [33, 2.996]], ["name/src.app.search", [34, 9.94]], ["names/src.app.search", [34, 5.646]], ["qname/src.app.search", [35, 2.996]], ["name/src.app.add", [36, 9.94]], ["names/src.app.add", [36, 5.646]], ["qname/src.app.add", [37, 2.996]], ["name/src.app.read_from_db", [38, 11.983]], ["names/src.app.read_from_db", [39, 5.123, 40, 5.123]], ["qname/src.app.read_from_db", [41, 2.996]], ["name/src.User.models.User", [3, 12.235]], ["names/src.User.models.User", [3, 6.95]], ["qname/src.User.models.User", [42, 5.991]], ["name/src.User.models.User.startSession", [43, 11.983]], ["names/src.User.models.User.startSession", [44, 5.123, 45, 5.123]], ["qname/src.User.models.User.startSession", [46, 2.996]], ["name/src.User.models.User.signup", [47, 7.588]], ["names/src.User.models.User.signup", [47, 4.31]], ["qname/src.User.models.User.signup", [48, 2.996]], ["name/src.User.models.User.logout", [49, 9.94]], ["names/src.User.models.User.logout", [49, 5.646]], ["qname/src.User.models.User.logout", [50, 2.996]], ["name/src.User.models.User.login", [24, 6.118]], ["names/src.User.models.User.login", [24, 3.475]], ["qname/src.User.models.User.login", [51, 2.996]], ["name/src.User.models.User.showProfile", [52, 11.983]], ["names/src.User.models.User.showProfile", [53, 4.249, 54, 4.249]], ["qname/src.User.models.User.showProfile", [55, 2.996]], ["name/src.User.models.User.saveResume", [56, 9.94]], ["names/src.User.models.User.saveResume", [57, 4.249, 58, 4.249]], ["qname/src.User.models.User.saveResume", [59, 2.996]], ["name/src.User.routes.signup", [47, 7.588]], ["names/src.User.routes.signup", [47, 4.31]], ["qname/src.User.routes.signup", [60, 2.996]], ["name/src.User.routes.signout", [61, 9.94]], ["names/src.User.routes.signout", [61, 5.646]], ["qname/src.User.routes.signout", [62, 2.996]], ["name/src.User.routes.loginUser", [63, 11.983]], ["names/src.User.routes.loginUser", [3, 2.615, 24, 2.615]], ["qname/src.User.routes.loginUser", [64, 2.996]], ["name/src.User.routes.showUserProfile", [65, 11.983]], ["names/src.User.routes.showUserProfile", [3, 2.097, 53, 3.406, 54, 3.406]], ["qname/src.User.routes.showUserProfile", [66, 2.996]], ["name/src.User.routes.saveResume", [56, 9.94]], ["names/src.User.routes.saveResume", [57, 4.249, 58, 4.249]], ["qname/src.User.routes.saveResume", [67, 2.996]]], "invertedIndex": [["add", {"name": {"src.app.add": {}}, "names": {"src.app.add": {}}, "qname": {}, "_index": 36}], ["app", {"name": {"src.app": {}, "src.app.app": {}}, "names": {"src.app": {}, "src.app.app": {}}, "qname": {}, "_index": 1}], ["client", {"name": {}, "names": {"src.app.mongodb_client": {}}, "qname": {}, "_index": 21}], ["conn", {"name": {}, "names": {"src.app.mongo_conn": {}}, "qname": {}, "_index": 14}], ["db", {"name": {}, "names": {"src.app.read_from_db": {}}, "qname": {}, "_index": 40}], ["index", {"name": {"src.app.index": {}}, "names": {"src.app.index": {}}, "qname": {}, "_index": 31}], ["lgin", {"name": {"src.app.lgin": {}}, "names": {"src.app.lgin": {}}, "qname": {}, "_index": 29}], ["login", {"name": {"src.app.login": {}, "src.User.models.User.login": {}}, "names": {"src.app.login_required": {}, "src.app.login": {}, "src.User.models.User.login": {}, "src.User.routes.loginUser": {}}, "qname": {}, "_index": 24}], ["login_required", {"name": {"src.app.login_required": {}}, "names": {}, "qname": {}, "_index": 23}], ["loginuser", {"name": {"src.User.routes.loginUser": {}}, "names": {}, "qname": {}, "_index": 63}], ["logout", {"name": {"src.User.models.User.logout": {}}, "names": {"src.User.models.User.logout": {}}, "qname": {}, "_index": 49}], ["model", {"name": {}, "names": {"src.User.models": {}}, "qname": {}, "_index": 6}], ["models", {"name": {"src.User.models": {}}, "names": {}, "qname": {}, "_index": 5}], ["mongo", {"name": {}, "names": {"src.app.mongo_conn": {}, "src.app.mongo_params": {}}, "qname": {}, "_index": 13}], ["mongo_conn", {"name": {"src.app.mongo_conn": {}}, "names": {}, "qname": {}, "_index": 12}], ["mongo_params", {"name": {"src.app.mongo_params": {}}, "names": {}, "qname": {}, "_index": 16}], ["mongodb", {"name": {}, "names": {"src.app.mongodb_client": {}}, "qname": {}, "_index": 20}], ["mongodb_client", {"name": {"src.app.mongodb_client": {}}, "names": {}, "qname": {}, "_index": 19}], ["param", {"name": {}, "names": {"src.app.mongo_params": {}}, "qname": {}, "_index": 17}], ["profil", {"name": {}, "names": {"src.User.models.User.showProfile": {}, "src.User.routes.showUserProfile": {}}, "qname": {}, "_index": 54}], ["read", {"name": {}, "names": {"src.app.read_from_db": {}}, "qname": {}, "_index": 39}], ["read_from_db", {"name": {"src.app.read_from_db": {}}, "names": {}, "qname": {}, "_index": 38}], ["requir", {"name": {}, "names": {"src.app.login_required": {}}, "qname": {}, "_index": 25}], ["resum", {"name": {}, "names": {"src.User.models.User.saveResume": {}, "src.User.routes.saveResume": {}}, "qname": {}, "_index": 58}], ["rout", {"name": {}, "names": {"src.User.routes": {}}, "qname": {}, "_index": 9}], ["routes", {"name": {"src.User.routes": {}}, "names": {}, "qname": {}, "_index": 8}], ["save", {"name": {}, "names": {"src.User.models.User.saveResume": {}, "src.User.routes.saveResume": {}}, "qname": {}, "_index": 57}], ["saveresume", {"name": {"src.User.models.User.saveResume": {}, "src.User.routes.saveResume": {}}, "names": {}, "qname": {}, "_index": 56}], ["search", {"name": {"src.app.search": {}}, "names": {"src.app.search": {}}, "qname": {}, "_index": 34}], ["session", {"name": {}, "names": {"src.User.models.User.startSession": {}}, "qname": {}, "_index": 45}], ["sgup", {"name": {"src.app.sgup": {}}, "names": {"src.app.sgup": {}}, "qname": {}, "_index": 27}], ["show", {"name": {}, "names": {"src.User.models.User.showProfile": {}, "src.User.routes.showUserProfile": {}}, "qname": {}, "_index": 53}], ["showprofile", {"name": {"src.User.models.User.showProfile": {}}, "names": {}, "qname": {}, "_index": 52}], ["showuserprofile", {"name": {"src.User.routes.showUserProfile": {}}, "names": {}, "qname": {}, "_index": 65}], ["signout", {"name": {"src.User.routes.signout": {}}, "names": {"src.User.routes.signout": {}}, "qname": {}, "_index": 61}], ["signup", {"name": {"src.User.models.User.signup": {}, "src.User.routes.signup": {}}, "names": {"src.User.models.User.signup": {}, "src.User.routes.signup": {}}, "qname": {}, "_index": 47}], ["src", {"name": {"src": {}}, "names": {"src": {}}, "qname": {"src": {}}, "_index": 0}], ["src.app", {"name": {}, "names": {}, "qname": {"src.app": {}}, "_index": 2}], ["src.app.add", {"name": {}, "names": {}, "qname": {"src.app.add": {}}, "_index": 37}], ["src.app.app", {"name": {}, "names": {}, "qname": {"src.app.app": {}}, "_index": 11}], ["src.app.index", {"name": {}, "names": {}, "qname": {"src.app.index": {}}, "_index": 32}], ["src.app.lgin", {"name": {}, "names": {}, "qname": {"src.app.lgin": {}}, "_index": 30}], ["src.app.login", {"name": {}, "names": {}, "qname": {"src.app.login": {}}, "_index": 33}], ["src.app.login_required", {"name": {}, "names": {}, "qname": {"src.app.login_required": {}}, "_index": 26}], ["src.app.mongo_conn", {"name": {}, "names": {}, "qname": {"src.app.mongo_conn": {}}, "_index": 15}], ["src.app.mongo_params", {"name": {}, "names": {}, "qname": {"src.app.mongo_params": {}}, "_index": 18}], ["src.app.mongodb_client", {"name": {}, "names": {}, "qname": {"src.app.mongodb_client": {}}, "_index": 22}], ["src.app.read_from_db", {"name": {}, "names": {}, "qname": {"src.app.read_from_db": {}}, "_index": 41}], ["src.app.search", {"name": {}, "names": {}, "qname": {"src.app.search": {}}, "_index": 35}], ["src.app.sgup", {"name": {}, "names": {}, "qname": {"src.app.sgup": {}}, "_index": 28}], ["src.user", {"name": {}, "names": {}, "qname": {"src.User": {}}, "_index": 4}], ["src.user.models", {"name": {}, "names": {}, "qname": {"src.User.models": {}}, "_index": 7}], ["src.user.models.user", {"name": {}, "names": {}, "qname": {"src.User.models.User": {}}, "_index": 42}], ["src.user.models.user.login", {"name": {}, "names": {}, "qname": {"src.User.models.User.login": {}}, "_index": 51}], ["src.user.models.user.logout", {"name": {}, "names": {}, "qname": {"src.User.models.User.logout": {}}, "_index": 50}], ["src.user.models.user.saveresume", {"name": {}, "names": {}, "qname": {"src.User.models.User.saveResume": {}}, "_index": 59}], ["src.user.models.user.showprofile", {"name": {}, "names": {}, "qname": {"src.User.models.User.showProfile": {}}, "_index": 55}], ["src.user.models.user.signup", {"name": {}, "names": {}, "qname": {"src.User.models.User.signup": {}}, "_index": 48}], ["src.user.models.user.startsession", {"name": {}, "names": {}, "qname": {"src.User.models.User.startSession": {}}, "_index": 46}], ["src.user.routes", {"name": {}, "names": {}, "qname": {"src.User.routes": {}}, "_index": 10}], ["src.user.routes.loginuser", {"name": {}, "names": {}, "qname": {"src.User.routes.loginUser": {}}, "_index": 64}], ["src.user.routes.saveresume", {"name": {}, "names": {}, "qname": {"src.User.routes.saveResume": {}}, "_index": 67}], ["src.user.routes.showuserprofile", {"name": {}, "names": {}, "qname": {"src.User.routes.showUserProfile": {}}, "_index": 66}], ["src.user.routes.signout", {"name": {}, "names": {}, "qname": {"src.User.routes.signout": {}}, "_index": 62}], ["src.user.routes.signup", {"name": {}, "names": {}, "qname": {"src.User.routes.signup": {}}, "_index": 60}], ["start", {"name": {}, "names": {"src.User.models.User.startSession": {}}, "qname": {}, "_index": 44}], ["startsession", {"name": {"src.User.models.User.startSession": {}}, "names": {}, "qname": {}, "_index": 43}], ["user", {"name": {"src.User": {}, "src.User.models.User": {}}, "names": {"src.User": {}, "src.User.models.User": {}, "src.User.routes.loginUser": {}, "src.User.routes.showUserProfile": {}}, "qname": {}, "_index": 3}]], "pipeline": []} \ No newline at end of file From 7660d334aee4201c1d55daa553d95f6f9c87ec72 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:12:57 -0500 Subject: [PATCH 16/29] searchlib and sidebartoggle --- docs/searchlib.js | 339 ++++++++++++++++++++++++++++++++++++++++++ docs/sidebartoggle.js | 69 +++++++++ 2 files changed, 408 insertions(+) create mode 100644 docs/searchlib.js create mode 100644 docs/sidebartoggle.js diff --git a/docs/searchlib.js b/docs/searchlib.js new file mode 100644 index 0000000..d1d4f70 --- /dev/null +++ b/docs/searchlib.js @@ -0,0 +1,339 @@ +// Wrapper around lunr index searching system for pydoctor API objects +// and function to format search results items into rederable HTML elements. +// This file is meant to be used as a library for the pydoctor search bar (search.js) as well as +// provide a hackable inferface to integrate API docs searching into other platforms, i.e. provide a +// "Search in API docs" option from Read The Docs search page. +// Depends on ajax.js, bundled with pydoctor. +// Other required ressources like lunr.js, searchindex.json and all-documents.html are passed as URL +// to functions. This makes the code reusable outside of pydoctor build directory. +// Implementation note: Searches are designed to be launched synchronously, if lunrSearch() is called sucessively (while already running), +// old promise will never resolves and the searhc worker will be restarted. + +// Hacky way to make the worker code inline with the rest of the source file handling the search. +// Worker message params are the following: +// - query: string +// - indexJSONData: dict +// - defaultFields: list of strings +let _lunrWorkerCode = ` + +// The lunr.js code will be inserted here. + +onmessage = (message) => { + if (!message.data.query) { + throw new Error('No search query provided.'); + } + if (!message.data.indexJSONData) { + throw new Error('No index data provided.'); + } + if (!message.data.defaultFields) { + throw new Error('No default fields provided.'); + } + // Create index + let index = lunr.Index.load(message.data.indexJSONData); + + // Declare query function building + function _queryfn(_query){ // _query is the Query object + // Edit the parsed query clauses that are applicable for all fields (default) in order + // to remove the field 'kind' from the clause since this it's only useful when specifically requested. + var parser = new lunr.QueryParser(message.data.query, _query) + parser.parse() + _query.clauses.forEach(clause => { + if (clause.fields == _query.allFields){ + // we change the query fields when they are applicable to all fields + // to a list of predefined fields because we might include additional filters (like kind:) + // which should not be matched by default. + clause.fields = message.data.defaultFields; + } + // TODO: If fuzzy match is greater than 20 throw an error. + }); + } + + // Launch the search + let results = index.query(_queryfn) + + // Post message with results + postMessage({'results':results}); +}; +`; + +// Adapted from https://stackoverflow.com/a/44137284 +// Override worker methods to detect termination and count message posting and restart() method. +// This allows some optimizations since the worker doesn't need to be restarted when it hasn't been used. +function _makeWorkerSmart(workerURL) { + // make normal worker + var worker = new Worker(workerURL); + // assume that it's running from the start + worker.terminated = false; + worker.postMessageCount = 0; + // count the number of times postMessage() is called + worker.postMessage = function() { + this.postMessageCount = this.postMessageCount + 1; + // normal post message + return Worker.prototype.postMessage.apply(this, arguments); + } + // sets terminated to true + worker.terminate = function() { + if (this.terminated===true){return;} + this.terminated = true; + // normal terminate + return Worker.prototype.terminate.apply(this, arguments); + } + // creates NEW WORKER with the same URL as itself, terminate worker first. + worker.restart = function() { + this.terminate(); + return _makeWorkerSmart(workerURL); + } + return worker; +} + +var _searchWorker = null + +/** + * The searchEventsEnv Document variable let's let caller register a event listener "searchStarted" for sending + * a signal when the search actually starts, could be up to 0.2 or 0.3 secs ater user finished typing. + */ +let searchEventsEnv = document.implementation.createHTMLDocument( + 'This is a document to popagate search related events, we avoid using "document" for performance reasons.'); + +// there is a difference in abortSearch() vs restartSearchWorker(). +// abortSearch() triggers a abortSearch event, which have a effect on searches that are not yet running in workers. +// whereas restartSearchWorker() which kills the worker if it's in use, but does not abort search that is not yet posted to the worker. +function abortSearch(){ + searchEventsEnv.dispatchEvent(new CustomEvent('abortSearch', {})); +} +// Kills and restarts search worker (if needed). +function restartSearchWorker() { + var w = _searchWorker; + if (w!=null){ + if (w.postMessageCount>0){ + // the worker has been used, it has to be restarted + // TODO: Actually it needs to be restarted only if it's running a search right now. + // Otherwise we can reuse the same worker, but that's not a very big deal in this context. + w = w.restart(); + } + // Else, the worker has never been used, it can be returned as is. + // This can happens when typing fast with a very large index JSON to load. + } + _searchWorker = w; +} + +function _getWorkerPromise(lunJsSourceCode){ // -> Promise of a fresh worker to run a query. + let promise = new Promise((resolve, reject) => { + // Do the search business, wrap the process inside an inline Worker. + // This is a hack such that the UI can refresh during the search. + if (_searchWorker===null){ + // Create only one blob and URL. + let lunrWorkerCode = lunJsSourceCode + _lunrWorkerCode; + let _workerBlob = new Blob([lunrWorkerCode], {type: 'text/javascript'}); + let _workerObjectURL = window.URL.createObjectURL(_workerBlob); + _searchWorker = _makeWorkerSmart(_workerObjectURL) + } + else{ + restartSearchWorker(); + } + resolve(_searchWorker); + }); + return promise +} + +/** + * Launch a search and get a promise of results. One search can be lauch at a time only. + * Old promise never resolves if calling lunrSearch() again while already running. + * @param query: Query string. + * @param indexURL: URL pointing to the Lunr search index, generated by pydoctor. + * @param defaultFields: List of strings: default fields to apply to query clauses when none is specified. ["name", "names", "qname"] for instance. + * @param lunrJsURL: URL pointing to a copy of lunr.js. + * @param searchDelay: Number of miliseconds to wait before actually launching the query. This is useful to set for "search as you type" kind of search box + * because it let a chance to users to continue typing without triggering useless searches (because previous search is aborted on launching a new one). + */ +function lunrSearch(query, indexURL, defaultFields, lunrJsURL, searchDelay){ + // Abort ongoing search + abortSearch(); + + // Register abort procedure. + var _aborted = false; + searchEventsEnv.addEventListener('abortSearch', (ev) => { + _aborted = true; + searchEventsEnv.removeEventListener('abortSearch', this); + }); + + // Pref: + // Because this function can be called a lot of times in a very few moments, + // Actually launch search after a delay to let a chance to users to continue typing, + // which would trigger a search abort event, which would avoid wasting a worker + // for a search that is not wanted anymore. + return new Promise((_resolve, _reject) => { + setTimeout(() => { + _resolve( + _getIndexDataPromise(indexURL).then((lunrIndexData) => { + // Include lunr.js source inside the worker such that it has no dependencies. + return httpGetPromise(lunrJsURL).then((responseText) => { + // Do the search business, wrap the process inside an inline Worker. + // This is a hack such that the UI can refresh during the search. + return _getWorkerPromise(responseText).then((worker) => { + let promise = new Promise((resolve, reject) => { + worker.onmessage = (message) => { + if (!message.data.results){ + reject("No data received from worker"); + } + else{ + console.log("Got result from worker:") + console.dir(message.data.results) + resolve(message.data.results) + } + } + worker.onerror = function(error) { + reject(error); + }; + }); + let _msgData = { + 'query': query, + 'indexJSONData': lunrIndexData, + 'defaultFields': defaultFields + } + + if (!_aborted){ + console.log(`Posting query "${query}" to worker:`) + console.dir(_msgData) + worker.postMessage(_msgData); + searchEventsEnv.dispatchEvent( + new CustomEvent("searchStarted", {'query':query}) + ); + } + + return promise + }); + }); + }) + );}, searchDelay); + }); +} + +/** +* @param results: list of lunr.Index~Result. +* @param allDocumentsURL: URL pointing to all-documents.html, generated by pydoctor. +* @returns: Promise of a list of HTMLElement corresponding to the all-documents.html +* list elements matching your search results. +*/ +function fetchResultsData(results, allDocumentsURL){ + return _getAllDocumentsPromise(allDocumentsURL).then((allDocuments) => { + // Look for results data in parsed all-documents.html + return _asyncFor(results, (result) => { + // Find the result model row data. + var dobj = allDocuments.getElementById(result.ref); + if (!dobj){ + throw new Error("Cannot find document ID: " + result.ref); + } + // Return result data + return dobj; + }) + }) +} + +/** + * Transform list item as in all-documents.html into a formatted search result row. + */ +function buildSearchResult(dobj) { + + // Build one result item + var tr = document.createElement('tr'), + kindtd = document.createElement('td'), + contenttd = document.createElement('td'), + article = document.createElement('article'), + header = document.createElement('header'), + section = document.createElement('section'), + code = document.createElement('code'), + a = document.createElement('a'), + p = document.createElement('p'); + + p.innerHTML = dobj.querySelector('.summary').innerHTML; + a.setAttribute('href', dobj.querySelector('.url').innerHTML); + a.setAttribute('class', 'internal-link'); + a.innerHTML = dobj.querySelector('.fullName').innerHTML; + + let kind_value = dobj.querySelector('.kind').innerHTML; + let type_value = dobj.querySelector('.type').innerHTML; + + // Adding '()' on functions and methods + if (type_value.endsWith("Function")){ + a.innerHTML = a.innerHTML + '()'; + } + + kindtd.innerHTML = kind_value; + + // Putting everything together + tr.appendChild(kindtd); + tr.appendChild(contenttd); + contenttd.appendChild(article); + article.appendChild(header); + article.appendChild(section); + header.appendChild(code); + code.appendChild(a); + section.appendChild(p); + + // Set kind as the CSS class of the kind td tag + let ob_css_class = dobj.querySelector('.kind').innerHTML.toLowerCase().replace(' ', ''); + kindtd.setAttribute('class', ob_css_class); + + // Set private + if (dobj.querySelector('.privacy').innerHTML.includes('PRIVATE')){ + tr.setAttribute('class', 'private'); + } + + return tr; +} + + +// This gives the UI the opportunity to refresh while we're iterating over a large list. +function _asyncFor(iterable, callback) { // -> Promise of List of results returned by callback + const promise_global = new Promise((resolve_global, reject_global) => { + let promises = []; + iterable.forEach((element) => { + promises.push(new Promise((resolve, _reject) => { + setTimeout(() => { + try{ resolve(callback(element)); } + catch (error){ _reject(error); } + }, 0); + })); + }); + Promise.all(promises).then((results) =>{ + resolve_global(results); + }).catch((err) => { + reject_global(err); + }); + }); + return promise_global; + } + +// Cache indexes JSON data since it takes a little bit of time to load JSON into stuctured data +var _indexDataCache = {}; +function _getIndexDataPromise(indexURL) { // -> Promise of a structured data for the lunr Index. + if (!_indexDataCache[indexURL]){ + return httpGetPromise(indexURL).then((responseText) => { + _indexDataCache[indexURL] = JSON.parse(responseText) + return (_indexDataCache[indexURL]); + }); + } + else{ + return new Promise((_resolve, _reject) => { + _resolve(_indexDataCache[indexURL]); + }); + } +} + +// Cache Document object +var _allDocumentsCache = {}; +function _getAllDocumentsPromise(allDocumentsURL) { // -> Promise of the all-documents.html Document object. + if (!_allDocumentsCache[allDocumentsURL]){ + return httpGetPromise(allDocumentsURL).then((responseText) => { + let _parser = new self.DOMParser(); + _allDocumentsCache[allDocumentsURL] = _parser.parseFromString(responseText, "text/html"); + return (_allDocumentsCache[allDocumentsURL]); + }); + } + else{ + return new Promise((_resolve, _reject) => { + _resolve(_allDocumentsCache[allDocumentsURL]); + }); + } +} diff --git a/docs/sidebartoggle.js b/docs/sidebartoggle.js new file mode 100644 index 0000000..dbe0566 --- /dev/null +++ b/docs/sidebartoggle.js @@ -0,0 +1,69 @@ +// Cookie manipulation functions, from https://www.w3schools.com/js/js_cookies.asp + +function setCookie(cname, cvalue, exdays) { + var d = new Date(); + d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); + var expires = "expires="+d.toUTCString(); + document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; +} + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length); + } + } + return ""; +} + +// Toogle sidebar collapse + +function initSideBarCollapse() { + var collapsed = getCookie("pydoctor-sidebar-collapsed"); + if (collapsed == "yes") { + document.body.classList.add("sidebar-collapsed"); + } + if (collapsed == ""){ + setCookie("pydoctor-sidebar-collapsed", "no", 365); + } + updateSideBarCollapse(); +} + +function toggleSideBarCollapse() { + if (document.body.classList.contains('sidebar-collapsed')){ + document.body.classList.remove('sidebar-collapsed'); + setCookie("pydoctor-sidebar-collapsed", "no", 365); + } + else { + document.body.classList.add("sidebar-collapsed"); + setCookie("pydoctor-sidebar-collapsed", "yes", 365); + } + + updateSideBarCollapse(); +} + +function updateSideBarCollapse() { + let link = document.querySelector('#collapseSideBar a') + // Since this script is called before the page finishes the parsing, + // link is undefined when it's first called. + if (link!=undefined){ + var collapsed = document.body.classList.contains('sidebar-collapsed'); + link.innerText = collapsed ? '»' : '«'; + } + // Fixes renderring issue with safari. + // https://stackoverflow.com/a/8840703 + var sidebarcontainer = document.querySelector('.sidebarcontainer'); + sidebarcontainer.style.display='none'; + sidebarcontainer.offsetHeight; // no need to store this anywhere, the reference is enough + // Set the sidebar display on load to avoid showing it for few miliseconds when loading.. + sidebarcontainer.style.display='flex'; + +} + +initSideBarCollapse(); From d2609baf7f9bd9359e9d20fbae9197c402cc7c8a Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:13:54 -0500 Subject: [PATCH 17/29] User models --- docs/src.User.html | 330 +++++++++++++++++++++ docs/src.User.models.User.html | 518 +++++++++++++++++++++++++++++++++ docs/src.User.models.html | 315 ++++++++++++++++++++ docs/src.User.routes.html | 490 +++++++++++++++++++++++++++++++ 4 files changed, 1653 insertions(+) create mode 100644 docs/src.User.html create mode 100644 docs/src.User.models.User.html create mode 100644 docs/src.User.models.html create mode 100644 docs/src.User.routes.html diff --git a/docs/src.User.html b/docs/src.User.html new file mode 100644 index 0000000..0a23287 --- /dev/null +++ b/docs/src.User.html @@ -0,0 +1,330 @@ + + + + + + + + src.User + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ package documentation +
+ +
+ +

+
+ +
+

Undocumented

+
+ +
+ + + + + + + + + + + + + + +
ModulemodelsUndocumented
ModuleroutesUndocumented
+ + + +
+ +
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/src.User.models.User.html b/docs/src.User.models.User.html new file mode 100644 index 0000000..237755c --- /dev/null +++ b/docs/src.User.models.User.html @@ -0,0 +1,518 @@ + + + + + + + + src.User.models.User + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ class documentation +
+ +
+

class User:

+

View In Hierarchy

+
+ +
+

Undocumented

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodloginUndocumented
MethodlogoutUndocumented
MethodsaveResumeUndocumented
MethodshowProfileUndocumented
MethodsignupUndocumented
MethodstartSessionUndocumented
+ + + +
+ +
+
+ + + + + + + + +
+ + def login(self): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ + def logout(self): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ + def saveResume(self): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ + def showProfile(self): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ + def signup(self): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ + def startSession(self, user): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/src.User.models.html b/docs/src.User.models.html new file mode 100644 index 0000000..dc4184b --- /dev/null +++ b/docs/src.User.models.html @@ -0,0 +1,315 @@ + + + + + + + + src.User.models + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ module documentation +
+ +
+ +

+
+ +
+

Undocumented

+
+ +
+ + + + + + + + + +
ClassUserUndocumented
+ + + +
+ +
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/src.User.routes.html b/docs/src.User.routes.html new file mode 100644 index 0000000..8901033 --- /dev/null +++ b/docs/src.User.routes.html @@ -0,0 +1,490 @@ + + + + + + + + src.User.routes + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ module documentation +
+ +
+ +

+
+ +
+

Undocumented

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionloginUserUndocumented
FunctionsaveResumeUndocumented
FunctionshowUserProfileUndocumented
FunctionsignoutUndocumented
FunctionsignupUndocumented
+ + + +
+ +
+
+ + + + + + + + +
+ @app.route('/user/login', methods=['POST'])
+ def loginUser(): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ @app.route('/user/saveResume', methods=['POST'])
+ def saveResume(): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ @app.route('/user/profile', methods=['GET'])
+ def showUserProfile(): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ @app.route('/user/logout')
+ def signout(): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ @app.route('/user/signup', methods=['POST'])
+ def signup(): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+
+ +
+
+ + + + + + + \ No newline at end of file From 3c91857e0ac7caa44d32032e6f2c7fdd8680636c Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:14:18 -0500 Subject: [PATCH 18/29] src app --- docs/src.app.html | 770 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 770 insertions(+) create mode 100644 docs/src.app.html diff --git a/docs/src.app.html b/docs/src.app.html new file mode 100644 index 0000000..7bd5bfd --- /dev/null +++ b/docs/src.app.html @@ -0,0 +1,770 @@ + + + + + + + + src.app + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ module documentation +
+ +
+ +

+
+ +
+

The module app holds the function related to flask app and database.

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionaddThe add function adds the skills column and adds the job data to the database.
FunctionindexRoute: '/' The index function renders the index.html page.
FunctionlginRoute: '/' The login function renders login.html page.
FunctionloginRoute: '/login' The index function renders the login.html page.
Functionlogin_requiredUndocumented
Functionread_from_dbThe read_from_db function reads the job details based on the input provided using regex. Returns a DataFrame with the details
FunctionsearchUndocumented
FunctionsgupRoute: '/' The index function renders the index.html page.
VariableappUndocumented
Variablemongo_connUndocumented
Variablemongo_paramsUndocumented
Variablemongodb_clientUndocumented
+ + + +
+ +
+
+ + + + + + + + +
+ + def add(db, job_data): + + + + + ¶ + +
+
+ +

The add function adds the skills column and adds the job data to the database.

+
+
+
+ + + + + + + + +
+ @app.route('/')
+ def index(): + + + + + ¶ + +
+
+ +

Route: '/' The index function renders the index.html page.

+
+
+
+ + + + + + + + +
+ @app.route('/login')
+ def lgin(): + + + + + ¶ + +
+
+ +

Route: '/' The login function renders login.html page.

+
+
+
+ + + + + + + + +
+ @app.route('/login')
+ def login(): + + + + + ¶ + +
+
+ +

Route: '/login' The index function renders the login.html page.

+
+
+
+ + + + + + + + +
+ + def login_required(f): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ + def read_from_db(request, db): + + + + + ¶ + +
+
+ +

The read_from_db function reads the job details based on the input provided using regex. Returns a DataFrame with the details

+
+
+
+ + + + + + + + +
+ @app.route('/search', methods=('GET', 'POST'))
+ def search(): + + + + + ¶ + +
+
+ +

Undocumented

+
+
+ + + + + + + + +
+ @app.route('/signup')
+ def sgup(): + + + + + ¶ + +
+
+ +

Route: '/' The index function renders the index.html page.

+
+
+
+ + + + + + + + +
+ + app = + + + + + ¶ + +
+
+ +

Undocumented

+ +
+
+ + + + + + + + +
+ + mongo_conn: str = + + + + + ¶ + +
+
+ +

Undocumented

+ +
+
+ + + + + + + + +
+ + mongo_params: str = + + + + + ¶ + +
+
+ +

Undocumented

+ +
+
+ + + + + + + + +
+ + mongodb_client = + + + + + ¶ + +
+
+ +

Undocumented

+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file From 8686d57a00cca9c8833c09ed85f995009f261d02 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:14:43 -0500 Subject: [PATCH 19/29] src --- docs/src.html | 1 + 1 file changed, 1 insertion(+) create mode 120000 docs/src.html diff --git a/docs/src.html b/docs/src.html new file mode 120000 index 0000000..64233a9 --- /dev/null +++ b/docs/src.html @@ -0,0 +1 @@ +index.html \ No newline at end of file From 398c9cf61667528177b92a4894e9604981442051 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:15:02 -0500 Subject: [PATCH 20/29] undoccedSummary --- docs/undoccedSummary.html | 167 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 docs/undoccedSummary.html diff --git a/docs/undoccedSummary.html b/docs/undoccedSummary.html new file mode 100644 index 0000000..94b458d --- /dev/null +++ b/docs/undoccedSummary.html @@ -0,0 +1,167 @@ + + + + + + + + Summary of Undocumented Objects + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 626c26125bdbf9246e189083503f24dff46a4746 Mon Sep 17 00:00:00 2001 From: Kunal Patil Date: Sun, 4 Dec 2022 19:43:18 -0500 Subject: [PATCH 21/29] Changes in index --- docs/source/index.rst | 3 +-- src/static/index.css | 4 ++-- src/static/main.css | 2 +- src/templates/index.html | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 9db10a1..45a03a2 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,8 +10,7 @@ Welcome to Job-Analyzer's documentation! :maxdepth: 2 :caption: Contents: - src - test + diff --git a/src/static/index.css b/src/static/index.css index 4f43fd1..aabbd62 100644 --- a/src/static/index.css +++ b/src/static/index.css @@ -1,7 +1,7 @@ #welcomeText{ - font-family: 'Lily Script One', cursive !important; + font-family: 'Times, Times New Roman, serif', cursive !important; font-size: 70px; - color: aliceblue; + color: rgb(1, 6, 10); margin-top: 50px; text-shadow: 1px 1px 5px lightseagreen; diff --git a/src/static/main.css b/src/static/main.css index 4605704..3ae0c3d 100644 --- a/src/static/main.css +++ b/src/static/main.css @@ -6,7 +6,7 @@ body { body { background: rgb(34,193,195); - background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(165,189,105,1) 60%, rgba(253,187,45,1) 100%); + background: linear-gradient(0deg, rgb(255, 250, 240) 20%, rgb(255, 253, 208) 70%, rgb(246, 240, 188) 90%); background-size: contain; min-height: 100%; } diff --git a/src/templates/index.html b/src/templates/index.html index ed2e479..2b0d1b4 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block content %} -

{% block title %} Welcome to JobCruncher! {% endblock %}

+

{% block title %} Welcome to JobCruncher! {% endblock %}

Juggling multiple assignments, quizzes, projects, presentations, and clutching the deadlines every week? From c450820bb28e30249f2e05680d7a275bea1f3dee Mon Sep 17 00:00:00 2001 From: Rohan S Date: Mon, 5 Dec 2022 00:25:40 -0500 Subject: [PATCH 22/29] update bg color and font --- src/static/index.css | 8 ++++++-- src/static/main.css | 11 +++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/static/index.css b/src/static/index.css index aabbd62..50f0b83 100644 --- a/src/static/index.css +++ b/src/static/index.css @@ -1,5 +1,8 @@ +@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@500&display=swap'); + #welcomeText{ - font-family: 'Times, Times New Roman, serif', cursive !important; + /* font-family: 'Times, Times New Roman, serif', cursive !important; */ + font-family: 'Open Sans', sans-serif; font-size: 70px; color: rgb(1, 6, 10); margin-top: 50px; @@ -20,7 +23,8 @@ div#intro{ } h2#whyQuestion{ - font-family: 'Lily Script One', cursive !important; + /* font-family: 'Lily Script One', cursive !important; */ + font-family: 'Open Sans', sans-serif; font-size: 35px; color: gold; text-shadow: 0px 1px 1px white; diff --git a/src/static/main.css b/src/static/main.css index 3ae0c3d..781e252 100644 --- a/src/static/main.css +++ b/src/static/main.css @@ -5,9 +5,16 @@ body { } body { - background: rgb(34,193,195); + /* background: rgb(34,193,195); + background-color: rgba(32, 178, 171, 0.884); background: linear-gradient(0deg, rgb(255, 250, 240) 20%, rgb(255, 253, 208) 70%, rgb(246, 240, 188) 90%); - background-size: contain; + background: rgb(39,59,98); + background: linear-gradient(0deg, 26%, rgba(32, 178, 171) 58%, rgba(1,83,191,1) 74%); background-size: contain; + background: rgb(44,65,167); +background: linear-gradient(90deg, rgba(44,65,167,1) 0%, rgba(33,52,134,1) 55%, rgba(31,125,175,1) 100%); +background: rgb(44,65,167); +background: linear-gradient(90deg, rgba(44,65,167,1) 0%, rgba(65,135,182,1) 55%, rgba(31,125,175,1) 100%); */ + background: rgba(65,135,182,1); min-height: 100%; } From 90b093a608b10157f83923f6a31c133d11a97f2b Mon Sep 17 00:00:00 2001 From: Rohan S Date: Mon, 5 Dec 2022 00:38:56 -0500 Subject: [PATCH 23/29] update home screen --- src/static/index.css | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/static/index.css b/src/static/index.css index 50f0b83..fc777f9 100644 --- a/src/static/index.css +++ b/src/static/index.css @@ -5,8 +5,15 @@ font-family: 'Open Sans', sans-serif; font-size: 70px; color: rgb(1, 6, 10); + color: lightseagreen; margin-top: 50px; - text-shadow: 1px 1px 5px lightseagreen; + text-shadow: 0px 0px 6px black; + text-shadow: 0px 0px 6px antiquewhite; + /* text-shadow: 1px 3px 5px antiquewhite; */ + /* text-shadow: 3px 2px 1px rgba(0, 0, 0, 0.438); */ + text-shadow: 1px 1px 1px antiquewhite; + text-shadow: 6px 8px 1px rgba(0, 0, 0, 0.098); + /* text-shadow: 0px 0px 6px antiquewhite; */ } @@ -20,6 +27,8 @@ div#intro{ line-height: 35px; word-spacing: 6px; text-align: justify; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.198); + } h2#whyQuestion{ @@ -40,4 +49,6 @@ p#whyAnswer{ line-height: 35px; word-spacing: 6px; text-align: justify; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.198); + } \ No newline at end of file From 48d0d49ecffdae36f4260c443260ba28fca6b95c Mon Sep 17 00:00:00 2001 From: Rohan S Date: Mon, 5 Dec 2022 00:50:56 -0500 Subject: [PATCH 24/29] update get_job_postings screen --- src/static/get_job_postings.css | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/static/get_job_postings.css b/src/static/get_job_postings.css index 5f65b62..fbb02ca 100644 --- a/src/static/get_job_postings.css +++ b/src/static/get_job_postings.css @@ -1,11 +1,15 @@ @import url('https://fonts.googleapis.com/css2?family=Calistoga&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@500&display=swap'); h1#getJobPostingsTitle{ font-family: 'Calistoga', cursive; - color: antiquewhite; + font-family: 'Open Sans', sans-serif; + color: greenyellow; margin-top: 18px; - text-shadow: 1px 1px 1px black; - text-shadow: 1px 1px 3px lightseagreen; + /* text-shadow: 1px 1px 1px black; + text-shadow: 1px 1px 3px lightseagreen; */ + text-shadow: 1px 1px 1px antiquewhite; + text-shadow: 6px 4px 1px rgba(0, 0, 0, 0.098); } div.jobFormDiv{ @@ -37,11 +41,13 @@ div.jobFormSubmitDiv{ } button#jobFormSubmitButton{ - font-size: 25px; + font-size: 27px; font-family: 'Calistoga', cursive; + font-family: 'Open Sans', sans-serif; border-radius: 30px; + font-weight: 700; width: 135px; - height: 45px; + height: 54px; border-width: 4px; border-color: antiquewhite; color: antiquewhite; @@ -49,12 +55,17 @@ button#jobFormSubmitButton{ } button#jobFormSubmitButton:hover{ - color: orange; + color: greenyellow; background-color: whitesmoke; - border-color: antiquewhite; + border-color: whitesmoke; + text-shadow: 0px 0px 2px black; + text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.098); + } label.jobFormTitle{ color: antiquewhite; - font-size: 18px; + font-size: 20px; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.247); + } \ No newline at end of file From 4d81b6a6a98412bf38e9672cde583ba696820b6d Mon Sep 17 00:00:00 2001 From: Rohan S Date: Mon, 5 Dec 2022 00:54:54 -0500 Subject: [PATCH 25/29] update search functionality in backend --- src/app.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/app.py b/src/app.py index afc698c..4706175 100644 --- a/src/app.py +++ b/src/app.py @@ -142,7 +142,6 @@ def read_from_db(request, db): Returns a DataFrame with the details """ job_title = request.form['title'] - job_type = request.form['type'] job_location = request.form['location'] company_name = request.form['companyName'] skills = request.form['skills'] @@ -153,7 +152,6 @@ def read_from_db(request, db): skills = skills.replace(char, '\\'+char) rgx_title = re.compile('.*' + job_title + '.*', re.IGNORECASE) - rgx_type = re.compile('.*' + job_type + '.*', re.IGNORECASE) rgx_location = re.compile('.*' + job_location + '.*', re.IGNORECASE) rgx_company_name = re.compile('.*' + company_name + '.*', re.IGNORECASE) rgx_skills = re.compile('.*' + skills + '.*', re.IGNORECASE) @@ -161,8 +159,6 @@ def read_from_db(request, db): data_filter = {} if job_title != '': data_filter['Job Title'] = rgx_title - if job_type != '': - data_filter['Employment type'] = rgx_type if job_location != '': data_filter['Location'] = rgx_location if company_name != '': From 578f7b5a62da8e7b865e033e847b969d9d1e7ef9 Mon Sep 17 00:00:00 2001 From: Rohan S Date: Mon, 5 Dec 2022 01:59:01 -0500 Subject: [PATCH 26/29] change findyourjob screen --- src/app.py | 12 +++++++----- src/static/job_posting.css | 24 ++++++++++++++++++++++++ src/templates/base.html | 3 ++- src/templates/job_posting.html | 13 ++++++++----- 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 src/static/job_posting.css diff --git a/src/app.py b/src/app.py index 4706175..7d80594 100644 --- a/src/app.py +++ b/src/app.py @@ -111,12 +111,13 @@ def search(): return render_template('job_posting.html', job_count=job_count, tables=['''