From: Morgan Richomme Date: Mon, 20 Mar 2017 07:53:38 +0000 (+0000) Subject: Merge "Add new testcases in reporting page" X-Git-Tag: danube.1.0~125 X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=commitdiff_plain;h=3921ccfb77876153edb8fdccd08ea10ad86b5635;hp=f9e0e623bcebe576125edfdb55b7ed99c1b8c086;p=releng.git Merge "Add new testcases in reporting page" --- diff --git a/jjb/apex/apex-deploy.sh b/jjb/apex/apex-deploy.sh index c91e3ee82..564c9cdb8 100755 --- a/jjb/apex/apex-deploy.sh +++ b/jjb/apex/apex-deploy.sh @@ -196,6 +196,15 @@ else NETWORK_SETTINGS_DIR="/root/network" INVENTORY_FILE="/root/inventory/pod_settings.yaml" + # if fdio on baremetal, then we are using UCS enic and + # need to use vfio-pci instead of uio generic + if [[ "$DEPLOY_SCENARIO" == *fdio* ]]; then + TMP_DEPLOY_FILE="${WORKSPACE}/${DEPLOY_SCENARIO}.yaml" + cp -f ${DEPLOY_FILE} ${TMP_DEPLOY_FILE} + sed -i 's/^\(\s*uio-driver:\).*$/\1 vfio-pci/g' ${TMP_DEPLOY_FILE} + DEPLOY_FILE=${TMP_DEPLOY_FILE} + fi + if ! sudo test -e "$INVENTORY_FILE"; then echo "ERROR: Required settings file missing: Inventory settings file ${INVENTORY_FILE}" exit 1 diff --git a/jjb/apex/apex.yml b/jjb/apex/apex.yml index 01ee1659a..93eaa6c6c 100644 --- a/jjb/apex/apex.yml +++ b/jjb/apex/apex.yml @@ -52,6 +52,7 @@ - 'os-odl_l3-fdio_dvr-noha' - 'os-odl_l3-fdio_dvr-ha' - 'os-odl_l3-csit-noha' + - 'os-odl_l3-nofeature-noha' - 'os-onos-nofeature-ha' - 'gate' @@ -375,7 +376,7 @@ builders: - trigger-builds: - - project: 'apex-deploy-baremetal-os-odl_l3-csit-noha-{stream}' + - project: 'apex-deploy-baremetal-os-odl_l3-nofeature-noha-{stream}' predefined-parameters: OPNFV_CLEAN=yes git-revision: false @@ -610,17 +611,17 @@ # i.e. one tempest smoke ipv6, two vping from functest) # 4.not used for release criteria or compliance, # only to debug the dovetail tool bugs with apex - - trigger-builds: - - project: 'dovetail-apex-{slave}-debug-{stream}' - current-parameters: false - predefined-parameters: - DEPLOY_SCENARIO=os-nosdn-nofeature-ha - block: true - same-node: true - block-thresholds: - build-step-failure-threshold: 'never' - failure-threshold: 'never' - unstable-threshold: 'FAILURE' + #- trigger-builds: + # - project: 'dovetail-apex-{slave}-debug-{stream}' + # current-parameters: false + # predefined-parameters: + # DEPLOY_SCENARIO=os-nosdn-nofeature-ha + # block: true + # same-node: true + # block-thresholds: + # build-step-failure-threshold: 'never' + # failure-threshold: 'never' + # unstable-threshold: 'FAILURE' - trigger-builds: - project: 'apex-deploy-baremetal-os-odl_l3-nofeature-ha-{stream}' predefined-parameters: | @@ -831,6 +832,36 @@ build-step-failure-threshold: 'never' failure-threshold: 'never' unstable-threshold: 'FAILURE' + - trigger-builds: + - project: 'apex-deploy-baremetal-os-nosdn-fdio-ha-{stream}' + predefined-parameters: | + BUILD_DIRECTORY=apex-build-{stream}/.build + OPNFV_CLEAN=yes + git-revision: true + same-node: true + block-thresholds: + build-step-failure-threshold: 'never' + block: true + - trigger-builds: + - project: 'functest-apex-{daily-slave}-daily-{stream}' + predefined-parameters: + DEPLOY_SCENARIO=os-nosdn-fdio-ha + block: true + same-node: true + block-thresholds: + build-step-failure-threshold: 'never' + failure-threshold: 'never' + unstable-threshold: 'FAILURE' + - trigger-builds: + - project: 'yardstick-apex-{slave}-daily-{stream}' + predefined-parameters: + DEPLOY_SCENARIO=os-nosdn-fdio-ha + block: true + same-node: true + block-thresholds: + build-step-failure-threshold: 'never' + failure-threshold: 'never' + unstable-threshold: 'FAILURE' # CSIT promote - job-template: @@ -1046,7 +1077,7 @@ - trigger: name: 'apex-master' triggers: - - timed: '0 3 * * 7' + - timed: '0 3 1 1 7' - trigger: name: 'apex-danube' triggers: diff --git a/jjb/armband/armband-ci-jobs.yml b/jjb/armband/armband-ci-jobs.yml index 137d645d1..ddcbbd038 100644 --- a/jjb/armband/armband-ci-jobs.yml +++ b/jjb/armband/armband-ci-jobs.yml @@ -56,6 +56,10 @@ slave-label: arm-pod3 installer: fuel <<: *danube + - arm-pod3-2: + slave-label: arm-pod3-2 + installer: fuel + <<: *danube #-------------------------------- # master #-------------------------------- @@ -67,6 +71,10 @@ slave-label: arm-pod3 installer: fuel <<: *master + - arm-pod3-2: + slave-label: arm-pod3-2 + installer: fuel + <<: *master #-------------------------------- # scenarios #-------------------------------- @@ -505,3 +513,65 @@ name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-danube-trigger' triggers: - timed: '' +#-------------------------------------------------------------------------- +# Enea Armband POD 3 Triggers running against master branch (aarch64 slave) +#-------------------------------------------------------------------------- +- trigger: + name: 'fuel-os-odl_l2-nofeature-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-nosdn-nofeature-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l3-nofeature-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-bgpvpn-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-nofeature-noha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-ha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-2-master-trigger' + triggers: + - timed: '' +#-------------------------------------------------------------------------- +# Enea Armband POD 3 Triggers running against danube branch (aarch64 slave) +#-------------------------------------------------------------------------- +- trigger: + name: 'fuel-os-odl_l2-nofeature-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-nosdn-nofeature-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l3-nofeature-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-bgpvpn-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-nofeature-noha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-ha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' +- trigger: + name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-2-danube-trigger' + triggers: + - timed: '' diff --git a/jjb/armband/armband-deploy.sh b/jjb/armband/armband-deploy.sh index adabfcaeb..2e5aa3924 100755 --- a/jjb/armband/armband-deploy.sh +++ b/jjb/armband/armband-deploy.sh @@ -32,6 +32,14 @@ fi # set deployment parameters export TMPDIR=${WORKSPACE}/tmpdir + +# arm-pod3-2 is an aarch64 jenkins slave for the same POD as the +# x86 jenkins slave arm-pod3; therefore we use the same pod name +# to deploy the pod from both jenkins slaves +if [[ "${NODE_NAME}" == "arm-pod3-2" ]]; then + NODE_NAME="arm-pod3" +fi + LAB_NAME=${NODE_NAME/-*} POD_NAME=${NODE_NAME/*-} diff --git a/jjb/fuel/fuel-daily-jobs.yml b/jjb/fuel/fuel-daily-jobs.yml index 36f3ce414..9e7c3034c 100644 --- a/jjb/fuel/fuel-daily-jobs.yml +++ b/jjb/fuel/fuel-daily-jobs.yml @@ -386,11 +386,11 @@ - trigger: name: 'fuel-os-onos-sfc-ha-baremetal-daily-danube-trigger' triggers: - - timed: '0 5 * * *' + - timed: '' # '0 5 * * *' - trigger: name: 'fuel-os-onos-nofeature-ha-baremetal-daily-danube-trigger' triggers: - - timed: '0 8 * * *' + - timed: '' # '0 8 * * *' - trigger: name: 'fuel-os-odl_l2-sfc-ha-baremetal-daily-danube-trigger' triggers: @@ -615,11 +615,11 @@ - trigger: name: 'fuel-os-onos-sfc-noha-virtual-daily-danube-trigger' triggers: - - timed: '30 20 * * *' + - timed: '' # '30 20 * * *' - trigger: name: 'fuel-os-onos-nofeature-noha-virtual-daily-danube-trigger' triggers: - - timed: '0 23 * * *' + - timed: '' # '0 23 * * *' - trigger: name: 'fuel-os-odl_l2-sfc-noha-virtual-daily-danube-trigger' triggers: diff --git a/jjb/functest/functest-daily-jobs.yml b/jjb/functest/functest-daily-jobs.yml index 972c4fd2f..a3268d3e5 100644 --- a/jjb/functest/functest-daily-jobs.yml +++ b/jjb/functest/functest-daily-jobs.yml @@ -158,6 +158,10 @@ slave-label: '{pod}' installer: fuel <<: *master + - arm-pod3-2: + slave-label: '{pod}' + installer: fuel + <<: *master - zte-pod1: slave-label: '{pod}' installer: fuel @@ -186,6 +190,10 @@ slave-label: '{pod}' installer: fuel <<: *danube + - arm-pod3-2: + slave-label: '{pod}' + installer: fuel + <<: *danube # PODs for verify jobs triggered by each patch upload - ool-virtual1: slave-label: '{pod}' diff --git a/jjb/global/slave-params.yml b/jjb/global/slave-params.yml index 6aa2e717c..1905a098a 100644 --- a/jjb/global/slave-params.yml +++ b/jjb/global/slave-params.yml @@ -746,6 +746,24 @@ name: LAB_CONFIG_URL default: ssh://jenkins-enea@gerrit.opnfv.org:29418/securedlab description: 'Base URI to the configuration directory' +- parameter: + name: 'arm-pod3-2-defaults' + parameters: + - node: + name: SLAVE_NAME + description: 'Slave name on Jenkins' + allowed-slaves: + - arm-pod3-2 + default-slaves: + - arm-pod3-2 + - string: + name: GIT_BASE + default: https://gerrit.opnfv.org/gerrit/$PROJECT + description: 'Git URL to use on this Jenkins Slave' + - string: + name: LAB_CONFIG_URL + default: ssh://jenkins-enea@gerrit.opnfv.org:29418/securedlab + description: 'Base URI to the configuration directory' - parameter: name: 'intel-virtual6-defaults' parameters: diff --git a/jjb/opnfvdocs/docs-rtd.yaml b/jjb/opnfvdocs/docs-rtd.yaml index bfe719149..bf6d0012b 100644 --- a/jjb/opnfvdocs/docs-rtd.yaml +++ b/jjb/opnfvdocs/docs-rtd.yaml @@ -7,6 +7,8 @@ stream: - master: branch: 'master' + - danube: + branch: 'stable/{stream}' project: 'opnfvdocs' rtdproject: 'opnfv' diff --git a/jjb/qtip/qtip-validate-jobs.yml b/jjb/qtip/qtip-validate-jobs.yml index 4cd8490fd..b8d2089d4 100644 --- a/jjb/qtip/qtip-validate-jobs.yml +++ b/jjb/qtip/qtip-validate-jobs.yml @@ -38,7 +38,7 @@ auto-trigger-name: 'qtip-daily-{pod}-trigger' - validate: auto-builder-name: qtip-validate-setup - auto-trigger-name: qtip-validate-trigger + auto-trigger-name: gerrit-trigger-change-merged - experimental: auto-builder-name: qtip-validate-setup auto-trigger-name: experimental @@ -58,7 +58,8 @@ parameters: - qtip-common-parameters: project: '{project}' - <<: *master + branch: '{branch}' + docker-tag: '{docker-tag}' - '{installer}-defaults' - '{pod}-defaults' - string: @@ -82,7 +83,6 @@ #--------- # builder #--------- - - builder: name: qtip-common-builders builders: @@ -144,11 +144,3 @@ name: qtip-daily-zte-pod3-trigger triggers: - timed: '0 1 * * *' - -- trigger: - name: qtip-validate-trigger - triggers: - - gerrit-trigger-change-merged: - project: '{project}' - branch: '{branch}' - files: '**' diff --git a/utils/lab-reconfiguration/foreman.yaml b/utils/lab-reconfiguration/foreman.yaml index 48ab9ab6e..0a37be2e1 100644 --- a/utils/lab-reconfiguration/foreman.yaml +++ b/utils/lab-reconfiguration/foreman.yaml @@ -1,3 +1,4 @@ +--- # Vnic configuration for foreman deploy network: diff --git a/utils/lab-reconfiguration/fuel.yaml b/utils/lab-reconfiguration/fuel.yaml index eb9028b2c..15e64c452 100644 --- a/utils/lab-reconfiguration/fuel.yaml +++ b/utils/lab-reconfiguration/fuel.yaml @@ -1,3 +1,4 @@ +--- # Vnic configuration for fuel deploy network: diff --git a/utils/test/dashboard/dashboard/functest/testcases.yaml b/utils/test/dashboard/dashboard/functest/testcases.yaml index 9c33d2e6b..85cb8b292 100644 --- a/utils/test/dashboard/dashboard/functest/testcases.yaml +++ b/utils/test/dashboard/dashboard/functest/testcases.yaml @@ -1,3 +1,4 @@ +--- functest: - name: tempest_smoke_serial diff --git a/utils/test/dashboard/dashboard/qtip/testcases.yaml b/utils/test/dashboard/dashboard/qtip/testcases.yaml index cd337cd73..dfa9cc2db 100644 --- a/utils/test/dashboard/dashboard/qtip/testcases.yaml +++ b/utils/test/dashboard/dashboard/qtip/testcases.yaml @@ -1,3 +1,4 @@ +--- qtip: - name: compute_test_suite @@ -18,7 +19,7 @@ qtip: fields: - field: details.index - - name:storage_test_suite + name: storage_test_suite format: qpi test_family: storage visualizations: diff --git a/utils/test/reporting/reporting.yaml b/utils/test/reporting/reporting.yaml index 33c7cc257..8c5ce1383 100644 --- a/utils/test/reporting/reporting.yaml +++ b/utils/test/reporting/reporting.yaml @@ -1,3 +1,4 @@ +--- general: installers: - apex @@ -20,12 +21,12 @@ general: directories: # Relative to the path where the repo is cloned: - dir_reporting: utils/tests/reporting/ - dir_log: utils/tests/reporting/log/ - dir_conf: utils/tests/reporting/conf/ - dir_utils: utils/tests/reporting/utils/ - dir_templates: utils/tests/reporting/templates/ - dir_display: utils/tests/reporting/display/ + dir_reporting: utils/tests/reporting/ + dir_log: utils/tests/reporting/log/ + dir_conf: utils/tests/reporting/conf/ + dir_utils: utils/tests/reporting/utils/ + dir_templates: utils/tests/reporting/templates/ + dir_display: utils/tests/reporting/display/ url: testresults.opnfv.org/reporting/ @@ -49,8 +50,8 @@ functest: test_conf: https://git.opnfv.org/cgit/functest/plain/functest/ci/testcases.yaml log_level: ERROR jenkins_url: https://build.opnfv.org/ci/view/functest/job/ - exclude_noha: False - exclude_virtual: False + exclude_noha: "False" + exclude_virtual: "False" yardstick: test_conf: https://git.opnfv.org/cgit/yardstick/plain/tests/ci/report_config.yaml @@ -58,7 +59,7 @@ yardstick: storperf: test_list: - - snia_steady_state + - snia_steady_state log_level: ERROR qtip: diff --git a/utils/test/testapi/update/test.yml b/utils/test/testapi/update/test.yml index a8868720d..943105c5f 100644 --- a/utils/test/testapi/update/test.yml +++ b/utils/test/testapi/update/test.yml @@ -1,7 +1,7 @@ --- - hosts: "{{ host }}" remote_user: "{{ user }}" - become: yes + become: "yes" become_method: sudo vars: user: "root" diff --git a/utils/test/testapi/update/update.yml b/utils/test/testapi/update/update.yml index e6663d905..18b75b6bf 100644 --- a/utils/test/testapi/update/update.yml +++ b/utils/test/testapi/update/update.yml @@ -1,7 +1,7 @@ --- - hosts: "{{ host }}" remote_user: "{{ user }}" - become: yes + become: "yes" become_method: sudo vars: user: "root" @@ -47,4 +47,4 @@ - name: remove temporary update directory file: path: "{{ update_path }}" - state: absent \ No newline at end of file + state: absent diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/README.md b/utils/test/vnfcatalogue/VNF_Catalogue/README.md index 32ad65416..22d429072 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/README.md +++ b/utils/test/vnfcatalogue/VNF_Catalogue/README.md @@ -5,8 +5,13 @@ First install the dependencies - ```npm install``` + ```npm install``` + +set time zone(Important) + Set same timezone in both nodejs server and mysql server. Something + similar to below can be used: + ``` SET GLOBAL time_zone = '+00:00'; ``` Then Start the Server - ```npm start``` + ```npm start``` diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/app.js b/utils/test/vnfcatalogue/VNF_Catalogue/app.js index 0f842b62d..4b6add2be 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/app.js +++ b/utils/test/vnfcatalogue/VNF_Catalogue/app.js @@ -13,9 +13,17 @@ var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); +var validator = require('express-validator'); var routes = require('./routes/index'); var search_projects = require('./routes/search_projects'); +var project_profile = require('./routes/project_profile'); +var add_project = require('./routes/add_project'); +var add_tag = require('./routes/add_tag'); +var search_tag = require('./routes/search_tag'); +var search_vnf = require('./routes/search_vnf'); +var vnf_tag_association = require('./routes/vnf_tag_association'); + var app = express(); @@ -23,27 +31,35 @@ var app = express(); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); +db_pool = require('./database').pool; + // Database -var db = require('mysql2'); +//var db = require('mysql2'); // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); +app.use(validator()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); // Make our db accessible to our router app.use(function(req,res,next){ - req.db = db; + //db_pool size 50 default + req.db_pool = db_pool; next(); }); app.use('/', routes); app.use('/search_projects', search_projects); - - +app.use('/project_profile', project_profile); +app.use('/add_project', add_project); +app.use('/add_tag', add_tag); +app.use('/search_tag', search_tag); +app.use('/search_vnf', search_vnf); +app.use('/vnf_tag_association', vnf_tag_association); // Some Error handling for now #TODO Remove /// catch 404 and forwarding to error handler diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/database.js b/utils/test/vnfcatalogue/VNF_Catalogue/database.js new file mode 100644 index 000000000..b31310480 --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/database.js @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2017 Kumar Rishabh and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +var mysql = require('mysql'); + +var pool = mysql.createPool({ + host: 'localhost', + user: 'myuser', + password: 'mypassword', + database: 'vnf_catalogue', + connectionLimit: 50, + supportBigNumbers: true, + multipleStatements: true, + dateStrings: 'date' +}); + +exports.pool = pool; diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/package.json b/utils/test/vnfcatalogue/VNF_Catalogue/package.json index 7c6a86730..414b42425 100644 --- a/utils/test/vnfcatalogue/VNF_Catalogue/package.json +++ b/utils/test/vnfcatalogue/VNF_Catalogue/package.json @@ -13,6 +13,11 @@ "jade": "~1.11.0", "morgan": "~1.7.0", "serve-favicon": "~2.3.0", - "mysql2": "*" + "mysql": "*", + "express-validator": "*", + "nodemon": "*", + "async": "*", + "multer": "*", + "octonode": "*" } -} \ No newline at end of file +} diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js new file mode 100644 index 000000000..11235e75b --- /dev/null +++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js @@ -0,0 +1,7 @@ +/*! + * typeahead.js 0.10.4 + * https://github.com/twitter/typeahead.js + * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT + */ + +!function(a){var b=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},toStr:function(a){return b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},noop:function(){}}}(),c="0.10.4",d=function(){"use strict";function a(a){return a=b.toStr(a),a?a.split(/\s+/):[]}function c(a){return a=b.toStr(a),a?a.split(/\W+/):[]}function d(a){return function(){var c=[].slice.call(arguments,0);return function(d){var e=[];return b.each(c,function(c){e=e.concat(a(b.toStr(d[c])))}),e}}}return{nonword:c,whitespace:a,obj:{nonword:d(c),whitespace:d(a)}}}(),e=function(){"use strict";function c(c){this.maxSize=b.isNumber(c)?c:100,this.reset(),this.maxSize<=0&&(this.set=this.get=a.noop)}function d(){this.head=this.tail=null}function e(a,b){this.key=a,this.val=b,this.prev=this.next=null}return b.mixin(c.prototype,{set:function(a,b){var c,d=this.list.tail;this.size>=this.maxSize&&(this.list.remove(d),delete this.hash[d.key]),(c=this.hash[a])?(c.val=b,this.list.moveToFront(c)):(c=new e(a,b),this.list.add(c),this.hash[a]=c,this.size++)},get:function(a){var b=this.hash[a];return b?(this.list.moveToFront(b),b.val):void 0},reset:function(){this.size=0,this.hash={},this.list=new d}}),b.mixin(d.prototype,{add:function(a){this.head&&(a.next=this.head,this.head.prev=a),this.head=a,this.tail=this.tail||a},remove:function(a){a.prev?a.prev.next=a.next:this.head=a.next,a.next?a.next.prev=a.prev:this.tail=a.prev},moveToFront:function(a){this.remove(a),this.add(a)}}),c}(),f=function(){"use strict";function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+b.escapeRegExChars(this.prefix))}function c(){return(new Date).getTime()}function d(a){return JSON.stringify(b.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return b.isNumber(g)?f.setItem(this._ttlKey(a),d(c()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return b.isNumber(d)&&c()>d?!0:!1}}:{get:b.noop,set:b.noop,remove:b.noop,clear:b.noop,isExpired:b.noop},b.mixin(a.prototype,g),a}(),g=function(){"use strict";function c(b){b=b||{},this.cancelled=!1,this.lastUrl=null,this._send=b.transport?d(b.transport):a.ajax,this._get=b.rateLimiter?b.rateLimiter(this._get):this._get,this._cache=b.cache===!1?new e(0):i}function d(c){return function(d,e){function f(a){b.defer(function(){h.resolve(a)})}function g(a){b.defer(function(){h.reject(a)})}var h=a.Deferred();return c(d,e,f,g),h}}var f=0,g={},h=6,i=new e(10);return c.setMaxPendingRequests=function(a){h=a},c.resetCache=function(){i.reset()},b.mixin(c.prototype,{_get:function(a,b,c){function d(b){c&&c(null,b),k._cache.set(a,b)}function e(){c&&c(!0)}function i(){f--,delete g[a],k.onDeckRequestArgs&&(k._get.apply(k,k.onDeckRequestArgs),k.onDeckRequestArgs=null)}var j,k=this;this.cancelled||a!==this.lastUrl||((j=g[a])?j.done(d).fail(e):h>f?(f++,g[a]=this._send(a,b).done(d).fail(e).always(i)):this.onDeckRequestArgs=[].slice.call(arguments,0))},get:function(a,c,d){var e;return b.isFunction(c)&&(d=c,c={}),this.cancelled=!1,this.lastUrl=a,(e=this._cache.get(a))?b.defer(function(){d&&d(null,e)}):this._get(a,c,d),!!e},cancel:function(){this.cancelled=!0}}),c}(),h=function(){"use strict";function c(b){b=b||{},b.datumTokenizer&&b.queryTokenizer||a.error("datumTokenizer and queryTokenizer are both required"),this.datumTokenizer=b.datumTokenizer,this.queryTokenizer=b.queryTokenizer,this.reset()}function d(a){return a=b.filter(a,function(a){return!!a}),a=b.map(a,function(a){return a.toLowerCase()})}function e(){return{ids:[],children:{}}}function f(a){for(var b={},c=[],d=0,e=a.length;e>d;d++)b[a[d]]||(b[a[d]]=!0,c.push(a[d]));return c}function g(a,b){function c(a,b){return a-b}var d=0,e=0,f=[];a=a.sort(c),b=b.sort(c);for(var g=a.length,h=b.length;g>d&&h>e;)a[d]b[e]?e++:(f.push(a[d]),d++,e++);return f}return b.mixin(c.prototype,{bootstrap:function(a){this.datums=a.datums,this.trie=a.trie},add:function(a){var c=this;a=b.isArray(a)?a:[a],b.each(a,function(a){var f,g;f=c.datums.push(a)-1,g=d(c.datumTokenizer(a)),b.each(g,function(a){var b,d,g;for(b=c.trie,d=a.split("");g=d.shift();)b=b.children[g]||(b.children[g]=e()),b.ids.push(f)})})},get:function(a){var c,e,h=this;return c=d(this.queryTokenizer(a)),b.each(c,function(a){var b,c,d,f;if(e&&0===e.length)return!1;for(b=h.trie,c=a.split("");b&&(d=c.shift());)b=b.children[d];return b&&0===c.length?(f=b.ids.slice(0),void(e=e?g(e,f):f)):(e=[],!1)}),e?b.map(f(e),function(a){return h.datums[a]}):[]},reset:function(){this.datums=[],this.trie=e()},serialize:function(){return{datums:this.datums,trie:this.trie}}}),c}(),i=function(){"use strict";function d(a){return a.local||null}function e(d){var e,f;return f={url:null,thumbprint:"",ttl:864e5,filter:null,ajax:{}},(e=d.prefetch||null)&&(e=b.isString(e)?{url:e}:e,e=b.mixin(f,e),e.thumbprint=c+e.thumbprint,e.ajax.type=e.ajax.type||"GET",e.ajax.dataType=e.ajax.dataType||"json",!e.url&&a.error("prefetch requires url to be set")),e}function f(c){function d(a){return function(c){return b.debounce(c,a)}}function e(a){return function(c){return b.throttle(c,a)}}var f,g;return g={url:null,cache:!0,wildcard:"%QUERY",replace:null,rateLimitBy:"debounce",rateLimitWait:300,send:null,filter:null,ajax:{}},(f=c.remote||null)&&(f=b.isString(f)?{url:f}:f,f=b.mixin(g,f),f.rateLimiter=/^throttle$/i.test(f.rateLimitBy)?e(f.rateLimitWait):d(f.rateLimitWait),f.ajax.type=f.ajax.type||"GET",f.ajax.dataType=f.ajax.dataType||"json",delete f.rateLimitBy,delete f.rateLimitWait,!f.url&&a.error("remote requires url to be set")),f}return{local:d,prefetch:e,remote:f}}();!function(c){"use strict";function e(b){b&&(b.local||b.prefetch||b.remote)||a.error("one of local, prefetch, or remote is required"),this.limit=b.limit||5,this.sorter=j(b.sorter),this.dupDetector=b.dupDetector||k,this.local=i.local(b),this.prefetch=i.prefetch(b),this.remote=i.remote(b),this.cacheKey=this.prefetch?this.prefetch.cacheKey||this.prefetch.url:null,this.index=new h({datumTokenizer:b.datumTokenizer,queryTokenizer:b.queryTokenizer}),this.storage=this.cacheKey?new f(this.cacheKey):null}function j(a){function c(b){return b.sort(a)}function d(a){return a}return b.isFunction(a)?c:d}function k(){return!1}var l,m;return l=c.Bloodhound,m={data:"data",protocol:"protocol",thumbprint:"thumbprint"},c.Bloodhound=e,e.noConflict=function(){return c.Bloodhound=l,e},e.tokenizers=d,b.mixin(e.prototype,{_loadPrefetch:function(b){function c(a){f.clear(),f.add(b.filter?b.filter(a):a),f._saveToStorage(f.index.serialize(),b.thumbprint,b.ttl)}var d,e,f=this;return(d=this._readFromStorage(b.thumbprint))?(this.index.bootstrap(d),e=a.Deferred().resolve()):e=a.ajax(b.url,b.ajax).done(c),e},_getFromRemote:function(a,b){function c(a,c){b(a?[]:f.remote.filter?f.remote.filter(c):c)}var d,e,f=this;if(this.transport)return a=a||"",e=encodeURIComponent(a),d=this.remote.replace?this.remote.replace(this.remote.url,a):this.remote.url.replace(this.remote.wildcard,e),this.transport.get(d,this.remote.ajax,c)},_cancelLastRemoteRequest:function(){this.transport&&this.transport.cancel()},_saveToStorage:function(a,b,c){this.storage&&(this.storage.set(m.data,a,c),this.storage.set(m.protocol,location.protocol,c),this.storage.set(m.thumbprint,b,c))},_readFromStorage:function(a){var b,c={};return this.storage&&(c.data=this.storage.get(m.data),c.protocol=this.storage.get(m.protocol),c.thumbprint=this.storage.get(m.thumbprint)),b=c.thumbprint!==a||c.protocol!==location.protocol,c.data&&!b?c.data:null},_initialize:function(){function c(){e.add(b.isFunction(f)?f():f)}var d,e=this,f=this.local;return d=this.prefetch?this._loadPrefetch(this.prefetch):a.Deferred().resolve(),f&&d.done(c),this.transport=this.remote?new g(this.remote):null,this.initPromise=d.promise()},initialize:function(a){return!this.initPromise||a?this._initialize():this.initPromise},add:function(a){this.index.add(a)},get:function(a,c){function d(a){var d=f.slice(0);b.each(a,function(a){var c;return c=b.some(d,function(b){return e.dupDetector(a,b)}),!c&&d.push(a),d.length0||!this.transport)&&c&&c(f)},clear:function(){this.index.reset()},clearPrefetchCache:function(){this.storage&&this.storage.clear()},clearRemoteCache:function(){this.transport&&g.resetCache()},ttAdapter:function(){return b.bind(this.get,this)}}),e}(this);var j=function(){return{wrapper:'',dropdown:'',dataset:'
',suggestions:'',suggestion:'
'}}(),k=function(){"use strict";var a={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),b.isMsie()&&b.isMsie()<=7&&b.mixin(a.input,{marginTop:"-1px"}),a}(),l=function(){"use strict";function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return b.mixin(c.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),c}(),m=function(){"use strict";function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0,f=a.length;!d&&f>e;e+=1)d=a[e].apply(b,c)===!1;return!d}return d}function g(){var a;return a=window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}function h(a,b){return a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var i=/\s+/,j=g();return{onSync:c,onAsync:b,off:d,trigger:e}}(),n=function(a){"use strict";function c(a,c,d){for(var e,f=[],g=0,h=a.length;h>g;g++)f.push(b.escapeRegExChars(a[g]));return e=d?"\\b("+f.join("|")+")\\b":"("+f.join("|")+")",c?new RegExp(e):new RegExp(e,"i")}var d={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(e){function f(b){var c,d,f;return(c=h.exec(b.data))&&(f=a.createElement(e.tagName),e.className&&(f.className=e.className),d=b.splitText(c.index),d.splitText(c[0].length),f.appendChild(d.cloneNode(!0)),b.parentNode.replaceChild(f,d)),!!c}function g(a,b){for(var c,d=3,e=0;e