From ed7df7b11fbb5e1afb4a2dcb19ab78997ff73eaa Mon Sep 17 00:00:00 2001 From: Senad Uka Date: Mon, 11 Jun 2018 11:09:35 +0200 Subject: [PATCH] Initial commit --- .gitlab-ci.yml | 36 + README.md | 35 + api-wiaas/.bowerrc | 5 + api-wiaas/.eslintrc.json | 40 + api-wiaas/.gitignore | 4 + api-wiaas/.htaccess | 12 + api-wiaas/.jsbeautifyrc | 32 + api-wiaas/Gruntfile.js | 29 + .../application_scripts/updateEndOfLife.php | 7 + api-wiaas/client/css/dist/bundle.min.css | 1 + api-wiaas/client/css/style.less | 100 + api-wiaas/client/img/wiaas_icon.png | Bin 0 -> 1948 bytes api-wiaas/client/img/wiass_bg.jpg | Bin 0 -> 312414 bytes api-wiaas/client/js/app.js | 32 + .../angular-dragdrop/.bower.json | 37 + .../bower_components/angular-dragdrop/LICENSE | 22 + .../angular-dragdrop/README.md | 108 + .../angular-dragdrop/bower.json | 27 + .../angular-dragdrop/karma.conf.js | 28 + .../angular-dragdrop/src/angular-dragdrop.js | 419 + .../src/angular-dragdrop.min.js | 29 + .../angular-route/.bower.json | 21 + .../bower_components/angular-route/LICENSE.md | 21 + .../bower_components/angular-route/README.md | 68 + .../angular-route/angular-route.js | 1216 + .../angular-route/angular-route.min.js | 17 + .../angular-route/angular-route.min.js.map | 8 + .../bower_components/angular-route/bower.json | 10 + .../bower_components/angular-route/index.js | 2 + .../angular-route/package.json | 33 + .../angular-translate-loader-url/.bower.json | 23 + .../angular-translate-loader-url/README.md | 29 + .../angular-translate-loader-url.js | 73 + .../angular-translate-loader-url.min.js | 6 + .../angular-translate-loader-url/bower.json | 12 + .../angular-translate-loader-url/package.json | 24 + .../angular-translate/.bower.json | 23 + .../angular-translate/README.md | 23 + .../angular-translate/angular-translate.js | 3704 ++ .../angular-translate.min.js | 6 + .../angular-translate/bower.json | 12 + .../angular-ui-notification/.bower.json | 49 + .../angular-ui-notification/LICENSE | 21 + .../angular-ui-notification/README.md | 186 + .../angular-ui-notification/bower.json | 39 + .../dist/angular-ui-notification.css | 85 + .../dist/angular-ui-notification.js | 242 + .../dist/angular-ui-notification.min.css | 8 + .../dist/angular-ui-notification.min.js | 8 + .../angular-ui-notification/gulpfile.js | 101 + .../angular-ui-notification/index.js | 5 + .../angular-ui-notification/package.json | 45 + .../protractor_conf.js | 24 + .../src/angular-ui-notification.html | 4 + .../src/angular-ui-notification.js | 233 + .../src/angular-ui-notification.less | 57 + .../angular-ui-notification/src/build.less | 3 + .../angular-ui-sortable/.bower.json | 23 + .../angular-ui-sortable/.travis.yml | 5 + .../angular-ui-sortable/bower.json | 10 + .../angular-ui-sortable/sortable.js | 567 + .../angular-ui-sortable/sortable.min.js | 8 + .../angular-ui-tinymce/.bower.json | 35 + .../angular-ui-tinymce/CONTRIBUTING.md | 45 + .../angular-ui-tinymce/LICENSE | 21 + .../angular-ui-tinymce/README.md | 150 + .../angular-ui-tinymce/bower.json | 25 + .../angular-ui-tinymce/dist/tinymce.min.js | 1 + .../angular-ui-tinymce/src/tinymce.js | 235 + .../js/bower_components/angular/.bower.json | 19 + .../js/bower_components/angular/LICENSE.md | 21 + .../js/bower_components/angular/README.md | 64 + .../bower_components/angular/angular-csp.css | 21 + .../js/bower_components/angular/angular.js | 32982 +++++++++++ .../bower_components/angular/angular.min.js | 330 + .../angular/angular.min.js.gzip | Bin 0 -> 58025 bytes .../angular/angular.min.js.map | 8 + .../js/bower_components/angular/bower.json | 9 + .../js/bower_components/angular/index.js | 2 + .../js/bower_components/angular/package.json | 25 + .../js/bower_components/bootstrap/.bower.json | 45 + .../bower_components/bootstrap/CHANGELOG.md | 5 + .../js/bower_components/bootstrap/Gemfile | 6 + .../bower_components/bootstrap/Gemfile.lock | 43 + .../bower_components/bootstrap/Gruntfile.js | 511 + .../bootstrap/ISSUE_TEMPLATE.md | 22 + .../js/bower_components/bootstrap/LICENSE | 21 + .../js/bower_components/bootstrap/README.md | 142 + .../js/bower_components/bootstrap/bower.json | 34 + .../bootstrap/dist/css/bootstrap-theme.css | 587 + .../dist/css/bootstrap-theme.css.map | 1 + .../dist/css/bootstrap-theme.min.css | 6 + .../dist/css/bootstrap-theme.min.css.map | 1 + .../bootstrap/dist/css/bootstrap.css | 6757 +++ .../bootstrap/dist/css/bootstrap.css.map | 1 + .../bootstrap/dist/css/bootstrap.min.css | 6 + .../bootstrap/dist/css/bootstrap.min.css.map | 1 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../bootstrap/dist/js/bootstrap.js | 2377 + .../bootstrap/dist/js/bootstrap.min.js | 7 + .../bower_components/bootstrap/dist/js/npm.js | 13 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../bootstrap/grunt/.jshintrc | 7 + .../bootstrap/grunt/bs-commonjs-generator.js | 30 + .../grunt/bs-glyphicons-data-generator.js | 42 + .../bootstrap/grunt/bs-lessdoc-parser.js | 237 + .../bootstrap/grunt/bs-raw-files-generator.js | 44 + .../bootstrap/grunt/change-version.js | 109 + .../bootstrap/grunt/configBridge.json | 46 + .../bootstrap/grunt/npm-shrinkwrap.json | 2679 + .../bootstrap/grunt/sauce_browsers.yml | 82 + .../js/bower_components/bootstrap/js/.jscsrc | 42 + .../bower_components/bootstrap/js/.jshintrc | 15 + .../js/bower_components/bootstrap/js/affix.js | 162 + .../js/bower_components/bootstrap/js/alert.js | 94 + .../bower_components/bootstrap/js/button.js | 125 + .../bower_components/bootstrap/js/carousel.js | 237 + .../bower_components/bootstrap/js/collapse.js | 212 + .../bower_components/bootstrap/js/dropdown.js | 165 + .../js/bower_components/bootstrap/js/modal.js | 339 + .../bower_components/bootstrap/js/popover.js | 108 + .../bootstrap/js/scrollspy.js | 172 + .../js/bower_components/bootstrap/js/tab.js | 155 + .../bower_components/bootstrap/js/tooltip.js | 520 + .../bootstrap/js/transition.js | 59 + .../bootstrap/less/.csscomb.json | 304 + .../bootstrap/less/.csslintrc | 19 + .../bootstrap/less/alerts.less | 73 + .../bootstrap/less/badges.less | 66 + .../bootstrap/less/bootstrap.less | 56 + .../bootstrap/less/breadcrumbs.less | 26 + .../bootstrap/less/button-groups.less | 244 + .../bootstrap/less/buttons.less | 166 + .../bootstrap/less/carousel.less | 270 + .../bootstrap/less/close.less | 34 + .../bower_components/bootstrap/less/code.less | 69 + .../bootstrap/less/component-animations.less | 33 + .../bootstrap/less/dropdowns.less | 216 + .../bootstrap/less/forms.less | 613 + .../bootstrap/less/glyphicons.less | 305 + .../bower_components/bootstrap/less/grid.less | 84 + .../bootstrap/less/input-groups.less | 171 + .../bootstrap/less/jumbotron.less | 54 + .../bootstrap/less/labels.less | 64 + .../bootstrap/less/list-group.less | 130 + .../bootstrap/less/media.less | 66 + .../bootstrap/less/mixins.less | 40 + .../bootstrap/less/mixins/alerts.less | 14 + .../less/mixins/background-variant.less | 9 + .../bootstrap/less/mixins/border-radius.less | 18 + .../bootstrap/less/mixins/buttons.less | 65 + .../bootstrap/less/mixins/center-block.less | 7 + .../bootstrap/less/mixins/clearfix.less | 22 + .../bootstrap/less/mixins/forms.less | 85 + .../bootstrap/less/mixins/gradients.less | 59 + .../bootstrap/less/mixins/grid-framework.less | 91 + .../bootstrap/less/mixins/grid.less | 122 + .../bootstrap/less/mixins/hide-text.less | 21 + .../bootstrap/less/mixins/image.less | 33 + .../bootstrap/less/mixins/labels.less | 12 + .../bootstrap/less/mixins/list-group.less | 30 + .../bootstrap/less/mixins/nav-divider.less | 10 + .../less/mixins/nav-vertical-align.less | 9 + .../bootstrap/less/mixins/opacity.less | 8 + .../bootstrap/less/mixins/pagination.less | 24 + .../bootstrap/less/mixins/panels.less | 24 + .../bootstrap/less/mixins/progress-bar.less | 10 + .../bootstrap/less/mixins/reset-filter.less | 8 + .../bootstrap/less/mixins/reset-text.less | 18 + .../bootstrap/less/mixins/resize.less | 6 + .../less/mixins/responsive-visibility.less | 15 + .../bootstrap/less/mixins/size.less | 10 + .../bootstrap/less/mixins/tab-focus.less | 9 + .../bootstrap/less/mixins/table-row.less | 28 + .../bootstrap/less/mixins/text-emphasis.less | 9 + .../bootstrap/less/mixins/text-overflow.less | 8 + .../less/mixins/vendor-prefixes.less | 227 + .../bootstrap/less/modals.less | 150 + .../bootstrap/less/navbar.less | 660 + .../bower_components/bootstrap/less/navs.less | 242 + .../bootstrap/less/normalize.less | 424 + .../bootstrap/less/pager.less | 54 + .../bootstrap/less/pagination.less | 89 + .../bootstrap/less/panels.less | 271 + .../bootstrap/less/popovers.less | 131 + .../bootstrap/less/print.less | 101 + .../bootstrap/less/progress-bars.less | 87 + .../bootstrap/less/responsive-embed.less | 35 + .../bootstrap/less/responsive-utilities.less | 194 + .../bootstrap/less/scaffolding.less | 161 + .../bootstrap/less/tables.less | 234 + .../bootstrap/less/theme.less | 291 + .../bootstrap/less/thumbnails.less | 36 + .../bootstrap/less/tooltip.less | 101 + .../bower_components/bootstrap/less/type.less | 302 + .../bootstrap/less/utilities.less | 55 + .../bootstrap/less/variables.less | 869 + .../bootstrap/less/wells.less | 29 + .../bootstrap/nuget/MyGet.ps1 | 8 + .../bootstrap/nuget/bootstrap.less.nuspec | 28 + .../bootstrap/nuget/bootstrap.nuspec | 28 + .../js/bower_components/bootstrap/package.js | 32 + .../bower_components/bootstrap/package.json | 89 + .../js/bower_components/clipboard/.bower.json | 32 + .../js/bower_components/clipboard/bower.json | 22 + .../bower_components/clipboard/composer.json | 25 + .../clipboard/contributing.md | 28 + .../clipboard/dist/clipboard.js | 939 + .../clipboard/dist/clipboard.min.js | 7 + .../js/bower_components/clipboard/package.js | 12 + .../bower_components/clipboard/package.json | 46 + .../js/bower_components/clipboard/readme.md | 189 + .../clipboard/webpack.config.js | 41 + .../datatables.net-bs/.bower.json | 49 + .../datatables.net-bs/License.txt | 20 + .../datatables.net-bs/Readme.md | 50 + .../datatables.net-bs/bower.json | 38 + .../css/dataTables.bootstrap.css | 184 + .../css/dataTables.bootstrap.min.css | 1 + .../js/dataTables.bootstrap.js | 182 + .../js/dataTables.bootstrap.min.js | 8 + .../datatables.net-responsive-dt/.bower.json | 48 + .../datatables.net-responsive-dt/License.txt | 20 + .../datatables.net-responsive-dt/Readme.md | 50 + .../datatables.net-responsive-dt/bower.json | 37 + .../css/responsive.dataTables.css | 178 + .../css/responsive.dataTables.min.css | 1 + .../datatables.net-responsive/.bower.json | 47 + .../datatables.net-responsive/License.txt | 20 + .../datatables.net-responsive/Readme.md | 50 + .../datatables.net-responsive/bower.json | 36 + .../js/dataTables.responsive.js | 1255 + .../js/dataTables.responsive.min.js | 26 + .../datatables.net/.bower.json | 47 + .../datatables.net/License.txt | 20 + .../bower_components/datatables.net/Readme.md | 50 + .../datatables.net/bower.json | 36 + .../datatables.net/js/jquery.dataTables.js | 15306 +++++ .../js/jquery.dataTables.min.js | 167 + .../flag-icon-css-master/.editorconfig | 11 + .../flag-icon-css-master/.gitignore | 6 + .../flag-icon-css-master/Gruntfile.coffee | 44 + .../flag-icon-css-master/LICENSE | 21 + .../flag-icon-css-master/README.md | 77 + .../flag-icon-css-master/assets/docs.css | 153 + .../flag-icon-css-master/assets/docs.js | 13 + .../flag-icon-css-master/assets/docs.less | 162 + .../flag-icon-css-master/bower.json | 16 + .../flag-icon-css-master/composer.json | 22 + .../flag-icon-css-master/css/flag-icon.css | 1550 + .../css/flag-icon.min.css | 1 + .../flag-icon-css-master/flags/1x1/ad.svg | 152 + .../flag-icon-css-master/flags/1x1/ae.svg | 6 + .../flag-icon-css-master/flags/1x1/af.svg | 83 + .../flag-icon-css-master/flags/1x1/ag.svg | 14 + .../flag-icon-css-master/flags/1x1/ai.svg | 767 + .../flag-icon-css-master/flags/1x1/al.svg | 5 + .../flag-icon-css-master/flags/1x1/am.svg | 5 + .../flag-icon-css-master/flags/1x1/ao.svg | 13 + .../flag-icon-css-master/flags/1x1/aq.svg | 13 + .../flag-icon-css-master/flags/1x1/ar.svg | 31 + .../flag-icon-css-master/flags/1x1/as.svg | 33 + .../flag-icon-css-master/flags/1x1/at.svg | 6 + .../flag-icon-css-master/flags/1x1/au.svg | 9 + .../flag-icon-css-master/flags/1x1/aw.svg | 186 + .../flag-icon-css-master/flags/1x1/ax.svg | 18 + .../flag-icon-css-master/flags/1x1/az.svg | 8 + .../flag-icon-css-master/flags/1x1/ba.svg | 12 + .../flag-icon-css-master/flags/1x1/bb.svg | 6 + .../flag-icon-css-master/flags/1x1/bd.svg | 4 + .../flag-icon-css-master/flags/1x1/be.svg | 7 + .../flag-icon-css-master/flags/1x1/bf.svg | 7 + .../flag-icon-css-master/flags/1x1/bg.svg | 7 + .../flag-icon-css-master/flags/1x1/bh.svg | 11 + .../flag-icon-css-master/flags/1x1/bi.svg | 15 + .../flag-icon-css-master/flags/1x1/bj.svg | 14 + .../flag-icon-css-master/flags/1x1/bl.svg | 7 + .../flag-icon-css-master/flags/1x1/bm.svg | 98 + .../flag-icon-css-master/flags/1x1/bn.svg | 36 + .../flag-icon-css-master/flags/1x1/bo.svg | 685 + .../flag-icon-css-master/flags/1x1/bq.svg | 5 + .../flag-icon-css-master/flags/1x1/br.svg | 45 + .../flag-icon-css-master/flags/1x1/bs.svg | 13 + .../flag-icon-css-master/flags/1x1/bt.svg | 91 + .../flag-icon-css-master/flags/1x1/bv.svg | 13 + .../flag-icon-css-master/flags/1x1/bw.svg | 7 + .../flag-icon-css-master/flags/1x1/by.svg | 59 + .../flag-icon-css-master/flags/1x1/bz.svg | 166 + .../flag-icon-css-master/flags/1x1/ca.svg | 6 + .../flag-icon-css-master/flags/1x1/cc.svg | 19 + .../flag-icon-css-master/flags/1x1/cd.svg | 12 + .../flag-icon-css-master/flags/1x1/cf.svg | 15 + .../flag-icon-css-master/flags/1x1/cg.svg | 12 + .../flag-icon-css-master/flags/1x1/ch.svg | 9 + .../flag-icon-css-master/flags/1x1/ci.svg | 7 + .../flag-icon-css-master/flags/1x1/ck.svg | 9 + .../flag-icon-css-master/flags/1x1/cl.svg | 13 + .../flag-icon-css-master/flags/1x1/cm.svg | 15 + .../flag-icon-css-master/flags/1x1/cn.svg | 11 + .../flag-icon-css-master/flags/1x1/co.svg | 7 + .../flag-icon-css-master/flags/1x1/cr.svg | 7 + .../flag-icon-css-master/flags/1x1/cu.svg | 13 + .../flag-icon-css-master/flags/1x1/cv.svg | 13 + .../flag-icon-css-master/flags/1x1/cw.svg | 14 + .../flag-icon-css-master/flags/1x1/cx.svg | 15 + .../flag-icon-css-master/flags/1x1/cy.svg | 6 + .../flag-icon-css-master/flags/1x1/cz.svg | 12 + .../flag-icon-css-master/flags/1x1/de.svg | 5 + .../flag-icon-css-master/flags/1x1/dj.svg | 13 + .../flag-icon-css-master/flags/1x1/dk.svg | 5 + .../flag-icon-css-master/flags/1x1/dm.svg | 152 + .../flag-icon-css-master/flags/1x1/do.svg | 6745 +++ .../flag-icon-css-master/flags/1x1/dz.svg | 5 + .../flag-icon-css-master/flags/1x1/ec.svg | 143 + .../flag-icon-css-master/flags/1x1/ee.svg | 7 + .../flag-icon-css-master/flags/1x1/eg.svg | 38 + .../flag-icon-css-master/flags/1x1/eh.svg | 15 + .../flag-icon-css-master/flags/1x1/er.svg | 13 + .../flag-icon-css-master/flags/1x1/es.svg | 581 + .../flag-icon-css-master/flags/1x1/et.svg | 14 + .../flag-icon-css-master/flags/1x1/eu.svg | 28 + .../flag-icon-css-master/flags/1x1/fi.svg | 5 + .../flag-icon-css-master/flags/1x1/fj.svg | 126 + .../flag-icon-css-master/flags/1x1/fk.svg | 90 + .../flag-icon-css-master/flags/1x1/fm.svg | 11 + .../flag-icon-css-master/flags/1x1/fo.svg | 12 + .../flag-icon-css-master/flags/1x1/fr.svg | 7 + .../flag-icon-css-master/flags/1x1/ga.svg | 7 + .../flag-icon-css-master/flags/1x1/gb-eng.svg | 5 + .../flag-icon-css-master/flags/1x1/gb-nir.svg | 158 + .../flag-icon-css-master/flags/1x1/gb-sct.svg | 4 + .../flag-icon-css-master/flags/1x1/gb-wls.svg | 9 + .../flag-icon-css-master/flags/1x1/gb.svg | 15 + .../flag-icon-css-master/flags/1x1/gd.svg | 27 + .../flag-icon-css-master/flags/1x1/ge.svg | 6 + .../flag-icon-css-master/flags/1x1/gf.svg | 5 + .../flag-icon-css-master/flags/1x1/gg.svg | 9 + .../flag-icon-css-master/flags/1x1/gh.svg | 6 + .../flag-icon-css-master/flags/1x1/gi.svg | 33 + .../flag-icon-css-master/flags/1x1/gl.svg | 12 + .../flag-icon-css-master/flags/1x1/gm.svg | 9 + .../flag-icon-css-master/flags/1x1/gn.svg | 7 + .../flag-icon-css-master/flags/1x1/gp.svg | 7 + .../flag-icon-css-master/flags/1x1/gq.svg | 31 + .../flag-icon-css-master/flags/1x1/gr.svg | 24 + .../flag-icon-css-master/flags/1x1/gs.svg | 210 + .../flag-icon-css-master/flags/1x1/gt.svg | 204 + .../flag-icon-css-master/flags/1x1/gu.svg | 39 + .../flag-icon-css-master/flags/1x1/gw.svg | 15 + .../flag-icon-css-master/flags/1x1/gy.svg | 9 + .../flag-icon-css-master/flags/1x1/hk.svg | 34 + .../flag-icon-css-master/flags/1x1/hm.svg | 9 + .../flag-icon-css-master/flags/1x1/hn.svg | 18 + .../flag-icon-css-master/flags/1x1/hr.svg | 61 + .../flag-icon-css-master/flags/1x1/ht.svg | 128 + .../flag-icon-css-master/flags/1x1/hu.svg | 7 + .../flag-icon-css-master/flags/1x1/id.svg | 6 + .../flag-icon-css-master/flags/1x1/ie.svg | 7 + .../flag-icon-css-master/flags/1x1/il.svg | 14 + .../flag-icon-css-master/flags/1x1/im.svg | 36 + .../flag-icon-css-master/flags/1x1/in.svg | 25 + .../flag-icon-css-master/flags/1x1/io.svg | 154 + .../flag-icon-css-master/flags/1x1/iq.svg | 10 + .../flag-icon-css-master/flags/1x1/ir.svg | 223 + .../flag-icon-css-master/flags/1x1/is.svg | 12 + .../flag-icon-css-master/flags/1x1/it.svg | 7 + .../flag-icon-css-master/flags/1x1/je.svg | 32 + .../flag-icon-css-master/flags/1x1/jm.svg | 8 + .../flag-icon-css-master/flags/1x1/jo.svg | 16 + .../flag-icon-css-master/flags/1x1/jp.svg | 11 + .../flag-icon-css-master/flags/1x1/ke.svg | 23 + .../flag-icon-css-master/flags/1x1/kg.svg | 15 + .../flag-icon-css-master/flags/1x1/kh.svg | 74 + .../flag-icon-css-master/flags/1x1/ki.svg | 36 + .../flag-icon-css-master/flags/1x1/km.svg | 16 + .../flag-icon-css-master/flags/1x1/kn.svg | 14 + .../flag-icon-css-master/flags/1x1/kp.svg | 15 + .../flag-icon-css-master/flags/1x1/kr.svg | 24 + .../flag-icon-css-master/flags/1x1/kw.svg | 13 + .../flag-icon-css-master/flags/1x1/ky.svg | 70 + .../flag-icon-css-master/flags/1x1/kz.svg | 23 + .../flag-icon-css-master/flags/1x1/la.svg | 12 + .../flag-icon-css-master/flags/1x1/lb.svg | 15 + .../flag-icon-css-master/flags/1x1/lc.svg | 8 + .../flag-icon-css-master/flags/1x1/li.svg | 43 + .../flag-icon-css-master/flags/1x1/lk.svg | 22 + .../flag-icon-css-master/flags/1x1/lr.svg | 14 + .../flag-icon-css-master/flags/1x1/ls.svg | 8 + .../flag-icon-css-master/flags/1x1/lt.svg | 7 + .../flag-icon-css-master/flags/1x1/lu.svg | 5 + .../flag-icon-css-master/flags/1x1/lv.svg | 6 + .../flag-icon-css-master/flags/1x1/ly.svg | 13 + .../flag-icon-css-master/flags/1x1/ma.svg | 4 + .../flag-icon-css-master/flags/1x1/mc.svg | 6 + .../flag-icon-css-master/flags/1x1/md.svg | 73 + .../flag-icon-css-master/flags/1x1/me.svg | 118 + .../flag-icon-css-master/flags/1x1/mf.svg | 7 + .../flag-icon-css-master/flags/1x1/mg.svg | 7 + .../flag-icon-css-master/flags/1x1/mh.svg | 8 + .../flag-icon-css-master/flags/1x1/mk.svg | 5 + .../flag-icon-css-master/flags/1x1/ml.svg | 7 + .../flag-icon-css-master/flags/1x1/mm.svg | 16 + .../flag-icon-css-master/flags/1x1/mn.svg | 13 + .../flag-icon-css-master/flags/1x1/mo.svg | 9 + .../flag-icon-css-master/flags/1x1/mp.svg | 88 + .../flag-icon-css-master/flags/1x1/mq.svg | 7 + .../flag-icon-css-master/flags/1x1/mr.svg | 13 + .../flag-icon-css-master/flags/1x1/ms.svg | 39 + .../flag-icon-css-master/flags/1x1/mt.svg | 50 + .../flag-icon-css-master/flags/1x1/mu.svg | 8 + .../flag-icon-css-master/flags/1x1/mv.svg | 6 + .../flag-icon-css-master/flags/1x1/mw.svg | 15 + .../flag-icon-css-master/flags/1x1/mx.svg | 385 + .../flag-icon-css-master/flags/1x1/my.svg | 15 + .../flag-icon-css-master/flags/1x1/mz.svg | 21 + .../flag-icon-css-master/flags/1x1/na.svg | 18 + .../flag-icon-css-master/flags/1x1/nc.svg | 7 + .../flag-icon-css-master/flags/1x1/ne.svg | 6 + .../flag-icon-css-master/flags/1x1/nf.svg | 11 + .../flag-icon-css-master/flags/1x1/ng.svg | 6 + .../flag-icon-css-master/flags/1x1/ni.svg | 133 + .../flag-icon-css-master/flags/1x1/nl.svg | 7 + .../flag-icon-css-master/flags/1x1/no.svg | 7 + .../flag-icon-css-master/flags/1x1/np.svg | 19 + .../flag-icon-css-master/flags/1x1/nr.svg | 12 + .../flag-icon-css-master/flags/1x1/nu.svg | 26 + .../flag-icon-css-master/flags/1x1/nz.svg | 41 + .../flag-icon-css-master/flags/1x1/om.svg | 128 + .../flag-icon-css-master/flags/1x1/pa.svg | 13 + .../flag-icon-css-master/flags/1x1/pe.svg | 320 + .../flag-icon-css-master/flags/1x1/pf.svg | 32 + .../flag-icon-css-master/flags/1x1/pg.svg | 16 + .../flag-icon-css-master/flags/1x1/ph.svg | 28 + .../flag-icon-css-master/flags/1x1/pk.svg | 15 + .../flag-icon-css-master/flags/1x1/pl.svg | 6 + .../flag-icon-css-master/flags/1x1/pm.svg | 7 + .../flag-icon-css-master/flags/1x1/pn.svg | 69 + .../flag-icon-css-master/flags/1x1/pr.svg | 13 + .../flag-icon-css-master/flags/1x1/ps.svg | 15 + .../flag-icon-css-master/flags/1x1/pt.svg | 57 + .../flag-icon-css-master/flags/1x1/pw.svg | 11 + .../flag-icon-css-master/flags/1x1/py.svg | 157 + .../flag-icon-css-master/flags/1x1/qa.svg | 4 + .../flag-icon-css-master/flags/1x1/re.svg | 7 + .../flag-icon-css-master/flags/1x1/ro.svg | 7 + .../flag-icon-css-master/flags/1x1/rs.svg | 296 + .../flag-icon-css-master/flags/1x1/ru.svg | 7 + .../flag-icon-css-master/flags/1x1/rw.svg | 13 + .../flag-icon-css-master/flags/1x1/sa.svg | 26 + .../flag-icon-css-master/flags/1x1/sb.svg | 13 + .../flag-icon-css-master/flags/1x1/sc.svg | 14 + .../flag-icon-css-master/flags/1x1/sd.svg | 13 + .../flag-icon-css-master/flags/1x1/se.svg | 16 + .../flag-icon-css-master/flags/1x1/sg.svg | 13 + .../flag-icon-css-master/flags/1x1/sh.svg | 81 + .../flag-icon-css-master/flags/1x1/si.svg | 18 + .../flag-icon-css-master/flags/1x1/sj.svg | 7 + .../flag-icon-css-master/flags/1x1/sk.svg | 9 + .../flag-icon-css-master/flags/1x1/sl.svg | 12 + .../flag-icon-css-master/flags/1x1/sm.svg | 92 + .../flag-icon-css-master/flags/1x1/sn.svg | 8 + .../flag-icon-css-master/flags/1x1/so.svg | 11 + .../flag-icon-css-master/flags/1x1/sr.svg | 6 + .../flag-icon-css-master/flags/1x1/ss.svg | 8 + .../flag-icon-css-master/flags/1x1/st.svg | 16 + .../flag-icon-css-master/flags/1x1/sv.svg | 621 + .../flag-icon-css-master/flags/1x1/sx.svg | 56 + .../flag-icon-css-master/flags/1x1/sy.svg | 6 + .../flag-icon-css-master/flags/1x1/sz.svg | 49 + .../flag-icon-css-master/flags/1x1/tc.svg | 80 + .../flag-icon-css-master/flags/1x1/td.svg | 7 + .../flag-icon-css-master/flags/1x1/tf.svg | 15 + .../flag-icon-css-master/flags/1x1/tg.svg | 14 + .../flag-icon-css-master/flags/1x1/th.svg | 7 + .../flag-icon-css-master/flags/1x1/tj.svg | 26 + .../flag-icon-css-master/flags/1x1/tk.svg | 5 + .../flag-icon-css-master/flags/1x1/tl.svg | 13 + .../flag-icon-css-master/flags/1x1/tm.svg | 221 + .../flag-icon-css-master/flags/1x1/tn.svg | 13 + .../flag-icon-css-master/flags/1x1/to.svg | 10 + .../flag-icon-css-master/flags/1x1/tr.svg | 8 + .../flag-icon-css-master/flags/1x1/tt.svg | 7 + .../flag-icon-css-master/flags/1x1/tv.svg | 29 + .../flag-icon-css-master/flags/1x1/tw.svg | 14 + .../flag-icon-css-master/flags/1x1/tz.svg | 15 + .../flag-icon-css-master/flags/1x1/ua.svg | 6 + .../flag-icon-css-master/flags/1x1/ug.svg | 30 + .../flag-icon-css-master/flags/1x1/um.svg | 45 + .../flag-icon-css-master/flags/1x1/un.svg | 16 + .../flag-icon-css-master/flags/1x1/us.svg | 18 + .../flag-icon-css-master/flags/1x1/uy.svg | 28 + .../flag-icon-css-master/flags/1x1/uz.svg | 30 + .../flag-icon-css-master/flags/1x1/va.svg | 483 + .../flag-icon-css-master/flags/1x1/vc.svg | 10 + .../flag-icon-css-master/flags/1x1/ve.svg | 26 + .../flag-icon-css-master/flags/1x1/vg.svg | 142 + .../flag-icon-css-master/flags/1x1/vi.svg | 32 + .../flag-icon-css-master/flags/1x1/vn.svg | 11 + .../flag-icon-css-master/flags/1x1/vu.svg | 18 + .../flag-icon-css-master/flags/1x1/wf.svg | 7 + .../flag-icon-css-master/flags/1x1/ws.svg | 9 + .../flag-icon-css-master/flags/1x1/ye.svg | 7 + .../flag-icon-css-master/flags/1x1/yt.svg | 7 + .../flag-icon-css-master/flags/1x1/za.svg | 17 + .../flag-icon-css-master/flags/1x1/zm.svg | 27 + .../flag-icon-css-master/flags/1x1/zw.svg | 26 + .../flag-icon-css-master/flags/4x3/ad.svg | 151 + .../flag-icon-css-master/flags/4x3/ae.svg | 6 + .../flag-icon-css-master/flags/4x3/af.svg | 83 + .../flag-icon-css-master/flags/4x3/ag.svg | 15 + .../flag-icon-css-master/flags/4x3/ai.svg | 767 + .../flag-icon-css-master/flags/4x3/al.svg | 5 + .../flag-icon-css-master/flags/4x3/am.svg | 5 + .../flag-icon-css-master/flags/4x3/ao.svg | 13 + .../flag-icon-css-master/flags/4x3/aq.svg | 6 + .../flag-icon-css-master/flags/4x3/ar.svg | 32 + .../flag-icon-css-master/flags/4x3/as.svg | 33 + .../flag-icon-css-master/flags/4x3/at.svg | 6 + .../flag-icon-css-master/flags/4x3/au.svg | 9 + .../flag-icon-css-master/flags/4x3/aw.svg | 186 + .../flag-icon-css-master/flags/4x3/ax.svg | 18 + .../flag-icon-css-master/flags/4x3/az.svg | 8 + .../flag-icon-css-master/flags/4x3/ba.svg | 12 + .../flag-icon-css-master/flags/4x3/bb.svg | 6 + .../flag-icon-css-master/flags/4x3/bd.svg | 4 + .../flag-icon-css-master/flags/4x3/be.svg | 7 + .../flag-icon-css-master/flags/4x3/bf.svg | 7 + .../flag-icon-css-master/flags/4x3/bg.svg | 7 + .../flag-icon-css-master/flags/4x3/bh.svg | 11 + .../flag-icon-css-master/flags/4x3/bi.svg | 15 + .../flag-icon-css-master/flags/4x3/bj.svg | 14 + .../flag-icon-css-master/flags/4x3/bl.svg | 7 + .../flag-icon-css-master/flags/4x3/bm.svg | 99 + .../flag-icon-css-master/flags/4x3/bn.svg | 36 + .../flag-icon-css-master/flags/4x3/bo.svg | 686 + .../flag-icon-css-master/flags/4x3/bq.svg | 5 + .../flag-icon-css-master/flags/4x3/br.svg | 45 + .../flag-icon-css-master/flags/4x3/bs.svg | 13 + .../flag-icon-css-master/flags/4x3/bt.svg | 91 + .../flag-icon-css-master/flags/4x3/bv.svg | 13 + .../flag-icon-css-master/flags/4x3/bw.svg | 7 + .../flag-icon-css-master/flags/4x3/by.svg | 61 + .../flag-icon-css-master/flags/4x3/bz.svg | 166 + .../flag-icon-css-master/flags/4x3/ca.svg | 6 + .../flag-icon-css-master/flags/4x3/cc.svg | 19 + .../flag-icon-css-master/flags/4x3/cd.svg | 5 + .../flag-icon-css-master/flags/4x3/cf.svg | 15 + .../flag-icon-css-master/flags/4x3/cg.svg | 12 + .../flag-icon-css-master/flags/4x3/ch.svg | 9 + .../flag-icon-css-master/flags/4x3/ci.svg | 7 + .../flag-icon-css-master/flags/4x3/ck.svg | 9 + .../flag-icon-css-master/flags/4x3/cl.svg | 13 + .../flag-icon-css-master/flags/4x3/cm.svg | 15 + .../flag-icon-css-master/flags/4x3/cn.svg | 11 + .../flag-icon-css-master/flags/4x3/co.svg | 7 + .../flag-icon-css-master/flags/4x3/cr.svg | 7 + .../flag-icon-css-master/flags/4x3/cu.svg | 13 + .../flag-icon-css-master/flags/4x3/cv.svg | 13 + .../flag-icon-css-master/flags/4x3/cw.svg | 14 + .../flag-icon-css-master/flags/4x3/cx.svg | 15 + .../flag-icon-css-master/flags/4x3/cy.svg | 6 + .../flag-icon-css-master/flags/4x3/cz.svg | 12 + .../flag-icon-css-master/flags/4x3/de.svg | 5 + .../flag-icon-css-master/flags/4x3/dj.svg | 13 + .../flag-icon-css-master/flags/4x3/dk.svg | 5 + .../flag-icon-css-master/flags/4x3/dm.svg | 152 + .../flag-icon-css-master/flags/4x3/do.svg | 6745 +++ .../flag-icon-css-master/flags/4x3/dz.svg | 5 + .../flag-icon-css-master/flags/4x3/ec.svg | 143 + .../flag-icon-css-master/flags/4x3/ee.svg | 7 + .../flag-icon-css-master/flags/4x3/eg.svg | 38 + .../flag-icon-css-master/flags/4x3/eh.svg | 15 + .../flag-icon-css-master/flags/4x3/er.svg | 8 + .../flag-icon-css-master/flags/4x3/es.svg | 581 + .../flag-icon-css-master/flags/4x3/et.svg | 14 + .../flag-icon-css-master/flags/4x3/eu.svg | 28 + .../flag-icon-css-master/flags/4x3/fi.svg | 5 + .../flag-icon-css-master/flags/4x3/fj.svg | 126 + .../flag-icon-css-master/flags/4x3/fk.svg | 90 + .../flag-icon-css-master/flags/4x3/fm.svg | 11 + .../flag-icon-css-master/flags/4x3/fo.svg | 12 + .../flag-icon-css-master/flags/4x3/fr.svg | 7 + .../flag-icon-css-master/flags/4x3/ga.svg | 7 + .../flag-icon-css-master/flags/4x3/gb-eng.svg | 5 + .../flag-icon-css-master/flags/4x3/gb-nir.svg | 158 + .../flag-icon-css-master/flags/4x3/gb-sct.svg | 4 + .../flag-icon-css-master/flags/4x3/gb-wls.svg | 9 + .../flag-icon-css-master/flags/4x3/gb.svg | 15 + .../flag-icon-css-master/flags/4x3/gd.svg | 27 + .../flag-icon-css-master/flags/4x3/ge.svg | 6 + .../flag-icon-css-master/flags/4x3/gf.svg | 5 + .../flag-icon-css-master/flags/4x3/gg.svg | 9 + .../flag-icon-css-master/flags/4x3/gh.svg | 6 + .../flag-icon-css-master/flags/4x3/gi.svg | 33 + .../flag-icon-css-master/flags/4x3/gl.svg | 12 + .../flag-icon-css-master/flags/4x3/gm.svg | 14 + .../flag-icon-css-master/flags/4x3/gn.svg | 7 + .../flag-icon-css-master/flags/4x3/gp.svg | 7 + .../flag-icon-css-master/flags/4x3/gq.svg | 31 + .../flag-icon-css-master/flags/4x3/gr.svg | 22 + .../flag-icon-css-master/flags/4x3/gs.svg | 205 + .../flag-icon-css-master/flags/4x3/gt.svg | 204 + .../flag-icon-css-master/flags/4x3/gu.svg | 39 + .../flag-icon-css-master/flags/4x3/gw.svg | 13 + .../flag-icon-css-master/flags/4x3/gy.svg | 9 + .../flag-icon-css-master/flags/4x3/hk.svg | 34 + .../flag-icon-css-master/flags/4x3/hm.svg | 9 + .../flag-icon-css-master/flags/4x3/hn.svg | 18 + .../flag-icon-css-master/flags/4x3/hr.svg | 61 + .../flag-icon-css-master/flags/4x3/ht.svg | 128 + .../flag-icon-css-master/flags/4x3/hu.svg | 7 + .../flag-icon-css-master/flags/4x3/id.svg | 6 + .../flag-icon-css-master/flags/4x3/ie.svg | 7 + .../flag-icon-css-master/flags/4x3/il.svg | 14 + .../flag-icon-css-master/flags/4x3/im.svg | 36 + .../flag-icon-css-master/flags/4x3/in.svg | 25 + .../flag-icon-css-master/flags/4x3/io.svg | 152 + .../flag-icon-css-master/flags/4x3/iq.svg | 10 + .../flag-icon-css-master/flags/4x3/ir.svg | 223 + .../flag-icon-css-master/flags/4x3/is.svg | 12 + .../flag-icon-css-master/flags/4x3/it.svg | 7 + .../flag-icon-css-master/flags/4x3/je.svg | 32 + .../flag-icon-css-master/flags/4x3/jm.svg | 8 + .../flag-icon-css-master/flags/4x3/jo.svg | 16 + .../flag-icon-css-master/flags/4x3/jp.svg | 11 + .../flag-icon-css-master/flags/4x3/ke.svg | 23 + .../flag-icon-css-master/flags/4x3/kg.svg | 15 + .../flag-icon-css-master/flags/4x3/kh.svg | 74 + .../flag-icon-css-master/flags/4x3/ki.svg | 36 + .../flag-icon-css-master/flags/4x3/km.svg | 16 + .../flag-icon-css-master/flags/4x3/kn.svg | 14 + .../flag-icon-css-master/flags/4x3/kp.svg | 15 + .../flag-icon-css-master/flags/4x3/kr.svg | 24 + .../flag-icon-css-master/flags/4x3/kw.svg | 13 + .../flag-icon-css-master/flags/4x3/ky.svg | 65 + .../flag-icon-css-master/flags/4x3/kz.svg | 23 + .../flag-icon-css-master/flags/4x3/la.svg | 12 + .../flag-icon-css-master/flags/4x3/lb.svg | 15 + .../flag-icon-css-master/flags/4x3/lc.svg | 8 + .../flag-icon-css-master/flags/4x3/li.svg | 43 + .../flag-icon-css-master/flags/4x3/lk.svg | 22 + .../flag-icon-css-master/flags/4x3/lr.svg | 14 + .../flag-icon-css-master/flags/4x3/ls.svg | 8 + .../flag-icon-css-master/flags/4x3/lt.svg | 7 + .../flag-icon-css-master/flags/4x3/lu.svg | 5 + .../flag-icon-css-master/flags/4x3/lv.svg | 6 + .../flag-icon-css-master/flags/4x3/ly.svg | 13 + .../flag-icon-css-master/flags/4x3/ma.svg | 4 + .../flag-icon-css-master/flags/4x3/mc.svg | 6 + .../flag-icon-css-master/flags/4x3/md.svg | 72 + .../flag-icon-css-master/flags/4x3/me.svg | 118 + .../flag-icon-css-master/flags/4x3/mf.svg | 7 + .../flag-icon-css-master/flags/4x3/mg.svg | 7 + .../flag-icon-css-master/flags/4x3/mh.svg | 7 + .../flag-icon-css-master/flags/4x3/mk.svg | 5 + .../flag-icon-css-master/flags/4x3/ml.svg | 7 + .../flag-icon-css-master/flags/4x3/mm.svg | 16 + .../flag-icon-css-master/flags/4x3/mn.svg | 13 + .../flag-icon-css-master/flags/4x3/mo.svg | 9 + .../flag-icon-css-master/flags/4x3/mp.svg | 88 + .../flag-icon-css-master/flags/4x3/mq.svg | 7 + .../flag-icon-css-master/flags/4x3/mr.svg | 13 + .../flag-icon-css-master/flags/4x3/ms.svg | 39 + .../flag-icon-css-master/flags/4x3/mt.svg | 49 + .../flag-icon-css-master/flags/4x3/mu.svg | 8 + .../flag-icon-css-master/flags/4x3/mv.svg | 6 + .../flag-icon-css-master/flags/4x3/mw.svg | 12 + .../flag-icon-css-master/flags/4x3/mx.svg | 385 + .../flag-icon-css-master/flags/4x3/my.svg | 15 + .../flag-icon-css-master/flags/4x3/mz.svg | 21 + .../flag-icon-css-master/flags/4x3/na.svg | 18 + .../flag-icon-css-master/flags/4x3/nc.svg | 7 + .../flag-icon-css-master/flags/4x3/ne.svg | 6 + .../flag-icon-css-master/flags/4x3/nf.svg | 9 + .../flag-icon-css-master/flags/4x3/ng.svg | 6 + .../flag-icon-css-master/flags/4x3/ni.svg | 133 + .../flag-icon-css-master/flags/4x3/nl.svg | 7 + .../flag-icon-css-master/flags/4x3/no.svg | 7 + .../flag-icon-css-master/flags/4x3/np.svg | 14 + .../flag-icon-css-master/flags/4x3/nr.svg | 12 + .../flag-icon-css-master/flags/4x3/nu.svg | 26 + .../flag-icon-css-master/flags/4x3/nz.svg | 41 + .../flag-icon-css-master/flags/4x3/om.svg | 128 + .../flag-icon-css-master/flags/4x3/pa.svg | 14 + .../flag-icon-css-master/flags/4x3/pe.svg | 320 + .../flag-icon-css-master/flags/4x3/pf.svg | 33 + .../flag-icon-css-master/flags/4x3/pg.svg | 9 + .../flag-icon-css-master/flags/4x3/ph.svg | 28 + .../flag-icon-css-master/flags/4x3/pk.svg | 15 + .../flag-icon-css-master/flags/4x3/pl.svg | 6 + .../flag-icon-css-master/flags/4x3/pm.svg | 7 + .../flag-icon-css-master/flags/4x3/pn.svg | 62 + .../flag-icon-css-master/flags/4x3/pr.svg | 13 + .../flag-icon-css-master/flags/4x3/ps.svg | 15 + .../flag-icon-css-master/flags/4x3/pt.svg | 57 + .../flag-icon-css-master/flags/4x3/pw.svg | 11 + .../flag-icon-css-master/flags/4x3/py.svg | 157 + .../flag-icon-css-master/flags/4x3/qa.svg | 4 + .../flag-icon-css-master/flags/4x3/re.svg | 7 + .../flag-icon-css-master/flags/4x3/ro.svg | 7 + .../flag-icon-css-master/flags/4x3/rs.svg | 292 + .../flag-icon-css-master/flags/4x3/ru.svg | 7 + .../flag-icon-css-master/flags/4x3/rw.svg | 13 + .../flag-icon-css-master/flags/4x3/sa.svg | 26 + .../flag-icon-css-master/flags/4x3/sb.svg | 13 + .../flag-icon-css-master/flags/4x3/sc.svg | 14 + .../flag-icon-css-master/flags/4x3/sd.svg | 13 + .../flag-icon-css-master/flags/4x3/se.svg | 16 + .../flag-icon-css-master/flags/4x3/sg.svg | 13 + .../flag-icon-css-master/flags/4x3/sh.svg | 76 + .../flag-icon-css-master/flags/4x3/si.svg | 18 + .../flag-icon-css-master/flags/4x3/sj.svg | 7 + .../flag-icon-css-master/flags/4x3/sk.svg | 9 + .../flag-icon-css-master/flags/4x3/sl.svg | 7 + .../flag-icon-css-master/flags/4x3/sm.svg | 92 + .../flag-icon-css-master/flags/4x3/sn.svg | 8 + .../flag-icon-css-master/flags/4x3/so.svg | 11 + .../flag-icon-css-master/flags/4x3/sr.svg | 6 + .../flag-icon-css-master/flags/4x3/ss.svg | 8 + .../flag-icon-css-master/flags/4x3/st.svg | 16 + .../flag-icon-css-master/flags/4x3/sv.svg | 621 + .../flag-icon-css-master/flags/4x3/sx.svg | 56 + .../flag-icon-css-master/flags/4x3/sy.svg | 6 + .../flag-icon-css-master/flags/4x3/sz.svg | 49 + .../flag-icon-css-master/flags/4x3/tc.svg | 73 + .../flag-icon-css-master/flags/4x3/td.svg | 7 + .../flag-icon-css-master/flags/4x3/tf.svg | 15 + .../flag-icon-css-master/flags/4x3/tg.svg | 14 + .../flag-icon-css-master/flags/4x3/th.svg | 7 + .../flag-icon-css-master/flags/4x3/tj.svg | 22 + .../flag-icon-css-master/flags/4x3/tk.svg | 5 + .../flag-icon-css-master/flags/4x3/tl.svg | 13 + .../flag-icon-css-master/flags/4x3/tm.svg | 221 + .../flag-icon-css-master/flags/4x3/tn.svg | 13 + .../flag-icon-css-master/flags/4x3/to.svg | 10 + .../flag-icon-css-master/flags/4x3/tr.svg | 8 + .../flag-icon-css-master/flags/4x3/tt.svg | 5 + .../flag-icon-css-master/flags/4x3/tv.svg | 29 + .../flag-icon-css-master/flags/4x3/tw.svg | 14 + .../flag-icon-css-master/flags/4x3/tz.svg | 13 + .../flag-icon-css-master/flags/4x3/ua.svg | 6 + .../flag-icon-css-master/flags/4x3/ug.svg | 30 + .../flag-icon-css-master/flags/4x3/um.svg | 45 + .../flag-icon-css-master/flags/4x3/un.svg | 16 + .../flag-icon-css-master/flags/4x3/us.svg | 18 + .../flag-icon-css-master/flags/4x3/uy.svg | 28 + .../flag-icon-css-master/flags/4x3/uz.svg | 30 + .../flag-icon-css-master/flags/4x3/va.svg | 483 + .../flag-icon-css-master/flags/4x3/vc.svg | 8 + .../flag-icon-css-master/flags/4x3/ve.svg | 26 + .../flag-icon-css-master/flags/4x3/vg.svg | 143 + .../flag-icon-css-master/flags/4x3/vi.svg | 32 + .../flag-icon-css-master/flags/4x3/vn.svg | 11 + .../flag-icon-css-master/flags/4x3/vu.svg | 18 + .../flag-icon-css-master/flags/4x3/wf.svg | 7 + .../flag-icon-css-master/flags/4x3/ws.svg | 9 + .../flag-icon-css-master/flags/4x3/ye.svg | 7 + .../flag-icon-css-master/flags/4x3/yt.svg | 7 + .../flag-icon-css-master/flags/4x3/za.svg | 17 + .../flag-icon-css-master/flags/4x3/zm.svg | 27 + .../flag-icon-css-master/flags/4x3/zw.svg | 26 + .../flag-icon-css-master/index.html | 504 + .../less/flag-icon-base.less | 28 + .../less/flag-icon-list.less | 249 + .../less/flag-icon-more.less | 6 + .../flag-icon-css-master/less/flag-icon.less | 4 + .../flag-icon-css-master/less/variables.less | 3 + .../flag-icon-css-master/package.json | 22 + .../sass/_flag-icon-base.scss | 28 + .../sass/_flag-icon-list.scss | 249 + .../sass/_flag-icon-more.scss | 6 + .../flag-icon-css-master/sass/_variables.scss | 3 + .../flag-icon-css-master/sass/flag-icon.scss | 4 + .../js/bower_components/jquery-ui/AUTHORS.txt | 333 + .../js/bower_components/jquery-ui/LICENSE.txt | 43 + .../jquery-ui/external/jquery/jquery.js | 11008 ++++ .../ui-bg_diagonals-small_40_db4865_40x40.png | Bin 0 -> 332 bytes .../ui-bg_diagonals-small_50_93c3cd_40x40.png | Bin 0 -> 333 bytes .../ui-bg_diagonals-small_50_ff3853_40x40.png | Bin 0 -> 330 bytes .../ui-bg_diagonals-small_75_ccd232_40x40.png | Bin 0 -> 333 bytes .../ui-bg_diagonals-thick_90_eeeeee_40x40.png | Bin 0 -> 312 bytes .../ui-bg_dots-medium_80_ffff38_4x4.png | Bin 0 -> 225 bytes .../images/ui-bg_dots-small_35_35414f_2x2.png | Bin 0 -> 223 bytes .../images/ui-bg_glass_100_e4f1fb_1x400.png | Bin 0 -> 350 bytes .../images/ui-bg_glass_50_3baae3_1x400.png | Bin 0 -> 336 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 335 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 207 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_80_d7ebf9_1x400.png | Bin 0 -> 346 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_highlight-hard_100_f2f5f7_1x100.png | Bin 0 -> 332 bytes .../ui-bg_highlight-hard_70_000000_1x100.png | Bin 0 -> 249 bytes .../ui-bg_highlight-soft_100_deedf7_1x100.png | Bin 0 -> 387 bytes .../ui-bg_highlight-soft_25_ffef8f_1x100.png | Bin 0 -> 309 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 280 bytes .../ui-bg_white-lines_85_f7f7ba_40x100.png | Bin 0 -> 364 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_2694e8_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_3d80b3_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_72a7cf_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 6999 bytes .../images/ui-icons_88a206_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_c02669_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_e1e463_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffeb33_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../js/bower_components/jquery-ui/index.html | 559 + .../bower_components/jquery-ui/jquery-ui.css | 1312 + .../bower_components/jquery-ui/jquery-ui.js | 18706 ++++++ .../jquery-ui/jquery-ui.min.css | 7 + .../jquery-ui/jquery-ui.min.js | 13 + .../jquery-ui/jquery-ui.structure.css | 886 + .../jquery-ui/jquery-ui.structure.min.css | 5 + .../jquery-ui/jquery-ui.theme.css | 443 + .../jquery-ui/jquery-ui.theme.min.css | 5 + .../bower_components/jquery-ui/package.json | 74 + .../js/bower_components/jquery/.bower.json | 26 + .../js/bower_components/jquery/AUTHORS.txt | 295 + .../js/bower_components/jquery/LICENSE.txt | 36 + .../js/bower_components/jquery/README.md | 65 + .../js/bower_components/jquery/bower.json | 14 + .../js/bower_components/jquery/dist/core.js | 482 + .../js/bower_components/jquery/dist/jquery.js | 10220 ++++ .../jquery/dist/jquery.min.js | 4 + .../jquery/dist/jquery.min.map | 1 + .../jquery/dist/jquery.slim.js | 8107 +++ .../jquery/dist/jquery.slim.min.js | 4 + .../jquery/dist/jquery.slim.min.map | 1 + .../jquery/external/sizzle/LICENSE.txt | 36 + .../jquery/external/sizzle/dist/sizzle.js | 2272 + .../jquery/external/sizzle/dist/sizzle.min.js | 3 + .../external/sizzle/dist/sizzle.min.map | 1 + .../jquery/src/.eslintrc.json | 18 + .../js/bower_components/jquery/src/ajax.js | 855 + .../bower_components/jquery/src/ajax/jsonp.js | 102 + .../bower_components/jquery/src/ajax/load.js | 76 + .../jquery/src/ajax/parseXML.js | 30 + .../jquery/src/ajax/script.js | 77 + .../jquery/src/ajax/var/location.js | 5 + .../jquery/src/ajax/var/nonce.js | 7 + .../jquery/src/ajax/var/rquery.js | 5 + .../bower_components/jquery/src/ajax/xhr.js | 169 + .../bower_components/jquery/src/attributes.js | 13 + .../jquery/src/attributes/attr.js | 140 + .../jquery/src/attributes/classes.js | 174 + .../jquery/src/attributes/prop.js | 143 + .../jquery/src/attributes/support.js | 33 + .../jquery/src/attributes/val.js | 188 + .../bower_components/jquery/src/callbacks.js | 234 + .../js/bower_components/jquery/src/core.js | 482 + .../jquery/src/core/DOMEval.js | 16 + .../jquery/src/core/access.js | 70 + .../bower_components/jquery/src/core/init.js | 127 + .../jquery/src/core/parseHTML.js | 65 + .../jquery/src/core/ready-no-deferred.js | 105 + .../bower_components/jquery/src/core/ready.js | 95 + .../jquery/src/core/readyException.js | 13 + .../jquery/src/core/stripAndCollapse.js | 14 + .../jquery/src/core/support.js | 20 + .../jquery/src/core/var/rsingleTag.js | 6 + .../js/bower_components/jquery/src/css.js | 426 + .../jquery/src/css/addGetHookIf.js | 26 + .../jquery/src/css/adjustCSS.js | 71 + .../bower_components/jquery/src/css/curCSS.js | 59 + .../jquery/src/css/hiddenVisibleSelectors.js | 15 + .../jquery/src/css/showHide.js | 105 + .../jquery/src/css/support.js | 89 + .../jquery/src/css/var/cssExpand.js | 5 + .../jquery/src/css/var/getStyles.js | 17 + .../jquery/src/css/var/isHiddenWithinTree.js | 34 + .../jquery/src/css/var/rmargin.js | 5 + .../jquery/src/css/var/rnumnonpx.js | 7 + .../jquery/src/css/var/swap.js | 26 + .../js/bower_components/jquery/src/data.js | 179 + .../bower_components/jquery/src/data/Data.js | 161 + .../jquery/src/data/var/acceptData.js | 19 + .../jquery/src/data/var/dataPriv.js | 7 + .../jquery/src/data/var/dataUser.js | 7 + .../bower_components/jquery/src/deferred.js | 389 + .../jquery/src/deferred/exceptionHook.js | 21 + .../bower_components/jquery/src/deprecated.js | 30 + .../bower_components/jquery/src/dimensions.js | 56 + .../js/bower_components/jquery/src/effects.js | 693 + .../jquery/src/effects/Tween.js | 123 + .../jquery/src/effects/animatedSelector.js | 15 + .../js/bower_components/jquery/src/event.js | 745 + .../bower_components/jquery/src/event/ajax.js | 22 + .../jquery/src/event/alias.js | 29 + .../jquery/src/event/focusin.js | 55 + .../jquery/src/event/support.js | 11 + .../jquery/src/event/trigger.js | 185 + .../jquery/src/exports/amd.js | 26 + .../jquery/src/exports/global.js | 34 + .../js/bower_components/jquery/src/jquery.js | 41 + .../jquery/src/manipulation.js | 486 + .../jquery/src/manipulation/_evalUrl.js | 23 + .../jquery/src/manipulation/buildFragment.js | 104 + .../jquery/src/manipulation/getAll.js | 31 + .../jquery/src/manipulation/setGlobalEval.js | 22 + .../jquery/src/manipulation/support.js | 35 + .../src/manipulation/var/rcheckableType.js | 5 + .../src/manipulation/var/rscriptType.js | 5 + .../jquery/src/manipulation/var/rtagName.js | 5 + .../jquery/src/manipulation/wrapMap.js | 29 + .../js/bower_components/jquery/src/offset.js | 232 + .../js/bower_components/jquery/src/queue.js | 145 + .../jquery/src/queue/delay.js | 24 + .../jquery/src/selector-native.js | 237 + .../jquery/src/selector-sizzle.js | 19 + .../bower_components/jquery/src/selector.js | 3 + .../bower_components/jquery/src/serialize.js | 130 + .../bower_components/jquery/src/traversing.js | 178 + .../jquery/src/traversing/findFilter.js | 106 + .../jquery/src/traversing/var/dir.js | 22 + .../src/traversing/var/rneedsContext.js | 8 + .../jquery/src/traversing/var/siblings.js | 17 + .../jquery/src/var/ObjectFunctionString.js | 7 + .../js/bower_components/jquery/src/var/arr.js | 5 + .../jquery/src/var/class2type.js | 6 + .../bower_components/jquery/src/var/concat.js | 7 + .../jquery/src/var/document.js | 5 + .../jquery/src/var/documentElement.js | 7 + .../jquery/src/var/fnToString.js | 7 + .../jquery/src/var/getProto.js | 5 + .../bower_components/jquery/src/var/hasOwn.js | 7 + .../jquery/src/var/indexOf.js | 7 + .../bower_components/jquery/src/var/pnum.js | 5 + .../bower_components/jquery/src/var/push.js | 7 + .../jquery/src/var/rcssNum.js | 9 + .../jquery/src/var/rnothtmlwhite.js | 8 + .../bower_components/jquery/src/var/slice.js | 7 + .../jquery/src/var/support.js | 6 + .../jquery/src/var/toString.js | 7 + .../js/bower_components/jquery/src/wrap.js | 77 + .../js/bower_components/less/.bower.json | 36 + .../js/bower_components/less/bower.json | 24 + .../js/bower_components/less/browser.js | 1 + .../js/bower_components/less/dist/less.js | 10832 ++++ .../js/bower_components/less/dist/less.min.js | 17 + .../client/js/bower_components/less/index.js | 1 + .../ng-file-upload/.bower.json | 25 + .../bower_components/ng-file-upload/.versions | 4 + .../ng-file-upload/FileAPI.flash.swf | Bin 0 -> 71214 bytes .../ng-file-upload/FileAPI.js | 4313 ++ .../ng-file-upload/FileAPI.min.js | 6 + .../bower_components/ng-file-upload/LICENSE | 20 + .../bower_components/ng-file-upload/README.md | 5 + .../ng-file-upload/bower.json | 14 + .../ng-file-upload/ng-file-upload-all.js | 2898 + .../ng-file-upload/ng-file-upload-all.min.js | 3 + .../ng-file-upload/ng-file-upload-shim.js | 421 + .../ng-file-upload/ng-file-upload-shim.min.js | 2 + .../ng-file-upload/ng-file-upload.js | 2476 + .../ng-file-upload/ng-file-upload.min.js | 3 + .../ng-file-upload/package.js | 12 + .../bower_components/ngclipboard/.bower.json | 36 + .../ngclipboard/.editorconfig | 16 + .../bower_components/ngclipboard/.gitignore | 2 + .../js/bower_components/ngclipboard/.jscsrc | 7 + .../js/bower_components/ngclipboard/.jshintrc | 18 + .../bower_components/ngclipboard/.travis.yml | 6 + .../bower_components/ngclipboard/Gruntfile.js | 89 + .../js/bower_components/ngclipboard/LICENSE | 22 + .../bower_components/ngclipboard/bower.json | 26 + .../ngclipboard/contributing.md | 32 + .../ngclipboard/dist/ngclipboard.js | 53 + .../ngclipboard/dist/ngclipboard.min.js | 4 + .../bower_components/ngclipboard/package.json | 51 + .../ngclipboard/src/.jshintrc | 20 + .../ngclipboard/src/ngclipboard.js | 50 + .../bower_components/ngclipboard/test/test.js | 1 + .../js/bower_components/tinymce/.bower.json | 31 + .../js/bower_components/tinymce/bower.json | 21 + .../tinymce/jquery.tinymce.js | 377 + .../tinymce/jquery.tinymce.min.js | 1 + .../js/bower_components/tinymce/license.txt | 504 + .../tinymce/plugins/advlist/index.js | 7 + .../tinymce/plugins/advlist/plugin.js | 139 + .../tinymce/plugins/advlist/plugin.min.js | 1 + .../tinymce/plugins/anchor/index.js | 7 + .../tinymce/plugins/anchor/plugin.js | 91 + .../tinymce/plugins/anchor/plugin.min.js | 1 + .../tinymce/plugins/autolink/index.js | 7 + .../tinymce/plugins/autolink/plugin.js | 209 + .../tinymce/plugins/autolink/plugin.min.js | 1 + .../tinymce/plugins/autoresize/index.js | 7 + .../tinymce/plugins/autoresize/plugin.js | 162 + .../tinymce/plugins/autoresize/plugin.min.js | 1 + .../tinymce/plugins/autosave/index.js | 7 + .../tinymce/plugins/autosave/plugin.js | 165 + .../tinymce/plugins/autosave/plugin.min.js | 1 + .../tinymce/plugins/bbcode/index.js | 7 + .../tinymce/plugins/bbcode/plugin.js | 123 + .../tinymce/plugins/bbcode/plugin.min.js | 1 + .../tinymce/plugins/charmap/index.js | 7 + .../tinymce/plugins/charmap/plugin.js | 466 + .../tinymce/plugins/charmap/plugin.min.js | 1 + .../tinymce/plugins/code/index.js | 7 + .../tinymce/plugins/code/plugin.js | 60 + .../tinymce/plugins/code/plugin.min.js | 1 + .../tinymce/plugins/codesample/css/prism.css | 138 + .../tinymce/plugins/codesample/index.js | 7 + .../tinymce/plugins/codesample/plugin.js | 1326 + .../tinymce/plugins/codesample/plugin.min.js | 1 + .../tinymce/plugins/colorpicker/index.js | 7 + .../tinymce/plugins/colorpicker/plugin.js | 112 + .../tinymce/plugins/colorpicker/plugin.min.js | 1 + .../tinymce/plugins/contextmenu/index.js | 7 + .../tinymce/plugins/contextmenu/plugin.js | 116 + .../tinymce/plugins/contextmenu/plugin.min.js | 1 + .../tinymce/plugins/directionality/index.js | 7 + .../tinymce/plugins/directionality/plugin.js | 64 + .../plugins/directionality/plugin.min.js | 1 + .../plugins/emoticons/img/smiley-cool.gif | Bin 0 -> 354 bytes .../plugins/emoticons/img/smiley-cry.gif | Bin 0 -> 329 bytes .../emoticons/img/smiley-embarassed.gif | Bin 0 -> 331 bytes .../emoticons/img/smiley-foot-in-mouth.gif | Bin 0 -> 342 bytes .../plugins/emoticons/img/smiley-frown.gif | Bin 0 -> 340 bytes .../plugins/emoticons/img/smiley-innocent.gif | Bin 0 -> 336 bytes .../plugins/emoticons/img/smiley-kiss.gif | Bin 0 -> 338 bytes .../plugins/emoticons/img/smiley-laughing.gif | Bin 0 -> 343 bytes .../emoticons/img/smiley-money-mouth.gif | Bin 0 -> 321 bytes .../plugins/emoticons/img/smiley-sealed.gif | Bin 0 -> 323 bytes .../plugins/emoticons/img/smiley-smile.gif | Bin 0 -> 344 bytes .../emoticons/img/smiley-surprised.gif | Bin 0 -> 338 bytes .../emoticons/img/smiley-tongue-out.gif | Bin 0 -> 328 bytes .../emoticons/img/smiley-undecided.gif | Bin 0 -> 337 bytes .../plugins/emoticons/img/smiley-wink.gif | Bin 0 -> 350 bytes .../plugins/emoticons/img/smiley-yell.gif | Bin 0 -> 336 bytes .../tinymce/plugins/emoticons/index.js | 7 + .../tinymce/plugins/emoticons/plugin.js | 65 + .../tinymce/plugins/emoticons/plugin.min.js | 1 + .../tinymce/plugins/fullpage/index.js | 7 + .../tinymce/plugins/fullpage/plugin.js | 493 + .../tinymce/plugins/fullpage/plugin.min.js | 1 + .../tinymce/plugins/fullscreen/index.js | 7 + .../tinymce/plugins/fullscreen/plugin.js | 154 + .../tinymce/plugins/fullscreen/plugin.min.js | 1 + .../tinymce/plugins/hr/index.js | 7 + .../tinymce/plugins/hr/plugin.js | 30 + .../tinymce/plugins/hr/plugin.min.js | 1 + .../tinymce/plugins/image/index.js | 7 + .../tinymce/plugins/image/plugin.js | 635 + .../tinymce/plugins/image/plugin.min.js | 1 + .../tinymce/plugins/imagetools/index.js | 7 + .../tinymce/plugins/imagetools/plugin.js | 2974 + .../tinymce/plugins/imagetools/plugin.min.js | 1 + .../tinymce/plugins/importcss/index.js | 7 + .../tinymce/plugins/importcss/plugin.js | 273 + .../tinymce/plugins/importcss/plugin.min.js | 1 + .../tinymce/plugins/insertdatetime/index.js | 7 + .../tinymce/plugins/insertdatetime/plugin.js | 121 + .../plugins/insertdatetime/plugin.min.js | 1 + .../tinymce/plugins/legacyoutput/index.js | 7 + .../tinymce/plugins/legacyoutput/plugin.js | 208 + .../plugins/legacyoutput/plugin.min.js | 1 + .../tinymce/plugins/link/index.js | 7 + .../tinymce/plugins/link/plugin.js | 615 + .../tinymce/plugins/link/plugin.min.js | 1 + .../tinymce/plugins/lists/index.js | 7 + .../tinymce/plugins/lists/plugin.js | 1447 + .../tinymce/plugins/lists/plugin.min.js | 1 + .../tinymce/plugins/media/index.js | 7 + .../tinymce/plugins/media/plugin.js | 1421 + .../tinymce/plugins/media/plugin.min.js | 1 + .../tinymce/plugins/nonbreaking/index.js | 7 + .../tinymce/plugins/nonbreaking/plugin.js | 53 + .../tinymce/plugins/nonbreaking/plugin.min.js | 1 + .../tinymce/plugins/noneditable/index.js | 7 + .../tinymce/plugins/noneditable/plugin.js | 113 + .../tinymce/plugins/noneditable/plugin.min.js | 1 + .../tinymce/plugins/pagebreak/index.js | 7 + .../tinymce/plugins/pagebreak/plugin.js | 88 + .../tinymce/plugins/pagebreak/plugin.min.js | 1 + .../tinymce/plugins/paste/index.js | 7 + .../tinymce/plugins/paste/plugin.js | 1884 + .../tinymce/plugins/paste/plugin.min.js | 1 + .../tinymce/plugins/preview/index.js | 7 + .../tinymce/plugins/preview/plugin.js | 101 + .../tinymce/plugins/preview/plugin.min.js | 1 + .../tinymce/plugins/print/index.js | 7 + .../tinymce/plugins/print/plugin.js | 32 + .../tinymce/plugins/print/plugin.min.js | 1 + .../tinymce/plugins/save/index.js | 7 + .../tinymce/plugins/save/plugin.js | 98 + .../tinymce/plugins/save/plugin.min.js | 1 + .../tinymce/plugins/searchreplace/index.js | 7 + .../tinymce/plugins/searchreplace/plugin.js | 609 + .../plugins/searchreplace/plugin.min.js | 1 + .../tinymce/plugins/spellchecker/index.js | 7 + .../tinymce/plugins/spellchecker/plugin.js | 1031 + .../plugins/spellchecker/plugin.min.js | 1 + .../tinymce/plugins/tabfocus/index.js | 7 + .../tinymce/plugins/tabfocus/plugin.js | 120 + .../tinymce/plugins/tabfocus/plugin.min.js | 1 + .../tinymce/plugins/table/index.js | 7 + .../tinymce/plugins/table/plugin.js | 4596 ++ .../tinymce/plugins/table/plugin.min.js | 2 + .../tinymce/plugins/template/index.js | 7 + .../tinymce/plugins/template/plugin.js | 276 + .../tinymce/plugins/template/plugin.min.js | 1 + .../tinymce/plugins/textcolor/index.js | 7 + .../tinymce/plugins/textcolor/plugin.js | 297 + .../tinymce/plugins/textcolor/plugin.min.js | 1 + .../tinymce/plugins/textpattern/index.js | 7 + .../tinymce/plugins/textpattern/plugin.js | 268 + .../tinymce/plugins/textpattern/plugin.min.js | 1 + .../tinymce/plugins/toc/index.js | 7 + .../tinymce/plugins/toc/plugin.js | 246 + .../tinymce/plugins/toc/plugin.min.js | 1 + .../plugins/visualblocks/css/visualblocks.css | 135 + .../tinymce/plugins/visualblocks/index.js | 7 + .../tinymce/plugins/visualblocks/plugin.js | 86 + .../plugins/visualblocks/plugin.min.js | 1 + .../tinymce/plugins/visualchars/index.js | 7 + .../tinymce/plugins/visualchars/plugin.js | 116 + .../tinymce/plugins/visualchars/plugin.min.js | 1 + .../tinymce/plugins/wordcount/index.js | 7 + .../tinymce/plugins/wordcount/plugin.js | 566 + .../tinymce/plugins/wordcount/plugin.min.js | 1 + .../skins/lightgray/content.inline.min.css | 1 + .../tinymce/skins/lightgray/content.min.css | 1 + .../skins/lightgray/fonts/tinymce-small.eot | Bin 0 -> 9492 bytes .../skins/lightgray/fonts/tinymce-small.svg | 63 + .../skins/lightgray/fonts/tinymce-small.ttf | Bin 0 -> 9304 bytes .../skins/lightgray/fonts/tinymce-small.woff | Bin 0 -> 9380 bytes .../tinymce/skins/lightgray/fonts/tinymce.eot | Bin 0 -> 17572 bytes .../tinymce/skins/lightgray/fonts/tinymce.svg | 131 + .../tinymce/skins/lightgray/fonts/tinymce.ttf | Bin 0 -> 17408 bytes .../skins/lightgray/fonts/tinymce.woff | Bin 0 -> 17484 bytes .../tinymce/skins/lightgray/img/anchor.gif | Bin 0 -> 53 bytes .../tinymce/skins/lightgray/img/loader.gif | Bin 0 -> 2608 bytes .../tinymce/skins/lightgray/img/object.gif | Bin 0 -> 152 bytes .../tinymce/skins/lightgray/img/trans.gif | Bin 0 -> 43 bytes .../tinymce/skins/lightgray/skin.ie7.min.css | 1 + .../tinymce/skins/lightgray/skin.min.css | 1 + .../tinymce/themes/inlite/index.js | 7 + .../tinymce/themes/inlite/theme.js | 1858 + .../tinymce/themes/inlite/theme.min.js | 1 + .../tinymce/themes/modern/index.js | 7 + .../tinymce/themes/modern/theme.js | 1342 + .../tinymce/themes/modern/theme.min.js | 1 + .../tinymce/tinymce.jquery.js | 49222 ++++++++++++++++ .../tinymce/tinymce.jquery.min.js | 49222 ++++++++++++++++ .../js/bower_components/tinymce/tinymce.js | 49221 +++++++++++++++ .../bower_components/tinymce/tinymce.min.js | 14 + .../activity/activityChecker.directive.js | 43 + .../bids/add-bid-margin.controller.js | 46 + .../js/components/bids/add-bid.directive.js | 145 + .../bids/add-supplier-bid.controller.js | 73 + .../js/components/bids/bids-view.directive.js | 112 + .../js/components/bids/bids.directive.js | 38 + api-wiaas/client/js/components/bids/bids.less | 82 + .../bids/link-supplier-bids.controller.js | 50 + .../components/bids/remove-bid.controller.js | 30 + .../contact/contact-page.directive.js | 30 + .../client/js/components/contact/contact.less | 50 + .../customers/customers-view.directive.js | 101 + .../customers/customers.directive.js | 38 + .../js/components/customers/customers.less | 25 + .../dashboards/create-dashboard.directive.js | 235 + .../dashboards-filters.directive.js | 44 + .../dashboards/dashboards-filters.service.js | 117 + .../dashboards/dashboards-view.directive.js | 124 + .../dashboards/dashboards.directive.js | 41 + .../js/components/dashboards/dashboards.less | 313 + .../gadget-assigned-orders.directive.js | 37 + .../gadget-next-actions.directive.js | 37 + .../gadget-order-central.directive.js | 37 + .../dataTableHelper.service.js | 131 + .../datepicker/datepicker.directive.js | 34 + .../js/components/dialog/dialog.directive.js | 73 + .../client/js/components/dialog/dialog.less | 3 + .../documents/documents-add.directive.js | 95 + .../documents/documents-link.directive.js | 120 + .../documents/documents-view.directive.js | 70 + .../documents/documents.directive.js | 38 + .../js/components/documents/documents.less | 198 + .../errors/errorsDialog.directive.js | 11 + .../financing/financing.directive.js | 63 + .../js/components/financing/financing.less | 33 + .../components/financing/financing.service.js | 56 + .../set-customers-discount.directive.js | 93 + .../financing/set-interest-rate.directive.js | 52 + .../order-projects-edit.directive.js | 42 + .../orderProjects/order-projects.directive.js | 101 + .../orders/assign-broker.directive.js | 65 + .../orders/change-orders-steps.directive.js | 555 + .../choose-installation.directive.js | 78 + .../customer-acceptance.directive.js | 188 + .../extra-actions/procurement.directive.js | 96 + .../schedule-meeting.directive.js | 147 + .../validate-questionnaire.directive.js | 178 + .../installation-scheduler.directive.js | 376 + .../orders/orders-details.directive.js | 18 + .../components/orders/orders-utils.service.js | 164 + .../js/components/orders/orders.directive.js | 196 + .../client/js/components/orders/orders.less | 1033 + .../orders/set-delivery-dates.directive.js | 303 + .../suppliers-procurement-view.directive.js | 35 + .../orders/support-mail.directive.js | 21 + ...d-documents-for-order-package.directive.js | 80 + .../add-virtual-products.directive.js | 53 + ...create-packages-from-template.directive.js | 356 + .../create-packages-template.directive.js | 9 + .../packages/create-packages.directive.js | 60 + .../packages/display-cdn-images.directive.js | 74 + .../edit-package-templates.directive.js | 37 + .../packages/edit-packages.directive.js | 97 + .../packages/my-packages-details.directive.js | 90 + .../packages/package-options.directive.js | 273 + .../packages/packages-details.directive.js | 43 + .../packages/packages-utils.service.js | 75 + .../components/packages/packages.directive.js | 267 + .../js/components/packages/packages.less | 1454 + ...ducts-by-categories-drag-drop.directive.js | 336 + ...plate-by-categories-drag-drop.directive.js | 269 + .../packages/select-package.directive.js | 373 + .../packages/set-package-price.directive.js | 242 + .../packages/upload-image-cdn.directive.js | 64 + .../processes/copy-processes.directive.js | 60 + .../create-process-steps.directive.js | 306 + .../processes/edit-processes.directive.js | 246 + .../processes/link-process.directive.js | 185 + .../processes/processes.directive.js | 38 + .../js/components/processes/processes.less | 219 + .../view-package-processes.directive.js | 76 + .../change-password.directive.js | 51 + .../edit-profile.directive.js | 80 + .../profile-settings.directive.js | 38 + .../profile-settings/profile-settings.less | 26 + .../components/shop/cart-review.directive.js | 21 + .../js/components/shop/shop-cart.directive.js | 488 + .../js/components/shop/shop-cart.service.js | 74 + .../shop/shop-package-details.directive.js | 305 + .../shop/shop-package-search.directive.js | 38 + .../shop/shop-packages.directive.js | 63 + .../js/components/shop/shop.directive.js | 38 + api-wiaas/client/js/components/shop/shop.less | 402 + .../components/sortable/sortable.directive.js | 41 + .../show-product-documents.directive.js | 42 + .../suppliers/suppliers-add-edit.directive.js | 52 + .../suppliers-products-add-edit.directive.js | 123 + .../suppliers/suppliers.directive.js | 225 + .../js/components/suppliers/suppliers.less | 139 + .../upload-product-document.directive.js | 72 + .../client/js/components/terms/terms.less | 6 + .../translate/translate.directive.js | 42 + .../components/users/create-user.directive.js | 189 + .../users/link-customers.directive.js | 118 + .../users/show-edit-users.directive.js | 61 + .../js/components/users/users.directive.js | 38 + .../client/js/components/users/users.less | 237 + .../client/js/components/utils.service.js | 117 + api-wiaas/client/js/constants.js | 24 + api-wiaas/client/js/errorHandlerFactory.js | 47 + api-wiaas/client/js/login.js | 9 + api-wiaas/composer.json | 8 + api-wiaas/composer.lock | 274 + api-wiaas/config.php | 160 + api-wiaas/index.php | 31 + api-wiaas/logout.php | 7 + api-wiaas/package-lock.json | 1433 + api-wiaas/runScript.php | 29 + .../database_structure/tables.txt | 1268 + .../get_database_structure.php | 31 + .../sandbox_scripts/updateOrdersEndOfLife.sh | 2 + .../update_application_mode.php | 16 + api-wiaas/scripts/updateEndOfLife.sh | 1 + .../server/components/v1/bids/BidMargin.php | 52 + api-wiaas/server/components/v1/bids/Bids.php | 231 + .../components/v1/bids/BidsController.php | 106 + .../server/components/v1/bids/BidsModel.php | 70 + .../server/components/v1/bids/BidsPage.php | 12 + .../components/v1/bids/SupplierBids.php | 161 + .../bids/templates/AddBidMarginTemplate.php | 29 + .../v1/bids/templates/AddBidTemplate.php | 90 + .../bids/templates/AddSupplierBidTemplate.php | 28 + .../v1/bids/templates/BidsAddMarginButton.php | 19 + .../v1/bids/templates/BidsRemoveButton.php | 19 + .../v1/bids/templates/BidsTemplate.php | 9 + .../v1/bids/templates/BidsTemplateBroker.php | 27 + .../templates/BidsTemplateCommercialLead.php | 14 + .../v1/bids/templates/BidsViewTemplate.php | 110 + .../templates/LinkSupplierBidsTemplate.php | 22 + .../v1/bids/templates/LinkedBidsTemplate.php | 43 + .../v1/contact/ContactController.php | 34 + .../components/v1/contact/ContactModel.php | 257 + .../components/v1/contact/ContactPage.php | 5 + .../ContactCommercialLeadTemplate.php | 50 + .../ContactCustomerAndBrokerTemplate.php | 57 + .../templates/ContactSupportTemplate.php | 16 + .../v1/contact/templates/ContactTemplate.php | 8 + .../components/v1/countries/Countries.php | 24 + .../v1/countries/CountriesController.php | 21 + .../v1/countries/CountriesModel.php | 29 + .../components/v1/customers/ClCustomers.php | 121 + .../v1/customers/CustomersController.php | 67 + .../v1/customers/CustomersModel.php | 51 + .../components/v1/customers/CustomersPage.php | 7 + .../components/v1/customers/OrderType.php | 135 + .../customers/templates/CustomersTemplate.php | 13 + .../templates/CustomersViewTemplate.php | 70 + .../v1/dashboards/DashboardsController.php | 162 + .../v1/dashboards/DashboardsModel.php | 663 + .../v1/dashboards/DashboardsPage.php | 14 + .../templates/CreateDashboardTemplate.php | 77 + .../templates/DashboardsFiltersTemplate.php | 22 + .../templates/DashboardsTemplate.php | 38 + .../templates/DashboardsViewTemplate.php | 42 + .../templates/PublicPrivateDashboard.php | 10 + .../gadgets/assignedOrdersTemplate.php | 65 + .../templates/gadgets/nextActionsTemplate.php | 41 + .../gadgets/orderCentralTemplate.php | 65 + .../v1/documents/DocumentsController.php | 100 + .../v1/documents/DocumentsModel.php | 332 + .../components/v1/documents/DocumentsPage.php | 9 + .../templates/AddDocumentsButton.php | 5 + .../documents/templates/AddDocumentsLayer.php | 7 + .../templates/DocumentsAddTemplate.php | 56 + .../templates/DocumentsLinkTemplate.php | 71 + .../documents/templates/DocumentsTemplate.php | 24 + .../templates/DocumentsViewTemplate.php | 46 + .../templates/LinkDocumentsButton.php | 5 + .../templates/LinkDocumentsLayer.php | 7 + .../v1/financing/FinancingController.php | 76 + .../v1/financing/FinancingModel.php | 52 + .../components/v1/financing/FinancingPage.php | 8 + .../components/v1/financing/InterestRate.php | 158 + .../financing/templates/FinancingTempalte.php | 28 + .../SetCustomersDiscountTemplate.php | 37 + .../templates/SetInterestRateTemplate.php | 15 + .../components/v1/home/HomeController.php | 8 + .../server/components/v1/home/apiTemplate.php | 17 + .../components/v1/home/excelTemplate.php | 27 + .../components/v1/home/htmlTemplate.php | 6 + .../components/v1/home/menuTemplate.php | 37 + .../components/v1/home/pageTemplate.php | 47 + .../components/v1/home/scriptTemplate.php | 5 + .../v1/home/templates/FooterTemplate.php | 3 + .../home/templates/ShopCartIconTemplate.php | 5 + .../v1/home/templates/cssIncludes.php | 11 + .../v1/home/templates/jsIncludes.php | 32 + .../v1/home/templates/loginCssIncludes.php | 2 + .../v1/home/templates/loginJsIncludes.php | 8 + .../components/v1/login/LoginController.php | 42 + .../server/components/v1/login/LoginPage.php | 26 + .../v1/login/templates/ForgotPasswordForm.php | 50 + .../v1/login/templates/LoginForm.php | 50 + .../v1/login/templates/ResetPasswordForm.php | 58 + .../v1/orderProjects/OrderProjects.php | 92 + .../orderProjects/OrderProjectsController.php | 31 + .../v1/orderProjects/OrderProjectsModel.php | 23 + .../templates/OrderProjectsEditTemplate.php | 41 + .../templates/OrderProjectsTemplate.php | 1 + .../v1/orders/InstallationScheduling.php | 1328 + .../components/v1/orders/OrderActions.php | 270 + .../components/v1/orders/OrderDocuments.php | 237 + .../v1/orders/OrderExtraActions.php | 544 + .../components/v1/orders/OrderHelper.php | 263 + .../v1/orders/OrderProcessHelper.php | 924 + .../components/v1/orders/OrderTraking.php | 121 + .../components/v1/orders/OrdersController.php | 664 + .../components/v1/orders/OrdersModel.php | 2357 + .../components/v1/orders/OrdersPage.php | 22 + .../components/v1/orders/Procurement.php | 88 + .../v1/orders/SupplierEstimations.php | 258 + .../templates/AddDocumentsToOrderLayer.html | 47 + .../orders/templates/AssignBrokerLayer.html | 9 + .../templates/AssignBrokerTemplate.html | 12 + .../orders/templates/CancelOrderButton.html | 21 + .../templates/ChangeOrderEstimationDate.html | 8 + .../templates/ChangeOrdersStepsButton.html | 5 + .../templates/ChangeOrdersStepsTemplate.php | 299 + .../DisplayEarliestInstallationDate.html | 6 + .../orders/templates/GoToNextStepButton.html | 42 + .../InstallationSchedulerBrokerTemplate.php | 105 + .../InstallationSchedulerCustomerTemplate.php | 36 + .../InstallationSchedulerSupplierTemplate.php | 55 + .../InstallationSchedulingDatesTemplate.html | 101 + .../templates/OrderDetailsAllTemplate.php | 55 + .../templates/OrderDetailsCommercialLead.html | 9 + .../templates/OrderDetailsCustomer.html | 12 + .../OrderDetailsSupplierTemplate.php | 19 + .../orders/templates/OrderEstimationDate.html | 2 + .../OrderStepFullDescriptionButton.html | 1 + .../templates/OrdersDetailsTemplate.php | 13 + .../orders/templates/OrdersStepEditInfo.html | 33 + .../v1/orders/templates/OrdersStepInfo.html | 19 + .../v1/orders/templates/OrdersTemplate.php | 60 + .../templates/SetDeliveryDatesTemplate.php | 178 + .../templates/SetProcessForPackage.html | 25 + .../templates/ShowDeliveryDatesCLTemplate.php | 39 + .../ShowPackageUnassignedProcess.html | 9 + .../SuppliersProcurementViewTemplate.php | 13 + .../orders/templates/SupportMailTemplate.html | 91 + .../chooseInstallationBrokerTemplate.php | 15 + .../chooseInstallationCustomerTemplate.php | 6 + .../chooseInstallationTemplate.php | 12 + .../customerAcceptanceBrokerTemplate.php | 37 + .../customerAcceptanceCustomerTemplate.php | 103 + .../customerAcceptanceTemplate.php | 11 + .../procurementBrokerTemplate.php | 52 + .../procurementSupplierTemplate.php | 46 + .../extra-actions/procurementTemplate.php | 11 + .../scheduleMeetingBrokerTemplate.php | 27 + .../scheduleMeetingCustomerTemplate.php | 26 + .../extra-actions/scheduleMeetingTemplate.php | 13 + .../validateQuestionnaireBrokerTemplate.php | 82 + .../validateQuestionnaireCustomerTemplate.php | 50 + .../validateQuestionnaireTemplate.php | 6 + .../v1/packages/CustomerPackages.php | 83 + .../v1/packages/PacakgeOptionsManager.php | 393 + .../v1/packages/PackageDocuments.php | 86 + .../components/v1/packages/Packages.php | 197 + .../v1/packages/PackagesController.php | 395 + .../components/v1/packages/PackagesModel.php | 1979 + .../components/v1/packages/PackagesPage.php | 23 + .../templates/AddVirtualProductsTemplate.php | 25 + .../templates/CreatePackagesButton.html | 5 + .../CreatePackagesFromTemplateButton.html | 5 + .../CreatePackagesFromTemplateLayer.html | 4 + .../CreatePackagesFromTemplateTemplate.php | 219 + .../templates/CreatePackagesLayer.html | 4 + .../templates/CreatePackagesTemplate.php | 14 + .../CreateTemplatePackagesButton.html | 5 + .../CreateTemplatePackagesLayer.html | 4 + .../CreateTemplatePackagesTemplate.php | 6 + .../templates/DisplayCdnImagesTemplate.php | 26 + .../templates/EditPackageTemplatesButton.html | 5 + .../templates/EditPackageTemplatesHtml.php | 16 + .../templates/EditPackageTemplatesLayer.html | 4 + .../templates/EditPackagesButton.html | 5 + .../packages/templates/EditPackagesLayer.html | 4 + .../templates/EditPackagesTemplate.php | 24 + .../v1/packages/templates/MyPackagesBtn.html | 5 + .../packages/templates/MyPackagesDetails.html | 119 + .../packages/templates/MyPackagesLayer.html | 9 + .../templates/PackageOptionsTemplate.html | 142 + .../PackageOptionsTemplateButton.html | 5 + .../PackageOptionsTemplateLayer.html | 5 + .../templates/PackagesDetailsTemplate.php | 104 + .../packages/templates/PackagesTemplate.php | 48 + .../ProductsByCategoriesDragDropTemplate.php | 180 + ...tsTemplateByCategoriesDragDropTemplate.php | 121 + .../v1/packages/templates/SelectPackage.html | 259 + .../templates/SelectPackageLayer.html | 8 + .../packages/templates/SetPackagePrice.html | 156 + .../templates/SetPackagePriceLayer.html | 8 + .../templates/UploadImageCdnTemplate.php | 34 + ...ackagesDetailsBrokerLinkOptionsBigBtn.html | 3 + .../PackagesDetailsBrokerLinkOptionsBtn.html | 3 + ...agesDetailsBrokerSetAdditonalPriceBtn.html | 3 + ...ackagesDetailsBrokerSetOptionPriceBtn.html | 3 + .../PackagesDetailsBrokerSetPriceBtn.html | 3 + .../server/components/v1/prices/Prices.php | 647 + .../v1/processes/ProcessesController.php | 180 + .../v1/processes/ProcessesModel.php | 771 + .../components/v1/processes/ProcessesPage.php | 11 + .../templates/CopyProcessesTemplate.php | 16 + .../templates/CreateProcessTemplate.php | 164 + .../templates/EditProcessesTemplate.php | 122 + .../templates/LinkProcessTemplate.php | 103 + .../processes/templates/ProcessesTemplate.php | 42 + .../ViewPackageProcessesTemplate.php | 47 + .../ProfileSettingsController.php | 30 + .../profile-settings/ProfileSettingsPage.php | 8 + .../templates/ChangePasswordTemplate.php | 42 + .../templates/EditProfileTemplate.php | 47 + .../templates/ProfileSettingsTemplate.php | 21 + .../components/v1/shop/ShopController.php | 189 + .../server/components/v1/shop/ShopModel.php | 1631 + .../server/components/v1/shop/ShopPage.php | 11 + .../v1/shop/templates/CartReview.php | 88 + .../v1/shop/templates/ShopCartTemplate.php | 271 + .../templates/ShopPackageDetailsTemplate.php | 141 + .../templates/ShopPackageSearchTemplate.php | 15 + .../shop/templates/ShopPackagesTemplate.php | 39 + .../v1/shop/templates/ShopTemplate.php | 24 + .../v1/suppliers/SuppliersController.php | 184 + .../v1/suppliers/SuppliersModel.php | 240 + .../components/v1/suppliers/SuppliersPage.php | 10 + .../v1/suppliers/SuppliersProducts.php | 518 + .../ShowProductDocumentsTemplate.php | 9 + .../SuppliersAddEditFormTemplate.php | 37 + .../SuppliersProductsAddEditFormTemplate.php | 170 + .../suppliers/templates/SuppliersTemplate.php | 46 + .../UploadProductDocumentTempalte.php | 46 + .../components/v1/terms/TermsController.php | 30 + .../server/components/v1/terms/TermsModel.php | 40 + .../server/components/v1/terms/TermsPage.php | 12 + .../v1/translate/TranslateController.php | 21 + .../components/v1/translate/languages/en.json | 1266 + .../v1/translate/languages/login_en.json | 50 + .../components/v1/translate/languages/ro.json | 55 + .../translate/templates/LanguagesTemplate.php | 6 + .../components/v1/users/UsersController.php | 102 + .../server/components/v1/users/UsersModel.php | 630 + .../server/components/v1/users/UsersPage.php | 9 + .../v1/users/templates/CreateUserButton.html | 5 + .../v1/users/templates/CreateUserLayer.html | 4 + .../v1/users/templates/CreateUserTemplate.php | 149 + .../users/templates/LinkCustomersButton.html | 5 + .../users/templates/LinkCustomersLayer.html | 4 + .../users/templates/LinkCustomersTemplate.php | 65 + .../users/templates/ShowEditUsersTemplate.php | 73 + .../v1/users/templates/UsersTemplate.php | 29 + .../components/v1/utils/UtilsController.php | 47 + .../server/components/v1/utils/UtilsModel.php | 477 + .../changedPasswordTemplate.php | 18 + .../mail_templates/createUserTemplate.php | 20 + .../customerScheduleInstallationEnabled.php | 26 + .../mail_templates/errorMailTemplate.php | 11 + .../generatePasswordUserTemplate.php | 20 + .../installationAcceptedTemplate.php | 17 + .../installationDateInvalidTemplate.php | 17 + .../installationDeclinedTemplate.php | 17 + .../installationProposedTemplate.php | 17 + .../installationSchedulingDisabled.php | 18 + .../invalidQuestionnaireTemplate.php | 19 + .../lastStepCompletedTemplate.php | 22 + .../orderCommentAddedTemplate.php | 21 + .../orderConfirmationBrokerTemplate.php | 17 + .../orderConfirmationTemplate.php | 20 + .../orderStatusChangedTemplate.php | 20 + .../orderStepUpdatedTemplate.php | 21 + .../packageStatusChangedTemplate.php | 20 + .../processAssignedTemplate.php | 19 + .../reUploadQuestionnaireTemplate.php | 16 + .../scheduleMeetingTemplate.php | 21 + .../mail_templates/supportMailTemplate.php | 59 + .../v1/utils/mail_templates/testTemplate.php | 13 + .../utils/mail_templates/undoStepTemplate.php | 20 + .../templates/activityCheckerTemplate.php | 11 + .../utils/templates/errorDialogTemplate.php | 7 + api-wiaas/server/components/v2/bids/Bids.php | 115 + .../components/v2/bids/SupplierBids.php | 103 + .../components/v2/cart/CartController.php | 112 + .../server/components/v2/cart/CartModel.php | 1375 + .../v2/coMarket/CoMarketController.php | 49 + .../components/v2/coMarket/CoMarketModel.php | 446 + .../components/v2/customers/ClCustomers.php | 75 + .../components/v2/customers/OrderType.php | 144 + .../v2/dashboards/DashboardsController.php | 39 + .../v2/dashboards/DashboardsModel.php | 278 + .../v2/financing/FinancingController.php | 35 + .../v2/financing/FinancingModel.php | 31 + .../components/v2/financing/InterestRate.php | 154 + .../components/v2/helpers/AddressHelper.php | 414 + .../components/v2/helpers/Countries.php | 55 + .../server/components/v2/home/apiTemplate.php | 17 + .../components/v2/login/LoginController.php | 84 + .../server/components/v2/login/LoginModel.php | 123 + .../v2/orderProjects/OrderProjects.php | 115 + .../orderProjects/OrderProjectsController.php | 20 + .../v2/orderProjects/OrderProjectsModel.php | 15 + .../v2/orders/CustomerAcceptance.php | 184 + .../v2/orders/InstallationScheduling.php | 1136 + .../components/v2/orders/OrderDocuments.php | 100 + .../v2/orders/OrderExtraActions.php | 1019 + .../v2/orders/OrderProcessHelper.php | 122 + .../components/v2/orders/OrdersController.php | 159 + .../components/v2/orders/OrdersModel.php | 1420 + .../v2/packages/PackageDocuments.php | 86 + .../components/v2/packages/Packages.php | 193 + .../server/components/v2/prices/Prices.php | 323 + .../ProfileSettingsController.php | 85 + .../profileSettings/ProfileSettingsModel.php | 238 + .../components/v2/terms/TermsController.php | 30 + .../server/components/v2/terms/TermsModel.php | 40 + .../components/v2/users/UsersHelper.php | 197 + .../components/v2/utils/UtilsController.php | 15 + .../server/components/v2/utils/UtilsModel.php | 426 + .../changedPasswordTemplate.php | 18 + .../mail_templates/createUserTemplate.php | 20 + .../customerScheduleInstallationEnabled.php | 26 + .../mail_templates/errorMailTemplate.php | 11 + .../generatePasswordUserTemplate.php | 20 + .../installationAcceptedTemplate.php | 17 + .../installationDateInvalidTemplate.php | 17 + .../installationDeclinedTemplate.php | 17 + .../installationProposedTemplate.php | 17 + .../installationSchedulingDisabled.php | 18 + .../invalidQuestionnaireTemplate.php | 19 + .../lastStepCompletedTemplate.php | 22 + .../orderCommentAddedTemplate.php | 21 + .../orderConfirmationBrokerTemplate.php | 17 + .../orderConfirmationTemplate.php | 20 + .../orderStatusChangedTemplate.php | 20 + .../orderStepUpdatedTemplate.php | 21 + .../packageStatusChangedTemplate.php | 20 + .../processAssignedTemplate.php | 19 + .../reUploadQuestionnaireTemplate.php | 16 + .../scheduleMeetingTemplate.php | 21 + .../mail_templates/supportMailTemplate.php | 59 + api-wiaas/server/core/Database.php | 197 + api-wiaas/server/core/ErrorHandler.php | 118 + api-wiaas/server/core/FileManager.php | 333 + api-wiaas/server/core/HeadersHelper.php | 41 + api-wiaas/server/core/Mail.php | 76 + api-wiaas/server/core/Routes.php | 185 + api-wiaas/server/core/User.php | 426 + client-wiaas/.gitignore | 24 + client-wiaas/package-lock.json | 10989 ++++ client-wiaas/package.json | 58 + client-wiaas/public/.htaccess | 4 + client-wiaas/public/index.html | 20 + client-wiaas/public/manifest.json | 15 + .../proxima-nova-web-fonts-master/README.md | 38 + ...imonson - Proxima Nova Alt Black-demo.html | 611 + ...onson - Proxima Nova Alt Black-webfont.svg | 545 + ...onson - Proxima Nova Alt Black-webfont.ttf | Bin 0 -> 45052 bytes ...nson - Proxima Nova Alt Black-webfont.woff | Bin 0 -> 23820 bytes ...son - Proxima Nova Alt Black-webfont.woff2 | Bin 0 -> 18276 bytes ...Simonson - Proxima Nova Alt Bold-demo.html | 611 + ...monson - Proxima Nova Alt Bold-webfont.eot | Bin 0 -> 20965 bytes ...monson - Proxima Nova Alt Bold-webfont.svg | 618 + ...monson - Proxima Nova Alt Bold-webfont.ttf | Bin 0 -> 45724 bytes ...onson - Proxima Nova Alt Bold-webfont.woff | Bin 0 -> 24444 bytes ...nson - Proxima Nova Alt Bold-webfont.woff2 | Bin 0 -> 18812 bytes ...xima Nova Alt Condensed Semibold-demo.html | 611 + ...ma Nova Alt Condensed Semibold-webfont.eot | Bin 0 -> 21066 bytes ...ma Nova Alt Condensed Semibold-webfont.svg | 547 + ...ma Nova Alt Condensed Semibold-webfont.ttf | Bin 0 -> 46144 bytes ...onson - Proxima Nova Alt Regular-demo.html | 611 + ...son - Proxima Nova Alt Regular-webfont.eot | Bin 0 -> 20765 bytes ...son - Proxima Nova Alt Regular-webfont.svg | 618 + ...son - Proxima Nova Alt Regular-webfont.ttf | Bin 0 -> 45880 bytes ...on - Proxima Nova Alt Regular-webfont.woff | Bin 0 -> 24172 bytes ...n - Proxima Nova Alt Regular-webfont.woff2 | Bin 0 -> 24172 bytes ...nson - Proxima Nova ScOsf Thin-webfont.eot | Bin 0 -> 19571 bytes ...nson - Proxima Nova ScOsf Thin-webfont.svg | 718 + ...nson - Proxima Nova ScOsf Thin-webfont.ttf | Bin 0 -> 43868 bytes ...son - Proxima Nova ScOsf Thin-webfont.woff | Bin 0 -> 22708 bytes ...monson - Proxima Nova Semibold-webfont.eot | Bin 0 -> 22993 bytes ...monson - Proxima Nova Semibold-webfont.svg | 555 + ...monson - Proxima Nova Semibold-webfont.ttf | Bin 0 -> 53640 bytes ...nson - Proxima Nova Semibold-webfont.woff2 | Bin 0 -> 20400 bytes ...k Simonson - Proxima Nova Thin-webfont.eot | Bin 0 -> 21972 bytes ...k Simonson - Proxima Nova Thin-webfont.svg | 528 + ...k Simonson - Proxima Nova Thin-webfont.ttf | Bin 0 -> 53004 bytes ... Simonson - Proxima Nova Thin-webfont.woff | Bin 0 -> 25024 bytes ...Simonson - Proxima Nova Thin-webfont.woff2 | Bin 0 -> 19440 bytes .../static/img/CoMarketStartsida_MAIN.JPG | Bin 0 -> 68107 bytes .../img/CoMarketStartsida_OFFERCoor.jpg | Bin 0 -> 59023 bytes client-wiaas/public/static/img/HC.PNG | Bin 0 -> 89974 bytes .../static/img/HC_FixedHuddle_interior.png | Bin 0 -> 444649 bytes .../HC_FixedHuddle_interior_small_resize.png | Bin 0 -> 47529 bytes .../img/HC_MiniHuddle_interior_small.png | Bin 0 -> 70272 bytes .../static/img/HC_MobileHuddle_interior.png | Bin 0 -> 919798 bytes .../HC_MobileHuddle_interior_small_resize.png | Bin 0 -> 54080 bytes .../img/HC_PreHuddle_interior_small.png | Bin 0 -> 47266 bytes client-wiaas/public/static/img/Huddle.png | Bin 0 -> 44787 bytes client-wiaas/public/static/img/IWB.PNG | Bin 0 -> 241066 bytes client-wiaas/public/static/img/VCP.PNG | Bin 0 -> 492599 bytes client-wiaas/public/static/img/commercial.png | Bin 0 -> 34270 bytes client-wiaas/public/static/img/hc_cut.png | Bin 0 -> 14784 bytes client-wiaas/public/static/img/hc_cut2.png | Bin 0 -> 12371 bytes client-wiaas/public/static/img/iwb_cut.png | Bin 0 -> 39318 bytes client-wiaas/public/static/img/iwb_cut1.png | Bin 0 -> 41525 bytes .../public/static/img/logoDefault.svg | 33 + client-wiaas/public/static/img/man-icon.png | Bin 0 -> 13387 bytes .../public/static/img/no-photo-package.jpg | Bin 0 -> 8406 bytes .../public/static/img/package-no-photo.png | Bin 0 -> 2528 bytes client-wiaas/public/static/img/vcp_cut.png | Bin 0 -> 57902 bytes client-wiaas/public/static/img/video.png | Bin 0 -> 54010 bytes .../public/static/img/wiaas-favicon.png | Bin 0 -> 11882 bytes client-wiaas/public/static/img/wiaas_icon.png | Bin 0 -> 1948 bytes .../public/static/js/tinymce/LICENSE.TXT | 504 + .../public/static/js/tinymce/changelog.txt | 850 + .../tinymce/js/tinymce/jquery.tinymce.min.js | 1 + .../js/tinymce/js/tinymce/langs/readme.md | 3 + .../static/js/tinymce/js/tinymce/license.txt | 504 + .../js/tinymce/plugins/advlist/plugin.min.js | 1 + .../js/tinymce/plugins/anchor/plugin.min.js | 1 + .../js/tinymce/plugins/autolink/plugin.min.js | 1 + .../tinymce/plugins/autoresize/plugin.min.js | 1 + .../js/tinymce/plugins/autosave/plugin.min.js | 1 + .../js/tinymce/plugins/bbcode/plugin.min.js | 1 + .../js/tinymce/plugins/charmap/plugin.min.js | 1 + .../js/tinymce/plugins/code/plugin.min.js | 1 + .../tinymce/plugins/codesample/plugin.min.js | 1 + .../tinymce/plugins/colorpicker/plugin.min.js | 1 + .../tinymce/plugins/contextmenu/plugin.min.js | 1 + .../plugins/directionality/plugin.min.js | 1 + .../plugins/emoticons/img/smiley-cool.gif | Bin 0 -> 354 bytes .../plugins/emoticons/img/smiley-cry.gif | Bin 0 -> 329 bytes .../emoticons/img/smiley-embarassed.gif | Bin 0 -> 331 bytes .../emoticons/img/smiley-foot-in-mouth.gif | Bin 0 -> 342 bytes .../plugins/emoticons/img/smiley-frown.gif | Bin 0 -> 340 bytes .../plugins/emoticons/img/smiley-innocent.gif | Bin 0 -> 336 bytes .../plugins/emoticons/img/smiley-kiss.gif | Bin 0 -> 338 bytes .../plugins/emoticons/img/smiley-laughing.gif | Bin 0 -> 343 bytes .../emoticons/img/smiley-money-mouth.gif | Bin 0 -> 321 bytes .../plugins/emoticons/img/smiley-sealed.gif | Bin 0 -> 323 bytes .../plugins/emoticons/img/smiley-smile.gif | Bin 0 -> 344 bytes .../emoticons/img/smiley-surprised.gif | Bin 0 -> 338 bytes .../emoticons/img/smiley-tongue-out.gif | Bin 0 -> 328 bytes .../emoticons/img/smiley-undecided.gif | Bin 0 -> 337 bytes .../plugins/emoticons/img/smiley-wink.gif | Bin 0 -> 350 bytes .../plugins/emoticons/img/smiley-yell.gif | Bin 0 -> 336 bytes .../tinymce/plugins/emoticons/plugin.min.js | 1 + .../js/tinymce/plugins/fullpage/plugin.min.js | 1 + .../tinymce/plugins/fullscreen/plugin.min.js | 1 + .../js/tinymce/plugins/help/img/logo.png | Bin 0 -> 13208 bytes .../js/tinymce/plugins/help/plugin.min.js | 1 + .../js/tinymce/plugins/hr/plugin.min.js | 1 + .../js/tinymce/plugins/image/plugin.min.js | 1 + .../tinymce/plugins/imagetools/plugin.min.js | 2 + .../tinymce/plugins/importcss/plugin.min.js | 1 + .../plugins/insertdatetime/plugin.min.js | 1 + .../plugins/legacyoutput/plugin.min.js | 1 + .../js/tinymce/plugins/link/plugin.min.js | 1 + .../js/tinymce/plugins/lists/plugin.min.js | 1 + .../js/tinymce/plugins/media/plugin.min.js | 1 + .../tinymce/plugins/nonbreaking/plugin.min.js | 1 + .../tinymce/plugins/noneditable/plugin.min.js | 1 + .../tinymce/plugins/pagebreak/plugin.min.js | 1 + .../js/tinymce/plugins/paste/plugin.min.js | 1 + .../js/tinymce/plugins/preview/plugin.min.js | 1 + .../js/tinymce/plugins/print/plugin.min.js | 1 + .../js/tinymce/plugins/save/plugin.min.js | 1 + .../plugins/searchreplace/plugin.min.js | 1 + .../plugins/spellchecker/plugin.min.js | 1 + .../js/tinymce/plugins/tabfocus/plugin.min.js | 1 + .../js/tinymce/plugins/table/plugin.min.js | 5 + .../js/tinymce/plugins/template/plugin.min.js | 1 + .../tinymce/plugins/textcolor/plugin.min.js | 1 + .../tinymce/plugins/textpattern/plugin.min.js | 1 + .../js/tinymce/plugins/toc/plugin.min.js | 1 + .../plugins/visualblocks/plugin.min.js | 1 + .../tinymce/plugins/visualchars/plugin.min.js | 1 + .../tinymce/plugins/wordcount/plugin.min.js | 1 + .../skins/lightgray/fonts/tinymce-mobile.woff | Bin 0 -> 4624 bytes .../skins/lightgray/fonts/tinymce-small.eot | Bin 0 -> 9492 bytes .../skins/lightgray/fonts/tinymce-small.svg | 63 + .../skins/lightgray/fonts/tinymce-small.ttf | Bin 0 -> 9304 bytes .../skins/lightgray/fonts/tinymce-small.woff | Bin 0 -> 9380 bytes .../tinymce/skins/lightgray/fonts/tinymce.eot | Bin 0 -> 17572 bytes .../tinymce/skins/lightgray/fonts/tinymce.svg | 131 + .../tinymce/skins/lightgray/fonts/tinymce.ttf | Bin 0 -> 17408 bytes .../skins/lightgray/fonts/tinymce.woff | Bin 0 -> 17484 bytes .../js/tinymce/skins/lightgray/img/anchor.gif | Bin 0 -> 53 bytes .../js/tinymce/skins/lightgray/img/loader.gif | Bin 0 -> 2608 bytes .../js/tinymce/skins/lightgray/img/object.gif | Bin 0 -> 152 bytes .../js/tinymce/skins/lightgray/img/trans.gif | Bin 0 -> 43 bytes .../js/tinymce/themes/inlite/theme.min.js | 5 + .../js/tinymce/themes/mobile/theme.min.js | 8 + .../js/tinymce/themes/modern/theme.min.js | 5 + .../js/tinymce/js/tinymce/tinymce.min.js | 13 + .../scripts/update_applciaiton_mode.php | 16 + client-wiaas/src/App.js | 34 + client-wiaas/src/App.scss | 6 + client-wiaas/src/App.test.js | 8 + client-wiaas/src/actions/bids/bidsActions.js | 40 + client-wiaas/src/actions/cart/cartActions.js | 312 + .../src/actions/coMarket/coMarketActions.js | 9 + .../coMarket/coMarketPackageDetailsActions.js | 166 + .../coMarket/coMarketPackagesActions.js | 86 + .../src/actions/dashboard/dashboardActions.js | 27 + .../actions/dashboard/nextActionsActions.js | 28 + .../src/actions/dashboard/ordersActions.js | 35 + .../src/actions/dialog/dialogActions.js | 4 + client-wiaas/src/actions/login/authActions.js | 268 + .../notification/notificationActions.js | 4 + .../orderProjects/orderProjectsActions.js | 77 + .../orders/customerAcceptanceActions.js | 102 + .../src/actions/orders/ordersActions.js | 66 + .../src/actions/orders/processActions.js | 344 + client-wiaas/src/actions/page/pageActions.js | 30 + .../actions/profileSettings/addressActions.js | 118 + .../profileSettings/profileSettingsActions.js | 123 + client-wiaas/src/config.js | 19 + client-wiaas/src/configureStore.js | 31 + client-wiaas/src/constants/appContainers.js | 33 + client-wiaas/src/constants/authConstants.js | 68 + client-wiaas/src/constants/bidsConstants.js | 11 + client-wiaas/src/constants/cartConstants.js | 176 + .../src/constants/coMarketConstants.js | 110 + .../src/constants/dashboardConstants.js | 44 + client-wiaas/src/constants/dialogConstants.js | 4 + client-wiaas/src/constants/menuConstants.jsx | 6 + .../src/constants/notificationConstants.js | 8 + .../src/constants/orderProjectsConstants.js | 15 + client-wiaas/src/constants/ordersConstants.js | 209 + client-wiaas/src/constants/pageConstants.js | 8 + .../src/constants/profileSettingsConstants.js | 82 + client-wiaas/src/constants/termsConstants.js | 5 + .../src/containers/ContentContainer.jsx | 47 + .../src/containers/cart/CartContainer.jsx | 44 + .../cart/CartCustomerDetailsContainer.jsx | 229 + .../containers/cart/CartItemsContainer.jsx | 83 + .../cart/CartReviewOrderContainer.jsx | 177 + .../containers/cart/CartStepsContainer.jsx | 75 + .../cart/CartUploadDocumentsContainer.jsx | 99 + .../cart/components/AddOrderProject.jsx | 49 + .../containers/cart/components/BidItem.jsx | 40 + .../containers/cart/components/BidsList.jsx | 34 + .../containers/cart/components/CartIcon.jsx | 23 + .../containers/cart/components/CartItem.jsx | 272 + .../cart/components/CartUploadDocument.jsx | 79 + .../cart/components/OrderProjectsSelect.jsx | 71 + .../cart/components/PackageBids.jsx | 47 + .../cart/components/SelectBillingAddress.jsx | 50 + .../cart/components/SelectDeliveryAddress.jsx | 41 + .../src/containers/cart/style/Cart.scss | 170 + .../cart/style/CartStepsContainer.scss | 165 + .../style/CartUploadDocumentsContainer.scss | 54 + .../containers/cart/style/OrderProjects.scss | 20 + .../containers/cart/style/PacakgeBids.scss | 13 + .../containers/coMarket/CoMarketContainer.jsx | 27 + .../coMarket/CoMarketNavContainer.jsx | 45 + .../CoMarketPackageDetailsContainer.jsx | 109 + .../coMarket/CoMarketPackagesContainer.jsx | 62 + .../AdditionalPackageItemContainer.jsx | 131 + .../components/AdditionalPackages.jsx | 26 + .../AgreementOptionItemContainer.jsx | 127 + .../coMarket/components/AgreementOptions.jsx | 24 + .../coMarket/components/CartIcon.jsx | 20 + .../components/CoMarketCatalogSelect.jsx | 83 + .../coMarket/components/PackageInfo.jsx | 61 + .../components/PackageOptionItemContainer.jsx | 123 + .../coMarket/components/PackageOptions.jsx | 35 + .../coMarket/components/PackagePrice.jsx | 80 + .../coMarket/components/ShopItem.jsx | 45 + .../containers/coMarket/style/CoMarket.scss | 175 + .../CoMarketPackageDetailsContainer.scss | 159 + .../src/containers/contentContainer.scss | 42 + .../src/containers/dashboard/Dashboards.scss | 19 + .../dashboard/DashboardsContainer.jsx | 83 + .../src/containers/dashboard/NextActions.scss | 46 + .../dashboard/NextActionsContainer.jsx | 41 + .../containers/dashboard/OrderCentral.scss | 45 + .../dashboard/OrderCentralContainer.jsx | 69 + .../dashboard/components/NextActionItem.jsx | 25 + .../dashboard/components/NextActionsList.jsx | 27 + .../dashboard/components/OrderItem.jsx | 34 + .../dashboard/components/OrdersList.jsx | 59 + client-wiaas/src/containers/footer/Footer.jsx | 17 + .../src/containers/footer/style/Footer.scss | 12 + .../login/ChangePasswordContainer.jsx | 90 + .../src/containers/login/LogInContainer.jsx | 91 + .../src/containers/login/LogInForm.jsx | 128 + client-wiaas/src/containers/login/login.scss | 208 + .../InstallationSchedulingContainer.jsx | 26 + .../src/containers/orders/OrdersContainer.jsx | 78 + .../containers/orders/OrdersDataContainer.jsx | 57 + .../containers/orders/ProcessContainer.jsx | 267 + .../containers/orders/ProcessNavContainer.jsx | 110 + .../orders/components/ActiveOrderItem.jsx | 79 + .../orders/components/AddComment.jsx | 26 + .../orders/components/HistoryOrderButtons.jsx | 81 + .../orders/components/HistoryOrderItem.jsx | 77 + .../orders/components/OrderComments.jsx | 72 + .../orders/components/OrderDocuments.jsx | 26 + .../orders/components/OrderDocumentsGroup.jsx | 85 + .../orders/components/OrderInfo.jsx | 152 + .../orders/components/OrderList.jsx | 75 + .../orders/components/OrderListHeader.jsx | 56 + .../orders/components/OrderPackage.jsx | 92 + .../orders/components/PackagesNav.jsx | 35 + .../orders/components/SupportMail.jsx | 121 + .../InstallationSchedulingDatesPerPackage.jsx | 165 + .../InstallationSchedulingForPackages.jsx | 175 + .../InstallationSchedulingPerPackage.jsx | 161 + .../components/packages/PackageInfo.jsx | 142 + .../components/packages/PackageName.jsx | 16 + .../components/packages/ProcessPackage.jsx | 23 + .../process/AcceptanceDeclineReason.jsx | 30 + .../components/process/CustomerAcceptance.jsx | 193 + .../components/process/OrderProcess.jsx | 54 + .../orders/components/process/ProcessStep.jsx | 76 + .../process/ValidateQuestionnaire.jsx | 46 + .../process/ValidateQuestionnaireItem.jsx | 99 + .../orders/style/CustomerAcceptance.scss | 66 + .../orders/style/InstallationScheduling.scss | 112 + .../src/containers/orders/style/Orders.scss | 128 + .../containers/orders/style/OrdersList.scss | 3 + .../orders/style/ProcessContainer.scss | 366 + .../orders/style/ProcessNavContainer.scss | 70 + .../orders/style/ValidateQuestionnaire.scss | 25 + .../BillingAddressesContainer.jsx | 151 + .../ChangePasswordContainer.jsx | 62 + .../profileSettings/CompanyEditContainer.jsx | 80 + .../ProfileAddressesContainer.jsx | 152 + .../profileSettings/ProfileEditContainer.jsx | 81 + .../ProfileSettingsContainer.jsx | 60 + .../profileSettings/ProfileShowContainer.jsx | 52 + .../components/AddEditBillingAddress.jsx | 123 + .../components/AddEditProfileAddress.jsx | 90 + .../components/BillingAddress.jsx | 37 + .../components/ProfileAddress.jsx | 28 + .../components/RemoveBillingAddress.jsx | 21 + .../components/RemoveProfileAddress.jsx | 18 + .../style/AddressesContainer.scss | 56 + .../style/ProfieSettingsContainer.scss | 10 + .../style/ProfileShowContainer.scss | 7 + .../src/containers/terms/TermsContainer.jsx | 18 + .../src/containers/terms/termsContainer.scss | 11 + client-wiaas/src/helpers/FileDownloader.js | 21 + client-wiaas/src/helpers/HtmlClient.js | 60 + .../src/helpers/coMarket/PriceHelper.js | 27 + client-wiaas/src/index.js | 17 + client-wiaas/src/index.scss | 73 + .../src/mainComponents/box/WiaasBox.jsx | 120 + .../src/mainComponents/box/WiaasBox.scss | 59 + .../src/mainComponents/dialog/DialogBox.jsx | 96 + .../src/mainComponents/dialog/DialogBox.scss | 128 + client-wiaas/src/mainComponents/menu/Menu.jsx | 107 + .../src/mainComponents/menu/Submenu.jsx | 128 + .../src/mainComponents/menu/menu.scss | 119 + .../notification/NotificationBox.jsx | 36 + .../notification/notificationBox.scss | 23 + .../src/mainComponents/table/WiaasTable.jsx | 63 + .../src/mainComponents/table/WiaasTable.scss | 55 + .../wiaasRouter/MyComponent.jsx | 21 + .../wiaasRouter/WiaasRouter.jsx | 91 + .../src/reducers/cart/cartReducers.js | 225 + .../coMarketPackageDetailsReducers.js | 73 + .../coMarket/coMarketPackagesReducers.js | 40 + .../src/reducers/coMarket/coMarketReducers.js | 18 + .../reducers/dashboard/dashboardReducers.js | 16 + .../reducers/dashboard/nextActionsReducers.js | 23 + .../dashboard/ordersCentralReducer.js | 26 + .../src/reducers/dialog/dialogReducers.js | 23 + client-wiaas/src/reducers/index.js | 46 + .../src/reducers/login/authReducers.js | 60 + .../notification/notificationReducers.js | 17 + .../orderProjects/orderProjectsReducer.js | 26 + .../src/reducers/orders/ordersReducers.js | 50 + .../src/reducers/orders/processReducers.js | 121 + client-wiaas/src/reducers/page/pageReducer.js | 47 + .../profileSettingsReducers.js | 41 + client-wiaas/src/registerServiceWorker.js | 108 + client-wiaas/src/styleConstants.scss | 59 + client-wiaas/src/svg/logoAlternative.svg | 33 + client-wiaas/src/svg/logoDefault.svg | 33 + client-wiaas/src/svg/logoWhite.svg | 32 + client-wiaas/src/svg/profile.svg | 1 + documentation/gitlab_runners.txt | 1 + package-lock.json | 19 + sql-dump/comarket_2018-06-08.sql | 5377 ++ 1954 files changed, 483354 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 README.md create mode 100644 api-wiaas/.bowerrc create mode 100644 api-wiaas/.eslintrc.json create mode 100644 api-wiaas/.gitignore create mode 100644 api-wiaas/.htaccess create mode 100644 api-wiaas/.jsbeautifyrc create mode 100644 api-wiaas/Gruntfile.js create mode 100644 api-wiaas/application_scripts/updateEndOfLife.php create mode 100644 api-wiaas/client/css/dist/bundle.min.css create mode 100644 api-wiaas/client/css/style.less create mode 100644 api-wiaas/client/img/wiaas_icon.png create mode 100644 api-wiaas/client/img/wiass_bg.jpg create mode 100644 api-wiaas/client/js/app.js create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/LICENSE create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/README.md create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/karma.conf.js create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.js create mode 100644 api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-route/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-route/LICENSE.md create mode 100644 api-wiaas/client/js/bower_components/angular-route/README.md create mode 100644 api-wiaas/client/js/bower_components/angular-route/angular-route.js create mode 100644 api-wiaas/client/js/bower_components/angular-route/angular-route.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-route/angular-route.min.js.map create mode 100644 api-wiaas/client/js/bower_components/angular-route/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-route/index.js create mode 100644 api-wiaas/client/js/bower_components/angular-route/package.json create mode 100644 api-wiaas/client/js/bower_components/angular-translate-loader-url/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-translate-loader-url/README.md create mode 100644 api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.js create mode 100644 api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-translate-loader-url/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-translate-loader-url/package.json create mode 100644 api-wiaas/client/js/bower_components/angular-translate/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-translate/README.md create mode 100644 api-wiaas/client/js/bower_components/angular-translate/angular-translate.js create mode 100644 api-wiaas/client/js/bower_components/angular-translate/angular-translate.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-translate/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/LICENSE create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/README.md create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.css create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.css create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/gulpfile.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/index.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/package.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/protractor_conf.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.html create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.less create mode 100644 api-wiaas/client/js/bower_components/angular-ui-notification/src/build.less create mode 100644 api-wiaas/client/js/bower_components/angular-ui-sortable/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-sortable/.travis.yml create mode 100644 api-wiaas/client/js/bower_components/angular-ui-sortable/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/CONTRIBUTING.md create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/LICENSE create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/README.md create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/dist/tinymce.min.js create mode 100644 api-wiaas/client/js/bower_components/angular-ui-tinymce/src/tinymce.js create mode 100644 api-wiaas/client/js/bower_components/angular/.bower.json create mode 100644 api-wiaas/client/js/bower_components/angular/LICENSE.md create mode 100644 api-wiaas/client/js/bower_components/angular/README.md create mode 100644 api-wiaas/client/js/bower_components/angular/angular-csp.css create mode 100644 api-wiaas/client/js/bower_components/angular/angular.js create mode 100644 api-wiaas/client/js/bower_components/angular/angular.min.js create mode 100644 api-wiaas/client/js/bower_components/angular/angular.min.js.gzip create mode 100644 api-wiaas/client/js/bower_components/angular/angular.min.js.map create mode 100644 api-wiaas/client/js/bower_components/angular/bower.json create mode 100644 api-wiaas/client/js/bower_components/angular/index.js create mode 100644 api-wiaas/client/js/bower_components/angular/package.json create mode 100644 api-wiaas/client/js/bower_components/bootstrap/.bower.json create mode 100644 api-wiaas/client/js/bower_components/bootstrap/CHANGELOG.md create mode 100644 api-wiaas/client/js/bower_components/bootstrap/Gemfile create mode 100644 api-wiaas/client/js/bower_components/bootstrap/Gemfile.lock create mode 100644 api-wiaas/client/js/bower_components/bootstrap/Gruntfile.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/ISSUE_TEMPLATE.md create mode 100644 api-wiaas/client/js/bower_components/bootstrap/LICENSE create mode 100644 api-wiaas/client/js/bower_components/bootstrap/README.md create mode 100644 api-wiaas/client/js/bower_components/bootstrap/bower.json create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap-theme.css create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap-theme.css.map create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap-theme.min.css create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap-theme.min.css.map create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap.css create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap.css.map create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap.min.css create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/css/bootstrap.min.css.map create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/js/bootstrap.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/js/bootstrap.min.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/dist/js/npm.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 api-wiaas/client/js/bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 api-wiaas/client/js/bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 api-wiaas/client/js/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 api-wiaas/client/js/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2 create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/.jshintrc create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/bs-commonjs-generator.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/bs-glyphicons-data-generator.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/bs-lessdoc-parser.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/bs-raw-files-generator.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/change-version.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/configBridge.json create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/npm-shrinkwrap.json create mode 100644 api-wiaas/client/js/bower_components/bootstrap/grunt/sauce_browsers.yml create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/.jscsrc create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/.jshintrc create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/affix.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/alert.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/button.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/carousel.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/collapse.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/dropdown.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/modal.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/popover.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/scrollspy.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/tab.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/tooltip.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/js/transition.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/.csscomb.json create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/.csslintrc create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/alerts.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/badges.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/bootstrap.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/breadcrumbs.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/button-groups.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/buttons.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/carousel.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/close.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/code.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/component-animations.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/dropdowns.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/forms.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/glyphicons.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/grid.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/input-groups.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/jumbotron.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/labels.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/list-group.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/media.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/alerts.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/background-variant.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/border-radius.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/buttons.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/center-block.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/clearfix.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/forms.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/gradients.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/grid-framework.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/grid.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/hide-text.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/image.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/labels.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/list-group.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/nav-divider.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/nav-vertical-align.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/opacity.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/pagination.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/panels.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/progress-bar.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/reset-filter.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/reset-text.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/resize.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/responsive-visibility.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/size.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/tab-focus.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/table-row.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/text-emphasis.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/text-overflow.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/mixins/vendor-prefixes.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/modals.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/navbar.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/navs.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/normalize.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/pager.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/pagination.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/panels.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/popovers.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/print.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/progress-bars.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/responsive-embed.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/responsive-utilities.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/scaffolding.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/tables.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/theme.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/thumbnails.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/tooltip.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/type.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/utilities.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/variables.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/less/wells.less create mode 100644 api-wiaas/client/js/bower_components/bootstrap/nuget/MyGet.ps1 create mode 100644 api-wiaas/client/js/bower_components/bootstrap/nuget/bootstrap.less.nuspec create mode 100644 api-wiaas/client/js/bower_components/bootstrap/nuget/bootstrap.nuspec create mode 100644 api-wiaas/client/js/bower_components/bootstrap/package.js create mode 100644 api-wiaas/client/js/bower_components/bootstrap/package.json create mode 100644 api-wiaas/client/js/bower_components/clipboard/.bower.json create mode 100644 api-wiaas/client/js/bower_components/clipboard/bower.json create mode 100644 api-wiaas/client/js/bower_components/clipboard/composer.json create mode 100644 api-wiaas/client/js/bower_components/clipboard/contributing.md create mode 100644 api-wiaas/client/js/bower_components/clipboard/dist/clipboard.js create mode 100644 api-wiaas/client/js/bower_components/clipboard/dist/clipboard.min.js create mode 100644 api-wiaas/client/js/bower_components/clipboard/package.js create mode 100644 api-wiaas/client/js/bower_components/clipboard/package.json create mode 100644 api-wiaas/client/js/bower_components/clipboard/readme.md create mode 100644 api-wiaas/client/js/bower_components/clipboard/webpack.config.js create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/.bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/License.txt create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/Readme.md create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/css/dataTables.bootstrap.css create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/js/dataTables.bootstrap.js create mode 100644 api-wiaas/client/js/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive-dt/.bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive-dt/License.txt create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive-dt/Readme.md create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive-dt/bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive-dt/css/responsive.dataTables.css create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive-dt/css/responsive.dataTables.min.css create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive/.bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive/License.txt create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive/Readme.md create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive/bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive/js/dataTables.responsive.js create mode 100644 api-wiaas/client/js/bower_components/datatables.net-responsive/js/dataTables.responsive.min.js create mode 100644 api-wiaas/client/js/bower_components/datatables.net/.bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net/License.txt create mode 100644 api-wiaas/client/js/bower_components/datatables.net/Readme.md create mode 100644 api-wiaas/client/js/bower_components/datatables.net/bower.json create mode 100644 api-wiaas/client/js/bower_components/datatables.net/js/jquery.dataTables.js create mode 100644 api-wiaas/client/js/bower_components/datatables.net/js/jquery.dataTables.min.js create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/.editorconfig create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/.gitignore create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/Gruntfile.coffee create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/LICENSE create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/README.md create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/assets/docs.css create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/assets/docs.js create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/assets/docs.less create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/bower.json create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/composer.json create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/css/flag-icon.css create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/css/flag-icon.min.css create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ad.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ae.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/af.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ag.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ai.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/al.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/am.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ao.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/aq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ar.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/as.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/at.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/au.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/aw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ax.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/az.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ba.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/be.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/br.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bs.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/by.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/bz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ca.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ch.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ci.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ck.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/co.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cx.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/cz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/de.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/dj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/dk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/dm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/do.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/dz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ec.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ee.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/eg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/eh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/er.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/es.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/et.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/eu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/fi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/fj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/fk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/fm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/fo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/fr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ga.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gb-eng.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gb-nir.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gb-sct.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gb-wls.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ge.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gs.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/gy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/hk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/hm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/hn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/hr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ht.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/hu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/id.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ie.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/il.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/im.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/in.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/io.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/iq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ir.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/is.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/it.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/je.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/jm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/jo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/jp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ke.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ki.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/km.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ky.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/kz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/la.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/li.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ls.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/lv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ly.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ma.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/md.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/me.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ml.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ms.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mx.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/my.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/mz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/na.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/nc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ne.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/nf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ng.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ni.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/nl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/no.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/np.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/nr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/nu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/nz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/om.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pa.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pe.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ph.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ps.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/pw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/py.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/qa.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/re.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ro.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/rs.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ru.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/rw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sa.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/se.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/si.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/so.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ss.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/st.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sx.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/sz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/td.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/th.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/to.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/tz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ua.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ug.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/um.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/un.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/us.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/uy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/uz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/va.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/vc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ve.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/vg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/vi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/vn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/vu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/wf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ws.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/ye.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/yt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/za.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/zm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/1x1/zw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ad.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ae.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/af.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ag.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ai.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/al.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/am.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ao.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/aq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ar.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/as.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/at.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/au.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/aw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ax.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/az.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ba.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/be.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/br.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bs.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/by.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/bz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ca.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ch.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ci.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ck.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/co.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cx.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/cz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/de.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/dj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/dk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/dm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/do.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/dz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ec.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ee.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/eg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/eh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/er.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/es.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/et.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/eu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/fi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/fj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/fk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/fm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/fo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/fr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ga.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gb-eng.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gb-nir.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gb-sct.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gb-wls.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ge.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gs.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/gy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/hk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/hm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/hn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/hr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ht.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/hu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/id.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ie.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/il.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/im.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/in.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/io.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/iq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ir.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/is.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/it.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/je.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/jm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/jo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/jp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ke.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ki.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/km.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ky.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/kz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/la.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/li.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ls.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/lv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ly.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ma.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/md.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/me.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ml.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mo.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mp.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mq.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ms.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mx.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/my.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/mz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/na.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/nc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ne.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/nf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ng.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ni.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/nl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/no.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/np.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/nr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/nu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/nz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/om.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pa.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pe.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ph.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ps.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/pw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/py.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/qa.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/re.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ro.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/rs.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ru.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/rw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sa.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sb.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sd.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/se.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sh.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/si.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/so.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ss.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/st.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sx.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/sz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/td.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/th.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tj.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tk.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tl.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/to.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tr.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tv.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/tz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ua.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ug.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/um.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/un.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/us.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/uy.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/uz.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/va.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/vc.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ve.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/vg.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/vi.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/vn.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/vu.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/wf.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ws.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/ye.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/yt.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/za.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/zm.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/flags/4x3/zw.svg create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/index.html create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/less/flag-icon-base.less create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/less/flag-icon-list.less create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/less/flag-icon-more.less create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/less/flag-icon.less create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/less/variables.less create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/package.json create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/sass/_flag-icon-base.scss create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/sass/_flag-icon-list.scss create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/sass/_flag-icon-more.scss create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/sass/_variables.scss create mode 100644 api-wiaas/client/js/bower_components/flag-icon-css-master/sass/flag-icon.scss create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/AUTHORS.txt create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/LICENSE.txt create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/external/jquery/jquery.js create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_diagonals-small_40_db4865_40x40.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_diagonals-small_50_93c3cd_40x40.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_diagonals-small_50_ff3853_40x40.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_diagonals-small_75_ccd232_40x40.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_dots-medium_80_ffff38_4x4.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_dots-small_35_35414f_2x2.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_100_e4f1fb_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_50_3baae3_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_80_d7ebf9_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_highlight-hard_70_000000_1x100.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_highlight-soft_100_deedf7_1x100.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_highlight-soft_25_ffef8f_1x100.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-bg_white-lines_85_f7f7ba_40x100.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_222222_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_2694e8_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_2e83ff_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_3d80b3_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_454545_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_72a7cf_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_888888_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_88a206_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_c02669_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_cd0a0a_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_e1e463_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_ffeb33_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/images/ui-icons_ffffff_256x240.png create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/index.html create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.css create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.js create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.min.css create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.min.js create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.structure.css create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.structure.min.css create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.theme.css create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/jquery-ui.theme.min.css create mode 100644 api-wiaas/client/js/bower_components/jquery-ui/package.json create mode 100644 api-wiaas/client/js/bower_components/jquery/.bower.json create mode 100644 api-wiaas/client/js/bower_components/jquery/AUTHORS.txt create mode 100644 api-wiaas/client/js/bower_components/jquery/LICENSE.txt create mode 100644 api-wiaas/client/js/bower_components/jquery/README.md create mode 100644 api-wiaas/client/js/bower_components/jquery/bower.json create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/core.js create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/jquery.js create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/jquery.min.js create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/jquery.min.map create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/jquery.slim.js create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/jquery.slim.min.js create mode 100644 api-wiaas/client/js/bower_components/jquery/dist/jquery.slim.min.map create mode 100644 api-wiaas/client/js/bower_components/jquery/external/sizzle/LICENSE.txt create mode 100644 api-wiaas/client/js/bower_components/jquery/external/sizzle/dist/sizzle.js create mode 100644 api-wiaas/client/js/bower_components/jquery/external/sizzle/dist/sizzle.min.js create mode 100644 api-wiaas/client/js/bower_components/jquery/external/sizzle/dist/sizzle.min.map create mode 100644 api-wiaas/client/js/bower_components/jquery/src/.eslintrc.json create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/jsonp.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/load.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/parseXML.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/script.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/var/location.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/var/nonce.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/var/rquery.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/ajax/xhr.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/attributes.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/attributes/attr.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/attributes/classes.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/attributes/prop.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/attributes/support.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/attributes/val.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/callbacks.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/DOMEval.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/access.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/init.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/parseHTML.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/ready-no-deferred.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/ready.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/readyException.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/stripAndCollapse.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/support.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/core/var/rsingleTag.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/addGetHookIf.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/adjustCSS.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/curCSS.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/hiddenVisibleSelectors.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/showHide.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/support.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/var/cssExpand.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/var/getStyles.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/var/isHiddenWithinTree.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/var/rmargin.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/var/rnumnonpx.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/css/var/swap.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/data.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/data/Data.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/data/var/acceptData.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/data/var/dataPriv.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/data/var/dataUser.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/deferred.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/deferred/exceptionHook.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/deprecated.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/dimensions.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/effects.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/effects/Tween.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/effects/animatedSelector.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/event.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/event/ajax.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/event/alias.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/event/focusin.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/event/support.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/event/trigger.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/exports/amd.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/exports/global.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/jquery.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/_evalUrl.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/buildFragment.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/getAll.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/setGlobalEval.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/support.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/var/rcheckableType.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/var/rscriptType.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/var/rtagName.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/manipulation/wrapMap.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/offset.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/queue.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/queue/delay.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/selector-native.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/selector-sizzle.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/selector.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/serialize.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/traversing.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/traversing/findFilter.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/traversing/var/dir.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/traversing/var/rneedsContext.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/traversing/var/siblings.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/ObjectFunctionString.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/arr.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/class2type.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/concat.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/document.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/documentElement.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/fnToString.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/getProto.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/hasOwn.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/indexOf.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/pnum.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/push.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/rcssNum.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/rnothtmlwhite.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/slice.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/support.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/var/toString.js create mode 100644 api-wiaas/client/js/bower_components/jquery/src/wrap.js create mode 100644 api-wiaas/client/js/bower_components/less/.bower.json create mode 100644 api-wiaas/client/js/bower_components/less/bower.json create mode 100644 api-wiaas/client/js/bower_components/less/browser.js create mode 100644 api-wiaas/client/js/bower_components/less/dist/less.js create mode 100644 api-wiaas/client/js/bower_components/less/dist/less.min.js create mode 100644 api-wiaas/client/js/bower_components/less/index.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/.bower.json create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/.versions create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/FileAPI.flash.swf create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/FileAPI.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/FileAPI.min.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/LICENSE create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/README.md create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/bower.json create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/ng-file-upload-all.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/ng-file-upload-all.min.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/ng-file-upload-shim.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/ng-file-upload-shim.min.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/ng-file-upload.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/ng-file-upload.min.js create mode 100644 api-wiaas/client/js/bower_components/ng-file-upload/package.js create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/.bower.json create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/.editorconfig create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/.gitignore create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/.jscsrc create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/.jshintrc create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/.travis.yml create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/Gruntfile.js create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/LICENSE create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/bower.json create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/contributing.md create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/dist/ngclipboard.js create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/dist/ngclipboard.min.js create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/package.json create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/src/.jshintrc create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/src/ngclipboard.js create mode 100644 api-wiaas/client/js/bower_components/ngclipboard/test/test.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/.bower.json create mode 100644 api-wiaas/client/js/bower_components/tinymce/bower.json create mode 100644 api-wiaas/client/js/bower_components/tinymce/jquery.tinymce.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/jquery.tinymce.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/license.txt create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/advlist/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/advlist/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/advlist/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/anchor/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/anchor/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/anchor/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autolink/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autolink/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autolink/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autoresize/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autoresize/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autoresize/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autosave/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autosave/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/autosave/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/bbcode/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/bbcode/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/bbcode/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/charmap/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/charmap/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/charmap/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/code/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/code/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/code/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/codesample/css/prism.css create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/codesample/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/codesample/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/codesample/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/colorpicker/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/colorpicker/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/colorpicker/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/contextmenu/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/contextmenu/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/contextmenu/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/directionality/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/directionality/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/directionality/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-cool.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-cry.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-embarassed.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-frown.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-innocent.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-kiss.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-laughing.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-money-mouth.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-sealed.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-smile.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-surprised.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-tongue-out.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-undecided.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-wink.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/img/smiley-yell.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/emoticons/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/fullpage/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/fullpage/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/fullpage/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/fullscreen/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/fullscreen/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/fullscreen/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/hr/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/hr/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/hr/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/image/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/image/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/image/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/imagetools/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/imagetools/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/imagetools/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/importcss/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/importcss/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/importcss/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/insertdatetime/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/insertdatetime/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/insertdatetime/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/legacyoutput/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/legacyoutput/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/legacyoutput/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/link/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/link/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/link/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/lists/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/lists/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/lists/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/media/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/media/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/media/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/nonbreaking/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/nonbreaking/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/nonbreaking/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/noneditable/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/noneditable/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/noneditable/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/pagebreak/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/pagebreak/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/pagebreak/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/paste/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/paste/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/paste/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/preview/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/preview/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/preview/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/print/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/print/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/print/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/save/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/save/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/save/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/searchreplace/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/searchreplace/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/searchreplace/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/spellchecker/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/spellchecker/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/spellchecker/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/tabfocus/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/tabfocus/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/tabfocus/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/table/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/table/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/table/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/template/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/template/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/template/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/textcolor/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/textcolor/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/textcolor/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/textpattern/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/textpattern/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/textpattern/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/toc/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/toc/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/toc/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualblocks/css/visualblocks.css create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualblocks/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualblocks/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualblocks/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualchars/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualchars/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/visualchars/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/wordcount/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/wordcount/plugin.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/plugins/wordcount/plugin.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/content.inline.min.css create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/content.min.css create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce-small.eot create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce-small.svg create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce-small.ttf create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce-small.woff create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce.eot create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce.svg create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce.ttf create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/fonts/tinymce.woff create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/img/anchor.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/img/loader.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/img/object.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/img/trans.gif create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/skin.ie7.min.css create mode 100644 api-wiaas/client/js/bower_components/tinymce/skins/lightgray/skin.min.css create mode 100644 api-wiaas/client/js/bower_components/tinymce/themes/inlite/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/themes/inlite/theme.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/themes/inlite/theme.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/themes/modern/index.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/themes/modern/theme.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/themes/modern/theme.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/tinymce.jquery.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/tinymce.jquery.min.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/tinymce.js create mode 100644 api-wiaas/client/js/bower_components/tinymce/tinymce.min.js create mode 100644 api-wiaas/client/js/components/activity/activityChecker.directive.js create mode 100644 api-wiaas/client/js/components/bids/add-bid-margin.controller.js create mode 100644 api-wiaas/client/js/components/bids/add-bid.directive.js create mode 100644 api-wiaas/client/js/components/bids/add-supplier-bid.controller.js create mode 100644 api-wiaas/client/js/components/bids/bids-view.directive.js create mode 100644 api-wiaas/client/js/components/bids/bids.directive.js create mode 100644 api-wiaas/client/js/components/bids/bids.less create mode 100644 api-wiaas/client/js/components/bids/link-supplier-bids.controller.js create mode 100644 api-wiaas/client/js/components/bids/remove-bid.controller.js create mode 100644 api-wiaas/client/js/components/contact/contact-page.directive.js create mode 100644 api-wiaas/client/js/components/contact/contact.less create mode 100644 api-wiaas/client/js/components/customers/customers-view.directive.js create mode 100644 api-wiaas/client/js/components/customers/customers.directive.js create mode 100644 api-wiaas/client/js/components/customers/customers.less create mode 100644 api-wiaas/client/js/components/dashboards/create-dashboard.directive.js create mode 100644 api-wiaas/client/js/components/dashboards/dashboards-filters.directive.js create mode 100644 api-wiaas/client/js/components/dashboards/dashboards-filters.service.js create mode 100644 api-wiaas/client/js/components/dashboards/dashboards-view.directive.js create mode 100644 api-wiaas/client/js/components/dashboards/dashboards.directive.js create mode 100644 api-wiaas/client/js/components/dashboards/dashboards.less create mode 100644 api-wiaas/client/js/components/dashboards/gadget-assigned-orders.directive.js create mode 100644 api-wiaas/client/js/components/dashboards/gadget-next-actions.directive.js create mode 100644 api-wiaas/client/js/components/dashboards/gadget-order-central.directive.js create mode 100644 api-wiaas/client/js/components/dataTableHelper/dataTableHelper.service.js create mode 100644 api-wiaas/client/js/components/datepicker/datepicker.directive.js create mode 100644 api-wiaas/client/js/components/dialog/dialog.directive.js create mode 100644 api-wiaas/client/js/components/dialog/dialog.less create mode 100644 api-wiaas/client/js/components/documents/documents-add.directive.js create mode 100644 api-wiaas/client/js/components/documents/documents-link.directive.js create mode 100644 api-wiaas/client/js/components/documents/documents-view.directive.js create mode 100644 api-wiaas/client/js/components/documents/documents.directive.js create mode 100644 api-wiaas/client/js/components/documents/documents.less create mode 100644 api-wiaas/client/js/components/errors/errorsDialog.directive.js create mode 100644 api-wiaas/client/js/components/financing/financing.directive.js create mode 100644 api-wiaas/client/js/components/financing/financing.less create mode 100644 api-wiaas/client/js/components/financing/financing.service.js create mode 100644 api-wiaas/client/js/components/financing/set-customers-discount.directive.js create mode 100644 api-wiaas/client/js/components/financing/set-interest-rate.directive.js create mode 100644 api-wiaas/client/js/components/orderProjects/order-projects-edit.directive.js create mode 100644 api-wiaas/client/js/components/orderProjects/order-projects.directive.js create mode 100644 api-wiaas/client/js/components/orders/assign-broker.directive.js create mode 100644 api-wiaas/client/js/components/orders/change-orders-steps.directive.js create mode 100644 api-wiaas/client/js/components/orders/extra-actions/choose-installation.directive.js create mode 100644 api-wiaas/client/js/components/orders/extra-actions/customer-acceptance.directive.js create mode 100644 api-wiaas/client/js/components/orders/extra-actions/procurement.directive.js create mode 100644 api-wiaas/client/js/components/orders/extra-actions/schedule-meeting.directive.js create mode 100644 api-wiaas/client/js/components/orders/extra-actions/validate-questionnaire.directive.js create mode 100644 api-wiaas/client/js/components/orders/installation-scheduler.directive.js create mode 100644 api-wiaas/client/js/components/orders/orders-details.directive.js create mode 100644 api-wiaas/client/js/components/orders/orders-utils.service.js create mode 100644 api-wiaas/client/js/components/orders/orders.directive.js create mode 100644 api-wiaas/client/js/components/orders/orders.less create mode 100644 api-wiaas/client/js/components/orders/set-delivery-dates.directive.js create mode 100644 api-wiaas/client/js/components/orders/suppliers-procurement-view.directive.js create mode 100644 api-wiaas/client/js/components/orders/support-mail.directive.js create mode 100644 api-wiaas/client/js/components/orders/upload-documents-for-order-package.directive.js create mode 100644 api-wiaas/client/js/components/packages/add-virtual-products.directive.js create mode 100644 api-wiaas/client/js/components/packages/create-packages-from-template.directive.js create mode 100644 api-wiaas/client/js/components/packages/create-packages-template.directive.js create mode 100644 api-wiaas/client/js/components/packages/create-packages.directive.js create mode 100644 api-wiaas/client/js/components/packages/display-cdn-images.directive.js create mode 100644 api-wiaas/client/js/components/packages/edit-package-templates.directive.js create mode 100644 api-wiaas/client/js/components/packages/edit-packages.directive.js create mode 100644 api-wiaas/client/js/components/packages/my-packages-details.directive.js create mode 100644 api-wiaas/client/js/components/packages/package-options.directive.js create mode 100644 api-wiaas/client/js/components/packages/packages-details.directive.js create mode 100644 api-wiaas/client/js/components/packages/packages-utils.service.js create mode 100644 api-wiaas/client/js/components/packages/packages.directive.js create mode 100644 api-wiaas/client/js/components/packages/packages.less create mode 100644 api-wiaas/client/js/components/packages/products-by-categories-drag-drop.directive.js create mode 100644 api-wiaas/client/js/components/packages/products-template-by-categories-drag-drop.directive.js create mode 100644 api-wiaas/client/js/components/packages/select-package.directive.js create mode 100644 api-wiaas/client/js/components/packages/set-package-price.directive.js create mode 100644 api-wiaas/client/js/components/packages/upload-image-cdn.directive.js create mode 100644 api-wiaas/client/js/components/processes/copy-processes.directive.js create mode 100644 api-wiaas/client/js/components/processes/create-process-steps.directive.js create mode 100644 api-wiaas/client/js/components/processes/edit-processes.directive.js create mode 100644 api-wiaas/client/js/components/processes/link-process.directive.js create mode 100644 api-wiaas/client/js/components/processes/processes.directive.js create mode 100644 api-wiaas/client/js/components/processes/processes.less create mode 100644 api-wiaas/client/js/components/processes/view-package-processes.directive.js create mode 100644 api-wiaas/client/js/components/profile-settings/change-password.directive.js create mode 100644 api-wiaas/client/js/components/profile-settings/edit-profile.directive.js create mode 100644 api-wiaas/client/js/components/profile-settings/profile-settings.directive.js create mode 100644 api-wiaas/client/js/components/profile-settings/profile-settings.less create mode 100644 api-wiaas/client/js/components/shop/cart-review.directive.js create mode 100644 api-wiaas/client/js/components/shop/shop-cart.directive.js create mode 100644 api-wiaas/client/js/components/shop/shop-cart.service.js create mode 100644 api-wiaas/client/js/components/shop/shop-package-details.directive.js create mode 100644 api-wiaas/client/js/components/shop/shop-package-search.directive.js create mode 100644 api-wiaas/client/js/components/shop/shop-packages.directive.js create mode 100644 api-wiaas/client/js/components/shop/shop.directive.js create mode 100644 api-wiaas/client/js/components/shop/shop.less create mode 100644 api-wiaas/client/js/components/sortable/sortable.directive.js create mode 100644 api-wiaas/client/js/components/suppliers/show-product-documents.directive.js create mode 100644 api-wiaas/client/js/components/suppliers/suppliers-add-edit.directive.js create mode 100644 api-wiaas/client/js/components/suppliers/suppliers-products-add-edit.directive.js create mode 100644 api-wiaas/client/js/components/suppliers/suppliers.directive.js create mode 100644 api-wiaas/client/js/components/suppliers/suppliers.less create mode 100644 api-wiaas/client/js/components/suppliers/upload-product-document.directive.js create mode 100644 api-wiaas/client/js/components/terms/terms.less create mode 100644 api-wiaas/client/js/components/translate/translate.directive.js create mode 100644 api-wiaas/client/js/components/users/create-user.directive.js create mode 100644 api-wiaas/client/js/components/users/link-customers.directive.js create mode 100644 api-wiaas/client/js/components/users/show-edit-users.directive.js create mode 100644 api-wiaas/client/js/components/users/users.directive.js create mode 100644 api-wiaas/client/js/components/users/users.less create mode 100644 api-wiaas/client/js/components/utils.service.js create mode 100644 api-wiaas/client/js/constants.js create mode 100644 api-wiaas/client/js/errorHandlerFactory.js create mode 100644 api-wiaas/client/js/login.js create mode 100644 api-wiaas/composer.json create mode 100644 api-wiaas/composer.lock create mode 100644 api-wiaas/config.php create mode 100644 api-wiaas/index.php create mode 100644 api-wiaas/logout.php create mode 100644 api-wiaas/package-lock.json create mode 100644 api-wiaas/runScript.php create mode 100644 api-wiaas/sandbox_scripts/database_structure/tables.txt create mode 100644 api-wiaas/sandbox_scripts/get_database_structure.php create mode 100644 api-wiaas/sandbox_scripts/updateOrdersEndOfLife.sh create mode 100644 api-wiaas/sandbox_scripts/update_application_mode.php create mode 100644 api-wiaas/scripts/updateEndOfLife.sh create mode 100644 api-wiaas/server/components/v1/bids/BidMargin.php create mode 100644 api-wiaas/server/components/v1/bids/Bids.php create mode 100644 api-wiaas/server/components/v1/bids/BidsController.php create mode 100644 api-wiaas/server/components/v1/bids/BidsModel.php create mode 100644 api-wiaas/server/components/v1/bids/BidsPage.php create mode 100644 api-wiaas/server/components/v1/bids/SupplierBids.php create mode 100644 api-wiaas/server/components/v1/bids/templates/AddBidMarginTemplate.php create mode 100644 api-wiaas/server/components/v1/bids/templates/AddBidTemplate.php create mode 100644 api-wiaas/server/components/v1/bids/templates/AddSupplierBidTemplate.php create mode 100644 api-wiaas/server/components/v1/bids/templates/BidsAddMarginButton.php create mode 100644 api-wiaas/server/components/v1/bids/templates/BidsRemoveButton.php create mode 100644 api-wiaas/server/components/v1/bids/templates/BidsTemplate.php create mode 100644 api-wiaas/server/components/v1/bids/templates/BidsTemplateBroker.php create mode 100644 api-wiaas/server/components/v1/bids/templates/BidsTemplateCommercialLead.php create mode 100644 api-wiaas/server/components/v1/bids/templates/BidsViewTemplate.php create mode 100644 api-wiaas/server/components/v1/bids/templates/LinkSupplierBidsTemplate.php create mode 100644 api-wiaas/server/components/v1/bids/templates/LinkedBidsTemplate.php create mode 100644 api-wiaas/server/components/v1/contact/ContactController.php create mode 100644 api-wiaas/server/components/v1/contact/ContactModel.php create mode 100644 api-wiaas/server/components/v1/contact/ContactPage.php create mode 100644 api-wiaas/server/components/v1/contact/templates/ContactCommercialLeadTemplate.php create mode 100644 api-wiaas/server/components/v1/contact/templates/ContactCustomerAndBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/contact/templates/ContactSupportTemplate.php create mode 100644 api-wiaas/server/components/v1/contact/templates/ContactTemplate.php create mode 100644 api-wiaas/server/components/v1/countries/Countries.php create mode 100644 api-wiaas/server/components/v1/countries/CountriesController.php create mode 100644 api-wiaas/server/components/v1/countries/CountriesModel.php create mode 100644 api-wiaas/server/components/v1/customers/ClCustomers.php create mode 100644 api-wiaas/server/components/v1/customers/CustomersController.php create mode 100644 api-wiaas/server/components/v1/customers/CustomersModel.php create mode 100644 api-wiaas/server/components/v1/customers/CustomersPage.php create mode 100644 api-wiaas/server/components/v1/customers/OrderType.php create mode 100644 api-wiaas/server/components/v1/customers/templates/CustomersTemplate.php create mode 100644 api-wiaas/server/components/v1/customers/templates/CustomersViewTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/DashboardsController.php create mode 100644 api-wiaas/server/components/v1/dashboards/DashboardsModel.php create mode 100644 api-wiaas/server/components/v1/dashboards/DashboardsPage.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/CreateDashboardTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/DashboardsFiltersTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/DashboardsTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/DashboardsViewTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/PublicPrivateDashboard.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/gadgets/assignedOrdersTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/gadgets/nextActionsTemplate.php create mode 100644 api-wiaas/server/components/v1/dashboards/templates/gadgets/orderCentralTemplate.php create mode 100644 api-wiaas/server/components/v1/documents/DocumentsController.php create mode 100644 api-wiaas/server/components/v1/documents/DocumentsModel.php create mode 100644 api-wiaas/server/components/v1/documents/DocumentsPage.php create mode 100644 api-wiaas/server/components/v1/documents/templates/AddDocumentsButton.php create mode 100644 api-wiaas/server/components/v1/documents/templates/AddDocumentsLayer.php create mode 100644 api-wiaas/server/components/v1/documents/templates/DocumentsAddTemplate.php create mode 100644 api-wiaas/server/components/v1/documents/templates/DocumentsLinkTemplate.php create mode 100644 api-wiaas/server/components/v1/documents/templates/DocumentsTemplate.php create mode 100644 api-wiaas/server/components/v1/documents/templates/DocumentsViewTemplate.php create mode 100644 api-wiaas/server/components/v1/documents/templates/LinkDocumentsButton.php create mode 100644 api-wiaas/server/components/v1/documents/templates/LinkDocumentsLayer.php create mode 100644 api-wiaas/server/components/v1/financing/FinancingController.php create mode 100644 api-wiaas/server/components/v1/financing/FinancingModel.php create mode 100644 api-wiaas/server/components/v1/financing/FinancingPage.php create mode 100644 api-wiaas/server/components/v1/financing/InterestRate.php create mode 100644 api-wiaas/server/components/v1/financing/templates/FinancingTempalte.php create mode 100644 api-wiaas/server/components/v1/financing/templates/SetCustomersDiscountTemplate.php create mode 100644 api-wiaas/server/components/v1/financing/templates/SetInterestRateTemplate.php create mode 100644 api-wiaas/server/components/v1/home/HomeController.php create mode 100644 api-wiaas/server/components/v1/home/apiTemplate.php create mode 100644 api-wiaas/server/components/v1/home/excelTemplate.php create mode 100644 api-wiaas/server/components/v1/home/htmlTemplate.php create mode 100644 api-wiaas/server/components/v1/home/menuTemplate.php create mode 100644 api-wiaas/server/components/v1/home/pageTemplate.php create mode 100644 api-wiaas/server/components/v1/home/scriptTemplate.php create mode 100644 api-wiaas/server/components/v1/home/templates/FooterTemplate.php create mode 100644 api-wiaas/server/components/v1/home/templates/ShopCartIconTemplate.php create mode 100644 api-wiaas/server/components/v1/home/templates/cssIncludes.php create mode 100644 api-wiaas/server/components/v1/home/templates/jsIncludes.php create mode 100644 api-wiaas/server/components/v1/home/templates/loginCssIncludes.php create mode 100644 api-wiaas/server/components/v1/home/templates/loginJsIncludes.php create mode 100644 api-wiaas/server/components/v1/login/LoginController.php create mode 100644 api-wiaas/server/components/v1/login/LoginPage.php create mode 100644 api-wiaas/server/components/v1/login/templates/ForgotPasswordForm.php create mode 100644 api-wiaas/server/components/v1/login/templates/LoginForm.php create mode 100644 api-wiaas/server/components/v1/login/templates/ResetPasswordForm.php create mode 100644 api-wiaas/server/components/v1/orderProjects/OrderProjects.php create mode 100644 api-wiaas/server/components/v1/orderProjects/OrderProjectsController.php create mode 100644 api-wiaas/server/components/v1/orderProjects/OrderProjectsModel.php create mode 100644 api-wiaas/server/components/v1/orderProjects/templates/OrderProjectsEditTemplate.php create mode 100644 api-wiaas/server/components/v1/orderProjects/templates/OrderProjectsTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/InstallationScheduling.php create mode 100644 api-wiaas/server/components/v1/orders/OrderActions.php create mode 100644 api-wiaas/server/components/v1/orders/OrderDocuments.php create mode 100644 api-wiaas/server/components/v1/orders/OrderExtraActions.php create mode 100644 api-wiaas/server/components/v1/orders/OrderHelper.php create mode 100644 api-wiaas/server/components/v1/orders/OrderProcessHelper.php create mode 100644 api-wiaas/server/components/v1/orders/OrderTraking.php create mode 100644 api-wiaas/server/components/v1/orders/OrdersController.php create mode 100644 api-wiaas/server/components/v1/orders/OrdersModel.php create mode 100644 api-wiaas/server/components/v1/orders/OrdersPage.php create mode 100644 api-wiaas/server/components/v1/orders/Procurement.php create mode 100644 api-wiaas/server/components/v1/orders/SupplierEstimations.php create mode 100644 api-wiaas/server/components/v1/orders/templates/AddDocumentsToOrderLayer.html create mode 100644 api-wiaas/server/components/v1/orders/templates/AssignBrokerLayer.html create mode 100644 api-wiaas/server/components/v1/orders/templates/AssignBrokerTemplate.html create mode 100644 api-wiaas/server/components/v1/orders/templates/CancelOrderButton.html create mode 100644 api-wiaas/server/components/v1/orders/templates/ChangeOrderEstimationDate.html create mode 100644 api-wiaas/server/components/v1/orders/templates/ChangeOrdersStepsButton.html create mode 100644 api-wiaas/server/components/v1/orders/templates/ChangeOrdersStepsTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/DisplayEarliestInstallationDate.html create mode 100644 api-wiaas/server/components/v1/orders/templates/GoToNextStepButton.html create mode 100644 api-wiaas/server/components/v1/orders/templates/InstallationSchedulerBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/InstallationSchedulerCustomerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/InstallationSchedulerSupplierTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/InstallationSchedulingDatesTemplate.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrderDetailsAllTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/OrderDetailsCommercialLead.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrderDetailsCustomer.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrderDetailsSupplierTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/OrderEstimationDate.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrderStepFullDescriptionButton.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrdersDetailsTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/OrdersStepEditInfo.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrdersStepInfo.html create mode 100644 api-wiaas/server/components/v1/orders/templates/OrdersTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/SetDeliveryDatesTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/SetProcessForPackage.html create mode 100644 api-wiaas/server/components/v1/orders/templates/ShowDeliveryDatesCLTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/ShowPackageUnassignedProcess.html create mode 100644 api-wiaas/server/components/v1/orders/templates/SuppliersProcurementViewTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/SupportMailTemplate.html create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/chooseInstallationBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/chooseInstallationCustomerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/chooseInstallationTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/customerAcceptanceBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/customerAcceptanceCustomerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/customerAcceptanceTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/procurementBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/procurementSupplierTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/procurementTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/scheduleMeetingBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/scheduleMeetingCustomerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/scheduleMeetingTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/validateQuestionnaireBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/validateQuestionnaireCustomerTemplate.php create mode 100644 api-wiaas/server/components/v1/orders/templates/extra-actions/validateQuestionnaireTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/CustomerPackages.php create mode 100644 api-wiaas/server/components/v1/packages/PacakgeOptionsManager.php create mode 100644 api-wiaas/server/components/v1/packages/PackageDocuments.php create mode 100644 api-wiaas/server/components/v1/packages/Packages.php create mode 100644 api-wiaas/server/components/v1/packages/PackagesController.php create mode 100644 api-wiaas/server/components/v1/packages/PackagesModel.php create mode 100644 api-wiaas/server/components/v1/packages/PackagesPage.php create mode 100644 api-wiaas/server/components/v1/packages/templates/AddVirtualProductsTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/CreatePackagesButton.html create mode 100644 api-wiaas/server/components/v1/packages/templates/CreatePackagesFromTemplateButton.html create mode 100644 api-wiaas/server/components/v1/packages/templates/CreatePackagesFromTemplateLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/CreatePackagesFromTemplateTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/CreatePackagesLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/CreatePackagesTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/CreateTemplatePackagesButton.html create mode 100644 api-wiaas/server/components/v1/packages/templates/CreateTemplatePackagesLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/CreateTemplatePackagesTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/DisplayCdnImagesTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/EditPackageTemplatesButton.html create mode 100644 api-wiaas/server/components/v1/packages/templates/EditPackageTemplatesHtml.php create mode 100644 api-wiaas/server/components/v1/packages/templates/EditPackageTemplatesLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/EditPackagesButton.html create mode 100644 api-wiaas/server/components/v1/packages/templates/EditPackagesLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/EditPackagesTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/MyPackagesBtn.html create mode 100644 api-wiaas/server/components/v1/packages/templates/MyPackagesDetails.html create mode 100644 api-wiaas/server/components/v1/packages/templates/MyPackagesLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/PackageOptionsTemplate.html create mode 100644 api-wiaas/server/components/v1/packages/templates/PackageOptionsTemplateButton.html create mode 100644 api-wiaas/server/components/v1/packages/templates/PackageOptionsTemplateLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/PackagesDetailsTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/PackagesTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/ProductsByCategoriesDragDropTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/ProductsTemplateByCategoriesDragDropTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/SelectPackage.html create mode 100644 api-wiaas/server/components/v1/packages/templates/SelectPackageLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/SetPackagePrice.html create mode 100644 api-wiaas/server/components/v1/packages/templates/SetPackagePriceLayer.html create mode 100644 api-wiaas/server/components/v1/packages/templates/UploadImageCdnTemplate.php create mode 100644 api-wiaas/server/components/v1/packages/templates/packagesDetailsBroker/PackagesDetailsBrokerLinkOptionsBigBtn.html create mode 100644 api-wiaas/server/components/v1/packages/templates/packagesDetailsBroker/PackagesDetailsBrokerLinkOptionsBtn.html create mode 100644 api-wiaas/server/components/v1/packages/templates/packagesDetailsBroker/PackagesDetailsBrokerSetAdditonalPriceBtn.html create mode 100644 api-wiaas/server/components/v1/packages/templates/packagesDetailsBroker/PackagesDetailsBrokerSetOptionPriceBtn.html create mode 100644 api-wiaas/server/components/v1/packages/templates/packagesDetailsBroker/PackagesDetailsBrokerSetPriceBtn.html create mode 100644 api-wiaas/server/components/v1/prices/Prices.php create mode 100644 api-wiaas/server/components/v1/processes/ProcessesController.php create mode 100644 api-wiaas/server/components/v1/processes/ProcessesModel.php create mode 100644 api-wiaas/server/components/v1/processes/ProcessesPage.php create mode 100644 api-wiaas/server/components/v1/processes/templates/CopyProcessesTemplate.php create mode 100644 api-wiaas/server/components/v1/processes/templates/CreateProcessTemplate.php create mode 100644 api-wiaas/server/components/v1/processes/templates/EditProcessesTemplate.php create mode 100644 api-wiaas/server/components/v1/processes/templates/LinkProcessTemplate.php create mode 100644 api-wiaas/server/components/v1/processes/templates/ProcessesTemplate.php create mode 100644 api-wiaas/server/components/v1/processes/templates/ViewPackageProcessesTemplate.php create mode 100644 api-wiaas/server/components/v1/profile-settings/ProfileSettingsController.php create mode 100644 api-wiaas/server/components/v1/profile-settings/ProfileSettingsPage.php create mode 100644 api-wiaas/server/components/v1/profile-settings/templates/ChangePasswordTemplate.php create mode 100644 api-wiaas/server/components/v1/profile-settings/templates/EditProfileTemplate.php create mode 100644 api-wiaas/server/components/v1/profile-settings/templates/ProfileSettingsTemplate.php create mode 100644 api-wiaas/server/components/v1/shop/ShopController.php create mode 100644 api-wiaas/server/components/v1/shop/ShopModel.php create mode 100644 api-wiaas/server/components/v1/shop/ShopPage.php create mode 100644 api-wiaas/server/components/v1/shop/templates/CartReview.php create mode 100644 api-wiaas/server/components/v1/shop/templates/ShopCartTemplate.php create mode 100644 api-wiaas/server/components/v1/shop/templates/ShopPackageDetailsTemplate.php create mode 100644 api-wiaas/server/components/v1/shop/templates/ShopPackageSearchTemplate.php create mode 100644 api-wiaas/server/components/v1/shop/templates/ShopPackagesTemplate.php create mode 100644 api-wiaas/server/components/v1/shop/templates/ShopTemplate.php create mode 100644 api-wiaas/server/components/v1/suppliers/SuppliersController.php create mode 100644 api-wiaas/server/components/v1/suppliers/SuppliersModel.php create mode 100644 api-wiaas/server/components/v1/suppliers/SuppliersPage.php create mode 100644 api-wiaas/server/components/v1/suppliers/SuppliersProducts.php create mode 100644 api-wiaas/server/components/v1/suppliers/templates/ShowProductDocumentsTemplate.php create mode 100644 api-wiaas/server/components/v1/suppliers/templates/SuppliersAddEditFormTemplate.php create mode 100644 api-wiaas/server/components/v1/suppliers/templates/SuppliersProductsAddEditFormTemplate.php create mode 100644 api-wiaas/server/components/v1/suppliers/templates/SuppliersTemplate.php create mode 100644 api-wiaas/server/components/v1/suppliers/templates/UploadProductDocumentTempalte.php create mode 100644 api-wiaas/server/components/v1/terms/TermsController.php create mode 100644 api-wiaas/server/components/v1/terms/TermsModel.php create mode 100644 api-wiaas/server/components/v1/terms/TermsPage.php create mode 100644 api-wiaas/server/components/v1/translate/TranslateController.php create mode 100644 api-wiaas/server/components/v1/translate/languages/en.json create mode 100644 api-wiaas/server/components/v1/translate/languages/login_en.json create mode 100644 api-wiaas/server/components/v1/translate/languages/ro.json create mode 100644 api-wiaas/server/components/v1/translate/templates/LanguagesTemplate.php create mode 100644 api-wiaas/server/components/v1/users/UsersController.php create mode 100644 api-wiaas/server/components/v1/users/UsersModel.php create mode 100644 api-wiaas/server/components/v1/users/UsersPage.php create mode 100644 api-wiaas/server/components/v1/users/templates/CreateUserButton.html create mode 100644 api-wiaas/server/components/v1/users/templates/CreateUserLayer.html create mode 100644 api-wiaas/server/components/v1/users/templates/CreateUserTemplate.php create mode 100644 api-wiaas/server/components/v1/users/templates/LinkCustomersButton.html create mode 100644 api-wiaas/server/components/v1/users/templates/LinkCustomersLayer.html create mode 100644 api-wiaas/server/components/v1/users/templates/LinkCustomersTemplate.php create mode 100644 api-wiaas/server/components/v1/users/templates/ShowEditUsersTemplate.php create mode 100644 api-wiaas/server/components/v1/users/templates/UsersTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/UtilsController.php create mode 100644 api-wiaas/server/components/v1/utils/UtilsModel.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/changedPasswordTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/createUserTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/customerScheduleInstallationEnabled.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/errorMailTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/generatePasswordUserTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/installationAcceptedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/installationDateInvalidTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/installationDeclinedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/installationProposedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/installationSchedulingDisabled.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/invalidQuestionnaireTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/lastStepCompletedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/orderCommentAddedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationBrokerTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/orderStatusChangedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/orderStepUpdatedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/packageStatusChangedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/processAssignedTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/reUploadQuestionnaireTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/scheduleMeetingTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/supportMailTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/testTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/mail_templates/undoStepTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/templates/activityCheckerTemplate.php create mode 100644 api-wiaas/server/components/v1/utils/templates/errorDialogTemplate.php create mode 100644 api-wiaas/server/components/v2/bids/Bids.php create mode 100644 api-wiaas/server/components/v2/bids/SupplierBids.php create mode 100644 api-wiaas/server/components/v2/cart/CartController.php create mode 100644 api-wiaas/server/components/v2/cart/CartModel.php create mode 100644 api-wiaas/server/components/v2/coMarket/CoMarketController.php create mode 100644 api-wiaas/server/components/v2/coMarket/CoMarketModel.php create mode 100644 api-wiaas/server/components/v2/customers/ClCustomers.php create mode 100644 api-wiaas/server/components/v2/customers/OrderType.php create mode 100644 api-wiaas/server/components/v2/dashboards/DashboardsController.php create mode 100644 api-wiaas/server/components/v2/dashboards/DashboardsModel.php create mode 100644 api-wiaas/server/components/v2/financing/FinancingController.php create mode 100644 api-wiaas/server/components/v2/financing/FinancingModel.php create mode 100644 api-wiaas/server/components/v2/financing/InterestRate.php create mode 100644 api-wiaas/server/components/v2/helpers/AddressHelper.php create mode 100644 api-wiaas/server/components/v2/helpers/Countries.php create mode 100644 api-wiaas/server/components/v2/home/apiTemplate.php create mode 100644 api-wiaas/server/components/v2/login/LoginController.php create mode 100644 api-wiaas/server/components/v2/login/LoginModel.php create mode 100644 api-wiaas/server/components/v2/orderProjects/OrderProjects.php create mode 100644 api-wiaas/server/components/v2/orderProjects/OrderProjectsController.php create mode 100644 api-wiaas/server/components/v2/orderProjects/OrderProjectsModel.php create mode 100644 api-wiaas/server/components/v2/orders/CustomerAcceptance.php create mode 100644 api-wiaas/server/components/v2/orders/InstallationScheduling.php create mode 100644 api-wiaas/server/components/v2/orders/OrderDocuments.php create mode 100644 api-wiaas/server/components/v2/orders/OrderExtraActions.php create mode 100644 api-wiaas/server/components/v2/orders/OrderProcessHelper.php create mode 100644 api-wiaas/server/components/v2/orders/OrdersController.php create mode 100644 api-wiaas/server/components/v2/orders/OrdersModel.php create mode 100644 api-wiaas/server/components/v2/packages/PackageDocuments.php create mode 100644 api-wiaas/server/components/v2/packages/Packages.php create mode 100644 api-wiaas/server/components/v2/prices/Prices.php create mode 100644 api-wiaas/server/components/v2/profileSettings/ProfileSettingsController.php create mode 100644 api-wiaas/server/components/v2/profileSettings/ProfileSettingsModel.php create mode 100644 api-wiaas/server/components/v2/terms/TermsController.php create mode 100644 api-wiaas/server/components/v2/terms/TermsModel.php create mode 100644 api-wiaas/server/components/v2/users/UsersHelper.php create mode 100644 api-wiaas/server/components/v2/utils/UtilsController.php create mode 100644 api-wiaas/server/components/v2/utils/UtilsModel.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/changedPasswordTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/createUserTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/customerScheduleInstallationEnabled.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/errorMailTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/generatePasswordUserTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/installationAcceptedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/installationDateInvalidTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/installationDeclinedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/installationProposedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/installationSchedulingDisabled.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/invalidQuestionnaireTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/lastStepCompletedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/orderCommentAddedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationBrokerTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/orderStatusChangedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/orderStepUpdatedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/packageStatusChangedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/processAssignedTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/reUploadQuestionnaireTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/scheduleMeetingTemplate.php create mode 100644 api-wiaas/server/components/v2/utils/mail_templates/supportMailTemplate.php create mode 100644 api-wiaas/server/core/Database.php create mode 100644 api-wiaas/server/core/ErrorHandler.php create mode 100644 api-wiaas/server/core/FileManager.php create mode 100644 api-wiaas/server/core/HeadersHelper.php create mode 100644 api-wiaas/server/core/Mail.php create mode 100644 api-wiaas/server/core/Routes.php create mode 100644 api-wiaas/server/core/User.php create mode 100644 client-wiaas/.gitignore create mode 100644 client-wiaas/package-lock.json create mode 100644 client-wiaas/package.json create mode 100644 client-wiaas/public/.htaccess create mode 100644 client-wiaas/public/index.html create mode 100644 client-wiaas/public/manifest.json create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/README.md create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-demo.html create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.woff create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.woff2 create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-demo.html create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.eot create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.woff create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.woff2 create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-demo.html create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.eot create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-demo.html create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.eot create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.woff create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.woff2 create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.eot create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.woff create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.eot create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.woff2 create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.eot create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.svg create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.ttf create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.woff create mode 100644 client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.woff2 create mode 100644 client-wiaas/public/static/img/CoMarketStartsida_MAIN.JPG create mode 100644 client-wiaas/public/static/img/CoMarketStartsida_OFFERCoor.jpg create mode 100644 client-wiaas/public/static/img/HC.PNG create mode 100644 client-wiaas/public/static/img/HC_FixedHuddle_interior.png create mode 100644 client-wiaas/public/static/img/HC_FixedHuddle_interior_small_resize.png create mode 100644 client-wiaas/public/static/img/HC_MiniHuddle_interior_small.png create mode 100644 client-wiaas/public/static/img/HC_MobileHuddle_interior.png create mode 100644 client-wiaas/public/static/img/HC_MobileHuddle_interior_small_resize.png create mode 100644 client-wiaas/public/static/img/HC_PreHuddle_interior_small.png create mode 100644 client-wiaas/public/static/img/Huddle.png create mode 100644 client-wiaas/public/static/img/IWB.PNG create mode 100644 client-wiaas/public/static/img/VCP.PNG create mode 100644 client-wiaas/public/static/img/commercial.png create mode 100644 client-wiaas/public/static/img/hc_cut.png create mode 100644 client-wiaas/public/static/img/hc_cut2.png create mode 100644 client-wiaas/public/static/img/iwb_cut.png create mode 100644 client-wiaas/public/static/img/iwb_cut1.png create mode 100644 client-wiaas/public/static/img/logoDefault.svg create mode 100644 client-wiaas/public/static/img/man-icon.png create mode 100644 client-wiaas/public/static/img/no-photo-package.jpg create mode 100644 client-wiaas/public/static/img/package-no-photo.png create mode 100644 client-wiaas/public/static/img/vcp_cut.png create mode 100644 client-wiaas/public/static/img/video.png create mode 100644 client-wiaas/public/static/img/wiaas-favicon.png create mode 100644 client-wiaas/public/static/img/wiaas_icon.png create mode 100644 client-wiaas/public/static/js/tinymce/LICENSE.TXT create mode 100644 client-wiaas/public/static/js/tinymce/changelog.txt create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/jquery.tinymce.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/langs/readme.md create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/license.txt create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/advlist/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/anchor/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/autolink/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/autoresize/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/autosave/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/bbcode/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/charmap/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/code/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/codesample/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/colorpicker/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/contextmenu/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/directionality/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-cool.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-cry.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-embarassed.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-frown.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-innocent.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-kiss.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-laughing.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-money-mouth.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-sealed.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-smile.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-surprised.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-tongue-out.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-undecided.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-wink.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/img/smiley-yell.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/emoticons/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/fullpage/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/fullscreen/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/help/img/logo.png create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/help/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/hr/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/image/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/imagetools/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/importcss/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/insertdatetime/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/legacyoutput/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/link/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/lists/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/media/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/nonbreaking/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/noneditable/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/pagebreak/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/paste/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/preview/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/print/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/save/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/searchreplace/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/spellchecker/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/tabfocus/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/table/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/template/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/textcolor/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/textpattern/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/toc/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/visualblocks/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/visualchars/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/plugins/wordcount/plugin.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-mobile.woff create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.eot create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.svg create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.woff create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.eot create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.svg create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.ttf create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.woff create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/img/anchor.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/img/loader.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/img/object.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/skins/lightgray/img/trans.gif create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/themes/inlite/theme.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/themes/mobile/theme.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/themes/modern/theme.min.js create mode 100644 client-wiaas/public/static/js/tinymce/js/tinymce/tinymce.min.js create mode 100644 client-wiaas/scripts/update_applciaiton_mode.php create mode 100644 client-wiaas/src/App.js create mode 100644 client-wiaas/src/App.scss create mode 100644 client-wiaas/src/App.test.js create mode 100644 client-wiaas/src/actions/bids/bidsActions.js create mode 100644 client-wiaas/src/actions/cart/cartActions.js create mode 100644 client-wiaas/src/actions/coMarket/coMarketActions.js create mode 100644 client-wiaas/src/actions/coMarket/coMarketPackageDetailsActions.js create mode 100644 client-wiaas/src/actions/coMarket/coMarketPackagesActions.js create mode 100644 client-wiaas/src/actions/dashboard/dashboardActions.js create mode 100644 client-wiaas/src/actions/dashboard/nextActionsActions.js create mode 100644 client-wiaas/src/actions/dashboard/ordersActions.js create mode 100644 client-wiaas/src/actions/dialog/dialogActions.js create mode 100644 client-wiaas/src/actions/login/authActions.js create mode 100644 client-wiaas/src/actions/notification/notificationActions.js create mode 100644 client-wiaas/src/actions/orderProjects/orderProjectsActions.js create mode 100644 client-wiaas/src/actions/orders/customerAcceptanceActions.js create mode 100644 client-wiaas/src/actions/orders/ordersActions.js create mode 100644 client-wiaas/src/actions/orders/processActions.js create mode 100644 client-wiaas/src/actions/page/pageActions.js create mode 100644 client-wiaas/src/actions/profileSettings/addressActions.js create mode 100644 client-wiaas/src/actions/profileSettings/profileSettingsActions.js create mode 100644 client-wiaas/src/config.js create mode 100644 client-wiaas/src/configureStore.js create mode 100644 client-wiaas/src/constants/appContainers.js create mode 100644 client-wiaas/src/constants/authConstants.js create mode 100644 client-wiaas/src/constants/bidsConstants.js create mode 100644 client-wiaas/src/constants/cartConstants.js create mode 100644 client-wiaas/src/constants/coMarketConstants.js create mode 100644 client-wiaas/src/constants/dashboardConstants.js create mode 100644 client-wiaas/src/constants/dialogConstants.js create mode 100644 client-wiaas/src/constants/menuConstants.jsx create mode 100644 client-wiaas/src/constants/notificationConstants.js create mode 100644 client-wiaas/src/constants/orderProjectsConstants.js create mode 100644 client-wiaas/src/constants/ordersConstants.js create mode 100644 client-wiaas/src/constants/pageConstants.js create mode 100644 client-wiaas/src/constants/profileSettingsConstants.js create mode 100644 client-wiaas/src/constants/termsConstants.js create mode 100644 client-wiaas/src/containers/ContentContainer.jsx create mode 100644 client-wiaas/src/containers/cart/CartContainer.jsx create mode 100644 client-wiaas/src/containers/cart/CartCustomerDetailsContainer.jsx create mode 100644 client-wiaas/src/containers/cart/CartItemsContainer.jsx create mode 100644 client-wiaas/src/containers/cart/CartReviewOrderContainer.jsx create mode 100644 client-wiaas/src/containers/cart/CartStepsContainer.jsx create mode 100644 client-wiaas/src/containers/cart/CartUploadDocumentsContainer.jsx create mode 100644 client-wiaas/src/containers/cart/components/AddOrderProject.jsx create mode 100644 client-wiaas/src/containers/cart/components/BidItem.jsx create mode 100644 client-wiaas/src/containers/cart/components/BidsList.jsx create mode 100644 client-wiaas/src/containers/cart/components/CartIcon.jsx create mode 100644 client-wiaas/src/containers/cart/components/CartItem.jsx create mode 100644 client-wiaas/src/containers/cart/components/CartUploadDocument.jsx create mode 100644 client-wiaas/src/containers/cart/components/OrderProjectsSelect.jsx create mode 100644 client-wiaas/src/containers/cart/components/PackageBids.jsx create mode 100644 client-wiaas/src/containers/cart/components/SelectBillingAddress.jsx create mode 100644 client-wiaas/src/containers/cart/components/SelectDeliveryAddress.jsx create mode 100644 client-wiaas/src/containers/cart/style/Cart.scss create mode 100644 client-wiaas/src/containers/cart/style/CartStepsContainer.scss create mode 100644 client-wiaas/src/containers/cart/style/CartUploadDocumentsContainer.scss create mode 100644 client-wiaas/src/containers/cart/style/OrderProjects.scss create mode 100644 client-wiaas/src/containers/cart/style/PacakgeBids.scss create mode 100644 client-wiaas/src/containers/coMarket/CoMarketContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/CoMarketNavContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/CoMarketPackageDetailsContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/CoMarketPackagesContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/AdditionalPackageItemContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/AdditionalPackages.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/AgreementOptionItemContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/AgreementOptions.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/CartIcon.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/CoMarketCatalogSelect.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/PackageInfo.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/PackageOptionItemContainer.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/PackageOptions.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/PackagePrice.jsx create mode 100644 client-wiaas/src/containers/coMarket/components/ShopItem.jsx create mode 100644 client-wiaas/src/containers/coMarket/style/CoMarket.scss create mode 100644 client-wiaas/src/containers/coMarket/style/CoMarketPackageDetailsContainer.scss create mode 100644 client-wiaas/src/containers/contentContainer.scss create mode 100644 client-wiaas/src/containers/dashboard/Dashboards.scss create mode 100644 client-wiaas/src/containers/dashboard/DashboardsContainer.jsx create mode 100644 client-wiaas/src/containers/dashboard/NextActions.scss create mode 100644 client-wiaas/src/containers/dashboard/NextActionsContainer.jsx create mode 100644 client-wiaas/src/containers/dashboard/OrderCentral.scss create mode 100644 client-wiaas/src/containers/dashboard/OrderCentralContainer.jsx create mode 100644 client-wiaas/src/containers/dashboard/components/NextActionItem.jsx create mode 100644 client-wiaas/src/containers/dashboard/components/NextActionsList.jsx create mode 100644 client-wiaas/src/containers/dashboard/components/OrderItem.jsx create mode 100644 client-wiaas/src/containers/dashboard/components/OrdersList.jsx create mode 100644 client-wiaas/src/containers/footer/Footer.jsx create mode 100644 client-wiaas/src/containers/footer/style/Footer.scss create mode 100644 client-wiaas/src/containers/login/ChangePasswordContainer.jsx create mode 100644 client-wiaas/src/containers/login/LogInContainer.jsx create mode 100644 client-wiaas/src/containers/login/LogInForm.jsx create mode 100644 client-wiaas/src/containers/login/login.scss create mode 100644 client-wiaas/src/containers/orders/InstallationSchedulingContainer.jsx create mode 100644 client-wiaas/src/containers/orders/OrdersContainer.jsx create mode 100644 client-wiaas/src/containers/orders/OrdersDataContainer.jsx create mode 100644 client-wiaas/src/containers/orders/ProcessContainer.jsx create mode 100644 client-wiaas/src/containers/orders/ProcessNavContainer.jsx create mode 100644 client-wiaas/src/containers/orders/components/ActiveOrderItem.jsx create mode 100644 client-wiaas/src/containers/orders/components/AddComment.jsx create mode 100644 client-wiaas/src/containers/orders/components/HistoryOrderButtons.jsx create mode 100644 client-wiaas/src/containers/orders/components/HistoryOrderItem.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderComments.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderDocuments.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderDocumentsGroup.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderInfo.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderList.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderListHeader.jsx create mode 100644 client-wiaas/src/containers/orders/components/OrderPackage.jsx create mode 100644 client-wiaas/src/containers/orders/components/PackagesNav.jsx create mode 100644 client-wiaas/src/containers/orders/components/SupportMail.jsx create mode 100644 client-wiaas/src/containers/orders/components/installationScheduling/InstallationSchedulingDatesPerPackage.jsx create mode 100644 client-wiaas/src/containers/orders/components/installationScheduling/InstallationSchedulingForPackages.jsx create mode 100644 client-wiaas/src/containers/orders/components/installationScheduling/InstallationSchedulingPerPackage.jsx create mode 100644 client-wiaas/src/containers/orders/components/packages/PackageInfo.jsx create mode 100644 client-wiaas/src/containers/orders/components/packages/PackageName.jsx create mode 100644 client-wiaas/src/containers/orders/components/packages/ProcessPackage.jsx create mode 100644 client-wiaas/src/containers/orders/components/process/AcceptanceDeclineReason.jsx create mode 100644 client-wiaas/src/containers/orders/components/process/CustomerAcceptance.jsx create mode 100644 client-wiaas/src/containers/orders/components/process/OrderProcess.jsx create mode 100644 client-wiaas/src/containers/orders/components/process/ProcessStep.jsx create mode 100644 client-wiaas/src/containers/orders/components/process/ValidateQuestionnaire.jsx create mode 100644 client-wiaas/src/containers/orders/components/process/ValidateQuestionnaireItem.jsx create mode 100644 client-wiaas/src/containers/orders/style/CustomerAcceptance.scss create mode 100644 client-wiaas/src/containers/orders/style/InstallationScheduling.scss create mode 100644 client-wiaas/src/containers/orders/style/Orders.scss create mode 100644 client-wiaas/src/containers/orders/style/OrdersList.scss create mode 100644 client-wiaas/src/containers/orders/style/ProcessContainer.scss create mode 100644 client-wiaas/src/containers/orders/style/ProcessNavContainer.scss create mode 100644 client-wiaas/src/containers/orders/style/ValidateQuestionnaire.scss create mode 100644 client-wiaas/src/containers/profileSettings/BillingAddressesContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/ChangePasswordContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/CompanyEditContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/ProfileAddressesContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/ProfileEditContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/ProfileSettingsContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/ProfileShowContainer.jsx create mode 100644 client-wiaas/src/containers/profileSettings/components/AddEditBillingAddress.jsx create mode 100644 client-wiaas/src/containers/profileSettings/components/AddEditProfileAddress.jsx create mode 100644 client-wiaas/src/containers/profileSettings/components/BillingAddress.jsx create mode 100644 client-wiaas/src/containers/profileSettings/components/ProfileAddress.jsx create mode 100644 client-wiaas/src/containers/profileSettings/components/RemoveBillingAddress.jsx create mode 100644 client-wiaas/src/containers/profileSettings/components/RemoveProfileAddress.jsx create mode 100644 client-wiaas/src/containers/profileSettings/style/AddressesContainer.scss create mode 100644 client-wiaas/src/containers/profileSettings/style/ProfieSettingsContainer.scss create mode 100644 client-wiaas/src/containers/profileSettings/style/ProfileShowContainer.scss create mode 100644 client-wiaas/src/containers/terms/TermsContainer.jsx create mode 100644 client-wiaas/src/containers/terms/termsContainer.scss create mode 100644 client-wiaas/src/helpers/FileDownloader.js create mode 100644 client-wiaas/src/helpers/HtmlClient.js create mode 100644 client-wiaas/src/helpers/coMarket/PriceHelper.js create mode 100644 client-wiaas/src/index.js create mode 100644 client-wiaas/src/index.scss create mode 100644 client-wiaas/src/mainComponents/box/WiaasBox.jsx create mode 100644 client-wiaas/src/mainComponents/box/WiaasBox.scss create mode 100644 client-wiaas/src/mainComponents/dialog/DialogBox.jsx create mode 100644 client-wiaas/src/mainComponents/dialog/DialogBox.scss create mode 100644 client-wiaas/src/mainComponents/menu/Menu.jsx create mode 100644 client-wiaas/src/mainComponents/menu/Submenu.jsx create mode 100644 client-wiaas/src/mainComponents/menu/menu.scss create mode 100644 client-wiaas/src/mainComponents/notification/NotificationBox.jsx create mode 100644 client-wiaas/src/mainComponents/notification/notificationBox.scss create mode 100644 client-wiaas/src/mainComponents/table/WiaasTable.jsx create mode 100644 client-wiaas/src/mainComponents/table/WiaasTable.scss create mode 100644 client-wiaas/src/mainComponents/wiaasRouter/MyComponent.jsx create mode 100644 client-wiaas/src/mainComponents/wiaasRouter/WiaasRouter.jsx create mode 100644 client-wiaas/src/reducers/cart/cartReducers.js create mode 100644 client-wiaas/src/reducers/coMarket/coMarketPackageDetailsReducers.js create mode 100644 client-wiaas/src/reducers/coMarket/coMarketPackagesReducers.js create mode 100644 client-wiaas/src/reducers/coMarket/coMarketReducers.js create mode 100644 client-wiaas/src/reducers/dashboard/dashboardReducers.js create mode 100644 client-wiaas/src/reducers/dashboard/nextActionsReducers.js create mode 100644 client-wiaas/src/reducers/dashboard/ordersCentralReducer.js create mode 100644 client-wiaas/src/reducers/dialog/dialogReducers.js create mode 100644 client-wiaas/src/reducers/index.js create mode 100644 client-wiaas/src/reducers/login/authReducers.js create mode 100644 client-wiaas/src/reducers/notification/notificationReducers.js create mode 100644 client-wiaas/src/reducers/orderProjects/orderProjectsReducer.js create mode 100644 client-wiaas/src/reducers/orders/ordersReducers.js create mode 100644 client-wiaas/src/reducers/orders/processReducers.js create mode 100644 client-wiaas/src/reducers/page/pageReducer.js create mode 100644 client-wiaas/src/reducers/profileSettings/profileSettingsReducers.js create mode 100644 client-wiaas/src/registerServiceWorker.js create mode 100644 client-wiaas/src/styleConstants.scss create mode 100644 client-wiaas/src/svg/logoAlternative.svg create mode 100644 client-wiaas/src/svg/logoDefault.svg create mode 100644 client-wiaas/src/svg/logoWhite.svg create mode 100644 client-wiaas/src/svg/profile.svg create mode 100644 documentation/gitlab_runners.txt create mode 100644 package-lock.json create mode 100644 sql-dump/comarket_2018-06-08.sql diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..d88456a --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,36 @@ +update_sandbox_repo: + stage: build + only: + - develop + script: +# - cd /gitlab/www-sandbox/dashboard/client/uploads/ +# - mkdir dummyFolderToBeDeleted +# - ls | grep -v 'templateQuestionaire\|orderQuestionaire\|configuration\|customerAcceptance\|installGuide' | xargs rm -fR + - rm -f api-wiaas/client/uploads/orderQuestionaire/* + - rm -f api-wiaas/client/uploads/configuration/* + - rm -f api-wiaas/client/uploads/customerAcceptance/* + - cd /gitlab/www-sandbox/dashboard/ + - git checkout -- . + - git pull + - php api-wiaas/sandbox_scripts/update_application_mode.php + - cd api-wiaas + - composer install + - cd .. + - cd client-wiaas + - php scripts/update_applciaiton_mode.php + - npm install + - npm run-script build + - cp -R /gitlab/www-sandbox/dashboard/client-wiaas/build/. /gitlab/www-sandbox/wiaasBuild + - cp -R /gitlab/www-sandbox/dashboard/api-wiaas /gitlab/www-sandbox/wiaasBuild + tags: + - dev-jobs + +wiias_test: + stage: test + only: + - develop + script: + - cd /gitlab/jenkins_cli + - java -jar jenkins-cli.jar -i /home/qa_automated_tests_user/.ssh/id_rsa -s http://jenkinsmaster.saguaronet.ro:8081/ build test-automation -s -v + tags: + - tests diff --git a/README.md b/README.md new file mode 100644 index 0000000..6399c6f --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# RICOH WIAAS + +### ENVIROMENT + +- PHP 7.0 +- MYSQL 5.7.22 +- NODE 8.0 + + +## APPLICATION API + +- install wamp or LAMP depending on the envirorment (or any other service that provides php + mysql) + Make sure that "rewrite" is allowed and enabled in APACHE server + +- create /public folder and configure apache to serve this folder as root folder + +- install composer + +-run `php composer install` in api-wiaas folder to get required libraries + +- create symlink to for /api-wiaas in /public directory + +-for old interface run `grunt` in api-wiaas to generated stylesheets + + +## APPLICATION CLIENT +JavasScript (React + Redux) + +- npm install in client-wiaas to update required libraries + +- npm run build + +- copy content of build folder to /public directory + +- npm start in client-wiaas to start the applicaiton diff --git a/api-wiaas/.bowerrc b/api-wiaas/.bowerrc new file mode 100644 index 0000000..cc2a80e --- /dev/null +++ b/api-wiaas/.bowerrc @@ -0,0 +1,5 @@ +{ + "directory": "client/js/bower_components", + "proxy": "http://proxy.saguaronet.ro:3128", + "https-proxy":"http://proxy.saguaronet.ro:3128" +} diff --git a/api-wiaas/.eslintrc.json b/api-wiaas/.eslintrc.json new file mode 100644 index 0000000..d798333 --- /dev/null +++ b/api-wiaas/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es6": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "curly": 2, + "block-scoped-var": 2, + "eqeqeq": 2, + "no-eval": 2, + "no-fallthrough": 2, + "no-multi-spaces": 2, + "no-param-reassign": 2, + "no-redeclare": 2, + "vars-on-top": 1, + "camelcase": 2, + "no-trailing-spaces": 2, + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "windows" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ] + } +} diff --git a/api-wiaas/.gitignore b/api-wiaas/.gitignore new file mode 100644 index 0000000..d7c2a17 --- /dev/null +++ b/api-wiaas/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +client/uploads +api-wiaas/client/js/bower_components +vendor diff --git a/api-wiaas/.htaccess b/api-wiaas/.htaccess new file mode 100644 index 0000000..71f005d --- /dev/null +++ b/api-wiaas/.htaccess @@ -0,0 +1,12 @@ +Options +FollowSymLinks + +RewriteEngine On # Turn on the rewriting engine + +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f + +RewriteRule ^([A-Za-z]+)/?$ index.php?module=$1 [QSA,NC,L] # Process modules +RewriteRule ^(v[0-9])/([A-Za-z]+)/([A-Za-z]+)/([A-Za-z]+)/?$ index.php?&version=$1&module=$2&controller=$3&action=$4 [QSA,NC,L] # Process modules with action +RewriteRule ^([A-Za-z]+)/([A-Za-z]+)/([A-Za-z]+)/?$ index.php?module=$1&controller=$2&action=$3 [QSA,NC,L] # Process modules with action + +RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] diff --git a/api-wiaas/.jsbeautifyrc b/api-wiaas/.jsbeautifyrc new file mode 100644 index 0000000..b87f41d --- /dev/null +++ b/api-wiaas/.jsbeautifyrc @@ -0,0 +1,32 @@ +{ +php: { + "indent_size": 4, + "indent_char": " ", + "other": " ", + "indent_level": 0, + "no_whitespace_in_blank_line": false, + "blank_line_after_namespace": true, + "blank_line_after_opening_tag": true, + "blank_line_before_return": true, + "braces": true, + "full_opening_tag": true, + "function_declaration": true, + "method_separation": true, + "no_extra_consecutive_blank_lines": true, + "no_spaces_after_function_name": true, + "phpdoc_add_missing_param_annotation": true, + "no_multiline_whitespace_around_double_arrow": true +}, +js: { + "indent_size": 4, + "indent_char": " ", + "other": " ", + "indent_level": 0, + "indent_with_tabs": false, + "preserve_newlines": true, + "max_preserve_newlines": 2, + "jslint_happy": true, + "indent_handlebars": true, + "object": {} + } +} diff --git a/api-wiaas/Gruntfile.js b/api-wiaas/Gruntfile.js new file mode 100644 index 0000000..6d0a9b7 --- /dev/null +++ b/api-wiaas/Gruntfile.js @@ -0,0 +1,29 @@ +//npm install grunt grunt-contrib-less grunt-contrib-watch jit-grunt --save-dev +module.exports = function (grunt) { + require('jit-grunt')(grunt); + + grunt.initConfig({ + less: { + development: { + options: { + compress: true, + yuicompress: true, + optimization: 2 + }, + files: { + 'client/css/dist/bundle.min.css': 'client/js/components/**/*.less' // destination file and source file + } + } + }, + watch: { + styles: { + files: ['client/js/components/**/*.less'], // which files to watch + tasks: ['less'], + options: { + nospawn: true + } + } + } + }); + grunt.registerTask('default', ['less', 'watch']); +}; diff --git a/api-wiaas/application_scripts/updateEndOfLife.php b/api-wiaas/application_scripts/updateEndOfLife.php new file mode 100644 index 0000000..caceae2 --- /dev/null +++ b/api-wiaas/application_scripts/updateEndOfLife.php @@ -0,0 +1,7 @@ + /dev/null +$result = exec($command, $output); + +echo $output[0]; diff --git a/api-wiaas/client/css/dist/bundle.min.css b/api-wiaas/client/css/dist/bundle.min.css new file mode 100644 index 0000000..09c3b98 --- /dev/null +++ b/api-wiaas/client/css/dist/bundle.min.css @@ -0,0 +1 @@ +.module-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#bids-view{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#bids-view .bid-item{position:relative;display:block;padding:1rem;border:1px solid #3bb9ff;border-radius:5px;min-height:36rem;margin-top:1rem}#bids-view .bid-header{font-weight:600}#bids-view .bid-date{font-size:70%}#bids-view .bid-number{font-weight:600}#bids-view .add-bid-margin-btn,#bids-view .remove-bid-btn{position:absolute;margin-top:1rem;bottom:1rem;left:2rem}#bids-view .expired{background:rgba(217,83,79,0.1)}#bids-view .used-status{color:#1f618d;font-weight:600}#bids-view .expired-status{color:#d9534f;font-weight:600}#add-bid{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#link-supplier-bids .supplier-bid-header{font-weight:600}#link-supplier-bids .supplier-bid{cursor:pointer}#link-supplier-bids .supplier-bid:hover{background:rgba(255,255,0,0.5)}#link-supplier-bids .supplier-bids-list{height:25rem;overflow-y:scroll}#link-supplier-bids .selected-bid{background:rgba(59,185,255,0.2)}#contact-module{padding-bottom:3%}#contact-module .contact-info-layer{position:relative;background:rgba(255,255,255,0.8);padding:3%;margin-top:1%;min-height:460px}#contact-module .contact-info-box{font-size:120%;margin-top:1%}#contact-module .contact-info-title{margin-bottom:5%;border-bottom:2px solid #000}#contact-module .info-icon{display:inline-block}#contact-module .info-big-text{display:inline-block}#contact-module .info-text{display:inline-block;margin-left:5%}#contact-module .contact-info-addresses-layer{margin-top:5%}#contact-module .contact-info-address{margin-top:5%}#contact-module .contact-info-country{display:inline-block}#contact-module .flag-icon{border-radius:3px}.module-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#customers-view-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#customers-view-layer .title-header{font-weight:bold;font-size:2rem;padding:1rem 0}#customers-view-layer .customer-row{padding:1rem 0}#customers-view-layer .custom-border{border-bottom:2px solid #337ab7}#dashboards{position:relative;margin-top:1%;margin-bottom:3%;padding-bottom:1%}#dashboards-layer .dashboard-name{position:relative;font-size:200%;padding:1% 0}#dashboards-layer .select-dashboard-layer{z-index:9999;background:rgba(255,255,255,0.8);border:1px solid #3bb9ff;padding:5px}#dashboards-layer .select-dashboard-title{text-align:center}#dashboards-layer .select-dashboard-type{text-align:center;margin-top:1%}#dashboards-layer .dashboard-row{cursor:pointer;border-bottom:1px solid #3bb9ff;padding:1%;font-size:60%}#dashboards-layer .dashboard-row:hover{background:rgba(59,185,255,0.1)}#dashboards-layer .private{color:#C11B17}#dashboards-layer .public{color:#2184be}#dashboards-layer .visibility-icon{float:right;margin-right:5px}#dashboards-layer .dashborad-selected-name{margin-right:2%}#dashboards-layer .dashborad-btn{cursor:pointer;font-size:80%}#dashboards-layer .edit-dashboard-btn{cursor:pointer;font-size:80%}#dashboards-layer .owner-btns a{color:#000;text-decoration:none}#dashboards-layer .remove-dashborad-btn{cursor:pointer;font-size:80%}#dashboards-layer .select-dashboard-btn{cursor:pointer;font-size:80%}#dashboards-layer .confirm-name{font-weight:bold}#dashboards-layer .gadget{padding:3%;background:rgba(255,255,255,0.8)}#dashboards-layer .gadget-header{font-weight:bold;font-size:120%}#dashboards-layer .gadget-row{padding:10px 0;border-bottom:1px solid #3bb9ff}#dashboards-layer .gadget-row-column{display:inline-block}#dashboards-layer .gadget-row-column a{cursor:pointer}#dashboards-layer .order-status{font-size:110%;font-weight:bold}#dashboards-layer .order-status-open{font-size:110%;font-weight:bold;color:#045FB4}#dashboards-layer .order-status-no-process{font-size:110%;font-weight:bold;color:#045FB4}#dashboards-layer .order-status-in-progress{font-size:110%;font-weight:bold;color:#FF8040}#dashboards-layer .order-status-production{font-size:110%;font-weight:bold;color:#4CC417}#dashboards-layer .order-status-canceled{font-size:110%;font-weight:bold;color:#F70D1A}#dashboards-layer .order-status-processing{font-size:110%;font-weight:bold;color:#FF8040}#dashboards-layer .order-status-end-of-life{font-size:110%;font-weight:bold;color:#800080}#dashboards-layer .fitler-layer{border-top:1px solid #3bb9ff;border-bottom:1px solid #3bb9ff;padding:1% 0}#dashboards-layer .filter-title{font-weight:bold}#dashboards-layer .filter-logic{padding:1% 0}#dashboards-layer .filter-apply{margin-top:1%}#dashboards-layer .filter-clear{margin-top:1%;margin-left:2%}#dashboards-layer .filter-value,#dashboards-layer .sort-icon{cursor:pointer;margin-left:5%;color:#045FB4}#dashboards-layer .is-fitlered{font-size:80%}#dashboards-layer .action-status{font-weight:bold}#dashboards-layer .invalid{color:#d58512}#dashboards-layer .pending{color:#800080}#dashboards-layer .not-accepted{color:#800080}#dashboards-layer .in-progress{color:#FF8040}#create-dashboard-container .dashborad-input{font-size:130%}#create-dashboard-container .user-type-select-layer{font-size:130%}#create-dashboard-container .user-type-select{padding:5px 0}#create-dashboard-container .create-dashboard-label{font-weight:bold;display:inline-block}#create-dashboard-container .gadget{position:relative;margin-top:1%;padding:3%;background:rgba(255,255,255,0.8);text-align:center;height:25em}#create-dashboard-container .add-gadget{color:#000;margin-top:3em;font-size:200%;padding:2em 0}#create-dashboard-container .add-gadget:hover{color:#204d74;border:5px dashed #204d74;cursor:pointer}#create-dashboard-container .drag-gadget{color:#000;margin-top:3em;font-size:200%;padding:2em 0}#create-dashboard-container .drop-zone{background:#FFF;color:#000;margin-top:3em;font-size:200%;padding:2em 0;border:5px dashed #5cb85c;display:none;position:absolute;z-index:1000;width:90%}#create-dashboard-container .drag-gadget:hover{color:#204d74;border:5px dashed #204d74;cursor:move}#create-dashboard-container .remove-gadget{margin-top:1%;position:relative;float:right}#create-dashboard-container .create-box{margin:1em 0}#create-dashboard-container .visibility-layer{display:inline-block;font-size:130%;margin-left:1%}#create-dashboard-container .visibility-icon{cursor:pointer}#create-dashboard-container .visibility-message{display:none}#create-dashboard-container .visibility-layer:hover .visibility-message{display:inline-block;font-weight:bold;cursor:pointer}#create-dashboard-container .private{color:#C11B17}#create-dashboard-container .public{color:#2184be}.confirmation-button-disabled{background:#d3d3d3}.module-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#documents-module .document-icon-layer{position:relative}#documents-module .document-icon{font-size:200%}#documents-module .document-icon-text{position:absolute;bottom:5%;color:#FFF;padding:2px;font-size:61%}#documents-module .docx,#documents-module .doc{color:#2372ba}#documents-module .pdf{color:#e74c3c}#documents-module .xlsx,#documents-module .xls{color:#060}#documents-view-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#documents-view-layer .document-categ{margin-top:1%}#documents-view-layer .document-layer{padding:1% 0;border-bottom:2px solid #337ab7}#documents-view-layer .document-layer:hover{background:rgba(59,185,255,0.5)}#documents-view-layer .document-name{font-size:130%;font-weight:bold}#documents-link-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%;padding-top:2%}#documents-link-layer .documents-header{padding:1%;text-align:center;background:#337ab7;color:#FFF;font-size:120%;font-weight:bold}#documents-link-layer .documents-big-container{height:445px;overflow:hidden}#documents-link-layer .documents-container{border:2px solid #337ab7;border-radius:10px}#documents-link-layer .documents-list{min-height:400px;height:400px;overflow:auto}#documents-link-layer .package-layer{padding:1%;border-bottom:2px solid #337ab7;cursor:pointer}#documents-link-layer .document-row{padding:1%;border-bottom:2px solid #337ab7;cursor:move}#documents-link-layer .document-row:hover,#documents-link-layer .package-layer:hover{background:rgba(59,185,255,0.5)}#documents-link-layer .selected-package{background:#3bb9ff}#documents-link-layer .document-icon-layer{display:inline-block;margin-right:2%}#documents-link-layer .documents-link-buttons{margin:2% 0}#documents-add-layer{background:rgba(255,255,255,0.8);margin-top:1%;margin-bottom:2%}#documents-add-layer .documents-add-layer{padding:2% 0}#documents-add-layer .documents-header{padding:1%;text-align:center;background:#337ab7;color:#FFF;font-size:120%;font-weight:bold}#documents-add-layer .documetns-types{border:2px solid #337ab7;border-radius:10px}#documents-add-layer .document-types-list{overflow-y:scroll;max-height:30rem;border-bottom:2px solid #337ab7}#documents-add-layer .add-type-layer{margin-top:1rem}#documents-add-layer .document-type-row{padding:1%;border-bottom:2px solid #337ab7}#documents-add-layer .can-add-document{cursor:pointer}#documents-add-layer .can-add-document:hover{background:rgba(59,185,255,0.5)}#documents-add-layer .special-document{cursor:pointer;background:rgba(192,192,192,0.5)}#documents-add-layer .special-document:hover{background:rgba(59,185,255,0.5)}#documents-add-layer .selected-document{background:#3bb9ff}#documents-add-layer .drop-box{margin-top:2%;color:#337ab7;border:5px dashed #337ab7;border-radius:10px;text-align:center;vertical-align:middle;font-size:150%;padding:10% 0;cursor:pointer}#documents-add-layer .dragover{border:5px dashed #4CC417}#documents-add-layer .doc-type-info{margin-top:1%}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;min-height:50rem}#financing-module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;min-height:50rem}#financing-module-layer .edit-interest-rate{width:7rem;padding:0 .6rem}#set-customers-discount-module-container .customer-info-discount{padding:.3% 0 .3% 1%}#set-customers-discount-module-container .customer-info-discount:hover{background:rgba(59,185,255,0.1)}#set-customers-discount-module-container .customer-discount-message{padding:1% 0}#set-customers-discount-module-container .edit-interest-rate-discount{width:70%}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding-bottom:1%}#orders-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding-bottom:1%}#orders-hostory-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding-bottom:1%}#order-chose-process .order-available-processes-layer{max-height:45rem;overflow-y:auto}#orders-module .order-status{font-size:110%;font-weight:bold;display:inline-block}#orders-module .order-status-open{font-size:110%;font-weight:bold;display:inline-block;color:#045FB4}#orders-module .order-status-no-process{font-size:110%;font-weight:bold;display:inline-block;color:#045FB4}#orders-module .order-status-in-progress{font-size:110%;font-weight:bold;display:inline-block;color:#FF8040}#orders-module .order-status-production{font-size:110%;font-weight:bold;display:inline-block;color:#4CC417}#orders-module .order-status-canceled{font-size:110%;font-weight:bold;display:inline-block;color:#F70D1A}#orders-module .order-status-processing{font-size:110%;font-weight:bold;display:inline-block;color:#FF8040}#orders-module .order-status-end-of-life{font-size:110%;font-weight:bold;display:inline-block;color:#4CC417}#orders-module td.info-control{position:relative}#orders-module td.info-control:before{left:9px;height:14px;width:14px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;font-family:'Courier New',Courier,monospace;line-height:14px;content:'+';background-color:#31b131;cursor:pointer}#orders-module tr.shown td.info-control:before{content:'-';background-color:#d33333;cursor:pointer}#orders-module .order-details{font-size:90%}#orders-module .package-item-info{display:inline-block;width:75%;margin-left:5%}#orders-module .package-item-status{width:19%;font-size:200%;display:inline-block;vertical-align:top;text-align:center}#orders-module .detailed-status{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center}#orders-module .detailed-status-open{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center;background:#045FB4}#orders-module .detailed-status-no-process{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center;background:#045FB4}#orders-module .detailed-status-in-progress{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center;background:#FF8040}#orders-module .detailed-status-production{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center;background:#4CC417}#orders-module .detailed-status-canceled{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center;background:#F70D1A}#orders-module .detailed-status-end-of-life{width:100%;font-size:110%;font-weight:bold;display:inline-block;color:#FFF;text-align:center;background:#4CC417}#orders-module .order-details-item{border:1px solid #000;border-radius:5px;margin-bottom:2%;margin-radius:5px}#orders-module .package-item-name{font-size:120%;font-weight:bold;text-align:center;padding:2% 0}#orders-module .order-details-total{text-align:right}#orders-module h5{font-weight:bold;font-size:110%}#orders-module .order-details-label{font-weight:bold}#orders-module .send-support-mail-details{display:inline-block}#orders-module .order-number-icon{font-size:120%;font-weight:bold}#orders-module .user-header{font-weight:bold;font-size:120%}#orders-module .order-cl-customer-display{display:block}#orders-module .acceptance-button-layer{font-size:120%;padding-top:2%}.assign-broker-layer{padding:5px 0 5px 5px;border-radius:5px}.assign-broker-layer .assigned-broker{display:inline-block;width:78%}.assign-broker-layer .assign-icon{display:inline-block;width:15%;margin-left:3%;margin-top:3px;cursor:pointer;font-size:120%;text-align:center;color:#3bb9ff}.assign-broker-layer .assign-buttons{width:50%;margin-left:50%;padding:2% 0;text-align:right}.assign-broker-layer .assign-btn{display:inline-block;padding:7px;margin-right:5px;background:#3bb9ff;border-radius:5px;color:#FFF;cursor:pointer}.assign-broker-layer .assign-btn:hover{background:#6cc417}#mail-support-container{padding:2% 0}#mail-support-container .mail-support-text{height:100px;max-width:100%}.assign-broker-layer:hover{border:1px solid rgba(59,185,255,0.5)}#order-cancel{margin-top:1%;margin-bottom:1%}#change-orders-steps-module{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding-bottom:1%}#change-orders-steps-layer .order-box{display:inline-block;width:80%}#change-orders-steps-layer .terms-layer{text-align:center}#change-orders-steps-layer #selected-broker{width:98%}#change-orders-steps-layer .add-order-comment{margin-top:1%}#change-orders-steps-layer .drop-box{cursor:pointer;color:#337ab7;border:5px dashed #337ab7;border-radius:10px;text-align:center;vertical-align:middle;font-size:150%;padding:10% 0;margin-top:2%}#change-orders-steps-layer .dragover{border:5px dashed #4CC417}#change-orders-steps-layer .document-layer{border-bottom:2px solid #337ab7;padding-bottom:2%;margin-bottom:2%;margin-top:3%}#change-orders-steps-layer .remove-document{display:inline-block;float:right}#change-orders-steps-layer .remove-document-btn{color:#FF0000;cursor:pointer}#change-orders-steps-layer .order-step-description{font-size:120%;margin-top:2%;margin-bottom:2%}#change-orders-steps-layer .order-info-toggle{font-size:80%;cursor:pointer}#change-orders-steps-layer .step-order-status{display:inline-block;font-size:80%}#change-orders-steps-layer .glyphicon-plus-sign{color:#31b131}#change-orders-steps-layer .glyphicon-minus-sign{color:#d33333}#change-orders-steps-layer .order-seps-more{width:100%}#change-orders-steps-layer .order-seps-more-icon{margin-left:4%}#change-orders-steps-layer .ordere-step-show-all-icon{cursor:pointer}#change-orders-steps-layer .hide-steps{margin-left:4%;display:block}#change-orders-steps-layer .order-description{border:1px solid #000;border-radius:5px;padding:1%;display:none}#change-orders-steps-layer .order-info-container{vertical-align:top}#change-orders-steps-layer .order-info-item{border:1px solid #000;border-radius:5px;margin-bottom:2%;margin-radius:5px;padding-bottom:2%}#change-orders-steps-layer .order-info-item .order-info-item-name{font-size:120%;font-weight:bold;text-align:center;padding:2% 0}#change-orders-steps-layer .order-info-item-info{display:inline-block;width:75%;margin-left:5%}#change-orders-steps-layer .order-info-item-status{width:19%;font-size:200%;display:inline-block;vertical-align:top;text-align:center}#change-orders-steps-layer .order-big-label{font-size:110%;font-weight:bold;margin-bottom:2%}#change-orders-steps-layer .order-label{font-size:110%;display:block;font-weight:bold;padding:8px 0 5px}#change-orders-steps-layer .my-selection{font-weight:bold;color:#31708f}#change-orders-steps-layer .prices-info{padding:5px}#change-orders-steps-layer .order-category{font-weight:bold}#change-orders-steps-layer .order-step-layer{position:relative;width:100%}#change-orders-steps-layer .order-available-process{width:100%;margin:1% 0}#change-orders-steps-layer .order-process-name{display:inline-block;width:65%;padding-left:2%}#change-orders-steps-layer .order-process-chose-btn{display:inline-block;width:30%;margin-left:2%}#change-orders-steps-layer .order-comments{margin-top:1%;border:1px solid #000;border-radius:5px;padding:0 2% 5%;vertical-align:top}#change-orders-steps-layer .package-steps{width:100%;display:inline-block;border:1px solid #000;border-radius:5px;padding:0 2% 2%;vertical-align:top;margin-top:1%}#change-orders-steps-layer .outside-process-steps{display:inline-block;background:rgba(59,185,255,0.3);border:1px solid #000;border-radius:5px;font-weight:bold;margin-top:3%}#change-orders-steps-layer .order-step{display:inline-block;border:1px solid #000;border-radius:5px;font-weight:bold;font-size:90%}#change-orders-steps-layer .order-step-link{display:block;width:2px;height:15px;position:relative;background:#000;margin-left:4%}#change-orders-steps-layer .order-step-number{display:inline-block;padding:5px;vertical-align:top;font-weight:bold;text-align:center;font-size:130%;margin-top:1%}#change-orders-steps-layer .order-step-info{display:inline-block;width:90%;padding-left:2%;padding-top:1%;padding-bottom:1%;border-left:1px solid #000}#change-orders-steps-layer .order-step-status-text{display:inline-block;position:relative;float:right;margin-right:2%;font-size:70%}#change-orders-steps-layer .order-step-full-description{padding:2% 0;margin-bottom:4%;border-top:2px dashed #000;border-bottom:2px dashed #000;font-weight:normal;font-size:90%}#change-orders-steps-layer .order-step-description-display{display:none}#change-orders-steps-layer .order-step-next{display:inline-block;vertical-align:top;margin-top:15%}#change-orders-steps-layer .step-done{background:rgba(76,196,23,0.3)}#change-orders-steps-layer .step-in-progress{background:rgba(59,185,255,0.3)}#change-orders-steps-layer .step-in-future{background:rgba(209,208,206,0.3);opacity:.6}#change-orders-steps-layer .order-step-estimation{font-size:90%}#change-orders-steps-layer .order-added-comments{padding:1%}#change-orders-steps-layer .order-comment-date{display:inline-block;width:80%;padding:2% 3%;margin-bottom:2%}#change-orders-steps-layer .order-comment-label{font-weight:bold;display:block}#change-orders-steps-layer .order-comment-layer,#change-orders-steps-layer .order-step-comment{font-size:90%;margin-top:2%;margin-bottom:2%;padding-bottom:2%;font-weight:normal;border-bottom:1px dashed #000}#change-orders-steps-layer .order-step-comment-textarea{display:inline-block;font-size:90%;margin-top:2%;font-weight:normal;max-width:90%}#change-orders-steps-layer .comment-glyphicon{margin-right:2%;vertical-align:top;float:right;cursor:pointer;font-size:120%}#change-orders-steps-layer .glyphicon-eye-open{color:#2184be}#change-orders-steps-layer .glyphicon-eye-close{color:#C11B17}#change-orders-steps-layer .extra-action-layer{padding:7% 0 1%}#change-orders-steps-layer .supplier-schedule-installation-container{padding-left:1%}.next-step-disabled{background-color:#D3D3D3;cursor:default}#validate-questionaire a{text-decoration:none}#validate-questionaire .document-name{font-size:100%}#validate-questionaire .document-status{display:inline-block;font-size:100%;font-weight:bold;margin-left:3%;margin-top:1%}#validate-questionaire .validation-buttons{display:inline-block;float:right}#validate-questionaire .invalid{color:#d58512}#validate-questionaire .validated{color:#398439;font-size:120%}#validate-questionaire .invalid-questionaire-comment-container{margin:2% 0 0 2%}#validate-questionaire .invalid-questionaire-text{max-width:100%;margin-bottom:1%}#validate-questionaire .save-invalid-doc-btn{float:right;margin-right:4%}#validate-questionaire .reason-comment{font-size:110%}#procuremnet-extra-action .supplier-layer{border-bottom:2px solid #337ab7;padding-bottom:2%;margin-bottom:2%}#procuremnet-extra-action .supplier-header{font-size:130%;font-weight:bold;margin:1% 0}#procuremnet-extra-action .product-input{width:100%}#procuremnet-extra-action .glyphicon{font-weight:bold}#procuremnet-extra-action .supplier-bids{margin-top:1rem}.delivery-dates-container .additional-procurement-header{text-align:center}.delivery-dates-container .supplier-layer{border-bottom:2px solid #337ab7;padding-bottom:1%}.delivery-dates-container .supplier-header{font-size:130%;font-weight:bold;margin:1% 0}.delivery-dates-container .final-dates-layer{border-bottom:2px solid #337ab7;margin-top:3%;padding:1% 0}.delivery-dates-container .final-dates-layer-cl{border-bottom:2px solid #337ab7;margin-top:1%;font-size:120%;padding:1% 0}.delivery-dates-container .saveTrakingBtn{font-size:80%}.delivery-dates-container .traking-layer{margin-top:1%;border-top:2px solid #337ab7}.delivery-dates-container .glyphicon{font-weight:bold}.delivery-dates-container .glyphicon-ok{color:#398439}.delivery-dates-container .earliest-installation-date-layer{margin-top:2%;padding-bottom:2%;font-size:110%}.delivery-dates-container .delivery-dates-header{padding-bottom:2%;text-align:center}.delivery-dates-container .traking-layer{padding:1%;border:1px dashed #337ab7}.delivery-dates-container .save-traking-btn{float:right}.delivery-dates-container .remove-date-btn{cursor:pointer;color:#E42217}.delivery-dates-container .display-tracking-info{border-bottom:2px solid #337ab7;padding-top:1%;padding-bottom:1%}.delivery-dates-container .date-input{width:75%}.delivery-dates-container .remove-estiamted,.delivery-dates-container .remove-confirmed{cursor:pointer;color:red}.delivery-dates-container .edit-date{cursor:pointer}.delivery-dates-container .display-date{width:55%;display:inline-block}.delivery-dates-container .remove-date-icon-container{display:inline-block}#set-delivery-dates-container .additional-procurement-header{text-align:center}#set-delivery-dates-container .supplier-layer{border-bottom:2px solid #337ab7;padding-bottom:1%}#set-delivery-dates-container .supplier-header{font-size:130%;font-weight:bold;margin:1% 0}#set-delivery-dates-container .final-dates-layer{border-bottom:2px solid #337ab7;margin-top:3%;padding:1% 0}#set-delivery-dates-container .final-dates-layer-cl{border-bottom:2px solid #337ab7;margin-top:1%;font-size:120%;padding:1% 0}#set-delivery-dates-container .saveTrakingBtn{font-size:80%}#set-delivery-dates-container .traking-layer{margin-top:1%;border-top:2px solid #337ab7}#set-delivery-dates-container .glyphicon{font-weight:bold}#set-delivery-dates-container .glyphicon-ok{color:#398439}#set-delivery-dates-container .earliest-installation-date-layer{margin-top:2%;padding-bottom:2%;font-size:110%}#set-delivery-dates-container .delivery-dates-header{padding-bottom:2%;text-align:center}#set-delivery-dates-container .traking-layer{padding:1%;border:1px dashed #337ab7}#set-delivery-dates-container .save-traking-btn{float:right}#set-delivery-dates-container .remove-date-btn{cursor:pointer;color:#E42217}#set-delivery-dates-container .display-tracking-info{border-bottom:2px solid #337ab7;padding-top:1%;padding-bottom:1%}#set-delivery-dates-container .date-input{width:75%}#set-delivery-dates-container .remove-estiamted,#set-delivery-dates-container .remove-confirmed{cursor:pointer;color:red}#set-delivery-dates-container .edit-date{cursor:pointer}#set-delivery-dates-container .display-date{width:55%;display:inline-block}#set-delivery-dates-container .remove-date-icon-container{display:inline-block}#show-delivery-dates-cl-container .additional-procurement-header{text-align:center}#show-delivery-dates-cl-container .supplier-layer{border-bottom:2px solid #337ab7;padding-bottom:1%}#show-delivery-dates-cl-container .supplier-header{font-size:130%;font-weight:bold;margin:1% 0}#show-delivery-dates-cl-container .final-dates-layer{border-bottom:2px solid #337ab7;margin-top:3%;padding:1% 0}#show-delivery-dates-cl-container .final-dates-layer-cl{border-bottom:2px solid #337ab7;margin-top:1%;font-size:120%;padding:1% 0}#show-delivery-dates-cl-container .saveTrakingBtn{font-size:80%}#show-delivery-dates-cl-container .traking-layer{margin-top:1%;border-top:2px solid #337ab7}#show-delivery-dates-cl-container .glyphicon{font-weight:bold}#show-delivery-dates-cl-container .glyphicon-ok{color:#398439}#show-delivery-dates-cl-container .earliest-installation-date-layer{margin-top:2%;padding-bottom:2%;font-size:110%}#show-delivery-dates-cl-container .delivery-dates-header{padding-bottom:2%;text-align:center}#show-delivery-dates-cl-container .traking-layer{padding:1%;border:1px dashed #337ab7}#show-delivery-dates-cl-container .save-traking-btn{float:right}#show-delivery-dates-cl-container .remove-date-btn{cursor:pointer;color:#E42217}#show-delivery-dates-cl-container .display-tracking-info{border-bottom:2px solid #337ab7;padding-top:1%;padding-bottom:1%}#show-delivery-dates-cl-container .date-input{width:75%}#show-delivery-dates-cl-container .remove-estiamted,#show-delivery-dates-cl-container .remove-confirmed{cursor:pointer;color:red}#show-delivery-dates-cl-container .edit-date{cursor:pointer}#show-delivery-dates-cl-container .display-date{width:55%;display:inline-block}#show-delivery-dates-cl-container .remove-date-icon-container{display:inline-block}#installation-scheduler-container .installation-company-disabled{background:#dddddd}#installation-scheduler-container .additional-procurement-header{text-align:center}#installation-scheduler-container .set-installation-dates{padding:0 0 2% 1%}#installation-scheduler-container .show-installation-dates{padding:2% 0 2% 1%}#installation-scheduler-container .add-new-date{padding-top:2%;padding-bottom:1%}#installation-scheduler-container .add-new-date-btn{padding-top:2%}#installation-scheduler-container .add-new-traking-btn{padding-top:2%}#installation-scheduler-container .earliest-installation-date-layer{padding-top:2%}#installation-scheduler-container .change-installation-btn{cursor:pointer;padding-bottom:3%;text-align:center}#propose-installation-dates .confirmation-proposed{color:#800080}#propose-installation-dates .confirmation-accepted{color:#398439}#propose-installation-dates .confirmation-declined{color:#E42217}#propose-installation-dates .confirmation-canceled{color:#E42217}#propose-installation-dates .confirmation-invalid{color:#E42217}#propose-installation-dates .date-row{padding-top:1%;padding-left:5%;padding-bottom:1%}#propose-installation-dates .installation-date-proposed{font-size:130%}#propose-installation-dates .installation-dates-history{padding-top:1%;padding-bottom:1%;border-bottom:2px solid #337ab7}#propose-installation-dates .display-dates-history{cursor:pointer}#propose-installation-dates .show-history-label{padding-top:1%}#propose-installation-dates .dates-info-btn{color:#337ab7;cursor:pointer}#orders-steps-schedule .chose-scheduled-date-layer{margin-top:2%;border-top:2px solid #337ab7;padding-top:1%}#orders-steps-schedule .confirmation-pending{color:#800080}#orders-steps-schedule .confirmation-accepted{color:#398439}#orders-steps-schedule .confirmation-declined{color:#E42217}#orders-steps-schedule .date-row{padding:1% 0}#orders-steps-schedule .schedule-date{font-size:130%}#customer-acceptance-extra-action .accepted{color:#398439;margin-bottom:1%}#customer-acceptance-extra-action .not-accepted{color:#800080;margin-bottom:1%}#customer-acceptance-extra-action .declined{color:#E42217;margin-bottom:1%}#customer-acceptance-extra-action .decline-installation-container{padding-top:4%}#customer-acceptance-extra-action .save-decline-install-btn{margin-top:2%}#customer-acceptance-extra-action .install-btn{text-overflow:ellipsis;overflow:hidden;white-space:inherit}#customer-acceptance-extra-action .decline-installation-text{width:100%}#customer-acceptance-extra-action .customer-installation-decline-reason{display:inline-block}#send-support-mail-btn .send-support-mail{float:right}#show-schedule-history-container .supplier-header{font-weight:bold;font-size:130%;margin:1% 0}#show-schedule-history-container .history-date{font-size:120%}#show-schedule-history-container .company-dates{border-bottom:2px solid #337ab7;padding-bottom:2%;margin-bottom:2%}#installation-files-container .installation-protocol-doc{border-bottom:2px solid #337ab7;padding-bottom:2%;margin-top:3%}#add-documents-to-order-container .upload-files-header{text-align:center}#add-documents-to-order-container .document-types{padding-bottom:5%}#add-documents-to-order-container .add-document-value{width:90%}#add-documents-to-order-container .drop-box{cursor:pointer;color:#337ab7;border:5px dashed #337ab7;border-radius:10px;text-align:center;vertical-align:middle;font-size:150%;padding:10% 0;margin-top:2%}#add-documents-to-order-container .outside-process-steps{display:inline-block;background:rgba(59,185,255,0.3);border:1px solid #000;border-radius:5px;font-weight:bold;margin-top:3%}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}.packages-lists{display:inline-block;border:1px solid #000;border-radius:5px;width:95%;height:200px;overflow-y:overlay}.dropzone-packages{display:inline-block;width:100%;padding:0 2%}.packages-countries{display:block;font-size:110%;padding-left:1%;padding-top:1%}.allowed-drop-zone{background:rgba(223,240,216,0.5);border:3px dashed #000}.create-packages-name-description{display:block;padding-left:1%;padding-top:1%}.create-packages-name-description .create-package-name,.create-packages-name-description .create-package-reference{display:inline-block;margin-top:1%;padding-left:1%}.create-packages-name-description .create-package-description{display:inline-block;margin-top:1%;padding-left:1%}.create-packages-name-description .package-label{vertical-align:top;display:inline-block}#upload-image-cdn-container .upload-image-title{text-align:center;padding-bottom:1.5%}#upload-image-cdn-container .drop-box{margin-top:2%;color:#337ab7;border:5px dashed #337ab7;border-radius:10px;text-align:center;vertical-align:middle;font-size:130%;padding:6% 0;cursor:pointer}#upload-image-cdn-container .dragover{border:5px dashed #4CC417}#upload-image-cdn-container .image-characteristic{padding-bottom:1%}#upload-image-cdn-container .use-same-image-for-market{padding-left:2%}#upload-image-cdn-container .image-url-label{font-weight:bold}.images-from-cdn-container{border:1px solid #000;border-radius:5px;height:400px;overflow:auto;padding:1%;white-space:nowrap}.display-small-image{padding-bottom:2%;display:inline-block}.image-from-cdn{width:60px;height:39px}.cover-image-from-cdn{width:100px;height:75px}.url-from-cdn{display:inline-block;white-space:nowrap}.cover-image-url-text{margin:2% 0}.image-label{padding-left:0}.create-package-title{display:inline-block;width:35%;margin-bottom:1%;font-weight:bold;font-size:120%}.steps-container{position:relative}.draggable-icon{color:#3c763d;left:28%;top:50%;font-size:200%;text-align:center;position:absolute}.draggable-icon-steps{color:#3c763d;left:34%;top:50%;font-size:200%;text-align:center;position:absolute}.draggable-icon-template{color:#3c763d;right:0;top:45%;font-size:200%;text-align:center}.create-packages-from-template-container{height:400px;overflow:hidden}#product-info-fields{border:1px solid #000;border-radius:5px;padding:5% 0;min-height:300px;font-size:90%}.product-info-label{display:inline-block;width:40%;margin-left:2%;font-weight:bold}.product-info-text{display:inline-block;width:55%}.create-packages{vertical-align:top}.create-package-list{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;height:400px;overflow-y:overlay}.create-package-list-from-template{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;overflow-y:scroll}.create-package-row{width:100%;background-color:#fff;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;display:block;padding:10px 15px;margin-bottom:-1px;cursor:pointer}.not-available-prdocut{background:rgba(255,166,47,0.3)}.create-package-products-display{display:block;font-size:100%}.create-package-products-display .create-package-header{display:inline;width:25%;font-weight:bold}.create-package-products-display .create-package-product{width:70%;display:inline}.create-package-products-info-display{display:inline;width:100%;font-size:90%}.create-package-products-info-display .create-package-header{display:inline;width:15%;font-weight:bold}.create-package-products-info-display .create-package-product-info{display:inline;width:30%}.product-quantity-box{font-size:90%}.product-quantity-box .product-quantity{width:20%}.create-package-row:hover{background:rgba(223,240,216,0.5)}.create-package-row .dndDraggingSource{display:none}.create-package-row .dndPlaceholder{background-color:#ddd;display:block}.create-package-row.selected{background-color:#dff0d8;color:#3c763d}.add-products-by-template{width:90%;min-height:40px;margin:2%;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px}.real-product-in-package{width:95%;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;margin:2%;padding:1%}#packages-list{overflow:hidden}#add-installation-companies-container{margin-top:1%}#add-installation-companies-container .installation-companies-list{display:inline-block;border:1px solid #000;border-radius:5px;width:95%;height:200px;overflow-y:overlay}#add-installation-companies-container .installation-companies-list-title{font-weight:bold;font-size:120%}#add-installation-companies-container .create-packages-lists-container{display:inline-block}#edit-package-installation-companies-container{margin-top:1%}#edit-package-installation-companies-container .installation-companies-list{display:inline-block;border:1px solid #000;border-radius:5px;width:95%;height:200px;overflow-y:overlay}#edit-package-installation-companies-container .installation-companies-list-title{font-weight:bold;font-size:120%}#edit-package-installation-companies-container .create-packages-lists-container{display:inline-block}#create-template-packages-container{margin-top:2%;margin-left:1%}#create-template-packages-container .create-packages-titles{margin-top:1%}#create-template-draggable-icon{color:#3c763d;left:29.5%;font-size:200%;text-align:center;position:absolute}.create-processes-name-description{padding-left:1%;display:block;font-size:110%}.create-processes-name-description .add-step-label{cursor:pointer}.create-processes-name-description .create-processes-name{display:block;margin-top:2%}.create-processes-name-description .create-package-name-input{display:inline-block}.create-processes-name-description .create-process-steps-add-button{margin-top:2%}.create-process-notice{width:98%;margin-left:1%;margin-top:1%}.select-group{display:block;font-size:110%;padding-left:1%;margin-top:1%}.create-process-steps-container{margin-top:2%;position:relative}.create-process-steps-container .create-processes-title{margin-bottom:2%;width:95%;font-weight:bold;font-size:120%}.create-process-steps-container #product-info-fields{border:1px solid #000;border-radius:5px;padding:5% 0;min-height:300px;font-size:90%}.create-process-steps-container .product-info-label{display:inline-block;width:40%;margin-left:2%;font-weight:bold}.create-process-steps-container .product-info-text{display:inline-block;width:55%}.create-process-steps-container .create-process-steps{display:inline-block;vertical-align:top;width:35%}.create-process-steps-container #create-processes-step-dragndrop-process{margin-left:10%}.create-process-steps-container .create-processes-list{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;height:400px;overflow-y:auto;background:#FFF}.create-processes-row{width:100%;background-color:#fff;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;display:block;padding:10px 15px;margin-bottom:-1px;cursor:pointer;font-weight:bold}.create-processes-row:hover{background:rgba(223,240,216,0.5)}.create-processes-row .dndDraggingSource{display:none}.create-processes-row .dndPlaceholder{background-color:#ddd;display:block}.create-processes-row.selected{background-color:#dff0d8;color:#3c763d}.create-processes-products-display{display:inline-block;width:100%;font-size:100%;padding-left:2%}.create-processes-products-display .create-processes-header{display:inline;width:25%;font-weight:bold}.create-processes-products-display .create-processes-product{width:70%;display:inline;padding-left:2%}.create-processes-step-number{border-right:2px solid black;width:10%;text-align:center;display:inline-block}.create-processes-button{width:100%;padding-top:1%;padding-bottom:2%}#edit-packages{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#edit-packages #all-edit-packages-container{padding:2%;position:relative}#edit-packages #all-edit-packages-container .draggable-icon{color:#3c763d;left:29%;font-size:200%;text-align:center;position:absolute}#edit-packages #edit-package-templates-container{padding:2%;position:relative}#edit-packages .draggable-icon{left:29%}#edit-packages .edit-buttons{padding-left:2%;padding-bottom:2%}#edit-packages .reset-button{min-width:20%}#edit-packages .edit-package-description-text{height:200px}#edit-packages .edit-packages{position:relative}.view-package-process-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%;padding:1%}.view-package-process-layer .search-process-label{display:inline-block;margin-left:2%}.view-package-process-layer .search-process-input{margin-left:2%;width:30%}.view-package-process-layer .search-package-process-button{margin-left:2%}.view-package-process-layer .glyphicon-eye-open{color:#2184be}.view-package-process-layer .glyphicon-eye-close{color:#C11B17}.view-package-process-layer .package-layer{border-bottom:2px solid #3bb9ff;padding-bottom:1%}.view-package-process-layer .process-info-container{margin-top:1%;vertical-align:top;border:2px solid #000;border-radius:5px;padding:2%}.view-package-process-layer .package-name{display:inline-block;width:96%;padding:2%;text-align:center;font-weight:bold;font-size:120%}.view-package-process-layer .process-name{display:inline-block;width:96%;padding:2%;text-align:center;font-weight:bold}.view-package-process-layer .step-number{width:10%;display:inline-block;text-align:center;font-weight:bold}.view-package-process-layer .process-step{width:70%;display:inline;border-left:1px solid #000;padding-top:2%;padding-bottom:2%;padding-left:2%}.view-package-process-layer .process-steps{height:30em;overflow-x:auto}.view-package-process-layer .package-process-row{width:100%;background-color:#fff;border-top:1px solid #ddd;display:block;padding:2%}.view-package-process-layer .package-process-details{float:left}#set-package-price-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#set-package-price-layer .product-category-title{margin:5px 0;font-weight:bold}#packages-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#packages-layer td.info-control{position:relative}#packages-layer td.info-control:before{left:9px;height:14px;width:14px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;font-family:'Courier New',Courier,monospace;line-height:14px;content:'+';background-color:#31b131;cursor:pointer}#packages-layer tr.shown td.info-control:before{content:'-';background-color:#d33333;cursor:pointer}#packages-layer .packages-details-layer{padding:1% 0}#packages-layer .package-header{font-weight:bold;text-align:center}#packages-layer .big-title{font-weight:bold;font-size:110%;padding:2% 0}#packages-layer .small-title{font-weight:bold;padding:5px 0}#packages-layer .warning-message{font-size:90%}#packages-layer .warning-icon{cursor:pointer;margin-left:2%}#packages-layer .edit-icon{font-size:120%;cursor:pointer;margin-left:5%}#packages-layer .small-price-icon{font-size:60%}#packages-layer .set-price-text{color:#4863A0}#packages-layer .edit-price-text{color:#437C17}#packages-layer .unavailable-products{color:#a94442}#packages-layer .margin-exceded{display:inline-block;color:#FFA62F}#my-packages-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#my-packages-layer .unavailable-products{display:inline-block;color:#a94442}#my-packages-layer .margin-exceded{display:inline-block;color:#FFA62F}#my-packages-layer td.info-control{position:relative}#my-packages-layer td.info-control:before{left:9px;height:14px;width:14px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;font-family:'Courier New',Courier,monospace;line-height:14px;content:'+';background-color:#31b131;cursor:pointer}#my-packages-layer tr.shown td.info-control:before{content:'-';background-color:#d33333;cursor:pointer}#my-packages-layer .customer-name{font-weight:bold;font-size:140%}#my-packages-layer .comission-headers{font-weight:bold;padding-top:1%}#my-packages-layer .price-group{padding-top:2%;border-bottom:2px solid #3bb9ff}#my-packages-layer .price-group:nth-child(odd){background:rgba(59,185,255,0.1)}#my-packages-layer .pay-type{font-weight:bold}#my-packages-layer .price-col{display:inline-block;width:15%}#my-packages-layer .price-col-small{display:inline-block;width:15%}#my-packages-layer .no-icon{display:none}#my-packages-layer .glyphicon-eye-open{color:#2184be}#my-packages-layer .glyphicon-eye-close{color:#C11B17}#my-packages-layer .packages-details-layer{padding:1% 0}#my-packages-layer .package-header{font-weight:bold;text-align:center}#my-packages-layer .big-title{font-weight:bold;font-size:110%;padding:2% 0}#my-packages-layer .small-title{font-weight:bold;padding:5px 0}#my-packages-layer .warning-message{font-size:90%}#my-packages-layer .warning-icon{cursor:pointer;margin-left:2%}#my-packages-layer .edit-icon{font-size:120%;cursor:pointer;margin-left:5%}#select-packages-steps .step{display:inline-block;padding:1%;border-radius:5px;cursor:default}#select-packages-steps .active-step{background:#2184be;color:#FFF}#select-packages-steps .inactive-step{background:#eee;color:#aaa}#select-packages-steps .done-step{background:#9dc8e2;color:#FFF}#select-packages-steps .step-link{display:inline-block;background:#2184be;width:30px;height:2px}#choose-customers{max-height:500px}#choose-customers .customer-select-layer{max-height:40rem;overflow-y:auto}#choose-customers .customer-row{padding:3%;border:1px solid #000;cursor:pointer}#choose-customers .customer-row:hover{background:#3bb9ff}#choose-customers .selected-customer{background:rgba(59,185,255,0.6)}#choose-customers .not-selected{background:#FFF}#choose-customers .select-customer-for-pricing{width:30rem;margin-bottom:3rem}#action-buttons{margin-top:2%;margin-bottom:10%}#action-buttons .prev-btn{float:right;margin-right:3%}#action-buttons .next-btn{float:right;margin-right:5%}#action-buttons .save-btn{float:right;margin-right:5%}#select-package-layer{background:rgba(255,255,255,0.7)}#select-packages-all .product-category-title{margin:5px 0;font-weight:bold}#select-packages-all .customer-name{font-weight:bold;font-size:140%}#select-packages-all .comission-headers{font-weight:bold;margin-bottom:2%}#select-packages-all .comissions-row{margin-bottom:1%;padding-bottom:1%;border-bottom:2px solid #3bb9ff}#select-packages-all .pay-type{font-weight:bold}#select-packages-all .pay-group:nth-child(odd){background:rgba(59,185,255,0.2)}#select-packages-all .comission-header{font-weight:bold;margin-bottom:2%}#select-packages-all .pay-comission-row{margin-top:3px;padding-bottom:5px}#select-packages-all .pay-comission-col-small{vertical-align:top;display:inline-block}#select-packages-all .visible-glyph{cursor:pointer;font-size:140%}#select-packages-all .glyphicon-eye-open{color:#2184be}#select-packages-all .glyphicon-eye-close{color:#C11B17}#select-packages-all .recurent-box{position:relative}#select-packages-all .recurent-tip{position:absolute;display:block;z-index:9999;bottom:3.5em}#select-packages-all .recurent-info{cursor:default}#packages-per-pay-type h3{font-weight:bold}#packages-per-pay-type .pay-type{font-size:140%;font-weight:bold;margin:1% 0}#packages-per-pay-type .price-header{font-weight:bold}#packages-per-pay-type .price-col{vertical-align:top}#packages-per-pay-type .price-group{padding:0 0 1% 1%;border-bottom:2px solid #3bb9ff}#packages-per-pay-type .price-group:nth-child(odd){background:rgba(59,185,255,0.1)}#packages-per-pay-type .price-small-group{margin-bottom:1%}#packages-per-pay-type .split-error{color:#E42217}#packages-per-pay-type .btn-extra-text{display:none}#packages-per-pay-type .pay-type-btn:hover .btn-extra-text{display:inline-block}#packages-per-pay-type .pay-type-selection{margin:1% 0;width:50%}#packages-per-pay-type .price-checkbox{cursor:pointer;width:15px;height:15px}#total-costs{margin-top:1%;margin-bottom:1%}#total-costs .price-header{font-weight:bold}#total-costs h3{font-weight:bold}#comission-split{margin-top:1%;margin-bottom:3%}#comission-split h3{font-weight:bold;margin-bottom:3%}#comission-split .user-layer{display:inline-block;width:12%;text-align:center;vertical-align:top;font-weight:bold}#comission-split .user-icon{font-size:220%;color:#337ab7}#comission-split .commission-range-layer{display:inline-block;width:40%}#comission-split .split-percent-sign{font-size:130%;font-weight:bold}#comission-split .range-input{display:inline-block;width:50%;margin-left:5%}#comission-split .small-input{display:inline-block;width:15%}#installation-products-container{margin-top:1%;position:relative}#installation-products-container .create-packages-from-template-installation-container{height:200px;overflow:hidden}#installation-products-container .installation-list{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;min-height:200px;overflow-y:overlay}#create-package-from-template-container{min-height:200px;position:relative}#create-package-from-template-container .arrows-icon-without-virtual{margin-top:6%}#create-package-from-template-container .disable-installation{background:#ccc}#create-package-from-template-container .list-by-category{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;overflow:overlay;height:400px}#create-package-from-template-container .add-products-by-template{width:90%;min-height:40px;margin:2%;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px}#create-package-from-template-container .add-additional-products-by-template{width:90%;min-height:40px;margin:2%;border:1px dashed #ddd;border-top-right-radius:4px;border-top-left-radius:4px;text-align:center;font-size:120%;font-weight:bold;color:#ddd}#create-package-from-template-container .create-packages-from-template-container{height:300px;overflow:hidden}#create-package-from-template-container .products-per-category-container{margin-top:2%}.create-from-template-btn{padding-top:2%;margin-bottom:2%}#add-virtual-products-container{margin-top:1%;width:100%;border-top:2px solid #3bb9ff;border-bottom:2px solid #3bb9ff;background:rgba(59,185,255,0.1);padding:2% 0;margin-bottom:2%}#add-virtual-products-container .label-value-pair{margin-bottom:2%}#create-packages-container{min-height:400px;margin-top:2%;margin-left:1%;position:relative}#create-packages-container .products-per-category-container{margin-top:2%}#create-packages-container .create-packages-titles{margin-top:1%}#create-packages-container .create-packages-container{height:400px;overflow:hidden}#create-packages-container .create-packages{vertical-align:top}#create-packages-container .list-by-category{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;overflow:overlay;height:400px}#create-packages-container .create-package-description-text{height:150px}.packages-buttons{display:inline;padding-top:2%;margin-bottom:2%}#edit-package-templates{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#update-packages-templates-container{min-height:300px;margin-top:2%;margin-left:1%;position:relative}#update-packages-templates-container .products-per-category-container{margin-top:2%}#update-packages-templates-container .create-packages-titles{margin-top:1%}#update-packages-templates-container .create-packages-container{height:300px;overflow:hidden}#update-packages-templates-container .create-packages{vertical-align:top}#update-packages-templates-container .list-by-category{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;overflow:overlay;height:300px}#update-packages-templates-container .create-package-description-text{height:150px}#create-packages{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#create-packages-templates{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#add-new-virtual-product-template{padding-left:1%}.arrows-icon{color:#3c763d;left:28%;font-size:200%;text-align:center;position:absolute;top:50%}.meeting-dates{margin-top:1%}#set-additional-installation-days-container{margin-top:2%;margin-bottom:1%}#set-additional-installation-days-container .days-input{margin-left:1%}#set-additional-installation-days-from-template-container{margin-top:2%;margin-bottom:1%}#set-additional-installation-days-from-template-container .days-input{margin-left:1%}#package-optios-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#package-optios-layer .options-header{padding:1%;text-align:center;background:#337ab7;color:#FFF;font-size:120%;font-weight:bold}#package-optios-layer .options-big-container{height:445px;overflow:hidden}#package-optios-layer .options-container{border:2px solid #337ab7;border-radius:10px}#package-optios-layer .options-list{min-height:400px;height:400px;overflow-x:auto;overflow-y:scroll}#package-optios-layer .package-layer{padding:1%;border-bottom:2px solid #337ab7;cursor:pointer}#package-optios-layer .option-row{padding:2% 1%;border-bottom:2px solid #337ab7;cursor:move}#package-optios-layer .option-row:hover,#package-optios-layer .package-layer:hover{background:rgba(59,185,255,0.5)}#package-optios-layer .selected-package{background:#3bb9ff}#package-optios-layer .option-group{margin:2%;padding-top:2%;border:2px solid #337ab7;min-height:100px}#package-optios-layer .option-group-name{padding-left:2%;font-weight:bold;font-size:110%;padding-bottom:2%;border-bottom:2px solid #337ab7}#package-optios-layer .glyphicon-pencil{cursor:pointer}#package-optios-layer .add-btn{margin:2%}#package-optios-layer .remove-group{float:right;font-size:70%;margin-right:2px}#package-optios-layer .default-value{display:inline-block;float:right;font-size:70%}#package-optios-layer .default-btn{float:right;font-size:70%}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#create-process-steps{width:100%;padding:1%;margin-bottom:2%}#create-process-steps .create-process-title{margin-bottom:1%;font-weight:bold;font-size:120%;text-align:center}#create-process-steps .processes-list{background:#FFF;height:360px;min-height:360px;overflow-y:scroll;border:1px solid #000;border-radius:5px}#create-process-steps .glyphicon-eye-open{color:#2184be;font-size:120%}#create-process-steps .glyphicon-eye-close{color:#C11B17;font-size:120%}#create-process-steps .step-extra-action-radios{display:inline-block}#create-process-steps .draggable-icon-steps{color:#3c763d;top:50%;font-size:200%;text-align:center;position:absolute}#create-process-steps .create-process-name-input,#create-process-steps .create-process-country-select{height:3rem}#create-process-steps .add-process-steps{display:inline-block;margin-top:1%;border-top:2px solid #3bb9ff;border-bottom:2px solid #3bb9ff;padding:2%;background:rgba(59,185,255,0.1)}#create-process-steps .add-process-steps .create-processes-description{display:inline-block;margin-top:2%;width:98%}#create-process-steps .add-process-steps .create-processes-description .package-label{width:30%}#create-process-steps .add-process-steps .create-processes-description .create-package-description-text{width:70%}#edit-process-button{margin:2%}#edit-processes-container{margin-left:1%}#edit-process-and-steps-container{height:400px;margin-bottom:2%;overflow:hidden;position:relative}#edit-process-and-steps-container .draggable-icon{color:#3c763d;left:28.5%;top:50%;font-size:200%;text-align:center;position:absolute}#edit-processes{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#edit-processes .glyphicon-eye-open{color:#2184be}#edit-processes .glyphicon-eye-close{color:#C11B17}#edit-processes .edit-processes-lists{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;height:400px;overflow-y:scroll;padding:0}#link-process-steps{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#link-process-steps .glyphicon-eye-open{color:#2184be}#link-process-steps .glyphicon-eye-close{color:#C11B17}#link-process-steps .processes-list{background:#FFF;height:360px;min-height:360px;overflow-y:scroll;border:1px solid #000;border-radius:5px}#link-process-steps .process-selection-layer{display:inline-block;position:relative;width:100%;height:360px;overflow:hidden}#link-process-steps .headers-col{margin-top:1%;margin-bottom:1%;vertical-align:top;text-align:center}#link-process-steps .process-draggable{padding:7px 5px;cursor:pointer;border:1px solid #ddd;font-weight:bold;padding-left:2%}#link-process-steps .process-draggable:hover{background:rgba(223,240,216,0.5)}#link-process-steps .info-placeholder{color:rgba(124,128,130,0.7);padding:5%}#link-process-steps .info-step{border:1px solid #ddd}#link-process-steps .step-position{display:inline-block;width:10%;font-weight:bold;vertical-align:middle;background:rgba(59,185,255,0.5);border-right:2px solid #3bb9ff;padding:5px 0 5px 5px}#link-process-steps .step-description{display:inline-block;width:85%;padding:5px 3px}#link-process-steps .link-processes-button{margin-top:1%;margin-bottom:3%}#link-process-steps .draggable-icon{color:#3c763d;left:31%;top:50%;font-size:200%;text-align:center;position:absolute}#link-process-steps .add-new-process{margin:1% 0}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#change-password-container{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#change-password-container .change-passwd-list{display:inline-block;padding:2%}#change-password-container .passwords-container{padding-bottom:1%}#change-profile-container{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}.ui-dialog-titlebar-close{display:none}#web-shop-layer{padding-bottom:2%}#web-shop-layer .shop-packages-found{font-size:70%}#web-shop-layer .shop-package-layer{position:relative;margin-top:2%;background:rgba(255,255,255,0.8);padding:3%;height:200px}#web-shop-layer .shop-package-title{font-size:120%;text-align:center;font-weight:bold}#web-shop-layer .shop-package-reference{margin-bottom:5%;text-align:center;font-weight:bold}#web-shop-layer .shop-package-details-btn{position:absolute;bottom:5%;right:5%}#web-shop-layer .shop-package-extra{position:absolute;bottom:5%;left:5%}#web-shop-layer .shop-package-label{display:inline-block;font-weight:bold}#web-shop-layer .shop-package-text{display:inline-block}#web-shop-layer .commercial-leads-layer{margin:1% 0}#web-shop-layer .comemrcial-lead{margin-right:1%}#web-shop-layer .selected-cl{color:#FFFF00}#shop-package-details-layer .shop-package-details-layer{position:relative;background:rgba(255,255,255,0.8);padding:1% 3%;margin-top:1%}#shop-package-details-layer .shop-package-title{font-size:160%;text-align:center;font-weight:bold}#shop-package-details-layer .shop-package-reference{margin-bottom:5%;text-align:center;font-weight:bold}#shop-package-details-layer .shop-package-label{display:inline-block;font-weight:bold}#shop-package-details-layer .shop-package-text{display:inline-block;vertical-align:top}#shop-package-details-layer .shop-package-full-description{margin-top:3%}#shop-package-details-layer .shop-package-details-country{margin-top:3%}#shop-package-details-layer .selection-price{font-size:160%;color:#E42217}#shop-package-details-layer .shop-package-prices,#shop-package-details-layer .shop-package-options{margin-top:3%;padding:1%;border-bottom:2px solid #000}#shop-package-details-layer .package-option{margin-top:2%}#shop-package-details-layer .package-option-input,#shop-package-details-layer .price-type-option{cursor:pointer}#shop-package-details-layer .package-option-checkbox{cursor:pointer;font-size:120%}#shop-package-details-layer .option-value{padding:3px;margin-right:3%}#shop-package-details-layer .option-value-text,#shop-package-details-layer .shop-package-pay-type{cursor:pointer}#shop-package-details-layer .option-value:hover,#shop-package-details-layer .shop-package-pay-type:hover{background:rgba(59,185,255,0.5);border-radius:5px}#shop-package-details-layer .add-to-cart-btn{margin-top:5%}#shop-package-details-layer .shop-pacakge-option-agreement{width:20%}#shop-package-details-layer .shop-pacakge-option-price{margin-left:5%}#shop-package-details-layer .shop-packages-details-cl{border-top:2px solid #000;margin-top:2%;padding-top:2%}#shop-package-details-layer .back-btn-layer{margin-top:2%}#shop-package-details-layer .price-info-btn{color:#337ab7;cursor:pointer;margin-left:5px}#shop-package-details-layer .price-info-title{font-weight:bold}#shop-package-details-layer .selected-price{font-weight:bold}#shop-package-details-layer .selected-option{font-weight:bold}#shop-package-details-layer .shop-package-details-documents{margin-top:3%}#shop-package-details-layer .options-header{margin-top:2%}#shop-package-details-layer .not-available{font-weight:bold;color:#FFA62F}#shop-package-search-btn{cursor:pointer}#shop-package-serach-input{background:rgba(255,255,255,0.8);border-radius:5px;margin:0;padding:0 5px;border:1px solid #2e6da4}#shop-package-clear-btn{color:#E42217;cursor:pointer}#shop-cart-container{background:rgba(255,255,255,0.8);padding-left:2%}#shop-cart-container .address-type{font-size:150%;margin-bottom:1%}#shop-cart .not-available{display:inline-block;color:#FFA62F}#shop-cart .shop-cart-item{padding:1% 0;border-bottom:2px solid #337ab7}#shop-cart .shop-item-name{font-weight:bold}#shop-cart .shop-item-option{font-weight:normal;font-size:90%}#shop-cart .shop-item-remove{font-size:150%;cursor:pointer;color:#E42217}#shop-cart .show-customer-addresses .label-value-pair{margin-bottom:1%}#shop-cart .show-customer-addresses .address-area{height:80px}#shop-cart .drop-box{color:#337ab7;border:5px dashed #337ab7;border-radius:10px;text-align:center;vertical-align:middle;font-size:200%;padding:10% 0;margin-top:2%}#shop-cart .dragover{border:5px dashed #4CC417}#shop-cart .document-layer{padding:1% 0;border-bottom:2px solid #337ab7}#shop-cart .upload-status{font-size:200%;padding:10% 0;margin-top:2%}#shop-cart .file-uploaded{color:#4CC417}#shop-cart .no-file-uploaded{color:#800080}#shop-cart .shop-terms-conditions{padding-left:2%;font-size:135%;font-weight:bold;width:98%}#shop-cart .shop-item-options,#shop-cart .shop-item-additional-packages{margin-top:1%;margin-left:4%;font-size:90%}#show-order-info-headers{padding-top:1%;padding-bottom:2%}#show-order-info-headers .step{display:inline-block;padding:1%;border-radius:5px;cursor:default}#show-order-info-headers .active-step{background:#2184be;color:#FFF}#show-order-info-headers .inactive-step{background:#eee;color:#aaa}#show-order-info-headers .done-step{background:#9dc8e2;color:#FFF}#show-order-info-headers .step-link{display:inline-block;background:#2184be;width:30px;height:2px}#order-action-buttons{padding-top:2%;padding-bottom:3%}#order-action-buttons .prev-btn{float:right;margin-right:3%}#order-action-buttons .next-btn{float:right;margin-right:5%}#order-action-buttons .save-btn{float:right;margin-right:5%}#cart-informations-review .package-details{margin-top:1%}#cart-informations-review .package-details-list{margin-left:10%;margin-top:1%}#cart-informations-review .label-value-pair{display:block}#cart-informations-review .value-pair{display:inline;margin-left:3%}#cart-informations-review .cart-review-title{color:#045FB4}#cart-informations-review .package-name-review{font-weight:bold}.shop-message{padding-left:2%;font-size:130%}#shop-cart-empty-container{background:rgba(255,255,255,0.8)}.mail-order-package-detail{padding-left:35px;display:block}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%}.suppliers-info{display:inline-block;width:10%}#suppliers-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%}#suppliers-layer .edit-tr{display:block;width:100%}#suppliers-layer .suppliers-add-edit{width:100%;display:block}#suppliers-layer .supplier-input{display:block;width:100%}#suppliers-layer .supplier-group{display:block;width:100%;margin-bottom:1%}#suppliers-products-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%}#suppliers-products-layer .edit-tr{display:block;width:100%}#suppliers-products-layer .product-input{display:block;width:100%}#suppliers-products-layer .product-group{display:inline-block;width:48%;margin-bottom:1%}#suppliers-products-layer .drop-box{cursor:pointer;color:#337ab7;border:5px dashed #337ab7;border-radius:10px;text-align:center;vertical-align:middle;font-size:150%;padding:10% 0;margin-top:2%}#suppliers-products-layer .dragover{border:5px dashed #4CC417}#suppliers-products-layer .show-documents-icon{cursor:pointer}#suppliers-products-layer .remove-document-icon{cursor:pointer;color:red;margin-left:5px}#suppliers-products-add-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding-bottom:2%}#suppliers-products-add-layer .form-notice{display:inline-block}#suppliers-products-add-layer .notice-icon{color:#337ab7}#suppliers-products-add-layer .product-radio-layer{display:inline-block;margin-left:1%}#suppliers-add-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding-bottom:2%}#suppliers-add-layer #suppliers-add-steps-layer{display:inline-block;width:100%;text-align:center}#suppliers-add-layer .suppliers-add-step{display:inline-block;padding:1%;border-radius:5px}#suppliers-add-layer .step-ongoing{background:#2184be;color:#FFF}#suppliers-add-layer .step-done{background:#9dc8e2;color:#FFF}#suppliers-add-layer .step-inactive{background:#eee;color:#aaa}#suppliers-add-layer .step-link{display:inline-block;height:2px;width:5%;background:#2184be;vertical-align:middle}.term-html{margin-top:1%;background:rgba(255,255,255,0.8);margin-bottom:3%;padding:1% 2% 1% 2%}.module-layer{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#create-user-template-container{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%}#create-user-template-container #user-whole-container{padding-top:2%}#create-user-template-container .label-value-pair{margin-bottom:1%}#create-user-template-container .choose-cl-title{display:inline-block;margin-bottom:1%;font-weight:bold;font-size:120%}#create-user-template-container .cl-lists{height:400px;overflow:hidden}#create-user-template-container .choose-cl{vertical-align:top}#create-user-template-container .choose-cl-list{display:inline-block;width:95%;border:1px solid #000;border-radius:5px;min-height:400px;overflow-y:auto;height:300px}#create-user-template-container .link-cl-user{display:block}#create-user-template-container .link-cl-user .link-cl-user-header{display:inline;width:25%;font-weight:bold}#create-user-template-container .link-cl-user .link-cl-user-data{width:70%;display:inline}#create-user-template-container .choose-cl-row{width:100%;background-color:#fff;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;display:block;padding:10px 15px;margin-bottom:-1px;cursor:pointer}#create-user-template-container .choose-cl-row:hover{background:rgba(223,240,216,0.5)}#create-user-template-container .choose-cl-row .dndDraggingSource{display:none}#create-user-template-container .choose-cl-row .dndPlaceholder{background-color:#ddd;display:block}#create-user-template-container .choose-cl-row.selected{background-color:#dff0d8;color:#3c763d}#create-user-template-container #user-action-buttons{margin:1% 0 2% 1%}#create-user-template-container .draggable-icon{color:#3c763d;left:28.5%;font-size:200%}#create-user-template-container .new-company-details{padding-left:2%}#create-user-template-container .select-inactive{background-color:#dddddd}#create-user-template-container .company-admin-box{padding-left:1.5%}#create-user-template-container .new-company-details-container{margin-top:1%;width:100%;border-top:2px solid #3bb9ff;border-bottom:2px solid #3bb9ff;background:rgba(59,185,255,0.1);padding:2% 0;margin-bottom:2%}#show-users{padding-bottom:2%}#show-users .search-input{padding:1%}#show-users .search-input .search-icon{margin-left:1%}#show-users .user-types-container{padding-bottom:2%}#show-users .users-informations-container{width:100%;display:inline-block}#show-users .users-info-button{display:inline-block;text-align:right;width:90%;position:absolute}#show-users .show-users-layer{position:relative;margin-top:2%;background:rgba(255,255,255,0.7);padding:3%;height:270px}#show-users .show-users-title{font-size:120%;font-weight:bold;display:inline-block}#show-users .users-info{margin-bottom:4%}#show-users .user-type-show{text-align:center;font-size:140%;font-weight:bold}#show-users .company-name-info-title{text-align:center;margin-bottom:5%;border-bottom:2px solid #000}#link-customers-template-container{position:relative;margin-top:1%;background:rgba(255,255,255,0.7);margin-bottom:3%;padding-bottom:2%;padding-top:2%}#link-customers-template-container .user-header{padding:1%;text-align:center;background:#337ab7;color:#FFF;font-size:120%;font-weight:bold}#link-customers-template-container .user-big-container{height:445px;overflow:hidden}#link-customers-template-container .user-container{border:2px solid #337ab7;border-radius:10px}#link-customers-template-container .user-list{min-height:400px;height:400px;overflow:auto}#link-customers-template-container .user-layer{padding:1%;border-bottom:2px solid #337ab7;cursor:pointer}#link-customers-template-container .customer-row{padding:1%;border-bottom:2px solid #337ab7;cursor:move}#link-customers-template-container .customer-row:hover,#link-customers-template-container .customer-layer:hover{background:rgba(59,185,255,0.5)}#link-customers-template-container .selected-user{background:#3bb9ff}#link-customers-template-container .users-link-buttons{margin:2% 0} \ No newline at end of file diff --git a/api-wiaas/client/css/style.less b/api-wiaas/client/css/style.less new file mode 100644 index 0000000..3f4f3fe --- /dev/null +++ b/api-wiaas/client/css/style.less @@ -0,0 +1,100 @@ +.wrapper { + position: relative; +} + +.footer { + position: relative; + background: #f8f8f8; + padding: 1% 0; + text-align: center; + + a { + color: #777; + } +} + +#languages-select { + border-radius: 5px; +} + +.data-tabel-info-icon { + display: inline-block; + padding: 0 5px; +} + +.glyphicon-warning-sign { + color: #f0ad4e; + padding-right: 5px; + font-size: 120%; +} + +.glyphicon-ban-circle { + color: #a94442; + padding-right: 5px; + font-size: 120%; +} + +.data-table-edit { + display: inline-block; + margin-right: 5%; + font-size: 90%; + color: #3BB9FF; + cursor: pointer; +} + +.data-table-edit:hover { + color: #0000A0; +} + +.data-table-edit-title { + padding: 10%; + background: #000000; + color: #FFFFFF; + border-radius: 50%; + font-size: 60%; +} + +#select-cl-form { + text-align: center; + + .cl-bn { + width: 18%; + font-size: 200%; + margin-left: 2%; + margin-top: 5%; + } +} + +.bg_photo { + width: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 0; +} + +.cart-notificaiton { + position: relative; + display: inline-block; + font-size: 100%; + background: #204d74; + color: #FFF; + border-radius: 10%; + padding: 0 5px; + text-align: center; + cursor: pointer; +} + +.password-confirmation-messages { + margin-top: 2%; +} + +.wiaas-title { + text-align: center; +} + +.back-to-sign-in-btn { + font-size: 140%; + font-weight: bold; + text-align: center; +} diff --git a/api-wiaas/client/img/wiaas_icon.png b/api-wiaas/client/img/wiaas_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9262c86417729e3e547db516d47ca72fe99e5e47 GIT binary patch literal 1948 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 z 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
@@OB6eqQ3>h2=0 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 literal 0 HcmV?d00001 diff --git a/api-wiaas/client/js/app.js b/api-wiaas/client/js/app.js new file mode 100644 index 0000000..917e691 --- /dev/null +++ b/api-wiaas/client/js/app.js @@ -0,0 +1,32 @@ +var global = { + dashModule: angular.module('dashApp', ['pascalprecht.translate', 'ui-notification', 'ngDragDrop', 'ngFileUpload', 'ui.sortable', 'ui.tinymce', 'ngclipboard']), + PATH_JS_COMPONENTS: 'client/js/components/', + getParameterByName: function (name) { + const url = window.location.href; + const parsedName = name.replace(/[\[\]]/g, '\\$&'); + var regex = new RegExp('[?&]' + parsedName + '(=([^&#]*)|&|#|$)'), + results = regex.exec(url); + + if (!results) { + return null; + } + + if (!results[2]) { + return ''; + } + + return decodeURIComponent(results[2].replace(/\+/g, ' ')); + } +}; + +global.dashModule.factory('$', [ + '$window', + ($window) => { + return $window.jQuery; + } +]); + +global.dashModule.config(function ($httpProvider) { + $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; + $httpProvider.defaults.paramSerializer = '$httpParamSerializerJQLike'; +}); diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/.bower.json b/api-wiaas/client/js/bower_components/angular-dragdrop/.bower.json new file mode 100644 index 0000000..ca692d2 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/.bower.json @@ -0,0 +1,37 @@ +{ + "name": "angular-dragdrop", + "version": "1.0.13", + "description": "This directive allows you to use jQuery UI's draggable and droppable plugins with AngularJS.", + "author": "https://github.com/codef0rmer/angular-dragdrop/contributors", + "license": "MIT", + "homepage": "http://codef0rmer.github.io/angular-dragdrop", + "main": "./src/angular-dragdrop.js", + "ignore": [ + "**/.*", + "node_modules", + "components", + "test*", + "demo*", + "gruntFile.js", + "package.json" + ], + "dependencies": { + "jquery-ui": "latest", + "angular": "latest" + }, + "devDependencies": { + "angular-mocks": "latest", + "angular-ui-bootstrap-bower": "latest", + "angular-animate": "latest" + }, + "_release": "1.0.13", + "_resolution": { + "type": "version", + "tag": "v1.0.13", + "commit": "aecc6ec885eb2e181576c5859f75fda61a0b178a" + }, + "_source": "https://github.com/codef0rmer/angular-dragdrop.git", + "_target": "^1.0.13", + "_originalSource": "angular-dragdrop", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/LICENSE b/api-wiaas/client/js/bower_components/angular-dragdrop/LICENSE new file mode 100644 index 0000000..f62ba65 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2013 Amit Gharat a.k.a codef0rmer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/README.md b/api-wiaas/client/js/bower_components/angular-dragdrop/README.md new file mode 100644 index 0000000..251614c --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/README.md @@ -0,0 +1,108 @@ +#Drag and Drop for AngularJS (with Animation) +[![Build Status](https://api.travis-ci.org/codef0rmer/angular-dragdrop.svg?branch=master)](https://travis-ci.org/codef0rmer/angular-dragdrop) +[![npm](https://img.shields.io/npm/dt/angular-dragdrop.svg)](https://www.npmjs.com/package/angular-dragdrop) +[![npm version](https://img.shields.io/npm/v/angular-dragdrop.svg)](https://www.npmjs.com/package/angular-dragdrop) +[![Bower version](https://img.shields.io/bower/v/angular-dragdrop.svg)](https://github.com/codef0rmer/angular-dragdrop) + +--- + +Implementing jQueryUI Drag and Drop functionality in AngularJS is easier than ever which is a wrapper for jQueryUI draggable/droppable components. + +###v1.0.13 + 1. Allow to animate back on beforeDrop-cancel event if jqyouioptions.revertDuration is set + 2. Pass right context in case of CtrlAs syntax + 3. Add vertical sortable example in demo/dnd-insertInline.html + + +##How to Use + + * `bower install angular-dragdrop` (or `sudo bower install angular-dragdrop --allow-root`) + * Reference `angular-dragdrop.min.js` in your application as: + + ``` + +``` + * Resolve the dependency in the main module of your application as: + + ``` + angular.module('myApp', ['ngDragDrop']) + ``` + + * Drag anything as: + + ``` + So you think you can drag + ``` + * Finally, check out [the cool demos](http://codef0rmer.github.io/angular-dragdrop/#/) + * Note, use [touchpunch.js](http://touchpunch.furf.com/) to enable drag/drop on touch devices. + +##Angular Draggable options +* **jqyoui-draggable** – A custom angular attribute to make any element draggable. It holds more settings such as: + * **index** – number – $index of an item of a model (if it is an array) associated with it + * **placeholder** – boolean/string – If true, the place will be occupied even though a dragggable is moved/dropped somewhere else. If 'keep' is supplied, the original item won't be removed from the draggable. + * **animate** – boolean – If true, draggable will be animated towards droppable when dropped. If multiple is not set to true on droppable then its draggable will swap its position. + * **onStart** – string – callback method to be invoked (has to be defined in a controller) when dragging starts + * **onStop** – string – callback method to be invoked when dragging stops + * **onDrag** – string – callback method to be invoked while the mouse is moved during the dragging + * **applyFilter** - string - applies AngularJS $filter on the list before swapping items. Only applicable, if ngRepeat has any filter (such as orderBy, limitTo) associated with it. + * **containment** – string - position/offset. Offset by default. This forces to use jQuery.position() or jQuery.offset() to calculate proper position with respect to parent element or document respectively. + * **deepCopy** - boolean (optional) – If true, makes a deep copy of draggable that looses prototypical inheritance. + * **beforeDrop** – promise (optional) – Ask for confirmation before swapping. Works with both window.confirm and custom popup. + * **insertInline** – boolean(optional) – Make a list sortable. Same model is mandatory for draggable and droppable. + * **direction** – string(optional) – Property name that will be created on each scope to manage animation direction. +* **data-drag** – boolean – If true, element can be draggable. Disabled otherwise. +* **data-jqyoui-options** – object – should hold all the valid options supported by [jQueryUI Draggable](http://api.jqueryui.com/draggable) +* **ng-model** – string – An angular model defined in a controller. Should be a JS array or object + +##Angular Droppable options +* **jqyoui-droppable** – A custom angular attribute to make any element droppable. It holds more settings such as: + * **index** – number – $index of an item of a model (if it is an array) associated with it + * **multiple** – boolean – Requires to be true only if animate is set to true for draggable and to avoid swapping. + * **stack** – boolean – Requires if animate is set to true on draggable and if multiple draggables positioned one below the other + * **onDrop** – string – callback method to be invoked a draggable is dropped into the droppable + * **onOver** – string – callback method to be invoked when an accepted draggable is dragged over the droppable + * **onOut** – string – callback method to be invoked when an accepted draggable is dragged out of the droppable + * **applyFilter** - string - requires if both droppable as well as draggable share the same ngModel. + * **containment** – string - position/offset. Offset by default. This forces to use jQuery.position() or jQuery.offset() to calculate proper position with respect to parent element or document respectively. + * **deepCopy** – boolean (optional) – If true, makes a deep copy of droppable that looses prototypical inheritance. + * **beforeDrop** – promise (optional) – Ask for confirmation before dropping. Works with both window.confirm and custom popup. +* **data-drop** – boolean – If true, element can be droppable. Disabled otherwise. +* **data-jqyoui-options** – object – should hold all the valid options supported by [jQueryUI Droppable](http://api.jqueryui.com/droppable) +* **ng-model** – string – An angular model defined in a controller. Should be a JS array or object. + +##How to Contribute +* $ git clone https://github.com/codef0rmer/angular-dragdrop.git +* $ cd angular-dragdrop +* $ npm install --quiet -g karma-cli bower +* $ sudo npm install +* $ sudo bower install --force-latest +* $ npm test + +##Demo +Demo is [here](http://codef0rmer.github.io/angular-dragdrop/#/) + +###v1.0.12 + 1. Supports insertInline option to simulate sortable functionality. + 2. Relies on ngAnimate for sortable animation from left/right. + 3. Checkout the demo in demo/dnd-insertInline.html + +###v1.0.9 - breaking change + 1. Draggable and Droppable will not be [deep copied](https://egghead.io/lessons/angularjs-angular-copy-for-deep-copy) by default unlike previous versions. Use `deepCopy` option if prototypical inheritance is not required. + 2. Callbacks will not be executed forcefully within the context of scope which requires an extra digest loop for each event (start, stop, over, out, etc), especially drag that fires many times and running a digest loop is performance intensive in such scenario. Call `scope.$apply()` within callback, if needed. + + +###v1.0.5 - breaking change +Do not pass evaluated expressions in callbacks. For example, +####Before: +``` +
{{item.title}}
+``` +####After: +``` +
{{item.title}}
+``` + +## Support +If you're having problems with using the project, use the support forum at CodersClan. + +
diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/bower.json b/api-wiaas/client/js/bower_components/angular-dragdrop/bower.json new file mode 100644 index 0000000..630e67b --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/bower.json @@ -0,0 +1,27 @@ +{ + "name": "angular-dragdrop", + "version": "1.0.13", + "description": "This directive allows you to use jQuery UI's draggable and droppable plugins with AngularJS.", + "author": "https://github.com/codef0rmer/angular-dragdrop/contributors", + "license": "MIT", + "homepage": "http://codef0rmer.github.io/angular-dragdrop", + "main": "./src/angular-dragdrop.js", + "ignore": [ + "**/.*", + "node_modules", + "components", + "test*", + "demo*", + "gruntFile.js", + "package.json" + ], + "dependencies": { + "jquery-ui": "latest", + "angular": "latest" + }, + "devDependencies": { + "angular-mocks": "latest", + "angular-ui-bootstrap-bower": "latest", + "angular-animate": "latest" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/karma.conf.js b/api-wiaas/client/js/bower_components/angular-dragdrop/karma.conf.js new file mode 100644 index 0000000..c56b400 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/karma.conf.js @@ -0,0 +1,28 @@ +module.exports = function(config) { + var configuration = { + basePath: '', + frameworks: ['jasmine'], + files: [ + 'components/jquery/dist/jquery.js', + 'components/jquery-ui/jquery-ui.min.js', + 'components/angular/angular.js', + 'components/angular-mocks/angular-mocks.js', + 'src/angular-dragdrop.js', + 'test/spec/*.js' + ], + singleRun: true, + browsers: ['Chrome'], + customLaunchers: { + Chrome_travis_ci: { + base: 'Chrome', + flags: ['--no-sandbox'] + } + } + }; + + if(process.env.TRAVIS){ + configuration.browsers = ['Chrome_travis_ci']; + } + + config.set(configuration); +}; \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.js b/api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.js new file mode 100644 index 0000000..5522936 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.js @@ -0,0 +1,419 @@ +/** + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * Implementing Drag and Drop functionality in AngularJS is easier than ever. + * Demo: http://codef0rmer.github.com/angular-dragdrop/ + * + * @version 1.0.13 + * + * (c) 2013 Amit Gharat a.k.a codef0rmer - amitgharat.wordpress.com + */ + +(function (window, angular, $, undefined) { +'use strict'; + +var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$timeout', '$parse', '$q', function($timeout, $parse, $q) { + this.draggableScope = null; + this.droppableScope = null; + + $('head').prepend(''); + + this.callEventCallback = function (scope, callbackName, event, ui) { + if (!callbackName) return; + + var objExtract = extract(callbackName), + callback = objExtract.callback, + constructor = objExtract.constructor, + args = [event, ui].concat(objExtract.args); + + // call either $scoped method i.e. $scope.dropCallback or constructor's method i.e. this.dropCallback. + // Removing scope.$apply call that was performance intensive (especially onDrag) and does not require it + // always. So call it within the callback if needed. + return (scope[callback] || scope[constructor][callback]).apply(scope[callback] ? scope : scope[constructor], args); + + function extract(callbackName) { + var atStartBracket = callbackName.indexOf('(') !== -1 ? callbackName.indexOf('(') : callbackName.length, + atEndBracket = callbackName.lastIndexOf(')') !== -1 ? callbackName.lastIndexOf(')') : callbackName.length, + args = callbackName.substring(atStartBracket + 1, atEndBracket), // matching function arguments inside brackets + constructor = callbackName.indexOf('.') !== -1 ? callbackName.substr(0, callbackName.indexOf('.')) : null; // matching a string upto a dot to check ctrl as syntax + constructor = scope[constructor] && typeof scope[constructor].constructor === 'function' ? constructor : null; + + return { + callback: callbackName.substring(constructor && constructor.length + 1 || 0, atStartBracket), + args: $.map(args && args.split(',') || [], function(item) { return [$parse(item)(scope)]; }), + constructor: constructor + } + } + }; + + this.invokeDrop = function ($draggable, $droppable, event, ui) { + var dragModel = '', + dropModel = '', + dragSettings = {}, + dropSettings = {}, + jqyoui_pos = null, + dragItem = {}, + dropItem = {}, + dragModelValue, + dropModelValue, + $droppableDraggable = null, + droppableScope = this.droppableScope, + draggableScope = this.draggableScope, + $helper = null, + promises = [], + temp; + + dragModel = $draggable.ngattr('ng-model'); + dropModel = $droppable.ngattr('ng-model'); + dragModelValue = draggableScope.$eval(dragModel); + dropModelValue = droppableScope.$eval(dropModel); + + $droppableDraggable = $droppable.find('[jqyoui-draggable]:last,[data-jqyoui-draggable]:last'); + dropSettings = droppableScope.$eval($droppable.attr('jqyoui-droppable') || $droppable.attr('data-jqyoui-droppable')) || []; + dragSettings = draggableScope.$eval($draggable.attr('jqyoui-draggable') || $draggable.attr('data-jqyoui-draggable')) || []; + + // Helps pick up the right item + dragSettings.index = this.fixIndex(draggableScope, dragSettings, dragModelValue); + dropSettings.index = this.fixIndex(droppableScope, dropSettings, dropModelValue); + + jqyoui_pos = angular.isArray(dragModelValue) ? dragSettings.index : null; + dragItem = angular.isArray(dragModelValue) ? dragModelValue[jqyoui_pos] : dragModelValue; + + if (dragSettings.deepCopy) { + dragItem = angular.copy(dragItem); + } + + if (angular.isArray(dropModelValue) && dropSettings && dropSettings.index !== undefined) { + dropItem = dropModelValue[dropSettings.index]; + } else if (!angular.isArray(dropModelValue)) { + dropItem = dropModelValue; + } else { + dropItem = {}; + } + + if (dropSettings.deepCopy) { + dropItem = angular.copy(dropItem); + } + + if (dragSettings.beforeDrop) { + promises.push(this.callEventCallback(draggableScope, dragSettings.beforeDrop, event, ui)); + } + + $q.all(promises).then(angular.bind(this, function() { + if (dragSettings.insertInline && dragModel === dropModel) { + if (dragSettings.index > dropSettings.index) { + temp = dragModelValue[dragSettings.index]; + for (var i = dragSettings.index; i > dropSettings.index; i--) { + dropModelValue[i] = angular.copy(dropModelValue[i - 1]); + dropModelValue[i - 1] = {}; + dropModelValue[i][dragSettings.direction] = 'left'; + } + dropModelValue[dropSettings.index] = temp; + } else { + temp = dragModelValue[dragSettings.index]; + for (var i = dragSettings.index; i < dropSettings.index; i++) { + dropModelValue[i] = angular.copy(dropModelValue[i + 1]); + dropModelValue[i + 1] = {}; + dropModelValue[i][dragSettings.direction] = 'right'; + } + dropModelValue[dropSettings.index] = temp; + } + this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui); + } else if (dragSettings.animate === true) { + // be nice with absolutely positioned brethren :-) + $helper = $draggable.clone(); + $helper.css({'position': 'absolute'}).css($draggable.offset()); + $('body').append($helper); + $draggable.addClass('angular-dragdrop-hide'); + + this.move($helper, $droppableDraggable.length > 0 ? $droppableDraggable : $droppable, null, 'fast', dropSettings, function() { $helper.remove(); }); + this.move($droppableDraggable.length > 0 && !dropSettings.multiple ? $droppableDraggable : [], $draggable.parent('[jqyoui-droppable],[data-jqyoui-droppable]'), jqyoui.startXY, 'fast', dropSettings, angular.bind(this, function() { + $timeout(angular.bind(this, function() { + // Do not move this into move() to avoid flickering issue + $draggable.css({'position': 'relative', 'left': '', 'top': ''}).removeClass('angular-dragdrop-hide'); + // Angular v1.2 uses ng-hide to hide an element not display property + // so we've to manually remove display:none set in this.move() + $droppableDraggable.css({'position': 'relative', 'left': '', 'top': '', 'display': $droppableDraggable.css('display') === 'none' ? '' : $droppableDraggable.css('display')}); + + this.mutateDraggable(draggableScope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable); + this.mutateDroppable(droppableScope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos); + this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui); + })); + })); + } else { + $timeout(angular.bind(this, function() { + this.mutateDraggable(draggableScope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable); + this.mutateDroppable(droppableScope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos); + this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui); + })); + } + })).finally(angular.bind(this, function() { + this.restore($draggable); + })); + }; + + this.move = function($fromEl, $toEl, toPos, duration, dropSettings, callback) { + if ($fromEl.length === 0) { + if (callback) { + window.setTimeout(function() { + callback(); + }, 300); + } + return false; + } + + var zIndex = $fromEl.css('z-index'), + fromPos = $fromEl[dropSettings.containment || 'offset'](), + displayProperty = $toEl.css('display'), // sometimes `display` is other than `block` + hadNgHideCls = $toEl.hasClass('ng-hide'), + hadDNDHideCls = $toEl.hasClass('angular-dragdrop-hide'); + + if (toPos === null && $toEl.length > 0) { + if (($toEl.attr('jqyoui-draggable') || $toEl.attr('data-jqyoui-draggable')) !== undefined && $toEl.ngattr('ng-model') !== undefined && $toEl.is(':visible') && dropSettings && dropSettings.multiple) { + toPos = $toEl[dropSettings.containment || 'offset'](); + if (dropSettings.stack === false) { + toPos.left+= $toEl.outerWidth(true); + } else { + toPos.top+= $toEl.outerHeight(true); + } + } else { + // Angular v1.2 uses ng-hide to hide an element + // so we've to remove it in order to grab its position + if (hadNgHideCls) $toEl.removeClass('ng-hide'); + if (hadDNDHideCls) $toEl.removeClass('angular-dragdrop-hide'); + toPos = $toEl.css({'visibility': 'hidden', 'display': 'block'})[dropSettings.containment || 'offset'](); + $toEl.css({'visibility': '','display': displayProperty}); + } + } + + $fromEl.css({'position': 'absolute', 'z-index': 9999}) + .css(fromPos) + .animate(toPos, duration, function() { + // Angular v1.2 uses ng-hide to hide an element + // and as we remove it above, we've to put it back to + // hide the element (while swapping) if it was hidden already + // because we remove the display:none in this.invokeDrop() + if (hadNgHideCls) $toEl.addClass('ng-hide'); + if (hadDNDHideCls) $toEl.addClass('angular-dragdrop-hide'); + $fromEl.css('z-index', zIndex); + if (callback) callback(); + }); + }; + + this.mutateDroppable = function(scope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos) { + var dropModelValue = scope.$eval(dropModel); + + scope.dndDragItem = dragItem; + + if (angular.isArray(dropModelValue)) { + if (dropSettings && dropSettings.index >= 0) { + dropModelValue[dropSettings.index] = dragItem; + } else { + dropModelValue.push(dragItem); + } + if (dragSettings && dragSettings.placeholder === true) { + dropModelValue[dropModelValue.length - 1]['jqyoui_pos'] = jqyoui_pos; + } + } else { + $parse(dropModel + ' = dndDragItem')(scope); + if (dragSettings && dragSettings.placeholder === true) { + dropModelValue['jqyoui_pos'] = jqyoui_pos; + } + } + }; + + this.mutateDraggable = function(scope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable) { + var isEmpty = angular.equals(dropItem, {}) || !dropItem, + dragModelValue = scope.$eval(dragModel); + + scope.dndDropItem = dropItem; + + if (dragSettings && dragSettings.placeholder) { + if (dragSettings.placeholder != 'keep'){ + if (angular.isArray(dragModelValue) && dragSettings.index !== undefined) { + dragModelValue[dragSettings.index] = dropItem; + } else { + $parse(dragModel + ' = dndDropItem')(scope); + } + } + } else { + if (angular.isArray(dragModelValue)) { + if (isEmpty) { + if (dragSettings && ( dragSettings.placeholder !== true && dragSettings.placeholder !== 'keep' )) { + dragModelValue.splice(dragSettings.index, 1); + } + } else { + dragModelValue[dragSettings.index] = dropItem; + } + } else { + // Fix: LIST(object) to LIST(array) - model does not get updated using just scope[dragModel] = {...} + // P.S.: Could not figure out why it happened + $parse(dragModel + ' = dndDropItem')(scope); + if (scope.$parent) { + $parse(dragModel + ' = dndDropItem')(scope.$parent); + } + } + } + + this.restore($draggable); + }; + + this.restore = function($draggable) { + $draggable.css({'z-index': '', 'left': '', 'top': ''}); + }; + + this.fixIndex = function(scope, settings, modelValue) { + if (settings.applyFilter && angular.isArray(modelValue) && modelValue.length > 0) { + var dragModelValueFiltered = scope[settings.applyFilter](), + lookup = dragModelValueFiltered[settings.index], + actualIndex = undefined; + + modelValue.forEach(function(item, i) { + if (angular.equals(item, lookup)) { + actualIndex = i; + } + }); + + return actualIndex; + } + + return settings.index; + }; + }]).directive('jqyouiDraggable', ['ngDragDropService', function(ngDragDropService) { + return { + require: '?jqyouiDroppable', + restrict: 'A', + link: function(scope, elem, attrs) { + var element = $(elem); + var dragSettings, jqyouiOptions, zIndex, killWatcher; + var updateDraggable = function(newValue, oldValue) { + if (newValue) { + dragSettings = scope.$eval(element.attr('jqyoui-draggable') || element.attr('data-jqyoui-draggable')) || {}; + jqyouiOptions = scope.$eval(attrs.jqyouiOptions) || {}; + element + .draggable({disabled: false}) + .draggable(jqyouiOptions) + .draggable({ + start: function(event, ui) { + ngDragDropService.draggableScope = scope; + zIndex = $(jqyouiOptions.helper ? ui.helper : this).css('z-index'); + $(jqyouiOptions.helper ? ui.helper : this).css('z-index', 9999); + jqyoui.startXY = $(this)[dragSettings.containment || 'offset'](); + ngDragDropService.callEventCallback(scope, dragSettings.onStart, event, ui); + }, + stop: function(event, ui) { + $(jqyouiOptions.helper ? ui.helper : this).css('z-index', zIndex); + ngDragDropService.callEventCallback(scope, dragSettings.onStop, event, ui); + }, + drag: function(event, ui) { + ngDragDropService.callEventCallback(scope, dragSettings.onDrag, event, ui); + } + }); + } else { + element.draggable({disabled: true}); + } + + if (killWatcher && angular.isDefined(newValue) && (angular.equals(attrs.drag, 'true') || angular.equals(attrs.drag, 'false'))) { + killWatcher(); + killWatcher = null; + } + }; + + killWatcher = scope.$watch(function() { return scope.$eval(attrs.drag); }, updateDraggable); + updateDraggable(); + + element.on('$destroy', function() { + element.draggable({disabled: true}).draggable('destroy'); + }); + } + }; + }]).directive('jqyouiDroppable', ['ngDragDropService', '$q', function(ngDragDropService, $q) { + return { + restrict: 'A', + priority: 1, + link: function(scope, elem, attrs) { + var element = $(elem); + var dropSettings, jqyouiOptions, killWatcher; + var updateDroppable = function(newValue, oldValue) { + if (newValue) { + dropSettings = scope.$eval($(element).attr('jqyoui-droppable') || $(element).attr('data-jqyoui-droppable')) || {}; + jqyouiOptions = scope.$eval(attrs.jqyouiOptions) || {}; + element + .droppable({disabled: false}) + .droppable(jqyouiOptions) + .droppable({ + over: function(event, ui) { + ngDragDropService.callEventCallback(scope, dropSettings.onOver, event, ui); + }, + out: function(event, ui) { + ngDragDropService.callEventCallback(scope, dropSettings.onOut, event, ui); + }, + drop: function(event, ui) { + var beforeDropPromise = null; + + if (dropSettings.beforeDrop) { + beforeDropPromise = ngDragDropService.callEventCallback(scope, dropSettings.beforeDrop, event, ui); + } else { + beforeDropPromise = (function() { + var deferred = $q.defer(); + deferred.resolve(); + return deferred.promise; + })(); + } + + beforeDropPromise.then(angular.bind(this, function() { + if ($(ui.draggable).ngattr('ng-model') && attrs.ngModel) { + ngDragDropService.droppableScope = scope; + ngDragDropService.invokeDrop($(ui.draggable), $(this), event, ui); + } else { + ngDragDropService.callEventCallback(scope, dropSettings.onDrop, event, ui); + } + }), function() { + ui.draggable.animate({left: '', top: ''}, jqyouiOptions.revertDuration || 0); + }); + } + }); + } else { + element.droppable({disabled: true}); + } + + if (killWatcher && angular.isDefined(newValue) && (angular.equals(attrs.drop, 'true') || angular.equals(attrs.drop, 'false'))) { + killWatcher(); + killWatcher = null; + } + }; + + killWatcher = scope.$watch(function() { return scope.$eval(attrs.drop); }, updateDroppable); + updateDroppable(); + + element.on('$destroy', function() { + element.droppable({disabled: true}).droppable('destroy'); + }); + } + }; + }]); + + $.fn.ngattr = function(name, value) { + var element = this[0]; + + return element.getAttribute(name) || element.getAttribute('data-' + name); + }; +})(window, window.angular, window.jQuery); diff --git a/api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.min.js b/api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.min.js new file mode 100644 index 0000000..fbcb739 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-dragdrop/src/angular-dragdrop.min.js @@ -0,0 +1,29 @@ +/** + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * Implementing Drag and Drop functionality in AngularJS is easier than ever. + * Demo: http://codef0rmer.github.com/angular-dragdrop/ + * + * @version 1.0.13 + * + * (c) 2013 Amit Gharat a.k.a codef0rmer - amitgharat.wordpress.com + */ +!function(e,a,t,n){"use strict";var i=a.module("ngDragDrop",[]).service("ngDragDropService",["$timeout","$parse","$q",function(r,l,o){this.draggableScope=null,this.droppableScope=null,t("head").prepend(''),this.callEventCallback=function(e,a,n,i){function r(a){var n=-1!==a.indexOf("(")?a.indexOf("("):a.length,i=-1!==a.lastIndexOf(")")?a.lastIndexOf(")"):a.length,r=a.substring(n+1,i),o=-1!==a.indexOf(".")?a.substr(0,a.indexOf(".")):null;return o=e[o]&&"function"==typeof e[o].constructor?o:null,{callback:a.substring(o&&o.length+1||0,n),args:t.map(r&&r.split(",")||[],function(a){return[l(a)(e)]}),constructor:o}}if(a){var o=r(a),d=o.callback,s=o.constructor,p=[n,i].concat(o.args);return(e[d]||e[s][d]).apply(e[d]?e:e[s],p)}},this.invokeDrop=function(e,l,d,s){var p,c,u,g="",f="",b={},h={},v=null,y={},x={},m=null,D=this.droppableScope,q=this.draggableScope,j=null,k=[];g=e.ngattr("ng-model"),f=l.ngattr("ng-model"),p=q.$eval(g),c=D.$eval(f),m=l.find("[jqyoui-draggable]:last,[data-jqyoui-draggable]:last"),h=D.$eval(l.attr("jqyoui-droppable")||l.attr("data-jqyoui-droppable"))||[],b=q.$eval(e.attr("jqyoui-draggable")||e.attr("data-jqyoui-draggable"))||[],b.index=this.fixIndex(q,b,p),h.index=this.fixIndex(D,h,c),v=a.isArray(p)?b.index:null,y=a.isArray(p)?p[v]:p,b.deepCopy&&(y=a.copy(y)),x=a.isArray(c)&&h&&h.index!==n?c[h.index]:a.isArray(c)?{}:c,h.deepCopy&&(x=a.copy(x)),b.beforeDrop&&k.push(this.callEventCallback(q,b.beforeDrop,d,s)),o.all(k).then(a.bind(this,function(){if(b.insertInline&&g===f){if(b.index>h.index){u=p[b.index];for(var n=b.index;n>h.index;n--)c[n]=a.copy(c[n-1]),c[n-1]={},c[n][b.direction]="left";c[h.index]=u}else{u=p[b.index];for(var n=b.index;n0?m:l,null,"fast",h,function(){j.remove()}),this.move(m.length>0&&!h.multiple?m:[],e.parent("[jqyoui-droppable],[data-jqyoui-droppable]"),i.startXY,"fast",h,a.bind(this,function(){r(a.bind(this,function(){e.css({position:"relative",left:"",top:""}).removeClass("angular-dragdrop-hide"),m.css({position:"relative",left:"",top:"",display:"none"===m.css("display")?"":m.css("display")}),this.mutateDraggable(q,h,b,g,f,x,e),this.mutateDroppable(D,h,b,f,y,v),this.callEventCallback(D,h.onDrop,d,s)}))}))):r(a.bind(this,function(){this.mutateDraggable(q,h,b,g,f,x,e),this.mutateDroppable(D,h,b,f,y,v),this.callEventCallback(D,h.onDrop,d,s)}))}))["finally"](a.bind(this,function(){this.restore(e)}))},this.move=function(a,t,i,r,l,o){if(0===a.length)return o&&e.setTimeout(function(){o()},300),!1;var d=a.css("z-index"),s=a[l.containment||"offset"](),p=t.css("display"),c=t.hasClass("ng-hide"),u=t.hasClass("angular-dragdrop-hide");null===i&&t.length>0&&((t.attr("jqyoui-draggable")||t.attr("data-jqyoui-draggable"))!==n&&t.ngattr("ng-model")!==n&&t.is(":visible")&&l&&l.multiple?(i=t[l.containment||"offset"](),l.stack===!1?i.left+=t.outerWidth(!0):i.top+=t.outerHeight(!0)):(c&&t.removeClass("ng-hide"),u&&t.removeClass("angular-dragdrop-hide"),i=t.css({visibility:"hidden",display:"block"})[l.containment||"offset"](),t.css({visibility:"",display:p}))),a.css({position:"absolute","z-index":9999}).css(s).animate(i,r,function(){c&&t.addClass("ng-hide"),u&&t.addClass("angular-dragdrop-hide"),a.css("z-index",d),o&&o()})},this.mutateDroppable=function(e,t,n,i,r,o){var d=e.$eval(i);e.dndDragItem=r,a.isArray(d)?(t&&t.index>=0?d[t.index]=r:d.push(r),n&&n.placeholder===!0&&(d[d.length-1].jqyoui_pos=o)):(l(i+" = dndDragItem")(e),n&&n.placeholder===!0&&(d.jqyoui_pos=o))},this.mutateDraggable=function(e,t,i,r,o,d,s){var p=a.equals(d,{})||!d,c=e.$eval(r);e.dndDropItem=d,i&&i.placeholder?"keep"!=i.placeholder&&(a.isArray(c)&&i.index!==n?c[i.index]=d:l(r+" = dndDropItem")(e)):a.isArray(c)?p?i&&i.placeholder!==!0&&"keep"!==i.placeholder&&c.splice(i.index,1):c[i.index]=d:(l(r+" = dndDropItem")(e),e.$parent&&l(r+" = dndDropItem")(e.$parent)),this.restore(s)},this.restore=function(e){e.css({"z-index":"",left:"",top:""})},this.fixIndex=function(e,t,i){if(t.applyFilter&&a.isArray(i)&&i.length>0){var r=e[t.applyFilter](),l=r[t.index],o=n;return i.forEach(function(e,t){a.equals(e,l)&&(o=t)}),o}return t.index}}]).directive("jqyouiDraggable",["ngDragDropService",function(e){return{require:"?jqyouiDroppable",restrict:"A",link:function(n,r,l){var o,d,s,p,c=t(r),u=function(r,u){r?(o=n.$eval(c.attr("jqyoui-draggable")||c.attr("data-jqyoui-draggable"))||{},d=n.$eval(l.jqyouiOptions)||{},c.draggable({disabled:!1}).draggable(d).draggable({start:function(a,r){e.draggableScope=n,s=t(d.helper?r.helper:this).css("z-index"),t(d.helper?r.helper:this).css("z-index",9999),i.startXY=t(this)[o.containment||"offset"](),e.callEventCallback(n,o.onStart,a,r)},stop:function(a,i){t(d.helper?i.helper:this).css("z-index",s),e.callEventCallback(n,o.onStop,a,i)},drag:function(a,t){e.callEventCallback(n,o.onDrag,a,t)}})):c.draggable({disabled:!0}),p&&a.isDefined(r)&&(a.equals(l.drag,"true")||a.equals(l.drag,"false"))&&(p(),p=null)};p=n.$watch(function(){return n.$eval(l.drag)},u),u(),c.on("$destroy",function(){c.draggable({disabled:!0}).draggable("destroy")})}}}]).directive("jqyouiDroppable",["ngDragDropService","$q",function(e,n){return{restrict:"A",priority:1,link:function(i,r,l){var o,d,s,p=t(r),c=function(r,c){r?(o=i.$eval(t(p).attr("jqyoui-droppable")||t(p).attr("data-jqyoui-droppable"))||{},d=i.$eval(l.jqyouiOptions)||{},p.droppable({disabled:!1}).droppable(d).droppable({over:function(a,t){e.callEventCallback(i,o.onOver,a,t)},out:function(a,t){e.callEventCallback(i,o.onOut,a,t)},drop:function(r,s){var p=null;p=o.beforeDrop?e.callEventCallback(i,o.beforeDrop,r,s):function(){var e=n.defer();return e.resolve(),e.promise}(),p.then(a.bind(this,function(){t(s.draggable).ngattr("ng-model")&&l.ngModel?(e.droppableScope=i,e.invokeDrop(t(s.draggable),t(this),r,s)):e.callEventCallback(i,o.onDrop,r,s)}),function(){s.draggable.animate({left:"",top:""},d.revertDuration||0)})}})):p.droppable({disabled:!0}),s&&a.isDefined(r)&&(a.equals(l.drop,"true")||a.equals(l.drop,"false"))&&(s(),s=null)};s=i.$watch(function(){return i.$eval(l.drop)},c),c(),p.on("$destroy",function(){p.droppable({disabled:!0}).droppable("destroy")})}}}]);t.fn.ngattr=function(e,a){var t=this[0];return t.getAttribute(e)||t.getAttribute("data-"+e)}}(window,window.angular,window.jQuery); \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-route/.bower.json b/api-wiaas/client/js/bower_components/angular-route/.bower.json new file mode 100644 index 0000000..bb2f83a --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-route/.bower.json @@ -0,0 +1,21 @@ +{ + "name": "angular-route", + "version": "1.6.1", + "license": "MIT", + "main": "./angular-route.js", + "ignore": [], + "dependencies": { + "angular": "1.6.1" + }, + "homepage": "https://github.com/angular/bower-angular-route", + "_release": "1.6.1", + "_resolution": { + "type": "version", + "tag": "v1.6.1", + "commit": "409c45cfc589d66457f7cbb11aa1fc47f8dbbf78" + }, + "_source": "https://github.com/angular/bower-angular-route.git", + "_target": "^1.6.1", + "_originalSource": "angular-route", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-route/LICENSE.md b/api-wiaas/client/js/bower_components/angular-route/LICENSE.md new file mode 100644 index 0000000..2c395ee --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-route/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Angular + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/api-wiaas/client/js/bower_components/angular-route/README.md b/api-wiaas/client/js/bower_components/angular-route/README.md new file mode 100644 index 0000000..2cd4f90 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-route/README.md @@ -0,0 +1,68 @@ +# packaged angular-route + +This repo is for distribution on `npm` and `bower`. The source for this module is in the +[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngRoute). +Please file issues and pull requests against that repo. + +## Install + +You can install this package either with `npm` or with `bower`. + +### npm + +```shell +npm install angular-route +``` + +Then add `ngRoute` as a dependency for your app: + +```javascript +angular.module('myApp', [require('angular-route')]); +``` + +### bower + +```shell +bower install angular-route +``` + +Add a ` +``` + +Then add `ngRoute` as a dependency for your app: + +```javascript +angular.module('myApp', ['ngRoute']); +``` + +## Documentation + +Documentation is available on the +[AngularJS docs site](http://docs.angularjs.org/api/ngRoute). + +## License + +The MIT License + +Copyright (c) 2010-2015 Google, Inc. http://angularjs.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/api-wiaas/client/js/bower_components/angular-route/angular-route.js b/api-wiaas/client/js/bower_components/angular-route/angular-route.js new file mode 100644 index 0000000..42e25ce --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-route/angular-route.js @@ -0,0 +1,1216 @@ +/** + * @license AngularJS v1.6.1 + * (c) 2010-2016 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular) {'use strict'; + +/* global shallowCopy: true */ + +/** + * Creates a shallow copy of an object, an array or a primitive. + * + * Assumes that there are no proto properties for objects. + */ +function shallowCopy(src, dst) { + if (isArray(src)) { + dst = dst || []; + + for (var i = 0, ii = src.length; i < ii; i++) { + dst[i] = src[i]; + } + } else if (isObject(src)) { + dst = dst || {}; + + for (var key in src) { + if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } + } + } + + return dst || src; +} + +/* global shallowCopy: false */ + +// `isArray` and `isObject` are necessary for `shallowCopy()` (included via `src/shallowCopy.js`). +// They are initialized inside the `$RouteProvider`, to ensure `window.angular` is available. +var isArray; +var isObject; +var isDefined; + +/** + * @ngdoc module + * @name ngRoute + * @description + * + * # ngRoute + * + * The `ngRoute` module provides routing and deeplinking services and directives for angular apps. + * + * ## Example + * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. + * + * + *
+ */ +/* global -ngRouteModule */ +var ngRouteModule = angular. + module('ngRoute', []). + provider('$route', $RouteProvider). + // Ensure `$route` will be instantiated in time to capture the initial `$locationChangeSuccess` + // event (unless explicitly disabled). This is necessary in case `ngView` is included in an + // asynchronously loaded template. + run(instantiateRoute); +var $routeMinErr = angular.$$minErr('ngRoute'); +var isEagerInstantiationEnabled; + + +/** + * @ngdoc provider + * @name $routeProvider + * @this + * + * @description + * + * Used for configuring routes. + * + * ## Example + * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. + * + * ## Dependencies + * Requires the {@link ngRoute `ngRoute`} module to be installed. + */ +function $RouteProvider() { + isArray = angular.isArray; + isObject = angular.isObject; + isDefined = angular.isDefined; + + function inherit(parent, extra) { + return angular.extend(Object.create(parent), extra); + } + + var routes = {}; + + /** + * @ngdoc method + * @name $routeProvider#when + * + * @param {string} path Route path (matched against `$location.path`). If `$location.path` + * contains redundant trailing slash or is missing one, the route will still match and the + * `$location.path` will be updated to add or drop the trailing slash to exactly match the + * route definition. + * + * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up + * to the next slash are matched and stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain named groups starting with a colon and ending with a star: + * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain optional named groups with a question mark: e.g.`:name?`. + * + * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match + * `/color/brown/largecode/code/with/slashes/edit` and extract: + * + * * `color: brown` + * * `largecode: code/with/slashes`. + * + * + * @param {Object} route Mapping information to be assigned to `$route.current` on route + * match. + * + * Object properties: + * + * - `controller` – `{(string|Function)=}` – Controller fn that should be associated with + * newly created scope or the name of a {@link angular.Module#controller registered + * controller} if passed as a string. + * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller. + * If present, the controller will be published to scope under the `controllerAs` name. + * - `template` – `{(string|Function)=}` – html template as a string or a function that + * returns an html template as a string which should be used by {@link + * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives. + * This property takes precedence over `templateUrl`. + * + * If `template` is a function, it will be called with the following parameters: + * + * - `{Array.}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * One of `template` or `templateUrl` is required. + * + * - `templateUrl` – `{(string|Function)=}` – path or function that returns a path to an html + * template that should be used by {@link ngRoute.directive:ngView ngView}. + * + * If `templateUrl` is a function, it will be called with the following parameters: + * + * - `{Array.}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * One of `templateUrl` or `template` is required. + * + * - `resolve` - `{Object.=}` - An optional map of dependencies which should + * be injected into the controller. If any of these dependencies are promises, the router + * will wait for them all to be resolved or one to be rejected before the controller is + * instantiated. + * If all the promises are resolved successfully, the values of the resolved promises are + * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is + * fired. If any of the promises are rejected the + * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. + * For easier access to the resolved dependencies from the template, the `resolve` map will + * be available on the scope of the route, under `$resolve` (by default) or a custom name + * specified by the `resolveAs` property (see below). This can be particularly useful, when + * working with {@link angular.Module#component components} as route templates.
+ *
+ * **Note:** If your scope already contains a property with this name, it will be hidden + * or overwritten. Make sure, you specify an appropriate name for this property, that + * does not collide with other properties on the scope. + *
+ * The map object is: + * + * - `key` – `{string}`: a name of a dependency to be injected into the controller. + * - `factory` - `{string|Function}`: If `string` then it is an alias for a service. + * Otherwise if function, then it is {@link auto.$injector#invoke injected} + * and the return value is treated as the dependency. If the result is a promise, it is + * resolved before its value is injected into the controller. Be aware that + * `ngRoute.$routeParams` will still refer to the previous route within these resolve + * functions. Use `$route.current.params` to access the new route parameters, instead. + * + * - `resolveAs` - `{string=}` - The name under which the `resolve` map will be available on + * the scope of the route. If omitted, defaults to `$resolve`. + * + * - `redirectTo` – `{(string|Function)=}` – value to update + * {@link ng.$location $location} path with and trigger route redirection. + * + * If `redirectTo` is a function, it will be called with the following parameters: + * + * - `{Object.}` - route parameters extracted from the current + * `$location.path()` by applying the current route templateUrl. + * - `{string}` - current `$location.path()` + * - `{Object}` - current `$location.search()` + * + * The custom `redirectTo` function is expected to return a string which will be used + * to update `$location.url()`. If the function throws an error, no further processing will + * take place and the {@link ngRoute.$route#$routeChangeError $routeChangeError} event will + * be fired. + * + * Routes that specify `redirectTo` will not have their controllers, template functions + * or resolves called, the `$location` will be changed to the redirect url and route + * processing will stop. The exception to this is if the `redirectTo` is a function that + * returns `undefined`. In this case the route transition occurs as though there was no + * redirection. + * + * - `resolveRedirectTo` – `{Function=}` – a function that will (eventually) return the value + * to update {@link ng.$location $location} URL with and trigger route redirection. In + * contrast to `redirectTo`, dependencies can be injected into `resolveRedirectTo` and the + * return value can be either a string or a promise that will be resolved to a string. + * + * Similar to `redirectTo`, if the return value is `undefined` (or a promise that gets + * resolved to `undefined`), no redirection takes place and the route transition occurs as + * though there was no redirection. + * + * If the function throws an error or the returned promise gets rejected, no further + * processing will take place and the + * {@link ngRoute.$route#$routeChangeError $routeChangeError} event will be fired. + * + * `redirectTo` takes precedence over `resolveRedirectTo`, so specifying both on the same + * route definition, will cause the latter to be ignored. + * + * - `[reloadOnSearch=true]` - `{boolean=}` - reload route when only `$location.search()` + * or `$location.hash()` changes. + * + * If the option is set to `false` and url in the browser changes, then + * `$routeUpdate` event is broadcasted on the root scope. + * + * - `[caseInsensitiveMatch=false]` - `{boolean=}` - match routes without being case sensitive + * + * If the option is set to `true`, then the particular route can be matched without being + * case sensitive + * + * @returns {Object} self + * + * @description + * Adds a new route definition to the `$route` service. + */ + this.when = function(path, route) { + //copy original route object to preserve params inherited from proto chain + var routeCopy = shallowCopy(route); + if (angular.isUndefined(routeCopy.reloadOnSearch)) { + routeCopy.reloadOnSearch = true; + } + if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) { + routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch; + } + routes[path] = angular.extend( + routeCopy, + path && pathRegExp(path, routeCopy) + ); + + // create redirection for trailing slashes + if (path) { + var redirectPath = (path[path.length - 1] === '/') + ? path.substr(0, path.length - 1) + : path + '/'; + + routes[redirectPath] = angular.extend( + {redirectTo: path}, + pathRegExp(redirectPath, routeCopy) + ); + } + + return this; + }; + + /** + * @ngdoc property + * @name $routeProvider#caseInsensitiveMatch + * @description + * + * A boolean property indicating if routes defined + * using this provider should be matched using a case insensitive + * algorithm. Defaults to `false`. + */ + this.caseInsensitiveMatch = false; + + /** + * @param path {string} path + * @param opts {Object} options + * @return {?Object} + * + * @description + * Normalizes the given path, returning a regular expression + * and the original path. + * + * Inspired by pathRexp in visionmedia/express/lib/utils.js. + */ + function pathRegExp(path, opts) { + var insensitive = opts.caseInsensitiveMatch, + ret = { + originalPath: path, + regexp: path + }, + keys = ret.keys = []; + + path = path + .replace(/([().])/g, '\\$1') + .replace(/(\/)?:(\w+)(\*\?|[?*])?/g, function(_, slash, key, option) { + var optional = (option === '?' || option === '*?') ? '?' : null; + var star = (option === '*' || option === '*?') ? '*' : null; + keys.push({ name: key, optional: !!optional }); + slash = slash || ''; + return '' + + (optional ? '' : slash) + + '(?:' + + (optional ? slash : '') + + (star && '(.+?)' || '([^/]+)') + + (optional || '') + + ')' + + (optional || ''); + }) + .replace(/([/$*])/g, '\\$1'); + + ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : ''); + return ret; + } + + /** + * @ngdoc method + * @name $routeProvider#otherwise + * + * @description + * Sets route definition that will be used on route change when no other route definition + * is matched. + * + * @param {Object|string} params Mapping information to be assigned to `$route.current`. + * If called with a string, the value maps to `redirectTo`. + * @returns {Object} self + */ + this.otherwise = function(params) { + if (typeof params === 'string') { + params = {redirectTo: params}; + } + this.when(null, params); + return this; + }; + + /** + * @ngdoc method + * @name $routeProvider#eagerInstantiationEnabled + * @kind function + * + * @description + * Call this method as a setter to enable/disable eager instantiation of the + * {@link ngRoute.$route $route} service upon application bootstrap. You can also call it as a + * getter (i.e. without any arguments) to get the current value of the + * `eagerInstantiationEnabled` flag. + * + * Instantiating `$route` early is necessary for capturing the initial + * {@link ng.$location#$locationChangeStart $locationChangeStart} event and navigating to the + * appropriate route. Usually, `$route` is instantiated in time by the + * {@link ngRoute.ngView ngView} directive. Yet, in cases where `ngView` is included in an + * asynchronously loaded template (e.g. in another directive's template), the directive factory + * might not be called soon enough for `$route` to be instantiated _before_ the initial + * `$locationChangeSuccess` event is fired. Eager instantiation ensures that `$route` is always + * instantiated in time, regardless of when `ngView` will be loaded. + * + * The default value is true. + * + * **Note**:
+ * You may want to disable the default behavior when unit-testing modules that depend on + * `ngRoute`, in order to avoid an unexpected request for the default route's template. + * + * @param {boolean=} enabled - If provided, update the internal `eagerInstantiationEnabled` flag. + * + * @returns {*} The current value of the `eagerInstantiationEnabled` flag if used as a getter or + * itself (for chaining) if used as a setter. + */ + isEagerInstantiationEnabled = true; + this.eagerInstantiationEnabled = function eagerInstantiationEnabled(enabled) { + if (isDefined(enabled)) { + isEagerInstantiationEnabled = enabled; + return this; + } + + return isEagerInstantiationEnabled; + }; + + + this.$get = ['$rootScope', + '$location', + '$routeParams', + '$q', + '$injector', + '$templateRequest', + '$sce', + function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) { + + /** + * @ngdoc service + * @name $route + * @requires $location + * @requires $routeParams + * + * @property {Object} current Reference to the current route definition. + * The route definition contains: + * + * - `controller`: The controller constructor as defined in the route definition. + * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for + * controller instantiation. The `locals` contain + * the resolved values of the `resolve` map. Additionally the `locals` also contain: + * + * - `$scope` - The current route scope. + * - `$template` - The current route template HTML. + * + * The `locals` will be assigned to the route scope's `$resolve` property. You can override + * the property name, using `resolveAs` in the route definition. See + * {@link ngRoute.$routeProvider $routeProvider} for more info. + * + * @property {Object} routes Object with all route configuration Objects as its properties. + * + * @description + * `$route` is used for deep-linking URLs to controllers and views (HTML partials). + * It watches `$location.url()` and tries to map the path to an existing route definition. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API. + * + * The `$route` service is typically used in conjunction with the + * {@link ngRoute.directive:ngView `ngView`} directive and the + * {@link ngRoute.$routeParams `$routeParams`} service. + * + * @example + * This example shows how changing the URL hash causes the `$route` to match a route against the + * URL, and the `ngView` pulls in the partial. + * + * + * + *
+ * Choose: + * Moby | + * Moby: Ch1 | + * Gatsby | + * Gatsby: Ch4 | + * Scarlet Letter
+ * + *
+ * + *
+ * + *
$location.path() = {{$location.path()}}
+ *
$route.current.templateUrl = {{$route.current.templateUrl}}
+ *
$route.current.params = {{$route.current.params}}
+ *
$route.current.scope.name = {{$route.current.scope.name}}
+ *
$routeParams = {{$routeParams}}
+ *
+ *
+ * + * + * controller: {{name}}
+ * Book Id: {{params.bookId}}
+ *
+ * + * + * controller: {{name}}
+ * Book Id: {{params.bookId}}
+ * Chapter Id: {{params.chapterId}} + *
+ * + * + * angular.module('ngRouteExample', ['ngRoute']) + * + * .controller('MainController', function($scope, $route, $routeParams, $location) { + * $scope.$route = $route; + * $scope.$location = $location; + * $scope.$routeParams = $routeParams; + * }) + * + * .controller('BookController', function($scope, $routeParams) { + * $scope.name = 'BookController'; + * $scope.params = $routeParams; + * }) + * + * .controller('ChapterController', function($scope, $routeParams) { + * $scope.name = 'ChapterController'; + * $scope.params = $routeParams; + * }) + * + * .config(function($routeProvider, $locationProvider) { + * $routeProvider + * .when('/Book/:bookId', { + * templateUrl: 'book.html', + * controller: 'BookController', + * resolve: { + * // I will cause a 1 second delay + * delay: function($q, $timeout) { + * var delay = $q.defer(); + * $timeout(delay.resolve, 1000); + * return delay.promise; + * } + * } + * }) + * .when('/Book/:bookId/ch/:chapterId', { + * templateUrl: 'chapter.html', + * controller: 'ChapterController' + * }); + * + * // configure html5 to get links working on jsfiddle + * $locationProvider.html5Mode(true); + * }); + * + * + * + * + * it('should load and compile correct template', function() { + * element(by.linkText('Moby: Ch1')).click(); + * var content = element(by.css('[ng-view]')).getText(); + * expect(content).toMatch(/controller: ChapterController/); + * expect(content).toMatch(/Book Id: Moby/); + * expect(content).toMatch(/Chapter Id: 1/); + * + * element(by.partialLinkText('Scarlet')).click(); + * + * content = element(by.css('[ng-view]')).getText(); + * expect(content).toMatch(/controller: BookController/); + * expect(content).toMatch(/Book Id: Scarlet/); + * }); + * + *
+ */ + + /** + * @ngdoc event + * @name $route#$routeChangeStart + * @eventType broadcast on root scope + * @description + * Broadcasted before a route change. At this point the route services starts + * resolving all of the dependencies needed for the route change to occur. + * Typically this involves fetching the view template as well as any dependencies + * defined in `resolve` route property. Once all of the dependencies are resolved + * `$routeChangeSuccess` is fired. + * + * The route change (and the `$location` change that triggered it) can be prevented + * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} + * for more details about event object. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} next Future route information. + * @param {Route} current Current route information. + */ + + /** + * @ngdoc event + * @name $route#$routeChangeSuccess + * @eventType broadcast on root scope + * @description + * Broadcasted after a route change has happened successfully. + * The `resolve` dependencies are now available in the `current.locals` property. + * + * {@link ngRoute.directive:ngView ngView} listens for the directive + * to instantiate the controller and render the view. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} current Current route information. + * @param {Route|Undefined} previous Previous route information, or undefined if current is + * first route entered. + */ + + /** + * @ngdoc event + * @name $route#$routeChangeError + * @eventType broadcast on root scope + * @description + * Broadcasted if a redirection function fails or any redirection or resolve promises are + * rejected. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current route information. + * @param {Route} previous Previous route information. + * @param {Route} rejection The thrown error or the rejection reason of the promise. Usually + * the rejection reason is the error that caused the promise to get rejected. + */ + + /** + * @ngdoc event + * @name $route#$routeUpdate + * @eventType broadcast on root scope + * @description + * The `reloadOnSearch` property has been set to false, and we are reusing the same + * instance of the Controller. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current/previous route information. + */ + + var forceReload = false, + preparedRoute, + preparedRouteIsUpdateOnly, + $route = { + routes: routes, + + /** + * @ngdoc method + * @name $route#reload + * + * @description + * Causes `$route` service to reload the current route even if + * {@link ng.$location $location} hasn't changed. + * + * As a result of that, {@link ngRoute.directive:ngView ngView} + * creates new scope and reinstantiates the controller. + */ + reload: function() { + forceReload = true; + + var fakeLocationEvent = { + defaultPrevented: false, + preventDefault: function fakePreventDefault() { + this.defaultPrevented = true; + forceReload = false; + } + }; + + $rootScope.$evalAsync(function() { + prepareRoute(fakeLocationEvent); + if (!fakeLocationEvent.defaultPrevented) commitRoute(); + }); + }, + + /** + * @ngdoc method + * @name $route#updateParams + * + * @description + * Causes `$route` service to update the current URL, replacing + * current route parameters with those specified in `newParams`. + * Provided property names that match the route's path segment + * definitions will be interpolated into the location's path, while + * remaining properties will be treated as query params. + * + * @param {!Object} newParams mapping of URL parameter names to values + */ + updateParams: function(newParams) { + if (this.current && this.current.$$route) { + newParams = angular.extend({}, this.current.params, newParams); + $location.path(interpolate(this.current.$$route.originalPath, newParams)); + // interpolate modifies newParams, only query params are left + $location.search(newParams); + } else { + throw $routeMinErr('norout', 'Tried updating route when with no current route'); + } + } + }; + + $rootScope.$on('$locationChangeStart', prepareRoute); + $rootScope.$on('$locationChangeSuccess', commitRoute); + + return $route; + + ///////////////////////////////////////////////////// + + /** + * @param on {string} current url + * @param route {Object} route regexp to match the url against + * @return {?Object} + * + * @description + * Check if the route matches the current url. + * + * Inspired by match in + * visionmedia/express/lib/router/router.js. + */ + function switchRouteMatcher(on, route) { + var keys = route.keys, + params = {}; + + if (!route.regexp) return null; + + var m = route.regexp.exec(on); + if (!m) return null; + + for (var i = 1, len = m.length; i < len; ++i) { + var key = keys[i - 1]; + + var val = m[i]; + + if (key && val) { + params[key.name] = val; + } + } + return params; + } + + function prepareRoute($locationEvent) { + var lastRoute = $route.current; + + preparedRoute = parseRoute(); + preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route + && angular.equals(preparedRoute.pathParams, lastRoute.pathParams) + && !preparedRoute.reloadOnSearch && !forceReload; + + if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) { + if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) { + if ($locationEvent) { + $locationEvent.preventDefault(); + } + } + } + } + + function commitRoute() { + var lastRoute = $route.current; + var nextRoute = preparedRoute; + + if (preparedRouteIsUpdateOnly) { + lastRoute.params = nextRoute.params; + angular.copy(lastRoute.params, $routeParams); + $rootScope.$broadcast('$routeUpdate', lastRoute); + } else if (nextRoute || lastRoute) { + forceReload = false; + $route.current = nextRoute; + + var nextRoutePromise = $q.resolve(nextRoute); + + nextRoutePromise. + then(getRedirectionData). + then(handlePossibleRedirection). + then(function(keepProcessingRoute) { + return keepProcessingRoute && nextRoutePromise. + then(resolveLocals). + then(function(locals) { + // after route change + if (nextRoute === $route.current) { + if (nextRoute) { + nextRoute.locals = locals; + angular.copy(nextRoute.params, $routeParams); + } + $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute); + } + }); + }).catch(function(error) { + if (nextRoute === $route.current) { + $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error); + } + }); + } + } + + function getRedirectionData(route) { + var data = { + route: route, + hasRedirection: false + }; + + if (route) { + if (route.redirectTo) { + if (angular.isString(route.redirectTo)) { + data.path = interpolate(route.redirectTo, route.params); + data.search = route.params; + data.hasRedirection = true; + } else { + var oldPath = $location.path(); + var oldSearch = $location.search(); + var newUrl = route.redirectTo(route.pathParams, oldPath, oldSearch); + + if (angular.isDefined(newUrl)) { + data.url = newUrl; + data.hasRedirection = true; + } + } + } else if (route.resolveRedirectTo) { + return $q. + resolve($injector.invoke(route.resolveRedirectTo)). + then(function(newUrl) { + if (angular.isDefined(newUrl)) { + data.url = newUrl; + data.hasRedirection = true; + } + + return data; + }); + } + } + + return data; + } + + function handlePossibleRedirection(data) { + var keepProcessingRoute = true; + + if (data.route !== $route.current) { + keepProcessingRoute = false; + } else if (data.hasRedirection) { + var oldUrl = $location.url(); + var newUrl = data.url; + + if (newUrl) { + $location. + url(newUrl). + replace(); + } else { + newUrl = $location. + path(data.path). + search(data.search). + replace(). + url(); + } + + if (newUrl !== oldUrl) { + // Exit out and don't process current next value, + // wait for next location change from redirect + keepProcessingRoute = false; + } + } + + return keepProcessingRoute; + } + + function resolveLocals(route) { + if (route) { + var locals = angular.extend({}, route.resolve); + angular.forEach(locals, function(value, key) { + locals[key] = angular.isString(value) ? + $injector.get(value) : + $injector.invoke(value, null, null, key); + }); + var template = getTemplateFor(route); + if (angular.isDefined(template)) { + locals['$template'] = template; + } + return $q.all(locals); + } + } + + function getTemplateFor(route) { + var template, templateUrl; + if (angular.isDefined(template = route.template)) { + if (angular.isFunction(template)) { + template = template(route.params); + } + } else if (angular.isDefined(templateUrl = route.templateUrl)) { + if (angular.isFunction(templateUrl)) { + templateUrl = templateUrl(route.params); + } + if (angular.isDefined(templateUrl)) { + route.loadedTemplateUrl = $sce.valueOf(templateUrl); + template = $templateRequest(templateUrl); + } + } + return template; + } + + /** + * @returns {Object} the current active route, by matching it against the URL + */ + function parseRoute() { + // Match a route + var params, match; + angular.forEach(routes, function(route, path) { + if (!match && (params = switchRouteMatcher($location.path(), route))) { + match = inherit(route, { + params: angular.extend({}, $location.search(), params), + pathParams: params}); + match.$$route = route; + } + }); + // No route matched; fallback to "otherwise" route + return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); + } + + /** + * @returns {string} interpolation of the redirect path with the parameters + */ + function interpolate(string, params) { + var result = []; + angular.forEach((string || '').split(':'), function(segment, i) { + if (i === 0) { + result.push(segment); + } else { + var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/); + var key = segmentMatch[1]; + result.push(params[key]); + result.push(segmentMatch[2] || ''); + delete params[key]; + } + }); + return result.join(''); + } + }]; +} + +instantiateRoute.$inject = ['$injector']; +function instantiateRoute($injector) { + if (isEagerInstantiationEnabled) { + // Instantiate `$route` + $injector.get('$route'); + } +} + +ngRouteModule.provider('$routeParams', $RouteParamsProvider); + + +/** + * @ngdoc service + * @name $routeParams + * @requires $route + * @this + * + * @description + * The `$routeParams` service allows you to retrieve the current set of route parameters. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * The route parameters are a combination of {@link ng.$location `$location`}'s + * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}. + * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched. + * + * In case of parameter name collision, `path` params take precedence over `search` params. + * + * The service guarantees that the identity of the `$routeParams` object will remain unchanged + * (but its properties will likely change) even when a route change occurs. + * + * Note that the `$routeParams` are only updated *after* a route change completes successfully. + * This means that you cannot rely on `$routeParams` being correct in route resolve functions. + * Instead you can use `$route.current.params` to access the new route's parameters. + * + * @example + * ```js + * // Given: + * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby + * // Route: /Chapter/:chapterId/Section/:sectionId + * // + * // Then + * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'} + * ``` + */ +function $RouteParamsProvider() { + this.$get = function() { return {}; }; +} + +ngRouteModule.directive('ngView', ngViewFactory); +ngRouteModule.directive('ngView', ngViewFillContentFactory); + + +/** + * @ngdoc directive + * @name ngView + * @restrict ECA + * + * @description + * # Overview + * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by + * including the rendered template of the current route into the main layout (`index.html`) file. + * Every time the current route changes, the included view changes with it according to the + * configuration of the `$route` service. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * @animations + * | Animation | Occurs | + * |----------------------------------|-------------------------------------| + * | {@link ng.$animate#enter enter} | when the new element is inserted to the DOM | + * | {@link ng.$animate#leave leave} | when the old element is removed from to the DOM | + * + * The enter and leave animation occur concurrently. + * + * @scope + * @priority 400 + * @param {string=} onload Expression to evaluate whenever the view updates. + * + * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll + * $anchorScroll} to scroll the viewport after the view is updated. + * + * - If the attribute is not set, disable scrolling. + * - If the attribute is set without value, enable scrolling. + * - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated + * as an expression yields a truthy value. + * @example + + +
+ Choose: + Moby | + Moby: Ch1 | + Gatsby | + Gatsby: Ch4 | + Scarlet Letter
+ +
+
+
+
+ +
$location.path() = {{main.$location.path()}}
+
$route.current.templateUrl = {{main.$route.current.templateUrl}}
+
$route.current.params = {{main.$route.current.params}}
+
$routeParams = {{main.$routeParams}}
+
+
+ + +
+ controller: {{book.name}}
+ Book Id: {{book.params.bookId}}
+
+
+ + +
+ controller: {{chapter.name}}
+ Book Id: {{chapter.params.bookId}}
+ Chapter Id: {{chapter.params.chapterId}} +
+
+ + + .view-animate-container { + position:relative; + height:100px!important; + background:white; + border:1px solid black; + height:40px; + overflow:hidden; + } + + .view-animate { + padding:10px; + } + + .view-animate.ng-enter, .view-animate.ng-leave { + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + + display:block; + width:100%; + border-left:1px solid black; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + padding:10px; + } + + .view-animate.ng-enter { + left:100%; + } + .view-animate.ng-enter.ng-enter-active { + left:0; + } + .view-animate.ng-leave.ng-leave-active { + left:-100%; + } + + + + angular.module('ngViewExample', ['ngRoute', 'ngAnimate']) + .config(['$routeProvider', '$locationProvider', + function($routeProvider, $locationProvider) { + $routeProvider + .when('/Book/:bookId', { + templateUrl: 'book.html', + controller: 'BookCtrl', + controllerAs: 'book' + }) + .when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: 'ChapterCtrl', + controllerAs: 'chapter' + }); + + $locationProvider.html5Mode(true); + }]) + .controller('MainCtrl', ['$route', '$routeParams', '$location', + function MainCtrl($route, $routeParams, $location) { + this.$route = $route; + this.$location = $location; + this.$routeParams = $routeParams; + }]) + .controller('BookCtrl', ['$routeParams', function BookCtrl($routeParams) { + this.name = 'BookCtrl'; + this.params = $routeParams; + }]) + .controller('ChapterCtrl', ['$routeParams', function ChapterCtrl($routeParams) { + this.name = 'ChapterCtrl'; + this.params = $routeParams; + }]); + + + + + it('should load and compile correct template', function() { + element(by.linkText('Moby: Ch1')).click(); + var content = element(by.css('[ng-view]')).getText(); + expect(content).toMatch(/controller: ChapterCtrl/); + expect(content).toMatch(/Book Id: Moby/); + expect(content).toMatch(/Chapter Id: 1/); + + element(by.partialLinkText('Scarlet')).click(); + + content = element(by.css('[ng-view]')).getText(); + expect(content).toMatch(/controller: BookCtrl/); + expect(content).toMatch(/Book Id: Scarlet/); + }); + +
+ */ + + +/** + * @ngdoc event + * @name ngView#$viewContentLoaded + * @eventType emit on the current ngView scope + * @description + * Emitted every time the ngView content is reloaded. + */ +ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate']; +function ngViewFactory($route, $anchorScroll, $animate) { + return { + restrict: 'ECA', + terminal: true, + priority: 400, + transclude: 'element', + link: function(scope, $element, attr, ctrl, $transclude) { + var currentScope, + currentElement, + previousLeaveAnimation, + autoScrollExp = attr.autoscroll, + onloadExp = attr.onload || ''; + + scope.$on('$routeChangeSuccess', update); + update(); + + function cleanupLastView() { + if (previousLeaveAnimation) { + $animate.cancel(previousLeaveAnimation); + previousLeaveAnimation = null; + } + + if (currentScope) { + currentScope.$destroy(); + currentScope = null; + } + if (currentElement) { + previousLeaveAnimation = $animate.leave(currentElement); + previousLeaveAnimation.done(function(response) { + if (response !== false) previousLeaveAnimation = null; + }); + currentElement = null; + } + } + + function update() { + var locals = $route.current && $route.current.locals, + template = locals && locals.$template; + + if (angular.isDefined(template)) { + var newScope = scope.$new(); + var current = $route.current; + + // Note: This will also link all children of ng-view that were contained in the original + // html. If that content contains controllers, ... they could pollute/change the scope. + // However, using ng-view on an element with additional content does not make sense... + // Note: We can't remove them in the cloneAttchFn of $transclude as that + // function is called before linking the content, which would apply child + // directives to non existing elements. + var clone = $transclude(newScope, function(clone) { + $animate.enter(clone, null, currentElement || $element).done(function onNgViewEnter(response) { + if (response !== false && angular.isDefined(autoScrollExp) + && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }); + cleanupLastView(); + }); + + currentElement = clone; + currentScope = current.scope = newScope; + currentScope.$emit('$viewContentLoaded'); + currentScope.$eval(onloadExp); + } else { + cleanupLastView(); + } + } + } + }; +} + +// This directive is called during the $transclude call of the first `ngView` directive. +// It will replace and compile the content of the element with the loaded template. +// We need this directive so that the element content is already filled when +// the link function of another directive on the same element as ngView +// is called. +ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route']; +function ngViewFillContentFactory($compile, $controller, $route) { + return { + restrict: 'ECA', + priority: -400, + link: function(scope, $element) { + var current = $route.current, + locals = current.locals; + + $element.html(locals.$template); + + var link = $compile($element.contents()); + + if (current.controller) { + locals.$scope = scope; + var controller = $controller(current.controller, locals); + if (current.controllerAs) { + scope[current.controllerAs] = controller; + } + $element.data('$ngControllerController', controller); + $element.children().data('$ngControllerController', controller); + } + scope[current.resolveAs || '$resolve'] = locals; + + link(scope); + } + }; +} + + +})(window, window.angular); diff --git a/api-wiaas/client/js/bower_components/angular-route/angular-route.min.js b/api-wiaas/client/js/bower_components/angular-route/angular-route.min.js new file mode 100644 index 0000000..7d1409b --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-route/angular-route.min.js @@ -0,0 +1,17 @@ +/* + AngularJS v1.6.1 + (c) 2010-2016 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(I,d){'use strict';function A(d){k&&d.get("$route")}function B(t,u,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,f,b,c,m){function v(){p&&(g.cancel(p),p=null);l&&(l.$destroy(),l=null);n&&(p=g.leave(n),p.done(function(a){!1!==a&&(p=null)}),n=null)}function D(){var b=t.current&&t.current.locals;if(d.isDefined(b&&b.$template)){var b=a.$new(),c=t.current;n=m(b,function(b){g.enter(b,null,n||f).done(function(b){!1===b||!d.isDefined(w)||w&&!a.$eval(w)||u()}); +v()});l=c.scope=b;l.$emit("$viewContentLoaded");l.$eval(k)}else v()}var l,n,p,w=b.autoscroll,k=b.onload||"";a.$on("$routeChangeSuccess",D);D()}}}function x(d,k,g){return{restrict:"ECA",priority:-400,link:function(a,f){var b=g.current,c=b.locals;f.html(c.$template);var m=d(f.contents());if(b.controller){c.$scope=a;var v=k(b.controller,c);b.controllerAs&&(a[b.controllerAs]=v);f.data("$ngControllerController",v);f.children().data("$ngControllerController",v)}a[b.resolveAs||"$resolve"]=c;m(a)}}}var y, +E,F,z=d.module("ngRoute",[]).provider("$route",function(){function t(a,f){return d.extend(Object.create(a),f)}function u(a,d){var b=d.caseInsensitiveMatch,c={originalPath:a,regexp:a},g=c.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)(\*\?|[?*])?/g,function(a,b,d,c){a="?"===c||"*?"===c?"?":null;c="*"===c||"*?"===c?"*":null;g.push({name:d,optional:!!a});b=b||"";return""+(a?"":b)+"(?:"+(a?b:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([/$*])/g,"\\$1");c.regexp=new RegExp("^"+ +a+"$",b?"i":"");return c}y=d.isArray;E=d.isObject;F=d.isDefined;var g={};this.when=function(a,f){var b;b=void 0;if(y(f)){b=b||[];for(var c=0,m=f.length;c", + "license": "MIT", + "bugs": { + "url": "https://github.com/angular/angular.js/issues" + }, + "homepage": "http://angularjs.org", + "jspm": { + "shim": { + "angular-route": { + "deps": ["angular"] + } + } + } +} diff --git a/api-wiaas/client/js/bower_components/angular-translate-loader-url/.bower.json b/api-wiaas/client/js/bower_components/angular-translate-loader-url/.bower.json new file mode 100644 index 0000000..9403b89 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate-loader-url/.bower.json @@ -0,0 +1,23 @@ +{ + "name": "angular-translate-loader-url", + "description": "A plugin for Angular Translate", + "version": "2.14.0", + "main": "./angular-translate-loader-url.js", + "ignore": [], + "author": "Pascal Precht", + "license": "MIT", + "dependencies": { + "angular-translate": "~2.14.0" + }, + "homepage": "https://github.com/PascalPrecht/bower-angular-translate-loader-url", + "_release": "2.14.0", + "_resolution": { + "type": "version", + "tag": "2.14.0", + "commit": "79f05cd7d272ece6a10eec216659c67a1e42589e" + }, + "_source": "https://github.com/PascalPrecht/bower-angular-translate-loader-url.git", + "_target": "^2.14.0", + "_originalSource": "angular-translate-loader-url", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-translate-loader-url/README.md b/api-wiaas/client/js/bower_components/angular-translate-loader-url/README.md new file mode 100644 index 0000000..a3c5374 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate-loader-url/README.md @@ -0,0 +1,29 @@ +# angular-translate-loader-url (bower shadow repository) + +This is the _Bower shadow_ repository for *angular-translate-loader-url*. + +## Bugs and issues + +Please file any issues and bugs in our main repository at [angular-translate/angular-translate](https://github.com/angular-translate/angular-translate/issues). + +## Usage + +### via Bower + +```bash +$ bower install angular-translate-loader-url +``` + +### via NPM + +```bash +$ npm install angular-translate-loader-url +``` + +### via cdnjs + +Please have a look at https://cdnjs.com/libraries/angular-translate-loader-url for specific versions. + +## License + +Licensed under MIT. See more details at [angular-translate/angular-translate](https://github.com/angular-translate/angular-translate). diff --git a/api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.js b/api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.js new file mode 100644 index 0000000..ef0f006 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.js @@ -0,0 +1,73 @@ +/*! + * angular-translate - v2.14.0 - 2017-02-11 + * + * Copyright (c) 2017 The angular-translate team, Pascal Precht; Licensed MIT + */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define([], function () { + return (factory()); + }); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + factory(); + } +}(this, function () { + +$translateUrlLoader.$inject = ['$q', '$http']; +angular.module('pascalprecht.translate') +/** + * @ngdoc object + * @name pascalprecht.translate.$translateUrlLoader + * @requires $q + * @requires $http + * + * @description + * Creates a loading function for a typical dynamic url pattern: + * "locale.php?lang=en_US", "locale.php?lang=de_DE", "locale.php?language=nl_NL" etc. + * Prefixing the specified url, the current requested, language id will be applied + * with "?{queryParameter}={key}". + * Using this service, the response of these urls must be an object of + * key-value pairs. + * + * @param {object} options Options object, which gets the url, key and + * optional queryParameter ('lang' is used by default). + */ +.factory('$translateUrlLoader', $translateUrlLoader); + +function $translateUrlLoader($q, $http) { + + 'use strict'; + + return function (options) { + + if (!options || !options.url) { + throw new Error('Couldn\'t use urlLoader since no url is given!'); + } + + var requestParams = {}; + + requestParams[options.queryParameter || 'lang'] = options.key; + + return $http(angular.extend({ + url: options.url, + params: requestParams, + method: 'GET' + }, options.$http)) + .then(function(result) { + return result.data; + }, function () { + return $q.reject(options.key); + }); + }; +} + +$translateUrlLoader.displayName = '$translateUrlLoader'; +return 'pascalprecht.translate'; + +})); diff --git a/api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.min.js b/api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.min.js new file mode 100644 index 0000000..8389264 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate-loader-url/angular-translate-loader-url.min.js @@ -0,0 +1,6 @@ +/*! + * angular-translate - v2.14.0 - 2017-02-11 + * + * Copyright (c) 2017 The angular-translate team, Pascal Precht; Licensed MIT + */ +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return b()}):"object"==typeof exports?module.exports=b():b()}(this,function(){function a(a,b){"use strict";return function(c){if(!c||!c.url)throw new Error("Couldn't use urlLoader since no url is given!");var d={};return d[c.queryParameter||"lang"]=c.key,b(angular.extend({url:c.url,params:d,method:"GET"},c.$http)).then(function(a){return a.data},function(){return a.reject(c.key)})}}return a.$inject=["$q","$http"],angular.module("pascalprecht.translate").factory("$translateUrlLoader",a),a.displayName="$translateUrlLoader","pascalprecht.translate"}); \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-translate-loader-url/bower.json b/api-wiaas/client/js/bower_components/angular-translate-loader-url/bower.json new file mode 100644 index 0000000..fa600d7 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate-loader-url/bower.json @@ -0,0 +1,12 @@ +{ + "name": "angular-translate-loader-url", + "description": "A plugin for Angular Translate", + "version": "2.14.0", + "main": "./angular-translate-loader-url.js", + "ignore": [], + "author": "Pascal Precht", + "license": "MIT", + "dependencies": { + "angular-translate": "~2.14.0" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-translate-loader-url/package.json b/api-wiaas/client/js/bower_components/angular-translate-loader-url/package.json new file mode 100644 index 0000000..ff1baf5 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate-loader-url/package.json @@ -0,0 +1,24 @@ +{ + "name": "angular-translate-loader-url", + "version": "2.14.0", + "description": "Creates a loading function for a typical dynamic url pattern: \"locale.php?lang=en_US\", \"locale.php?lang=de_DE\", \"locale.php?language=nl_NL\" etc. Prefixing the specified url, the current requested, language id will be applied with \"?{queryParameter}={key}\". Using this service, the response of these urls must be an object of key-value pairs.", + "main": "angular-translate-loader-url.js", + "repository": { + "type": "git", + "url": "https://github.com/angular-translate/bower-angular-translate-loader-url.git" + }, + "keywords": [ + "angular", + "translate", + "loader" + ], + "author": "Pascal Precht", + "license": "MIT", + "bugs": { + "url": "https://github.com/angular-translate/angular-translate/issues" + }, + "homepage": "https://angular-translate.github.io", + "dependencies": { + "angular-translate": "~2.14.0" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-translate/.bower.json b/api-wiaas/client/js/bower_components/angular-translate/.bower.json new file mode 100644 index 0000000..abb1be9 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate/.bower.json @@ -0,0 +1,23 @@ +{ + "name": "angular-translate", + "description": "A translation module for AngularJS", + "version": "2.14.0", + "main": "./angular-translate.js", + "ignore": [], + "author": "Pascal Precht", + "license": "MIT", + "dependencies": { + "angular": ">=1.2.26 <1.7" + }, + "homepage": "https://github.com/PascalPrecht/bower-angular-translate", + "_release": "2.14.0", + "_resolution": { + "type": "version", + "tag": "2.14.0", + "commit": "de75c2457dfc3609230f23f7ebbf1d55f493bdfe" + }, + "_source": "https://github.com/PascalPrecht/bower-angular-translate.git", + "_target": "^2.14.0", + "_originalSource": "angular-translate", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-translate/README.md b/api-wiaas/client/js/bower_components/angular-translate/README.md new file mode 100644 index 0000000..4991a99 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate/README.md @@ -0,0 +1,23 @@ +# angular-translate (bower shadow repository) + +This is the _Bower shadow_ repository for *angular-translate*. + +## Bugs and issues + +Please file any issues and bugs in our main repository at [angular-translate/angular-translate](https://github.com/angular-translate/angular-translate/issues). + +## Usage + +### via Bower + +```bash +$ bower install angular-translate +``` + +### via cdnjs + +Please have a look at https://cdnjs.com/libraries/angular-translate for specific versions. + +## License + +Licensed under MIT. See more details at [angular-translate/angular-translate](https://github.com/angular-translate/angular-translate). diff --git a/api-wiaas/client/js/bower_components/angular-translate/angular-translate.js b/api-wiaas/client/js/bower_components/angular-translate/angular-translate.js new file mode 100644 index 0000000..f53cbb2 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate/angular-translate.js @@ -0,0 +1,3704 @@ +/*! + * angular-translate - v2.14.0 - 2017-02-11 + * + * Copyright (c) 2017 The angular-translate team, Pascal Precht; Licensed MIT + */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define([], function () { + return (factory()); + }); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + factory(); + } +}(this, function () { + +/** + * @ngdoc overview + * @name pascalprecht.translate + * + * @description + * The main module which holds everything together. + */ +runTranslate.$inject = ['$translate']; +$translate.$inject = ['$STORAGE_KEY', '$windowProvider', '$translateSanitizationProvider', 'pascalprechtTranslateOverrider']; +$translateDefaultInterpolation.$inject = ['$interpolate', '$translateSanitization']; +translateDirective.$inject = ['$translate', '$interpolate', '$compile', '$parse', '$rootScope']; +translateAttrDirective.$inject = ['$translate', '$rootScope']; +translateCloakDirective.$inject = ['$translate']; +translateFilterFactory.$inject = ['$parse', '$translate']; +$translationCache.$inject = ['$cacheFactory']; +angular.module('pascalprecht.translate', ['ng']) + .run(runTranslate); + +function runTranslate($translate) { + + 'use strict'; + + var key = $translate.storageKey(), + storage = $translate.storage(); + + var fallbackFromIncorrectStorageValue = function () { + var preferred = $translate.preferredLanguage(); + if (angular.isString(preferred)) { + $translate.use(preferred); + // $translate.use() will also remember the language. + // So, we don't need to call storage.put() here. + } else { + storage.put(key, $translate.use()); + } + }; + + fallbackFromIncorrectStorageValue.displayName = 'fallbackFromIncorrectStorageValue'; + + if (storage) { + if (!storage.get(key)) { + fallbackFromIncorrectStorageValue(); + } else { + $translate.use(storage.get(key))['catch'](fallbackFromIncorrectStorageValue); + } + } else if (angular.isString($translate.preferredLanguage())) { + $translate.use($translate.preferredLanguage()); + } +} + +runTranslate.displayName = 'runTranslate'; + +/** + * @ngdoc object + * @name pascalprecht.translate.$translateSanitizationProvider + * + * @description + * + * Configurations for $translateSanitization + */ +angular.module('pascalprecht.translate').provider('$translateSanitization', $translateSanitizationProvider); + +function $translateSanitizationProvider () { + + 'use strict'; + + var $sanitize, + $sce, + currentStrategy = null, // TODO change to either 'sanitize', 'escape' or ['sanitize', 'escapeParameters'] in 3.0. + hasConfiguredStrategy = false, + hasShownNoStrategyConfiguredWarning = false, + strategies; + + /** + * Definition of a sanitization strategy function + * @callback StrategyFunction + * @param {string|object} value - value to be sanitized (either a string or an interpolated value map) + * @param {string} mode - either 'text' for a string (translation) or 'params' for the interpolated params + * @return {string|object} + */ + + /** + * @ngdoc property + * @name strategies + * @propertyOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Following strategies are built-in: + *
+ *
sanitize
+ *
Sanitizes HTML in the translation text using $sanitize
+ *
escape
+ *
Escapes HTML in the translation
+ *
sanitizeParameters
+ *
Sanitizes HTML in the values of the interpolation parameters using $sanitize
+ *
escapeParameters
+ *
Escapes HTML in the values of the interpolation parameters
+ *
escaped
+ *
Support legacy strategy name 'escaped' for backwards compatibility (will be removed in 3.0)
+ *
+ * + */ + + strategies = { + sanitize: function (value, mode/*, context*/) { + if (mode === 'text') { + value = htmlSanitizeValue(value); + } + return value; + }, + escape: function (value, mode/*, context*/) { + if (mode === 'text') { + value = htmlEscapeValue(value); + } + return value; + }, + sanitizeParameters: function (value, mode/*, context*/) { + if (mode === 'params') { + value = mapInterpolationParameters(value, htmlSanitizeValue); + } + return value; + }, + escapeParameters: function (value, mode/*, context*/) { + if (mode === 'params') { + value = mapInterpolationParameters(value, htmlEscapeValue); + } + return value; + }, + sce: function (value, mode, context) { + if (mode === 'text') { + value = htmlTrustValue(value); + } else if (mode === 'params') { + if (context !== 'filter') { + // do html escape in filter context #1101 + value = mapInterpolationParameters(value, htmlEscapeValue); + } + } + return value; + }, + sceParameters: function (value, mode/*, context*/) { + if (mode === 'params') { + value = mapInterpolationParameters(value, htmlTrustValue); + } + return value; + } + }; + // Support legacy strategy name 'escaped' for backwards compatibility. + // TODO should be removed in 3.0 + strategies.escaped = strategies.escapeParameters; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitizationProvider#addStrategy + * @methodOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Adds a sanitization strategy to the list of known strategies. + * + * @param {string} strategyName - unique key for a strategy + * @param {StrategyFunction} strategyFunction - strategy function + * @returns {object} this + */ + this.addStrategy = function (strategyName, strategyFunction) { + strategies[strategyName] = strategyFunction; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitizationProvider#removeStrategy + * @methodOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Removes a sanitization strategy from the list of known strategies. + * + * @param {string} strategyName - unique key for a strategy + * @returns {object} this + */ + this.removeStrategy = function (strategyName) { + delete strategies[strategyName]; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitizationProvider#useStrategy + * @methodOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Selects a sanitization strategy. When an array is provided the strategies will be executed in order. + * + * @param {string|StrategyFunction|array} strategy The sanitization strategy / strategies which should be used. Either a name of an existing strategy, a custom strategy function, or an array consisting of multiple names and / or custom functions. + * @returns {object} this + */ + this.useStrategy = function (strategy) { + hasConfiguredStrategy = true; + currentStrategy = strategy; + return this; + }; + + /** + * @ngdoc object + * @name pascalprecht.translate.$translateSanitization + * @requires $injector + * @requires $log + * + * @description + * Sanitizes interpolation parameters and translated texts. + * + */ + this.$get = ['$injector', '$log', function ($injector, $log) { + + var cachedStrategyMap = {}; + + var applyStrategies = function (value, mode, context, selectedStrategies) { + angular.forEach(selectedStrategies, function (selectedStrategy) { + if (angular.isFunction(selectedStrategy)) { + value = selectedStrategy(value, mode, context); + } else if (angular.isFunction(strategies[selectedStrategy])) { + value = strategies[selectedStrategy](value, mode, context); + } else if (angular.isString(strategies[selectedStrategy])) { + if (!cachedStrategyMap[strategies[selectedStrategy]]) { + try { + cachedStrategyMap[strategies[selectedStrategy]] = $injector.get(strategies[selectedStrategy]); + } catch (e) { + cachedStrategyMap[strategies[selectedStrategy]] = function() {}; + throw new Error('pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: \'' + selectedStrategy + '\''); + } + } + value = cachedStrategyMap[strategies[selectedStrategy]](value, mode, context); + } else { + throw new Error('pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: \'' + selectedStrategy + '\''); + } + }); + return value; + }; + + // TODO: should be removed in 3.0 + var showNoStrategyConfiguredWarning = function () { + if (!hasConfiguredStrategy && !hasShownNoStrategyConfiguredWarning) { + $log.warn('pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details.'); + hasShownNoStrategyConfiguredWarning = true; + } + }; + + if ($injector.has('$sanitize')) { + $sanitize = $injector.get('$sanitize'); + } + if ($injector.has('$sce')) { + $sce = $injector.get('$sce'); + } + + return { + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitization#useStrategy + * @methodOf pascalprecht.translate.$translateSanitization + * + * @description + * Selects a sanitization strategy. When an array is provided the strategies will be executed in order. + * + * @param {string|StrategyFunction|array} strategy The sanitization strategy / strategies which should be used. Either a name of an existing strategy, a custom strategy function, or an array consisting of multiple names and / or custom functions. + */ + useStrategy: (function (self) { + return function (strategy) { + self.useStrategy(strategy); + }; + })(this), + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitization#sanitize + * @methodOf pascalprecht.translate.$translateSanitization + * + * @description + * Sanitizes a value. + * + * @param {string|object} value The value which should be sanitized. + * @param {string} mode The current sanitization mode, either 'params' or 'text'. + * @param {string|StrategyFunction|array} [strategy] Optional custom strategy which should be used instead of the currently selected strategy. + * @param {string} [context] The context of this call: filter, service. Default is service + * @returns {string|object} sanitized value + */ + sanitize: function (value, mode, strategy, context) { + if (!currentStrategy) { + showNoStrategyConfiguredWarning(); + } + + if (!strategy && strategy !== null) { + strategy = currentStrategy; + } + + if (!strategy) { + return value; + } + + if (!context) { + context = 'service'; + } + + var selectedStrategies = angular.isArray(strategy) ? strategy : [strategy]; + return applyStrategies(value, mode, context, selectedStrategies); + } + }; + }]; + + var htmlEscapeValue = function (value) { + var element = angular.element('
'); + element.text(value); // not chainable, see #1044 + return element.html(); + }; + + var htmlSanitizeValue = function (value) { + if (!$sanitize) { + throw new Error('pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as \'escape\'.'); + } + return $sanitize(value); + }; + + var htmlTrustValue = function (value) { + if (!$sce) { + throw new Error('pascalprecht.translate.$translateSanitization: Error cannot find $sce service.'); + } + return $sce.trustAsHtml(value); + }; + + var mapInterpolationParameters = function (value, iteratee, stack) { + if (angular.isDate(value)) { + return value; + } else if (angular.isObject(value)) { + var result = angular.isArray(value) ? [] : {}; + + if (!stack) { + stack = []; + } else { + if (stack.indexOf(value) > -1) { + throw new Error('pascalprecht.translate.$translateSanitization: Error cannot interpolate parameter due recursive object'); + } + } + + stack.push(value); + angular.forEach(value, function (propertyValue, propertyKey) { + + /* Skipping function properties. */ + if (angular.isFunction(propertyValue)) { + return; + } + + result[propertyKey] = mapInterpolationParameters(propertyValue, iteratee, stack); + }); + stack.splice(-1, 1); // remove last + + return result; + } else if (angular.isNumber(value)) { + return value; + } else if (!angular.isUndefined(value) && value !== null) { + return iteratee(value); + } else { + return value; + } + }; +} + +/** + * @ngdoc object + * @name pascalprecht.translate.$translateProvider + * @description + * + * $translateProvider allows developers to register translation-tables, asynchronous loaders + * and similar to configure translation behavior directly inside of a module. + * + */ +angular.module('pascalprecht.translate') + .constant('pascalprechtTranslateOverrider', {}) + .provider('$translate', $translate); + +function $translate($STORAGE_KEY, $windowProvider, $translateSanitizationProvider, pascalprechtTranslateOverrider) { + + 'use strict'; + + var $translationTable = {}, + $preferredLanguage, + $availableLanguageKeys = [], + $languageKeyAliases, + $fallbackLanguage, + $fallbackWasString, + $uses, + $nextLang, + $storageFactory, + $storageKey = $STORAGE_KEY, + $storagePrefix, + $missingTranslationHandlerFactory, + $interpolationFactory, + $interpolatorFactories = [], + $loaderFactory, + $cloakClassName = 'translate-cloak', + $loaderOptions, + $notFoundIndicatorLeft, + $notFoundIndicatorRight, + $postCompilingEnabled = false, + $forceAsyncReloadEnabled = false, + $nestedObjectDelimeter = '.', + $isReady = false, + $keepContent = false, + loaderCache, + directivePriority = 0, + statefulFilter = true, + postProcessFn, + uniformLanguageTagResolver = 'default', + languageTagResolver = { + 'default' : function (tag) { + return (tag || '').split('-').join('_'); + }, + java : function (tag) { + var temp = (tag || '').split('-').join('_'); + var parts = temp.split('_'); + return parts.length > 1 ? (parts[0].toLowerCase() + '_' + parts[1].toUpperCase()) : temp; + }, + bcp47 : function (tag) { + var temp = (tag || '').split('_').join('-'); + var parts = temp.split('-'); + return parts.length > 1 ? (parts[0].toLowerCase() + '-' + parts[1].toUpperCase()) : temp; + }, + 'iso639-1' : function (tag) { + var temp = (tag || '').split('_').join('-'); + var parts = temp.split('-'); + return parts[0].toLowerCase(); + } + }; + + var version = '2.14.0'; + + // tries to determine the browsers language + var getFirstBrowserLanguage = function () { + + // internal purpose only + if (angular.isFunction(pascalprechtTranslateOverrider.getLocale)) { + return pascalprechtTranslateOverrider.getLocale(); + } + + var nav = $windowProvider.$get().navigator, + browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'], + i, + language; + + // support for HTML 5.1 "navigator.languages" + if (angular.isArray(nav.languages)) { + for (i = 0; i < nav.languages.length; i++) { + language = nav.languages[i]; + if (language && language.length) { + return language; + } + } + } + + // support for other well known properties in browsers + for (i = 0; i < browserLanguagePropertyKeys.length; i++) { + language = nav[browserLanguagePropertyKeys[i]]; + if (language && language.length) { + return language; + } + } + + return null; + }; + getFirstBrowserLanguage.displayName = 'angular-translate/service: getFirstBrowserLanguage'; + + // tries to determine the browsers locale + var getLocale = function () { + var locale = getFirstBrowserLanguage() || ''; + if (languageTagResolver[uniformLanguageTagResolver]) { + locale = languageTagResolver[uniformLanguageTagResolver](locale); + } + return locale; + }; + getLocale.displayName = 'angular-translate/service: getLocale'; + + /** + * @name indexOf + * @private + * + * @description + * indexOf polyfill. Kinda sorta. + * + * @param {array} array Array to search in. + * @param {string} searchElement Element to search for. + * + * @returns {int} Index of search element. + */ + var indexOf = function (array, searchElement) { + for (var i = 0, len = array.length; i < len; i++) { + if (array[i] === searchElement) { + return i; + } + } + return -1; + }; + + /** + * @name trim + * @private + * + * @description + * trim polyfill + * + * @returns {string} The string stripped of whitespace from both ends + */ + var trim = function () { + return this.toString().replace(/^\s+|\s+$/g, ''); + }; + + var negotiateLocale = function (preferred) { + if (!preferred) { + return; + } + + var avail = [], + locale = angular.lowercase(preferred), + i = 0, + n = $availableLanguageKeys.length; + + for (; i < n; i++) { + avail.push(angular.lowercase($availableLanguageKeys[i])); + } + + // Check for an exact match in our list of available keys + if (indexOf(avail, locale) > -1) { + return preferred; + } + + if ($languageKeyAliases) { + var alias; + for (var langKeyAlias in $languageKeyAliases) { + if ($languageKeyAliases.hasOwnProperty(langKeyAlias)) { + var hasWildcardKey = false; + var hasExactKey = Object.prototype.hasOwnProperty.call($languageKeyAliases, langKeyAlias) && + angular.lowercase(langKeyAlias) === angular.lowercase(preferred); + + if (langKeyAlias.slice(-1) === '*') { + hasWildcardKey = langKeyAlias.slice(0, -1) === preferred.slice(0, langKeyAlias.length - 1); + } + if (hasExactKey || hasWildcardKey) { + alias = $languageKeyAliases[langKeyAlias]; + if (indexOf(avail, angular.lowercase(alias)) > -1) { + return alias; + } + } + } + } + } + + // Check for a language code without region + var parts = preferred.split('_'); + + if (parts.length > 1 && indexOf(avail, angular.lowercase(parts[0])) > -1) { + return parts[0]; + } + + // If everything fails, return undefined. + return; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#translations + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Registers a new translation table for specific language key. + * + * To register a translation table for specific language, pass a defined language + * key as first parameter. + * + *
+   *  // register translation table for language: 'de_DE'
+   *  $translateProvider.translations('de_DE', {
+   *    'GREETING': 'Hallo Welt!'
+   *  });
+   *
+   *  // register another one
+   *  $translateProvider.translations('en_US', {
+   *    'GREETING': 'Hello world!'
+   *  });
+   * 
+ * + * When registering multiple translation tables for for the same language key, + * the actual translation table gets extended. This allows you to define module + * specific translation which only get added, once a specific module is loaded in + * your app. + * + * Invoking this method with no arguments returns the translation table which was + * registered with no language key. Invoking it with a language key returns the + * related translation table. + * + * @param {string} langKey A language key. + * @param {object} translationTable A plain old JavaScript object that represents a translation table. + * + */ + var translations = function (langKey, translationTable) { + + if (!langKey && !translationTable) { + return $translationTable; + } + + if (langKey && !translationTable) { + if (angular.isString(langKey)) { + return $translationTable[langKey]; + } + } else { + if (!angular.isObject($translationTable[langKey])) { + $translationTable[langKey] = {}; + } + angular.extend($translationTable[langKey], flatObject(translationTable)); + } + return this; + }; + + this.translations = translations; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#cloakClassName + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * + * Let's you change the class name for `translate-cloak` directive. + * Default class name is `translate-cloak`. + * + * @param {string} name translate-cloak class name + */ + this.cloakClassName = function (name) { + if (!name) { + return $cloakClassName; + } + $cloakClassName = name; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#nestedObjectDelimeter + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * + * Let's you change the delimiter for namespaced translations. + * Default delimiter is `.`. + * + * @param {string} delimiter namespace separator + */ + this.nestedObjectDelimeter = function (delimiter) { + if (!delimiter) { + return $nestedObjectDelimeter; + } + $nestedObjectDelimeter = delimiter; + return this; + }; + + /** + * @name flatObject + * @private + * + * @description + * Flats an object. This function is used to flatten given translation data with + * namespaces, so they are later accessible via dot notation. + */ + var flatObject = function (data, path, result, prevKey) { + var key, keyWithPath, keyWithShortPath, val; + + if (!path) { + path = []; + } + if (!result) { + result = {}; + } + for (key in data) { + if (!Object.prototype.hasOwnProperty.call(data, key)) { + continue; + } + val = data[key]; + if (angular.isObject(val)) { + flatObject(val, path.concat(key), result, key); + } else { + keyWithPath = path.length ? ('' + path.join($nestedObjectDelimeter) + $nestedObjectDelimeter + key) : key; + if (path.length && key === prevKey) { + // Create shortcut path (foo.bar == foo.bar.bar) + keyWithShortPath = '' + path.join($nestedObjectDelimeter); + // Link it to original path + result[keyWithShortPath] = '@:' + keyWithPath; + } + result[keyWithPath] = val; + } + } + return result; + }; + flatObject.displayName = 'flatObject'; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#addInterpolation + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Adds interpolation services to angular-translate, so it can manage them. + * + * @param {object} factory Interpolation service factory + */ + this.addInterpolation = function (factory) { + $interpolatorFactories.push(factory); + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useMessageFormatInterpolation + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use interpolation functionality of messageformat.js. + * This is useful when having high level pluralization and gender selection. + */ + this.useMessageFormatInterpolation = function () { + return this.useInterpolation('$translateMessageFormatInterpolation'); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useInterpolation + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate which interpolation style to use as default, application-wide. + * Simply pass a factory/service name. The interpolation service has to implement + * the correct interface. + * + * @param {string} factory Interpolation service name. + */ + this.useInterpolation = function (factory) { + $interpolationFactory = factory; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useSanitizeStrategy + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Simply sets a sanitation strategy type. + * + * @param {string} value Strategy type. + */ + this.useSanitizeValueStrategy = function (value) { + $translateSanitizationProvider.useStrategy(value); + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#preferredLanguage + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells the module which of the registered translation tables to use for translation + * at initial startup by passing a language key. Similar to `$translateProvider#use` + * only that it says which language to **prefer**. + * + * @param {string} langKey A language key. + */ + this.preferredLanguage = function (langKey) { + if (langKey) { + setupPreferredLanguage(langKey); + return this; + } + return $preferredLanguage; + }; + var setupPreferredLanguage = function (langKey) { + if (langKey) { + $preferredLanguage = langKey; + } + return $preferredLanguage; + }; + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#translationNotFoundIndicator + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Sets an indicator which is used when a translation isn't found. E.g. when + * setting the indicator as 'X' and one tries to translate a translation id + * called `NOT_FOUND`, this will result in `X NOT_FOUND X`. + * + * Internally this methods sets a left indicator and a right indicator using + * `$translateProvider.translationNotFoundIndicatorLeft()` and + * `$translateProvider.translationNotFoundIndicatorRight()`. + * + * **Note**: These methods automatically add a whitespace between the indicators + * and the translation id. + * + * @param {string} indicator An indicator, could be any string. + */ + this.translationNotFoundIndicator = function (indicator) { + this.translationNotFoundIndicatorLeft(indicator); + this.translationNotFoundIndicatorRight(indicator); + return this; + }; + + /** + * ngdoc function + * @name pascalprecht.translate.$translateProvider#translationNotFoundIndicatorLeft + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Sets an indicator which is used when a translation isn't found left to the + * translation id. + * + * @param {string} indicator An indicator. + */ + this.translationNotFoundIndicatorLeft = function (indicator) { + if (!indicator) { + return $notFoundIndicatorLeft; + } + $notFoundIndicatorLeft = indicator; + return this; + }; + + /** + * ngdoc function + * @name pascalprecht.translate.$translateProvider#translationNotFoundIndicatorLeft + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Sets an indicator which is used when a translation isn't found right to the + * translation id. + * + * @param {string} indicator An indicator. + */ + this.translationNotFoundIndicatorRight = function (indicator) { + if (!indicator) { + return $notFoundIndicatorRight; + } + $notFoundIndicatorRight = indicator; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#fallbackLanguage + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells the module which of the registered translation tables to use when missing translations + * at initial startup by passing a language key. Similar to `$translateProvider#use` + * only that it says which language to **fallback**. + * + * @param {string||array} langKey A language key. + * + */ + this.fallbackLanguage = function (langKey) { + fallbackStack(langKey); + return this; + }; + + var fallbackStack = function (langKey) { + if (langKey) { + if (angular.isString(langKey)) { + $fallbackWasString = true; + $fallbackLanguage = [langKey]; + } else if (angular.isArray(langKey)) { + $fallbackWasString = false; + $fallbackLanguage = langKey; + } + if (angular.isString($preferredLanguage) && indexOf($fallbackLanguage, $preferredLanguage) < 0) { + $fallbackLanguage.push($preferredLanguage); + } + + return this; + } else { + if ($fallbackWasString) { + return $fallbackLanguage[0]; + } else { + return $fallbackLanguage; + } + } + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#use + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Set which translation table to use for translation by given language key. When + * trying to 'use' a language which isn't provided, it'll throw an error. + * + * You actually don't have to use this method since `$translateProvider#preferredLanguage` + * does the job too. + * + * @param {string} langKey A language key. + */ + this.use = function (langKey) { + if (langKey) { + if (!$translationTable[langKey] && (!$loaderFactory)) { + // only throw an error, when not loading translation data asynchronously + throw new Error('$translateProvider couldn\'t find translationTable for langKey: \'' + langKey + '\''); + } + $uses = langKey; + return this; + } + return $uses; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#resolveClientLocale + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * This returns the current browser/client's language key. The result is processed with the configured uniform tag resolver. + * + * @returns {string} the current client/browser language key + */ + this.resolveClientLocale = function () { + return getLocale(); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#storageKey + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells the module which key must represent the choosed language by a user in the storage. + * + * @param {string} key A key for the storage. + */ + var storageKey = function (key) { + if (!key) { + if ($storagePrefix) { + return $storagePrefix + $storageKey; + } + return $storageKey; + } + $storageKey = key; + return this; + }; + + this.storageKey = storageKey; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useUrlLoader + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use `$translateUrlLoader` extension service as loader. + * + * @param {string} url Url + * @param {Object=} options Optional configuration object + */ + this.useUrlLoader = function (url, options) { + return this.useLoader('$translateUrlLoader', angular.extend({url : url}, options)); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useStaticFilesLoader + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use `$translateStaticFilesLoader` extension service as loader. + * + * @param {Object=} options Optional configuration object + */ + this.useStaticFilesLoader = function (options) { + return this.useLoader('$translateStaticFilesLoader', options); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useLoader + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use any other service as loader. + * + * @param {string} loaderFactory Factory name to use + * @param {Object=} options Optional configuration object + */ + this.useLoader = function (loaderFactory, options) { + $loaderFactory = loaderFactory; + $loaderOptions = options || {}; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useLocalStorage + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use `$translateLocalStorage` service as storage layer. + * + */ + this.useLocalStorage = function () { + return this.useStorage('$translateLocalStorage'); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useCookieStorage + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use `$translateCookieStorage` service as storage layer. + */ + this.useCookieStorage = function () { + return this.useStorage('$translateCookieStorage'); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useStorage + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use custom service as storage layer. + */ + this.useStorage = function (storageFactory) { + $storageFactory = storageFactory; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#storagePrefix + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Sets prefix for storage key. + * + * @param {string} prefix Storage key prefix + */ + this.storagePrefix = function (prefix) { + if (!prefix) { + return prefix; + } + $storagePrefix = prefix; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useMissingTranslationHandlerLog + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to use built-in log handler when trying to translate + * a translation Id which doesn't exist. + * + * This is actually a shortcut method for `useMissingTranslationHandler()`. + * + */ + this.useMissingTranslationHandlerLog = function () { + return this.useMissingTranslationHandler('$translateMissingTranslationHandlerLog'); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useMissingTranslationHandler + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Expects a factory name which later gets instantiated with `$injector`. + * This method can be used to tell angular-translate to use a custom + * missingTranslationHandler. Just build a factory which returns a function + * and expects a translation id as argument. + * + * Example: + *
+   *  app.config(function ($translateProvider) {
+   *    $translateProvider.useMissingTranslationHandler('customHandler');
+   *  });
+   *
+   *  app.factory('customHandler', function (dep1, dep2) {
+   *    return function (translationId) {
+   *      // something with translationId and dep1 and dep2
+   *    };
+   *  });
+   * 
+ * + * @param {string} factory Factory name + */ + this.useMissingTranslationHandler = function (factory) { + $missingTranslationHandlerFactory = factory; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#usePostCompiling + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * If post compiling is enabled, all translated values will be processed + * again with AngularJS' $compile. + * + * Example: + *
+   *  app.config(function ($translateProvider) {
+   *    $translateProvider.usePostCompiling(true);
+   *  });
+   * 
+ * + * @param {string} factory Factory name + */ + this.usePostCompiling = function (value) { + $postCompilingEnabled = !(!value); + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#forceAsyncReload + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * If force async reload is enabled, async loader will always be called + * even if $translationTable already contains the language key, adding + * possible new entries to the $translationTable. + * + * Example: + *
+   *  app.config(function ($translateProvider) {
+   *    $translateProvider.forceAsyncReload(true);
+   *  });
+   * 
+ * + * @param {boolean} value - valid values are true or false + */ + this.forceAsyncReload = function (value) { + $forceAsyncReloadEnabled = !(!value); + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#uniformLanguageTag + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate which language tag should be used as a result when determining + * the current browser language. + * + * This setting must be set before invoking {@link pascalprecht.translate.$translateProvider#methods_determinePreferredLanguage determinePreferredLanguage()}. + * + *
+   * $translateProvider
+   *   .uniformLanguageTag('bcp47')
+   *   .determinePreferredLanguage()
+   * 
+ * + * The resolver currently supports: + * * default + * (traditionally: hyphens will be converted into underscores, i.e. en-US => en_US) + * en-US => en_US + * en_US => en_US + * en-us => en_us + * * java + * like default, but the second part will be always in uppercase + * en-US => en_US + * en_US => en_US + * en-us => en_US + * * BCP 47 (RFC 4646 & 4647) + * en-US => en-US + * en_US => en-US + * en-us => en-US + * + * See also: + * * http://en.wikipedia.org/wiki/IETF_language_tag + * * http://www.w3.org/International/core/langtags/ + * * http://tools.ietf.org/html/bcp47 + * + * @param {string|object} options - options (or standard) + * @param {string} options.standard - valid values are 'default', 'bcp47', 'java' + */ + this.uniformLanguageTag = function (options) { + + if (!options) { + options = {}; + } else if (angular.isString(options)) { + options = { + standard : options + }; + } + + uniformLanguageTagResolver = options.standard; + + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#determinePreferredLanguage + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate to try to determine on its own which language key + * to set as preferred language. When `fn` is given, angular-translate uses it + * to determine a language key, otherwise it uses the built-in `getLocale()` + * method. + * + * The `getLocale()` returns a language key in the format `[lang]_[country]` or + * `[lang]` depending on what the browser provides. + * + * Use this method at your own risk, since not all browsers return a valid + * locale (see {@link pascalprecht.translate.$translateProvider#methods_uniformLanguageTag uniformLanguageTag()}). + * + * @param {Function=} fn Function to determine a browser's locale + */ + this.determinePreferredLanguage = function (fn) { + + var locale = (fn && angular.isFunction(fn)) ? fn() : getLocale(); + + if (!$availableLanguageKeys.length) { + $preferredLanguage = locale; + } else { + $preferredLanguage = negotiateLocale(locale) || locale; + } + + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#registerAvailableLanguageKeys + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Registers a set of language keys the app will work with. Use this method in + * combination with + * {@link pascalprecht.translate.$translateProvider#determinePreferredLanguage determinePreferredLanguage}. + * When available languages keys are registered, angular-translate + * tries to find the best fitting language key depending on the browsers locale, + * considering your language key convention. + * + * @param {object} languageKeys Array of language keys the your app will use + * @param {object=} aliases Alias map. + */ + this.registerAvailableLanguageKeys = function (languageKeys, aliases) { + if (languageKeys) { + $availableLanguageKeys = languageKeys; + if (aliases) { + $languageKeyAliases = aliases; + } + return this; + } + return $availableLanguageKeys; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#useLoaderCache + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Registers a cache for internal $http based loaders. + * {@link pascalprecht.translate.$translationCache $translationCache}. + * When false the cache will be disabled (default). When true or undefined + * the cache will be a default (see $cacheFactory). When an object it will + * be treat as a cache object itself: the usage is $http({cache: cache}) + * + * @param {object} cache boolean, string or cache-object + */ + this.useLoaderCache = function (cache) { + if (cache === false) { + // disable cache + loaderCache = undefined; + } else if (cache === true) { + // enable cache using AJS defaults + loaderCache = true; + } else if (typeof(cache) === 'undefined') { + // enable cache using default + loaderCache = '$translationCache'; + } else if (cache) { + // enable cache using given one (see $cacheFactory) + loaderCache = cache; + } + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#directivePriority + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Sets the default priority of the translate directive. The standard value is `0`. + * Calling this function without an argument will return the current value. + * + * @param {number} priority for the translate-directive + */ + this.directivePriority = function (priority) { + if (priority === undefined) { + // getter + return directivePriority; + } else { + // setter with chaining + directivePriority = priority; + return this; + } + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#statefulFilter + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Since AngularJS 1.3, filters which are not stateless (depending at the scope) + * have to explicit define this behavior. + * Sets whether the translate filter should be stateful or stateless. The standard value is `true` + * meaning being stateful. + * Calling this function without an argument will return the current value. + * + * @param {boolean} state - defines the state of the filter + */ + this.statefulFilter = function (state) { + if (state === undefined) { + // getter + return statefulFilter; + } else { + // setter with chaining + statefulFilter = state; + return this; + } + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#postProcess + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * The post processor will be intercept right after the translation result. It can modify the result. + * + * @param {object} fn Function or service name (string) to be called after the translation value has been set / resolved. The function itself will enrich every value being processed and then continue the normal resolver process + */ + this.postProcess = function (fn) { + if (fn) { + postProcessFn = fn; + } else { + postProcessFn = undefined; + } + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#keepContent + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * If keepContent is set to true than translate directive will always use innerHTML + * as a default translation + * + * Example: + *
+   *  app.config(function ($translateProvider) {
+   *    $translateProvider.keepContent(true);
+   *  });
+   * 
+ * + * @param {boolean} value - valid values are true or false + */ + this.keepContent = function (value) { + $keepContent = !(!value); + return this; + }; + + /** + * @ngdoc object + * @name pascalprecht.translate.$translate + * @requires $interpolate + * @requires $log + * @requires $rootScope + * @requires $q + * + * @description + * The `$translate` service is the actual core of angular-translate. It expects a translation id + * and optional interpolate parameters to translate contents. + * + *
+   *  $translate('HEADLINE_TEXT').then(function (translation) {
+   *    $scope.translatedText = translation;
+   *  });
+   * 
+ * + * @param {string|array} translationId A token which represents a translation id + * This can be optionally an array of translation ids which + * results that the function returns an object where each key + * is the translation id and the value the translation. + * @param {object=} interpolateParams An object hash for dynamic values + * @param {string} interpolationId The id of the interpolation to use + * @param {string} defaultTranslationText the optional default translation text that is written as + * as default text in case it is not found in any configured language + * @param {string} forceLanguage A language to be used instead of the current language + * @returns {object} promise + */ + this.$get = ['$log', '$injector', '$rootScope', '$q', function ($log, $injector, $rootScope, $q) { + + var Storage, + defaultInterpolator = $injector.get($interpolationFactory || '$translateDefaultInterpolation'), + pendingLoader = false, + interpolatorHashMap = {}, + langPromises = {}, + fallbackIndex, + startFallbackIteration; + + var $translate = function (translationId, interpolateParams, interpolationId, defaultTranslationText, forceLanguage) { + if (!$uses && $preferredLanguage) { + $uses = $preferredLanguage; + } + var uses = (forceLanguage && forceLanguage !== $uses) ? // we don't want to re-negotiate $uses + (negotiateLocale(forceLanguage) || forceLanguage) : $uses; + + // Check forceLanguage is present + if (forceLanguage) { + loadTranslationsIfMissing(forceLanguage); + } + + // Duck detection: If the first argument is an array, a bunch of translations was requested. + // The result is an object. + if (angular.isArray(translationId)) { + // Inspired by Q.allSettled by Kris Kowal + // https://github.com/kriskowal/q/blob/b0fa72980717dc202ffc3cbf03b936e10ebbb9d7/q.js#L1553-1563 + // This transforms all promises regardless resolved or rejected + var translateAll = function (translationIds) { + var results = {}; // storing the actual results + var promises = []; // promises to wait for + // Wraps the promise a) being always resolved and b) storing the link id->value + var translate = function (translationId) { + var deferred = $q.defer(); + var regardless = function (value) { + results[translationId] = value; + deferred.resolve([translationId, value]); + }; + // we don't care whether the promise was resolved or rejected; just store the values + $translate(translationId, interpolateParams, interpolationId, defaultTranslationText, forceLanguage).then(regardless, regardless); + return deferred.promise; + }; + for (var i = 0, c = translationIds.length; i < c; i++) { + promises.push(translate(translationIds[i])); + } + // wait for all (including storing to results) + return $q.all(promises).then(function () { + // return the results + return results; + }); + }; + return translateAll(translationId); + } + + var deferred = $q.defer(); + + // trim off any whitespace + if (translationId) { + translationId = trim.apply(translationId); + } + + var promiseToWaitFor = (function () { + var promise = $preferredLanguage ? + langPromises[$preferredLanguage] : + langPromises[uses]; + + fallbackIndex = 0; + + if ($storageFactory && !promise) { + // looks like there's no pending promise for $preferredLanguage or + // $uses. Maybe there's one pending for a language that comes from + // storage. + var langKey = Storage.get($storageKey); + promise = langPromises[langKey]; + + if ($fallbackLanguage && $fallbackLanguage.length) { + var index = indexOf($fallbackLanguage, langKey); + // maybe the language from storage is also defined as fallback language + // we increase the fallback language index to not search in that language + // as fallback, since it's probably the first used language + // in that case the index starts after the first element + fallbackIndex = (index === 0) ? 1 : 0; + + // but we can make sure to ALWAYS fallback to preferred language at least + if (indexOf($fallbackLanguage, $preferredLanguage) < 0) { + $fallbackLanguage.push($preferredLanguage); + } + } + } + return promise; + }()); + + if (!promiseToWaitFor) { + // no promise to wait for? okay. Then there's no loader registered + // nor is a one pending for language that comes from storage. + // We can just translate. + determineTranslation(translationId, interpolateParams, interpolationId, defaultTranslationText, uses).then(deferred.resolve, deferred.reject); + } else { + var promiseResolved = function () { + // $uses may have changed while waiting + if (!forceLanguage) { + uses = $uses; + } + determineTranslation(translationId, interpolateParams, interpolationId, defaultTranslationText, uses).then(deferred.resolve, deferred.reject); + }; + promiseResolved.displayName = 'promiseResolved'; + + promiseToWaitFor['finally'](promiseResolved) + .catch(angular.noop); // we don't care about errors here, already handled + } + return deferred.promise; + }; + + /** + * @name applyNotFoundIndicators + * @private + * + * @description + * Applies not fount indicators to given translation id, if needed. + * This function gets only executed, if a translation id doesn't exist, + * which is why a translation id is expected as argument. + * + * @param {string} translationId Translation id. + * @returns {string} Same as given translation id but applied with not found + * indicators. + */ + var applyNotFoundIndicators = function (translationId) { + // applying notFoundIndicators + if ($notFoundIndicatorLeft) { + translationId = [$notFoundIndicatorLeft, translationId].join(' '); + } + if ($notFoundIndicatorRight) { + translationId = [translationId, $notFoundIndicatorRight].join(' '); + } + return translationId; + }; + + /** + * @name useLanguage + * @private + * + * @description + * Makes actual use of a language by setting a given language key as used + * language and informs registered interpolators to also use the given + * key as locale. + * + * @param {string} key Locale key. + */ + var useLanguage = function (key) { + $uses = key; + + // make sure to store new language key before triggering success event + if ($storageFactory) { + Storage.put($translate.storageKey(), $uses); + } + + $rootScope.$emit('$translateChangeSuccess', {language : key}); + + // inform default interpolator + defaultInterpolator.setLocale($uses); + + var eachInterpolator = function (interpolator, id) { + interpolatorHashMap[id].setLocale($uses); + }; + eachInterpolator.displayName = 'eachInterpolatorLocaleSetter'; + + // inform all others too! + angular.forEach(interpolatorHashMap, eachInterpolator); + $rootScope.$emit('$translateChangeEnd', {language : key}); + }; + + /** + * @name loadAsync + * @private + * + * @description + * Kicks off registered async loader using `$injector` and applies existing + * loader options. When resolved, it updates translation tables accordingly + * or rejects with given language key. + * + * @param {string} key Language key. + * @return {Promise} A promise. + */ + var loadAsync = function (key) { + if (!key) { + throw 'No language key specified for loading.'; + } + + var deferred = $q.defer(); + + $rootScope.$emit('$translateLoadingStart', {language : key}); + pendingLoader = true; + + var cache = loaderCache; + if (typeof(cache) === 'string') { + // getting on-demand instance of loader + cache = $injector.get(cache); + } + + var loaderOptions = angular.extend({}, $loaderOptions, { + key : key, + $http : angular.extend({}, { + cache : cache + }, $loaderOptions.$http) + }); + + var onLoaderSuccess = function (data) { + var translationTable = {}; + $rootScope.$emit('$translateLoadingSuccess', {language : key}); + + if (angular.isArray(data)) { + angular.forEach(data, function (table) { + angular.extend(translationTable, flatObject(table)); + }); + } else { + angular.extend(translationTable, flatObject(data)); + } + pendingLoader = false; + deferred.resolve({ + key : key, + table : translationTable + }); + $rootScope.$emit('$translateLoadingEnd', {language : key}); + }; + onLoaderSuccess.displayName = 'onLoaderSuccess'; + + var onLoaderError = function (key) { + $rootScope.$emit('$translateLoadingError', {language : key}); + deferred.reject(key); + $rootScope.$emit('$translateLoadingEnd', {language : key}); + }; + onLoaderError.displayName = 'onLoaderError'; + + $injector.get($loaderFactory)(loaderOptions) + .then(onLoaderSuccess, onLoaderError); + + return deferred.promise; + }; + + if ($storageFactory) { + Storage = $injector.get($storageFactory); + + if (!Storage.get || !Storage.put) { + throw new Error('Couldn\'t use storage \'' + $storageFactory + '\', missing get() or put() method!'); + } + } + + // if we have additional interpolations that were added via + // $translateProvider.addInterpolation(), we have to map'em + if ($interpolatorFactories.length) { + var eachInterpolationFactory = function (interpolatorFactory) { + var interpolator = $injector.get(interpolatorFactory); + // setting initial locale for each interpolation service + interpolator.setLocale($preferredLanguage || $uses); + // make'em recognizable through id + interpolatorHashMap[interpolator.getInterpolationIdentifier()] = interpolator; + }; + eachInterpolationFactory.displayName = 'interpolationFactoryAdder'; + + angular.forEach($interpolatorFactories, eachInterpolationFactory); + } + + /** + * @name getTranslationTable + * @private + * + * @description + * Returns a promise that resolves to the translation table + * or is rejected if an error occurred. + * + * @param langKey + * @returns {Q.promise} + */ + var getTranslationTable = function (langKey) { + var deferred = $q.defer(); + if (Object.prototype.hasOwnProperty.call($translationTable, langKey)) { + deferred.resolve($translationTable[langKey]); + } else if (langPromises[langKey]) { + var onResolve = function (data) { + translations(data.key, data.table); + deferred.resolve(data.table); + }; + onResolve.displayName = 'translationTableResolver'; + langPromises[langKey].then(onResolve, deferred.reject); + } else { + deferred.reject(); + } + return deferred.promise; + }; + + /** + * @name getFallbackTranslation + * @private + * + * @description + * Returns a promise that will resolve to the translation + * or be rejected if no translation was found for the language. + * This function is currently only used for fallback language translation. + * + * @param langKey The language to translate to. + * @param translationId + * @param interpolateParams + * @param Interpolator + * @param sanitizeStrategy + * @returns {Q.promise} + */ + var getFallbackTranslation = function (langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy) { + var deferred = $q.defer(); + + var onResolve = function (translationTable) { + if (Object.prototype.hasOwnProperty.call(translationTable, translationId) && translationTable[translationId] !== null) { + Interpolator.setLocale(langKey); + var translation = translationTable[translationId]; + if (translation.substr(0, 2) === '@:') { + getFallbackTranslation(langKey, translation.substr(2), interpolateParams, Interpolator, sanitizeStrategy) + .then(deferred.resolve, deferred.reject); + } else { + var interpolatedValue = Interpolator.interpolate(translationTable[translationId], interpolateParams, 'service', sanitizeStrategy, translationId); + interpolatedValue = applyPostProcessing(translationId, translationTable[translationId], interpolatedValue, interpolateParams, langKey); + + deferred.resolve(interpolatedValue); + + } + Interpolator.setLocale($uses); + } else { + deferred.reject(); + } + }; + onResolve.displayName = 'fallbackTranslationResolver'; + + getTranslationTable(langKey).then(onResolve, deferred.reject); + + return deferred.promise; + }; + + /** + * @name getFallbackTranslationInstant + * @private + * + * @description + * Returns a translation + * This function is currently only used for fallback language translation. + * + * @param langKey The language to translate to. + * @param translationId + * @param interpolateParams + * @param Interpolator + * @param sanitizeStrategy sanitize strategy override + * + * @returns {string} translation + */ + var getFallbackTranslationInstant = function (langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy) { + var result, translationTable = $translationTable[langKey]; + + if (translationTable && Object.prototype.hasOwnProperty.call(translationTable, translationId) && translationTable[translationId] !== null) { + Interpolator.setLocale(langKey); + result = Interpolator.interpolate(translationTable[translationId], interpolateParams, 'filter', sanitizeStrategy, translationId); + result = applyPostProcessing(translationId, translationTable[translationId], result, interpolateParams, langKey, sanitizeStrategy); + // workaround for TrustedValueHolderType + if (!angular.isString(result) && angular.isFunction(result.$$unwrapTrustedValue)) { + var result2 = result.$$unwrapTrustedValue(); + if (result2.substr(0, 2) === '@:') { + return getFallbackTranslationInstant(langKey, result2.substr(2), interpolateParams, Interpolator, sanitizeStrategy); + } + } else if (result.substr(0, 2) === '@:') { + return getFallbackTranslationInstant(langKey, result.substr(2), interpolateParams, Interpolator, sanitizeStrategy); + } + Interpolator.setLocale($uses); + } + + return result; + }; + + + /** + * @name translateByHandler + * @private + * + * Translate by missing translation handler. + * + * @param translationId + * @param interpolateParams + * @param defaultTranslationText + * @param sanitizeStrategy sanitize strategy override + * + * @returns translation created by $missingTranslationHandler or translationId is $missingTranslationHandler is + * absent + */ + var translateByHandler = function (translationId, interpolateParams, defaultTranslationText, sanitizeStrategy) { + // If we have a handler factory - we might also call it here to determine if it provides + // a default text for a translationid that can't be found anywhere in our tables + if ($missingTranslationHandlerFactory) { + return $injector.get($missingTranslationHandlerFactory)(translationId, $uses, interpolateParams, defaultTranslationText, sanitizeStrategy); + } else { + return translationId; + } + }; + + /** + * @name resolveForFallbackLanguage + * @private + * + * Recursive helper function for fallbackTranslation that will sequentially look + * for a translation in the fallbackLanguages starting with fallbackLanguageIndex. + * + * @param fallbackLanguageIndex + * @param translationId + * @param interpolateParams + * @param Interpolator + * @param defaultTranslationText + * @param sanitizeStrategy + * @returns {Q.promise} Promise that will resolve to the translation. + */ + var resolveForFallbackLanguage = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy) { + var deferred = $q.defer(); + + if (fallbackLanguageIndex < $fallbackLanguage.length) { + var langKey = $fallbackLanguage[fallbackLanguageIndex]; + getFallbackTranslation(langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy).then( + function (data) { + deferred.resolve(data); + }, + function () { + // Look in the next fallback language for a translation. + // It delays the resolving by passing another promise to resolve. + return resolveForFallbackLanguage(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy).then(deferred.resolve, deferred.reject); + } + ); + } else { + // No translation found in any fallback language + // if a default translation text is set in the directive, then return this as a result + if (defaultTranslationText) { + deferred.resolve(defaultTranslationText); + } else { + var missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, defaultTranslationText); + + // if no default translation is set and an error handler is defined, send it to the handler + // and then return the result if it isn't undefined + if ($missingTranslationHandlerFactory && missingTranslationHandlerTranslation) { + deferred.resolve(missingTranslationHandlerTranslation); + } else { + deferred.reject(applyNotFoundIndicators(translationId)); + } + } + } + return deferred.promise; + }; + + /** + * @name resolveForFallbackLanguageInstant + * @private + * + * Recursive helper function for fallbackTranslation that will sequentially look + * for a translation in the fallbackLanguages starting with fallbackLanguageIndex. + * + * @param fallbackLanguageIndex + * @param translationId + * @param interpolateParams + * @param Interpolator + * @param sanitizeStrategy + * @returns {string} translation + */ + var resolveForFallbackLanguageInstant = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator, sanitizeStrategy) { + var result; + + if (fallbackLanguageIndex < $fallbackLanguage.length) { + var langKey = $fallbackLanguage[fallbackLanguageIndex]; + result = getFallbackTranslationInstant(langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy); + if (!result && result !== '') { + result = resolveForFallbackLanguageInstant(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator); + } + } + return result; + }; + + /** + * Translates with the usage of the fallback languages. + * + * @param translationId + * @param interpolateParams + * @param Interpolator + * @param defaultTranslationText + * @param sanitizeStrategy + * @returns {Q.promise} Promise, that resolves to the translation. + */ + var fallbackTranslation = function (translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy) { + // Start with the fallbackLanguage with index 0 + return resolveForFallbackLanguage((startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex), translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy); + }; + + /** + * Translates with the usage of the fallback languages. + * + * @param translationId + * @param interpolateParams + * @param Interpolator + * @param sanitizeStrategy + * @returns {String} translation + */ + var fallbackTranslationInstant = function (translationId, interpolateParams, Interpolator, sanitizeStrategy) { + // Start with the fallbackLanguage with index 0 + return resolveForFallbackLanguageInstant((startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex), translationId, interpolateParams, Interpolator, sanitizeStrategy); + }; + + var determineTranslation = function (translationId, interpolateParams, interpolationId, defaultTranslationText, uses, sanitizeStrategy) { + + var deferred = $q.defer(); + + var table = uses ? $translationTable[uses] : $translationTable, + Interpolator = (interpolationId) ? interpolatorHashMap[interpolationId] : defaultInterpolator; + + // if the translation id exists, we can just interpolate it + if (table && Object.prototype.hasOwnProperty.call(table, translationId) && table[translationId] !== null) { + var translation = table[translationId]; + + // If using link, rerun $translate with linked translationId and return it + if (translation.substr(0, 2) === '@:') { + + $translate(translation.substr(2), interpolateParams, interpolationId, defaultTranslationText, uses) + .then(deferred.resolve, deferred.reject); + } else { + // + var resolvedTranslation = Interpolator.interpolate(translation, interpolateParams, 'service', sanitizeStrategy, translationId); + resolvedTranslation = applyPostProcessing(translationId, translation, resolvedTranslation, interpolateParams, uses); + deferred.resolve(resolvedTranslation); + } + } else { + var missingTranslationHandlerTranslation; + // for logging purposes only (as in $translateMissingTranslationHandlerLog), value is not returned to promise + if ($missingTranslationHandlerFactory && !pendingLoader) { + missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, defaultTranslationText); + } + + // since we couldn't translate the inital requested translation id, + // we try it now with one or more fallback languages, if fallback language(s) is + // configured. + if (uses && $fallbackLanguage && $fallbackLanguage.length) { + fallbackTranslation(translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy) + .then(function (translation) { + deferred.resolve(translation); + }, function (_translationId) { + deferred.reject(applyNotFoundIndicators(_translationId)); + }); + } else if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { + // looks like the requested translation id doesn't exists. + // Now, if there is a registered handler for missing translations and no + // asyncLoader is pending, we execute the handler + if (defaultTranslationText) { + deferred.resolve(defaultTranslationText); + } else { + deferred.resolve(missingTranslationHandlerTranslation); + } + } else { + if (defaultTranslationText) { + deferred.resolve(defaultTranslationText); + } else { + deferred.reject(applyNotFoundIndicators(translationId)); + } + } + } + return deferred.promise; + }; + + var determineTranslationInstant = function (translationId, interpolateParams, interpolationId, uses, sanitizeStrategy) { + + var result, table = uses ? $translationTable[uses] : $translationTable, + Interpolator = defaultInterpolator; + + // if the interpolation id exists use custom interpolator + if (interpolatorHashMap && Object.prototype.hasOwnProperty.call(interpolatorHashMap, interpolationId)) { + Interpolator = interpolatorHashMap[interpolationId]; + } + + // if the translation id exists, we can just interpolate it + if (table && Object.prototype.hasOwnProperty.call(table, translationId) && table[translationId] !== null) { + var translation = table[translationId]; + + // If using link, rerun $translate with linked translationId and return it + if (translation.substr(0, 2) === '@:') { + result = determineTranslationInstant(translation.substr(2), interpolateParams, interpolationId, uses, sanitizeStrategy); + } else { + result = Interpolator.interpolate(translation, interpolateParams, 'filter', sanitizeStrategy, translationId); + result = applyPostProcessing(translationId, translation, result, interpolateParams, uses, sanitizeStrategy); + } + } else { + var missingTranslationHandlerTranslation; + // for logging purposes only (as in $translateMissingTranslationHandlerLog), value is not returned to promise + if ($missingTranslationHandlerFactory && !pendingLoader) { + missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, sanitizeStrategy); + } + + // since we couldn't translate the inital requested translation id, + // we try it now with one or more fallback languages, if fallback language(s) is + // configured. + if (uses && $fallbackLanguage && $fallbackLanguage.length) { + fallbackIndex = 0; + result = fallbackTranslationInstant(translationId, interpolateParams, Interpolator, sanitizeStrategy); + } else if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { + // looks like the requested translation id doesn't exists. + // Now, if there is a registered handler for missing translations and no + // asyncLoader is pending, we execute the handler + result = missingTranslationHandlerTranslation; + } else { + result = applyNotFoundIndicators(translationId); + } + } + + return result; + }; + + var clearNextLangAndPromise = function (key) { + if ($nextLang === key) { + $nextLang = undefined; + } + langPromises[key] = undefined; + }; + + var applyPostProcessing = function (translationId, translation, resolvedTranslation, interpolateParams, uses, sanitizeStrategy) { + var fn = postProcessFn; + + if (fn) { + + if (typeof(fn) === 'string') { + // getting on-demand instance + fn = $injector.get(fn); + } + if (fn) { + return fn(translationId, translation, resolvedTranslation, interpolateParams, uses, sanitizeStrategy); + } + } + + return resolvedTranslation; + }; + + var loadTranslationsIfMissing = function (key) { + if (!$translationTable[key] && $loaderFactory && !langPromises[key]) { + langPromises[key] = loadAsync(key).then(function (translation) { + translations(translation.key, translation.table); + return translation; + }); + } + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#preferredLanguage + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the language key for the preferred language. + * + * @param {string} langKey language String or Array to be used as preferredLanguage (changing at runtime) + * + * @return {string} preferred language key + */ + $translate.preferredLanguage = function (langKey) { + if (langKey) { + setupPreferredLanguage(langKey); + } + return $preferredLanguage; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#cloakClassName + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the configured class name for `translate-cloak` directive. + * + * @return {string} cloakClassName + */ + $translate.cloakClassName = function () { + return $cloakClassName; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#nestedObjectDelimeter + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the configured delimiter for nested namespaces. + * + * @return {string} nestedObjectDelimeter + */ + $translate.nestedObjectDelimeter = function () { + return $nestedObjectDelimeter; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#fallbackLanguage + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the language key for the fallback languages or sets a new fallback stack. + * + * @param {string=} langKey language String or Array of fallback languages to be used (to change stack at runtime) + * + * @return {string||array} fallback language key + */ + $translate.fallbackLanguage = function (langKey) { + if (langKey !== undefined && langKey !== null) { + fallbackStack(langKey); + + // as we might have an async loader initiated and a new translation language might have been defined + // we need to add the promise to the stack also. So - iterate. + if ($loaderFactory) { + if ($fallbackLanguage && $fallbackLanguage.length) { + for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { + if (!langPromises[$fallbackLanguage[i]]) { + langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]); + } + } + } + } + $translate.use($translate.use()); + } + if ($fallbackWasString) { + return $fallbackLanguage[0]; + } else { + return $fallbackLanguage; + } + + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#useFallbackLanguage + * @methodOf pascalprecht.translate.$translate + * + * @description + * Sets the first key of the fallback language stack to be used for translation. + * Therefore all languages in the fallback array BEFORE this key will be skipped! + * + * @param {string=} langKey Contains the langKey the iteration shall start with. Set to false if you want to + * get back to the whole stack + */ + $translate.useFallbackLanguage = function (langKey) { + if (langKey !== undefined && langKey !== null) { + if (!langKey) { + startFallbackIteration = 0; + } else { + var langKeyPosition = indexOf($fallbackLanguage, langKey); + if (langKeyPosition > -1) { + startFallbackIteration = langKeyPosition; + } + } + + } + + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#proposedLanguage + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the language key of language that is currently loaded asynchronously. + * + * @return {string} language key + */ + $translate.proposedLanguage = function () { + return $nextLang; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#storage + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns registered storage. + * + * @return {object} Storage + */ + $translate.storage = function () { + return Storage; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#negotiateLocale + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns a language key based on available languages and language aliases. If a + * language key cannot be resolved, returns undefined. + * + * If no or a falsy key is given, returns undefined. + * + * @param {string} [key] Language key + * @return {string|undefined} Language key or undefined if no language key is found. + */ + $translate.negotiateLocale = negotiateLocale; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#use + * @methodOf pascalprecht.translate.$translate + * + * @description + * Tells angular-translate which language to use by given language key. This method is + * used to change language at runtime. It also takes care of storing the language + * key in a configured store to let your app remember the choosed language. + * + * When trying to 'use' a language which isn't available it tries to load it + * asynchronously with registered loaders. + * + * Returns promise object with loaded language file data or string of the currently used language. + * + * If no or a falsy key is given it returns the currently used language key. + * The returned string will be ```undefined``` if setting up $translate hasn't finished. + * @example + * $translate.use("en_US").then(function(data){ + * $scope.text = $translate("HELLO"); + * }); + * + * @param {string} [key] Language key + * @return {object|string} Promise with loaded language data or the language key if a falsy param was given. + */ + $translate.use = function (key) { + if (!key) { + return $uses; + } + + var deferred = $q.defer(); + deferred.promise.then(null, angular.noop); // AJS "Possibly unhandled rejection" + + $rootScope.$emit('$translateChangeStart', {language : key}); + + // Try to get the aliased language key + var aliasedKey = negotiateLocale(key); + // Ensure only registered language keys will be loaded + if ($availableLanguageKeys.length > 0 && !aliasedKey) { + return $q.reject(key); + } + + if (aliasedKey) { + key = aliasedKey; + } + + // if there isn't a translation table for the language we've requested, + // we load it asynchronously + $nextLang = key; + if (($forceAsyncReloadEnabled || !$translationTable[key]) && $loaderFactory && !langPromises[key]) { + langPromises[key] = loadAsync(key).then(function (translation) { + translations(translation.key, translation.table); + deferred.resolve(translation.key); + if ($nextLang === key) { + useLanguage(translation.key); + } + return translation; + }, function (key) { + $rootScope.$emit('$translateChangeError', {language : key}); + deferred.reject(key); + $rootScope.$emit('$translateChangeEnd', {language : key}); + return $q.reject(key); + }); + langPromises[key]['finally'](function () { + clearNextLangAndPromise(key); + }).catch(angular.noop); // we don't care about errors (clearing) + } else if (langPromises[key]) { + // we are already loading this asynchronously + // resolve our new deferred when the old langPromise is resolved + langPromises[key].then(function (translation) { + if ($nextLang === translation.key) { + useLanguage(translation.key); + } + deferred.resolve(translation.key); + return translation; + }, function (key) { + // find first available fallback language if that request has failed + if (!$uses && $fallbackLanguage && $fallbackLanguage.length > 0 && $fallbackLanguage[0] !== key) { + return $translate.use($fallbackLanguage[0]).then(deferred.resolve, deferred.reject); + } else { + return deferred.reject(key); + } + }); + } else { + deferred.resolve(key); + useLanguage(key); + } + + return deferred.promise; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#resolveClientLocale + * @methodOf pascalprecht.translate.$translate + * + * @description + * This returns the current browser/client's language key. The result is processed with the configured uniform tag resolver. + * + * @returns {string} the current client/browser language key + */ + $translate.resolveClientLocale = function () { + return getLocale(); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#storageKey + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the key for the storage. + * + * @return {string} storage key + */ + $translate.storageKey = function () { + return storageKey(); + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#isPostCompilingEnabled + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns whether post compiling is enabled or not + * + * @return {bool} storage key + */ + $translate.isPostCompilingEnabled = function () { + return $postCompilingEnabled; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#isForceAsyncReloadEnabled + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns whether force async reload is enabled or not + * + * @return {boolean} forceAsyncReload value + */ + $translate.isForceAsyncReloadEnabled = function () { + return $forceAsyncReloadEnabled; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#isKeepContent + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns whether keepContent or not + * + * @return {boolean} keepContent value + */ + $translate.isKeepContent = function () { + return $keepContent; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#refresh + * @methodOf pascalprecht.translate.$translate + * + * @description + * Refreshes a translation table pointed by the given langKey. If langKey is not specified, + * the module will drop all existent translation tables and load new version of those which + * are currently in use. + * + * Refresh means that the module will drop target translation table and try to load it again. + * + * In case there are no loaders registered the refresh() method will throw an Error. + * + * If the module is able to refresh translation tables refresh() method will broadcast + * $translateRefreshStart and $translateRefreshEnd events. + * + * @example + * // this will drop all currently existent translation tables and reload those which are + * // currently in use + * $translate.refresh(); + * // this will refresh a translation table for the en_US language + * $translate.refresh('en_US'); + * + * @param {string} langKey A language key of the table, which has to be refreshed + * + * @return {promise} Promise, which will be resolved in case a translation tables refreshing + * process is finished successfully, and reject if not. + */ + $translate.refresh = function (langKey) { + if (!$loaderFactory) { + throw new Error('Couldn\'t refresh translation table, no loader registered!'); + } + + $rootScope.$emit('$translateRefreshStart', {language : langKey}); + + var deferred = $q.defer(), updatedLanguages = {}; + + //private helper + function loadNewData(languageKey) { + var promise = loadAsync(languageKey); + //update the load promise cache for this language + langPromises[languageKey] = promise; + //register a data handler for the promise + promise.then(function (data) { + //clear the cache for this language + $translationTable[languageKey] = {}; + //add the new data for this language + translations(languageKey, data.table); + //track that we updated this language + updatedLanguages[languageKey] = true; + }, + //handle rejection to appease the $q validation + angular.noop); + return promise; + } + + //set up post-processing + deferred.promise.then( + function () { + for (var key in $translationTable) { + if ($translationTable.hasOwnProperty(key)) { + //delete cache entries that were not updated + if (!(key in updatedLanguages)) { + delete $translationTable[key]; + } + } + } + if ($uses) { + useLanguage($uses); + } + }, + //handle rejection to appease the $q validation + angular.noop + ).finally( + function () { + $rootScope.$emit('$translateRefreshEnd', {language : langKey}); + } + ); + + if (!langKey) { + // if there's no language key specified we refresh ALL THE THINGS! + var languagesToReload = $fallbackLanguage && $fallbackLanguage.slice() || []; + if ($uses && languagesToReload.indexOf($uses) === -1) { + languagesToReload.push($uses); + } + $q.all(languagesToReload.map(loadNewData)).then(deferred.resolve, deferred.reject); + + } else if ($translationTable[langKey]) { + //just refresh the specified language cache + loadNewData(langKey).then(deferred.resolve, deferred.reject); + + } else { + deferred.reject(); + } + + return deferred.promise; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#instant + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns a translation instantly from the internal state of loaded translation. All rules + * regarding the current language, the preferred language of even fallback languages will be + * used except any promise handling. If a language was not found, an asynchronous loading + * will be invoked in the background. + * + * @param {string|array} translationId A token which represents a translation id + * This can be optionally an array of translation ids which + * results that the function's promise returns an object where + * each key is the translation id and the value the translation. + * @param {object} interpolateParams Params + * @param {string} interpolationId The id of the interpolation to use + * @param {string} forceLanguage A language to be used instead of the current language + * @param {string} sanitizeStrategy force sanitize strategy for this call instead of using the configured one + * + * @return {string|object} translation + */ + $translate.instant = function (translationId, interpolateParams, interpolationId, forceLanguage, sanitizeStrategy) { + + // we don't want to re-negotiate $uses + var uses = (forceLanguage && forceLanguage !== $uses) ? // we don't want to re-negotiate $uses + (negotiateLocale(forceLanguage) || forceLanguage) : $uses; + + // Detect undefined and null values to shorten the execution and prevent exceptions + if (translationId === null || angular.isUndefined(translationId)) { + return translationId; + } + + // Check forceLanguage is present + if (forceLanguage) { + loadTranslationsIfMissing(forceLanguage); + } + + // Duck detection: If the first argument is an array, a bunch of translations was requested. + // The result is an object. + if (angular.isArray(translationId)) { + var results = {}; + for (var i = 0, c = translationId.length; i < c; i++) { + results[translationId[i]] = $translate.instant(translationId[i], interpolateParams, interpolationId, forceLanguage, sanitizeStrategy); + } + return results; + } + + // We discarded unacceptable values. So we just need to verify if translationId is empty String + if (angular.isString(translationId) && translationId.length < 1) { + return translationId; + } + + // trim off any whitespace + if (translationId) { + translationId = trim.apply(translationId); + } + + var result, possibleLangKeys = []; + if ($preferredLanguage) { + possibleLangKeys.push($preferredLanguage); + } + if (uses) { + possibleLangKeys.push(uses); + } + if ($fallbackLanguage && $fallbackLanguage.length) { + possibleLangKeys = possibleLangKeys.concat($fallbackLanguage); + } + for (var j = 0, d = possibleLangKeys.length; j < d; j++) { + var possibleLangKey = possibleLangKeys[j]; + if ($translationTable[possibleLangKey]) { + if (typeof $translationTable[possibleLangKey][translationId] !== 'undefined') { + result = determineTranslationInstant(translationId, interpolateParams, interpolationId, uses, sanitizeStrategy); + } + } + if (typeof result !== 'undefined') { + break; + } + } + + if (!result && result !== '') { + if ($notFoundIndicatorLeft || $notFoundIndicatorRight) { + result = applyNotFoundIndicators(translationId); + } else { + // Return translation of default interpolator if not found anything. + result = defaultInterpolator.interpolate(translationId, interpolateParams, 'filter', sanitizeStrategy); + + // looks like the requested translation id doesn't exists. + // Now, if there is a registered handler for missing translations and no + // asyncLoader is pending, we execute the handler + var missingTranslationHandlerTranslation; + if ($missingTranslationHandlerFactory && !pendingLoader) { + missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, sanitizeStrategy); + } + + if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { + result = missingTranslationHandlerTranslation; + } + } + } + + return result; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#versionInfo + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the current version information for the angular-translate library + * + * @return {string} angular-translate version + */ + $translate.versionInfo = function () { + return version; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#loaderCache + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns the defined loaderCache. + * + * @return {boolean|string|object} current value of loaderCache + */ + $translate.loaderCache = function () { + return loaderCache; + }; + + // internal purpose only + $translate.directivePriority = function () { + return directivePriority; + }; + + // internal purpose only + $translate.statefulFilter = function () { + return statefulFilter; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#isReady + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns whether the service is "ready" to translate (i.e. loading 1st language). + * + * See also {@link pascalprecht.translate.$translate#methods_onReady onReady()}. + * + * @return {boolean} current value of ready + */ + $translate.isReady = function () { + return $isReady; + }; + + var $onReadyDeferred = $q.defer(); + $onReadyDeferred.promise.then(function () { + $isReady = true; + }); + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#onReady + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns whether the service is "ready" to translate (i.e. loading 1st language). + * + * See also {@link pascalprecht.translate.$translate#methods_isReady isReady()}. + * + * @param {Function=} fn Function to invoke when service is ready + * @return {object} Promise resolved when service is ready + */ + $translate.onReady = function (fn) { + var deferred = $q.defer(); + if (angular.isFunction(fn)) { + deferred.promise.then(fn); + } + if ($isReady) { + deferred.resolve(); + } else { + $onReadyDeferred.promise.then(deferred.resolve); + } + return deferred.promise; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#getAvailableLanguageKeys + * @methodOf pascalprecht.translate.$translate + * + * @description + * This function simply returns the registered language keys being defined before in the config phase + * With this, an application can use the array to provide a language selection dropdown or similar + * without any additional effort + * + * @returns {object} returns the list of possibly registered language keys and mapping or null if not defined + */ + $translate.getAvailableLanguageKeys = function () { + if ($availableLanguageKeys.length > 0) { + return $availableLanguageKeys; + } + return null; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translate#getTranslationTable + * @methodOf pascalprecht.translate.$translate + * + * @description + * Returns translation table by the given language key. + * + * Unless a language is provided it returns a translation table of the current one. + * Note: If translation dictionary is currently downloading or in progress + * it will return null. + * + * @param {string} langKey A token which represents a translation id + * + * @return {object} a copy of angular-translate $translationTable + */ + $translate.getTranslationTable = function (langKey) { + langKey = langKey || $translate.use(); + if (langKey && $translationTable[langKey]) { + return angular.copy($translationTable[langKey]); + } + return null; + }; + + // Whenever $translateReady is being fired, this will ensure the state of $isReady + var globalOnReadyListener = $rootScope.$on('$translateReady', function () { + $onReadyDeferred.resolve(); + globalOnReadyListener(); // one time only + globalOnReadyListener = null; + }); + var globalOnChangeListener = $rootScope.$on('$translateChangeEnd', function () { + $onReadyDeferred.resolve(); + globalOnChangeListener(); // one time only + globalOnChangeListener = null; + }); + + if ($loaderFactory) { + + // If at least one async loader is defined and there are no + // (default) translations available we should try to load them. + if (angular.equals($translationTable, {})) { + if ($translate.use()) { + $translate.use($translate.use()); + } + } + + // Also, if there are any fallback language registered, we start + // loading them asynchronously as soon as we can. + if ($fallbackLanguage && $fallbackLanguage.length) { + var processAsyncResult = function (translation) { + translations(translation.key, translation.table); + $rootScope.$emit('$translateChangeEnd', {language : translation.key}); + return translation; + }; + for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { + var fallbackLanguageId = $fallbackLanguage[i]; + if ($forceAsyncReloadEnabled || !$translationTable[fallbackLanguageId]) { + langPromises[fallbackLanguageId] = loadAsync(fallbackLanguageId).then(processAsyncResult); + } + } + } + } else { + $rootScope.$emit('$translateReady', {language : $translate.use()}); + } + + return $translate; + }]; +} + +$translate.displayName = 'displayName'; + +/** + * @ngdoc object + * @name pascalprecht.translate.$translateDefaultInterpolation + * @requires $interpolate + * + * @description + * Uses angular's `$interpolate` services to interpolate strings against some values. + * + * Be aware to configure a proper sanitization strategy. + * + * See also: + * * {@link pascalprecht.translate.$translateSanitization} + * + * @return {object} $translateDefaultInterpolation Interpolator service + */ +angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation', $translateDefaultInterpolation); + +function $translateDefaultInterpolation ($interpolate, $translateSanitization) { + + 'use strict'; + + var $translateInterpolator = {}, + $locale, + $identifier = 'default'; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateDefaultInterpolation#setLocale + * @methodOf pascalprecht.translate.$translateDefaultInterpolation + * + * @description + * Sets current locale (this is currently not use in this interpolation). + * + * @param {string} locale Language key or locale. + */ + $translateInterpolator.setLocale = function (locale) { + $locale = locale; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateDefaultInterpolation#getInterpolationIdentifier + * @methodOf pascalprecht.translate.$translateDefaultInterpolation + * + * @description + * Returns an identifier for this interpolation service. + * + * @returns {string} $identifier + */ + $translateInterpolator.getInterpolationIdentifier = function () { + return $identifier; + }; + + /** + * @deprecated will be removed in 3.0 + * @see {@link pascalprecht.translate.$translateSanitization} + */ + $translateInterpolator.useSanitizeValueStrategy = function (value) { + $translateSanitization.useStrategy(value); + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateDefaultInterpolation#interpolate + * @methodOf pascalprecht.translate.$translateDefaultInterpolation + * + * @description + * Interpolates given value agains given interpolate params using angulars + * `$interpolate` service. + * + * Since AngularJS 1.5, `value` must not be a string but can be anything input. + * + * @param value translation + * @param interpolationParams interpolation params + * @param context current context (filter, directive, service) + * @param sanitizeStrategy sanitize strategy + * @param translationId current translationId + * + * @returns {string} interpolated string + */ + $translateInterpolator.interpolate = function (value, interpolationParams, context, sanitizeStrategy/*, translationId*/) { + interpolationParams = interpolationParams || {}; + interpolationParams = $translateSanitization.sanitize(interpolationParams, 'params', sanitizeStrategy, context); + + var interpolatedText; + if (angular.isNumber(value)) { + // numbers are safe + interpolatedText = '' + value; + } else if (angular.isString(value)) { + // strings must be interpolated (that's the job here) + interpolatedText = $interpolate(value)(interpolationParams); + interpolatedText = $translateSanitization.sanitize(interpolatedText, 'text', sanitizeStrategy, context); + } else { + // neither a number or a string, cant interpolate => empty string + interpolatedText = ''; + } + + return interpolatedText; + }; + + return $translateInterpolator; +} + +$translateDefaultInterpolation.displayName = '$translateDefaultInterpolation'; + +angular.module('pascalprecht.translate').constant('$STORAGE_KEY', 'NG_TRANSLATE_LANG_KEY'); + +angular.module('pascalprecht.translate') +/** + * @ngdoc directive + * @name pascalprecht.translate.directive:translate + * @requires $interpolate, + * @requires $compile, + * @requires $parse, + * @requires $rootScope + * @restrict AE + * + * @description + * Translates given translation id either through attribute or DOM content. + * Internally it uses $translate service to translate the translation id. It possible to + * pass an optional `translate-values` object literal as string into translation id. + * + * @param {string=} translate Translation id which could be either string or interpolated string. + * @param {string=} translate-values Values to pass into translation id. Can be passed as object literal string or interpolated object. + * @param {string=} translate-attr-ATTR translate Translation id and put it into ATTR attribute. + * @param {string=} translate-default will be used unless translation was successful + * @param {boolean=} translate-compile (default true if present) defines locally activation of {@link pascalprecht.translate.$translateProvider#methods_usePostCompiling} + * @param {boolean=} translate-keep-content (default true if present) defines that in case a KEY could not be translated, that the existing content is left in the innerHTML} + * + * @example + + +
+ +

+        
TRANSLATION_ID
+

+        

+        
{{translationId}}
+

+        
WITH_VALUES
+

+        
WITH_VALUES
+

+        

+
+      
+
+ + angular.module('ngView', ['pascalprecht.translate']) + + .config(function ($translateProvider) { + + $translateProvider.translations('en',{ + 'TRANSLATION_ID': 'Hello there!', + 'WITH_VALUES': 'The following value is dynamic: {{value}}', + 'WITH_CAMEL_CASE_KEY': 'The interpolation key is camel cased: {{camelCaseKey}}' + }).preferredLanguage('en'); + + }); + + angular.module('ngView').controller('TranslateCtrl', function ($scope) { + $scope.translationId = 'TRANSLATION_ID'; + + $scope.values = { + value: 78 + }; + }); + + + it('should translate', function () { + inject(function ($rootScope, $compile) { + $rootScope.translationId = 'TRANSLATION_ID'; + + element = $compile('

')($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('Hello there!'); + + element = $compile('

')($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('Hello there!'); + + element = $compile('

TRANSLATION_ID

')($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('Hello there!'); + + element = $compile('

{{translationId}}

')($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('Hello there!'); + + element = $compile('

')($rootScope); + $rootScope.$digest(); + expect(element.attr('title')).toBe('Hello there!'); + + element = $compile('

')($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('The interpolation key is camel cased: Hello'); + }); + }); +
+
+ */ +.directive('translate', translateDirective); +function translateDirective($translate, $interpolate, $compile, $parse, $rootScope) { + + 'use strict'; + + /** + * @name trim + * @private + * + * @description + * trim polyfill + * + * @returns {string} The string stripped of whitespace from both ends + */ + var trim = function() { + return this.toString().replace(/^\s+|\s+$/g, ''); + }; + + return { + restrict: 'AE', + scope: true, + priority: $translate.directivePriority(), + compile: function (tElement, tAttr) { + + var translateValuesExist = (tAttr.translateValues) ? + tAttr.translateValues : undefined; + + var translateInterpolation = (tAttr.translateInterpolation) ? + tAttr.translateInterpolation : undefined; + + var translateValueExist = tElement[0].outerHTML.match(/translate-value-+/i); + + var interpolateRegExp = '^(.*)(' + $interpolate.startSymbol() + '.*' + $interpolate.endSymbol() + ')(.*)', + watcherRegExp = '^(.*)' + $interpolate.startSymbol() + '(.*)' + $interpolate.endSymbol() + '(.*)'; + + return function linkFn(scope, iElement, iAttr) { + + scope.interpolateParams = {}; + scope.preText = ''; + scope.postText = ''; + scope.translateNamespace = getTranslateNamespace(scope); + var translationIds = {}; + + var initInterpolationParams = function (interpolateParams, iAttr, tAttr) { + // initial setup + if (iAttr.translateValues) { + angular.extend(interpolateParams, $parse(iAttr.translateValues)(scope.$parent)); + } + // initially fetch all attributes if existing and fill the params + if (translateValueExist) { + for (var attr in tAttr) { + if (Object.prototype.hasOwnProperty.call(iAttr, attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') { + var attributeName = angular.lowercase(attr.substr(14, 1)) + attr.substr(15); + interpolateParams[attributeName] = tAttr[attr]; + } + } + } + }; + + // Ensures any change of the attribute "translate" containing the id will + // be re-stored to the scope's "translationId". + // If the attribute has no content, the element's text value (white spaces trimmed off) will be used. + var observeElementTranslation = function (translationId) { + + // Remove any old watcher + if (angular.isFunction(observeElementTranslation._unwatchOld)) { + observeElementTranslation._unwatchOld(); + observeElementTranslation._unwatchOld = undefined; + } + + if (angular.equals(translationId , '') || !angular.isDefined(translationId)) { + var iElementText = trim.apply(iElement.text()); + + // Resolve translation id by inner html if required + var interpolateMatches = iElementText.match(interpolateRegExp); + // Interpolate translation id if required + if (angular.isArray(interpolateMatches)) { + scope.preText = interpolateMatches[1]; + scope.postText = interpolateMatches[3]; + translationIds.translate = $interpolate(interpolateMatches[2])(scope.$parent); + var watcherMatches = iElementText.match(watcherRegExp); + if (angular.isArray(watcherMatches) && watcherMatches[2] && watcherMatches[2].length) { + observeElementTranslation._unwatchOld = scope.$watch(watcherMatches[2], function (newValue) { + translationIds.translate = newValue; + updateTranslations(); + }); + } + } else { + // do not assigne the translation id if it is empty. + translationIds.translate = !iElementText ? undefined : iElementText; + } + } else { + translationIds.translate = translationId; + } + updateTranslations(); + }; + + var observeAttributeTranslation = function (translateAttr) { + iAttr.$observe(translateAttr, function (translationId) { + translationIds[translateAttr] = translationId; + updateTranslations(); + }); + }; + + // initial setup with values + initInterpolationParams(scope.interpolateParams, iAttr, tAttr); + + var firstAttributeChangedEvent = true; + iAttr.$observe('translate', function (translationId) { + if (typeof translationId === 'undefined') { + // case of element "xyz" + observeElementTranslation(''); + } else { + // case of regular attribute + if (translationId !== '' || !firstAttributeChangedEvent) { + translationIds.translate = translationId; + updateTranslations(); + } + } + firstAttributeChangedEvent = false; + }); + + for (var translateAttr in iAttr) { + if (iAttr.hasOwnProperty(translateAttr) && translateAttr.substr(0, 13) === 'translateAttr' && translateAttr.length > 13) { + observeAttributeTranslation(translateAttr); + } + } + + iAttr.$observe('translateDefault', function (value) { + scope.defaultText = value; + updateTranslations(); + }); + + if (translateValuesExist) { + iAttr.$observe('translateValues', function (interpolateParams) { + if (interpolateParams) { + scope.$parent.$watch(function () { + angular.extend(scope.interpolateParams, $parse(interpolateParams)(scope.$parent)); + }); + } + }); + } + + if (translateValueExist) { + var observeValueAttribute = function (attrName) { + iAttr.$observe(attrName, function (value) { + var attributeName = angular.lowercase(attrName.substr(14, 1)) + attrName.substr(15); + scope.interpolateParams[attributeName] = value; + }); + }; + for (var attr in iAttr) { + if (Object.prototype.hasOwnProperty.call(iAttr, attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') { + observeValueAttribute(attr); + } + } + } + + // Master update function + var updateTranslations = function () { + for (var key in translationIds) { + if (translationIds.hasOwnProperty(key) && translationIds[key] !== undefined) { + updateTranslation(key, translationIds[key], scope, scope.interpolateParams, scope.defaultText, scope.translateNamespace); + } + } + }; + + // Put translation processing function outside loop + var updateTranslation = function(translateAttr, translationId, scope, interpolateParams, defaultTranslationText, translateNamespace) { + if (translationId) { + // if translation id starts with '.' and translateNamespace given, prepend namespace + if (translateNamespace && translationId.charAt(0) === '.') { + translationId = translateNamespace + translationId; + } + + $translate(translationId, interpolateParams, translateInterpolation, defaultTranslationText, scope.translateLanguage) + .then(function (translation) { + applyTranslation(translation, scope, true, translateAttr); + }, function (translationId) { + applyTranslation(translationId, scope, false, translateAttr); + }); + } else { + // as an empty string cannot be translated, we can solve this using successful=false + applyTranslation(translationId, scope, false, translateAttr); + } + }; + + var applyTranslation = function (value, scope, successful, translateAttr) { + if (!successful) { + if (typeof scope.defaultText !== 'undefined') { + value = scope.defaultText; + } + } + if (translateAttr === 'translate') { + // default translate into innerHTML + if (successful || (!successful && !$translate.isKeepContent() && typeof iAttr.translateKeepContent === 'undefined')) { + iElement.empty().append(scope.preText + value + scope.postText); + } + var globallyEnabled = $translate.isPostCompilingEnabled(); + var locallyDefined = typeof tAttr.translateCompile !== 'undefined'; + var locallyEnabled = locallyDefined && tAttr.translateCompile !== 'false'; + if ((globallyEnabled && !locallyDefined) || locallyEnabled) { + $compile(iElement.contents())(scope); + } + } else { + // translate attribute + var attributeName = iAttr.$attr[translateAttr]; + if (attributeName.substr(0, 5) === 'data-') { + // ensure html5 data prefix is stripped + attributeName = attributeName.substr(5); + } + attributeName = attributeName.substr(15); + iElement.attr(attributeName, value); + } + }; + + if (translateValuesExist || translateValueExist || iAttr.translateDefault) { + scope.$watch('interpolateParams', updateTranslations, true); + } + + // Replaced watcher on translateLanguage with event listener + scope.$on('translateLanguageChanged', updateTranslations); + + // Ensures the text will be refreshed after the current language was changed + // w/ $translate.use(...) + var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslations); + + // ensure translation will be looked up at least one + if (iElement.text().length) { + if (iAttr.translate) { + observeElementTranslation(iAttr.translate); + } else { + observeElementTranslation(''); + } + } else if (iAttr.translate) { + // ensure attribute will be not skipped + observeElementTranslation(iAttr.translate); + } + updateTranslations(); + scope.$on('$destroy', unbind); + }; + } + }; +} + +/** + * Returns the scope's namespace. + * @private + * @param scope + * @returns {string} + */ +function getTranslateNamespace(scope) { + 'use strict'; + if (scope.translateNamespace) { + return scope.translateNamespace; + } + if (scope.$parent) { + return getTranslateNamespace(scope.$parent); + } +} + +translateDirective.displayName = 'translateDirective'; + +angular.module('pascalprecht.translate') +/** + * @ngdoc directive + * @name pascalprecht.translate.directive:translate-attr + * @restrict A + * + * @description + * Translates attributes like translate-attr-ATTR, but with an object like ng-class. + * Internally it uses `translate` service to translate translation id. It possible to + * pass an optional `translate-values` object literal as string into translation id. + * + * @param {string=} translate-attr Object literal mapping attributes to translation ids. + * @param {string=} translate-values Values to pass into the translation ids. Can be passed as object literal string. + * + * @example + + +
+ + + +
+
+ + angular.module('ngView', ['pascalprecht.translate']) + + .config(function ($translateProvider) { + + $translateProvider.translations('en',{ + 'TRANSLATION_ID': 'Hello there!', + 'WITH_VALUES': 'The following value is dynamic: {{value}}', + }).preferredLanguage('en'); + + }); + + angular.module('ngView').controller('TranslateCtrl', function ($scope) { + $scope.translationId = 'TRANSLATION_ID'; + + $scope.values = { + value: 78 + }; + }); + + + it('should translate', function () { + inject(function ($rootScope, $compile) { + $rootScope.translationId = 'TRANSLATION_ID'; + + element = $compile('')($rootScope); + $rootScope.$digest(); + expect(element.attr('placeholder)).toBe('Hello there!'); + expect(element.attr('title)).toBe('The following value is dynamic: 5'); + }); + }); + +
+ */ +.directive('translateAttr', translateAttrDirective); +function translateAttrDirective($translate, $rootScope) { + + 'use strict'; + + return { + restrict: 'A', + priority: $translate.directivePriority(), + link: function linkFn(scope, element, attr) { + + var translateAttr, + translateValues, + previousAttributes = {}; + + // Main update translations function + var updateTranslations = function () { + angular.forEach(translateAttr, function (translationId, attributeName) { + if (!translationId) { + return; + } + previousAttributes[attributeName] = true; + + // if translation id starts with '.' and translateNamespace given, prepend namespace + if (scope.translateNamespace && translationId.charAt(0) === '.') { + translationId = scope.translateNamespace + translationId; + } + $translate(translationId, translateValues, attr.translateInterpolation, undefined, scope.translateLanguage) + .then(function (translation) { + element.attr(attributeName, translation); + }, function (translationId) { + element.attr(attributeName, translationId); + }); + }); + + // Removing unused attributes that were previously used + angular.forEach(previousAttributes, function (flag, attributeName) { + if (!translateAttr[attributeName]) { + element.removeAttr(attributeName); + delete previousAttributes[attributeName]; + } + }); + }; + + // Watch for attribute changes + watchAttribute( + scope, + attr.translateAttr, + function (newValue) { translateAttr = newValue; }, + updateTranslations + ); + // Watch for value changes + watchAttribute( + scope, + attr.translateValues, + function (newValue) { translateValues = newValue; }, + updateTranslations + ); + + if (attr.translateValues) { + scope.$watch(attr.translateValues, updateTranslations, true); + } + + // Replaced watcher on translateLanguage with event listener + scope.$on('translateLanguageChanged', updateTranslations); + + // Ensures the text will be refreshed after the current language was changed + // w/ $translate.use(...) + var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslations); + + updateTranslations(); + scope.$on('$destroy', unbind); + } + }; +} + +function watchAttribute(scope, attribute, valueCallback, changeCallback) { + 'use strict'; + if (!attribute) { + return; + } + if (attribute.substr(0, 2) === '::') { + attribute = attribute.substr(2); + } else { + scope.$watch(attribute, function(newValue) { + valueCallback(newValue); + changeCallback(); + }, true); + } + valueCallback(scope.$eval(attribute)); +} + +translateAttrDirective.displayName = 'translateAttrDirective'; + +angular.module('pascalprecht.translate') +/** + * @ngdoc directive + * @name pascalprecht.translate.directive:translateCloak + * @requires $translate + * @restrict A + * + * $description + * Adds a `translate-cloak` class name to the given element where this directive + * is applied initially and removes it, once a loader has finished loading. + * + * This directive can be used to prevent initial flickering when loading translation + * data asynchronously. + * + * The class name is defined in + * {@link pascalprecht.translate.$translateProvider#cloakClassName $translate.cloakClassName()}. + * + * @param {string=} translate-cloak If a translationId is provided, it will be used for showing + * or hiding the cloak. Basically it relies on the translation + * resolve. + */ +.directive('translateCloak', translateCloakDirective); + +function translateCloakDirective($translate) { + + 'use strict'; + + return { + compile : function (tElement) { + var applyCloak = function (element) { + element.addClass($translate.cloakClassName()); + }, + removeCloak = function (element) { + element.removeClass($translate.cloakClassName()); + }; + applyCloak(tElement); + + return function linkFn(scope, iElement, iAttr) { + //Create bound functions that incorporate the active DOM element. + var iRemoveCloak = removeCloak.bind(this, iElement), iApplyCloak = applyCloak.bind(this, iElement); + if (iAttr.translateCloak && iAttr.translateCloak.length) { + // Register a watcher for the defined translation allowing a fine tuned cloak + iAttr.$observe('translateCloak', function (translationId) { + $translate(translationId).then(iRemoveCloak, iApplyCloak); + }); + } + else { + $translate.onReady(iRemoveCloak); + } + }; + } + }; +} + +translateCloakDirective.displayName = 'translateCloakDirective'; + +angular.module('pascalprecht.translate') +/** + * @ngdoc directive + * @name pascalprecht.translate.directive:translateNamespace + * @restrict A + * + * @description + * Translates given translation id either through attribute or DOM content. + * Internally it uses `translate` filter to translate translation id. It possible to + * pass an optional `translate-values` object literal as string into translation id. + * + * @param {string=} translate namespace name which could be either string or interpolated string. + * + * @example + + +
+ +
+

.HEADERS.TITLE

+

.HEADERS.WELCOME

+
+ +
+

.TITLE

+

.WELCOME

+
+ +
+
+ + angular.module('ngView', ['pascalprecht.translate']) + + .config(function ($translateProvider) { + + $translateProvider.translations('en',{ + 'TRANSLATION_ID': 'Hello there!', + 'CONTENT': { + 'HEADERS': { + TITLE: 'Title' + } + }, + 'CONTENT.HEADERS.WELCOME': 'Welcome' + }).preferredLanguage('en'); + + }); + + +
+ */ +.directive('translateNamespace', translateNamespaceDirective); + +function translateNamespaceDirective() { + + 'use strict'; + + return { + restrict: 'A', + scope: true, + compile: function () { + return { + pre: function (scope, iElement, iAttrs) { + scope.translateNamespace = getTranslateNamespace(scope); + + if (scope.translateNamespace && iAttrs.translateNamespace.charAt(0) === '.') { + scope.translateNamespace += iAttrs.translateNamespace; + } else { + scope.translateNamespace = iAttrs.translateNamespace; + } + } + }; + } + }; +} + +/** + * Returns the scope's namespace. + * @private + * @param scope + * @returns {string} + */ +function getTranslateNamespace(scope) { + 'use strict'; + if (scope.translateNamespace) { + return scope.translateNamespace; + } + if (scope.$parent) { + return getTranslateNamespace(scope.$parent); + } +} + +translateNamespaceDirective.displayName = 'translateNamespaceDirective'; + +angular.module('pascalprecht.translate') +/** + * @ngdoc directive + * @name pascalprecht.translate.directive:translateLanguage + * @restrict A + * + * @description + * Forces the language to the directives in the underlying scope. + * + * @param {string=} translate language that will be negotiated. + * + * @example + + +
+ +
+

HELLO

+
+ +
+

HELLO

+
+ +
+
+ + angular.module('ngView', ['pascalprecht.translate']) + + .config(function ($translateProvider) { + + $translateProvider + .translations('en',{ + 'HELLO': 'Hello world!' + }) + .translations('de',{ + 'HELLO': 'Hallo Welt!' + }) + .preferredLanguage('en'); + + }); + + +
+ */ +.directive('translateLanguage', translateLanguageDirective); + +function translateLanguageDirective() { + + 'use strict'; + + return { + restrict: 'A', + scope: true, + compile: function () { + return function linkFn(scope, iElement, iAttrs) { + + iAttrs.$observe('translateLanguage', function (newTranslateLanguage) { + scope.translateLanguage = newTranslateLanguage; + }); + + scope.$watch('translateLanguage', function(){ + scope.$broadcast('translateLanguageChanged'); + }); + }; + } + }; +} + +translateLanguageDirective.displayName = 'translateLanguageDirective'; + +angular.module('pascalprecht.translate') +/** + * @ngdoc filter + * @name pascalprecht.translate.filter:translate + * @requires $parse + * @requires pascalprecht.translate.$translate + * @function + * + * @description + * Uses `$translate` service to translate contents. Accepts interpolate parameters + * to pass dynamized values though translation. + * + * @param {string} translationId A translation id to be translated. + * @param {*=} interpolateParams Optional object literal (as hash or string) to pass values into translation. + * + * @returns {string} Translated text. + * + * @example + + +
+ +
{{ 'TRANSLATION_ID' | translate }}
+
{{ translationId | translate }}
+
{{ 'WITH_VALUES' | translate:'{value: 5}' }}
+
{{ 'WITH_VALUES' | translate:values }}
+ +
+
+ + angular.module('ngView', ['pascalprecht.translate']) + + .config(function ($translateProvider) { + + $translateProvider.translations('en', { + 'TRANSLATION_ID': 'Hello there!', + 'WITH_VALUES': 'The following value is dynamic: {{value}}' + }); + $translateProvider.preferredLanguage('en'); + + }); + + angular.module('ngView').controller('TranslateCtrl', function ($scope) { + $scope.translationId = 'TRANSLATION_ID'; + + $scope.values = { + value: 78 + }; + }); + +
+ */ +.filter('translate', translateFilterFactory); + +function translateFilterFactory($parse, $translate) { + + 'use strict'; + + var translateFilter = function (translationId, interpolateParams, interpolation, forceLanguage) { + if (!angular.isObject(interpolateParams)) { + interpolateParams = $parse(interpolateParams)(this); + } + + return $translate.instant(translationId, interpolateParams, interpolation, forceLanguage); + }; + + if ($translate.statefulFilter()) { + translateFilter.$stateful = true; + } + + return translateFilter; +} + +translateFilterFactory.displayName = 'translateFilterFactory'; + +angular.module('pascalprecht.translate') + +/** + * @ngdoc object + * @name pascalprecht.translate.$translationCache + * @requires $cacheFactory + * + * @description + * The first time a translation table is used, it is loaded in the translation cache for quick retrieval. You + * can load translation tables directly into the cache by consuming the + * `$translationCache` service directly. + * + * @return {object} $cacheFactory object. + */ + .factory('$translationCache', $translationCache); + +function $translationCache($cacheFactory) { + + 'use strict'; + + return $cacheFactory('translations'); +} + +$translationCache.displayName = '$translationCache'; +return 'pascalprecht.translate'; + +})); diff --git a/api-wiaas/client/js/bower_components/angular-translate/angular-translate.min.js b/api-wiaas/client/js/bower_components/angular-translate/angular-translate.min.js new file mode 100644 index 0000000..c0a9447 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate/angular-translate.min.js @@ -0,0 +1,6 @@ +/*! + * angular-translate - v2.14.0 - 2017-02-11 + * + * Copyright (c) 2017 The angular-translate team, Pascal Precht; Licensed MIT + */ +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return b()}):"object"==typeof exports?module.exports=b():b()}(this,function(){function a(a){"use strict";var b=a.storageKey(),c=a.storage(),d=function(){var d=a.preferredLanguage();angular.isString(d)?a.use(d):c.put(b,a.use())};d.displayName="fallbackFromIncorrectStorageValue",c?c.get(b)?a.use(c.get(b)).catch(d):d():angular.isString(a.preferredLanguage())&&a.use(a.preferredLanguage())}function b(){"use strict";var a,b,c,d=null,e=!1,f=!1;c={sanitize:function(a,b){return"text"===b&&(a=h(a)),a},escape:function(a,b){return"text"===b&&(a=g(a)),a},sanitizeParameters:function(a,b){return"params"===b&&(a=j(a,h)),a},escapeParameters:function(a,b){return"params"===b&&(a=j(a,g)),a},sce:function(a,b,c){return"text"===b?a=i(a):"params"===b&&"filter"!==c&&(a=j(a,g)),a},sceParameters:function(a,b){return"params"===b&&(a=j(a,i)),a}},c.escaped=c.escapeParameters,this.addStrategy=function(a,b){return c[a]=b,this},this.removeStrategy=function(a){return delete c[a],this},this.useStrategy=function(a){return e=!0,d=a,this},this.$get=["$injector","$log",function(g,h){var i={},j=function(a,b,d,e){return angular.forEach(e,function(e){if(angular.isFunction(e))a=e(a,b,d);else if(angular.isFunction(c[e]))a=c[e](a,b,d);else{if(!angular.isString(c[e]))throw new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+e+"'");if(!i[c[e]])try{i[c[e]]=g.get(c[e])}catch(a){throw i[c[e]]=function(){},new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+e+"'")}a=i[c[e]](a,b,d)}}),a},k=function(){e||f||(h.warn("pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details."),f=!0)};return g.has("$sanitize")&&(a=g.get("$sanitize")),g.has("$sce")&&(b=g.get("$sce")),{useStrategy:function(a){return function(b){a.useStrategy(b)}}(this),sanitize:function(a,b,c,e){if(d||k(),c||null===c||(c=d),!c)return a;e||(e="service");var f=angular.isArray(c)?c:[c];return j(a,b,e,f)}}}];var g=function(a){var b=angular.element("
");return b.text(a),b.html()},h=function(b){if(!a)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as 'escape'.");return a(b)},i=function(a){if(!b)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot find $sce service.");return b.trustAsHtml(a)},j=function(a,b,c){if(angular.isDate(a))return a;if(angular.isObject(a)){var d=angular.isArray(a)?[]:{};if(c){if(c.indexOf(a)>-1)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot interpolate parameter due recursive object")}else c=[];return c.push(a),angular.forEach(a,function(a,e){angular.isFunction(a)||(d[e]=j(a,b,c))}),c.splice(-1,1),d}return angular.isNumber(a)?a:angular.isUndefined(a)||null===a?a:b(a)}}function c(a,b,c,d){"use strict";var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u={},v=[],w=a,x=[],y="translate-cloak",z=!1,A=!1,B=".",C=!1,D=!1,E=0,F=!0,G="default",H={default:function(a){return(a||"").split("-").join("_")},java:function(a){var b=(a||"").split("-").join("_"),c=b.split("_");return c.length>1?c[0].toLowerCase()+"_"+c[1].toUpperCase():b},bcp47:function(a){var b=(a||"").split("_").join("-"),c=b.split("-");return c.length>1?c[0].toLowerCase()+"-"+c[1].toUpperCase():b},"iso639-1":function(a){var b=(a||"").split("_").join("-"),c=b.split("-");return c[0].toLowerCase()}},I="2.14.0",J=function(){if(angular.isFunction(d.getLocale))return d.getLocale();var a,c,e=b.$get().navigator,f=["language","browserLanguage","systemLanguage","userLanguage"];if(angular.isArray(e.languages))for(a=0;a-1)return a;if(f){var g;for(var h in f)if(f.hasOwnProperty(h)){var i=!1,j=Object.prototype.hasOwnProperty.call(f,h)&&angular.lowercase(h)===angular.lowercase(a);if("*"===h.slice(-1)&&(i=h.slice(0,-1)===a.slice(0,h.length-1)),(j||i)&&(g=f[h],L(b,angular.lowercase(g))>-1))return g}}var k=a.split("_");return k.length>1&&L(b,angular.lowercase(k[0]))>-1?k[0]:void 0}},O=function(a,b){if(!a&&!b)return u;if(a&&!b){if(angular.isString(a))return u[a]}else angular.isObject(u[a])||(u[a]={}),angular.extend(u[a],P(b));return this};this.translations=O,this.cloakClassName=function(a){return a?(y=a,this):y},this.nestedObjectDelimeter=function(a){return a?(B=a,this):B};var P=function(a,b,c,d){var e,f,g,h;b||(b=[]),c||(c={});for(e in a)Object.prototype.hasOwnProperty.call(a,e)&&(h=a[e],angular.isObject(h)?P(h,b.concat(e),c,e):(f=b.length?""+b.join(B)+B+e:e,b.length&&e===d&&(g=""+b.join(B),c[g]="@:"+f),c[f]=h));return c};P.displayName="flatObject",this.addInterpolation=function(a){return x.push(a),this},this.useMessageFormatInterpolation=function(){return this.useInterpolation("$translateMessageFormatInterpolation")},this.useInterpolation=function(a){return n=a,this},this.useSanitizeValueStrategy=function(a){return c.useStrategy(a),this},this.preferredLanguage=function(a){return a?(Q(a),this):e};var Q=function(a){return a&&(e=a),e};this.translationNotFoundIndicator=function(a){return this.translationNotFoundIndicatorLeft(a),this.translationNotFoundIndicatorRight(a),this},this.translationNotFoundIndicatorLeft=function(a){return a?(q=a,this):q},this.translationNotFoundIndicatorRight=function(a){return a?(r=a,this):r},this.fallbackLanguage=function(a){return R(a),this};var R=function(a){return a?(angular.isString(a)?(h=!0,g=[a]):angular.isArray(a)&&(h=!1,g=a),angular.isString(e)&&L(g,e)<0&&g.push(e),this):h?g[0]:g};this.use=function(a){if(a){if(!u[a]&&!o)throw new Error("$translateProvider couldn't find translationTable for langKey: '"+a+"'");return i=a,this}return i},this.resolveClientLocale=function(){return K()};var S=function(a){return a?(w=a,this):l?l+w:w};this.storageKey=S,this.useUrlLoader=function(a,b){return this.useLoader("$translateUrlLoader",angular.extend({url:a},b))},this.useStaticFilesLoader=function(a){return this.useLoader("$translateStaticFilesLoader",a)},this.useLoader=function(a,b){return o=a,p=b||{},this},this.useLocalStorage=function(){return this.useStorage("$translateLocalStorage")},this.useCookieStorage=function(){return this.useStorage("$translateCookieStorage")},this.useStorage=function(a){return k=a,this},this.storagePrefix=function(a){return a?(l=a,this):a},this.useMissingTranslationHandlerLog=function(){return this.useMissingTranslationHandler("$translateMissingTranslationHandlerLog")},this.useMissingTranslationHandler=function(a){return m=a,this},this.usePostCompiling=function(a){return z=!!a,this},this.forceAsyncReload=function(a){return A=!!a,this},this.uniformLanguageTag=function(a){return a?angular.isString(a)&&(a={standard:a}):a={},G=a.standard,this},this.determinePreferredLanguage=function(a){var b=a&&angular.isFunction(a)?a():K();return e=v.length?N(b)||b:b,this},this.registerAvailableLanguageKeys=function(a,b){return a?(v=a,b&&(f=b),this):v},this.useLoaderCache=function(a){return a===!1?s=void 0:a===!0?s=!0:"undefined"==typeof a?s="$translationCache":a&&(s=a),this},this.directivePriority=function(a){return void 0===a?E:(E=a,this)},this.statefulFilter=function(a){return void 0===a?F:(F=a,this)},this.postProcess=function(a){return t=a?a:void 0,this},this.keepContent=function(a){return D=!!a,this},this.$get=["$log","$injector","$rootScope","$q",function(a,b,c,d){var f,l,G,H=b.get(n||"$translateDefaultInterpolation"),J=!1,T={},U={},V=function(a,b,c,h,j){!i&&e&&(i=e);var m=j&&j!==i?N(j)||j:i;if(j&&ka(j),angular.isArray(a)){var n=function(a){for(var e={},f=[],g=function(a){var f=d.defer(),g=function(b){e[a]=b,f.resolve([a,b])};return V(a,b,c,h,j).then(g,g),f.promise},i=0,k=a.length;i0?G:l,a,b,c,d,e)},fa=function(a,b,c,d){return da(G>0?G:l,a,b,c,d)},ga=function(a,b,c,e,f,h){var i=d.defer(),j=f?u[f]:u,k=c?T[c]:H;if(j&&Object.prototype.hasOwnProperty.call(j,a)&&null!==j[a]){var l=j[a];if("@:"===l.substr(0,2))V(l.substr(2),b,c,e,f).then(i.resolve,i.reject);else{var n=k.interpolate(l,b,"service",h,a);n=ja(a,l,n,b,f),i.resolve(n)}}else{var o;m&&!J&&(o=ba(a,b,e)),f&&g&&g.length?ea(a,b,k,e,h).then(function(a){i.resolve(a)},function(a){i.reject(W(a))}):m&&!J&&o?e?i.resolve(e):i.resolve(o):e?i.resolve(e):i.reject(W(a))}return i.promise},ha=function(a,b,c,d,e){var f,h=d?u[d]:u,i=H;if(T&&Object.prototype.hasOwnProperty.call(T,c)&&(i=T[c]),h&&Object.prototype.hasOwnProperty.call(h,a)&&null!==h[a]){var j=h[a];"@:"===j.substr(0,2)?f=ha(j.substr(2),b,c,d,e):(f=i.interpolate(j,b,"filter",e,a),f=ja(a,j,f,b,d,e))}else{var k;m&&!J&&(k=ba(a,b,e)),d&&g&&g.length?(l=0,f=fa(a,b,i,e)):f=m&&!J&&k?k:W(a)}return f},ia=function(a){j===a&&(j=void 0),U[a]=void 0},ja=function(a,c,d,e,f,g){var h=t;return h&&("string"==typeof h&&(h=b.get(h)),h)?h(a,c,d,e,f,g):d},ka=function(a){u[a]||!o||U[a]||(U[a]=Y(a).then(function(a){return O(a.key,a.table),a}))};V.preferredLanguage=function(a){return a&&Q(a),e},V.cloakClassName=function(){return y},V.nestedObjectDelimeter=function(){return B},V.fallbackLanguage=function(a){if(void 0!==a&&null!==a){if(R(a),o&&g&&g.length)for(var b=0,c=g.length;b-1&&(G=b)}else G=0},V.proposedLanguage=function(){return j},V.storage=function(){return f},V.negotiateLocale=N,V.use=function(a){if(!a)return i;var b=d.defer();b.promise.then(null,angular.noop),c.$emit("$translateChangeStart",{language:a});var e=N(a);return v.length>0&&!e?d.reject(a):(e&&(a=e),j=a,!A&&u[a]||!o||U[a]?U[a]?U[a].then(function(a){return j===a.key&&X(a.key),b.resolve(a.key),a},function(a){return!i&&g&&g.length>0&&g[0]!==a?V.use(g[0]).then(b.resolve,b.reject):b.reject(a)}):(b.resolve(a),X(a)):(U[a]=Y(a).then(function(c){return O(c.key,c.table),b.resolve(c.key),j===a&&X(c.key),c},function(a){return c.$emit("$translateChangeError",{language:a}),b.reject(a),c.$emit("$translateChangeEnd",{language:a}),d.reject(a)}),U[a].finally(function(){ia(a)}).catch(angular.noop)),b.promise)},V.resolveClientLocale=function(){return K()},V.storageKey=function(){return S()},V.isPostCompilingEnabled=function(){return z},V.isForceAsyncReloadEnabled=function(){return A},V.isKeepContent=function(){return D},V.refresh=function(a){function b(a){var b=Y(a);return U[a]=b,b.then(function(b){u[a]={},O(a,b.table),f[a]=!0},angular.noop),b}if(!o)throw new Error("Couldn't refresh translation table, no loader registered!");c.$emit("$translateRefreshStart",{language:a});var e=d.defer(),f={};if(e.promise.then(function(){for(var a in u)u.hasOwnProperty(a)&&(a in f||delete u[a]);i&&X(i)},angular.noop).finally(function(){c.$emit("$translateRefreshEnd",{language:a})}),a)u[a]?b(a).then(e.resolve,e.reject):e.reject();else{var h=g&&g.slice()||[];i&&h.indexOf(i)===-1&&h.push(i),d.all(h.map(b)).then(e.resolve,e.reject)}return e.promise},V.instant=function(a,b,c,d,f){var h=d&&d!==i?N(d)||d:i;if(null===a||angular.isUndefined(a))return a;if(d&&ka(d),angular.isArray(a)){for(var j={},k=0,l=a.length;k0?v:null},V.getTranslationTable=function(a){return a=a||V.use(),a&&u[a]?angular.copy(u[a]):null};var ma=c.$on("$translateReady",function(){la.resolve(),ma(),ma=null}),na=c.$on("$translateChangeEnd",function(){la.resolve(),na(),na=null});if(o){if(angular.equals(u,{})&&V.use()&&V.use(V.use()),g&&g.length)for(var oa=function(a){return O(a.key,a.table),c.$emit("$translateChangeEnd",{language:a.key}),a},pa=0,qa=g.length;pa13&&t(v);if(p.$observe("translateDefault",function(a){h.defaultText=a,y()}),j&&p.$observe("translateValues",function(a){a&&h.$parent.$watch(function(){angular.extend(h.interpolateParams,d(a)(h.$parent))})}),l){var w=function(a){p.$observe(a,function(b){var c=angular.lowercase(a.substr(14,1))+a.substr(15);h.interpolateParams[c]=b})};for(var x in p)Object.prototype.hasOwnProperty.call(p,x)&&"translateValue"===x.substr(0,14)&&"translateValues"!==x&&w(x)}var y=function(){for(var a in q)q.hasOwnProperty(a)&&void 0!==q[a]&&z(a,q[a],h,h.interpolateParams,h.defaultText,h.translateNamespace)},z=function(b,c,d,e,f,g){c?(g&&"."===c.charAt(0)&&(c=g+c),a(c,e,k,f,d.translateLanguage).then(function(a){A(a,d,!0,b)},function(a){A(a,d,!1,b)})):A(c,d,!1,b)},A=function(b,d,e,f){if(e||"undefined"!=typeof d.defaultText&&(b=d.defaultText),"translate"===f){(e||!e&&!a.isKeepContent()&&"undefined"==typeof p.translateKeepContent)&&o.empty().append(d.preText+b+d.postText);var g=a.isPostCompilingEnabled(),h="undefined"!=typeof i.translateCompile,j=h&&"false"!==i.translateCompile;(g&&!h||j)&&c(o.contents())(d)}else{var k=p.$attr[f];"data-"===k.substr(0,5)&&(k=k.substr(5)),k=k.substr(15),o.attr(k,b)}};(j||l||p.translateDefault)&&h.$watch("interpolateParams",y,!0),h.$on("translateLanguageChanged",y);var B=e.$on("$translateChangeSuccess",y);o.text().length?s(p.translate?p.translate:""):p.translate&&s(p.translate),y(),h.$on("$destroy",B)}}}}function f(a){"use strict";return a.translateNamespace?a.translateNamespace:a.$parent?f(a.$parent):void 0}function g(a,b){"use strict";return{restrict:"A",priority:a.directivePriority(),link:function(c,d,e){var f,g,i={},j=function(){angular.forEach(f,function(b,f){b&&(i[f]=!0,c.translateNamespace&&"."===b.charAt(0)&&(b=c.translateNamespace+b),a(b,g,e.translateInterpolation,void 0,c.translateLanguage).then(function(a){d.attr(f,a)},function(a){d.attr(f,a)}))}),angular.forEach(i,function(a,b){f[b]||(d.removeAttr(b),delete i[b])})};h(c,e.translateAttr,function(a){f=a},j),h(c,e.translateValues,function(a){g=a},j),e.translateValues&&c.$watch(e.translateValues,j,!0),c.$on("translateLanguageChanged",j);var k=b.$on("$translateChangeSuccess",j);j(),c.$on("$destroy",k)}}}function h(a,b,c,d){"use strict";b&&("::"===b.substr(0,2)?b=b.substr(2):a.$watch(b,function(a){c(a),d()},!0),c(a.$eval(b)))}function i(a){"use strict";return{compile:function(b){var c=function(b){b.addClass(a.cloakClassName())},d=function(b){b.removeClass(a.cloakClassName())};return c(b),function(b,e,f){var g=d.bind(this,e),h=c.bind(this,e);f.translateCloak&&f.translateCloak.length?f.$observe("translateCloak",function(b){a(b).then(g,h)}):a.onReady(g)}}}}function j(){"use strict";return{restrict:"A",scope:!0,compile:function(){return{pre:function(a,b,c){a.translateNamespace=f(a),a.translateNamespace&&"."===c.translateNamespace.charAt(0)?a.translateNamespace+=c.translateNamespace:a.translateNamespace=c.translateNamespace}}}}}function f(a){"use strict";return a.translateNamespace?a.translateNamespace:a.$parent?f(a.$parent):void 0}function k(){"use strict";return{restrict:"A",scope:!0,compile:function(){return function(a,b,c){c.$observe("translateLanguage",function(b){a.translateLanguage=b}),a.$watch("translateLanguage",function(){a.$broadcast("translateLanguageChanged")})}}}}function l(a,b){"use strict";var c=function(c,d,e,f){return angular.isObject(d)||(d=a(d)(this)),b.instant(c,d,e,f)};return b.statefulFilter()&&(c.$stateful=!0),c}function m(a){"use strict";return a("translations")}return a.$inject=["$translate"],c.$inject=["$STORAGE_KEY","$windowProvider","$translateSanitizationProvider","pascalprechtTranslateOverrider"],d.$inject=["$interpolate","$translateSanitization"],e.$inject=["$translate","$interpolate","$compile","$parse","$rootScope"],g.$inject=["$translate","$rootScope"],i.$inject=["$translate"],l.$inject=["$parse","$translate"],m.$inject=["$cacheFactory"],angular.module("pascalprecht.translate",["ng"]).run(a),a.displayName="runTranslate",angular.module("pascalprecht.translate").provider("$translateSanitization",b),angular.module("pascalprecht.translate").constant("pascalprechtTranslateOverrider",{}).provider("$translate",c),c.displayName="displayName",angular.module("pascalprecht.translate").factory("$translateDefaultInterpolation",d),d.displayName="$translateDefaultInterpolation",angular.module("pascalprecht.translate").constant("$STORAGE_KEY","NG_TRANSLATE_LANG_KEY"),angular.module("pascalprecht.translate").directive("translate",e),e.displayName="translateDirective",angular.module("pascalprecht.translate").directive("translateAttr",g),g.displayName="translateAttrDirective",angular.module("pascalprecht.translate").directive("translateCloak",i),i.displayName="translateCloakDirective",angular.module("pascalprecht.translate").directive("translateNamespace",j),j.displayName="translateNamespaceDirective",angular.module("pascalprecht.translate").directive("translateLanguage",k),k.displayName="translateLanguageDirective",angular.module("pascalprecht.translate").filter("translate",l),l.displayName="translateFilterFactory",angular.module("pascalprecht.translate").factory("$translationCache",m),m.displayName="$translationCache","pascalprecht.translate"}); \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-translate/bower.json b/api-wiaas/client/js/bower_components/angular-translate/bower.json new file mode 100644 index 0000000..e92aae6 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-translate/bower.json @@ -0,0 +1,12 @@ +{ + "name": "angular-translate", + "description": "A translation module for AngularJS", + "version": "2.14.0", + "main": "./angular-translate.js", + "ignore": [], + "author": "Pascal Precht", + "license": "MIT", + "dependencies": { + "angular": ">=1.2.26 <1.7" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/.bower.json b/api-wiaas/client/js/bower_components/angular-ui-notification/.bower.json new file mode 100644 index 0000000..1389afd --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/.bower.json @@ -0,0 +1,49 @@ +{ + "name": "angular-ui-notification", + "version": "0.3.5", + "homepage": "https://github.com/alexcrack/angular-ui-notification", + "repository": { + "type": "git", + "url": "git://github.com/jermorin/angular-ui-notification" + }, + "authors": [ + "Alexey Avramchik" + ], + "description": "Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating", + "main": [ + "dist/angular-ui-notification.css", + "dist/angular-ui-notification.js" + ], + "keywords": [ + "angular", + "notification", + "notify", + "bootstrap" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "demo", + "build" + ], + "dependencies": { + "angular": "^1.5.x" + }, + "devDependencies": { + "bootstrap": "^3.3.x" + }, + "_release": "0.3.5", + "_resolution": { + "type": "version", + "tag": "v0.3.5", + "commit": "fc92bd7e620a5dc4e616fed4aca5ad9bb6382fbd" + }, + "_source": "https://github.com/alexcrack/angular-ui-notification.git", + "_target": "^0.3.5", + "_originalSource": "angular-ui-notification", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/LICENSE b/api-wiaas/client/js/bower_components/angular-ui-notification/LICENSE new file mode 100644 index 0000000..678fd37 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Alexey Avramchik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/README.md b/api-wiaas/client/js/bower_components/angular-ui-notification/README.md new file mode 100644 index 0000000..c335ac2 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/README.md @@ -0,0 +1,186 @@ +angular-ui-notification +======================= + +[![Dependency Status](https://david-dm.org/alexcrack/angular-ui-notification.png)](https://david-dm.org/alexcrack/angular-ui-notification) +[![devDependency Status](https://david-dm.org/alexcrack/angular-ui-notification/dev-status.png)](https://david-dm.org/alexcrack/angular-ui-notification#info=devDependencies) +[![Build Status](https://travis-ci.org/alexcrack/angular-ui-notification.svg?branch=master)](https://travis-ci.org/alexcrack/angular-ui-notification) +[![Dependency Status](https://www.versioneye.com/user/projects/54f96af44f3108e7800000e4/badge.svg?style=flat)](https://www.versioneye.com/user/projects/54f96af44f3108e7800000e4) +[![Code Climate](https://codeclimate.com/github/alexcrack/angular-ui-notification/badges/gpa.svg)](https://codeclimate.com/github/alexcrack/angular-ui-notification) + +Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animations + +## Features +* No dependencies except of angular.js. +* CSS3 Animations. +* Small size. +* 5 message types. +* Use HTML in your messages. +* Configure options globally py the provider +* Use custom options by the message +* Use custom template + +## Install + +To install the package using bower and save as a dependency use... +```bash +bower install angular-ui-notification --save +``` + +To install via NPM: +```bash +npm install angular-ui-notification --save +``` + +## Usage + [Heres a plunker demo](http://plnkr.co/edit/h08qQF2qlVE3arERpdfi?p=preview) + + +In your html/template add +```html +... + +... + +... + +``` + +In your application, declare dependency injection like so.. + +```javascript + angular.module('notificationTest', ['ui-notification']); +... +``` + +You can configure module by the provider +```javascript +angular.module('notificationTest', ['ui-notification']) + .config(function(NotificationProvider) { + NotificationProvider.setOptions({ + delay: 10000, + startTop: 20, + startRight: 10, + verticalSpacing: 20, + horizontalSpacing: 20, + positionX: 'left', + positionY: 'bottom' + }); + }); +... +``` + + +And when you need to show notifications, inject service and call it! + +```javascript +angular.module('notificationTest').controller('notificationController', function($scope, Notification) { + + Notification.primary('Primary notification'); + // or simply.. + Notification('Primary notification'); + + // Other Options + // Success + Notification.success('Success notification'); + + // Message with custom type + Notification({message: 'Warning notification'}, 'warning'); + + // With Title + Notification({message: 'Primary notification', title: 'Primary notification'}); + + // Message with custom delay + Notification.error({message: 'Error notification 1s', delay: 1000}); + + // Embed HTML within your message..... + Notification.success({message: 'Success notification
Some other content
This is a link
', title: 'Html content'}); + + // Change position notification + Notification.error({message: 'Error Bottom Right', positionY: 'bottom', positionX: 'right'}); + + // Replace message + Notification.error({message: 'Error notification 1s', replaceMessage: true}); +} +``` + +## Service + +Module name: "ui-notification" + +Service: "Notification" + +Configuration provider: "NotificationProvider" + + +## Options + +Options can be passed to configuration provider globally or used in the current message. + +The options list: + +| Option | Possible values | Default value | Description | +| ----------------- | ------------------------- | ------------------------------ | ------------------------------------------------------------------------ | +| delay | Any integer value | 5000 | The time in ms the message is showing before start fading out | +| startTop | Any integer value | 10 | Vertical padding between messages and vertical border of the browser | +| startRight | Any integer value | 10 | Horizontal padding between messages and horizontal border of the browser | +| verticalSpacing | Any integer value | 10 | Vertical spacing between messages | +| horizontalSpacing | Any integer value | 10 | Horizontal spacing between messages | +| positionX | "right", "left", "center" | "right" | Horizontal position of the message | +| positionY | "top", "bottom" | "top" | Vertical position of the message | +| replaceMessage | true, false | false | If true every next appearing message replace old messages | +| templateUrl | Any string | "angular-ui-notification.html" | Custom template filename (URL) | +| onClose | Any function | undefined | Callback to execute when a notification element is closed. Callback receives the element as its argument. | +| closeOnClick | true, false | true | If true, messages are closed on click | +| maxCount | Any integer | 0 | Show only [maxCount] last messages. Old messages will be killed. 0 - do not kill | + +Also you can pass the "scope" option. This is an angular scope option Notification scope will be inherited from. This option can be passed only in the methods. The default value is $rootScope + +## Methods + +#### Notification service methods + +| Method name | Description | +|----------------------------------------|-------------------------------------------------| +| Notification(), Notification.primary() | Show the message with bootstrap's primary class | +| Notification.info() | Show the message with bootstrap's info class | +| Notification.success() | Show the message with bootstrap's success class | +| Notification.warning() | Show the message with bootstrap's warn class | +| Notification.error() | Show the message with bootstrap's danger class | +| Notification.clearAll() | Remove all shown messages | + +#### Notification service options + +| Option | Possible values | Default value | Description | +| -------------- | ------------------------------------------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------ | +| title | *String* | `""` | Title to appear at the top of the notification | +| message | *String* | `""` | Message to appear in the notification | +| templateUrl | *String* | `"angular-ui-notification.html"` | URL of template to be used for notification | +| delay | *Int* (?) | `5000` or configured global delay | Number of ms before notification fades out. If not an integer, notification will persist until killed. | +| type | "primary", "info", "success", "warning", "error" | `"primary"` | Bootstrap flavoring | +| positionY | "top", "bottom" | `"top"` | | +| positionX | "right", "left", "center" | `"right" | | +| replaceMessage | *Boolean* | `false` | If true this message will replace old(er) message(s) | +| closeOnClick | true, false | true | If true, the message is closed on click | + +#### Returning value + +Every "show" method returns a promise that resolves a notification scope with these methods: + +| Method name | Description | +|--------------------------------|------------------------------------------------------------------------------------------------------------------| +| notificationScope.kill(isHard) | Remove the specific message
isHard - if false or omitted kill message with fadeout effect (default). If true - immediately remove the message| + + + +## Custom Templates + +Custom template can be provided. + +```html +
+

+
+
+``` +Default existing scope values is "title" - the title of the message and "message". +Also any custom scope's properties can be used. diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/bower.json b/api-wiaas/client/js/bower_components/angular-ui-notification/bower.json new file mode 100644 index 0000000..e980ed2 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/bower.json @@ -0,0 +1,39 @@ +{ + "name": "angular-ui-notification", + "version": "0.3.5", + "homepage": "https://github.com/alexcrack/angular-ui-notification", + "repository": { + "type": "git", + "url": "git://github.com/jermorin/angular-ui-notification" + }, + "authors": [ + "Alexey Avramchik" + ], + "description": "Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating", + "main": [ + "dist/angular-ui-notification.css", + "dist/angular-ui-notification.js" + ], + "keywords": [ + "angular", + "notification", + "notify", + "bootstrap" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "demo", + "build" + ], + "dependencies": { + "angular": "^1.5.x" + }, + "devDependencies": { + "bootstrap": "^3.3.x" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.css b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.css new file mode 100644 index 0000000..98451ea --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.css @@ -0,0 +1,85 @@ +/** + * angular-ui-notification - Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating + * @author Alex_Crack + * @version v0.3.5 + * @link https://github.com/alexcrack/angular-ui-notification + * @license MIT + */ +.ui-notification +{ + position: fixed; + z-index: 9999; + + width: 300px; + + -webkit-transition: all ease .5s; + -o-transition: all ease .5s; + transition: all ease .5s; + + color: #fff; + border-radius: 0; + background: #337ab7; + box-shadow: 5px 5px 10px rgba(0, 0, 0, .3); +} +.ui-notification.clickable +{ + cursor: pointer; +} +.ui-notification.clickable:hover +{ + opacity: .7; +} +.ui-notification.killed +{ + -webkit-transition: opacity ease 1s; + -o-transition: opacity ease 1s; + transition: opacity ease 1s; + + opacity: 0; +} +.ui-notification > h3 +{ + font-size: 14px; + font-weight: bold; + + display: block; + + margin: 10px 10px 0 10px; + padding: 0 0 5px 0; + + text-align: left; + + border-bottom: 1px solid rgba(255, 255, 255, .3); +} +.ui-notification a +{ + color: #fff; +} +.ui-notification a:hover +{ + text-decoration: underline; +} +.ui-notification > .message +{ + margin: 10px 10px 10px 10px; +} +.ui-notification.warning +{ + color: #fff; + background: #f0ad4e; +} +.ui-notification.error +{ + color: #fff; + background: #d9534f; +} +.ui-notification.success +{ + color: #fff; + background: #5cb85c; +} +.ui-notification.info +{ + color: #fff; + background: #5bc0de; +} diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.js b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.js new file mode 100644 index 0000000..af792dc --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.js @@ -0,0 +1,242 @@ +/** + * angular-ui-notification - Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating + * @author Alex_Crack + * @version v0.3.5 + * @link https://github.com/alexcrack/angular-ui-notification + * @license MIT + */ +angular.module('ui-notification',[]); + +angular.module('ui-notification').provider('Notification', function() { + + this.options = { + delay: 5000, + startTop: 10, + startRight: 10, + verticalSpacing: 10, + horizontalSpacing: 10, + positionX: 'right', + positionY: 'top', + replaceMessage: false, + templateUrl: 'angular-ui-notification.html', + onClose: undefined, + closeOnClick: true, + maxCount: 0, // 0 - Infinite + container: 'body' + }; + + this.setOptions = function(options) { + if (!angular.isObject(options)) throw new Error("Options should be an object!"); + this.options = angular.extend({}, this.options, options); + }; + + this.$get = ["$timeout", "$http", "$compile", "$templateCache", "$rootScope", "$injector", "$sce", "$q", "$window", function($timeout, $http, $compile, $templateCache, $rootScope, $injector, $sce, $q, $window) { + var options = this.options; + + var startTop = options.startTop; + var startRight = options.startRight; + var verticalSpacing = options.verticalSpacing; + var horizontalSpacing = options.horizontalSpacing; + var delay = options.delay; + + var messageElements = []; + var isResizeBound = false; + + var notify = function(args, t){ + var deferred = $q.defer(); + + if (typeof args !== 'object' || args === null) { + args = {message:args}; + } + + args.scope = args.scope ? args.scope : $rootScope; + args.template = args.templateUrl ? args.templateUrl : options.templateUrl; + args.delay = !angular.isUndefined(args.delay) ? args.delay : delay; + args.type = t || args.type || options.type || ''; + args.positionY = args.positionY ? args.positionY : options.positionY; + args.positionX = args.positionX ? args.positionX : options.positionX; + args.replaceMessage = args.replaceMessage ? args.replaceMessage : options.replaceMessage; + args.onClose = args.onClose ? args.onClose : options.onClose; + args.closeOnClick = (args.closeOnClick !== null && args.closeOnClick !== undefined) ? args.closeOnClick : options.closeOnClick; + args.container = args.container ? args.container : options.container; + + var template=$templateCache.get(args.template); + + if(template){ + processNotificationTemplate(template); + }else{ + // load it via $http only if it isn't default template and template isn't exist in template cache + // cache:true means cache it for later access. + $http.get(args.template,{cache: true}) + .then(processNotificationTemplate) + .catch(function(data){ + throw new Error('Template ('+args.template+') could not be loaded. ' + data); + }); + } + + + function processNotificationTemplate(template) { + + var scope = args.scope.$new(); + scope.message = $sce.trustAsHtml(args.message); + scope.title = $sce.trustAsHtml(args.title); + scope.t = args.type.substr(0,1); + scope.delay = args.delay; + scope.onClose = args.onClose; + + var reposite = function() { + var j = 0; + var k = 0; + var lastTop = startTop; + var lastRight = startRight; + var lastPosition = []; + for(var i = messageElements.length - 1; i >= 0; i --) { + var element = messageElements[i]; + if (args.replaceMessage && i < messageElements.length - 1) { + element.addClass('killed'); + continue; + } + var elHeight = parseInt(element[0].offsetHeight); + var elWidth = parseInt(element[0].offsetWidth); + var position = lastPosition[element._positionY+element._positionX]; + + if ((top + elHeight) > window.innerHeight) { + position = startTop; + k ++; + j = 0; + } + + var top = (lastTop = position ? (j === 0 ? position : position + verticalSpacing) : startTop); + var right = lastRight + (k * (horizontalSpacing + elWidth)); + + element.css(element._positionY, top + 'px'); + if (element._positionX == 'center') { + element.css('left', parseInt(window.innerWidth / 2 - elWidth / 2) + 'px'); + } else { + element.css(element._positionX, right + 'px'); + } + + lastPosition[element._positionY+element._positionX] = top + elHeight; + + if (options.maxCount > 0 && messageElements.length > options.maxCount && i === 0) { + element.scope().kill(true); + } + + j ++; + } + }; + + var templateElement = $compile(template)(scope); + templateElement._positionY = args.positionY; + templateElement._positionX = args.positionX; + templateElement.addClass(args.type); + + var closeEvent = function(e) { + e = e.originalEvent || e; + if (e.type === 'click' || (e.propertyName === 'opacity' && e.elapsedTime >= 1)){ + if (scope.onClose) { + scope.$apply(scope.onClose(templateElement)); + } + + templateElement.remove(); + messageElements.splice(messageElements.indexOf(templateElement), 1); + scope.$destroy(); + reposite(); + } + }; + + if (args.closeOnClick) { + templateElement.addClass('clickable'); + templateElement.bind('click', closeEvent); + } + + templateElement.bind('webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd', closeEvent); + + if (angular.isNumber(args.delay)) { + $timeout(function() { + templateElement.addClass('killed'); + }, args.delay); + } + + setCssTransitions('none'); + + angular.element(document.querySelector(args.container)).append(templateElement); + var offset = -(parseInt(templateElement[0].offsetHeight) + 50); + templateElement.css(templateElement._positionY, offset + "px"); + messageElements.push(templateElement); + + if(args.positionX == 'center'){ + var elWidth = parseInt(templateElement[0].offsetWidth); + templateElement.css('left', parseInt(window.innerWidth / 2 - elWidth / 2) + 'px'); + } + + $timeout(function(){ + setCssTransitions(''); + }); + + function setCssTransitions(value){ + ['-webkit-transition', '-o-transition', 'transition'].forEach(function(prefix){ + templateElement.css(prefix, value); + }); + } + + scope._templateElement = templateElement; + + scope.kill = function(isHard) { + if (isHard) { + if (scope.onClose) { + scope.$apply(scope.onClose(scope._templateElement)); + } + + messageElements.splice(messageElements.indexOf(scope._templateElement), 1); + scope._templateElement.remove(); + scope.$destroy(); + $timeout(reposite); + } else { + scope._templateElement.addClass('killed'); + } + }; + + $timeout(reposite); + + if (!isResizeBound) { + angular.element($window).bind('resize', function(e) { + $timeout(reposite); + }); + isResizeBound = true; + } + + deferred.resolve(scope); + + } + + return deferred.promise; + }; + + notify.primary = function(args) { + return this(args, 'primary'); + }; + notify.error = function(args) { + return this(args, 'error'); + }; + notify.success = function(args) { + return this(args, 'success'); + }; + notify.info = function(args) { + return this(args, 'info'); + }; + notify.warning = function(args) { + return this(args, 'warning'); + }; + + notify.clearAll = function() { + angular.forEach(messageElements, function(element) { + element.addClass('killed'); + }); + }; + + return notify; + }]; +}); + +angular.module("ui-notification").run(["$templateCache", function($templateCache) {$templateCache.put("angular-ui-notification.html","

");}]); \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.css b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.css new file mode 100644 index 0000000..a055ef4 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.css @@ -0,0 +1,8 @@ +/** + * angular-ui-notification - Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating + * @author Alex_Crack + * @version v0.3.5 + * @link https://github.com/alexcrack/angular-ui-notification + * @license MIT + */ +.ui-notification{position:fixed;z-index:9999;width:300px;-webkit-transition:all ease .5s;-o-transition:all ease .5s;transition:all ease .5s;color:#fff;border-radius:0;background:#337ab7;box-shadow:5px 5px 10px rgba(0,0,0,.3)}.ui-notification.clickable{cursor:pointer}.ui-notification.clickable:hover{opacity:.7}.ui-notification.killed{-webkit-transition:opacity ease 1s;-o-transition:opacity ease 1s;transition:opacity ease 1s;opacity:0}.ui-notification>h3{font-size:14px;font-weight:700;display:block;margin:10px 10px 0;padding:0 0 5px;text-align:left;border-bottom:1px solid rgba(255,255,255,.3)}.ui-notification a{color:#fff}.ui-notification a:hover{text-decoration:underline}.ui-notification>.message{margin:10px}.ui-notification.warning{color:#fff;background:#f0ad4e}.ui-notification.error{color:#fff;background:#d9534f}.ui-notification.success{color:#fff;background:#5cb85c}.ui-notification.info{color:#fff;background:#5bc0de} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.js b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.js new file mode 100644 index 0000000..7d7e567 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/dist/angular-ui-notification.min.js @@ -0,0 +1,8 @@ +/** + * angular-ui-notification - Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating + * @author Alex_Crack + * @version v0.3.5 + * @link https://github.com/alexcrack/angular-ui-notification + * @license MIT + */ +angular.module("ui-notification",[]),angular.module("ui-notification").provider("Notification",function(){this.options={delay:5e3,startTop:52,startRight:10,verticalSpacing:10,horizontalSpacing:10,positionX:"right",positionY:"top",replaceMessage:!1,templateUrl:"angular-ui-notification.html",onClose:void 0,closeOnClick:!0,maxCount:5,container:"body"},this.setOptions=function(e){if(!angular.isObject(e))throw new Error("Options should be an object!");this.options=angular.extend({},this.options,e)},this.$get=["$timeout","$http","$compile","$templateCache","$rootScope","$injector","$sce","$q","$window",function(e,t,n,i,o,s,a,l,r){var c=this.options,p=c.startTop,d=c.startRight,u=c.verticalSpacing,f=c.horizontalSpacing,m=c.delay,g=[],h=!1,C=function(s,C){function y(t){function i(e){["-webkit-transition","-o-transition","transition"].forEach(function(t){m.css(t,e)})}var o=s.scope.$new();o.message=a.trustAsHtml(s.message),o.title=a.trustAsHtml(s.title),o.t=s.type.substr(0,1),o.delay=s.delay,o.onClose=s.onClose;var l=function(){for(var e=0,t=0,n=p,i=d,o=[],a=g.length-1;a>=0;a--){var l=g[a];if(s.replaceMessage&&awindow.innerHeight&&(h=p,t++,e=0);var C=n=h?0===e?h:h+u:p,y=i+t*(f+m);l.css(l._positionY,C+"px"),"center"==l._positionX?l.css("left",parseInt(window.innerWidth/2-m/2)+"px"):l.css(l._positionX,y+"px"),o[l._positionY+l._positionX]=C+r,c.maxCount>0&&g.length>c.maxCount&&0===a&&l.scope().kill(!0),e++}}},m=n(t)(o);m._positionY=s.positionY,m._positionX=s.positionX,m.addClass(s.type);var C=function(e){e=e.originalEvent||e,("click"===e.type||"opacity"===e.propertyName&&e.elapsedTime>=1)&&(o.onClose&&o.$apply(o.onClose(m)),m.remove(),g.splice(g.indexOf(m),1),o.$destroy(),l())};s.closeOnClick&&(m.addClass("clickable"),m.bind("click",C)),m.bind("webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd",C),angular.isNumber(s.delay)&&e(function(){m.addClass("killed")},s.delay),i("none"),angular.element(document.querySelector(s.container)).append(m);var y=-(parseInt(m[0].offsetHeight)+50);if(m.css(m._positionY,y+"px"),g.push(m),"center"==s.positionX){var k=parseInt(m[0].offsetWidth);m.css("left",parseInt(window.innerWidth/2-k/2)+"px")}e(function(){i("")}),o._templateElement=m,o.kill=function(t){t?(o.onClose&&o.$apply(o.onClose(o._templateElement)),g.splice(g.indexOf(o._templateElement),1),o._templateElement.remove(),o.$destroy(),e(l)):o._templateElement.addClass("killed")},e(l),h||(angular.element(r).bind("resize",function(t){e(l)}),h=!0),v.resolve(o)}var v=l.defer();"object"!=typeof s&&(s={message:s}),s.scope=s.scope?s.scope:o,s.template=s.templateUrl?s.templateUrl:c.templateUrl,s.delay=angular.isUndefined(s.delay)?m:s.delay,s.type=C||s.type||c.type||"",s.positionY=s.positionY?s.positionY:c.positionY,s.positionX=s.positionX?s.positionX:c.positionX,s.replaceMessage=s.replaceMessage?s.replaceMessage:c.replaceMessage,s.onClose=s.onClose?s.onClose:c.onClose,s.closeOnClick=null!==s.closeOnClick&&void 0!==s.closeOnClick?s.closeOnClick:c.closeOnClick,s.container=s.container?s.container:c.container;var k=i.get(s.template);return k?y(k):t.get(s.template,{cache:!0}).then(y)["catch"](function(e){throw new Error("Template ("+s.template+") could not be loaded. "+e)}),v.promise};return C.primary=function(e){return this(e,"primary")},C.error=function(e){return this(e,"error")},C.success=function(e){return this(e,"success")},C.info=function(e){return this(e,"info")},C.warning=function(e){return this(e,"warning")},C.clearAll=function(){angular.forEach(g,function(e){e.addClass("killed")})},C}]}),angular.module("ui-notification").run(["$templateCache",function(e){e.put("angular-ui-notification.html",'

')}]); diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/gulpfile.js b/api-wiaas/client/js/bower_components/angular-ui-notification/gulpfile.js new file mode 100644 index 0000000..5eb3a0f --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/gulpfile.js @@ -0,0 +1,101 @@ +var gulp = require('gulp'); +var less = require('gulp-less'); +var minifyCSS = require('gulp-minify-css'); +var csscomb = require('gulp-csscomb'); +var ngAnnotate = require('gulp-ng-annotate'); +var uglify = require('gulp-uglify'); +var jshint = require('gulp-jshint'); +var rename = require('gulp-rename'); +var header = require('gulp-header'); +var templateCache = require('gulp-angular-templatecache'); +var minifyHtml = require("gulp-minify-html"); +var concat = require('gulp-concat'); +var addsrc = require('gulp-add-src'); +var order = require("gulp-order"); +var protractor = require("gulp-protractor").protractor; + +var pkg = require('./package.json'); +var banner = ['/**', + ' * <%= pkg.name %> - <%= pkg.description %>', + ' * @author <%= pkg.author %>', + ' * @version v<%= pkg.version %>', + ' * @link <%= pkg.homepage %>', + ' * @license <%= pkg.license %>', + ' */', + ''].join('\n'); + + // ==== Styles +gulp.task('styles', function() { + gulp.src('src/build.less') + .pipe(less({ + strictMath: true + })) + .pipe(csscomb()) + .pipe(header(banner, { pkg : pkg })) + .pipe(rename({ + basename: 'angular-ui-notification' + })) + .pipe(gulp.dest('dist')) + .pipe(minifyCSS()) + .pipe(rename({ + suffix: '.min' + })) + .pipe(header(banner, { pkg : pkg })) + .pipe(gulp.dest('dist')) + .pipe(gulp.dest('demo')); +}); + +// ====== Templates +gulp.task('templates', function() { + gulp.src(['*.html'], {cwd: 'src'}) + .pipe(minifyHtml({ + empty: true, + spare: true, + quotes: true + })) + .pipe(templateCache({ + module: 'ui-notification' + })) + .pipe(rename('angular-ui-notification.templates.js')) + .pipe(gulp.dest("build")); +}); + +gulp.task('service', function() { + gulp.src(['src/*.js']) + .pipe(jshint()) + .pipe(jshint.reporter('default')) + .pipe(jshint.reporter('fail')) + .pipe(ngAnnotate()) + .pipe(addsrc('build/*.js')) + .pipe(order([ + 'src/*.js', + 'build/angular-ui-notification.templates.js' + ])) + .pipe(concat('angular-ui-notification.js')) + + .pipe(header(banner, { pkg : pkg })) + .pipe(gulp.dest('dist')) + + .pipe(uglify()) + .pipe(rename({ + suffix: '.min' + })) + .pipe(header(banner, { pkg : pkg })) + .pipe(gulp.dest('dist')) + .pipe(gulp.dest('demo')); +}); + +// ====== +gulp.task('e2eTest', function() { + gulp.src(['./test/**/*_spec.js']) + .pipe(protractor({ + configFile: "protractor_conf.js" + })) + .on('error', function(e) {throw e}); +}); + +gulp.task('tests', ['e2eTest']); +gulp.task('build', ['templates', 'service', 'styles']); +gulp.task('deploy', ['build', 'tests']); + +gulp.task('default', ['deploy'], function() {}); \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/index.js b/api-wiaas/client/js/bower_components/angular-ui-notification/index.js new file mode 100644 index 0000000..bb180c1 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/index.js @@ -0,0 +1,5 @@ +/** + * Created by alex_crack on 20.11.15. + */ +require('./dist/angular-ui-notification.js'); +module.exports = 'ui-notification'; \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/package.json b/api-wiaas/client/js/bower_components/angular-ui-notification/package.json new file mode 100644 index 0000000..44d67a2 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/package.json @@ -0,0 +1,45 @@ +{ + "name": "angular-ui-notification", + "version": "0.3.5", + "description": "Angular.js service providing simple notifications using Bootstrap 3 styles with css transitions for animating", + "main": "index.js", + "scripts": { + "update-chromedriver": "./node_modules/protractor/bin/webdriver-manager update", + "test": "gulp tests" + }, + "repository": { + "type": "git", + "url": "https://github.com/alexcrack/angular-ui-notification.git" + }, + "keywords": [ + "angular", + "notification", + "notify", + "bootstrap" + ], + "author": "Alex_Crack", + "license": "MIT", + "bugs": { + "url": "https://github.com/alexcrack/angular-ui-notification/issues" + }, + "homepage": "https://github.com/alexcrack/angular-ui-notification", + "devDependencies": { + "chromedriver": "^2.14.1", + "gulp": "^3.8.11", + "gulp-add-src": "^0.2.0", + "gulp-angular-templatecache": "^1.5.0", + "gulp-concat": "^2.5.2", + "gulp-csscomb": "^3.0.3", + "gulp-header": "^1.2.2", + "gulp-jshint": "^1.9.2", + "gulp-less": "^3.0.1", + "gulp-minify-css": "^0.5.1", + "gulp-minify-html": "^1.0.0", + "gulp-ng-annotate": "^0.5.2", + "gulp-order": "^1.1.1", + "gulp-protractor": "0.0.12", + "gulp-rename": "^1.2.0", + "gulp-uglify": "^1.1.0", + "protractor": "^1.8.0" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/protractor_conf.js b/api-wiaas/client/js/bower_components/angular-ui-notification/protractor_conf.js new file mode 100644 index 0000000..297274e --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/protractor_conf.js @@ -0,0 +1,24 @@ +// An example configuration file. +exports.config = { + allScriptsTimeout: 99999, + // Do not start a Selenium Standalone sever - only run this using chrome. + //directConnect: true, + //chromeDriver: './node_modules/protractor/selenium/chromedriver', + + seleniumArgs: ['-browserTimeout=60'], + + // Capabilities to be passed to the webdriver instance. + capabilities: { + 'browserName': 'firefox' + }, + + // Spec patterns are relative to the current working directly when + // protractor is called. + specs: ['test/e2e/**/*.spec.js'], + + // Options to be passed to Jasmine-node. + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + } +}; diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.html b/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.html new file mode 100644 index 0000000..5f628fc --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.html @@ -0,0 +1,4 @@ +
+

+
+
\ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.js b/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.js new file mode 100644 index 0000000..44224fa --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.js @@ -0,0 +1,233 @@ +angular.module('ui-notification',[]); + +angular.module('ui-notification').provider('Notification', function() { + + this.options = { + delay: 5000, + startTop: 10, + startRight: 10, + verticalSpacing: 10, + horizontalSpacing: 10, + positionX: 'right', + positionY: 'top', + replaceMessage: false, + templateUrl: 'angular-ui-notification.html', + onClose: undefined, + closeOnClick: true, + maxCount: 0, // 0 - Infinite + container: 'body' + }; + + this.setOptions = function(options) { + if (!angular.isObject(options)) throw new Error("Options should be an object!"); + this.options = angular.extend({}, this.options, options); + }; + + this.$get = function($timeout, $http, $compile, $templateCache, $rootScope, $injector, $sce, $q, $window) { + var options = this.options; + + var startTop = options.startTop; + var startRight = options.startRight; + var verticalSpacing = options.verticalSpacing; + var horizontalSpacing = options.horizontalSpacing; + var delay = options.delay; + + var messageElements = []; + var isResizeBound = false; + + var notify = function(args, t){ + var deferred = $q.defer(); + + if (typeof args !== 'object' || args === null) { + args = {message:args}; + } + + args.scope = args.scope ? args.scope : $rootScope; + args.template = args.templateUrl ? args.templateUrl : options.templateUrl; + args.delay = !angular.isUndefined(args.delay) ? args.delay : delay; + args.type = t || args.type || options.type || ''; + args.positionY = args.positionY ? args.positionY : options.positionY; + args.positionX = args.positionX ? args.positionX : options.positionX; + args.replaceMessage = args.replaceMessage ? args.replaceMessage : options.replaceMessage; + args.onClose = args.onClose ? args.onClose : options.onClose; + args.closeOnClick = (args.closeOnClick !== null && args.closeOnClick !== undefined) ? args.closeOnClick : options.closeOnClick; + args.container = args.container ? args.container : options.container; + + var template=$templateCache.get(args.template); + + if(template){ + processNotificationTemplate(template); + }else{ + // load it via $http only if it isn't default template and template isn't exist in template cache + // cache:true means cache it for later access. + $http.get(args.template,{cache: true}) + .then(processNotificationTemplate) + .catch(function(data){ + throw new Error('Template ('+args.template+') could not be loaded. ' + data); + }); + } + + + function processNotificationTemplate(template) { + + var scope = args.scope.$new(); + scope.message = $sce.trustAsHtml(args.message); + scope.title = $sce.trustAsHtml(args.title); + scope.t = args.type.substr(0,1); + scope.delay = args.delay; + scope.onClose = args.onClose; + + var reposite = function() { + var j = 0; + var k = 0; + var lastTop = startTop; + var lastRight = startRight; + var lastPosition = []; + for(var i = messageElements.length - 1; i >= 0; i --) { + var element = messageElements[i]; + if (args.replaceMessage && i < messageElements.length - 1) { + element.addClass('killed'); + continue; + } + var elHeight = parseInt(element[0].offsetHeight); + var elWidth = parseInt(element[0].offsetWidth); + var position = lastPosition[element._positionY+element._positionX]; + + if ((top + elHeight) > window.innerHeight) { + position = startTop; + k ++; + j = 0; + } + + var top = (lastTop = position ? (j === 0 ? position : position + verticalSpacing) : startTop); + var right = lastRight + (k * (horizontalSpacing + elWidth)); + + element.css(element._positionY, top + 'px'); + if (element._positionX == 'center') { + element.css('left', parseInt(window.innerWidth / 2 - elWidth / 2) + 'px'); + } else { + element.css(element._positionX, right + 'px'); + } + + lastPosition[element._positionY+element._positionX] = top + elHeight; + + if (options.maxCount > 0 && messageElements.length > options.maxCount && i === 0) { + element.scope().kill(true); + } + + j ++; + } + }; + + var templateElement = $compile(template)(scope); + templateElement._positionY = args.positionY; + templateElement._positionX = args.positionX; + templateElement.addClass(args.type); + + var closeEvent = function(e) { + e = e.originalEvent || e; + if (e.type === 'click' || (e.propertyName === 'opacity' && e.elapsedTime >= 1)){ + if (scope.onClose) { + scope.$apply(scope.onClose(templateElement)); + } + + templateElement.remove(); + messageElements.splice(messageElements.indexOf(templateElement), 1); + scope.$destroy(); + reposite(); + } + }; + + if (args.closeOnClick) { + templateElement.addClass('clickable'); + templateElement.bind('click', closeEvent); + } + + templateElement.bind('webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd', closeEvent); + + if (angular.isNumber(args.delay)) { + $timeout(function() { + templateElement.addClass('killed'); + }, args.delay); + } + + setCssTransitions('none'); + + angular.element(document.querySelector(args.container)).append(templateElement); + var offset = -(parseInt(templateElement[0].offsetHeight) + 50); + templateElement.css(templateElement._positionY, offset + "px"); + messageElements.push(templateElement); + + if(args.positionX == 'center'){ + var elWidth = parseInt(templateElement[0].offsetWidth); + templateElement.css('left', parseInt(window.innerWidth / 2 - elWidth / 2) + 'px'); + } + + $timeout(function(){ + setCssTransitions(''); + }); + + function setCssTransitions(value){ + ['-webkit-transition', '-o-transition', 'transition'].forEach(function(prefix){ + templateElement.css(prefix, value); + }); + } + + scope._templateElement = templateElement; + + scope.kill = function(isHard) { + if (isHard) { + if (scope.onClose) { + scope.$apply(scope.onClose(scope._templateElement)); + } + + messageElements.splice(messageElements.indexOf(scope._templateElement), 1); + scope._templateElement.remove(); + scope.$destroy(); + $timeout(reposite); + } else { + scope._templateElement.addClass('killed'); + } + }; + + $timeout(reposite); + + if (!isResizeBound) { + angular.element($window).bind('resize', function(e) { + $timeout(reposite); + }); + isResizeBound = true; + } + + deferred.resolve(scope); + + } + + return deferred.promise; + }; + + notify.primary = function(args) { + return this(args, 'primary'); + }; + notify.error = function(args) { + return this(args, 'error'); + }; + notify.success = function(args) { + return this(args, 'success'); + }; + notify.info = function(args) { + return this(args, 'info'); + }; + notify.warning = function(args) { + return this(args, 'warning'); + }; + + notify.clearAll = function() { + angular.forEach(messageElements, function(element) { + element.addClass('killed'); + }); + }; + + return notify; + }; +}); diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.less b/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.less new file mode 100644 index 0000000..be4e3b0 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/src/angular-ui-notification.less @@ -0,0 +1,57 @@ +@ui-notification-border-radius: 0px; + +.ui-notification { + border-radius: @ui-notification-border-radius; + position: fixed; + z-index: 9999; + box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3); + width: 300px; + color: @btn-primary-color; + background: @brand-primary; + .transition(all ease 0.5s); + &.clickable { + cursor: pointer; + + &:hover { + opacity: 0.7; + } + } + &.killed { + opacity: 0; + .transition(opacity ease 1s); + } + & > h3 { + display: block; + margin: 10px 10px 0 10px; + padding: 0 0 5px 0; + text-align: left; + font-size: @font-size-base; + font-weight: bold; + border-bottom: 1px solid fadeout(@btn-primary-color, 70%); + } + & a { + color: @btn-primary-color; + &:hover { + text-decoration: underline; + } + } + & > .message { + margin: 10px 10px 10px 10px; + } + &.warning { + color: @btn-warning-color; + background: @brand-warning; + } + &.error { + color: @btn-danger-color; + background: @brand-danger; + } + &.success { + color: @btn-success-color; + background: @brand-success; + } + &.info { + color: @btn-info-color; + background: @brand-info; + } +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-notification/src/build.less b/api-wiaas/client/js/bower_components/angular-ui-notification/src/build.less new file mode 100644 index 0000000..0b0f5d5 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-notification/src/build.less @@ -0,0 +1,3 @@ +@import "../bower_components/bootstrap/less/variables.less"; +@import "../bower_components/bootstrap/less/mixins.less"; +@import "angular-ui-notification.less"; diff --git a/api-wiaas/client/js/bower_components/angular-ui-sortable/.bower.json b/api-wiaas/client/js/bower_components/angular-ui-sortable/.bower.json new file mode 100644 index 0000000..3481f71 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-sortable/.bower.json @@ -0,0 +1,23 @@ +{ + "name": "angular-ui-sortable", + "version": "0.17.1", + "main": [ + "./sortable.js" + ], + "dependencies": { + "angular": ">=1.2.x", + "jquery": ">=3.1.x", + "jquery-ui": ">=1.12.x" + }, + "homepage": "https://github.com/angular-ui/ui-sortable", + "_release": "0.17.1", + "_resolution": { + "type": "version", + "tag": "v0.17.1", + "commit": "3168bcc0c83ac63b1791ba5fb21be0b9b2ed18e4" + }, + "_source": "https://github.com/angular-ui/ui-sortable.git", + "_target": "^0.17.1", + "_originalSource": "angular-ui-sortable", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-sortable/.travis.yml b/api-wiaas/client/js/bower_components/angular-ui-sortable/.travis.yml new file mode 100644 index 0000000..8c4c2c4 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-sortable/.travis.yml @@ -0,0 +1,5 @@ +--- +# blacklist the bower branch +branches: + only: + - master diff --git a/api-wiaas/client/js/bower_components/angular-ui-sortable/bower.json b/api-wiaas/client/js/bower_components/angular-ui-sortable/bower.json new file mode 100644 index 0000000..61aea41 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-sortable/bower.json @@ -0,0 +1,10 @@ +{ + "name": "angular-ui-sortable", + "version": "0.17.1", + "main": ["./sortable.js"], + "dependencies": { + "angular": ">=1.2.x", + "jquery": ">=3.1.x", + "jquery-ui": ">=1.12.x" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.js b/api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.js new file mode 100644 index 0000000..f2164c8 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.js @@ -0,0 +1,567 @@ +/** + * angular-ui-sortable - This directive allows you to jQueryUI Sortable. + * @version v0.17.1 - 2017-04-15 + * @link http://angular-ui.github.com + * @license MIT + */ + +(function(window, angular, undefined) { +'use strict'; +/* + jQuery UI Sortable plugin wrapper + + @param [ui-sortable] {object} Options to pass to $.fn.sortable() merged onto ui.config + */ +angular.module('ui.sortable', []) + .value('uiSortableConfig',{ + // the default for jquery-ui sortable is "> *", we need to restrict this to + // ng-repeat items + // if the user uses + items: '> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]' + }) + .directive('uiSortable', [ + 'uiSortableConfig', '$timeout', '$log', + function(uiSortableConfig, $timeout, $log) { + return { + require:'?ngModel', + scope: { + ngModel:'=', + uiSortable:'=', + ////Expression bindings from html. + create:'&uiSortableCreate', + // helper:'&uiSortableHelper', + start:'&uiSortableStart', + activate:'&uiSortableActivate', + // sort:'&uiSortableSort', + // change:'&uiSortableChange', + // over:'&uiSortableOver', + // out:'&uiSortableOut', + beforeStop:'&uiSortableBeforeStop', + update:'&uiSortableUpdate', + remove:'&uiSortableRemove', + receive:'&uiSortableReceive', + deactivate:'&uiSortableDeactivate', + stop:'&uiSortableStop' + }, + link: function(scope, element, attrs, ngModel) { + var savedNodes; + var helper; + + function combineCallbacks(first, second){ + var firstIsFunc = typeof first === 'function'; + var secondIsFunc = typeof second === 'function'; + if(firstIsFunc && secondIsFunc) { + return function() { + first.apply(this, arguments); + second.apply(this, arguments); + }; + } else if (secondIsFunc) { + return second; + } + return first; + } + + function getSortableWidgetInstance(element) { + // this is a fix to support jquery-ui prior to v1.11.x + // otherwise we should be using `element.sortable('instance')` + var data = element.data('ui-sortable'); + if (data && typeof data === 'object' && data.widgetFullName === 'ui-sortable') { + return data; + } + return null; + } + + function patchSortableOption(key, value) { + if (callbacks[key]) { + if( key === 'stop' ){ + // call apply after stop + value = combineCallbacks( + value, function() { scope.$apply(); }); + + value = combineCallbacks(value, afterStop); + } + // wrap the callback + value = combineCallbacks(callbacks[key], value); + } else if (wrappers[key]) { + value = wrappers[key](value); + } + + // patch the options that need to have values set + if (!value && (key === 'items' || key === 'ui-model-items')) { + value = uiSortableConfig.items; + } + + return value; + } + + function patchUISortableOptions(newVal, oldVal, sortableWidgetInstance) { + function addDummyOptionKey(value, key) { + if (!(key in opts)) { + // add the key in the opts object so that + // the patch function detects and handles it + opts[key] = null; + } + } + // for this directive to work we have to attach some callbacks + angular.forEach(callbacks, addDummyOptionKey); + + // only initialize it in case we have to + // update some options of the sortable + var optsDiff = null; + + if (oldVal) { + // reset deleted options to default + var defaultOptions; + angular.forEach(oldVal, function(oldValue, key) { + if (!newVal || !(key in newVal)) { + if (key in directiveOpts) { + if (key === 'ui-floating') { + opts[key] = 'auto'; + } else { + opts[key] = patchSortableOption(key, undefined); + } + return; + } + + if (!defaultOptions) { + defaultOptions = angular.element.ui.sortable().options; + } + var defaultValue = defaultOptions[key]; + defaultValue = patchSortableOption(key, defaultValue); + + if (!optsDiff) { + optsDiff = {}; + } + optsDiff[key] = defaultValue; + opts[key] = defaultValue; + } + }); + } + + // update changed options + angular.forEach(newVal, function(value, key) { + // if it's a custom option of the directive, + // handle it approprietly + if (key in directiveOpts) { + if (key === 'ui-floating' && (value === false || value === true) && sortableWidgetInstance) { + sortableWidgetInstance.floating = value; + } + + opts[key] = patchSortableOption(key, value); + return; + } + + value = patchSortableOption(key, value); + + if (!optsDiff) { + optsDiff = {}; + } + optsDiff[key] = value; + opts[key] = value; + }); + + return optsDiff; + } + + function getPlaceholderElement (element) { + var placeholder = element.sortable('option','placeholder'); + + // placeholder.element will be a function if the placeholder, has + // been created (placeholder will be an object). If it hasn't + // been created, either placeholder will be false if no + // placeholder class was given or placeholder.element will be + // undefined if a class was given (placeholder will be a string) + if (placeholder && placeholder.element && typeof placeholder.element === 'function') { + var result = placeholder.element(); + // workaround for jquery ui 1.9.x, + // not returning jquery collection + result = angular.element(result); + return result; + } + return null; + } + + function getPlaceholderExcludesludes (element, placeholder) { + // exact match with the placeholder's class attribute to handle + // the case that multiple connected sortables exist and + // the placeholder option equals the class of sortable items + var notCssSelector = opts['ui-model-items'].replace(/[^,]*>/g, ''); + var excludes = element.find('[class="' + placeholder.attr('class') + '"]:not(' + notCssSelector + ')'); + return excludes; + } + + function hasSortingHelper (element, ui) { + var helperOption = element.sortable('option','helper'); + return helperOption === 'clone' || (typeof helperOption === 'function' && ui.item.sortable.isCustomHelperUsed()); + } + + function getSortingHelper (element, ui/*, savedNodes*/) { + var result = null; + if (hasSortingHelper(element, ui) && + element.sortable( 'option', 'appendTo' ) === 'parent') { + // The .ui-sortable-helper element (that's the default class name) + result = helper; + } + return result; + } + + // thanks jquery-ui + function isFloating (item) { + return (/left|right/).test(item.css('float')) || (/inline|table-cell/).test(item.css('display')); + } + + function getElementContext(elementScopes, element) { + for (var i = 0; i < elementScopes.length; i++) { + var c = elementScopes[i]; + if (c.element[0] === element[0]) { + return c; + } + } + } + + function afterStop(e, ui) { + ui.item.sortable._destroy(); + } + + // return the index of ui.item among the items + // we can't just do ui.item.index() because there it might have siblings + // which are not items + function getItemIndex(item) { + return item.parent() + .find(opts['ui-model-items']) + .index(item); + } + + var opts = {}; + + // directive specific options + var directiveOpts = { + 'ui-floating': undefined, + 'ui-model-items': uiSortableConfig.items + }; + + var callbacks = { + create: null, + start: null, + activate: null, + // sort: null, + // change: null, + // over: null, + // out: null, + beforeStop: null, + update: null, + remove: null, + receive: null, + deactivate: null, + stop: null + }; + + var wrappers = { + helper: null + }; + + angular.extend(opts, directiveOpts, uiSortableConfig, scope.uiSortable); + + if (!angular.element.fn || !angular.element.fn.jquery) { + $log.error('ui.sortable: jQuery should be included before AngularJS!'); + return; + } + + function wireUp () { + // When we add or remove elements, we need the sortable to 'refresh' + // so it can find the new/removed elements. + scope.$watchCollection('ngModel', function() { + // Timeout to let ng-repeat modify the DOM + $timeout(function() { + // ensure that the jquery-ui-sortable widget instance + // is still bound to the directive's element + if (!!getSortableWidgetInstance(element)) { + element.sortable('refresh'); + } + }, 0, false); + }); + + callbacks.start = function(e, ui) { + if (opts['ui-floating'] === 'auto') { + // since the drag has started, the element will be + // absolutely positioned, so we check its siblings + var siblings = ui.item.siblings(); + var sortableWidgetInstance = getSortableWidgetInstance(angular.element(e.target)); + sortableWidgetInstance.floating = isFloating(siblings); + } + + // Save the starting position of dragged item + var index = getItemIndex(ui.item); + ui.item.sortable = { + model: ngModel.$modelValue[index], + index: index, + source: element, + sourceList: ui.item.parent(), + sourceModel: ngModel.$modelValue, + cancel: function () { + ui.item.sortable._isCanceled = true; + }, + isCanceled: function () { + return ui.item.sortable._isCanceled; + }, + isCustomHelperUsed: function () { + return !!ui.item.sortable._isCustomHelperUsed; + }, + _isCanceled: false, + _isCustomHelperUsed: ui.item.sortable._isCustomHelperUsed, + _destroy: function () { + angular.forEach(ui.item.sortable, function(value, key) { + ui.item.sortable[key] = undefined; + }); + }, + _connectedSortables: [], + _getElementContext: function (element) { + return getElementContext(this._connectedSortables, element); + } + }; + }; + + callbacks.activate = function(e, ui) { + var isSourceContext = ui.item.sortable.source === element; + var savedNodesOrigin = isSourceContext ? + ui.item.sortable.sourceList : + element; + var elementContext = { + element: element, + scope: scope, + isSourceContext: isSourceContext, + savedNodesOrigin: savedNodesOrigin + }; + // save the directive's scope so that it is accessible from ui.item.sortable + ui.item.sortable._connectedSortables.push(elementContext); + + // We need to make a copy of the current element's contents so + // we can restore it after sortable has messed it up. + // This is inside activate (instead of start) in order to save + // both lists when dragging between connected lists. + savedNodes = savedNodesOrigin.contents(); + helper = ui.helper; + + // If this list has a placeholder (the connected lists won't), + // don't inlcude it in saved nodes. + var placeholder = getPlaceholderElement(element); + if (placeholder && placeholder.length) { + var excludes = getPlaceholderExcludesludes(element, placeholder); + savedNodes = savedNodes.not(excludes); + } + }; + + callbacks.update = function(e, ui) { + // Save current drop position but only if this is not a second + // update that happens when moving between lists because then + // the value will be overwritten with the old value + if (!ui.item.sortable.received) { + ui.item.sortable.dropindex = getItemIndex(ui.item); + var droptarget = ui.item.closest('[ui-sortable], [data-ui-sortable], [x-ui-sortable]'); + ui.item.sortable.droptarget = droptarget; + ui.item.sortable.droptargetList = ui.item.parent(); + + var droptargetContext = ui.item.sortable._getElementContext(droptarget); + ui.item.sortable.droptargetModel = droptargetContext.scope.ngModel; + + // Cancel the sort (let ng-repeat do the sort for us) + // Don't cancel if this is the received list because it has + // already been canceled in the other list, and trying to cancel + // here will mess up the DOM. + element.sortable('cancel'); + } + + // Put the nodes back exactly the way they started (this is very + // important because ng-repeat uses comment elements to delineate + // the start and stop of repeat sections and sortable doesn't + // respect their order (even if we cancel, the order of the + // comments are still messed up). + var sortingHelper = !ui.item.sortable.received && getSortingHelper(element, ui, savedNodes); + if (sortingHelper && sortingHelper.length) { + // Restore all the savedNodes except from the sorting helper element. + // That way it will be garbage collected. + savedNodes = savedNodes.not(sortingHelper); + } + var elementContext = ui.item.sortable._getElementContext(element); + savedNodes.appendTo(elementContext.savedNodesOrigin); + + // If this is the target connected list then + // it's safe to clear the restored nodes since: + // update is currently running and + // stop is not called for the target list. + if (ui.item.sortable.received) { + savedNodes = null; + } + + // If received is true (an item was dropped in from another list) + // then we add the new item to this list otherwise wait until the + // stop event where we will know if it was a sort or item was + // moved here from another list + if (ui.item.sortable.received && !ui.item.sortable.isCanceled()) { + scope.$apply(function () { + ngModel.$modelValue.splice(ui.item.sortable.dropindex, 0, + ui.item.sortable.moved); + }); + scope.$emit('ui-sortable:moved', ui); + } + }; + + callbacks.stop = function(e, ui) { + // If the received flag hasn't be set on the item, this is a + // normal sort, if dropindex is set, the item was moved, so move + // the items in the list. + var wasMoved = ('dropindex' in ui.item.sortable) && + !ui.item.sortable.isCanceled(); + + if (wasMoved && !ui.item.sortable.received) { + + scope.$apply(function () { + ngModel.$modelValue.splice( + ui.item.sortable.dropindex, 0, + ngModel.$modelValue.splice(ui.item.sortable.index, 1)[0]); + }); + scope.$emit('ui-sortable:moved', ui); + } else if (!wasMoved && + !angular.equals(element.contents().toArray(), savedNodes.toArray())) { + // if the item was not moved + // and the DOM element order has changed, + // then restore the elements + // so that the ngRepeat's comment are correct. + + var sortingHelper = getSortingHelper(element, ui, savedNodes); + if (sortingHelper && sortingHelper.length) { + // Restore all the savedNodes except from the sorting helper element. + // That way it will be garbage collected. + savedNodes = savedNodes.not(sortingHelper); + } + var elementContext = ui.item.sortable._getElementContext(element); + savedNodes.appendTo(elementContext.savedNodesOrigin); + } + + // It's now safe to clear the savedNodes and helper + // since stop is the last callback. + savedNodes = null; + helper = null; + }; + + callbacks.receive = function(e, ui) { + // An item was dropped here from another list, set a flag on the + // item. + ui.item.sortable.received = true; + }; + + callbacks.remove = function(e, ui) { + // Workaround for a problem observed in nested connected lists. + // There should be an 'update' event before 'remove' when moving + // elements. If the event did not fire, cancel sorting. + if (!('dropindex' in ui.item.sortable)) { + element.sortable('cancel'); + ui.item.sortable.cancel(); + } + + // Remove the item from this list's model and copy data into item, + // so the next list can retrive it + if (!ui.item.sortable.isCanceled()) { + scope.$apply(function () { + ui.item.sortable.moved = ngModel.$modelValue.splice( + ui.item.sortable.index, 1)[0]; + }); + } + }; + + // setup attribute handlers + angular.forEach(callbacks, function(value, key) { + callbacks[key] = combineCallbacks(callbacks[key], + function () { + var attrHandler = scope[key]; + var attrHandlerFn; + if (typeof attrHandler === 'function' && + ('uiSortable' + key.substring(0,1).toUpperCase() + key.substring(1)).length && + typeof (attrHandlerFn = attrHandler()) === 'function') { + attrHandlerFn.apply(this, arguments); + } + }); + }); + + + wrappers.helper = function (inner) { + if (inner && typeof inner === 'function') { + return function (e, item) { + var oldItemSortable = item.sortable; + var index = getItemIndex(item); + item.sortable = { + model: ngModel.$modelValue[index], + index: index, + source: element, + sourceList: item.parent(), + sourceModel: ngModel.$modelValue, + _restore: function () { + angular.forEach(item.sortable, function(value, key) { + item.sortable[key] = undefined; + }); + + item.sortable = oldItemSortable; + } + }; + + var innerResult = inner.apply(this, arguments); + item.sortable._restore(); + item.sortable._isCustomHelperUsed = item !== innerResult; + return innerResult; + }; + } + return inner; + }; + + scope.$watchCollection('uiSortable', function(newVal, oldVal) { + // ensure that the jquery-ui-sortable widget instance + // is still bound to the directive's element + var sortableWidgetInstance = getSortableWidgetInstance(element); + if (!!sortableWidgetInstance) { + var optsDiff = patchUISortableOptions(newVal, oldVal, sortableWidgetInstance); + + if (optsDiff) { + element.sortable('option', optsDiff); + } + } + }, true); + + patchUISortableOptions(opts); + } + + function init () { + if (ngModel) { + wireUp(); + } else { + $log.info('ui.sortable: ngModel not provided!', element); + } + + // Create sortable + element.sortable(opts); + } + + function initIfEnabled () { + if (scope.uiSortable && scope.uiSortable.disabled) { + return false; + } + + init(); + + // Stop Watcher + initIfEnabled.cancelWatcher(); + initIfEnabled.cancelWatcher = angular.noop; + + return true; + } + + initIfEnabled.cancelWatcher = angular.noop; + + if (!initIfEnabled()) { + initIfEnabled.cancelWatcher = scope.$watch('uiSortable.disabled', initIfEnabled); + } + } + }; + } + ]); + +})(window, window.angular); diff --git a/api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.min.js b/api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.min.js new file mode 100644 index 0000000..a7c3a6a --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-sortable/sortable.min.js @@ -0,0 +1,8 @@ +/** + * angular-ui-sortable - This directive allows you to jQueryUI Sortable. + * @version v0.17.1 - 2017-04-15 + * @link http://angular-ui.github.com + * @license MIT + */ + +!function(a,b,c){"use strict";b.module("ui.sortable",[]).value("uiSortableConfig",{items:"> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]"}).directive("uiSortable",["uiSortableConfig","$timeout","$log",function(a,d,e){return{require:"?ngModel",scope:{ngModel:"=",uiSortable:"=",create:"&uiSortableCreate",start:"&uiSortableStart",activate:"&uiSortableActivate",beforeStop:"&uiSortableBeforeStop",update:"&uiSortableUpdate",remove:"&uiSortableRemove",receive:"&uiSortableReceive",deactivate:"&uiSortableDeactivate",stop:"&uiSortableStop"},link:function(f,g,h,i){function j(a,b){var c="function"==typeof a,d="function"==typeof b;return c&&d?function(){a.apply(this,arguments),b.apply(this,arguments)}:d?b:a}function k(a){var b=a.data("ui-sortable");return b&&"object"==typeof b&&"ui-sortable"===b.widgetFullName?b:null}function l(b,c){return C[b]?("stop"===b&&(c=j(c,function(){f.$apply()}),c=j(c,t)),c=j(C[b],c)):D[b]&&(c=D[b](c)),c||"items"!==b&&"ui-model-items"!==b||(c=a.items),c}function m(a,d,e){function f(a,b){b in A||(A[b]=null)}b.forEach(C,f);var g=null;if(d){var h;b.forEach(d,function(d,e){if(!(a&&e in a)){if(e in B)return void("ui-floating"===e?A[e]="auto":A[e]=l(e,c));h||(h=b.element.ui.sortable().options);var f=h[e];f=l(e,f),g||(g={}),g[e]=f,A[e]=f}})}return b.forEach(a,function(a,b){return b in B?("ui-floating"!==b||a!==!1&&a!==!0||!e||(e.floating=a),void(A[b]=l(b,a))):(a=l(b,a),g||(g={}),g[b]=a,void(A[b]=a))}),g}function n(a){var c=a.sortable("option","placeholder");if(c&&c.element&&"function"==typeof c.element){var d=c.element();return d=b.element(d)}return null}function o(a,b){var c=A["ui-model-items"].replace(/[^,]*>/g,""),d=a.find('[class="'+b.attr("class")+'"]:not('+c+")");return d}function p(a,b){var c=a.sortable("option","helper");return"clone"===c||"function"==typeof c&&b.item.sortable.isCustomHelperUsed()}function q(a,b){var c=null;return p(a,b)&&"parent"===a.sortable("option","appendTo")&&(c=z),c}function r(a){return/left|right/.test(a.css("float"))||/inline|table-cell/.test(a.css("display"))}function s(a,b){for(var c=0;c=1.4.0", + "tinymce": "~4.5.1" + }, + "devDependencies": { + "angular-mocks": "~1.4.x" + }, + "_release": "0.0.19", + "_resolution": { + "type": "version", + "tag": "v0.0.19", + "commit": "30434e227768c47cdcf97b552cdbc4f12fad86da" + }, + "_source": "https://github.com/angular-ui/ui-tinymce.git", + "_target": "^0.0.19", + "_originalSource": "angular-ui-tinymce", + "_direct": true +} \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-tinymce/CONTRIBUTING.md b/api-wiaas/client/js/bower_components/angular-ui-tinymce/CONTRIBUTING.md new file mode 100644 index 0000000..258db5b --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-tinymce/CONTRIBUTING.md @@ -0,0 +1,45 @@ +## Got a question or problem? + +Please, do not open issues for the general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on [StackOverflow](http://stackoverflow.com/questions/tagged/angular-ui-tinymce) where maintainers are looking at questions questions tagged with `angular-ui-tinymce`. + +StackOverflow is a much better place to ask questions since: +* there are hundreds of people willing to help on StackOverflow +* questions and answers stay available for public viewing so your question / answer might help someone else +* SO voting system assures that the best answers are prominently visible. + +To save your and our time we will be systematically closing all the issues that are requests for general support and redirecting people to StackOverflow. + +## You think you've found a bug? + +Oh, we are ashamed and want to fix it asap! But before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs we will systematically ask you to provide a _minimal_ reproduce scenario using http://plnkr.co/. Having a live reproduce scenario gives us wealth of important information without going back & forth to you with additional questions like: +* version of AngularJS used +* version of this library that you are using +* 3rd-party libraries used, if any +* and most importantly - a use-case that fails + +A minimal reproduce scenario using http://plnkr.co/ allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem. + +We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often find coding problems themselves while preparing a minimal plunk. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it. + +Unfortunately we are not able to investigate / fix bugs without a minimal reproduce scenario using http://plnkr.co/, so if we don't hear back from you we are going to close an issue that don't have enough info to be reproduced. + + +## You want to contribute some code? + +We are always looking for the quality contributions and will be happy to accept your Pull Requests as long as those adhere to some basic rules: + +* Please open all pull requests against the `master` branch. +* Please assure that you are submitting quality code, specifically make sure that: + * You have accompanying tests and all the tests are passing. See testing below. + * Your PR doesn't break the build; check the Travis-CI build status after opening a PR and push corrective commits if anything goes wrong + * You are using 2 space indentation + * Your commits conform to the conventions established [here](https://github.com/stevemao/conventional-changelog-angular/blob/master/convention.md) + + +## Testing +To run tests: +```bash +$ npm install +$ bower install +$ grunt +``` diff --git a/api-wiaas/client/js/bower_components/angular-ui-tinymce/LICENSE b/api-wiaas/client/js/bower_components/angular-ui-tinymce/LICENSE new file mode 100644 index 0000000..dfc5e0c --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-tinymce/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/api-wiaas/client/js/bower_components/angular-ui-tinymce/README.md b/api-wiaas/client/js/bower_components/angular-ui-tinymce/README.md new file mode 100644 index 0000000..71e562f --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-tinymce/README.md @@ -0,0 +1,150 @@ +# UI Tinymce - [AngularJS](http://angularjs.org/) directive for [TinyMCE](http://tinymce.com). + +[![Build Status](https://travis-ci.org/angular-ui/ui-tinymce.png)](https://travis-ci.org/angular-ui/ui-tinymce) +[![Join the chat at https://gitter.im/angular-ui/ui-tinymce](https://badges.gitter.im/angular-ui/ui-tinymce.svg)](https://gitter.im/angular-ui/ui-tinymce?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +# Call for Maintainer + +This library is looking for a maintainer. If you feel up to the task please open an issue indicating so. + +# Requirements + +- AngularJS 1.4.x or higher and it has been tested with Angular 1.4.8. +- TinyMCE 4 + +# Testing + +We use karma and jshint to ensure the quality of the code. The easiest way to run these checks is to use grunt: +``` +npm install -g grunt-cli +npm install +bower install +grunt +``` + +The karma task will try to open Chrome as a browser in which to run the tests. Make sure this is available or change the configuration in `test\test.config.js` + +# Usage + +We use [bower](http://twitter.github.com/bower/) for dependency management. Add + +``` +dependencies: { +"angular-ui-tinymce": "latest" +} +``` + +To your `bower.json` file. Then run + +``` +bower install +``` + +This will copy the ui-tinymce files into your `components` folder, along with its dependencies. Load the script files in your application: + +```html + + + +``` + +Add the tinymce module as a dependency to your application module: + +```javascript +var myAppModule = angular.module('MyApp', ['ui.tinymce']) +``` + +Apply the directive to your form elements: + +```html +
+ +
+``` + +**Be sure not to set an `id` attribute**. This is because the directive needs to maintain selector knowledge in order to handle buggy behavior in TinyMCE when DOM manipulation is involved, such as in a reordering of HTML through ng-repeat or DOM destruction/recreation through ng-if. + +When using other directives which do DOM manipulation involving elements with `ui-tinymce`, you may need to re-render the editor due to this buggy behavior with TinyMCE. For those situations, it is recommended to use the `$tinymce:refresh` event, which will handle re-rendering the editor to fix this problem. + +## Working with ng-model + +The ui-tinymce directive plays nicely with the ng-model directive such as ng-required. + +If you add the ng-model directive to same the element as ui-tinymce then the text in the editor is automatically synchronized with the model value. + +_The ui-tinymce directive stores the configuration options as specified in the [TinyMCE documentation](http://www.tinymce.com/wiki.php/Configuration) and expects the model value to be a html string or raw text, depending on whether `raw` is `true` (default value is `false`)._ + +**Note:** Make sure you using scopes correctly by following [this wiki page](https://github.com/angular/angular.js/wiki/Understanding-Scopes). If you are having issues with your model not updating, make sure you have a '.' in your model. + +> This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch. + +## Options + +The directive supports all of the standard TinyMCE initialization options as listed [here](http://www.tinymce.com/wiki.php/Configuration). + +Use the [setup](https://www.tinymce.com/docs/configure/integration-and-setup/#setup) function to bind different events: + +```javascript +scope.tinymceOptions = { + setup: function(editor) { + //Focus the editor on load + $timeout(function(){ editor.focus(); }); + editor.on("init", function() { + ... + }); + editor.on("click", function() { + ... + }); + } +}; +``` +By default all TinyMCE content that is set to `ngModel` will be whitelisted by `$sce`. + +In addition, it supports these additional optional options + +- `format` Format to get content as, i.e. 'raw' for raw HTML, or 'text' for text only. Defaults to 'html'. Documentation [here](http://www.tinymce.com/wiki.php/api4:method.tinymce.Editor.getContent) +- `baseURL` This will set [baseURL property on the EditorManager](https://www.tinymce.com/docs/api/class/tinymce.editormanager/) +- `debounce` This will debounce the model update which helps with performance of editors with large text. Defaults to true. + +This option is only supported when present on the `uiTinymceConfig` global injectable - this injectable needs to be an object. + +- `baseUrl` Sets the base url used by tinymce asset loading + +```javascript +myAppModule.controller('MyController', function($scope) { + $scope.tinymceOptions = { + onChange: function(e) { + // put logic here for keypress and cut/paste changes + }, + inline: false, + plugins : 'advlist autolink link image lists charmap print preview', + skin: 'lightgray', + theme : 'modern' + }; +}); +``` +```html +
+ +
+``` + +## Testing your Application (Protractor) + +If you are testing your application using Protractor and you wish to be able to automate the +contribution of rich text content as part of the tests, use the TinyMCE API method `insertContent` +in conjunction with the WebDriver's `executeScript` method, like this: + +```javascript +browser.driver.executeScript("tinyMCE.activeEditor.insertContent('This is RICH content')"); +``` + +Note that if you use the TinyMCE API method `setContent`, this will fail to update the Angular model +with the entered content, so use `insertContent` instead. + +---- + + +# Contributing to the project + +We are always looking for the quality contributions! Please check the [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution guidelines. diff --git a/api-wiaas/client/js/bower_components/angular-ui-tinymce/bower.json b/api-wiaas/client/js/bower_components/angular-ui-tinymce/bower.json new file mode 100644 index 0000000..d4a142a --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-tinymce/bower.json @@ -0,0 +1,25 @@ +{ + "name": "angular-ui-tinymce", + "version": "0.0.18", + "description": "This directive allows you to TinyMCE in your form.", + "author": "https://github.com/angular-ui/ui-tinymce/graphs/contributors", + "license": "MIT", + "homepage": "http://angular-ui.github.com", + "main": "./src/tinymce.js", + "ignore": [ + "**/.*", + "node_modules", + "components", + "test*", + "demo*", + "gruntFile.js", + "package.json" + ], + "dependencies": { + "angular": ">=1.4.0", + "tinymce": "~4.5.1" + }, + "devDependencies": { + "angular-mocks": "~1.4.x" + } +} diff --git a/api-wiaas/client/js/bower_components/angular-ui-tinymce/dist/tinymce.min.js b/api-wiaas/client/js/bower_components/angular-ui-tinymce/dist/tinymce.min.js new file mode 100644 index 0000000..cd6b161 --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-tinymce/dist/tinymce.min.js @@ -0,0 +1 @@ +angular.module("ui.tinymce",[]).value("uiTinymceConfig",{}).directive("uiTinymce",["$rootScope","$compile","$timeout","$window","$sce","uiTinymceConfig","uiTinymceService",function(a,b,c,d,e,f,g){return f=f||{},f.baseUrl&&(tinymce.baseURL=f.baseUrl),{require:["ngModel","^?form"],priority:599,link:function(h,i,j,k){function l(a){a?(m(),o&&o.getBody().setAttribute("contenteditable",!1)):(m(),o&&!o.settings.readonly&&o.getDoc()&&o.getBody().setAttribute("contenteditable",!0))}function m(){o||(o=tinymce.get(j.id))}if(d.tinymce){var n,o,p=k[0],q=k[1]||null,r={debounce:!0},s=function(b){var c=b.getContent({format:r.format}).trim();c=e.trustAsHtml(c),p.$setViewValue(c),a.$$phase||h.$digest()},t=g.getUniqueId();j.$set("id",t),n={},angular.extend(n,h.$eval(j.uiTinymce));var u=function(a){var b;return function(d){c.cancel(b),b=c(function(){return function(a){a.isDirty()&&(a.save(),s(a))}(d)},a)}}(400),v={setup:function(b){b.on("init",function(){p.$render(),p.$setPristine(),p.$setUntouched(),q&&q.$setPristine()}),b.on("ExecCommand change NodeChange ObjectResized",function(){return r.debounce?void u(b):(b.save(),void s(b))}),b.on("blur",function(){i[0].blur(),p.$setTouched(),a.$$phase||h.$digest()}),b.on("remove",function(){i.remove()}),f.setup&&f.setup(b,{updateView:s}),n.setup&&n.setup(b,{updateView:s})},format:n.format||"html",selector:"#"+j.id};angular.extend(r,f,n,v),c(function(){r.baseURL&&(tinymce.baseURL=r.baseURL);var a=tinymce.init(r);a&&"function"==typeof a.then?a.then(function(){l(h.$eval(j.ngDisabled))}):l(h.$eval(j.ngDisabled))}),p.$formatters.unshift(function(a){return a?e.trustAsHtml(a):""}),p.$parsers.unshift(function(a){return a?e.getTrustedHtml(a):""}),p.$render=function(){m();var a=p.$viewValue?e.getTrustedHtml(p.$viewValue):"";o&&o.getDoc()&&(o.setContent(a),o.fire("change"))},j.$observe("disabled",l),h.$on("$tinymce:refresh",function(a,c){var d=j.id;if(angular.isUndefined(c)||c===d){var e=i.parent(),f=i.clone();f.removeAttr("id"),f.removeAttr("style"),f.removeAttr("aria-hidden"),tinymce.execCommand("mceRemoveEditor",!1,d),e.append(b(f)(h))}}),h.$on("$destroy",function(){m(),o&&(o.remove(),o=null)})}}}}]).service("uiTinymceService",[function(){var a=function(){var a="ui-tinymce",b=0,c=function(){return b++,a+"-"+b};return{getUniqueId:c}};return new a}]); \ No newline at end of file diff --git a/api-wiaas/client/js/bower_components/angular-ui-tinymce/src/tinymce.js b/api-wiaas/client/js/bower_components/angular-ui-tinymce/src/tinymce.js new file mode 100644 index 0000000..e51b7af --- /dev/null +++ b/api-wiaas/client/js/bower_components/angular-ui-tinymce/src/tinymce.js @@ -0,0 +1,235 @@ +/** + * Binds a TinyMCE widget to
+
+ + + + it('should auto compile', function() { + var textarea = $('textarea'); + var output = $('div[compile]'); + // The initial state reads 'Hello Angular'. + expect(output.getText()).toBe('Hello Angular'); + textarea.clear(); + textarea.sendKeys('{{name}}!'); + expect(output.getText()).toBe('Angular!'); + }); + + + + * + * + * @param {string|DOMElement} element Element or HTML string to compile into a template function. + * @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED. + * + *
+ * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it + * e.g. will not use the right outer scope. Please pass the transclude function as a + * `parentBoundTranscludeFn` to the link function instead. + *
+ * + * @param {number} maxPriority only apply directives lower than given priority (Only effects the + * root element(s), not their children) + * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template + * (a DOM element/tree) to a scope. Where: + * + * * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to. + * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the + * `template` and call the `cloneAttachFn` function allowing the caller to attach the + * cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is + * called as:
`cloneAttachFn(clonedElement, scope)` where: + * + * * `clonedElement` - is a clone of the original `element` passed into the compiler. + * * `scope` - is the current scope with which the linking function is working with. + * + * * `options` - An optional object hash with linking options. If `options` is provided, then the following + * keys may be used to control linking behavior: + * + * * `parentBoundTranscludeFn` - the transclude function made available to + * directives; if given, it will be passed through to the link functions of + * directives found in `element` during compilation. + * * `transcludeControllers` - an object hash with keys that map controller names + * to a hash with the key `instance`, which maps to the controller instance; + * if given, it will make the controllers available to directives on the compileNode: + * ``` + * { + * parent: { + * instance: parentControllerInstance + * } + * } + * ``` + * * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add + * the cloned elements; only needed for transcludes that are allowed to contain non html + * elements (e.g. SVG elements). See also the directive.controller property. + * + * Calling the linking function returns the element of the template. It is either the original + * element passed in, or the clone of the element if the `cloneAttachFn` is provided. + * + * After linking the view is not updated until after a call to $digest which typically is done by + * Angular automatically. + * + * If you need access to the bound view, there are two ways to do it: + * + * - If you are not asking the linking function to clone the template, create the DOM element(s) + * before you send them to the compiler and keep this reference around. + * ```js + * var element = $compile('

{{total}}

')(scope); + * ``` + * + * - if on the other hand, you need the element to be cloned, the view reference from the original + * example would not point to the clone, but rather to the original template that was cloned. In + * this case, you can access the clone via the cloneAttachFn: + * ```js + * var templateElement = angular.element('

{{total}}

'), + * scope = ....; + * + * var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) { + * //attach the clone to DOM document at the right place + * }); + * + * //now we have reference to the cloned DOM via `clonedElement` + * ``` + * + * + * For information on how the compiler works, see the + * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide. + * + * @knownIssue + * + * ### Double Compilation + * + Double compilation occurs when an already compiled part of the DOM gets + compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues, + and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it + section on double compilation} for an in-depth explanation and ways to avoid it. + * + */ + +var $compileMinErr = minErr('$compile'); + +function UNINITIALIZED_VALUE() {} +var _UNINITIALIZED_VALUE = new UNINITIALIZED_VALUE(); + +/** + * @ngdoc provider + * @name $compileProvider + * + * @description + */ +$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider']; +/** @this */ +function $CompileProvider($provide, $$sanitizeUriProvider) { + var hasDirectives = {}, + Suffix = 'Directive', + COMMENT_DIRECTIVE_REGEXP = /^\s*directive:\s*([\w-]+)\s+(.*)$/, + CLASS_DIRECTIVE_REGEXP = /(([\w-]+)(?::([^;]+))?;?)/, + ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'), + REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/; + + // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes + // The assumption is that future DOM event attribute names will begin with + // 'on' and be composed of only English letters. + var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/; + var bindingCache = createMap(); + + function parseIsolateBindings(scope, directiveName, isController) { + var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/; + + var bindings = createMap(); + + forEach(scope, function(definition, scopeName) { + if (definition in bindingCache) { + bindings[scopeName] = bindingCache[definition]; + return; + } + var match = definition.match(LOCAL_REGEXP); + + if (!match) { + throw $compileMinErr('iscp', + 'Invalid {3} for directive \'{0}\'.' + + ' Definition: {... {1}: \'{2}\' ...}', + directiveName, scopeName, definition, + (isController ? 'controller bindings definition' : + 'isolate scope definition')); + } + + bindings[scopeName] = { + mode: match[1][0], + collection: match[2] === '*', + optional: match[3] === '?', + attrName: match[4] || scopeName + }; + if (match[4]) { + bindingCache[definition] = bindings[scopeName]; + } + }); + + return bindings; + } + + function parseDirectiveBindings(directive, directiveName) { + var bindings = { + isolateScope: null, + bindToController: null + }; + if (isObject(directive.scope)) { + if (directive.bindToController === true) { + bindings.bindToController = parseIsolateBindings(directive.scope, + directiveName, true); + bindings.isolateScope = {}; + } else { + bindings.isolateScope = parseIsolateBindings(directive.scope, + directiveName, false); + } + } + if (isObject(directive.bindToController)) { + bindings.bindToController = + parseIsolateBindings(directive.bindToController, directiveName, true); + } + if (bindings.bindToController && !directive.controller) { + // There is no controller + throw $compileMinErr('noctrl', + 'Cannot bind to controller without directive \'{0}\'s controller.', + directiveName); + } + return bindings; + } + + function assertValidDirectiveName(name) { + var letter = name.charAt(0); + if (!letter || letter !== lowercase(letter)) { + throw $compileMinErr('baddir', 'Directive/Component name \'{0}\' is invalid. The first character must be a lowercase letter', name); + } + if (name !== name.trim()) { + throw $compileMinErr('baddir', + 'Directive/Component name \'{0}\' is invalid. The name should not contain leading or trailing whitespaces', + name); + } + } + + function getDirectiveRequire(directive) { + var require = directive.require || (directive.controller && directive.name); + + if (!isArray(require) && isObject(require)) { + forEach(require, function(value, key) { + var match = value.match(REQUIRE_PREFIX_REGEXP); + var name = value.substring(match[0].length); + if (!name) require[key] = match[0] + key; + }); + } + + return require; + } + + function getDirectiveRestrict(restrict, name) { + if (restrict && !(isString(restrict) && /[EACM]/.test(restrict))) { + throw $compileMinErr('badrestrict', + 'Restrict property \'{0}\' of directive \'{1}\' is invalid', + restrict, + name); + } + + return restrict || 'EA'; + } + + /** + * @ngdoc method + * @name $compileProvider#directive + * @kind function + * + * @description + * Register a new directive with the compiler. + * + * @param {string|Object} name Name of the directive in camel-case (i.e. ngBind which + * will match as ng-bind), or an object map of directives where the keys are the + * names and the values are the factories. + * @param {Function|Array} directiveFactory An injectable directive factory function. See the + * {@link guide/directive directive guide} and the {@link $compile compile API} for more info. + * @returns {ng.$compileProvider} Self for chaining. + */ + this.directive = function registerDirective(name, directiveFactory) { + assertArg(name, 'name'); + assertNotHasOwnProperty(name, 'directive'); + if (isString(name)) { + assertValidDirectiveName(name); + assertArg(directiveFactory, 'directiveFactory'); + if (!hasDirectives.hasOwnProperty(name)) { + hasDirectives[name] = []; + $provide.factory(name + Suffix, ['$injector', '$exceptionHandler', + function($injector, $exceptionHandler) { + var directives = []; + forEach(hasDirectives[name], function(directiveFactory, index) { + try { + var directive = $injector.invoke(directiveFactory); + if (isFunction(directive)) { + directive = { compile: valueFn(directive) }; + } else if (!directive.compile && directive.link) { + directive.compile = valueFn(directive.link); + } + directive.priority = directive.priority || 0; + directive.index = index; + directive.name = directive.name || name; + directive.require = getDirectiveRequire(directive); + directive.restrict = getDirectiveRestrict(directive.restrict, name); + directive.$$moduleName = directiveFactory.$$moduleName; + directives.push(directive); + } catch (e) { + $exceptionHandler(e); + } + }); + return directives; + }]); + } + hasDirectives[name].push(directiveFactory); + } else { + forEach(name, reverseParams(registerDirective)); + } + return this; + }; + + /** + * @ngdoc method + * @name $compileProvider#component + * @module ng + * @param {string} name Name of the component in camelCase (i.e. `myComp` which will match ``) + * @param {Object} options Component definition object (a simplified + * {@link ng.$compile#directive-definition-object directive definition object}), + * with the following properties (all optional): + * + * - `controller` – `{(string|function()=}` – controller constructor function that should be + * associated with newly created scope or the name of a {@link ng.$compile#-controller- + * registered controller} if passed as a string. An empty `noop` function by default. + * - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope. + * If present, the controller will be published to scope under the `controllerAs` name. + * If not present, this will default to be `$ctrl`. + * - `template` – `{string=|function()=}` – html template as a string or a function that + * returns an html template as a string which should be used as the contents of this component. + * Empty string by default. + * + * If `template` is a function, then it is {@link auto.$injector#invoke injected} with + * the following locals: + * + * - `$element` - Current element + * - `$attrs` - Current attributes object for the element + * + * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html + * template that should be used as the contents of this component. + * + * If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with + * the following locals: + * + * - `$element` - Current element + * - `$attrs` - Current attributes object for the element + * + * - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties. + * Component properties are always bound to the component controller and not to the scope. + * See {@link ng.$compile#-bindtocontroller- `bindToController`}. + * - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled. + * Disabled by default. + * - `require` - `{Object=}` - requires the controllers of other directives and binds them to + * this component's controller. The object keys specify the property names under which the required + * controllers (object values) will be bound. See {@link ng.$compile#-require- `require`}. + * - `$...` – additional properties to attach to the directive factory function and the controller + * constructor function. (This is used by the component router to annotate) + * + * @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls. + * @description + * Register a **component definition** with the compiler. This is a shorthand for registering a special + * type of directive, which represents a self-contained UI component in your application. Such components + * are always isolated (i.e. `scope: {}`) and are always restricted to elements (i.e. `restrict: 'E'`). + * + * Component definitions are very simple and do not require as much configuration as defining general + * directives. Component definitions usually consist only of a template and a controller backing it. + * + * In order to make the definition easier, components enforce best practices like use of `controllerAs`, + * `bindToController`. They always have **isolate scope** and are restricted to elements. + * + * Here are a few examples of how you would usually define components: + * + * ```js + * var myMod = angular.module(...); + * myMod.component('myComp', { + * template: '
My name is {{$ctrl.name}}
', + * controller: function() { + * this.name = 'shahar'; + * } + * }); + * + * myMod.component('myComp', { + * template: '
My name is {{$ctrl.name}}
', + * bindings: {name: '@'} + * }); + * + * myMod.component('myComp', { + * templateUrl: 'views/my-comp.html', + * controller: 'MyCtrl', + * controllerAs: 'ctrl', + * bindings: {name: '@'} + * }); + * + * ``` + * For more examples, and an in-depth guide, see the {@link guide/component component guide}. + * + *
+ * See also {@link ng.$compileProvider#directive $compileProvider.directive()}. + */ + this.component = function registerComponent(name, options) { + var controller = options.controller || function() {}; + + function factory($injector) { + function makeInjectable(fn) { + if (isFunction(fn) || isArray(fn)) { + return /** @this */ function(tElement, tAttrs) { + return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs}); + }; + } else { + return fn; + } + } + + var template = (!options.template && !options.templateUrl ? '' : options.template); + var ddo = { + controller: controller, + controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl', + template: makeInjectable(template), + templateUrl: makeInjectable(options.templateUrl), + transclude: options.transclude, + scope: {}, + bindToController: options.bindings || {}, + restrict: 'E', + require: options.require + }; + + // Copy annotations (starting with $) over to the DDO + forEach(options, function(val, key) { + if (key.charAt(0) === '$') ddo[key] = val; + }); + + return ddo; + } + + // TODO(pete) remove the following `forEach` before we release 1.6.0 + // The component-router@0.2.0 looks for the annotations on the controller constructor + // Nothing in Angular looks for annotations on the factory function but we can't remove + // it from 1.5.x yet. + + // Copy any annotation properties (starting with $) over to the factory and controller constructor functions + // These could be used by libraries such as the new component router + forEach(options, function(val, key) { + if (key.charAt(0) === '$') { + factory[key] = val; + // Don't try to copy over annotations to named controller + if (isFunction(controller)) controller[key] = val; + } + }); + + factory.$inject = ['$injector']; + + return this.directive(name, factory); + }; + + + /** + * @ngdoc method + * @name $compileProvider#aHrefSanitizationWhitelist + * @kind function + * + * @description + * Retrieves or overrides the default regular expression that is used for whitelisting of safe + * urls during a[href] sanitization. + * + * The sanitization is a security measure aimed at preventing XSS attacks via html links. + * + * Any url about to be assigned to a[href] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * + * @param {RegExp=} regexp New regexp to whitelist urls with. + * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for + * chaining otherwise. + */ + this.aHrefSanitizationWhitelist = function(regexp) { + if (isDefined(regexp)) { + $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp); + return this; + } else { + return $$sanitizeUriProvider.aHrefSanitizationWhitelist(); + } + }; + + + /** + * @ngdoc method + * @name $compileProvider#imgSrcSanitizationWhitelist + * @kind function + * + * @description + * Retrieves or overrides the default regular expression that is used for whitelisting of safe + * urls during img[src] sanitization. + * + * The sanitization is a security measure aimed at prevent XSS attacks via html links. + * + * Any url about to be assigned to img[src] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * + * @param {RegExp=} regexp New regexp to whitelist urls with. + * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for + * chaining otherwise. + */ + this.imgSrcSanitizationWhitelist = function(regexp) { + if (isDefined(regexp)) { + $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp); + return this; + } else { + return $$sanitizeUriProvider.imgSrcSanitizationWhitelist(); + } + }; + + /** + * @ngdoc method + * @name $compileProvider#debugInfoEnabled + * + * @param {boolean=} enabled update the debugInfoEnabled state if provided, otherwise just return the + * current debugInfoEnabled state + * @returns {*} current value if used as getter or itself (chaining) if used as setter + * + * @kind function + * + * @description + * Call this method to enable/disable various debug runtime information in the compiler such as adding + * binding information and a reference to the current scope on to DOM elements. + * If enabled, the compiler will add the following to DOM elements that have been bound to the scope + * * `ng-binding` CSS class + * * `$binding` data property containing an array of the binding expressions + * + * You may want to disable this in production for a significant performance boost. See + * {@link guide/production#disabling-debug-data Disabling Debug Data} for more. + * + * The default value is true. + */ + var debugInfoEnabled = true; + this.debugInfoEnabled = function(enabled) { + if (isDefined(enabled)) { + debugInfoEnabled = enabled; + return this; + } + return debugInfoEnabled; + }; + + /** + * @ngdoc method + * @name $compileProvider#preAssignBindingsEnabled + * + * @param {boolean=} enabled update the preAssignBindingsEnabled state if provided, otherwise just return the + * current preAssignBindingsEnabled state + * @returns {*} current value if used as getter or itself (chaining) if used as setter + * + * @kind function + * + * @description + * Call this method to enable/disable whether directive controllers are assigned bindings before + * calling the controller's constructor. + * If enabled (true), the compiler assigns the value of each of the bindings to the + * properties of the controller object before the constructor of this object is called. + * + * If disabled (false), the compiler calls the constructor first before assigning bindings. + * + * The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x. + */ + var preAssignBindingsEnabled = false; + this.preAssignBindingsEnabled = function(enabled) { + if (isDefined(enabled)) { + preAssignBindingsEnabled = enabled; + return this; + } + return preAssignBindingsEnabled; + }; + + + var TTL = 10; + /** + * @ngdoc method + * @name $compileProvider#onChangesTtl + * @description + * + * Sets the number of times `$onChanges` hooks can trigger new changes before giving up and + * assuming that the model is unstable. + * + * The current default is 10 iterations. + * + * In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result + * in several iterations of calls to these hooks. However if an application needs more than the default 10 + * iterations to stabilize then you should investigate what is causing the model to continuously change during + * the `$onChanges` hook execution. + * + * Increasing the TTL could have performance implications, so you should not change it without proper justification. + * + * @param {number} limit The number of `$onChanges` hook iterations. + * @returns {number|object} the current limit (or `this` if called as a setter for chaining) + */ + this.onChangesTtl = function(value) { + if (arguments.length) { + TTL = value; + return this; + } + return TTL; + }; + + var commentDirectivesEnabledConfig = true; + /** + * @ngdoc method + * @name $compileProvider#commentDirectivesEnabled + * @description + * + * It indicates to the compiler + * whether or not directives on comments should be compiled. + * Defaults to `true`. + * + * Calling this function with false disables the compilation of directives + * on comments for the whole application. + * This results in a compilation performance gain, + * as the compiler doesn't have to check comments when looking for directives. + * This should however only be used if you are sure that no comment directives are used in + * the application (including any 3rd party directives). + * + * @param {boolean} enabled `false` if the compiler may ignore directives on comments + * @returns {boolean|object} the current value (or `this` if called as a setter for chaining) + */ + this.commentDirectivesEnabled = function(value) { + if (arguments.length) { + commentDirectivesEnabledConfig = value; + return this; + } + return commentDirectivesEnabledConfig; + }; + + + var cssClassDirectivesEnabledConfig = true; + /** + * @ngdoc method + * @name $compileProvider#cssClassDirectivesEnabled + * @description + * + * It indicates to the compiler + * whether or not directives on element classes should be compiled. + * Defaults to `true`. + * + * Calling this function with false disables the compilation of directives + * on element classes for the whole application. + * This results in a compilation performance gain, + * as the compiler doesn't have to check element classes when looking for directives. + * This should however only be used if you are sure that no class directives are used in + * the application (including any 3rd party directives). + * + * @param {boolean} enabled `false` if the compiler may ignore directives on element classes + * @returns {boolean|object} the current value (or `this` if called as a setter for chaining) + */ + this.cssClassDirectivesEnabled = function(value) { + if (arguments.length) { + cssClassDirectivesEnabledConfig = value; + return this; + } + return cssClassDirectivesEnabledConfig; + }; + + this.$get = [ + '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse', + '$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri', + function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse, + $controller, $rootScope, $sce, $animate, $$sanitizeUri) { + + var SIMPLE_ATTR_NAME = /^\w/; + var specialAttrHolder = window.document.createElement('div'); + + + var commentDirectivesEnabled = commentDirectivesEnabledConfig; + var cssClassDirectivesEnabled = cssClassDirectivesEnabledConfig; + + + var onChangesTtl = TTL; + // The onChanges hooks should all be run together in a single digest + // When changes occur, the call to trigger their hooks will be added to this queue + var onChangesQueue; + + // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest + function flushOnChangesQueue() { + try { + if (!(--onChangesTtl)) { + // We have hit the TTL limit so reset everything + onChangesQueue = undefined; + throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\n', TTL); + } + // We must run this hook in an apply since the $$postDigest runs outside apply + $rootScope.$apply(function() { + var errors = []; + for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) { + try { + onChangesQueue[i](); + } catch (e) { + errors.push(e); + } + } + // Reset the queue to trigger a new schedule next time there is a change + onChangesQueue = undefined; + if (errors.length) { + throw errors; + } + }); + } finally { + onChangesTtl++; + } + } + + + function Attributes(element, attributesToCopy) { + if (attributesToCopy) { + var keys = Object.keys(attributesToCopy); + var i, l, key; + + for (i = 0, l = keys.length; i < l; i++) { + key = keys[i]; + this[key] = attributesToCopy[key]; + } + } else { + this.$attr = {}; + } + + this.$$element = element; + } + + Attributes.prototype = { + /** + * @ngdoc method + * @name $compile.directive.Attributes#$normalize + * @kind function + * + * @description + * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or + * `data-`) to its normalized, camelCase form. + * + * Also there is special case for Moz prefix starting with upper case letter. + * + * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives} + * + * @param {string} name Name to normalize + */ + $normalize: directiveNormalize, + + + /** + * @ngdoc method + * @name $compile.directive.Attributes#$addClass + * @kind function + * + * @description + * Adds the CSS class value specified by the classVal parameter to the element. If animations + * are enabled then an animation will be triggered for the class addition. + * + * @param {string} classVal The className value that will be added to the element + */ + $addClass: function(classVal) { + if (classVal && classVal.length > 0) { + $animate.addClass(this.$$element, classVal); + } + }, + + /** + * @ngdoc method + * @name $compile.directive.Attributes#$removeClass + * @kind function + * + * @description + * Removes the CSS class value specified by the classVal parameter from the element. If + * animations are enabled then an animation will be triggered for the class removal. + * + * @param {string} classVal The className value that will be removed from the element + */ + $removeClass: function(classVal) { + if (classVal && classVal.length > 0) { + $animate.removeClass(this.$$element, classVal); + } + }, + + /** + * @ngdoc method + * @name $compile.directive.Attributes#$updateClass + * @kind function + * + * @description + * Adds and removes the appropriate CSS class values to the element based on the difference + * between the new and old CSS class values (specified as newClasses and oldClasses). + * + * @param {string} newClasses The current CSS className value + * @param {string} oldClasses The former CSS className value + */ + $updateClass: function(newClasses, oldClasses) { + var toAdd = tokenDifference(newClasses, oldClasses); + if (toAdd && toAdd.length) { + $animate.addClass(this.$$element, toAdd); + } + + var toRemove = tokenDifference(oldClasses, newClasses); + if (toRemove && toRemove.length) { + $animate.removeClass(this.$$element, toRemove); + } + }, + + /** + * Set a normalized attribute on the element in a way such that all directives + * can share the attribute. This function properly handles boolean attributes. + * @param {string} key Normalized key. (ie ngAttribute) + * @param {string|boolean} value The value to set. If `null` attribute will be deleted. + * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute. + * Defaults to true. + * @param {string=} attrName Optional none normalized name. Defaults to key. + */ + $set: function(key, value, writeAttr, attrName) { + // TODO: decide whether or not to throw an error if "class" + //is set through this function since it may cause $updateClass to + //become unstable. + + var node = this.$$element[0], + booleanKey = getBooleanAttrName(node, key), + aliasedKey = getAliasedAttrName(key), + observer = key, + nodeName; + + if (booleanKey) { + this.$$element.prop(key, value); + attrName = booleanKey; + } else if (aliasedKey) { + this[aliasedKey] = value; + observer = aliasedKey; + } + + this[key] = value; + + // translate normalized key to actual key + if (attrName) { + this.$attr[key] = attrName; + } else { + attrName = this.$attr[key]; + if (!attrName) { + this.$attr[key] = attrName = snake_case(key, '-'); + } + } + + nodeName = nodeName_(this.$$element); + + if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) || + (nodeName === 'img' && key === 'src')) { + // sanitize a[href] and img[src] values + this[key] = value = $$sanitizeUri(value, key === 'src'); + } else if (nodeName === 'img' && key === 'srcset' && isDefined(value)) { + // sanitize img[srcset] values + var result = ''; + + // first check if there are spaces because it's not the same pattern + var trimmedSrcset = trim(value); + // ( 999x ,| 999w ,| ,|, ) + var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/; + var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/; + + // split srcset into tuple of uri and descriptor except for the last item + var rawUris = trimmedSrcset.split(pattern); + + // for each tuples + var nbrUrisWith2parts = Math.floor(rawUris.length / 2); + for (var i = 0; i < nbrUrisWith2parts; i++) { + var innerIdx = i * 2; + // sanitize the uri + result += $$sanitizeUri(trim(rawUris[innerIdx]), true); + // add the descriptor + result += (' ' + trim(rawUris[innerIdx + 1])); + } + + // split the last item into uri and descriptor + var lastTuple = trim(rawUris[i * 2]).split(/\s/); + + // sanitize the last uri + result += $$sanitizeUri(trim(lastTuple[0]), true); + + // and add the last descriptor if any + if (lastTuple.length === 2) { + result += (' ' + trim(lastTuple[1])); + } + this[key] = value = result; + } + + if (writeAttr !== false) { + if (value === null || isUndefined(value)) { + this.$$element.removeAttr(attrName); + } else { + if (SIMPLE_ATTR_NAME.test(attrName)) { + this.$$element.attr(attrName, value); + } else { + setSpecialAttr(this.$$element[0], attrName, value); + } + } + } + + // fire observers + var $$observers = this.$$observers; + if ($$observers) { + forEach($$observers[observer], function(fn) { + try { + fn(value); + } catch (e) { + $exceptionHandler(e); + } + }); + } + }, + + + /** + * @ngdoc method + * @name $compile.directive.Attributes#$observe + * @kind function + * + * @description + * Observes an interpolated attribute. + * + * The observer function will be invoked once during the next `$digest` following + * compilation. The observer is then invoked whenever the interpolated value + * changes. + * + * @param {string} key Normalized key. (ie ngAttribute) . + * @param {function(interpolatedValue)} fn Function that will be called whenever + the interpolated value of the attribute changes. + * See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation + * guide} for more info. + * @returns {function()} Returns a deregistration function for this observer. + */ + $observe: function(key, fn) { + var attrs = this, + $$observers = (attrs.$$observers || (attrs.$$observers = createMap())), + listeners = ($$observers[key] || ($$observers[key] = [])); + + listeners.push(fn); + $rootScope.$evalAsync(function() { + if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) { + // no one registered attribute interpolation function, so lets call it manually + fn(attrs[key]); + } + }); + + return function() { + arrayRemove(listeners, fn); + }; + } + }; + + function setSpecialAttr(element, attrName, value) { + // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute` + // so we have to jump through some hoops to get such an attribute + // https://github.com/angular/angular.js/pull/13318 + specialAttrHolder.innerHTML = ''; + var attributes = specialAttrHolder.firstChild.attributes; + var attribute = attributes[0]; + // We have to remove the attribute from its container element before we can add it to the destination element + attributes.removeNamedItem(attribute.name); + attribute.value = value; + element.attributes.setNamedItem(attribute); + } + + function safeAddClass($element, className) { + try { + $element.addClass(className); + } catch (e) { + // ignore, since it means that we are trying to set class on + // SVG element, where class name is read-only. + } + } + + + var startSymbol = $interpolate.startSymbol(), + endSymbol = $interpolate.endSymbol(), + denormalizeTemplate = (startSymbol === '{{' && endSymbol === '}}') + ? identity + : function denormalizeTemplate(template) { + return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol); + }, + NG_ATTR_BINDING = /^ngAttr[A-Z]/; + var MULTI_ELEMENT_DIR_RE = /^(.+)Start$/; + + compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) { + var bindings = $element.data('$binding') || []; + + if (isArray(binding)) { + bindings = bindings.concat(binding); + } else { + bindings.push(binding); + } + + $element.data('$binding', bindings); + } : noop; + + compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) { + safeAddClass($element, 'ng-binding'); + } : noop; + + compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) { + var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope'; + $element.data(dataName, scope); + } : noop; + + compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) { + safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope'); + } : noop; + + compile.$$createComment = function(directiveName, comment) { + var content = ''; + if (debugInfoEnabled) { + content = ' ' + (directiveName || '') + ': '; + if (comment) content += comment + ' '; + } + return window.document.createComment(content); + }; + + return compile; + + //================================ + + function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, + previousCompileContext) { + if (!($compileNodes instanceof jqLite)) { + // jquery always rewraps, whereas we need to preserve the original selector so that we can + // modify it. + $compileNodes = jqLite($compileNodes); + } + var compositeLinkFn = + compileNodes($compileNodes, transcludeFn, $compileNodes, + maxPriority, ignoreDirective, previousCompileContext); + compile.$$addScopeClass($compileNodes); + var namespace = null; + return function publicLinkFn(scope, cloneConnectFn, options) { + if (!$compileNodes) { + throw $compileMinErr('multilink', 'This element has already been linked.'); + } + assertArg(scope, 'scope'); + + if (previousCompileContext && previousCompileContext.needsNewScope) { + // A parent directive did a replace and a directive on this element asked + // for transclusion, which caused us to lose a layer of element on which + // we could hold the new transclusion scope, so we will create it manually + // here. + scope = scope.$parent.$new(); + } + + options = options || {}; + var parentBoundTranscludeFn = options.parentBoundTranscludeFn, + transcludeControllers = options.transcludeControllers, + futureParentElement = options.futureParentElement; + + // When `parentBoundTranscludeFn` is passed, it is a + // `controllersBoundTransclude` function (it was previously passed + // as `transclude` to directive.link) so we must unwrap it to get + // its `boundTranscludeFn` + if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) { + parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude; + } + + if (!namespace) { + namespace = detectNamespaceForChildElements(futureParentElement); + } + var $linkNode; + if (namespace !== 'html') { + // When using a directive with replace:true and templateUrl the $compileNodes + // (or a child element inside of them) + // might change, so we need to recreate the namespace adapted compileNodes + // for call to the link function. + // Note: This will already clone the nodes... + $linkNode = jqLite( + wrapTemplate(namespace, jqLite('
').append($compileNodes).html()) + ); + } else if (cloneConnectFn) { + // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart + // and sometimes changes the structure of the DOM. + $linkNode = JQLitePrototype.clone.call($compileNodes); + } else { + $linkNode = $compileNodes; + } + + if (transcludeControllers) { + for (var controllerName in transcludeControllers) { + $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance); + } + } + + compile.$$addScopeInfo($linkNode, scope); + + if (cloneConnectFn) cloneConnectFn($linkNode, scope); + if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn); + + if (!cloneConnectFn) { + $compileNodes = compositeLinkFn = null; + } + return $linkNode; + }; + } + + function detectNamespaceForChildElements(parentElement) { + // TODO: Make this detect MathML as well... + var node = parentElement && parentElement[0]; + if (!node) { + return 'html'; + } else { + return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html'; + } + } + + /** + * Compile function matches each node in nodeList against the directives. Once all directives + * for a particular node are collected their compile functions are executed. The compile + * functions return values - the linking functions - are combined into a composite linking + * function, which is the a linking function for the node. + * + * @param {NodeList} nodeList an array of nodes or NodeList to compile + * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the + * scope argument is auto-generated to the new child of the transcluded parent scope. + * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then + * the rootElement must be set the jqLite collection of the compile root. This is + * needed so that the jqLite collection items can be replaced with widgets. + * @param {number=} maxPriority Max directive priority. + * @returns {Function} A composite linking function of all of the matched directives or null. + */ + function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, + previousCompileContext) { + var linkFns = [], + // `nodeList` can be either an element's `.childNodes` (live NodeList) + // or a jqLite/jQuery collection or an array + notLiveList = isArray(nodeList) || (nodeList instanceof jqLite), + attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound; + + + for (var i = 0; i < nodeList.length; i++) { + attrs = new Attributes(); + + // Support: IE 11 only + // Workaround for #11781 and #14924 + if (msie === 11) { + mergeConsecutiveTextNodes(nodeList, i, notLiveList); + } + + // We must always refer to `nodeList[i]` hereafter, + // since the nodes can be replaced underneath us. + directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined, + ignoreDirective); + + nodeLinkFn = (directives.length) + ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement, + null, [], [], previousCompileContext) + : null; + + if (nodeLinkFn && nodeLinkFn.scope) { + compile.$$addScopeClass(attrs.$$element); + } + + childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || + !(childNodes = nodeList[i].childNodes) || + !childNodes.length) + ? null + : compileNodes(childNodes, + nodeLinkFn ? ( + (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) + && nodeLinkFn.transclude) : transcludeFn); + + if (nodeLinkFn || childLinkFn) { + linkFns.push(i, nodeLinkFn, childLinkFn); + linkFnFound = true; + nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn; + } + + //use the previous context only for the first element in the virtual group + previousCompileContext = null; + } + + // return a linking function if we have found anything, null otherwise + return linkFnFound ? compositeLinkFn : null; + + function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) { + var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn; + var stableNodeList; + + + if (nodeLinkFnFound) { + // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our + // offsets don't get screwed up + var nodeListLength = nodeList.length; + stableNodeList = new Array(nodeListLength); + + // create a sparse array by only copying the elements which have a linkFn + for (i = 0; i < linkFns.length; i += 3) { + idx = linkFns[i]; + stableNodeList[idx] = nodeList[idx]; + } + } else { + stableNodeList = nodeList; + } + + for (i = 0, ii = linkFns.length; i < ii;) { + node = stableNodeList[linkFns[i++]]; + nodeLinkFn = linkFns[i++]; + childLinkFn = linkFns[i++]; + + if (nodeLinkFn) { + if (nodeLinkFn.scope) { + childScope = scope.$new(); + compile.$$addScopeInfo(jqLite(node), childScope); + } else { + childScope = scope; + } + + if (nodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn( + scope, nodeLinkFn.transclude, parentBoundTranscludeFn); + + } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) { + childBoundTranscludeFn = parentBoundTranscludeFn; + + } else if (!parentBoundTranscludeFn && transcludeFn) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn); + + } else { + childBoundTranscludeFn = null; + } + + nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn); + + } else if (childLinkFn) { + childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn); + } + } + } + } + + function mergeConsecutiveTextNodes(nodeList, idx, notLiveList) { + var node = nodeList[idx]; + var parent = node.parentNode; + var sibling; + + if (node.nodeType !== NODE_TYPE_TEXT) { + return; + } + + while (true) { + sibling = parent ? node.nextSibling : nodeList[idx + 1]; + if (!sibling || sibling.nodeType !== NODE_TYPE_TEXT) { + break; + } + + node.nodeValue = node.nodeValue + sibling.nodeValue; + + if (sibling.parentNode) { + sibling.parentNode.removeChild(sibling); + } + if (notLiveList && sibling === nodeList[idx + 1]) { + nodeList.splice(idx + 1, 1); + } + } + } + + function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) { + function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) { + + if (!transcludedScope) { + transcludedScope = scope.$new(false, containingScope); + transcludedScope.$$transcluded = true; + } + + return transcludeFn(transcludedScope, cloneFn, { + parentBoundTranscludeFn: previousBoundTranscludeFn, + transcludeControllers: controllers, + futureParentElement: futureParentElement + }); + } + + // We need to attach the transclusion slots onto the `boundTranscludeFn` + // so that they are available inside the `controllersBoundTransclude` function + var boundSlots = boundTranscludeFn.$$slots = createMap(); + for (var slotName in transcludeFn.$$slots) { + if (transcludeFn.$$slots[slotName]) { + boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn); + } else { + boundSlots[slotName] = null; + } + } + + return boundTranscludeFn; + } + + /** + * Looks for directives on the given node and adds them to the directive collection which is + * sorted. + * + * @param node Node to search. + * @param directives An array to which the directives are added to. This array is sorted before + * the function returns. + * @param attrs The shared attrs object which is used to populate the normalized attributes. + * @param {number=} maxPriority Max directive priority. + */ + function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) { + var nodeType = node.nodeType, + attrsMap = attrs.$attr, + match, + nodeName, + className; + + switch (nodeType) { + case NODE_TYPE_ELEMENT: /* Element */ + + nodeName = nodeName_(node); + + // use the node name: + addDirective(directives, + directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective); + + // iterate over the attributes + for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes, + j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) { + var attrStartName = false; + var attrEndName = false; + + attr = nAttrs[j]; + name = attr.name; + value = attr.value; + + // support ngAttr attribute binding + ngAttrName = directiveNormalize(name); + isNgAttr = NG_ATTR_BINDING.test(ngAttrName); + if (isNgAttr) { + name = name.replace(PREFIX_REGEXP, '') + .substr(8).replace(/_(.)/g, function(match, letter) { + return letter.toUpperCase(); + }); + } + + var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE); + if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) { + attrStartName = name; + attrEndName = name.substr(0, name.length - 5) + 'end'; + name = name.substr(0, name.length - 6); + } + + nName = directiveNormalize(name.toLowerCase()); + attrsMap[nName] = name; + if (isNgAttr || !attrs.hasOwnProperty(nName)) { + attrs[nName] = value; + if (getBooleanAttrName(node, nName)) { + attrs[nName] = true; // presence means true + } + } + addAttrInterpolateDirective(node, directives, value, nName, isNgAttr); + addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, + attrEndName); + } + + if (nodeName === 'input' && node.getAttribute('type') === 'hidden') { + // Hidden input elements can have strange behaviour when navigating back to the page + // This tells the browser not to try to cache and reinstate previous values + node.setAttribute('autocomplete', 'off'); + } + + // use class as directive + if (!cssClassDirectivesEnabled) break; + className = node.className; + if (isObject(className)) { + // Maybe SVGAnimatedString + className = className.animVal; + } + if (isString(className) && className !== '') { + while ((match = CLASS_DIRECTIVE_REGEXP.exec(className))) { + nName = directiveNormalize(match[2]); + if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) { + attrs[nName] = trim(match[3]); + } + className = className.substr(match.index + match[0].length); + } + } + break; + case NODE_TYPE_TEXT: /* Text Node */ + addTextInterpolateDirective(directives, node.nodeValue); + break; + case NODE_TYPE_COMMENT: /* Comment */ + if (!commentDirectivesEnabled) break; + collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective); + break; + } + + directives.sort(byPriority); + return directives; + } + + function collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective) { + // function created because of performance, try/catch disables + // the optimization of the whole function #14848 + try { + var match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue); + if (match) { + var nName = directiveNormalize(match[1]); + if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) { + attrs[nName] = trim(match[2]); + } + } + } catch (e) { + // turns out that under some circumstances IE9 throws errors when one attempts to read + // comment's node value. + // Just ignore it and continue. (Can't seem to reproduce in test case.) + } + } + + /** + * Given a node with a directive-start it collects all of the siblings until it finds + * directive-end. + * @param node + * @param attrStart + * @param attrEnd + * @returns {*} + */ + function groupScan(node, attrStart, attrEnd) { + var nodes = []; + var depth = 0; + if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) { + do { + if (!node) { + throw $compileMinErr('uterdir', + 'Unterminated attribute, found \'{0}\' but no matching \'{1}\' found.', + attrStart, attrEnd); + } + if (node.nodeType === NODE_TYPE_ELEMENT) { + if (node.hasAttribute(attrStart)) depth++; + if (node.hasAttribute(attrEnd)) depth--; + } + nodes.push(node); + node = node.nextSibling; + } while (depth > 0); + } else { + nodes.push(node); + } + + return jqLite(nodes); + } + + /** + * Wrapper for linking function which converts normal linking function into a grouped + * linking function. + * @param linkFn + * @param attrStart + * @param attrEnd + * @returns {Function} + */ + function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) { + return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) { + element = groupScan(element[0], attrStart, attrEnd); + return linkFn(scope, element, attrs, controllers, transcludeFn); + }; + } + + /** + * A function generator that is used to support both eager and lazy compilation + * linking function. + * @param eager + * @param $compileNodes + * @param transcludeFn + * @param maxPriority + * @param ignoreDirective + * @param previousCompileContext + * @returns {Function} + */ + function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) { + var compiled; + + if (eager) { + return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext); + } + return /** @this */ function lazyCompilation() { + if (!compiled) { + compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext); + + // Null out all of these references in order to make them eligible for garbage collection + // since this is a potentially long lived closure + $compileNodes = transcludeFn = previousCompileContext = null; + } + return compiled.apply(this, arguments); + }; + } + + /** + * Once the directives have been collected, their compile functions are executed. This method + * is responsible for inlining directive templates as well as terminating the application + * of the directives if the terminal directive has been reached. + * + * @param {Array} directives Array of collected directives to execute their compile function. + * this needs to be pre-sorted by priority order. + * @param {Node} compileNode The raw DOM node to apply the compile functions to + * @param {Object} templateAttrs The shared attribute function + * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the + * scope argument is auto-generated to the new + * child of the transcluded parent scope. + * @param {JQLite} jqCollection If we are working on the root of the compile tree then this + * argument has the root jqLite array so that we can replace nodes + * on it. + * @param {Object=} originalReplaceDirective An optional directive that will be ignored when + * compiling the transclusion. + * @param {Array.} preLinkFns + * @param {Array.} postLinkFns + * @param {Object} previousCompileContext Context used for previous compilation of the current + * node + * @returns {Function} linkFn + */ + function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, + jqCollection, originalReplaceDirective, preLinkFns, postLinkFns, + previousCompileContext) { + previousCompileContext = previousCompileContext || {}; + + var terminalPriority = -Number.MAX_VALUE, + newScopeDirective = previousCompileContext.newScopeDirective, + controllerDirectives = previousCompileContext.controllerDirectives, + newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective, + templateDirective = previousCompileContext.templateDirective, + nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, + hasTranscludeDirective = false, + hasTemplate = false, + hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective, + $compileNode = templateAttrs.$$element = jqLite(compileNode), + directive, + directiveName, + $template, + replaceDirective = originalReplaceDirective, + childTranscludeFn = transcludeFn, + linkFn, + didScanForMultipleTransclusion = false, + mightHaveMultipleTransclusionError = false, + directiveValue; + + // executes all directives on the current element + for (var i = 0, ii = directives.length; i < ii; i++) { + directive = directives[i]; + var attrStart = directive.$$start; + var attrEnd = directive.$$end; + + // collect multiblock sections + if (attrStart) { + $compileNode = groupScan(compileNode, attrStart, attrEnd); + } + $template = undefined; + + if (terminalPriority > directive.priority) { + break; // prevent further processing of directives + } + + directiveValue = directive.scope; + + if (directiveValue) { + + // skip the check for directives with async templates, we'll check the derived sync + // directive when the template arrives + if (!directive.templateUrl) { + if (isObject(directiveValue)) { + // This directive is trying to add an isolated scope. + // Check that there is no scope of any kind already + assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective, + directive, $compileNode); + newIsolateScopeDirective = directive; + } else { + // This directive is trying to add a child scope. + // Check that there is no isolated scope already + assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive, + $compileNode); + } + } + + newScopeDirective = newScopeDirective || directive; + } + + directiveName = directive.name; + + // If we encounter a condition that can result in transclusion on the directive, + // then scan ahead in the remaining directives for others that may cause a multiple + // transclusion error to be thrown during the compilation process. If a matching directive + // is found, then we know that when we encounter a transcluded directive, we need to eagerly + // compile the `transclude` function rather than doing it lazily in order to throw + // exceptions at the correct time + if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template)) + || (directive.transclude && !directive.$$tlb))) { + var candidateDirective; + + for (var scanningIndex = i + 1; (candidateDirective = directives[scanningIndex++]);) { + if ((candidateDirective.transclude && !candidateDirective.$$tlb) + || (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) { + mightHaveMultipleTransclusionError = true; + break; + } + } + + didScanForMultipleTransclusion = true; + } + + if (!directive.templateUrl && directive.controller) { + controllerDirectives = controllerDirectives || createMap(); + assertNoDuplicate('\'' + directiveName + '\' controller', + controllerDirectives[directiveName], directive, $compileNode); + controllerDirectives[directiveName] = directive; + } + + directiveValue = directive.transclude; + + if (directiveValue) { + hasTranscludeDirective = true; + + // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion. + // This option should only be used by directives that know how to safely handle element transclusion, + // where the transcluded nodes are added or replaced after linking. + if (!directive.$$tlb) { + assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode); + nonTlbTranscludeDirective = directive; + } + + if (directiveValue === 'element') { + hasElementTranscludeDirective = true; + terminalPriority = directive.priority; + $template = $compileNode; + $compileNode = templateAttrs.$$element = + jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName])); + compileNode = $compileNode[0]; + replaceWith(jqCollection, sliceArgs($template), compileNode); + + // Support: Chrome < 50 + // https://github.com/angular/angular.js/issues/14041 + + // In the versions of V8 prior to Chrome 50, the document fragment that is created + // in the `replaceWith` function is improperly garbage collected despite still + // being referenced by the `parentNode` property of all of the child nodes. By adding + // a reference to the fragment via a different property, we can avoid that incorrect + // behavior. + // TODO: remove this line after Chrome 50 has been released + $template[0].$$parentNode = $template[0].parentNode; + + childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority, + replaceDirective && replaceDirective.name, { + // Don't pass in: + // - controllerDirectives - otherwise we'll create duplicates controllers + // - newIsolateScopeDirective or templateDirective - combining templates with + // element transclusion doesn't make sense. + // + // We need only nonTlbTranscludeDirective so that we prevent putting transclusion + // on the same element more than once. + nonTlbTranscludeDirective: nonTlbTranscludeDirective + }); + } else { + + var slots = createMap(); + + if (!isObject(directiveValue)) { + $template = jqLite(jqLiteClone(compileNode)).contents(); + } else { + + // We have transclusion slots, + // collect them up, compile them and store their transclusion functions + $template = []; + + var slotMap = createMap(); + var filledSlots = createMap(); + + // Parse the element selectors + forEach(directiveValue, function(elementSelector, slotName) { + // If an element selector starts with a ? then it is optional + var optional = (elementSelector.charAt(0) === '?'); + elementSelector = optional ? elementSelector.substring(1) : elementSelector; + + slotMap[elementSelector] = slotName; + + // We explicitly assign `null` since this implies that a slot was defined but not filled. + // Later when calling boundTransclusion functions with a slot name we only error if the + // slot is `undefined` + slots[slotName] = null; + + // filledSlots contains `true` for all slots that are either optional or have been + // filled. This is used to check that we have not missed any required slots + filledSlots[slotName] = optional; + }); + + // Add the matching elements into their slot + forEach($compileNode.contents(), function(node) { + var slotName = slotMap[directiveNormalize(nodeName_(node))]; + if (slotName) { + filledSlots[slotName] = true; + slots[slotName] = slots[slotName] || []; + slots[slotName].push(node); + } else { + $template.push(node); + } + }); + + // Check for required slots that were not filled + forEach(filledSlots, function(filled, slotName) { + if (!filled) { + throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName); + } + }); + + for (var slotName in slots) { + if (slots[slotName]) { + // Only define a transclusion function if the slot was filled + slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn); + } + } + } + + $compileNode.empty(); // clear contents + childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined, + undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope}); + childTranscludeFn.$$slots = slots; + } + } + + if (directive.template) { + hasTemplate = true; + assertNoDuplicate('template', templateDirective, directive, $compileNode); + templateDirective = directive; + + directiveValue = (isFunction(directive.template)) + ? directive.template($compileNode, templateAttrs) + : directive.template; + + directiveValue = denormalizeTemplate(directiveValue); + + if (directive.replace) { + replaceDirective = directive; + if (jqLiteIsTextNode(directiveValue)) { + $template = []; + } else { + $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue))); + } + compileNode = $template[0]; + + if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) { + throw $compileMinErr('tplrt', + 'Template for directive \'{0}\' must have exactly one root element. {1}', + directiveName, ''); + } + + replaceWith(jqCollection, $compileNode, compileNode); + + var newTemplateAttrs = {$attr: {}}; + + // combine directives from the original node and from the template: + // - take the array of directives for this element + // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed) + // - collect directives from the template and sort them by priority + // - combine directives as: processed + template + unprocessed + var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs); + var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1)); + + if (newIsolateScopeDirective || newScopeDirective) { + // The original directive caused the current element to be replaced but this element + // also needs to have a new scope, so we need to tell the template directives + // that they would need to get their scope from further up, if they require transclusion + markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective); + } + directives = directives.concat(templateDirectives).concat(unprocessedDirectives); + mergeTemplateAttributes(templateAttrs, newTemplateAttrs); + + ii = directives.length; + } else { + $compileNode.html(directiveValue); + } + } + + if (directive.templateUrl) { + hasTemplate = true; + assertNoDuplicate('template', templateDirective, directive, $compileNode); + templateDirective = directive; + + if (directive.replace) { + replaceDirective = directive; + } + + // eslint-disable-next-line no-func-assign + nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, + templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, { + controllerDirectives: controllerDirectives, + newScopeDirective: (newScopeDirective !== directive) && newScopeDirective, + newIsolateScopeDirective: newIsolateScopeDirective, + templateDirective: templateDirective, + nonTlbTranscludeDirective: nonTlbTranscludeDirective + }); + ii = directives.length; + } else if (directive.compile) { + try { + linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn); + var context = directive.$$originalDirective || directive; + if (isFunction(linkFn)) { + addLinkFns(null, bind(context, linkFn), attrStart, attrEnd); + } else if (linkFn) { + addLinkFns(bind(context, linkFn.pre), bind(context, linkFn.post), attrStart, attrEnd); + } + } catch (e) { + $exceptionHandler(e, startingTag($compileNode)); + } + } + + if (directive.terminal) { + nodeLinkFn.terminal = true; + terminalPriority = Math.max(terminalPriority, directive.priority); + } + + } + + nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; + nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective; + nodeLinkFn.templateOnThisElement = hasTemplate; + nodeLinkFn.transclude = childTranscludeFn; + + previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective; + + // might be normal or delayed nodeLinkFn depending on if templateUrl is present + return nodeLinkFn; + + //////////////////// + + function addLinkFns(pre, post, attrStart, attrEnd) { + if (pre) { + if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd); + pre.require = directive.require; + pre.directiveName = directiveName; + if (newIsolateScopeDirective === directive || directive.$$isolateScope) { + pre = cloneAndAnnotateFn(pre, {isolateScope: true}); + } + preLinkFns.push(pre); + } + if (post) { + if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd); + post.require = directive.require; + post.directiveName = directiveName; + if (newIsolateScopeDirective === directive || directive.$$isolateScope) { + post = cloneAndAnnotateFn(post, {isolateScope: true}); + } + postLinkFns.push(post); + } + } + + function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { + var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element, + attrs, scopeBindingInfo; + + if (compileNode === linkNode) { + attrs = templateAttrs; + $element = templateAttrs.$$element; + } else { + $element = jqLite(linkNode); + attrs = new Attributes($element, templateAttrs); + } + + controllerScope = scope; + if (newIsolateScopeDirective) { + isolateScope = scope.$new(true); + } else if (newScopeDirective) { + controllerScope = scope.$parent; + } + + if (boundTranscludeFn) { + // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn` + // is later passed as `parentBoundTranscludeFn` to `publicLinkFn` + transcludeFn = controllersBoundTransclude; + transcludeFn.$$boundTransclude = boundTranscludeFn; + // expose the slots on the `$transclude` function + transcludeFn.isSlotFilled = function(slotName) { + return !!boundTranscludeFn.$$slots[slotName]; + }; + } + + if (controllerDirectives) { + elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective); + } + + if (newIsolateScopeDirective) { + // Initialize isolate scope bindings for new isolate scope directive. + compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective || + templateDirective === newIsolateScopeDirective.$$originalDirective))); + compile.$$addScopeClass($element, true); + isolateScope.$$isolateBindings = + newIsolateScopeDirective.$$isolateBindings; + scopeBindingInfo = initializeDirectiveBindings(scope, attrs, isolateScope, + isolateScope.$$isolateBindings, + newIsolateScopeDirective); + if (scopeBindingInfo.removeWatches) { + isolateScope.$on('$destroy', scopeBindingInfo.removeWatches); + } + } + + // Initialize bindToController bindings + for (var name in elementControllers) { + var controllerDirective = controllerDirectives[name]; + var controller = elementControllers[name]; + var bindings = controllerDirective.$$bindings.bindToController; + + if (preAssignBindingsEnabled) { + if (bindings) { + controller.bindingInfo = + initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective); + } else { + controller.bindingInfo = {}; + } + + var controllerResult = controller(); + if (controllerResult !== controller.instance) { + // If the controller constructor has a return value, overwrite the instance + // from setupControllers + controller.instance = controllerResult; + $element.data('$' + controllerDirective.name + 'Controller', controllerResult); + if (controller.bindingInfo.removeWatches) { + controller.bindingInfo.removeWatches(); + } + controller.bindingInfo = + initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective); + } + } else { + controller.instance = controller(); + $element.data('$' + controllerDirective.name + 'Controller', controller.instance); + controller.bindingInfo = + initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective); + } + } + + // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy + forEach(controllerDirectives, function(controllerDirective, name) { + var require = controllerDirective.require; + if (controllerDirective.bindToController && !isArray(require) && isObject(require)) { + extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers)); + } + }); + + // Handle the init and destroy lifecycle hooks on all controllers that have them + forEach(elementControllers, function(controller) { + var controllerInstance = controller.instance; + if (isFunction(controllerInstance.$onChanges)) { + try { + controllerInstance.$onChanges(controller.bindingInfo.initialChanges); + } catch (e) { + $exceptionHandler(e); + } + } + if (isFunction(controllerInstance.$onInit)) { + try { + controllerInstance.$onInit(); + } catch (e) { + $exceptionHandler(e); + } + } + if (isFunction(controllerInstance.$doCheck)) { + controllerScope.$watch(function() { controllerInstance.$doCheck(); }); + controllerInstance.$doCheck(); + } + if (isFunction(controllerInstance.$onDestroy)) { + controllerScope.$on('$destroy', function callOnDestroyHook() { + controllerInstance.$onDestroy(); + }); + } + }); + + // PRELINKING + for (i = 0, ii = preLinkFns.length; i < ii; i++) { + linkFn = preLinkFns[i]; + invokeLinkFn(linkFn, + linkFn.isolateScope ? isolateScope : scope, + $element, + attrs, + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), + transcludeFn + ); + } + + // RECURSION + // We only pass the isolate scope, if the isolate directive has a template, + // otherwise the child elements do not belong to the isolate directive. + var scopeToChild = scope; + if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) { + scopeToChild = isolateScope; + } + if (childLinkFn) { + childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn); + } + + // POSTLINKING + for (i = postLinkFns.length - 1; i >= 0; i--) { + linkFn = postLinkFns[i]; + invokeLinkFn(linkFn, + linkFn.isolateScope ? isolateScope : scope, + $element, + attrs, + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), + transcludeFn + ); + } + + // Trigger $postLink lifecycle hooks + forEach(elementControllers, function(controller) { + var controllerInstance = controller.instance; + if (isFunction(controllerInstance.$postLink)) { + controllerInstance.$postLink(); + } + }); + + // This is the function that is injected as `$transclude`. + // Note: all arguments are optional! + function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) { + var transcludeControllers; + // No scope passed in: + if (!isScope(scope)) { + slotName = futureParentElement; + futureParentElement = cloneAttachFn; + cloneAttachFn = scope; + scope = undefined; + } + + if (hasElementTranscludeDirective) { + transcludeControllers = elementControllers; + } + if (!futureParentElement) { + futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element; + } + if (slotName) { + // slotTranscludeFn can be one of three things: + // * a transclude function - a filled slot + // * `null` - an optional slot that was not filled + // * `undefined` - a slot that was not declared (i.e. invalid) + var slotTranscludeFn = boundTranscludeFn.$$slots[slotName]; + if (slotTranscludeFn) { + return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); + } else if (isUndefined(slotTranscludeFn)) { + throw $compileMinErr('noslot', + 'No parent directive that requires a transclusion with slot name "{0}". ' + + 'Element: {1}', + slotName, startingTag($element)); + } + } else { + return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); + } + } + } + } + + function getControllers(directiveName, require, $element, elementControllers) { + var value; + + if (isString(require)) { + var match = require.match(REQUIRE_PREFIX_REGEXP); + var name = require.substring(match[0].length); + var inheritType = match[1] || match[3]; + var optional = match[2] === '?'; + + //If only parents then start at the parent element + if (inheritType === '^^') { + $element = $element.parent(); + //Otherwise attempt getting the controller from elementControllers in case + //the element is transcluded (and has no data) and to avoid .data if possible + } else { + value = elementControllers && elementControllers[name]; + value = value && value.instance; + } + + if (!value) { + var dataName = '$' + name + 'Controller'; + value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName); + } + + if (!value && !optional) { + throw $compileMinErr('ctreq', + 'Controller \'{0}\', required by directive \'{1}\', can\'t be found!', + name, directiveName); + } + } else if (isArray(require)) { + value = []; + for (var i = 0, ii = require.length; i < ii; i++) { + value[i] = getControllers(directiveName, require[i], $element, elementControllers); + } + } else if (isObject(require)) { + value = {}; + forEach(require, function(controller, property) { + value[property] = getControllers(directiveName, controller, $element, elementControllers); + }); + } + + return value || null; + } + + function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) { + var elementControllers = createMap(); + for (var controllerKey in controllerDirectives) { + var directive = controllerDirectives[controllerKey]; + var locals = { + $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope, + $element: $element, + $attrs: attrs, + $transclude: transcludeFn + }; + + var controller = directive.controller; + if (controller === '@') { + controller = attrs[directive.name]; + } + + var controllerInstance = $controller(controller, locals, true, directive.controllerAs); + + // For directives with element transclusion the element is a comment. + // In this case .data will not attach any data. + // Instead, we save the controllers for the element in a local hash and attach to .data + // later, once we have the actual element. + elementControllers[directive.name] = controllerInstance; + $element.data('$' + directive.name + 'Controller', controllerInstance.instance); + } + return elementControllers; + } + + // Depending upon the context in which a directive finds itself it might need to have a new isolated + // or child scope created. For instance: + // * if the directive has been pulled into a template because another directive with a higher priority + // asked for element transclusion + // * if the directive itself asks for transclusion but it is at the root of a template and the original + // element was replaced. See https://github.com/angular/angular.js/issues/12936 + function markDirectiveScope(directives, isolateScope, newScope) { + for (var j = 0, jj = directives.length; j < jj; j++) { + directives[j] = inherit(directives[j], {$$isolateScope: isolateScope, $$newScope: newScope}); + } + } + + /** + * looks up the directive and decorates it with exception handling and proper parameters. We + * call this the boundDirective. + * + * @param {string} name name of the directive to look up. + * @param {string} location The directive must be found in specific format. + * String containing any of theses characters: + * + * * `E`: element name + * * `A': attribute + * * `C`: class + * * `M`: comment + * @returns {boolean} true if directive was added. + */ + function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, + endAttrName) { + if (name === ignoreDirective) return null; + var match = null; + if (hasDirectives.hasOwnProperty(name)) { + for (var directive, directives = $injector.get(name + Suffix), + i = 0, ii = directives.length; i < ii; i++) { + directive = directives[i]; + if ((isUndefined(maxPriority) || maxPriority > directive.priority) && + directive.restrict.indexOf(location) !== -1) { + if (startAttrName) { + directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName}); + } + if (!directive.$$bindings) { + var bindings = directive.$$bindings = + parseDirectiveBindings(directive, directive.name); + if (isObject(bindings.isolateScope)) { + directive.$$isolateBindings = bindings.isolateScope; + } + } + tDirectives.push(directive); + match = directive; + } + } + } + return match; + } + + + /** + * looks up the directive and returns true if it is a multi-element directive, + * and therefore requires DOM nodes between -start and -end markers to be grouped + * together. + * + * @param {string} name name of the directive to look up. + * @returns true if directive was registered as multi-element. + */ + function directiveIsMultiElement(name) { + if (hasDirectives.hasOwnProperty(name)) { + for (var directive, directives = $injector.get(name + Suffix), + i = 0, ii = directives.length; i < ii; i++) { + directive = directives[i]; + if (directive.multiElement) { + return true; + } + } + } + return false; + } + + /** + * When the element is replaced with HTML template then the new attributes + * on the template need to be merged with the existing attributes in the DOM. + * The desired effect is to have both of the attributes present. + * + * @param {object} dst destination attributes (original DOM) + * @param {object} src source attributes (from the directive template) + */ + function mergeTemplateAttributes(dst, src) { + var srcAttr = src.$attr, + dstAttr = dst.$attr; + + // reapply the old attributes to the new element + forEach(dst, function(value, key) { + if (key.charAt(0) !== '$') { + if (src[key] && src[key] !== value) { + if (value.length) { + value += (key === 'style' ? ';' : ' ') + src[key]; + } else { + value = src[key]; + } + } + dst.$set(key, value, true, srcAttr[key]); + } + }); + + // copy the new attributes on the old attrs object + forEach(src, function(value, key) { + // Check if we already set this attribute in the loop above. + // `dst` will never contain hasOwnProperty as DOM parser won't let it. + // You will get an "InvalidCharacterError: DOM Exception 5" error if you + // have an attribute like "has-own-property" or "data-has-own-property", etc. + if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') { + dst[key] = value; + + if (key !== 'class' && key !== 'style') { + dstAttr[key] = srcAttr[key]; + } + } + }); + } + + + function compileTemplateUrl(directives, $compileNode, tAttrs, + $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) { + var linkQueue = [], + afterTemplateNodeLinkFn, + afterTemplateChildLinkFn, + beforeTemplateCompileNode = $compileNode[0], + origAsyncDirective = directives.shift(), + derivedSyncDirective = inherit(origAsyncDirective, { + templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective + }), + templateUrl = (isFunction(origAsyncDirective.templateUrl)) + ? origAsyncDirective.templateUrl($compileNode, tAttrs) + : origAsyncDirective.templateUrl, + templateNamespace = origAsyncDirective.templateNamespace; + + $compileNode.empty(); + + $templateRequest(templateUrl) + .then(function(content) { + var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn; + + content = denormalizeTemplate(content); + + if (origAsyncDirective.replace) { + if (jqLiteIsTextNode(content)) { + $template = []; + } else { + $template = removeComments(wrapTemplate(templateNamespace, trim(content))); + } + compileNode = $template[0]; + + if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) { + throw $compileMinErr('tplrt', + 'Template for directive \'{0}\' must have exactly one root element. {1}', + origAsyncDirective.name, templateUrl); + } + + tempTemplateAttrs = {$attr: {}}; + replaceWith($rootElement, $compileNode, compileNode); + var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs); + + if (isObject(origAsyncDirective.scope)) { + // the original directive that caused the template to be loaded async required + // an isolate scope + markDirectiveScope(templateDirectives, true); + } + directives = templateDirectives.concat(directives); + mergeTemplateAttributes(tAttrs, tempTemplateAttrs); + } else { + compileNode = beforeTemplateCompileNode; + $compileNode.html(content); + } + + directives.unshift(derivedSyncDirective); + + afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, + childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns, + previousCompileContext); + forEach($rootElement, function(node, i) { + if (node === compileNode) { + $rootElement[i] = $compileNode[0]; + } + }); + afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn); + + while (linkQueue.length) { + var scope = linkQueue.shift(), + beforeTemplateLinkNode = linkQueue.shift(), + linkRootElement = linkQueue.shift(), + boundTranscludeFn = linkQueue.shift(), + linkNode = $compileNode[0]; + + if (scope.$$destroyed) continue; + + if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { + var oldClasses = beforeTemplateLinkNode.className; + + if (!(previousCompileContext.hasElementTranscludeDirective && + origAsyncDirective.replace)) { + // it was cloned therefore we have to clone as well. + linkNode = jqLiteClone(compileNode); + } + replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode); + + // Copy in CSS classes from original node + safeAddClass(jqLite(linkNode), oldClasses); + } + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); + } else { + childBoundTranscludeFn = boundTranscludeFn; + } + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, + childBoundTranscludeFn); + } + linkQueue = null; + }).catch(function(error) { + if (error instanceof Error) { + $exceptionHandler(error); + } + }).catch(noop); + + return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) { + var childBoundTranscludeFn = boundTranscludeFn; + if (scope.$$destroyed) return; + if (linkQueue) { + linkQueue.push(scope, + node, + rootElement, + childBoundTranscludeFn); + } else { + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); + } + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn); + } + }; + } + + + /** + * Sorting function for bound directives. + */ + function byPriority(a, b) { + var diff = b.priority - a.priority; + if (diff !== 0) return diff; + if (a.name !== b.name) return (a.name < b.name) ? -1 : 1; + return a.index - b.index; + } + + function assertNoDuplicate(what, previousDirective, directive, element) { + + function wrapModuleNameIfDefined(moduleName) { + return moduleName ? + (' (module: ' + moduleName + ')') : + ''; + } + + if (previousDirective) { + throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}', + previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName), + directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element)); + } + } + + + function addTextInterpolateDirective(directives, text) { + var interpolateFn = $interpolate(text, true); + if (interpolateFn) { + directives.push({ + priority: 0, + compile: function textInterpolateCompileFn(templateNode) { + var templateNodeParent = templateNode.parent(), + hasCompileParent = !!templateNodeParent.length; + + // When transcluding a template that has bindings in the root + // we don't have a parent and thus need to add the class during linking fn. + if (hasCompileParent) compile.$$addBindingClass(templateNodeParent); + + return function textInterpolateLinkFn(scope, node) { + var parent = node.parent(); + if (!hasCompileParent) compile.$$addBindingClass(parent); + compile.$$addBindingInfo(parent, interpolateFn.expressions); + scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { + node[0].nodeValue = value; + }); + }; + } + }); + } + } + + + function wrapTemplate(type, template) { + type = lowercase(type || 'html'); + switch (type) { + case 'svg': + case 'math': + var wrapper = window.document.createElement('div'); + wrapper.innerHTML = '<' + type + '>' + template + ''; + return wrapper.childNodes[0].childNodes; + default: + return template; + } + } + + + function getTrustedContext(node, attrNormalizedName) { + if (attrNormalizedName === 'srcdoc') { + return $sce.HTML; + } + var tag = nodeName_(node); + // All tags with src attributes require a RESOURCE_URL value, except for + // img and various html5 media tags. + if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') { + if (['img', 'video', 'audio', 'source', 'track'].indexOf(tag) === -1) { + return $sce.RESOURCE_URL; + } + // maction[xlink:href] can source SVG. It's not limited to . + } else if (attrNormalizedName === 'xlinkHref' || + (tag === 'form' && attrNormalizedName === 'action') || + // links can be stylesheets or imports, which can run script in the current origin + (tag === 'link' && attrNormalizedName === 'href') + ) { + return $sce.RESOURCE_URL; + } + } + + + function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) { + var trustedContext = getTrustedContext(node, name); + var mustHaveExpression = !isNgAttr; + var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr; + + var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing); + + // no interpolation found -> ignore + if (!interpolateFn) return; + + if (name === 'multiple' && nodeName_(node) === 'select') { + throw $compileMinErr('selmulti', + 'Binding to the \'multiple\' attribute is not supported. Element: {0}', + startingTag(node)); + } + + if (EVENT_HANDLER_ATTR_REGEXP.test(name)) { + throw $compileMinErr('nodomevents', + 'Interpolations for HTML DOM event attributes are disallowed. Please use the ' + + 'ng- versions (such as ng-click instead of onclick) instead.'); + } + + directives.push({ + priority: 100, + compile: function() { + return { + pre: function attrInterpolatePreLinkFn(scope, element, attr) { + var $$observers = (attr.$$observers || (attr.$$observers = createMap())); + + // If the attribute has changed since last $interpolate()ed + var newValue = attr[name]; + if (newValue !== value) { + // we need to interpolate again since the attribute value has been updated + // (e.g. by another directive's compile function) + // ensure unset/empty values make interpolateFn falsy + interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing); + value = newValue; + } + + // if attribute was updated so that there is no interpolation going on we don't want to + // register any observers + if (!interpolateFn) return; + + // initialize attr object so that it's ready in case we need the value for isolate + // scope initialization, otherwise the value would not be available from isolate + // directive's linking fn during linking phase + attr[name] = interpolateFn(scope); + + ($$observers[name] || ($$observers[name] = [])).$$inter = true; + (attr.$$observers && attr.$$observers[name].$$scope || scope). + $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) { + //special case for class attribute addition + removal + //so that class changes can tap into the animation + //hooks provided by the $animate service. Be sure to + //skip animations when the first digest occurs (when + //both the new and the old values are the same) since + //the CSS classes are the non-interpolated values + if (name === 'class' && newValue !== oldValue) { + attr.$updateClass(newValue, oldValue); + } else { + attr.$set(name, newValue); + } + }); + } + }; + } + }); + } + + + /** + * This is a special jqLite.replaceWith, which can replace items which + * have no parents, provided that the containing jqLite collection is provided. + * + * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes + * in the root of the tree. + * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep + * the shell, but replace its DOM node reference. + * @param {Node} newNode The new DOM node. + */ + function replaceWith($rootElement, elementsToRemove, newNode) { + var firstElementToRemove = elementsToRemove[0], + removeCount = elementsToRemove.length, + parent = firstElementToRemove.parentNode, + i, ii; + + if ($rootElement) { + for (i = 0, ii = $rootElement.length; i < ii; i++) { + if ($rootElement[i] === firstElementToRemove) { + $rootElement[i++] = newNode; + for (var j = i, j2 = j + removeCount - 1, + jj = $rootElement.length; + j < jj; j++, j2++) { + if (j2 < jj) { + $rootElement[j] = $rootElement[j2]; + } else { + delete $rootElement[j]; + } + } + $rootElement.length -= removeCount - 1; + + // If the replaced element is also the jQuery .context then replace it + // .context is a deprecated jQuery api, so we should set it only when jQuery set it + // http://api.jquery.com/context/ + if ($rootElement.context === firstElementToRemove) { + $rootElement.context = newNode; + } + break; + } + } + } + + if (parent) { + parent.replaceChild(newNode, firstElementToRemove); + } + + // Append all the `elementsToRemove` to a fragment. This will... + // - remove them from the DOM + // - allow them to still be traversed with .nextSibling + // - allow a single fragment.qSA to fetch all elements being removed + var fragment = window.document.createDocumentFragment(); + for (i = 0; i < removeCount; i++) { + fragment.appendChild(elementsToRemove[i]); + } + + if (jqLite.hasData(firstElementToRemove)) { + // Copy over user data (that includes Angular's $scope etc.). Don't copy private + // data here because there's no public interface in jQuery to do that and copying over + // event listeners (which is the main use of private data) wouldn't work anyway. + jqLite.data(newNode, jqLite.data(firstElementToRemove)); + + // Remove $destroy event listeners from `firstElementToRemove` + jqLite(firstElementToRemove).off('$destroy'); + } + + // Cleanup any data/listeners on the elements and children. + // This includes invoking the $destroy event on any elements with listeners. + jqLite.cleanData(fragment.querySelectorAll('*')); + + // Update the jqLite collection to only contain the `newNode` + for (i = 1; i < removeCount; i++) { + delete elementsToRemove[i]; + } + elementsToRemove[0] = newNode; + elementsToRemove.length = 1; + } + + + function cloneAndAnnotateFn(fn, annotation) { + return extend(function() { return fn.apply(null, arguments); }, fn, annotation); + } + + + function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) { + try { + linkFn(scope, $element, attrs, controllers, transcludeFn); + } catch (e) { + $exceptionHandler(e, startingTag($element)); + } + } + + + // Set up $watches for isolate scope and controller bindings. + function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) { + var removeWatchCollection = []; + var initialChanges = {}; + var changes; + forEach(bindings, function initializeBinding(definition, scopeName) { + var attrName = definition.attrName, + optional = definition.optional, + mode = definition.mode, // @, =, <, or & + lastValue, + parentGet, parentSet, compare, removeWatch; + + switch (mode) { + + case '@': + if (!optional && !hasOwnProperty.call(attrs, attrName)) { + destination[scopeName] = attrs[attrName] = undefined; + } + removeWatch = attrs.$observe(attrName, function(value) { + if (isString(value) || isBoolean(value)) { + var oldValue = destination[scopeName]; + recordChanges(scopeName, value, oldValue); + destination[scopeName] = value; + } + }); + attrs.$$observers[attrName].$$scope = scope; + lastValue = attrs[attrName]; + if (isString(lastValue)) { + // If the attribute has been provided then we trigger an interpolation to ensure + // the value is there for use in the link fn + destination[scopeName] = $interpolate(lastValue)(scope); + } else if (isBoolean(lastValue)) { + // If the attributes is one of the BOOLEAN_ATTR then Angular will have converted + // the value to boolean rather than a string, so we special case this situation + destination[scopeName] = lastValue; + } + initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]); + removeWatchCollection.push(removeWatch); + break; + + case '=': + if (!hasOwnProperty.call(attrs, attrName)) { + if (optional) break; + attrs[attrName] = undefined; + } + if (optional && !attrs[attrName]) break; + + parentGet = $parse(attrs[attrName]); + if (parentGet.literal) { + compare = equals; + } else { + // eslint-disable-next-line no-self-compare + compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); }; + } + parentSet = parentGet.assign || function() { + // reset the change, or we will throw this exception on every $digest + lastValue = destination[scopeName] = parentGet(scope); + throw $compileMinErr('nonassign', + 'Expression \'{0}\' in attribute \'{1}\' used with directive \'{2}\' is non-assignable!', + attrs[attrName], attrName, directive.name); + }; + lastValue = destination[scopeName] = parentGet(scope); + var parentValueWatch = function parentValueWatch(parentValue) { + if (!compare(parentValue, destination[scopeName])) { + // we are out of sync and need to copy + if (!compare(parentValue, lastValue)) { + // parent changed and it has precedence + destination[scopeName] = parentValue; + } else { + // if the parent can be assigned then do so + parentSet(scope, parentValue = destination[scopeName]); + } + } + lastValue = parentValue; + return lastValue; + }; + parentValueWatch.$stateful = true; + if (definition.collection) { + removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch); + } else { + removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal); + } + removeWatchCollection.push(removeWatch); + break; + + case '<': + if (!hasOwnProperty.call(attrs, attrName)) { + if (optional) break; + attrs[attrName] = undefined; + } + if (optional && !attrs[attrName]) break; + + parentGet = $parse(attrs[attrName]); + var deepWatch = parentGet.literal; + + var initialValue = destination[scopeName] = parentGet(scope); + initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]); + + removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) { + if (oldValue === newValue) { + if (oldValue === initialValue || (deepWatch && equals(oldValue, initialValue))) { + return; + } + oldValue = initialValue; + } + recordChanges(scopeName, newValue, oldValue); + destination[scopeName] = newValue; + }, deepWatch); + + removeWatchCollection.push(removeWatch); + break; + + case '&': + // Don't assign Object.prototype method to scope + parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop; + + // Don't assign noop to destination if expression is not valid + if (parentGet === noop && optional) break; + + destination[scopeName] = function(locals) { + return parentGet(scope, locals); + }; + break; + } + }); + + function recordChanges(key, currentValue, previousValue) { + if (isFunction(destination.$onChanges) && currentValue !== previousValue && + // eslint-disable-next-line no-self-compare + (currentValue === currentValue || previousValue === previousValue)) { + // If we have not already scheduled the top level onChangesQueue handler then do so now + if (!onChangesQueue) { + scope.$$postDigest(flushOnChangesQueue); + onChangesQueue = []; + } + // If we have not already queued a trigger of onChanges for this controller then do so now + if (!changes) { + changes = {}; + onChangesQueue.push(triggerOnChangesHook); + } + // If the has been a change on this property already then we need to reuse the previous value + if (changes[key]) { + previousValue = changes[key].previousValue; + } + // Store this change + changes[key] = new SimpleChange(previousValue, currentValue); + } + } + + function triggerOnChangesHook() { + destination.$onChanges(changes); + // Now clear the changes so that we schedule onChanges when more changes arrive + changes = undefined; + } + + return { + initialChanges: initialChanges, + removeWatches: removeWatchCollection.length && function removeWatches() { + for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) { + removeWatchCollection[i](); + } + } + }; + } + }]; +} + +function SimpleChange(previous, current) { + this.previousValue = previous; + this.currentValue = current; +} +SimpleChange.prototype.isFirstChange = function() { return this.previousValue === _UNINITIALIZED_VALUE; }; + + +var PREFIX_REGEXP = /^((?:x|data)[:\-_])/i; +var SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g; + +/** + * Converts all accepted directives format into proper directive name. + * @param name Name to normalize + */ +function directiveNormalize(name) { + return name + .replace(PREFIX_REGEXP, '') + .replace(SPECIAL_CHARS_REGEXP, fnCamelCaseReplace); +} + +/** + * @ngdoc type + * @name $compile.directive.Attributes + * + * @description + * A shared object between directive compile / linking functions which contains normalized DOM + * element attributes. The values reflect current binding state `{{ }}`. The normalization is + * needed since all of these are treated as equivalent in Angular: + * + * ``` + * + * ``` + */ + +/** + * @ngdoc property + * @name $compile.directive.Attributes#$attr + * + * @description + * A map of DOM element attribute names to the normalized name. This is + * needed to do reverse lookup from normalized name back to actual name. + */ + + +/** + * @ngdoc method + * @name $compile.directive.Attributes#$set + * @kind function + * + * @description + * Set DOM element attribute value. + * + * + * @param {string} name Normalized element attribute name of the property to modify. The name is + * reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr} + * property to the original name. + * @param {string} value Value to set the attribute to. The value can be an interpolated string. + */ + + + +/** + * Closure compiler type information + */ + +function nodesetLinkingFn( + /* angular.Scope */ scope, + /* NodeList */ nodeList, + /* Element */ rootElement, + /* function(Function) */ boundTranscludeFn +) {} + +function directiveLinkingFn( + /* nodesetLinkingFn */ nodesetLinkingFn, + /* angular.Scope */ scope, + /* Node */ node, + /* Element */ rootElement, + /* function(Function) */ boundTranscludeFn +) {} + +function tokenDifference(str1, str2) { + var values = '', + tokens1 = str1.split(/\s+/), + tokens2 = str2.split(/\s+/); + + outer: + for (var i = 0; i < tokens1.length; i++) { + var token = tokens1[i]; + for (var j = 0; j < tokens2.length; j++) { + if (token === tokens2[j]) continue outer; + } + values += (values.length > 0 ? ' ' : '') + token; + } + return values; +} + +function removeComments(jqNodes) { + jqNodes = jqLite(jqNodes); + var i = jqNodes.length; + + if (i <= 1) { + return jqNodes; + } + + while (i--) { + var node = jqNodes[i]; + if (node.nodeType === NODE_TYPE_COMMENT || + (node.nodeType === NODE_TYPE_TEXT && node.nodeValue.trim() === '')) { + splice.call(jqNodes, i, 1); + } + } + return jqNodes; +} + +var $controllerMinErr = minErr('$controller'); + + +var CNTRL_REG = /^(\S+)(\s+as\s+([\w$]+))?$/; +function identifierForController(controller, ident) { + if (ident && isString(ident)) return ident; + if (isString(controller)) { + var match = CNTRL_REG.exec(controller); + if (match) return match[3]; + } +} + + +/** + * @ngdoc provider + * @name $controllerProvider + * @this + * + * @description + * The {@link ng.$controller $controller service} is used by Angular to create new + * controllers. + * + * This provider allows controller registration via the + * {@link ng.$controllerProvider#register register} method. + */ +function $ControllerProvider() { + var controllers = {}, + globals = false; + + /** + * @ngdoc method + * @name $controllerProvider#has + * @param {string} name Controller name to check. + */ + this.has = function(name) { + return controllers.hasOwnProperty(name); + }; + + /** + * @ngdoc method + * @name $controllerProvider#register + * @param {string|Object} name Controller name, or an object map of controllers where the keys are + * the names and the values are the constructors. + * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI + * annotations in the array notation). + */ + this.register = function(name, constructor) { + assertNotHasOwnProperty(name, 'controller'); + if (isObject(name)) { + extend(controllers, name); + } else { + controllers[name] = constructor; + } + }; + + /** + * @ngdoc method + * @name $controllerProvider#allowGlobals + * @description If called, allows `$controller` to find controller constructors on `window` + * + * @deprecated + * sinceVersion="v1.3.0" + * removeVersion="v1.7.0" + * This method of finding controllers has been deprecated. + */ + this.allowGlobals = function() { + globals = true; + }; + + + this.$get = ['$injector', '$window', function($injector, $window) { + + /** + * @ngdoc service + * @name $controller + * @requires $injector + * + * @param {Function|string} constructor If called with a function then it's considered to be the + * controller constructor function. Otherwise it's considered to be a string which is used + * to retrieve the controller constructor using the following steps: + * + * * check if a controller with given name is registered via `$controllerProvider` + * * check if evaluating the string on the current scope returns a constructor + * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global + * `window` object (deprecated, not recommended) + * + * The string can use the `controller as property` syntax, where the controller instance is published + * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this + * to work correctly. + * + * @param {Object} locals Injection locals for Controller. + * @return {Object} Instance of given controller. + * + * @description + * `$controller` service is responsible for instantiating controllers. + * + * It's just a simple call to {@link auto.$injector $injector}, but extracted into + * a service, so that one can override this service with [BC version](https://gist.github.com/1649788). + */ + return function $controller(expression, locals, later, ident) { + // PRIVATE API: + // param `later` --- indicates that the controller's constructor is invoked at a later time. + // If true, $controller will allocate the object with the correct + // prototype chain, but will not invoke the controller until a returned + // callback is invoked. + // param `ident` --- An optional label which overrides the label parsed from the controller + // expression, if any. + var instance, match, constructor, identifier; + later = later === true; + if (ident && isString(ident)) { + identifier = ident; + } + + if (isString(expression)) { + match = expression.match(CNTRL_REG); + if (!match) { + throw $controllerMinErr('ctrlfmt', + 'Badly formed controller string \'{0}\'. ' + + 'Must match `__name__ as __id__` or `__name__`.', expression); + } + constructor = match[1]; + identifier = identifier || match[3]; + expression = controllers.hasOwnProperty(constructor) + ? controllers[constructor] + : getter(locals.$scope, constructor, true) || + (globals ? getter($window, constructor, true) : undefined); + + if (!expression) { + throw $controllerMinErr('ctrlreg', + 'The controller with the name \'{0}\' is not registered.', constructor); + } + + assertArgFn(expression, constructor, true); + } + + if (later) { + // Instantiate controller later: + // This machinery is used to create an instance of the object before calling the + // controller's constructor itself. + // + // This allows properties to be added to the controller before the constructor is + // invoked. Primarily, this is used for isolate scope bindings in $compile. + // + // This feature is not intended for use by applications, and is thus not documented + // publicly. + // Object creation: http://jsperf.com/create-constructor/2 + var controllerPrototype = (isArray(expression) ? + expression[expression.length - 1] : expression).prototype; + instance = Object.create(controllerPrototype || null); + + if (identifier) { + addIdentifier(locals, identifier, instance, constructor || expression.name); + } + + return extend(function $controllerInit() { + var result = $injector.invoke(expression, instance, locals, constructor); + if (result !== instance && (isObject(result) || isFunction(result))) { + instance = result; + if (identifier) { + // If result changed, re-assign controllerAs value to scope. + addIdentifier(locals, identifier, instance, constructor || expression.name); + } + } + return instance; + }, { + instance: instance, + identifier: identifier + }); + } + + instance = $injector.instantiate(expression, locals, constructor); + + if (identifier) { + addIdentifier(locals, identifier, instance, constructor || expression.name); + } + + return instance; + }; + + function addIdentifier(locals, identifier, instance, name) { + if (!(locals && isObject(locals.$scope))) { + throw minErr('$controller')('noscp', + 'Cannot export controller \'{0}\' as \'{1}\'! No $scope object provided via `locals`.', + name, identifier); + } + + locals.$scope[identifier] = instance; + } + }]; +} + +/** + * @ngdoc service + * @name $document + * @requires $window + * @this + * + * @description + * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object. + * + * @example + + +
+

$document title:

+

window.document title:

+
+
+ + angular.module('documentExample', []) + .controller('ExampleController', ['$scope', '$document', function($scope, $document) { + $scope.title = $document[0].title; + $scope.windowTitle = angular.element(window.document)[0].title; + }]); + +
+ */ +function $DocumentProvider() { + this.$get = ['$window', function(window) { + return jqLite(window.document); + }]; +} + + +/** + * @private + * @this + * Listens for document visibility change and makes the current status accessible. + */ +function $$IsDocumentHiddenProvider() { + this.$get = ['$document', '$rootScope', function($document, $rootScope) { + var doc = $document[0]; + var hidden = doc && doc.hidden; + + $document.on('visibilitychange', changeListener); + + $rootScope.$on('$destroy', function() { + $document.off('visibilitychange', changeListener); + }); + + function changeListener() { + hidden = doc.hidden; + } + + return function() { + return hidden; + }; + }]; +} + +/** + * @ngdoc service + * @name $exceptionHandler + * @requires ng.$log + * @this + * + * @description + * Any uncaught exception in angular expressions is delegated to this service. + * The default implementation simply delegates to `$log.error` which logs it into + * the browser console. + * + * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by + * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing. + * + * ## Example: + * + * The example below will overwrite the default `$exceptionHandler` in order to (a) log uncaught + * errors to the backend for later inspection by the developers and (b) to use `$log.warn()` instead + * of `$log.error()`. + * + * ```js + * angular. + * module('exceptionOverwrite', []). + * factory('$exceptionHandler', ['$log', 'logErrorsToBackend', function($log, logErrorsToBackend) { + * return function myExceptionHandler(exception, cause) { + * logErrorsToBackend(exception, cause); + * $log.warn(exception, cause); + * }; + * }]); + * ``` + * + *
+ * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind` + * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler} + * (unless executed during a digest). + * + * If you wish, you can manually delegate exceptions, e.g. + * `try { ... } catch(e) { $exceptionHandler(e); }` + * + * @param {Error} exception Exception associated with the error. + * @param {string=} cause Optional information about the context in which + * the error was thrown. + * + */ +function $ExceptionHandlerProvider() { + this.$get = ['$log', function($log) { + return function(exception, cause) { + $log.error.apply($log, arguments); + }; + }]; +} + +var $$ForceReflowProvider = /** @this */ function() { + this.$get = ['$document', function($document) { + return function(domNode) { + //the line below will force the browser to perform a repaint so + //that all the animated elements within the animation frame will + //be properly updated and drawn on screen. This is required to + //ensure that the preparation animation is properly flushed so that + //the active state picks up from there. DO NOT REMOVE THIS LINE. + //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH + //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND + //WILL TAKE YEARS AWAY FROM YOUR LIFE. + if (domNode) { + if (!domNode.nodeType && domNode instanceof jqLite) { + domNode = domNode[0]; + } + } else { + domNode = $document[0].body; + } + return domNode.offsetWidth + 1; + }; + }]; +}; + +var APPLICATION_JSON = 'application/json'; +var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'}; +var JSON_START = /^\[|^\{(?!\{)/; +var JSON_ENDS = { + '[': /]$/, + '{': /}$/ +}; +var JSON_PROTECTION_PREFIX = /^\)]\}',?\n/; +var $httpMinErr = minErr('$http'); + +function serializeValue(v) { + if (isObject(v)) { + return isDate(v) ? v.toISOString() : toJson(v); + } + return v; +} + + +/** @this */ +function $HttpParamSerializerProvider() { + /** + * @ngdoc service + * @name $httpParamSerializer + * @description + * + * Default {@link $http `$http`} params serializer that converts objects to strings + * according to the following rules: + * + * * `{'foo': 'bar'}` results in `foo=bar` + * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object) + * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element) + * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D` (stringified and encoded representation of an object) + * + * Note that serializer will sort the request parameters alphabetically. + * */ + + this.$get = function() { + return function ngParamSerializer(params) { + if (!params) return ''; + var parts = []; + forEachSorted(params, function(value, key) { + if (value === null || isUndefined(value)) return; + if (isArray(value)) { + forEach(value, function(v) { + parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v))); + }); + } else { + parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value))); + } + }); + + return parts.join('&'); + }; + }; +} + +/** @this */ +function $HttpParamSerializerJQLikeProvider() { + /** + * @ngdoc service + * @name $httpParamSerializerJQLike + * + * @description + * + * Alternative {@link $http `$http`} params serializer that follows + * jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic. + * The serializer will also sort the params alphabetically. + * + * To use it for serializing `$http` request parameters, set it as the `paramSerializer` property: + * + * ```js + * $http({ + * url: myUrl, + * method: 'GET', + * params: myParams, + * paramSerializer: '$httpParamSerializerJQLike' + * }); + * ``` + * + * It is also possible to set it as the default `paramSerializer` in the + * {@link $httpProvider#defaults `$httpProvider`}. + * + * Additionally, you can inject the serializer and use it explicitly, for example to serialize + * form data for submission: + * + * ```js + * .controller(function($http, $httpParamSerializerJQLike) { + * //... + * + * $http({ + * url: myUrl, + * method: 'POST', + * data: $httpParamSerializerJQLike(myData), + * headers: { + * 'Content-Type': 'application/x-www-form-urlencoded' + * } + * }); + * + * }); + * ``` + * + * */ + this.$get = function() { + return function jQueryLikeParamSerializer(params) { + if (!params) return ''; + var parts = []; + serialize(params, '', true); + return parts.join('&'); + + function serialize(toSerialize, prefix, topLevel) { + if (toSerialize === null || isUndefined(toSerialize)) return; + if (isArray(toSerialize)) { + forEach(toSerialize, function(value, index) { + serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']'); + }); + } else if (isObject(toSerialize) && !isDate(toSerialize)) { + forEachSorted(toSerialize, function(value, key) { + serialize(value, prefix + + (topLevel ? '' : '[') + + key + + (topLevel ? '' : ']')); + }); + } else { + parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize))); + } + } + }; + }; +} + +function defaultHttpResponseTransform(data, headers) { + if (isString(data)) { + // Strip json vulnerability protection prefix and trim whitespace + var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim(); + + if (tempData) { + var contentType = headers('Content-Type'); + if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) { + data = fromJson(tempData); + } + } + } + + return data; +} + +function isJsonLike(str) { + var jsonStart = str.match(JSON_START); + return jsonStart && JSON_ENDS[jsonStart[0]].test(str); +} + +/** + * Parse headers into key value object + * + * @param {string} headers Raw headers as a string + * @returns {Object} Parsed headers as key value object + */ +function parseHeaders(headers) { + var parsed = createMap(), i; + + function fillInParsed(key, val) { + if (key) { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + } + + if (isString(headers)) { + forEach(headers.split('\n'), function(line) { + i = line.indexOf(':'); + fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1))); + }); + } else if (isObject(headers)) { + forEach(headers, function(headerVal, headerKey) { + fillInParsed(lowercase(headerKey), trim(headerVal)); + }); + } + + return parsed; +} + + +/** + * Returns a function that provides access to parsed headers. + * + * Headers are lazy parsed when first requested. + * @see parseHeaders + * + * @param {(string|Object)} headers Headers to provide access to. + * @returns {function(string=)} Returns a getter function which if called with: + * + * - if called with an argument returns a single header value or null + * - if called with no arguments returns an object containing all headers. + */ +function headersGetter(headers) { + var headersObj; + + return function(name) { + if (!headersObj) headersObj = parseHeaders(headers); + + if (name) { + var value = headersObj[lowercase(name)]; + if (value === undefined) { + value = null; + } + return value; + } + + return headersObj; + }; +} + + +/** + * Chain all given functions + * + * This function is used for both request and response transforming + * + * @param {*} data Data to transform. + * @param {function(string=)} headers HTTP headers getter fn. + * @param {number} status HTTP status code of the response. + * @param {(Function|Array.)} fns Function or an array of functions. + * @returns {*} Transformed data. + */ +function transformData(data, headers, status, fns) { + if (isFunction(fns)) { + return fns(data, headers, status); + } + + forEach(fns, function(fn) { + data = fn(data, headers, status); + }); + + return data; +} + + +function isSuccess(status) { + return 200 <= status && status < 300; +} + + +/** + * @ngdoc provider + * @name $httpProvider + * @this + * + * @description + * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service. + * */ +function $HttpProvider() { + /** + * @ngdoc property + * @name $httpProvider#defaults + * @description + * + * Object containing default values for all {@link ng.$http $http} requests. + * + * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with + * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses + * by default. See {@link $http#caching $http Caching} for more information. + * + * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token. + * Defaults value is `'XSRF-TOKEN'`. + * + * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the + * XSRF token. Defaults value is `'X-XSRF-TOKEN'`. + * + * - **`defaults.headers`** - {Object} - Default headers for all $http requests. + * Refer to {@link ng.$http#setting-http-headers $http} for documentation on + * setting default headers. + * - **`defaults.headers.common`** + * - **`defaults.headers.post`** + * - **`defaults.headers.put`** + * - **`defaults.headers.patch`** + * + * + * - **`defaults.paramSerializer`** - `{string|function(Object):string}` - A function + * used to the prepare string representation of request parameters (specified as an object). + * If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}. + * Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}. + * + * - **`defaults.jsonpCallbackParam`** - `{string}` - the name of the query parameter that passes the name of the + * callback in a JSONP request. The value of this parameter will be replaced with the expression generated by the + * {@link $jsonpCallbacks} service. Defaults to `'callback'`. + * + **/ + var defaults = this.defaults = { + // transform incoming response data + transformResponse: [defaultHttpResponseTransform], + + // transform outgoing request data + transformRequest: [function(d) { + return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d; + }], + + // default headers + headers: { + common: { + 'Accept': 'application/json, text/plain, */*' + }, + post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON) + }, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + paramSerializer: '$httpParamSerializer', + + jsonpCallbackParam: 'callback' + }; + + var useApplyAsync = false; + /** + * @ngdoc method + * @name $httpProvider#useApplyAsync + * @description + * + * Configure $http service to combine processing of multiple http responses received at around + * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in + * significant performance improvement for bigger applications that make many HTTP requests + * concurrently (common during application bootstrap). + * + * Defaults to false. If no value is specified, returns the current configured value. + * + * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred + * "apply" on the next tick, giving time for subsequent requests in a roughly ~10ms window + * to load and share the same digest cycle. + * + * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining. + * otherwise, returns the current configured value. + **/ + this.useApplyAsync = function(value) { + if (isDefined(value)) { + useApplyAsync = !!value; + return this; + } + return useApplyAsync; + }; + + /** + * @ngdoc property + * @name $httpProvider#interceptors + * @description + * + * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http} + * pre-processing of request or postprocessing of responses. + * + * These service factories are ordered by request, i.e. they are applied in the same order as the + * array, on request, but reverse order, on response. + * + * {@link ng.$http#interceptors Interceptors detailed info} + **/ + var interceptorFactories = this.interceptors = []; + + this.$get = ['$browser', '$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', '$sce', + function($browser, $httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector, $sce) { + + var defaultCache = $cacheFactory('$http'); + + /** + * Make sure that default param serializer is exposed as a function + */ + defaults.paramSerializer = isString(defaults.paramSerializer) ? + $injector.get(defaults.paramSerializer) : defaults.paramSerializer; + + /** + * Interceptors stored in reverse order. Inner interceptors before outer interceptors. + * The reversal is needed so that we can build up the interception chain around the + * server request. + */ + var reversedInterceptors = []; + + forEach(interceptorFactories, function(interceptorFactory) { + reversedInterceptors.unshift(isString(interceptorFactory) + ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory)); + }); + + /** + * @ngdoc service + * @kind function + * @name $http + * @requires ng.$httpBackend + * @requires $cacheFactory + * @requires $rootScope + * @requires $q + * @requires $injector + * + * @description + * The `$http` service is a core Angular service that facilitates communication with the remote + * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest) + * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP). + * + * For unit testing applications that use `$http` service, see + * {@link ngMock.$httpBackend $httpBackend mock}. + * + * For a higher level of abstraction, please check out the {@link ngResource.$resource + * $resource} service. + * + * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by + * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage + * it is important to familiarize yourself with these APIs and the guarantees they provide. + * + * + * ## General usage + * The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} — + * that is used to generate an HTTP request and returns a {@link ng.$q promise}. + * + * ```js + * // Simple GET request example: + * $http({ + * method: 'GET', + * url: '/someUrl' + * }).then(function successCallback(response) { + * // this callback will be called asynchronously + * // when the response is available + * }, function errorCallback(response) { + * // called asynchronously if an error occurs + * // or server returns response with an error status. + * }); + * ``` + * + * The response object has these properties: + * + * - **data** – `{string|Object}` – The response body transformed with the transform + * functions. + * - **status** – `{number}` – HTTP status code of the response. + * - **headers** – `{function([headerName])}` – Header getter function. + * - **config** – `{Object}` – The configuration object that was used to generate the request. + * - **statusText** – `{string}` – HTTP status text of the response. + * + * A response status code between 200 and 299 is considered a success status and will result in + * the success callback being called. Any response status code outside of that range is + * considered an error status and will result in the error callback being called. + * Also, status codes less than -1 are normalized to zero. -1 usually means the request was + * aborted, e.g. using a `config.timeout`. + * Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning + * that the outcome (success or error) will be determined by the final response status code. + * + * + * ## Shortcut methods + * + * Shortcut methods are also available. All shortcut methods require passing in the URL, and + * request data must be passed in for POST/PUT requests. An optional config can be passed as the + * last argument. + * + * ```js + * $http.get('/someUrl', config).then(successCallback, errorCallback); + * $http.post('/someUrl', data, config).then(successCallback, errorCallback); + * ``` + * + * Complete list of shortcut methods: + * + * - {@link ng.$http#get $http.get} + * - {@link ng.$http#head $http.head} + * - {@link ng.$http#post $http.post} + * - {@link ng.$http#put $http.put} + * - {@link ng.$http#delete $http.delete} + * - {@link ng.$http#jsonp $http.jsonp} + * - {@link ng.$http#patch $http.patch} + * + * + * ## Writing Unit Tests that use $http + * When unit testing (using {@link ngMock ngMock}), it is necessary to call + * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending + * request using trained responses. + * + * ``` + * $httpBackend.expectGET(...); + * $http.get(...); + * $httpBackend.flush(); + * ``` + * + * ## Setting HTTP Headers + * + * The $http service will automatically add certain HTTP headers to all requests. These defaults + * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration + * object, which currently contains this default configuration: + * + * - `$httpProvider.defaults.headers.common` (headers that are common for all requests): + * - Accept: application/json, text/plain, \*/\* + * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests) + * - `Content-Type: application/json` + * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests) + * - `Content-Type: application/json` + * + * To add or overwrite these defaults, simply add or remove a property from these configuration + * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object + * with the lowercased HTTP method name as the key, e.g. + * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }`. + * + * The defaults can also be set at runtime via the `$http.defaults` object in the same + * fashion. For example: + * + * ``` + * module.run(function($http) { + * $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'; + * }); + * ``` + * + * In addition, you can supply a `headers` property in the config object passed when + * calling `$http(config)`, which overrides the defaults without changing them globally. + * + * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis, + * Use the `headers` property, setting the desired header to `undefined`. For example: + * + * ```js + * var req = { + * method: 'POST', + * url: 'http://example.com', + * headers: { + * 'Content-Type': undefined + * }, + * data: { test: 'test' } + * } + * + * $http(req).then(function(){...}, function(){...}); + * ``` + * + * ## Transforming Requests and Responses + * + * Both requests and responses can be transformed using transformation functions: `transformRequest` + * and `transformResponse`. These properties can be a single function that returns + * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions, + * which allows you to `push` or `unshift` a new transformation function into the transformation chain. + * + *
+ * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline. + * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference). + * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest + * function will be reflected on the scope and in any templates where the object is data-bound. + * To prevent this, transform functions should have no side-effects. + * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return. + *
+ * + * ### Default Transformations + * + * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and + * `defaults.transformResponse` properties. If a request does not provide its own transformations + * then these will be applied. + * + * You can augment or replace the default transformations by modifying these properties by adding to or + * replacing the array. + * + * Angular provides the following default transformations: + * + * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`): + * + * - If the `data` property of the request configuration object contains an object, serialize it + * into JSON format. + * + * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`): + * + * - If XSRF prefix is detected, strip it (see Security Considerations section below). + * - If JSON response is detected, deserialize it using a JSON parser. + * + * + * ### Overriding the Default Transformations Per Request + * + * If you wish to override the request/response transformations only for a single request then provide + * `transformRequest` and/or `transformResponse` properties on the configuration object passed + * into `$http`. + * + * Note that if you provide these properties on the config object the default transformations will be + * overwritten. If you wish to augment the default transformations then you must include them in your + * local transformation array. + * + * The following code demonstrates adding a new response transformation to be run after the default response + * transformations have been run. + * + * ```js + * function appendTransform(defaults, transform) { + * + * // We can't guarantee that the default transformation is an array + * defaults = angular.isArray(defaults) ? defaults : [defaults]; + * + * // Append the new transformation to the defaults + * return defaults.concat(transform); + * } + * + * $http({ + * url: '...', + * method: 'GET', + * transformResponse: appendTransform($http.defaults.transformResponse, function(value) { + * return doTransform(value); + * }) + * }); + * ``` + * + * + * ## Caching + * + * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must + * set the config.cache value or the default cache value to TRUE or to a cache object (created + * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes + * precedence over the default cache value. + * + * In order to: + * * cache all responses - set the default cache value to TRUE or to a cache object + * * cache a specific response - set config.cache value to TRUE or to a cache object + * + * If caching is enabled, but neither the default cache nor config.cache are set to a cache object, + * then the default `$cacheFactory("$http")` object is used. + * + * The default cache value can be set by updating the + * {@link ng.$http#defaults `$http.defaults.cache`} property or the + * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property. + * + * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using + * the relevant cache object. The next time the same request is made, the response is returned + * from the cache without sending a request to the server. + * + * Take note that: + * + * * Only GET and JSONP requests are cached. + * * The cache key is the request URL including search parameters; headers are not considered. + * * Cached responses are returned asynchronously, in the same way as responses from the server. + * * If multiple identical requests are made using the same cache, which is not yet populated, + * one request will be made to the server and remaining requests will return the same response. + * * A cache-control header on the response does not affect if or how responses are cached. + * + * + * ## Interceptors + * + * Before you start creating interceptors, be sure to understand the + * {@link ng.$q $q and deferred/promise APIs}. + * + * For purposes of global error handling, authentication, or any kind of synchronous or + * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be + * able to intercept requests before they are handed to the server and + * responses before they are handed over to the application code that + * initiated these requests. The interceptors leverage the {@link ng.$q + * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing. + * + * The interceptors are service factories that are registered with the `$httpProvider` by + * adding them to the `$httpProvider.interceptors` array. The factory is called and + * injected with dependencies (if specified) and returns the interceptor. + * + * There are two kinds of interceptors (and two kinds of rejection interceptors): + * + * * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to + * modify the `config` object or create a new one. The function needs to return the `config` + * object directly, or a promise containing the `config` or a new `config` object. + * * `requestError`: interceptor gets called when a previous interceptor threw an error or + * resolved with a rejection. + * * `response`: interceptors get called with http `response` object. The function is free to + * modify the `response` object or create a new one. The function needs to return the `response` + * object directly, or as a promise containing the `response` or a new `response` object. + * * `responseError`: interceptor gets called when a previous interceptor threw an error or + * resolved with a rejection. + * + * + * ```js + * // register the interceptor as a service + * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { + * return { + * // optional method + * 'request': function(config) { + * // do something on success + * return config; + * }, + * + * // optional method + * 'requestError': function(rejection) { + * // do something on error + * if (canRecover(rejection)) { + * return responseOrNewPromise + * } + * return $q.reject(rejection); + * }, + * + * + * + * // optional method + * 'response': function(response) { + * // do something on success + * return response; + * }, + * + * // optional method + * 'responseError': function(rejection) { + * // do something on error + * if (canRecover(rejection)) { + * return responseOrNewPromise + * } + * return $q.reject(rejection); + * } + * }; + * }); + * + * $httpProvider.interceptors.push('myHttpInterceptor'); + * + * + * // alternatively, register the interceptor via an anonymous factory + * $httpProvider.interceptors.push(function($q, dependency1, dependency2) { + * return { + * 'request': function(config) { + * // same as above + * }, + * + * 'response': function(response) { + * // same as above + * } + * }; + * }); + * ``` + * + * ## Security Considerations + * + * When designing web applications, consider security threats from: + * + * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx) + * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) + * + * Both server and the client must cooperate in order to eliminate these threats. Angular comes + * pre-configured with strategies that address these issues, but for this to work backend server + * cooperation is required. + * + * ### JSON Vulnerability Protection + * + * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx) + * allows third party website to turn your JSON resource URL into + * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To + * counter this your server can prefix all JSON requests with following string `")]}',\n"`. + * Angular will automatically strip the prefix before processing it as JSON. + * + * For example if your server needs to return: + * ```js + * ['one','two'] + * ``` + * + * which is vulnerable to attack, your server can return: + * ```js + * )]}', + * ['one','two'] + * ``` + * + * Angular will strip the prefix, before processing the JSON. + * + * + * ### Cross Site Request Forgery (XSRF) Protection + * + * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by + * which the attacker can trick an authenticated user into unknowingly executing actions on your + * website. Angular provides a mechanism to counter XSRF. When performing XHR requests, the + * $http service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP + * header (`X-XSRF-TOKEN`). Since only JavaScript that runs on your domain could read the + * cookie, your server can be assured that the XHR came from JavaScript running on your domain. + * The header will not be set for cross-domain requests. + * + * To take advantage of this, your server needs to set a token in a JavaScript readable session + * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the + * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure + * that only JavaScript running on your domain could have sent the request. The token must be + * unique for each user and must be verifiable by the server (to prevent the JavaScript from + * making up its own tokens). We recommend that the token is a digest of your site's + * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography)) + * for added security. + * + * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName + * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time, + * or the per-request config object. + * + * In order to prevent collisions in environments where multiple Angular apps share the + * same domain or subdomain, we recommend that each application uses unique cookie name. + * + * @param {object} config Object describing the request to be made and how it should be + * processed. The object has following properties: + * + * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc) + * - **url** – `{string|TrustedObject}` – Absolute or relative URL of the resource that is being requested; + * or an object created by a call to `$sce.trustAsResourceUrl(url)`. + * - **params** – `{Object.}` – Map of strings or objects which will be serialized + * with the `paramSerializer` and appended as GET parameters. + * - **data** – `{string|Object}` – Data to be sent as the request message data. + * - **headers** – `{Object}` – Map of strings or functions which return strings representing + * HTTP headers to send to the server. If the return value of a function is null, the + * header will not be sent. Functions accept a config object as an argument. + * - **eventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object. + * To bind events to the XMLHttpRequest upload object, use `uploadEventHandlers`. + * The handler will be called in the context of a `$apply` block. + * - **uploadEventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest upload + * object. To bind events to the XMLHttpRequest object, use `eventHandlers`. + * The handler will be called in the context of a `$apply` block. + * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token. + * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token. + * - **transformRequest** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * See {@link ng.$http#overriding-the-default-transformations-per-request + * Overriding the Default Transformations} + * - **transformResponse** – + * `{function(data, headersGetter, status)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * response body, headers and status and returns its transformed (typically deserialized) version. + * See {@link ng.$http#overriding-the-default-transformations-per-request + * Overriding the Default Transformations} + * - **paramSerializer** - `{string|function(Object):string}` - A function used to + * prepare the string representation of request parameters (specified as an object). + * If specified as string, it is interpreted as function registered with the + * {@link $injector $injector}, which means you can create your own serializer + * by registering it as a {@link auto.$provide#service service}. + * The default serializer is the {@link $httpParamSerializer $httpParamSerializer}; + * alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike} + * - **cache** – `{boolean|Object}` – A boolean value or object created with + * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response. + * See {@link $http#caching $http Caching} for more information. + * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} + * that should abort the request when resolved. + * - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the + * XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials) + * for more information. + * - **responseType** - `{string}` - see + * [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype). + * + * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object + * when the request succeeds or fails. + * + * + * @property {Array.} pendingRequests Array of config objects for currently pending + * requests. This is primarily meant to be used for debugging purposes. + * + * + * @example + + +
+ + +
+ + + +
http status code: {{status}}
+
http response data: {{data}}
+
+
+ + angular.module('httpExample', []) + .config(['$sceDelegateProvider', function($sceDelegateProvider) { + // We must whitelist the JSONP endpoint that we are using to show that we trust it + $sceDelegateProvider.resourceUrlWhitelist([ + 'self', + 'https://angularjs.org/**' + ]); + }]) + .controller('FetchController', ['$scope', '$http', '$templateCache', + function($scope, $http, $templateCache) { + $scope.method = 'GET'; + $scope.url = 'http-hello.html'; + + $scope.fetch = function() { + $scope.code = null; + $scope.response = null; + + $http({method: $scope.method, url: $scope.url, cache: $templateCache}). + then(function(response) { + $scope.status = response.status; + $scope.data = response.data; + }, function(response) { + $scope.data = response.data || 'Request failed'; + $scope.status = response.status; + }); + }; + + $scope.updateModel = function(method, url) { + $scope.method = method; + $scope.url = url; + }; + }]); + + + Hello, $http! + + + var status = element(by.binding('status')); + var data = element(by.binding('data')); + var fetchBtn = element(by.id('fetchbtn')); + var sampleGetBtn = element(by.id('samplegetbtn')); + var invalidJsonpBtn = element(by.id('invalidjsonpbtn')); + + it('should make an xhr GET request', function() { + sampleGetBtn.click(); + fetchBtn.click(); + expect(status.getText()).toMatch('200'); + expect(data.getText()).toMatch(/Hello, \$http!/); + }); + +// Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185 +// it('should make a JSONP request to angularjs.org', function() { +// var sampleJsonpBtn = element(by.id('samplejsonpbtn')); +// sampleJsonpBtn.click(); +// fetchBtn.click(); +// expect(status.getText()).toMatch('200'); +// expect(data.getText()).toMatch(/Super Hero!/); +// }); + + it('should make JSONP request to invalid URL and invoke the error handler', + function() { + invalidJsonpBtn.click(); + fetchBtn.click(); + expect(status.getText()).toMatch('0'); + expect(data.getText()).toMatch('Request failed'); + }); + +
+ */ + function $http(requestConfig) { + + if (!isObject(requestConfig)) { + throw minErr('$http')('badreq', 'Http request configuration must be an object. Received: {0}', requestConfig); + } + + if (!isString($sce.valueOf(requestConfig.url))) { + throw minErr('$http')('badreq', 'Http request configuration url must be a string or a $sce trusted object. Received: {0}', requestConfig.url); + } + + var config = extend({ + method: 'get', + transformRequest: defaults.transformRequest, + transformResponse: defaults.transformResponse, + paramSerializer: defaults.paramSerializer, + jsonpCallbackParam: defaults.jsonpCallbackParam + }, requestConfig); + + config.headers = mergeHeaders(requestConfig); + config.method = uppercase(config.method); + config.paramSerializer = isString(config.paramSerializer) ? + $injector.get(config.paramSerializer) : config.paramSerializer; + + $browser.$$incOutstandingRequestCount(); + + var requestInterceptors = []; + var responseInterceptors = []; + var promise = $q.resolve(config); + + // apply interceptors + forEach(reversedInterceptors, function(interceptor) { + if (interceptor.request || interceptor.requestError) { + requestInterceptors.unshift(interceptor.request, interceptor.requestError); + } + if (interceptor.response || interceptor.responseError) { + responseInterceptors.push(interceptor.response, interceptor.responseError); + } + }); + + promise = chainInterceptors(promise, requestInterceptors); + promise = promise.then(serverRequest); + promise = chainInterceptors(promise, responseInterceptors); + promise = promise.finally(completeOutstandingRequest); + + return promise; + + + function chainInterceptors(promise, interceptors) { + for (var i = 0, ii = interceptors.length; i < ii;) { + var thenFn = interceptors[i++]; + var rejectFn = interceptors[i++]; + + promise = promise.then(thenFn, rejectFn); + } + + interceptors.length = 0; + + return promise; + } + + function completeOutstandingRequest() { + $browser.$$completeOutstandingRequest(noop); + } + + function executeHeaderFns(headers, config) { + var headerContent, processedHeaders = {}; + + forEach(headers, function(headerFn, header) { + if (isFunction(headerFn)) { + headerContent = headerFn(config); + if (headerContent != null) { + processedHeaders[header] = headerContent; + } + } else { + processedHeaders[header] = headerFn; + } + }); + + return processedHeaders; + } + + function mergeHeaders(config) { + var defHeaders = defaults.headers, + reqHeaders = extend({}, config.headers), + defHeaderName, lowercaseDefHeaderName, reqHeaderName; + + defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]); + + // using for-in instead of forEach to avoid unnecessary iteration after header has been found + defaultHeadersIteration: + for (defHeaderName in defHeaders) { + lowercaseDefHeaderName = lowercase(defHeaderName); + + for (reqHeaderName in reqHeaders) { + if (lowercase(reqHeaderName) === lowercaseDefHeaderName) { + continue defaultHeadersIteration; + } + } + + reqHeaders[defHeaderName] = defHeaders[defHeaderName]; + } + + // execute if header value is a function for merged headers + return executeHeaderFns(reqHeaders, shallowCopy(config)); + } + + function serverRequest(config) { + var headers = config.headers; + var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest); + + // strip content-type if data is undefined + if (isUndefined(reqData)) { + forEach(headers, function(value, header) { + if (lowercase(header) === 'content-type') { + delete headers[header]; + } + }); + } + + if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) { + config.withCredentials = defaults.withCredentials; + } + + // send request + return sendReq(config, reqData).then(transformResponse, transformResponse); + } + + function transformResponse(response) { + // make a copy since the response must be cacheable + var resp = extend({}, response); + resp.data = transformData(response.data, response.headers, response.status, + config.transformResponse); + return (isSuccess(response.status)) + ? resp + : $q.reject(resp); + } + } + + $http.pendingRequests = []; + + /** + * @ngdoc method + * @name $http#get + * + * @description + * Shortcut method to perform `GET` request. + * + * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested; + * or an object created by a call to `$sce.trustAsResourceUrl(url)`. + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name $http#delete + * + * @description + * Shortcut method to perform `DELETE` request. + * + * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested; + * or an object created by a call to `$sce.trustAsResourceUrl(url)`. + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name $http#head + * + * @description + * Shortcut method to perform `HEAD` request. + * + * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested; + * or an object created by a call to `$sce.trustAsResourceUrl(url)`. + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name $http#jsonp + * + * @description + * Shortcut method to perform `JSONP` request. + * + * Note that, since JSONP requests are sensitive because the response is given full access to the browser, + * the url must be declared, via {@link $sce} as a trusted resource URL. + * You can trust a URL by adding it to the whitelist via + * {@link $sceDelegateProvider#resourceUrlWhitelist `$sceDelegateProvider.resourceUrlWhitelist`} or + * by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}. + * + * JSONP requests must specify a callback to be used in the response from the server. This callback + * is passed as a query parameter in the request. You must specify the name of this parameter by + * setting the `jsonpCallbackParam` property on the request config object. + * + * ``` + * $http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'}) + * ``` + * + * You can also specify a default callback parameter name in `$http.defaults.jsonpCallbackParam`. + * Initially this is set to `'callback'`. + * + *
+ * You can no longer use the `JSON_CALLBACK` string as a placeholder for specifying where the callback + * parameter value should go. + *
+ * + * If you would like to customise where and how the callbacks are stored then try overriding + * or decorating the {@link $jsonpCallbacks} service. + * + * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested; + * or an object created by a call to `$sce.trustAsResourceUrl(url)`. + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + createShortMethods('get', 'delete', 'head', 'jsonp'); + + /** + * @ngdoc method + * @name $http#post + * + * @description + * Shortcut method to perform `POST` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name $http#put + * + * @description + * Shortcut method to perform `PUT` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name $http#patch + * + * @description + * Shortcut method to perform `PATCH` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + createShortMethodsWithData('post', 'put', 'patch'); + + /** + * @ngdoc property + * @name $http#defaults + * + * @description + * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of + * default headers, withCredentials as well as request and response transformations. + * + * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above. + */ + $http.defaults = defaults; + + + return $http; + + + function createShortMethods(names) { + forEach(arguments, function(name) { + $http[name] = function(url, config) { + return $http(extend({}, config || {}, { + method: name, + url: url + })); + }; + }); + } + + + function createShortMethodsWithData(name) { + forEach(arguments, function(name) { + $http[name] = function(url, data, config) { + return $http(extend({}, config || {}, { + method: name, + url: url, + data: data + })); + }; + }); + } + + + /** + * Makes the request. + * + * !!! ACCESSES CLOSURE VARS: + * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests + */ + function sendReq(config, reqData) { + var deferred = $q.defer(), + promise = deferred.promise, + cache, + cachedResp, + reqHeaders = config.headers, + isJsonp = lowercase(config.method) === 'jsonp', + url = config.url; + + if (isJsonp) { + // JSONP is a pretty sensitive operation where we're allowing a script to have full access to + // our DOM and JS space. So we require that the URL satisfies SCE.RESOURCE_URL. + url = $sce.getTrustedResourceUrl(url); + } else if (!isString(url)) { + // If it is not a string then the URL must be a $sce trusted object + url = $sce.valueOf(url); + } + + url = buildUrl(url, config.paramSerializer(config.params)); + + if (isJsonp) { + // Check the url and add the JSONP callback placeholder + url = sanitizeJsonpCallbackParam(url, config.jsonpCallbackParam); + } + + $http.pendingRequests.push(config); + promise.then(removePendingReq, removePendingReq); + + if ((config.cache || defaults.cache) && config.cache !== false && + (config.method === 'GET' || config.method === 'JSONP')) { + cache = isObject(config.cache) ? config.cache + : isObject(defaults.cache) ? defaults.cache + : defaultCache; + } + + if (cache) { + cachedResp = cache.get(url); + if (isDefined(cachedResp)) { + if (isPromiseLike(cachedResp)) { + // cached request has already been sent, but there is no response yet + cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult); + } else { + // serving from cache + if (isArray(cachedResp)) { + resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]); + } else { + resolvePromise(cachedResp, 200, {}, 'OK'); + } + } + } else { + // put the promise for the non-transformed response into cache as a placeholder + cache.put(url, promise); + } + } + + + // if we won't have the response in cache, set the xsrf headers and + // send the request to the backend + if (isUndefined(cachedResp)) { + var xsrfValue = urlIsSameOrigin(config.url) + ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName] + : undefined; + if (xsrfValue) { + reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue; + } + + $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, + config.withCredentials, config.responseType, + createApplyHandlers(config.eventHandlers), + createApplyHandlers(config.uploadEventHandlers)); + } + + return promise; + + function createApplyHandlers(eventHandlers) { + if (eventHandlers) { + var applyHandlers = {}; + forEach(eventHandlers, function(eventHandler, key) { + applyHandlers[key] = function(event) { + if (useApplyAsync) { + $rootScope.$applyAsync(callEventHandler); + } else if ($rootScope.$$phase) { + callEventHandler(); + } else { + $rootScope.$apply(callEventHandler); + } + + function callEventHandler() { + eventHandler(event); + } + }; + }); + return applyHandlers; + } + } + + + /** + * Callback registered to $httpBackend(): + * - caches the response if desired + * - resolves the raw $http promise + * - calls $apply + */ + function done(status, response, headersString, statusText) { + if (cache) { + if (isSuccess(status)) { + cache.put(url, [status, response, parseHeaders(headersString), statusText]); + } else { + // remove promise from the cache + cache.remove(url); + } + } + + function resolveHttpPromise() { + resolvePromise(response, status, headersString, statusText); + } + + if (useApplyAsync) { + $rootScope.$applyAsync(resolveHttpPromise); + } else { + resolveHttpPromise(); + if (!$rootScope.$$phase) $rootScope.$apply(); + } + } + + + /** + * Resolves the raw $http promise. + */ + function resolvePromise(response, status, headers, statusText) { + //status: HTTP response status code, 0, -1 (aborted by timeout / promise) + status = status >= -1 ? status : 0; + + (isSuccess(status) ? deferred.resolve : deferred.reject)({ + data: response, + status: status, + headers: headersGetter(headers), + config: config, + statusText: statusText + }); + } + + function resolvePromiseWithResult(result) { + resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText); + } + + function removePendingReq() { + var idx = $http.pendingRequests.indexOf(config); + if (idx !== -1) $http.pendingRequests.splice(idx, 1); + } + } + + + function buildUrl(url, serializedParams) { + if (serializedParams.length > 0) { + url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams; + } + return url; + } + + function sanitizeJsonpCallbackParam(url, key) { + if (/[&?][^=]+=JSON_CALLBACK/.test(url)) { + // Throw if the url already contains a reference to JSON_CALLBACK + throw $httpMinErr('badjsonp', 'Illegal use of JSON_CALLBACK in url, "{0}"', url); + } + + var callbackParamRegex = new RegExp('[&?]' + key + '='); + if (callbackParamRegex.test(url)) { + // Throw if the callback param was already provided + throw $httpMinErr('badjsonp', 'Illegal use of callback param, "{0}", in url, "{1}"', key, url); + } + + // Add in the JSON_CALLBACK callback param value + url += ((url.indexOf('?') === -1) ? '?' : '&') + key + '=JSON_CALLBACK'; + + return url; + } + }]; +} + +/** + * @ngdoc service + * @name $xhrFactory + * @this + * + * @description + * Factory function used to create XMLHttpRequest objects. + * + * Replace or decorate this service to create your own custom XMLHttpRequest objects. + * + * ``` + * angular.module('myApp', []) + * .factory('$xhrFactory', function() { + * return function createXhr(method, url) { + * return new window.XMLHttpRequest({mozSystem: true}); + * }; + * }); + * ``` + * + * @param {string} method HTTP method of the request (GET, POST, PUT, ..) + * @param {string} url URL of the request. + */ +function $xhrFactoryProvider() { + this.$get = function() { + return function createXhr() { + return new window.XMLHttpRequest(); + }; + }; +} + +/** + * @ngdoc service + * @name $httpBackend + * @requires $jsonpCallbacks + * @requires $document + * @requires $xhrFactory + * @this + * + * @description + * HTTP backend used by the {@link ng.$http service} that delegates to + * XMLHttpRequest object or JSONP and deals with browser incompatibilities. + * + * You should never need to use this service directly, instead use the higher-level abstractions: + * {@link ng.$http $http} or {@link ngResource.$resource $resource}. + * + * During testing this implementation is swapped with {@link ngMock.$httpBackend mock + * $httpBackend} which can be trained with responses. + */ +function $HttpBackendProvider() { + this.$get = ['$browser', '$jsonpCallbacks', '$document', '$xhrFactory', function($browser, $jsonpCallbacks, $document, $xhrFactory) { + return createHttpBackend($browser, $xhrFactory, $browser.defer, $jsonpCallbacks, $document[0]); + }]; +} + +function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) { + // TODO(vojta): fix the signature + return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) { + url = url || $browser.url(); + + if (lowercase(method) === 'jsonp') { + var callbackPath = callbacks.createCallback(url); + var jsonpDone = jsonpReq(url, callbackPath, function(status, text) { + // jsonpReq only ever sets status to 200 (OK), 404 (ERROR) or -1 (WAITING) + var response = (status === 200) && callbacks.getResponse(callbackPath); + completeRequest(callback, status, response, '', text); + callbacks.removeCallback(callbackPath); + }); + } else { + + var xhr = createXhr(method, url); + + xhr.open(method, url, true); + forEach(headers, function(value, key) { + if (isDefined(value)) { + xhr.setRequestHeader(key, value); + } + }); + + xhr.onload = function requestLoaded() { + var statusText = xhr.statusText || ''; + + // responseText is the old-school way of retrieving response (supported by IE9) + // response/responseType properties were introduced in XHR Level2 spec (supported by IE10) + var response = ('response' in xhr) ? xhr.response : xhr.responseText; + + // normalize IE9 bug (http://bugs.jquery.com/ticket/1450) + var status = xhr.status === 1223 ? 204 : xhr.status; + + // fix status code when it is 0 (0 status is undocumented). + // Occurs when accessing file resources or on Android 4.1 stock browser + // while retrieving files from application cache. + if (status === 0) { + status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0; + } + + completeRequest(callback, + status, + response, + xhr.getAllResponseHeaders(), + statusText); + }; + + var requestError = function() { + // The response is always empty + // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error + completeRequest(callback, -1, null, null, ''); + }; + + xhr.onerror = requestError; + xhr.onabort = requestError; + xhr.ontimeout = requestError; + + forEach(eventHandlers, function(value, key) { + xhr.addEventListener(key, value); + }); + + forEach(uploadEventHandlers, function(value, key) { + xhr.upload.addEventListener(key, value); + }); + + if (withCredentials) { + xhr.withCredentials = true; + } + + if (responseType) { + try { + xhr.responseType = responseType; + } catch (e) { + // WebKit added support for the json responseType value on 09/03/2013 + // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are + // known to throw when setting the value "json" as the response type. Other older + // browsers implementing the responseType + // + // The json response type can be ignored if not supported, because JSON payloads are + // parsed on the client-side regardless. + if (responseType !== 'json') { + throw e; + } + } + } + + xhr.send(isUndefined(post) ? null : post); + } + + if (timeout > 0) { + var timeoutId = $browserDefer(timeoutRequest, timeout); + } else if (isPromiseLike(timeout)) { + timeout.then(timeoutRequest); + } + + + function timeoutRequest() { + if (jsonpDone) { + jsonpDone(); + } + if (xhr) { + xhr.abort(); + } + } + + function completeRequest(callback, status, response, headersString, statusText) { + // cancel timeout and subsequent timeout promise resolution + if (isDefined(timeoutId)) { + $browserDefer.cancel(timeoutId); + } + jsonpDone = xhr = null; + + callback(status, response, headersString, statusText); + } + }; + + function jsonpReq(url, callbackPath, done) { + url = url.replace('JSON_CALLBACK', callbackPath); + // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.: + // - fetches local scripts via XHR and evals them + // - adds and immediately removes script elements from the document + var script = rawDocument.createElement('script'), callback = null; + script.type = 'text/javascript'; + script.src = url; + script.async = true; + + callback = function(event) { + script.removeEventListener('load', callback); + script.removeEventListener('error', callback); + rawDocument.body.removeChild(script); + script = null; + var status = -1; + var text = 'unknown'; + + if (event) { + if (event.type === 'load' && !callbacks.wasCalled(callbackPath)) { + event = { type: 'error' }; + } + text = event.type; + status = event.type === 'error' ? 404 : 200; + } + + if (done) { + done(status, text); + } + }; + + script.addEventListener('load', callback); + script.addEventListener('error', callback); + rawDocument.body.appendChild(script); + return callback; + } +} + +var $interpolateMinErr = angular.$interpolateMinErr = minErr('$interpolate'); +$interpolateMinErr.throwNoconcat = function(text) { + throw $interpolateMinErr('noconcat', + 'Error while interpolating: {0}\nStrict Contextual Escaping disallows ' + + 'interpolations that concatenate multiple expressions when a trusted value is ' + + 'required. See http://docs.angularjs.org/api/ng.$sce', text); +}; + +$interpolateMinErr.interr = function(text, err) { + return $interpolateMinErr('interr', 'Can\'t interpolate: {0}\n{1}', text, err.toString()); +}; + +/** + * @ngdoc provider + * @name $interpolateProvider + * @this + * + * @description + * + * Used for configuring the interpolation markup. Defaults to `{{` and `}}`. + * + *
+ * This feature is sometimes used to mix different markup languages, e.g. to wrap an Angular + * template within a Python Jinja template (or any other template language). Mixing templating + * languages is **very dangerous**. The embedding template language will not safely escape Angular + * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS) + * security bugs! + *
+ * + * @example + + + +
+ //demo.label// +
+
+ + it('should interpolate binding with custom symbols', function() { + expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.'); + }); + +
+ */ +function $InterpolateProvider() { + var startSymbol = '{{'; + var endSymbol = '}}'; + + /** + * @ngdoc method + * @name $interpolateProvider#startSymbol + * @description + * Symbol to denote start of expression in the interpolated string. Defaults to `{{`. + * + * @param {string=} value new value to set the starting symbol to. + * @returns {string|self} Returns the symbol when used as getter and self if used as setter. + */ + this.startSymbol = function(value) { + if (value) { + startSymbol = value; + return this; + } else { + return startSymbol; + } + }; + + /** + * @ngdoc method + * @name $interpolateProvider#endSymbol + * @description + * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`. + * + * @param {string=} value new value to set the ending symbol to. + * @returns {string|self} Returns the symbol when used as getter and self if used as setter. + */ + this.endSymbol = function(value) { + if (value) { + endSymbol = value; + return this; + } else { + return endSymbol; + } + }; + + + this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) { + var startSymbolLength = startSymbol.length, + endSymbolLength = endSymbol.length, + escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'), + escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g'); + + function escape(ch) { + return '\\\\\\' + ch; + } + + function unescapeText(text) { + return text.replace(escapedStartRegexp, startSymbol). + replace(escapedEndRegexp, endSymbol); + } + + // TODO: this is the same as the constantWatchDelegate in parse.js + function constantWatchDelegate(scope, listener, objectEquality, constantInterp) { + var unwatch = scope.$watch(function constantInterpolateWatch(scope) { + unwatch(); + return constantInterp(scope); + }, listener, objectEquality); + return unwatch; + } + + /** + * @ngdoc service + * @name $interpolate + * @kind function + * + * @requires $parse + * @requires $sce + * + * @description + * + * Compiles a string with markup into an interpolation function. This service is used by the + * HTML {@link ng.$compile $compile} service for data binding. See + * {@link ng.$interpolateProvider $interpolateProvider} for configuring the + * interpolation markup. + * + * + * ```js + * var $interpolate = ...; // injected + * var exp = $interpolate('Hello {{name | uppercase}}!'); + * expect(exp({name:'Angular'})).toEqual('Hello ANGULAR!'); + * ``` + * + * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is + * `true`, the interpolation function will return `undefined` unless all embedded expressions + * evaluate to a value other than `undefined`. + * + * ```js + * var $interpolate = ...; // injected + * var context = {greeting: 'Hello', name: undefined }; + * + * // default "forgiving" mode + * var exp = $interpolate('{{greeting}} {{name}}!'); + * expect(exp(context)).toEqual('Hello !'); + * + * // "allOrNothing" mode + * exp = $interpolate('{{greeting}} {{name}}!', false, null, true); + * expect(exp(context)).toBeUndefined(); + * context.name = 'Angular'; + * expect(exp(context)).toEqual('Hello Angular!'); + * ``` + * + * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior. + * + * #### Escaped Interpolation + * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers + * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash). + * It will be rendered as a regular start/end marker, and will not be interpreted as an expression + * or binding. + * + * This enables web-servers to prevent script injection attacks and defacing attacks, to some + * degree, while also enabling code examples to work without relying on the + * {@link ng.directive:ngNonBindable ngNonBindable} directive. + * + * **For security purposes, it is strongly encouraged that web servers escape user-supplied data, + * replacing angle brackets (<, >) with &lt; and &gt; respectively, and replacing all + * interpolation start/end markers with their escaped counterparts.** + * + * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered + * output when the $interpolate service processes the text. So, for HTML elements interpolated + * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter + * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such, + * this is typically useful only when user-data is used in rendering a template from the server, or + * when otherwise untrusted data is used by a directive. + * + * + * + *
+ *

{{apptitle}}: \{\{ username = "defaced value"; \}\} + *

+ *

{{username}} attempts to inject code which will deface the + * application, but fails to accomplish their task, because the server has correctly + * escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash) + * characters.

+ *

Instead, the result of the attempted script injection is visible, and can be removed + * from the database by an administrator.

+ *
+ *
+ *
+ * + * @knownIssue + * It is currently not possible for an interpolated expression to contain the interpolation end + * symbol. For example, `{{ '}}' }}` will be incorrectly interpreted as `{{ ' }}` + `' }}`, i.e. + * an interpolated expression consisting of a single-quote (`'`) and the `' }}` string. + * + * @knownIssue + * All directives and components must use the standard `{{` `}}` interpolation symbols + * in their templates. If you change the application interpolation symbols the {@link $compile} + * service will attempt to denormalize the standard symbols to the custom symbols. + * The denormalization process is not clever enough to know not to replace instances of the standard + * symbols where they would not normally be treated as interpolation symbols. For example in the following + * code snippet the closing braces of the literal object will get incorrectly denormalized: + * + * ``` + *
+ * ``` + * + * See https://github.com/angular/angular.js/pull/14610#issuecomment-219401099 for more information. + * + * @param {string} text The text with markup to interpolate. + * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have + * embedded expression in order to return an interpolation function. Strings with no + * embedded expression will return null for the interpolation function. + * @param {string=} trustedContext when provided, the returned function passes the interpolated + * result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult, + * trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that + * provides Strict Contextual Escaping for details. + * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined + * unless all embedded expressions evaluate to a value other than `undefined`. + * @returns {function(context)} an interpolation function which is used to compute the + * interpolated string. The function has these parameters: + * + * - `context`: evaluation context for all expressions embedded in the interpolated text + */ + function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) { + // Provide a quick exit and simplified result function for text with no interpolation + if (!text.length || text.indexOf(startSymbol) === -1) { + var constantInterp; + if (!mustHaveExpression) { + var unescapedText = unescapeText(text); + constantInterp = valueFn(unescapedText); + constantInterp.exp = text; + constantInterp.expressions = []; + constantInterp.$$watchDelegate = constantWatchDelegate; + } + return constantInterp; + } + + allOrNothing = !!allOrNothing; + var startIndex, + endIndex, + index = 0, + expressions = [], + parseFns = [], + textLength = text.length, + exp, + concat = [], + expressionPositions = []; + + while (index < textLength) { + if (((startIndex = text.indexOf(startSymbol, index)) !== -1) && + ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) !== -1)) { + if (index !== startIndex) { + concat.push(unescapeText(text.substring(index, startIndex))); + } + exp = text.substring(startIndex + startSymbolLength, endIndex); + expressions.push(exp); + parseFns.push($parse(exp, parseStringifyInterceptor)); + index = endIndex + endSymbolLength; + expressionPositions.push(concat.length); + concat.push(''); + } else { + // we did not find an interpolation, so we have to add the remainder to the separators array + if (index !== textLength) { + concat.push(unescapeText(text.substring(index))); + } + break; + } + } + + // Concatenating expressions makes it hard to reason about whether some combination of + // concatenated values are unsafe to use and could easily lead to XSS. By requiring that a + // single expression be used for iframe[src], object[src], etc., we ensure that the value + // that's used is assigned or constructed by some JS code somewhere that is more testable or + // make it obvious that you bound the value to some user controlled value. This helps reduce + // the load when auditing for XSS issues. + if (trustedContext && concat.length > 1) { + $interpolateMinErr.throwNoconcat(text); + } + + if (!mustHaveExpression || expressions.length) { + var compute = function(values) { + for (var i = 0, ii = expressions.length; i < ii; i++) { + if (allOrNothing && isUndefined(values[i])) return; + concat[expressionPositions[i]] = values[i]; + } + return concat.join(''); + }; + + var getValue = function(value) { + return trustedContext ? + $sce.getTrusted(trustedContext, value) : + $sce.valueOf(value); + }; + + return extend(function interpolationFn(context) { + var i = 0; + var ii = expressions.length; + var values = new Array(ii); + + try { + for (; i < ii; i++) { + values[i] = parseFns[i](context); + } + + return compute(values); + } catch (err) { + $exceptionHandler($interpolateMinErr.interr(text, err)); + } + + }, { + // all of these properties are undocumented for now + exp: text, //just for compatibility with regular watchers created via $watch + expressions: expressions, + $$watchDelegate: function(scope, listener) { + var lastValue; + return scope.$watchGroup(parseFns, /** @this */ function interpolateFnWatcher(values, oldValues) { + var currValue = compute(values); + if (isFunction(listener)) { + listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope); + } + lastValue = currValue; + }); + } + }); + } + + function parseStringifyInterceptor(value) { + try { + value = getValue(value); + return allOrNothing && !isDefined(value) ? value : stringify(value); + } catch (err) { + $exceptionHandler($interpolateMinErr.interr(text, err)); + } + } + } + + + /** + * @ngdoc method + * @name $interpolate#startSymbol + * @description + * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`. + * + * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change + * the symbol. + * + * @returns {string} start symbol. + */ + $interpolate.startSymbol = function() { + return startSymbol; + }; + + + /** + * @ngdoc method + * @name $interpolate#endSymbol + * @description + * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`. + * + * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change + * the symbol. + * + * @returns {string} end symbol. + */ + $interpolate.endSymbol = function() { + return endSymbol; + }; + + return $interpolate; + }]; +} + +/** @this */ +function $IntervalProvider() { + this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser', + function($rootScope, $window, $q, $$q, $browser) { + var intervals = {}; + + + /** + * @ngdoc service + * @name $interval + * + * @description + * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay` + * milliseconds. + * + * The return value of registering an interval function is a promise. This promise will be + * notified upon each tick of the interval, and will be resolved after `count` iterations, or + * run indefinitely if `count` is not defined. The value of the notification will be the + * number of iterations that have run. + * To cancel an interval, call `$interval.cancel(promise)`. + * + * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to + * move forward by `millis` milliseconds and trigger any functions scheduled to run in that + * time. + * + *
+ * **Note**: Intervals created by this service must be explicitly destroyed when you are finished + * with them. In particular they are not automatically destroyed when a controller's scope or a + * directive's element are destroyed. + * You should take this into consideration and make sure to always cancel the interval at the + * appropriate moment. See the example below for more details on how and when to do this. + *
+ * + * @param {function()} fn A function that should be called repeatedly. If no additional arguments + * are passed (see below), the function is called with the current iteration count. + * @param {number} delay Number of milliseconds between each function call. + * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat + * indefinitely. + * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * @param {...*=} Pass additional parameters to the executed function. + * @returns {promise} A promise which will be notified on each iteration. + * + * @example + * + * + * + * + *
+ *
+ *
+ * Current time is: + *
+ * Blood 1 : {{blood_1}} + * Blood 2 : {{blood_2}} + * + * + * + *
+ *
+ * + *
+ *
+ */ + function interval(fn, delay, count, invokeApply) { + var hasParams = arguments.length > 4, + args = hasParams ? sliceArgs(arguments, 4) : [], + setInterval = $window.setInterval, + clearInterval = $window.clearInterval, + iteration = 0, + skipApply = (isDefined(invokeApply) && !invokeApply), + deferred = (skipApply ? $$q : $q).defer(), + promise = deferred.promise; + + count = isDefined(count) ? count : 0; + + promise.$$intervalId = setInterval(function tick() { + if (skipApply) { + $browser.defer(callback); + } else { + $rootScope.$evalAsync(callback); + } + deferred.notify(iteration++); + + if (count > 0 && iteration >= count) { + deferred.resolve(iteration); + clearInterval(promise.$$intervalId); + delete intervals[promise.$$intervalId]; + } + + if (!skipApply) $rootScope.$apply(); + + }, delay); + + intervals[promise.$$intervalId] = deferred; + + return promise; + + function callback() { + if (!hasParams) { + fn(iteration); + } else { + fn.apply(null, args); + } + } + } + + + /** + * @ngdoc method + * @name $interval#cancel + * + * @description + * Cancels a task associated with the `promise`. + * + * @param {Promise=} promise returned by the `$interval` function. + * @returns {boolean} Returns `true` if the task was successfully canceled. + */ + interval.cancel = function(promise) { + if (promise && promise.$$intervalId in intervals) { + // Interval cancels should not report as unhandled promise. + intervals[promise.$$intervalId].promise.catch(noop); + intervals[promise.$$intervalId].reject('canceled'); + $window.clearInterval(promise.$$intervalId); + delete intervals[promise.$$intervalId]; + return true; + } + return false; + }; + + return interval; + }]; +} + +/** + * @ngdoc service + * @name $jsonpCallbacks + * @requires $window + * @description + * This service handles the lifecycle of callbacks to handle JSONP requests. + * Override this service if you wish to customise where the callbacks are stored and + * how they vary compared to the requested url. + */ +var $jsonpCallbacksProvider = /** @this */ function() { + this.$get = ['$window', function($window) { + var callbacks = $window.angular.callbacks; + var callbackMap = {}; + + function createCallback(callbackId) { + var callback = function(data) { + callback.data = data; + callback.called = true; + }; + callback.id = callbackId; + return callback; + } + + return { + /** + * @ngdoc method + * @name $jsonpCallbacks#createCallback + * @param {string} url the url of the JSONP request + * @returns {string} the callback path to send to the server as part of the JSONP request + * @description + * {@link $httpBackend} calls this method to create a callback and get hold of the path to the callback + * to pass to the server, which will be used to call the callback with its payload in the JSONP response. + */ + createCallback: function(url) { + var callbackId = '_' + (callbacks.$$counter++).toString(36); + var callbackPath = 'angular.callbacks.' + callbackId; + var callback = createCallback(callbackId); + callbackMap[callbackPath] = callbacks[callbackId] = callback; + return callbackPath; + }, + /** + * @ngdoc method + * @name $jsonpCallbacks#wasCalled + * @param {string} callbackPath the path to the callback that was sent in the JSONP request + * @returns {boolean} whether the callback has been called, as a result of the JSONP response + * @description + * {@link $httpBackend} calls this method to find out whether the JSONP response actually called the + * callback that was passed in the request. + */ + wasCalled: function(callbackPath) { + return callbackMap[callbackPath].called; + }, + /** + * @ngdoc method + * @name $jsonpCallbacks#getResponse + * @param {string} callbackPath the path to the callback that was sent in the JSONP request + * @returns {*} the data received from the response via the registered callback + * @description + * {@link $httpBackend} calls this method to get hold of the data that was provided to the callback + * in the JSONP response. + */ + getResponse: function(callbackPath) { + return callbackMap[callbackPath].data; + }, + /** + * @ngdoc method + * @name $jsonpCallbacks#removeCallback + * @param {string} callbackPath the path to the callback that was sent in the JSONP request + * @description + * {@link $httpBackend} calls this method to remove the callback after the JSONP request has + * completed or timed-out. + */ + removeCallback: function(callbackPath) { + var callback = callbackMap[callbackPath]; + delete callbacks[callback.id]; + delete callbackMap[callbackPath]; + } + }; + }]; +}; + +/** + * @ngdoc service + * @name $locale + * + * @description + * $locale service provides localization rules for various Angular components. As of right now the + * only public api is: + * + * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`) + */ + +var PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/, + DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21}; +var $locationMinErr = minErr('$location'); + + +/** + * Encode path using encodeUriSegment, ignoring forward slashes + * + * @param {string} path Path to encode + * @returns {string} + */ +function encodePath(path) { + var segments = path.split('/'), + i = segments.length; + + while (i--) { + segments[i] = encodeUriSegment(segments[i]); + } + + return segments.join('/'); +} + +function parseAbsoluteUrl(absoluteUrl, locationObj) { + var parsedUrl = urlResolve(absoluteUrl); + + locationObj.$$protocol = parsedUrl.protocol; + locationObj.$$host = parsedUrl.hostname; + locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null; +} + +var DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/; +function parseAppUrl(url, locationObj) { + + if (DOUBLE_SLASH_REGEX.test(url)) { + throw $locationMinErr('badpath', 'Invalid url "{0}".', url); + } + + var prefixed = (url.charAt(0) !== '/'); + if (prefixed) { + url = '/' + url; + } + var match = urlResolve(url); + locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ? + match.pathname.substring(1) : match.pathname); + locationObj.$$search = parseKeyValue(match.search); + locationObj.$$hash = decodeURIComponent(match.hash); + + // make sure path starts with '/'; + if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') { + locationObj.$$path = '/' + locationObj.$$path; + } +} + +function startsWith(str, search) { + return str.slice(0, search.length) === search; +} + +/** + * + * @param {string} base + * @param {string} url + * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with + * the expected string. + */ +function stripBaseUrl(base, url) { + if (startsWith(url, base)) { + return url.substr(base.length); + } +} + + +function stripHash(url) { + var index = url.indexOf('#'); + return index === -1 ? url : url.substr(0, index); +} + +function trimEmptyHash(url) { + return url.replace(/(#.+)|#$/, '$1'); +} + + +function stripFile(url) { + return url.substr(0, stripHash(url).lastIndexOf('/') + 1); +} + +/* return the server only (scheme://host:port) */ +function serverBase(url) { + return url.substring(0, url.indexOf('/', url.indexOf('//') + 2)); +} + + +/** + * LocationHtml5Url represents a URL + * This object is exposed as $location service when HTML5 mode is enabled and supported + * + * @constructor + * @param {string} appBase application base URL + * @param {string} appBaseNoFile application base URL stripped of any filename + * @param {string} basePrefix URL path prefix + */ +function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) { + this.$$html5 = true; + basePrefix = basePrefix || ''; + parseAbsoluteUrl(appBase, this); + + + /** + * Parse given HTML5 (regular) URL string into properties + * @param {string} url HTML5 URL + * @private + */ + this.$$parse = function(url) { + var pathUrl = stripBaseUrl(appBaseNoFile, url); + if (!isString(pathUrl)) { + throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url, + appBaseNoFile); + } + + parseAppUrl(pathUrl, this); + + if (!this.$$path) { + this.$$path = '/'; + } + + this.$$compose(); + }; + + /** + * Compose url and update `absUrl` property + * @private + */ + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/' + }; + + this.$$parseLinkUrl = function(url, relHref) { + if (relHref && relHref[0] === '#') { + // special case for links to hash fragments: + // keep the old url and only replace the hash fragment + this.hash(relHref.slice(1)); + return true; + } + var appUrl, prevAppUrl; + var rewrittenUrl; + + + if (isDefined(appUrl = stripBaseUrl(appBase, url))) { + prevAppUrl = appUrl; + if (basePrefix && isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) { + rewrittenUrl = appBaseNoFile + (stripBaseUrl('/', appUrl) || appUrl); + } else { + rewrittenUrl = appBase + prevAppUrl; + } + } else if (isDefined(appUrl = stripBaseUrl(appBaseNoFile, url))) { + rewrittenUrl = appBaseNoFile + appUrl; + } else if (appBaseNoFile === url + '/') { + rewrittenUrl = appBaseNoFile; + } + if (rewrittenUrl) { + this.$$parse(rewrittenUrl); + } + return !!rewrittenUrl; + }; +} + + +/** + * LocationHashbangUrl represents URL + * This object is exposed as $location service when developer doesn't opt into html5 mode. + * It also serves as the base class for html5 mode fallback on legacy browsers. + * + * @constructor + * @param {string} appBase application base URL + * @param {string} appBaseNoFile application base URL stripped of any filename + * @param {string} hashPrefix hashbang prefix + */ +function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) { + + parseAbsoluteUrl(appBase, this); + + + /** + * Parse given hashbang URL into properties + * @param {string} url Hashbang URL + * @private + */ + this.$$parse = function(url) { + var withoutBaseUrl = stripBaseUrl(appBase, url) || stripBaseUrl(appBaseNoFile, url); + var withoutHashUrl; + + if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') { + + // The rest of the URL starts with a hash so we have + // got either a hashbang path or a plain hash fragment + withoutHashUrl = stripBaseUrl(hashPrefix, withoutBaseUrl); + if (isUndefined(withoutHashUrl)) { + // There was no hashbang prefix so we just have a hash fragment + withoutHashUrl = withoutBaseUrl; + } + + } else { + // There was no hashbang path nor hash fragment: + // If we are in HTML5 mode we use what is left as the path; + // Otherwise we ignore what is left + if (this.$$html5) { + withoutHashUrl = withoutBaseUrl; + } else { + withoutHashUrl = ''; + if (isUndefined(withoutBaseUrl)) { + appBase = url; + this.replace(); + } + } + } + + parseAppUrl(withoutHashUrl, this); + + this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase); + + this.$$compose(); + + /* + * In Windows, on an anchor node on documents loaded from + * the filesystem, the browser will return a pathname + * prefixed with the drive name ('/C:/path') when a + * pathname without a drive is set: + * * a.setAttribute('href', '/foo') + * * a.pathname === '/C:/foo' //true + * + * Inside of Angular, we're always using pathnames that + * do not include drive names for routing. + */ + function removeWindowsDriveName(path, url, base) { + /* + Matches paths for file protocol on windows, + such as /C:/foo/bar, and captures only /foo/bar. + */ + var windowsFilePathExp = /^\/[A-Z]:(\/.*)/; + + var firstPathSegmentMatch; + + //Get the relative path from the input URL. + if (startsWith(url, base)) { + url = url.replace(base, ''); + } + + // The input URL intentionally contains a first path segment that ends with a colon. + if (windowsFilePathExp.exec(url)) { + return path; + } + + firstPathSegmentMatch = windowsFilePathExp.exec(path); + return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path; + } + }; + + /** + * Compose hashbang URL and update `absUrl` property + * @private + */ + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : ''); + }; + + this.$$parseLinkUrl = function(url, relHref) { + if (stripHash(appBase) === stripHash(url)) { + this.$$parse(url); + return true; + } + return false; + }; +} + + +/** + * LocationHashbangUrl represents URL + * This object is exposed as $location service when html5 history api is enabled but the browser + * does not support it. + * + * @constructor + * @param {string} appBase application base URL + * @param {string} appBaseNoFile application base URL stripped of any filename + * @param {string} hashPrefix hashbang prefix + */ +function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) { + this.$$html5 = true; + LocationHashbangUrl.apply(this, arguments); + + this.$$parseLinkUrl = function(url, relHref) { + if (relHref && relHref[0] === '#') { + // special case for links to hash fragments: + // keep the old url and only replace the hash fragment + this.hash(relHref.slice(1)); + return true; + } + + var rewrittenUrl; + var appUrl; + + if (appBase === stripHash(url)) { + rewrittenUrl = url; + } else if ((appUrl = stripBaseUrl(appBaseNoFile, url))) { + rewrittenUrl = appBase + hashPrefix + appUrl; + } else if (appBaseNoFile === url + '/') { + rewrittenUrl = appBaseNoFile; + } + if (rewrittenUrl) { + this.$$parse(rewrittenUrl); + } + return !!rewrittenUrl; + }; + + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#' + this.$$absUrl = appBase + hashPrefix + this.$$url; + }; + +} + + +var locationPrototype = { + + /** + * Ensure absolute URL is initialized. + * @private + */ + $$absUrl:'', + + /** + * Are we in html5 mode? + * @private + */ + $$html5: false, + + /** + * Has any change been replacing? + * @private + */ + $$replace: false, + + /** + * @ngdoc method + * @name $location#absUrl + * + * @description + * This method is getter only. + * + * Return full URL representation with all segments encoded according to rules specified in + * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt). + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var absUrl = $location.absUrl(); + * // => "http://example.com/#/some/path?foo=bar&baz=xoxo" + * ``` + * + * @return {string} full URL + */ + absUrl: locationGetter('$$absUrl'), + + /** + * @ngdoc method + * @name $location#url + * + * @description + * This method is getter / setter. + * + * Return URL (e.g. `/path?a=b#hash`) when called without any parameter. + * + * Change path, search and hash, when called with parameter and return `$location`. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var url = $location.url(); + * // => "/some/path?foo=bar&baz=xoxo" + * ``` + * + * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`) + * @return {string} url + */ + url: function(url) { + if (isUndefined(url)) { + return this.$$url; + } + + var match = PATH_MATCH.exec(url); + if (match[1] || url === '') this.path(decodeURIComponent(match[1])); + if (match[2] || match[1] || url === '') this.search(match[3] || ''); + this.hash(match[5] || ''); + + return this; + }, + + /** + * @ngdoc method + * @name $location#protocol + * + * @description + * This method is getter only. + * + * Return protocol of current URL. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var protocol = $location.protocol(); + * // => "http" + * ``` + * + * @return {string} protocol of current URL + */ + protocol: locationGetter('$$protocol'), + + /** + * @ngdoc method + * @name $location#host + * + * @description + * This method is getter only. + * + * Return host of current URL. + * + * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var host = $location.host(); + * // => "example.com" + * + * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo + * host = $location.host(); + * // => "example.com" + * host = location.host; + * // => "example.com:8080" + * ``` + * + * @return {string} host of current URL. + */ + host: locationGetter('$$host'), + + /** + * @ngdoc method + * @name $location#port + * + * @description + * This method is getter only. + * + * Return port of current URL. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var port = $location.port(); + * // => 80 + * ``` + * + * @return {Number} port + */ + port: locationGetter('$$port'), + + /** + * @ngdoc method + * @name $location#path + * + * @description + * This method is getter / setter. + * + * Return path of current URL when called without any parameter. + * + * Change path when called with parameter and return `$location`. + * + * Note: Path should always begin with forward slash (/), this method will add the forward slash + * if it is missing. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var path = $location.path(); + * // => "/some/path" + * ``` + * + * @param {(string|number)=} path New path + * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter + */ + path: locationGetterSetter('$$path', function(path) { + path = path !== null ? path.toString() : ''; + return path.charAt(0) === '/' ? path : '/' + path; + }), + + /** + * @ngdoc method + * @name $location#search + * + * @description + * This method is getter / setter. + * + * Return search part (as object) of current URL when called without any parameter. + * + * Change search part when called with parameter and return `$location`. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo + * var searchObject = $location.search(); + * // => {foo: 'bar', baz: 'xoxo'} + * + * // set foo to 'yipee' + * $location.search('foo', 'yipee'); + * // $location.search() => {foo: 'yipee', baz: 'xoxo'} + * ``` + * + * @param {string|Object.|Object.>} search New search params - string or + * hash object. + * + * When called with a single argument the method acts as a setter, setting the `search` component + * of `$location` to the specified value. + * + * If the argument is a hash object containing an array of values, these values will be encoded + * as duplicate search parameters in the URL. + * + * @param {(string|Number|Array|boolean)=} paramValue If `search` is a string or number, then `paramValue` + * will override only a single search property. + * + * If `paramValue` is an array, it will override the property of the `search` component of + * `$location` specified via the first argument. + * + * If `paramValue` is `null`, the property specified via the first argument will be deleted. + * + * If `paramValue` is `true`, the property specified via the first argument will be added with no + * value nor trailing equal sign. + * + * @return {Object} If called with no arguments returns the parsed `search` object. If called with + * one or more arguments returns `$location` object itself. + */ + search: function(search, paramValue) { + switch (arguments.length) { + case 0: + return this.$$search; + case 1: + if (isString(search) || isNumber(search)) { + search = search.toString(); + this.$$search = parseKeyValue(search); + } else if (isObject(search)) { + search = copy(search, {}); + // remove object undefined or null properties + forEach(search, function(value, key) { + if (value == null) delete search[key]; + }); + + this.$$search = search; + } else { + throw $locationMinErr('isrcharg', + 'The first argument of the `$location#search()` call must be a string or an object.'); + } + break; + default: + if (isUndefined(paramValue) || paramValue === null) { + delete this.$$search[search]; + } else { + this.$$search[search] = paramValue; + } + } + + this.$$compose(); + return this; + }, + + /** + * @ngdoc method + * @name $location#hash + * + * @description + * This method is getter / setter. + * + * Returns the hash fragment when called without any parameters. + * + * Changes the hash fragment when called with a parameter and returns `$location`. + * + * + * ```js + * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue + * var hash = $location.hash(); + * // => "hashValue" + * ``` + * + * @param {(string|number)=} hash New hash fragment + * @return {string} hash + */ + hash: locationGetterSetter('$$hash', function(hash) { + return hash !== null ? hash.toString() : ''; + }), + + /** + * @ngdoc method + * @name $location#replace + * + * @description + * If called, all changes to $location during the current `$digest` will replace the current history + * record, instead of adding a new one. + */ + replace: function() { + this.$$replace = true; + return this; + } +}; + +forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) { + Location.prototype = Object.create(locationPrototype); + + /** + * @ngdoc method + * @name $location#state + * + * @description + * This method is getter / setter. + * + * Return the history state object when called without any parameter. + * + * Change the history state object when called with one parameter and return `$location`. + * The state object is later passed to `pushState` or `replaceState`. + * + * NOTE: This method is supported only in HTML5 mode and only in browsers supporting + * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support + * older browsers (like IE9 or Android < 4.0), don't use this method. + * + * @param {object=} state State object for pushState or replaceState + * @return {object} state + */ + Location.prototype.state = function(state) { + if (!arguments.length) { + return this.$$state; + } + + if (Location !== LocationHtml5Url || !this.$$html5) { + throw $locationMinErr('nostate', 'History API state support is available only ' + + 'in HTML5 mode and only in browsers supporting HTML5 History API'); + } + // The user might modify `stateObject` after invoking `$location.state(stateObject)` + // but we're changing the $$state reference to $browser.state() during the $digest + // so the modification window is narrow. + this.$$state = isUndefined(state) ? null : state; + + return this; + }; +}); + + +function locationGetter(property) { + return /** @this */ function() { + return this[property]; + }; +} + + +function locationGetterSetter(property, preprocess) { + return /** @this */ function(value) { + if (isUndefined(value)) { + return this[property]; + } + + this[property] = preprocess(value); + this.$$compose(); + + return this; + }; +} + + +/** + * @ngdoc service + * @name $location + * + * @requires $rootElement + * + * @description + * The $location service parses the URL in the browser address bar (based on the + * [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL + * available to your application. Changes to the URL in the address bar are reflected into + * $location service and changes to $location are reflected into the browser address bar. + * + * **The $location service:** + * + * - Exposes the current URL in the browser address bar, so you can + * - Watch and observe the URL. + * - Change the URL. + * - Synchronizes the URL with the browser when the user + * - Changes the address bar. + * - Clicks the back or forward button (or clicks a History link). + * - Clicks on a link. + * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash). + * + * For more information see {@link guide/$location Developer Guide: Using $location} + */ + +/** + * @ngdoc provider + * @name $locationProvider + * @this + * + * @description + * Use the `$locationProvider` to configure how the application deep linking paths are stored. + */ +function $LocationProvider() { + var hashPrefix = '!', + html5Mode = { + enabled: false, + requireBase: true, + rewriteLinks: true + }; + + /** + * @ngdoc method + * @name $locationProvider#hashPrefix + * @description + * The default value for the prefix is `'!'`. + * @param {string=} prefix Prefix for hash part (containing path and search) + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.hashPrefix = function(prefix) { + if (isDefined(prefix)) { + hashPrefix = prefix; + return this; + } else { + return hashPrefix; + } + }; + + /** + * @ngdoc method + * @name $locationProvider#html5Mode + * @description + * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value. + * If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported + * properties: + * - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to + * change urls where supported. Will fall back to hash-prefixed paths in browsers that do not + * support `pushState`. + * - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies + * whether or not a tag is required to be present. If `enabled` and `requireBase` are + * true, and a base tag is not present, an error will be thrown when `$location` is injected. + * See the {@link guide/$location $location guide for more information} + * - **rewriteLinks** - `{boolean|string}` - (default: `true`) When html5Mode is enabled, + * enables/disables URL rewriting for relative links. If set to a string, URL rewriting will + * only happen on links with an attribute that matches the given string. For example, if set + * to `'internal-link'`, then the URL will only be rewritten for `` links. + * Note that [attribute name normalization](guide/directive#normalization) does not apply + * here, so `'internalLink'` will **not** match `'internal-link'`. + * + * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter + */ + this.html5Mode = function(mode) { + if (isBoolean(mode)) { + html5Mode.enabled = mode; + return this; + } else if (isObject(mode)) { + + if (isBoolean(mode.enabled)) { + html5Mode.enabled = mode.enabled; + } + + if (isBoolean(mode.requireBase)) { + html5Mode.requireBase = mode.requireBase; + } + + if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) { + html5Mode.rewriteLinks = mode.rewriteLinks; + } + + return this; + } else { + return html5Mode; + } + }; + + /** + * @ngdoc event + * @name $location#$locationChangeStart + * @eventType broadcast on root scope + * @description + * Broadcasted before a URL will change. + * + * This change can be prevented by calling + * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more + * details about event object. Upon successful change + * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired. + * + * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when + * the browser supports the HTML5 History API. + * + * @param {Object} angularEvent Synthetic event object. + * @param {string} newUrl New URL + * @param {string=} oldUrl URL that was before it was changed. + * @param {string=} newState New history state object + * @param {string=} oldState History state object that was before it was changed. + */ + + /** + * @ngdoc event + * @name $location#$locationChangeSuccess + * @eventType broadcast on root scope + * @description + * Broadcasted after a URL was changed. + * + * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when + * the browser supports the HTML5 History API. + * + * @param {Object} angularEvent Synthetic event object. + * @param {string} newUrl New URL + * @param {string=} oldUrl URL that was before it was changed. + * @param {string=} newState New history state object + * @param {string=} oldState History state object that was before it was changed. + */ + + this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window', + function($rootScope, $browser, $sniffer, $rootElement, $window) { + var $location, + LocationMode, + baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to '' + initialUrl = $browser.url(), + appBase; + + if (html5Mode.enabled) { + if (!baseHref && html5Mode.requireBase) { + throw $locationMinErr('nobase', + '$location in HTML5 mode requires a tag to be present!'); + } + appBase = serverBase(initialUrl) + (baseHref || '/'); + LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url; + } else { + appBase = stripHash(initialUrl); + LocationMode = LocationHashbangUrl; + } + var appBaseNoFile = stripFile(appBase); + + $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix); + $location.$$parseLinkUrl(initialUrl, initialUrl); + + $location.$$state = $browser.state(); + + var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i; + + function setBrowserUrlWithFallback(url, replace, state) { + var oldUrl = $location.url(); + var oldState = $location.$$state; + try { + $browser.url(url, replace, state); + + // Make sure $location.state() returns referentially identical (not just deeply equal) + // state object; this makes possible quick checking if the state changed in the digest + // loop. Checking deep equality would be too expensive. + $location.$$state = $browser.state(); + } catch (e) { + // Restore old values if pushState fails + $location.url(oldUrl); + $location.$$state = oldState; + + throw e; + } + } + + $rootElement.on('click', function(event) { + var rewriteLinks = html5Mode.rewriteLinks; + // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) + // currently we open nice url link and redirect then + + if (!rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return; + + var elm = jqLite(event.target); + + // traverse the DOM up to find first A tag + while (nodeName_(elm[0]) !== 'a') { + // ignore rewriting if no A tag (reached root element, or no parent - removed from document) + if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return; + } + + if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks))) return; + + var absHref = elm.prop('href'); + // get the actual href attribute - see + // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx + var relHref = elm.attr('href') || elm.attr('xlink:href'); + + if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') { + // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during + // an animation. + absHref = urlResolve(absHref.animVal).href; + } + + // Ignore when url is started with javascript: or mailto: + if (IGNORE_URI_REGEXP.test(absHref)) return; + + if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) { + if ($location.$$parseLinkUrl(absHref, relHref)) { + // We do a preventDefault for all urls that are part of the angular application, + // in html5mode and also without, so that we are able to abort navigation without + // getting double entries in the location history. + event.preventDefault(); + // update location manually + if ($location.absUrl() !== $browser.url()) { + $rootScope.$apply(); + // hack to work around FF6 bug 684208 when scenario runner clicks on links + $window.angular['ff-684208-preventDefault'] = true; + } + } + } + }); + + + // rewrite hashbang url <> html5 url + if (trimEmptyHash($location.absUrl()) !== trimEmptyHash(initialUrl)) { + $browser.url($location.absUrl(), true); + } + + var initializing = true; + + // update $location when $browser url changes + $browser.onUrlChange(function(newUrl, newState) { + + if (!startsWith(newUrl, appBaseNoFile)) { + // If we are navigating outside of the app then force a reload + $window.location.href = newUrl; + return; + } + + $rootScope.$evalAsync(function() { + var oldUrl = $location.absUrl(); + var oldState = $location.$$state; + var defaultPrevented; + newUrl = trimEmptyHash(newUrl); + $location.$$parse(newUrl); + $location.$$state = newState; + + defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl, + newState, oldState).defaultPrevented; + + // if the location was changed by a `$locationChangeStart` handler then stop + // processing this location change + if ($location.absUrl() !== newUrl) return; + + if (defaultPrevented) { + $location.$$parse(oldUrl); + $location.$$state = oldState; + setBrowserUrlWithFallback(oldUrl, false, oldState); + } else { + initializing = false; + afterLocationChange(oldUrl, oldState); + } + }); + if (!$rootScope.$$phase) $rootScope.$digest(); + }); + + // update browser + $rootScope.$watch(function $locationWatch() { + var oldUrl = trimEmptyHash($browser.url()); + var newUrl = trimEmptyHash($location.absUrl()); + var oldState = $browser.state(); + var currentReplace = $location.$$replace; + var urlOrStateChanged = oldUrl !== newUrl || + ($location.$$html5 && $sniffer.history && oldState !== $location.$$state); + + if (initializing || urlOrStateChanged) { + initializing = false; + + $rootScope.$evalAsync(function() { + var newUrl = $location.absUrl(); + var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl, + $location.$$state, oldState).defaultPrevented; + + // if the location was changed by a `$locationChangeStart` handler then stop + // processing this location change + if ($location.absUrl() !== newUrl) return; + + if (defaultPrevented) { + $location.$$parse(oldUrl); + $location.$$state = oldState; + } else { + if (urlOrStateChanged) { + setBrowserUrlWithFallback(newUrl, currentReplace, + oldState === $location.$$state ? null : $location.$$state); + } + afterLocationChange(oldUrl, oldState); + } + }); + } + + $location.$$replace = false; + + // we don't need to return anything because $evalAsync will make the digest loop dirty when + // there is a change + }); + + return $location; + + function afterLocationChange(oldUrl, oldState) { + $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl, + $location.$$state, oldState); + } +}]; +} + +/** + * @ngdoc service + * @name $log + * @requires $window + * + * @description + * Simple service for logging. Default implementation safely writes the message + * into the browser's console (if present). + * + * The main purpose of this service is to simplify debugging and troubleshooting. + * + * The default is to log `debug` messages. You can use + * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this. + * + * @example + + + angular.module('logExample', []) + .controller('LogController', ['$scope', '$log', function($scope, $log) { + $scope.$log = $log; + $scope.message = 'Hello World!'; + }]); + + +
+

Reload this page with open console, enter text and hit the log button...

+ + + + + + +
+
+
+ */ + +/** + * @ngdoc provider + * @name $logProvider + * @this + * + * @description + * Use the `$logProvider` to configure how the application logs messages + */ +function $LogProvider() { + var debug = true, + self = this; + + /** + * @ngdoc method + * @name $logProvider#debugEnabled + * @description + * @param {boolean=} flag enable or disable debug level messages + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.debugEnabled = function(flag) { + if (isDefined(flag)) { + debug = flag; + return this; + } else { + return debug; + } + }; + + this.$get = ['$window', function($window) { + return { + /** + * @ngdoc method + * @name $log#log + * + * @description + * Write a log message + */ + log: consoleLog('log'), + + /** + * @ngdoc method + * @name $log#info + * + * @description + * Write an information message + */ + info: consoleLog('info'), + + /** + * @ngdoc method + * @name $log#warn + * + * @description + * Write a warning message + */ + warn: consoleLog('warn'), + + /** + * @ngdoc method + * @name $log#error + * + * @description + * Write an error message + */ + error: consoleLog('error'), + + /** + * @ngdoc method + * @name $log#debug + * + * @description + * Write a debug message + */ + debug: (function() { + var fn = consoleLog('debug'); + + return function() { + if (debug) { + fn.apply(self, arguments); + } + }; + })() + }; + + function formatError(arg) { + if (arg instanceof Error) { + if (arg.stack) { + arg = (arg.message && arg.stack.indexOf(arg.message) === -1) + ? 'Error: ' + arg.message + '\n' + arg.stack + : arg.stack; + } else if (arg.sourceURL) { + arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line; + } + } + return arg; + } + + function consoleLog(type) { + var console = $window.console || {}, + logFn = console[type] || console.log || noop, + hasApply = false; + + // Note: reading logFn.apply throws an error in IE11 in IE8 document mode. + // The reason behind this is that console.log has type "object" in IE8... + try { + hasApply = !!logFn.apply; + } catch (e) { /* empty */ } + + if (hasApply) { + return function() { + var args = []; + forEach(arguments, function(arg) { + args.push(formatError(arg)); + }); + return logFn.apply(console, args); + }; + } + + // we are IE which either doesn't have window.console => this is noop and we do nothing, + // or we are IE where console.log doesn't have apply so we log at least first 2 args + return function(arg1, arg2) { + logFn(arg1, arg2 == null ? '' : arg2); + }; + } + }]; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Any commits to this file should be reviewed with security in mind. * + * Changes to this file can potentially create security vulnerabilities. * + * An approval from 2 Core members with history of modifying * + * this file is required. * + * * + * Does the change somehow allow for arbitrary javascript to be executed? * + * Or allows for someone to change the prototype of built-in objects? * + * Or gives undesired access to variables likes document or window? * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +var $parseMinErr = minErr('$parse'); + +var objectValueOf = {}.constructor.prototype.valueOf; + +// Sandboxing Angular Expressions +// ------------------------------ +// Angular expressions are no longer sandboxed. So it is now even easier to access arbitrary JS code by +// various means such as obtaining a reference to native JS functions like the Function constructor. +// +// As an example, consider the following Angular expression: +// +// {}.toString.constructor('alert("evil JS code")') +// +// It is important to realize that if you create an expression from a string that contains user provided +// content then it is possible that your application contains a security vulnerability to an XSS style attack. +// +// See https://docs.angularjs.org/guide/security + + +function getStringValue(name) { + // Property names must be strings. This means that non-string objects cannot be used + // as keys in an object. Any non-string object, including a number, is typecasted + // into a string via the toString method. + // -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names + // + // So, to ensure that we are checking the same `name` that JavaScript would use, we cast it + // to a string. It's not always possible. If `name` is an object and its `toString` method is + // 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown: + // + // TypeError: Cannot convert object to primitive value + // + // For performance reasons, we don't catch this error here and allow it to propagate up the call + // stack. Note that you'll get the same error in JavaScript if you try to access a property using + // such a 'broken' object as a key. + return name + ''; +} + + +var OPERATORS = createMap(); +forEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) { OPERATORS[operator] = true; }); +var ESCAPE = {'n':'\n', 'f':'\f', 'r':'\r', 't':'\t', 'v':'\v', '\'':'\'', '"':'"'}; + + +///////////////////////////////////////// + + +/** + * @constructor + */ +var Lexer = function Lexer(options) { + this.options = options; +}; + +Lexer.prototype = { + constructor: Lexer, + + lex: function(text) { + this.text = text; + this.index = 0; + this.tokens = []; + + while (this.index < this.text.length) { + var ch = this.text.charAt(this.index); + if (ch === '"' || ch === '\'') { + this.readString(ch); + } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) { + this.readNumber(); + } else if (this.isIdentifierStart(this.peekMultichar())) { + this.readIdent(); + } else if (this.is(ch, '(){}[].,;:?')) { + this.tokens.push({index: this.index, text: ch}); + this.index++; + } else if (this.isWhitespace(ch)) { + this.index++; + } else { + var ch2 = ch + this.peek(); + var ch3 = ch2 + this.peek(2); + var op1 = OPERATORS[ch]; + var op2 = OPERATORS[ch2]; + var op3 = OPERATORS[ch3]; + if (op1 || op2 || op3) { + var token = op3 ? ch3 : (op2 ? ch2 : ch); + this.tokens.push({index: this.index, text: token, operator: true}); + this.index += token.length; + } else { + this.throwError('Unexpected next character ', this.index, this.index + 1); + } + } + } + return this.tokens; + }, + + is: function(ch, chars) { + return chars.indexOf(ch) !== -1; + }, + + peek: function(i) { + var num = i || 1; + return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false; + }, + + isNumber: function(ch) { + return ('0' <= ch && ch <= '9') && typeof ch === 'string'; + }, + + isWhitespace: function(ch) { + // IE treats non-breaking space as \u00A0 + return (ch === ' ' || ch === '\r' || ch === '\t' || + ch === '\n' || ch === '\v' || ch === '\u00A0'); + }, + + isIdentifierStart: function(ch) { + return this.options.isIdentifierStart ? + this.options.isIdentifierStart(ch, this.codePointAt(ch)) : + this.isValidIdentifierStart(ch); + }, + + isValidIdentifierStart: function(ch) { + return ('a' <= ch && ch <= 'z' || + 'A' <= ch && ch <= 'Z' || + '_' === ch || ch === '$'); + }, + + isIdentifierContinue: function(ch) { + return this.options.isIdentifierContinue ? + this.options.isIdentifierContinue(ch, this.codePointAt(ch)) : + this.isValidIdentifierContinue(ch); + }, + + isValidIdentifierContinue: function(ch, cp) { + return this.isValidIdentifierStart(ch, cp) || this.isNumber(ch); + }, + + codePointAt: function(ch) { + if (ch.length === 1) return ch.charCodeAt(0); + // eslint-disable-next-line no-bitwise + return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35FDC00; + }, + + peekMultichar: function() { + var ch = this.text.charAt(this.index); + var peek = this.peek(); + if (!peek) { + return ch; + } + var cp1 = ch.charCodeAt(0); + var cp2 = peek.charCodeAt(0); + if (cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF) { + return ch + peek; + } + return ch; + }, + + isExpOperator: function(ch) { + return (ch === '-' || ch === '+' || this.isNumber(ch)); + }, + + throwError: function(error, start, end) { + end = end || this.index; + var colStr = (isDefined(start) + ? 's ' + start + '-' + this.index + ' [' + this.text.substring(start, end) + ']' + : ' ' + end); + throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].', + error, colStr, this.text); + }, + + readNumber: function() { + var number = ''; + var start = this.index; + while (this.index < this.text.length) { + var ch = lowercase(this.text.charAt(this.index)); + if (ch === '.' || this.isNumber(ch)) { + number += ch; + } else { + var peekCh = this.peek(); + if (ch === 'e' && this.isExpOperator(peekCh)) { + number += ch; + } else if (this.isExpOperator(ch) && + peekCh && this.isNumber(peekCh) && + number.charAt(number.length - 1) === 'e') { + number += ch; + } else if (this.isExpOperator(ch) && + (!peekCh || !this.isNumber(peekCh)) && + number.charAt(number.length - 1) === 'e') { + this.throwError('Invalid exponent'); + } else { + break; + } + } + this.index++; + } + this.tokens.push({ + index: start, + text: number, + constant: true, + value: Number(number) + }); + }, + + readIdent: function() { + var start = this.index; + this.index += this.peekMultichar().length; + while (this.index < this.text.length) { + var ch = this.peekMultichar(); + if (!this.isIdentifierContinue(ch)) { + break; + } + this.index += ch.length; + } + this.tokens.push({ + index: start, + text: this.text.slice(start, this.index), + identifier: true + }); + }, + + readString: function(quote) { + var start = this.index; + this.index++; + var string = ''; + var rawString = quote; + var escape = false; + while (this.index < this.text.length) { + var ch = this.text.charAt(this.index); + rawString += ch; + if (escape) { + if (ch === 'u') { + var hex = this.text.substring(this.index + 1, this.index + 5); + if (!hex.match(/[\da-f]{4}/i)) { + this.throwError('Invalid unicode escape [\\u' + hex + ']'); + } + this.index += 4; + string += String.fromCharCode(parseInt(hex, 16)); + } else { + var rep = ESCAPE[ch]; + string = string + (rep || ch); + } + escape = false; + } else if (ch === '\\') { + escape = true; + } else if (ch === quote) { + this.index++; + this.tokens.push({ + index: start, + text: rawString, + constant: true, + value: string + }); + return; + } else { + string += ch; + } + this.index++; + } + this.throwError('Unterminated quote', start); + } +}; + +var AST = function AST(lexer, options) { + this.lexer = lexer; + this.options = options; +}; + +AST.Program = 'Program'; +AST.ExpressionStatement = 'ExpressionStatement'; +AST.AssignmentExpression = 'AssignmentExpression'; +AST.ConditionalExpression = 'ConditionalExpression'; +AST.LogicalExpression = 'LogicalExpression'; +AST.BinaryExpression = 'BinaryExpression'; +AST.UnaryExpression = 'UnaryExpression'; +AST.CallExpression = 'CallExpression'; +AST.MemberExpression = 'MemberExpression'; +AST.Identifier = 'Identifier'; +AST.Literal = 'Literal'; +AST.ArrayExpression = 'ArrayExpression'; +AST.Property = 'Property'; +AST.ObjectExpression = 'ObjectExpression'; +AST.ThisExpression = 'ThisExpression'; +AST.LocalsExpression = 'LocalsExpression'; + +// Internal use only +AST.NGValueParameter = 'NGValueParameter'; + +AST.prototype = { + ast: function(text) { + this.text = text; + this.tokens = this.lexer.lex(text); + + var value = this.program(); + + if (this.tokens.length !== 0) { + this.throwError('is an unexpected token', this.tokens[0]); + } + + return value; + }, + + program: function() { + var body = []; + while (true) { + if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']')) + body.push(this.expressionStatement()); + if (!this.expect(';')) { + return { type: AST.Program, body: body}; + } + } + }, + + expressionStatement: function() { + return { type: AST.ExpressionStatement, expression: this.filterChain() }; + }, + + filterChain: function() { + var left = this.expression(); + while (this.expect('|')) { + left = this.filter(left); + } + return left; + }, + + expression: function() { + return this.assignment(); + }, + + assignment: function() { + var result = this.ternary(); + if (this.expect('=')) { + if (!isAssignable(result)) { + throw $parseMinErr('lval', 'Trying to assign a value to a non l-value'); + } + + result = { type: AST.AssignmentExpression, left: result, right: this.assignment(), operator: '='}; + } + return result; + }, + + ternary: function() { + var test = this.logicalOR(); + var alternate; + var consequent; + if (this.expect('?')) { + alternate = this.expression(); + if (this.consume(':')) { + consequent = this.expression(); + return { type: AST.ConditionalExpression, test: test, alternate: alternate, consequent: consequent}; + } + } + return test; + }, + + logicalOR: function() { + var left = this.logicalAND(); + while (this.expect('||')) { + left = { type: AST.LogicalExpression, operator: '||', left: left, right: this.logicalAND() }; + } + return left; + }, + + logicalAND: function() { + var left = this.equality(); + while (this.expect('&&')) { + left = { type: AST.LogicalExpression, operator: '&&', left: left, right: this.equality()}; + } + return left; + }, + + equality: function() { + var left = this.relational(); + var token; + while ((token = this.expect('==','!=','===','!=='))) { + left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.relational() }; + } + return left; + }, + + relational: function() { + var left = this.additive(); + var token; + while ((token = this.expect('<', '>', '<=', '>='))) { + left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.additive() }; + } + return left; + }, + + additive: function() { + var left = this.multiplicative(); + var token; + while ((token = this.expect('+','-'))) { + left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.multiplicative() }; + } + return left; + }, + + multiplicative: function() { + var left = this.unary(); + var token; + while ((token = this.expect('*','/','%'))) { + left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.unary() }; + } + return left; + }, + + unary: function() { + var token; + if ((token = this.expect('+', '-', '!'))) { + return { type: AST.UnaryExpression, operator: token.text, prefix: true, argument: this.unary() }; + } else { + return this.primary(); + } + }, + + primary: function() { + var primary; + if (this.expect('(')) { + primary = this.filterChain(); + this.consume(')'); + } else if (this.expect('[')) { + primary = this.arrayDeclaration(); + } else if (this.expect('{')) { + primary = this.object(); + } else if (this.selfReferential.hasOwnProperty(this.peek().text)) { + primary = copy(this.selfReferential[this.consume().text]); + } else if (this.options.literals.hasOwnProperty(this.peek().text)) { + primary = { type: AST.Literal, value: this.options.literals[this.consume().text]}; + } else if (this.peek().identifier) { + primary = this.identifier(); + } else if (this.peek().constant) { + primary = this.constant(); + } else { + this.throwError('not a primary expression', this.peek()); + } + + var next; + while ((next = this.expect('(', '[', '.'))) { + if (next.text === '(') { + primary = {type: AST.CallExpression, callee: primary, arguments: this.parseArguments() }; + this.consume(')'); + } else if (next.text === '[') { + primary = { type: AST.MemberExpression, object: primary, property: this.expression(), computed: true }; + this.consume(']'); + } else if (next.text === '.') { + primary = { type: AST.MemberExpression, object: primary, property: this.identifier(), computed: false }; + } else { + this.throwError('IMPOSSIBLE'); + } + } + return primary; + }, + + filter: function(baseExpression) { + var args = [baseExpression]; + var result = {type: AST.CallExpression, callee: this.identifier(), arguments: args, filter: true}; + + while (this.expect(':')) { + args.push(this.expression()); + } + + return result; + }, + + parseArguments: function() { + var args = []; + if (this.peekToken().text !== ')') { + do { + args.push(this.filterChain()); + } while (this.expect(',')); + } + return args; + }, + + identifier: function() { + var token = this.consume(); + if (!token.identifier) { + this.throwError('is not a valid identifier', token); + } + return { type: AST.Identifier, name: token.text }; + }, + + constant: function() { + // TODO check that it is a constant + return { type: AST.Literal, value: this.consume().value }; + }, + + arrayDeclaration: function() { + var elements = []; + if (this.peekToken().text !== ']') { + do { + if (this.peek(']')) { + // Support trailing commas per ES5.1. + break; + } + elements.push(this.expression()); + } while (this.expect(',')); + } + this.consume(']'); + + return { type: AST.ArrayExpression, elements: elements }; + }, + + object: function() { + var properties = [], property; + if (this.peekToken().text !== '}') { + do { + if (this.peek('}')) { + // Support trailing commas per ES5.1. + break; + } + property = {type: AST.Property, kind: 'init'}; + if (this.peek().constant) { + property.key = this.constant(); + property.computed = false; + this.consume(':'); + property.value = this.expression(); + } else if (this.peek().identifier) { + property.key = this.identifier(); + property.computed = false; + if (this.peek(':')) { + this.consume(':'); + property.value = this.expression(); + } else { + property.value = property.key; + } + } else if (this.peek('[')) { + this.consume('['); + property.key = this.expression(); + this.consume(']'); + property.computed = true; + this.consume(':'); + property.value = this.expression(); + } else { + this.throwError('invalid key', this.peek()); + } + properties.push(property); + } while (this.expect(',')); + } + this.consume('}'); + + return {type: AST.ObjectExpression, properties: properties }; + }, + + throwError: function(msg, token) { + throw $parseMinErr('syntax', + 'Syntax Error: Token \'{0}\' {1} at column {2} of the expression [{3}] starting at [{4}].', + token.text, msg, (token.index + 1), this.text, this.text.substring(token.index)); + }, + + consume: function(e1) { + if (this.tokens.length === 0) { + throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text); + } + + var token = this.expect(e1); + if (!token) { + this.throwError('is unexpected, expecting [' + e1 + ']', this.peek()); + } + return token; + }, + + peekToken: function() { + if (this.tokens.length === 0) { + throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text); + } + return this.tokens[0]; + }, + + peek: function(e1, e2, e3, e4) { + return this.peekAhead(0, e1, e2, e3, e4); + }, + + peekAhead: function(i, e1, e2, e3, e4) { + if (this.tokens.length > i) { + var token = this.tokens[i]; + var t = token.text; + if (t === e1 || t === e2 || t === e3 || t === e4 || + (!e1 && !e2 && !e3 && !e4)) { + return token; + } + } + return false; + }, + + expect: function(e1, e2, e3, e4) { + var token = this.peek(e1, e2, e3, e4); + if (token) { + this.tokens.shift(); + return token; + } + return false; + }, + + selfReferential: { + 'this': {type: AST.ThisExpression }, + '$locals': {type: AST.LocalsExpression } + } +}; + +function ifDefined(v, d) { + return typeof v !== 'undefined' ? v : d; +} + +function plusFn(l, r) { + if (typeof l === 'undefined') return r; + if (typeof r === 'undefined') return l; + return l + r; +} + +function isStateless($filter, filterName) { + var fn = $filter(filterName); + return !fn.$stateful; +} + +function findConstantAndWatchExpressions(ast, $filter) { + var allConstants; + var argsToWatch; + var isStatelessFilter; + switch (ast.type) { + case AST.Program: + allConstants = true; + forEach(ast.body, function(expr) { + findConstantAndWatchExpressions(expr.expression, $filter); + allConstants = allConstants && expr.expression.constant; + }); + ast.constant = allConstants; + break; + case AST.Literal: + ast.constant = true; + ast.toWatch = []; + break; + case AST.UnaryExpression: + findConstantAndWatchExpressions(ast.argument, $filter); + ast.constant = ast.argument.constant; + ast.toWatch = ast.argument.toWatch; + break; + case AST.BinaryExpression: + findConstantAndWatchExpressions(ast.left, $filter); + findConstantAndWatchExpressions(ast.right, $filter); + ast.constant = ast.left.constant && ast.right.constant; + ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch); + break; + case AST.LogicalExpression: + findConstantAndWatchExpressions(ast.left, $filter); + findConstantAndWatchExpressions(ast.right, $filter); + ast.constant = ast.left.constant && ast.right.constant; + ast.toWatch = ast.constant ? [] : [ast]; + break; + case AST.ConditionalExpression: + findConstantAndWatchExpressions(ast.test, $filter); + findConstantAndWatchExpressions(ast.alternate, $filter); + findConstantAndWatchExpressions(ast.consequent, $filter); + ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant; + ast.toWatch = ast.constant ? [] : [ast]; + break; + case AST.Identifier: + ast.constant = false; + ast.toWatch = [ast]; + break; + case AST.MemberExpression: + findConstantAndWatchExpressions(ast.object, $filter); + if (ast.computed) { + findConstantAndWatchExpressions(ast.property, $filter); + } + ast.constant = ast.object.constant && (!ast.computed || ast.property.constant); + ast.toWatch = [ast]; + break; + case AST.CallExpression: + isStatelessFilter = ast.filter ? isStateless($filter, ast.callee.name) : false; + allConstants = isStatelessFilter; + argsToWatch = []; + forEach(ast.arguments, function(expr) { + findConstantAndWatchExpressions(expr, $filter); + allConstants = allConstants && expr.constant; + if (!expr.constant) { + argsToWatch.push.apply(argsToWatch, expr.toWatch); + } + }); + ast.constant = allConstants; + ast.toWatch = isStatelessFilter ? argsToWatch : [ast]; + break; + case AST.AssignmentExpression: + findConstantAndWatchExpressions(ast.left, $filter); + findConstantAndWatchExpressions(ast.right, $filter); + ast.constant = ast.left.constant && ast.right.constant; + ast.toWatch = [ast]; + break; + case AST.ArrayExpression: + allConstants = true; + argsToWatch = []; + forEach(ast.elements, function(expr) { + findConstantAndWatchExpressions(expr, $filter); + allConstants = allConstants && expr.constant; + if (!expr.constant) { + argsToWatch.push.apply(argsToWatch, expr.toWatch); + } + }); + ast.constant = allConstants; + ast.toWatch = argsToWatch; + break; + case AST.ObjectExpression: + allConstants = true; + argsToWatch = []; + forEach(ast.properties, function(property) { + findConstantAndWatchExpressions(property.value, $filter); + allConstants = allConstants && property.value.constant && !property.computed; + if (!property.value.constant) { + argsToWatch.push.apply(argsToWatch, property.value.toWatch); + } + }); + ast.constant = allConstants; + ast.toWatch = argsToWatch; + break; + case AST.ThisExpression: + ast.constant = false; + ast.toWatch = []; + break; + case AST.LocalsExpression: + ast.constant = false; + ast.toWatch = []; + break; + } +} + +function getInputs(body) { + if (body.length !== 1) return; + var lastExpression = body[0].expression; + var candidate = lastExpression.toWatch; + if (candidate.length !== 1) return candidate; + return candidate[0] !== lastExpression ? candidate : undefined; +} + +function isAssignable(ast) { + return ast.type === AST.Identifier || ast.type === AST.MemberExpression; +} + +function assignableAST(ast) { + if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) { + return {type: AST.AssignmentExpression, left: ast.body[0].expression, right: {type: AST.NGValueParameter}, operator: '='}; + } +} + +function isLiteral(ast) { + return ast.body.length === 0 || + ast.body.length === 1 && ( + ast.body[0].expression.type === AST.Literal || + ast.body[0].expression.type === AST.ArrayExpression || + ast.body[0].expression.type === AST.ObjectExpression); +} + +function isConstant(ast) { + return ast.constant; +} + +function ASTCompiler(astBuilder, $filter) { + this.astBuilder = astBuilder; + this.$filter = $filter; +} + +ASTCompiler.prototype = { + compile: function(expression) { + var self = this; + var ast = this.astBuilder.ast(expression); + this.state = { + nextId: 0, + filters: {}, + fn: {vars: [], body: [], own: {}}, + assign: {vars: [], body: [], own: {}}, + inputs: [] + }; + findConstantAndWatchExpressions(ast, self.$filter); + var extra = ''; + var assignable; + this.stage = 'assign'; + if ((assignable = assignableAST(ast))) { + this.state.computing = 'assign'; + var result = this.nextId(); + this.recurse(assignable, result); + this.return_(result); + extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l'); + } + var toWatch = getInputs(ast.body); + self.stage = 'inputs'; + forEach(toWatch, function(watch, key) { + var fnKey = 'fn' + key; + self.state[fnKey] = {vars: [], body: [], own: {}}; + self.state.computing = fnKey; + var intoId = self.nextId(); + self.recurse(watch, intoId); + self.return_(intoId); + self.state.inputs.push(fnKey); + watch.watchId = key; + }); + this.state.computing = 'fn'; + this.stage = 'main'; + this.recurse(ast); + var fnString = + // The build and minification steps remove the string "use strict" from the code, but this is done using a regex. + // This is a workaround for this until we do a better job at only removing the prefix only when we should. + '"' + this.USE + ' ' + this.STRICT + '";\n' + + this.filterPrefix() + + 'var fn=' + this.generateFunction('fn', 's,l,a,i') + + extra + + this.watchFns() + + 'return fn;'; + + // eslint-disable-next-line no-new-func + var fn = (new Function('$filter', + 'getStringValue', + 'ifDefined', + 'plus', + fnString))( + this.$filter, + getStringValue, + ifDefined, + plusFn); + this.state = this.stage = undefined; + fn.literal = isLiteral(ast); + fn.constant = isConstant(ast); + return fn; + }, + + USE: 'use', + + STRICT: 'strict', + + watchFns: function() { + var result = []; + var fns = this.state.inputs; + var self = this; + forEach(fns, function(name) { + result.push('var ' + name + '=' + self.generateFunction(name, 's')); + }); + if (fns.length) { + result.push('fn.inputs=[' + fns.join(',') + '];'); + } + return result.join(''); + }, + + generateFunction: function(name, params) { + return 'function(' + params + '){' + + this.varsPrefix(name) + + this.body(name) + + '};'; + }, + + filterPrefix: function() { + var parts = []; + var self = this; + forEach(this.state.filters, function(id, filter) { + parts.push(id + '=$filter(' + self.escape(filter) + ')'); + }); + if (parts.length) return 'var ' + parts.join(',') + ';'; + return ''; + }, + + varsPrefix: function(section) { + return this.state[section].vars.length ? 'var ' + this.state[section].vars.join(',') + ';' : ''; + }, + + body: function(section) { + return this.state[section].body.join(''); + }, + + recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) { + var left, right, self = this, args, expression, computed; + recursionFn = recursionFn || noop; + if (!skipWatchIdCheck && isDefined(ast.watchId)) { + intoId = intoId || this.nextId(); + this.if_('i', + this.lazyAssign(intoId, this.computedMember('i', ast.watchId)), + this.lazyRecurse(ast, intoId, nameId, recursionFn, create, true) + ); + return; + } + switch (ast.type) { + case AST.Program: + forEach(ast.body, function(expression, pos) { + self.recurse(expression.expression, undefined, undefined, function(expr) { right = expr; }); + if (pos !== ast.body.length - 1) { + self.current().body.push(right, ';'); + } else { + self.return_(right); + } + }); + break; + case AST.Literal: + expression = this.escape(ast.value); + this.assign(intoId, expression); + recursionFn(intoId || expression); + break; + case AST.UnaryExpression: + this.recurse(ast.argument, undefined, undefined, function(expr) { right = expr; }); + expression = ast.operator + '(' + this.ifDefined(right, 0) + ')'; + this.assign(intoId, expression); + recursionFn(expression); + break; + case AST.BinaryExpression: + this.recurse(ast.left, undefined, undefined, function(expr) { left = expr; }); + this.recurse(ast.right, undefined, undefined, function(expr) { right = expr; }); + if (ast.operator === '+') { + expression = this.plus(left, right); + } else if (ast.operator === '-') { + expression = this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0); + } else { + expression = '(' + left + ')' + ast.operator + '(' + right + ')'; + } + this.assign(intoId, expression); + recursionFn(expression); + break; + case AST.LogicalExpression: + intoId = intoId || this.nextId(); + self.recurse(ast.left, intoId); + self.if_(ast.operator === '&&' ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId)); + recursionFn(intoId); + break; + case AST.ConditionalExpression: + intoId = intoId || this.nextId(); + self.recurse(ast.test, intoId); + self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId)); + recursionFn(intoId); + break; + case AST.Identifier: + intoId = intoId || this.nextId(); + if (nameId) { + nameId.context = self.stage === 'inputs' ? 's' : this.assign(this.nextId(), this.getHasOwnProperty('l', ast.name) + '?l:s'); + nameId.computed = false; + nameId.name = ast.name; + } + self.if_(self.stage === 'inputs' || self.not(self.getHasOwnProperty('l', ast.name)), + function() { + self.if_(self.stage === 'inputs' || 's', function() { + if (create && create !== 1) { + self.if_( + self.isNull(self.nonComputedMember('s', ast.name)), + self.lazyAssign(self.nonComputedMember('s', ast.name), '{}')); + } + self.assign(intoId, self.nonComputedMember('s', ast.name)); + }); + }, intoId && self.lazyAssign(intoId, self.nonComputedMember('l', ast.name)) + ); + recursionFn(intoId); + break; + case AST.MemberExpression: + left = nameId && (nameId.context = this.nextId()) || this.nextId(); + intoId = intoId || this.nextId(); + self.recurse(ast.object, left, undefined, function() { + self.if_(self.notNull(left), function() { + if (ast.computed) { + right = self.nextId(); + self.recurse(ast.property, right); + self.getStringValue(right); + if (create && create !== 1) { + self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}')); + } + expression = self.computedMember(left, right); + self.assign(intoId, expression); + if (nameId) { + nameId.computed = true; + nameId.name = right; + } + } else { + if (create && create !== 1) { + self.if_(self.isNull(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}')); + } + expression = self.nonComputedMember(left, ast.property.name); + self.assign(intoId, expression); + if (nameId) { + nameId.computed = false; + nameId.name = ast.property.name; + } + } + }, function() { + self.assign(intoId, 'undefined'); + }); + recursionFn(intoId); + }, !!create); + break; + case AST.CallExpression: + intoId = intoId || this.nextId(); + if (ast.filter) { + right = self.filter(ast.callee.name); + args = []; + forEach(ast.arguments, function(expr) { + var argument = self.nextId(); + self.recurse(expr, argument); + args.push(argument); + }); + expression = right + '(' + args.join(',') + ')'; + self.assign(intoId, expression); + recursionFn(intoId); + } else { + right = self.nextId(); + left = {}; + args = []; + self.recurse(ast.callee, right, left, function() { + self.if_(self.notNull(right), function() { + forEach(ast.arguments, function(expr) { + self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) { + args.push(argument); + }); + }); + if (left.name) { + expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')'; + } else { + expression = right + '(' + args.join(',') + ')'; + } + self.assign(intoId, expression); + }, function() { + self.assign(intoId, 'undefined'); + }); + recursionFn(intoId); + }); + } + break; + case AST.AssignmentExpression: + right = this.nextId(); + left = {}; + this.recurse(ast.left, undefined, left, function() { + self.if_(self.notNull(left.context), function() { + self.recurse(ast.right, right); + expression = self.member(left.context, left.name, left.computed) + ast.operator + right; + self.assign(intoId, expression); + recursionFn(intoId || expression); + }); + }, 1); + break; + case AST.ArrayExpression: + args = []; + forEach(ast.elements, function(expr) { + self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) { + args.push(argument); + }); + }); + expression = '[' + args.join(',') + ']'; + this.assign(intoId, expression); + recursionFn(intoId || expression); + break; + case AST.ObjectExpression: + args = []; + computed = false; + forEach(ast.properties, function(property) { + if (property.computed) { + computed = true; + } + }); + if (computed) { + intoId = intoId || this.nextId(); + this.assign(intoId, '{}'); + forEach(ast.properties, function(property) { + if (property.computed) { + left = self.nextId(); + self.recurse(property.key, left); + } else { + left = property.key.type === AST.Identifier ? + property.key.name : + ('' + property.key.value); + } + right = self.nextId(); + self.recurse(property.value, right); + self.assign(self.member(intoId, left, property.computed), right); + }); + } else { + forEach(ast.properties, function(property) { + self.recurse(property.value, ast.constant ? undefined : self.nextId(), undefined, function(expr) { + args.push(self.escape( + property.key.type === AST.Identifier ? property.key.name : + ('' + property.key.value)) + + ':' + expr); + }); + }); + expression = '{' + args.join(',') + '}'; + this.assign(intoId, expression); + } + recursionFn(intoId || expression); + break; + case AST.ThisExpression: + this.assign(intoId, 's'); + recursionFn(intoId || 's'); + break; + case AST.LocalsExpression: + this.assign(intoId, 'l'); + recursionFn(intoId || 'l'); + break; + case AST.NGValueParameter: + this.assign(intoId, 'v'); + recursionFn(intoId || 'v'); + break; + } + }, + + getHasOwnProperty: function(element, property) { + var key = element + '.' + property; + var own = this.current().own; + if (!own.hasOwnProperty(key)) { + own[key] = this.nextId(false, element + '&&(' + this.escape(property) + ' in ' + element + ')'); + } + return own[key]; + }, + + assign: function(id, value) { + if (!id) return; + this.current().body.push(id, '=', value, ';'); + return id; + }, + + filter: function(filterName) { + if (!this.state.filters.hasOwnProperty(filterName)) { + this.state.filters[filterName] = this.nextId(true); + } + return this.state.filters[filterName]; + }, + + ifDefined: function(id, defaultValue) { + return 'ifDefined(' + id + ',' + this.escape(defaultValue) + ')'; + }, + + plus: function(left, right) { + return 'plus(' + left + ',' + right + ')'; + }, + + return_: function(id) { + this.current().body.push('return ', id, ';'); + }, + + if_: function(test, alternate, consequent) { + if (test === true) { + alternate(); + } else { + var body = this.current().body; + body.push('if(', test, '){'); + alternate(); + body.push('}'); + if (consequent) { + body.push('else{'); + consequent(); + body.push('}'); + } + } + }, + + not: function(expression) { + return '!(' + expression + ')'; + }, + + isNull: function(expression) { + return expression + '==null'; + }, + + notNull: function(expression) { + return expression + '!=null'; + }, + + nonComputedMember: function(left, right) { + var SAFE_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/; + var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g; + if (SAFE_IDENTIFIER.test(right)) { + return left + '.' + right; + } else { + return left + '["' + right.replace(UNSAFE_CHARACTERS, this.stringEscapeFn) + '"]'; + } + }, + + computedMember: function(left, right) { + return left + '[' + right + ']'; + }, + + member: function(left, right, computed) { + if (computed) return this.computedMember(left, right); + return this.nonComputedMember(left, right); + }, + + getStringValue: function(item) { + this.assign(item, 'getStringValue(' + item + ')'); + }, + + lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) { + var self = this; + return function() { + self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck); + }; + }, + + lazyAssign: function(id, value) { + var self = this; + return function() { + self.assign(id, value); + }; + }, + + stringEscapeRegex: /[^ a-zA-Z0-9]/g, + + stringEscapeFn: function(c) { + return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4); + }, + + escape: function(value) { + if (isString(value)) return '\'' + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + '\''; + if (isNumber(value)) return value.toString(); + if (value === true) return 'true'; + if (value === false) return 'false'; + if (value === null) return 'null'; + if (typeof value === 'undefined') return 'undefined'; + + throw $parseMinErr('esc', 'IMPOSSIBLE'); + }, + + nextId: function(skip, init) { + var id = 'v' + (this.state.nextId++); + if (!skip) { + this.current().vars.push(id + (init ? '=' + init : '')); + } + return id; + }, + + current: function() { + return this.state[this.state.computing]; + } +}; + + +function ASTInterpreter(astBuilder, $filter) { + this.astBuilder = astBuilder; + this.$filter = $filter; +} + +ASTInterpreter.prototype = { + compile: function(expression) { + var self = this; + var ast = this.astBuilder.ast(expression); + findConstantAndWatchExpressions(ast, self.$filter); + var assignable; + var assign; + if ((assignable = assignableAST(ast))) { + assign = this.recurse(assignable); + } + var toWatch = getInputs(ast.body); + var inputs; + if (toWatch) { + inputs = []; + forEach(toWatch, function(watch, key) { + var input = self.recurse(watch); + watch.input = input; + inputs.push(input); + watch.watchId = key; + }); + } + var expressions = []; + forEach(ast.body, function(expression) { + expressions.push(self.recurse(expression.expression)); + }); + var fn = ast.body.length === 0 ? noop : + ast.body.length === 1 ? expressions[0] : + function(scope, locals) { + var lastValue; + forEach(expressions, function(exp) { + lastValue = exp(scope, locals); + }); + return lastValue; + }; + if (assign) { + fn.assign = function(scope, value, locals) { + return assign(scope, locals, value); + }; + } + if (inputs) { + fn.inputs = inputs; + } + fn.literal = isLiteral(ast); + fn.constant = isConstant(ast); + return fn; + }, + + recurse: function(ast, context, create) { + var left, right, self = this, args; + if (ast.input) { + return this.inputs(ast.input, ast.watchId); + } + switch (ast.type) { + case AST.Literal: + return this.value(ast.value, context); + case AST.UnaryExpression: + right = this.recurse(ast.argument); + return this['unary' + ast.operator](right, context); + case AST.BinaryExpression: + left = this.recurse(ast.left); + right = this.recurse(ast.right); + return this['binary' + ast.operator](left, right, context); + case AST.LogicalExpression: + left = this.recurse(ast.left); + right = this.recurse(ast.right); + return this['binary' + ast.operator](left, right, context); + case AST.ConditionalExpression: + return this['ternary?:']( + this.recurse(ast.test), + this.recurse(ast.alternate), + this.recurse(ast.consequent), + context + ); + case AST.Identifier: + return self.identifier(ast.name, context, create); + case AST.MemberExpression: + left = this.recurse(ast.object, false, !!create); + if (!ast.computed) { + right = ast.property.name; + } + if (ast.computed) right = this.recurse(ast.property); + return ast.computed ? + this.computedMember(left, right, context, create) : + this.nonComputedMember(left, right, context, create); + case AST.CallExpression: + args = []; + forEach(ast.arguments, function(expr) { + args.push(self.recurse(expr)); + }); + if (ast.filter) right = this.$filter(ast.callee.name); + if (!ast.filter) right = this.recurse(ast.callee, true); + return ast.filter ? + function(scope, locals, assign, inputs) { + var values = []; + for (var i = 0; i < args.length; ++i) { + values.push(args[i](scope, locals, assign, inputs)); + } + var value = right.apply(undefined, values, inputs); + return context ? {context: undefined, name: undefined, value: value} : value; + } : + function(scope, locals, assign, inputs) { + var rhs = right(scope, locals, assign, inputs); + var value; + if (rhs.value != null) { + var values = []; + for (var i = 0; i < args.length; ++i) { + values.push(args[i](scope, locals, assign, inputs)); + } + value = rhs.value.apply(rhs.context, values); + } + return context ? {value: value} : value; + }; + case AST.AssignmentExpression: + left = this.recurse(ast.left, true, 1); + right = this.recurse(ast.right); + return function(scope, locals, assign, inputs) { + var lhs = left(scope, locals, assign, inputs); + var rhs = right(scope, locals, assign, inputs); + lhs.context[lhs.name] = rhs; + return context ? {value: rhs} : rhs; + }; + case AST.ArrayExpression: + args = []; + forEach(ast.elements, function(expr) { + args.push(self.recurse(expr)); + }); + return function(scope, locals, assign, inputs) { + var value = []; + for (var i = 0; i < args.length; ++i) { + value.push(args[i](scope, locals, assign, inputs)); + } + return context ? {value: value} : value; + }; + case AST.ObjectExpression: + args = []; + forEach(ast.properties, function(property) { + if (property.computed) { + args.push({key: self.recurse(property.key), + computed: true, + value: self.recurse(property.value) + }); + } else { + args.push({key: property.key.type === AST.Identifier ? + property.key.name : + ('' + property.key.value), + computed: false, + value: self.recurse(property.value) + }); + } + }); + return function(scope, locals, assign, inputs) { + var value = {}; + for (var i = 0; i < args.length; ++i) { + if (args[i].computed) { + value[args[i].key(scope, locals, assign, inputs)] = args[i].value(scope, locals, assign, inputs); + } else { + value[args[i].key] = args[i].value(scope, locals, assign, inputs); + } + } + return context ? {value: value} : value; + }; + case AST.ThisExpression: + return function(scope) { + return context ? {value: scope} : scope; + }; + case AST.LocalsExpression: + return function(scope, locals) { + return context ? {value: locals} : locals; + }; + case AST.NGValueParameter: + return function(scope, locals, assign) { + return context ? {value: assign} : assign; + }; + } + }, + + 'unary+': function(argument, context) { + return function(scope, locals, assign, inputs) { + var arg = argument(scope, locals, assign, inputs); + if (isDefined(arg)) { + arg = +arg; + } else { + arg = 0; + } + return context ? {value: arg} : arg; + }; + }, + 'unary-': function(argument, context) { + return function(scope, locals, assign, inputs) { + var arg = argument(scope, locals, assign, inputs); + if (isDefined(arg)) { + arg = -arg; + } else { + arg = -0; + } + return context ? {value: arg} : arg; + }; + }, + 'unary!': function(argument, context) { + return function(scope, locals, assign, inputs) { + var arg = !argument(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary+': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var lhs = left(scope, locals, assign, inputs); + var rhs = right(scope, locals, assign, inputs); + var arg = plusFn(lhs, rhs); + return context ? {value: arg} : arg; + }; + }, + 'binary-': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var lhs = left(scope, locals, assign, inputs); + var rhs = right(scope, locals, assign, inputs); + var arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0); + return context ? {value: arg} : arg; + }; + }, + 'binary*': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary/': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary%': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary===': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary!==': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary==': function(left, right, context) { + return function(scope, locals, assign, inputs) { + // eslint-disable-next-line eqeqeq + var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary!=': function(left, right, context) { + return function(scope, locals, assign, inputs) { + // eslint-disable-next-line eqeqeq + var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary<': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary>': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary<=': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary>=': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary&&': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'binary||': function(left, right, context) { + return function(scope, locals, assign, inputs) { + var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + 'ternary?:': function(test, alternate, consequent, context) { + return function(scope, locals, assign, inputs) { + var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs); + return context ? {value: arg} : arg; + }; + }, + value: function(value, context) { + return function() { return context ? {context: undefined, name: undefined, value: value} : value; }; + }, + identifier: function(name, context, create) { + return function(scope, locals, assign, inputs) { + var base = locals && (name in locals) ? locals : scope; + if (create && create !== 1 && base && base[name] == null) { + base[name] = {}; + } + var value = base ? base[name] : undefined; + if (context) { + return {context: base, name: name, value: value}; + } else { + return value; + } + }; + }, + computedMember: function(left, right, context, create) { + return function(scope, locals, assign, inputs) { + var lhs = left(scope, locals, assign, inputs); + var rhs; + var value; + if (lhs != null) { + rhs = right(scope, locals, assign, inputs); + rhs = getStringValue(rhs); + if (create && create !== 1) { + if (lhs && !(lhs[rhs])) { + lhs[rhs] = {}; + } + } + value = lhs[rhs]; + } + if (context) { + return {context: lhs, name: rhs, value: value}; + } else { + return value; + } + }; + }, + nonComputedMember: function(left, right, context, create) { + return function(scope, locals, assign, inputs) { + var lhs = left(scope, locals, assign, inputs); + if (create && create !== 1) { + if (lhs && lhs[right] == null) { + lhs[right] = {}; + } + } + var value = lhs != null ? lhs[right] : undefined; + if (context) { + return {context: lhs, name: right, value: value}; + } else { + return value; + } + }; + }, + inputs: function(input, watchId) { + return function(scope, value, locals, inputs) { + if (inputs) return inputs[watchId]; + return input(scope, value, locals); + }; + } +}; + +/** + * @constructor + */ +var Parser = function Parser(lexer, $filter, options) { + this.lexer = lexer; + this.$filter = $filter; + this.options = options; + this.ast = new AST(lexer, options); + this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) : + new ASTCompiler(this.ast, $filter); +}; + +Parser.prototype = { + constructor: Parser, + + parse: function(text) { + return this.astCompiler.compile(text); + } +}; + +function getValueOf(value) { + return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value); +} + +/////////////////////////////////// + +/** + * @ngdoc service + * @name $parse + * @kind function + * + * @description + * + * Converts Angular {@link guide/expression expression} into a function. + * + * ```js + * var getter = $parse('user.name'); + * var setter = getter.assign; + * var context = {user:{name:'angular'}}; + * var locals = {user:{name:'local'}}; + * + * expect(getter(context)).toEqual('angular'); + * setter(context, 'newValue'); + * expect(context.user.name).toEqual('newValue'); + * expect(getter(context, locals)).toEqual('local'); + * ``` + * + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + * + * The returned function also has the following properties: + * * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript + * literal. + * * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript + * constant literals. + * * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be + * set to a function to change its value on the given context. + * + */ + + +/** + * @ngdoc provider + * @name $parseProvider + * @this + * + * @description + * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} + * service. + */ +function $ParseProvider() { + var cache = createMap(); + var literals = { + 'true': true, + 'false': false, + 'null': null, + 'undefined': undefined + }; + var identStart, identContinue; + + /** + * @ngdoc method + * @name $parseProvider#addLiteral + * @description + * + * Configure $parse service to add literal values that will be present as literal at expressions. + * + * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name. + * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`. + * + **/ + this.addLiteral = function(literalName, literalValue) { + literals[literalName] = literalValue; + }; + + /** + * @ngdoc method + * @name $parseProvider#setIdentifierFns + * + * @description + * + * Allows defining the set of characters that are allowed in Angular expressions. The function + * `identifierStart` will get called to know if a given character is a valid character to be the + * first character for an identifier. The function `identifierContinue` will get called to know if + * a given character is a valid character to be a follow-up identifier character. The functions + * `identifierStart` and `identifierContinue` will receive as arguments the single character to be + * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in + * mind that the `string` parameter can be two characters long depending on the character + * representation. It is expected for the function to return `true` or `false`, whether that + * character is allowed or not. + * + * Since this function will be called extensively, keep the implementation of these functions fast, + * as the performance of these functions have a direct impact on the expressions parsing speed. + * + * @param {function=} identifierStart The function that will decide whether the given character is + * a valid identifier start character. + * @param {function=} identifierContinue The function that will decide whether the given character is + * a valid identifier continue character. + */ + this.setIdentifierFns = function(identifierStart, identifierContinue) { + identStart = identifierStart; + identContinue = identifierContinue; + return this; + }; + + this.$get = ['$filter', function($filter) { + var noUnsafeEval = csp().noUnsafeEval; + var $parseOptions = { + csp: noUnsafeEval, + literals: copy(literals), + isIdentifierStart: isFunction(identStart) && identStart, + isIdentifierContinue: isFunction(identContinue) && identContinue + }; + return $parse; + + function $parse(exp, interceptorFn) { + var parsedExpression, oneTime, cacheKey; + + switch (typeof exp) { + case 'string': + exp = exp.trim(); + cacheKey = exp; + + parsedExpression = cache[cacheKey]; + + if (!parsedExpression) { + if (exp.charAt(0) === ':' && exp.charAt(1) === ':') { + oneTime = true; + exp = exp.substring(2); + } + var lexer = new Lexer($parseOptions); + var parser = new Parser(lexer, $filter, $parseOptions); + parsedExpression = parser.parse(exp); + if (parsedExpression.constant) { + parsedExpression.$$watchDelegate = constantWatchDelegate; + } else if (oneTime) { + parsedExpression.$$watchDelegate = parsedExpression.literal ? + oneTimeLiteralWatchDelegate : oneTimeWatchDelegate; + } else if (parsedExpression.inputs) { + parsedExpression.$$watchDelegate = inputsWatchDelegate; + } + cache[cacheKey] = parsedExpression; + } + return addInterceptor(parsedExpression, interceptorFn); + + case 'function': + return addInterceptor(exp, interceptorFn); + + default: + return addInterceptor(noop, interceptorFn); + } + } + + function expressionInputDirtyCheck(newValue, oldValueOfValue) { + + if (newValue == null || oldValueOfValue == null) { // null/undefined + return newValue === oldValueOfValue; + } + + if (typeof newValue === 'object') { + + // attempt to convert the value to a primitive type + // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can + // be cheaply dirty-checked + newValue = getValueOf(newValue); + + if (typeof newValue === 'object') { + // objects/arrays are not supported - deep-watching them would be too expensive + return false; + } + + // fall-through to the primitive equality check + } + + //Primitive or NaN + // eslint-disable-next-line no-self-compare + return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue); + } + + function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) { + var inputExpressions = parsedExpression.inputs; + var lastResult; + + if (inputExpressions.length === 1) { + var oldInputValueOf = expressionInputDirtyCheck; // init to something unique so that equals check fails + inputExpressions = inputExpressions[0]; + return scope.$watch(function expressionInputWatch(scope) { + var newInputValue = inputExpressions(scope); + if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf)) { + lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]); + oldInputValueOf = newInputValue && getValueOf(newInputValue); + } + return lastResult; + }, listener, objectEquality, prettyPrintExpression); + } + + var oldInputValueOfValues = []; + var oldInputValues = []; + for (var i = 0, ii = inputExpressions.length; i < ii; i++) { + oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails + oldInputValues[i] = null; + } + + return scope.$watch(function expressionInputsWatch(scope) { + var changed = false; + + for (var i = 0, ii = inputExpressions.length; i < ii; i++) { + var newInputValue = inputExpressions[i](scope); + if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) { + oldInputValues[i] = newInputValue; + oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue); + } + } + + if (changed) { + lastResult = parsedExpression(scope, undefined, undefined, oldInputValues); + } + + return lastResult; + }, listener, objectEquality, prettyPrintExpression); + } + + function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) { + var unwatch, lastValue; + if (parsedExpression.inputs) { + unwatch = inputsWatchDelegate(scope, oneTimeListener, objectEquality, parsedExpression, prettyPrintExpression); + } else { + unwatch = scope.$watch(oneTimeWatch, oneTimeListener, objectEquality); + } + return unwatch; + + function oneTimeWatch(scope) { + return parsedExpression(scope); + } + function oneTimeListener(value, old, scope) { + lastValue = value; + if (isFunction(listener)) { + listener(value, old, scope); + } + if (isDefined(value)) { + scope.$$postDigest(function() { + if (isDefined(lastValue)) { + unwatch(); + } + }); + } + } + } + + function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) { + var unwatch, lastValue; + unwatch = scope.$watch(function oneTimeWatch(scope) { + return parsedExpression(scope); + }, function oneTimeListener(value, old, scope) { + lastValue = value; + if (isFunction(listener)) { + listener(value, old, scope); + } + if (isAllDefined(value)) { + scope.$$postDigest(function() { + if (isAllDefined(lastValue)) unwatch(); + }); + } + }, objectEquality); + + return unwatch; + + function isAllDefined(value) { + var allDefined = true; + forEach(value, function(val) { + if (!isDefined(val)) allDefined = false; + }); + return allDefined; + } + } + + function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) { + var unwatch = scope.$watch(function constantWatch(scope) { + unwatch(); + return parsedExpression(scope); + }, listener, objectEquality); + return unwatch; + } + + function addInterceptor(parsedExpression, interceptorFn) { + if (!interceptorFn) return parsedExpression; + var watchDelegate = parsedExpression.$$watchDelegate; + var useInputs = false; + + var regularWatch = + watchDelegate !== oneTimeLiteralWatchDelegate && + watchDelegate !== oneTimeWatchDelegate; + + var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) { + var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs); + return interceptorFn(value, scope, locals); + } : function oneTimeInterceptedExpression(scope, locals, assign, inputs) { + var value = parsedExpression(scope, locals, assign, inputs); + var result = interceptorFn(value, scope, locals); + // we only return the interceptor's result if the + // initial value is defined (for bind-once) + return isDefined(value) ? result : value; + }; + + // Propagate $$watchDelegates other then inputsWatchDelegate + useInputs = !parsedExpression.inputs; + if (parsedExpression.$$watchDelegate && + parsedExpression.$$watchDelegate !== inputsWatchDelegate) { + fn.$$watchDelegate = parsedExpression.$$watchDelegate; + fn.inputs = parsedExpression.inputs; + } else if (!interceptorFn.$stateful) { + // If there is an interceptor, but no watchDelegate then treat the interceptor like + // we treat filters - it is assumed to be a pure function unless flagged with $stateful + fn.$$watchDelegate = inputsWatchDelegate; + fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression]; + } + + return fn; + } + }]; +} + +/** + * @ngdoc service + * @name $q + * @requires $rootScope + * + * @description + * A service that helps you run functions asynchronously, and use their return values (or exceptions) + * when they are done processing. + * + * This is a [Promises/A+](https://promisesaplus.com/)-compliant implementation of promises/deferred + * objects inspired by [Kris Kowal's Q](https://github.com/kriskowal/q). + * + * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred + * implementations, and the other which resembles ES6 (ES2015) promises to some degree. + * + * # $q constructor + * + * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver` + * function as the first argument. This is similar to the native Promise implementation from ES6, + * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). + * + * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are + * available yet. + * + * It can be used like so: + * + * ```js + * // for the purpose of this example let's assume that variables `$q` and `okToGreet` + * // are available in the current lexical scope (they could have been injected or passed in). + * + * function asyncGreet(name) { + * // perform some asynchronous operation, resolve or reject the promise when appropriate. + * return $q(function(resolve, reject) { + * setTimeout(function() { + * if (okToGreet(name)) { + * resolve('Hello, ' + name + '!'); + * } else { + * reject('Greeting ' + name + ' is not allowed.'); + * } + * }, 1000); + * }); + * } + * + * var promise = asyncGreet('Robin Hood'); + * promise.then(function(greeting) { + * alert('Success: ' + greeting); + * }, function(reason) { + * alert('Failed: ' + reason); + * }); + * ``` + * + * Note: progress/notify callbacks are not currently supported via the ES6-style interface. + * + * Note: unlike ES6 behavior, an exception thrown in the constructor function will NOT implicitly reject the promise. + * + * However, the more traditional CommonJS-style usage is still available, and documented below. + * + * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an + * interface for interacting with an object that represents the result of an action that is + * performed asynchronously, and may or may not be finished at any given point in time. + * + * From the perspective of dealing with error handling, deferred and promise APIs are to + * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming. + * + * ```js + * // for the purpose of this example let's assume that variables `$q` and `okToGreet` + * // are available in the current lexical scope (they could have been injected or passed in). + * + * function asyncGreet(name) { + * var deferred = $q.defer(); + * + * setTimeout(function() { + * deferred.notify('About to greet ' + name + '.'); + * + * if (okToGreet(name)) { + * deferred.resolve('Hello, ' + name + '!'); + * } else { + * deferred.reject('Greeting ' + name + ' is not allowed.'); + * } + * }, 1000); + * + * return deferred.promise; + * } + * + * var promise = asyncGreet('Robin Hood'); + * promise.then(function(greeting) { + * alert('Success: ' + greeting); + * }, function(reason) { + * alert('Failed: ' + reason); + * }, function(update) { + * alert('Got notification: ' + update); + * }); + * ``` + * + * At first it might not be obvious why this extra complexity is worth the trouble. The payoff + * comes in the way of guarantees that promise and deferred APIs make, see + * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md. + * + * Additionally the promise api allows for composition that is very hard to do with the + * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach. + * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the + * section on serial or parallel joining of promises. + * + * # The Deferred API + * + * A new instance of deferred is constructed by calling `$q.defer()`. + * + * The purpose of the deferred object is to expose the associated Promise instance as well as APIs + * that can be used for signaling the successful or unsuccessful completion, as well as the status + * of the task. + * + * **Methods** + * + * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection + * constructed via `$q.reject`, the promise will be rejected instead. + * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to + * resolving it with a rejection constructed via `$q.reject`. + * - `notify(value)` - provides updates on the status of the promise's execution. This may be called + * multiple times before the promise is either resolved or rejected. + * + * **Properties** + * + * - promise – `{Promise}` – promise object associated with this deferred. + * + * + * # The Promise API + * + * A new promise instance is created when a deferred instance is created and can be retrieved by + * calling `deferred.promise`. + * + * The purpose of the promise object is to allow for interested parties to get access to the result + * of the deferred task when it completes. + * + * **Methods** + * + * - `then(successCallback, [errorCallback], [notifyCallback])` – regardless of when the promise was or + * will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously + * as soon as the result is available. The callbacks are called with a single argument: the result + * or rejection reason. Additionally, the notify callback may be called zero or more times to + * provide a progress indication, before the promise is resolved or rejected. + * + * This method *returns a new promise* which is resolved or rejected via the return value of the + * `successCallback`, `errorCallback` (unless that value is a promise, in which case it is resolved + * with the value which is resolved in that promise using + * [promise chaining](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promises-queues)). + * It also notifies via the return value of the `notifyCallback` method. The promise cannot be + * resolved or rejected from the notifyCallback method. The errorCallback and notifyCallback + * arguments are optional. + * + * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)` + * + * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise, + * but to do so without modifying the final value. This is useful to release resources or do some + * clean-up that needs to be done whether the promise was rejected or resolved. See the [full + * specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for + * more information. + * + * # Chaining promises + * + * Because calling the `then` method of a promise returns a new derived promise, it is easily + * possible to create a chain of promises: + * + * ```js + * promiseB = promiseA.then(function(result) { + * return result + 1; + * }); + * + * // promiseB will be resolved immediately after promiseA is resolved and its value + * // will be the result of promiseA incremented by 1 + * ``` + * + * It is possible to create chains of any length and since a promise can be resolved with another + * promise (which will defer its resolution further), it is possible to pause/defer resolution of + * the promises at any point in the chain. This makes it possible to implement powerful APIs like + * $http's response interceptors. + * + * + * # Differences between Kris Kowal's Q and $q + * + * There are two main differences: + * + * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation + * mechanism in angular, which means faster propagation of resolution or rejection into your + * models and avoiding unnecessary browser repaints, which would result in flickering UI. + * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains + * all the important functionality needed for common async tasks. + * + * # Testing + * + * ```js + * it('should simulate promise', inject(function($q, $rootScope) { + * var deferred = $q.defer(); + * var promise = deferred.promise; + * var resolvedValue; + * + * promise.then(function(value) { resolvedValue = value; }); + * expect(resolvedValue).toBeUndefined(); + * + * // Simulate resolving of promise + * deferred.resolve(123); + * // Note that the 'then' function does not get called synchronously. + * // This is because we want the promise API to always be async, whether or not + * // it got called synchronously or asynchronously. + * expect(resolvedValue).toBeUndefined(); + * + * // Propagate promise resolution to 'then' functions using $apply(). + * $rootScope.$apply(); + * expect(resolvedValue).toEqual(123); + * })); + * ``` + * + * @param {function(function, function)} resolver Function which is responsible for resolving or + * rejecting the newly created promise. The first parameter is a function which resolves the + * promise, the second parameter is a function which rejects the promise. + * + * @returns {Promise} The newly created promise. + */ +/** + * @ngdoc provider + * @name $qProvider + * @this + * + * @description + */ +function $QProvider() { + var errorOnUnhandledRejections = true; + this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) { + return qFactory(function(callback) { + $rootScope.$evalAsync(callback); + }, $exceptionHandler, errorOnUnhandledRejections); + }]; + + /** + * @ngdoc method + * @name $qProvider#errorOnUnhandledRejections + * @kind function + * + * @description + * Retrieves or overrides whether to generate an error when a rejected promise is not handled. + * This feature is enabled by default. + * + * @param {boolean=} value Whether to generate an error when a rejected promise is not handled. + * @returns {boolean|ng.$qProvider} Current value when called without a new value or self for + * chaining otherwise. + */ + this.errorOnUnhandledRejections = function(value) { + if (isDefined(value)) { + errorOnUnhandledRejections = value; + return this; + } else { + return errorOnUnhandledRejections; + } + }; +} + +/** @this */ +function $$QProvider() { + var errorOnUnhandledRejections = true; + this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) { + return qFactory(function(callback) { + $browser.defer(callback); + }, $exceptionHandler, errorOnUnhandledRejections); + }]; + + this.errorOnUnhandledRejections = function(value) { + if (isDefined(value)) { + errorOnUnhandledRejections = value; + return this; + } else { + return errorOnUnhandledRejections; + } + }; +} + +/** + * Constructs a promise manager. + * + * @param {function(function)} nextTick Function for executing functions in the next turn. + * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for + * debugging purposes. + @ param {=boolean} errorOnUnhandledRejections Whether an error should be generated on unhandled + * promises rejections. + * @returns {object} Promise manager. + */ +function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) { + var $qMinErr = minErr('$q', TypeError); + var queueSize = 0; + var checkQueue = []; + + /** + * @ngdoc method + * @name ng.$q#defer + * @kind function + * + * @description + * Creates a `Deferred` object which represents a task which will finish in the future. + * + * @returns {Deferred} Returns a new instance of deferred. + */ + function defer() { + return new Deferred(); + } + + function Deferred() { + var promise = this.promise = new Promise(); + //Non prototype methods necessary to support unbound execution :/ + this.resolve = function(val) { resolvePromise(promise, val); }; + this.reject = function(reason) { rejectPromise(promise, reason); }; + this.notify = function(progress) { notifyPromise(promise, progress); }; + } + + + function Promise() { + this.$$state = { status: 0 }; + } + + extend(Promise.prototype, { + then: function(onFulfilled, onRejected, progressBack) { + if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) { + return this; + } + var result = new Promise(); + + this.$$state.pending = this.$$state.pending || []; + this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]); + if (this.$$state.status > 0) scheduleProcessQueue(this.$$state); + + return result; + }, + + 'catch': function(callback) { + return this.then(null, callback); + }, + + 'finally': function(callback, progressBack) { + return this.then(function(value) { + return handleCallback(value, resolve, callback); + }, function(error) { + return handleCallback(error, reject, callback); + }, progressBack); + } + }); + + function processQueue(state) { + var fn, promise, pending; + + pending = state.pending; + state.processScheduled = false; + state.pending = undefined; + try { + for (var i = 0, ii = pending.length; i < ii; ++i) { + state.pur = true; + promise = pending[i][0]; + fn = pending[i][state.status]; + try { + if (isFunction(fn)) { + resolvePromise(promise, fn(state.value)); + } else if (state.status === 1) { + resolvePromise(promise, state.value); + } else { + rejectPromise(promise, state.value); + } + } catch (e) { + rejectPromise(promise, e); + } + } + } finally { + --queueSize; + if (errorOnUnhandledRejections && queueSize === 0) { + nextTick(processChecks); + } + } + } + + function processChecks() { + // eslint-disable-next-line no-unmodified-loop-condition + while (!queueSize && checkQueue.length) { + var toCheck = checkQueue.shift(); + if (!toCheck.pur) { + toCheck.pur = true; + var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value); + if (toCheck.value instanceof Error) { + exceptionHandler(toCheck.value, errorMessage); + } else { + exceptionHandler(errorMessage); + } + } + } + } + + function scheduleProcessQueue(state) { + if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !state.pur) { + if (queueSize === 0 && checkQueue.length === 0) { + nextTick(processChecks); + } + checkQueue.push(state); + } + if (state.processScheduled || !state.pending) return; + state.processScheduled = true; + ++queueSize; + nextTick(function() { processQueue(state); }); + } + + function resolvePromise(promise, val) { + if (promise.$$state.status) return; + if (val === promise) { + $$reject(promise, $qMinErr( + 'qcycle', + 'Expected promise to be resolved with value other than itself \'{0}\'', + val)); + } else { + $$resolve(promise, val); + } + + } + + function $$resolve(promise, val) { + var then; + var done = false; + try { + if (isObject(val) || isFunction(val)) then = val.then; + if (isFunction(then)) { + promise.$$state.status = -1; + then.call(val, doResolve, doReject, doNotify); + } else { + promise.$$state.value = val; + promise.$$state.status = 1; + scheduleProcessQueue(promise.$$state); + } + } catch (e) { + doReject(e); + } + + function doResolve(val) { + if (done) return; + done = true; + $$resolve(promise, val); + } + function doReject(val) { + if (done) return; + done = true; + $$reject(promise, val); + } + function doNotify(progress) { + notifyPromise(promise, progress); + } + } + + function rejectPromise(promise, reason) { + if (promise.$$state.status) return; + $$reject(promise, reason); + } + + function $$reject(promise, reason) { + promise.$$state.value = reason; + promise.$$state.status = 2; + scheduleProcessQueue(promise.$$state); + } + + function notifyPromise(promise, progress) { + var callbacks = promise.$$state.pending; + + if ((promise.$$state.status <= 0) && callbacks && callbacks.length) { + nextTick(function() { + var callback, result; + for (var i = 0, ii = callbacks.length; i < ii; i++) { + result = callbacks[i][0]; + callback = callbacks[i][3]; + try { + notifyPromise(result, isFunction(callback) ? callback(progress) : progress); + } catch (e) { + exceptionHandler(e); + } + } + }); + } + } + + /** + * @ngdoc method + * @name $q#reject + * @kind function + * + * @description + * Creates a promise that is resolved as rejected with the specified `reason`. This api should be + * used to forward rejection in a chain of promises. If you are dealing with the last promise in + * a promise chain, you don't need to worry about it. + * + * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of + * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via + * a promise error callback and you want to forward the error to the promise derived from the + * current promise, you have to "rethrow" the error by returning a rejection constructed via + * `reject`. + * + * ```js + * promiseB = promiseA.then(function(result) { + * // success: do something and resolve promiseB + * // with the old or a new result + * return result; + * }, function(reason) { + * // error: handle the error if possible and + * // resolve promiseB with newPromiseOrValue, + * // otherwise forward the rejection to promiseB + * if (canHandle(reason)) { + * // handle the error and recover + * return newPromiseOrValue; + * } + * return $q.reject(reason); + * }); + * ``` + * + * @param {*} reason Constant, message, exception or an object representing the rejection reason. + * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`. + */ + function reject(reason) { + var result = new Promise(); + rejectPromise(result, reason); + return result; + } + + function handleCallback(value, resolver, callback) { + var callbackOutput = null; + try { + if (isFunction(callback)) callbackOutput = callback(); + } catch (e) { + return reject(e); + } + if (isPromiseLike(callbackOutput)) { + return callbackOutput.then(function() { + return resolver(value); + }, reject); + } else { + return resolver(value); + } + } + + /** + * @ngdoc method + * @name $q#when + * @kind function + * + * @description + * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. + * This is useful when you are dealing with an object that might or might not be a promise, or if + * the promise comes from a source that can't be trusted. + * + * @param {*} value Value or a promise + * @param {Function=} successCallback + * @param {Function=} errorCallback + * @param {Function=} progressCallback + * @returns {Promise} Returns a promise of the passed value or promise + */ + + + function when(value, callback, errback, progressBack) { + var result = new Promise(); + resolvePromise(result, value); + return result.then(callback, errback, progressBack); + } + + /** + * @ngdoc method + * @name $q#resolve + * @kind function + * + * @description + * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6. + * + * @param {*} value Value or a promise + * @param {Function=} successCallback + * @param {Function=} errorCallback + * @param {Function=} progressCallback + * @returns {Promise} Returns a promise of the passed value or promise + */ + var resolve = when; + + /** + * @ngdoc method + * @name $q#all + * @kind function + * + * @description + * Combines multiple promises into a single promise that is resolved when all of the input + * promises are resolved. + * + * @param {Array.|Object.} promises An array or hash of promises. + * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values, + * each value corresponding to the promise at the same index/key in the `promises` array/hash. + * If any of the promises is resolved with a rejection, this resulting promise will be rejected + * with the same rejection value. + */ + + function all(promises) { + var result = new Promise(), + counter = 0, + results = isArray(promises) ? [] : {}; + + forEach(promises, function(promise, key) { + counter++; + when(promise).then(function(value) { + results[key] = value; + if (!(--counter)) resolvePromise(result, results); + }, function(reason) { + rejectPromise(result, reason); + }); + }); + + if (counter === 0) { + resolvePromise(result, results); + } + + return result; + } + + /** + * @ngdoc method + * @name $q#race + * @kind function + * + * @description + * Returns a promise that resolves or rejects as soon as one of those promises + * resolves or rejects, with the value or reason from that promise. + * + * @param {Array.|Object.} promises An array or hash of promises. + * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises` + * resolves or rejects, with the value or reason from that promise. + */ + + function race(promises) { + var deferred = defer(); + + forEach(promises, function(promise) { + when(promise).then(deferred.resolve, deferred.reject); + }); + + return deferred.promise; + } + + function $Q(resolver) { + if (!isFunction(resolver)) { + throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver); + } + + var promise = new Promise(); + + function resolveFn(value) { + resolvePromise(promise, value); + } + + function rejectFn(reason) { + rejectPromise(promise, reason); + } + + resolver(resolveFn, rejectFn); + + return promise; + } + + // Let's make the instanceof operator work for promises, so that + // `new $q(fn) instanceof $q` would evaluate to true. + $Q.prototype = Promise.prototype; + + $Q.defer = defer; + $Q.reject = reject; + $Q.when = when; + $Q.resolve = resolve; + $Q.all = all; + $Q.race = race; + + return $Q; +} + +/** @this */ +function $$RAFProvider() { //rAF + this.$get = ['$window', '$timeout', function($window, $timeout) { + var requestAnimationFrame = $window.requestAnimationFrame || + $window.webkitRequestAnimationFrame; + + var cancelAnimationFrame = $window.cancelAnimationFrame || + $window.webkitCancelAnimationFrame || + $window.webkitCancelRequestAnimationFrame; + + var rafSupported = !!requestAnimationFrame; + var raf = rafSupported + ? function(fn) { + var id = requestAnimationFrame(fn); + return function() { + cancelAnimationFrame(id); + }; + } + : function(fn) { + var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666 + return function() { + $timeout.cancel(timer); + }; + }; + + raf.supported = rafSupported; + + return raf; + }]; +} + +/** + * DESIGN NOTES + * + * The design decisions behind the scope are heavily favored for speed and memory consumption. + * + * The typical use of scope is to watch the expressions, which most of the time return the same + * value as last time so we optimize the operation. + * + * Closures construction is expensive in terms of speed as well as memory: + * - No closures, instead use prototypical inheritance for API + * - Internal state needs to be stored on scope directly, which means that private state is + * exposed as $$____ properties + * + * Loop operations are optimized by using while(count--) { ... } + * - This means that in order to keep the same order of execution as addition we have to add + * items to the array at the beginning (unshift) instead of at the end (push) + * + * Child scopes are created and removed often + * - Using an array would be slow since inserts in the middle are expensive; so we use linked lists + * + * There are fewer watches than observers. This is why you don't want the observer to be implemented + * in the same way as watch. Watch requires return of the initialization function which is expensive + * to construct. + */ + + +/** + * @ngdoc provider + * @name $rootScopeProvider + * @description + * + * Provider for the $rootScope service. + */ + +/** + * @ngdoc method + * @name $rootScopeProvider#digestTtl + * @description + * + * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and + * assuming that the model is unstable. + * + * The current default is 10 iterations. + * + * In complex applications it's possible that the dependencies between `$watch`s will result in + * several digest iterations. However if an application needs more than the default 10 digest + * iterations for its model to stabilize then you should investigate what is causing the model to + * continuously change during the digest. + * + * Increasing the TTL could have performance implications, so you should not change it without + * proper justification. + * + * @param {number} limit The number of digest iterations. + */ + + +/** + * @ngdoc service + * @name $rootScope + * @this + * + * @description + * + * Every application has a single root {@link ng.$rootScope.Scope scope}. + * All other scopes are descendant scopes of the root scope. Scopes provide separation + * between the model and the view, via a mechanism for watching the model for changes. + * They also provide event emission/broadcast and subscription facility. See the + * {@link guide/scope developer guide on scopes}. + */ +function $RootScopeProvider() { + var TTL = 10; + var $rootScopeMinErr = minErr('$rootScope'); + var lastDirtyWatch = null; + var applyAsyncId = null; + + this.digestTtl = function(value) { + if (arguments.length) { + TTL = value; + } + return TTL; + }; + + function createChildScopeClass(parent) { + function ChildScope() { + this.$$watchers = this.$$nextSibling = + this.$$childHead = this.$$childTail = null; + this.$$listeners = {}; + this.$$listenerCount = {}; + this.$$watchersCount = 0; + this.$id = nextUid(); + this.$$ChildScope = null; + } + ChildScope.prototype = parent; + return ChildScope; + } + + this.$get = ['$exceptionHandler', '$parse', '$browser', + function($exceptionHandler, $parse, $browser) { + + function destroyChildScope($event) { + $event.currentScope.$$destroyed = true; + } + + function cleanUpScope($scope) { + + // Support: IE 9 only + if (msie === 9) { + // There is a memory leak in IE9 if all child scopes are not disconnected + // completely when a scope is destroyed. So this code will recurse up through + // all this scopes children + // + // See issue https://github.com/angular/angular.js/issues/10706 + if ($scope.$$childHead) { + cleanUpScope($scope.$$childHead); + } + if ($scope.$$nextSibling) { + cleanUpScope($scope.$$nextSibling); + } + } + + // The code below works around IE9 and V8's memory leaks + // + // See: + // - https://code.google.com/p/v8/issues/detail?id=2073#c26 + // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909 + // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451 + + $scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead = + $scope.$$childTail = $scope.$root = $scope.$$watchers = null; + } + + /** + * @ngdoc type + * @name $rootScope.Scope + * + * @description + * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the + * {@link auto.$injector $injector}. Child scopes are created using the + * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when + * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for + * an in-depth introduction and usage examples. + * + * + * # Inheritance + * A scope can inherit from a parent scope, as in this example: + * ```js + var parent = $rootScope; + var child = parent.$new(); + + parent.salutation = "Hello"; + expect(child.salutation).toEqual('Hello'); + + child.salutation = "Welcome"; + expect(child.salutation).toEqual('Welcome'); + expect(parent.salutation).toEqual('Hello'); + * ``` + * + * When interacting with `Scope` in tests, additional helper methods are available on the + * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional + * details. + * + * + * @param {Object.=} providers Map of service factory which need to be + * provided for the current scope. Defaults to {@link ng}. + * @param {Object.=} instanceCache Provides pre-instantiated services which should + * append/override services provided by `providers`. This is handy + * when unit-testing and having the need to override a default + * service. + * @returns {Object} Newly created scope. + * + */ + function Scope() { + this.$id = nextUid(); + this.$$phase = this.$parent = this.$$watchers = + this.$$nextSibling = this.$$prevSibling = + this.$$childHead = this.$$childTail = null; + this.$root = this; + this.$$destroyed = false; + this.$$listeners = {}; + this.$$listenerCount = {}; + this.$$watchersCount = 0; + this.$$isolateBindings = null; + } + + /** + * @ngdoc property + * @name $rootScope.Scope#$id + * + * @description + * Unique scope ID (monotonically increasing) useful for debugging. + */ + + /** + * @ngdoc property + * @name $rootScope.Scope#$parent + * + * @description + * Reference to the parent scope. + */ + + /** + * @ngdoc property + * @name $rootScope.Scope#$root + * + * @description + * Reference to the root scope. + */ + + Scope.prototype = { + constructor: Scope, + /** + * @ngdoc method + * @name $rootScope.Scope#$new + * @kind function + * + * @description + * Creates a new child {@link ng.$rootScope.Scope scope}. + * + * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event. + * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. + * + * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is + * desired for the scope and its child scopes to be permanently detached from the parent and + * thus stop participating in model change detection and listener notification by invoking. + * + * @param {boolean} isolate If true, then the scope does not prototypically inherit from the + * parent scope. The scope is isolated, as it can not see parent scope properties. + * When creating widgets, it is useful for the widget to not accidentally read parent + * state. + * + * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent` + * of the newly created scope. Defaults to `this` scope if not provided. + * This is used when creating a transclude scope to correctly place it + * in the scope hierarchy while maintaining the correct prototypical + * inheritance. + * + * @returns {Object} The newly created child scope. + * + */ + $new: function(isolate, parent) { + var child; + + parent = parent || this; + + if (isolate) { + child = new Scope(); + child.$root = this.$root; + } else { + // Only create a child scope class if somebody asks for one, + // but cache it to allow the VM to optimize lookups. + if (!this.$$ChildScope) { + this.$$ChildScope = createChildScopeClass(this); + } + child = new this.$$ChildScope(); + } + child.$parent = parent; + child.$$prevSibling = parent.$$childTail; + if (parent.$$childHead) { + parent.$$childTail.$$nextSibling = child; + parent.$$childTail = child; + } else { + parent.$$childHead = parent.$$childTail = child; + } + + // When the new scope is not isolated or we inherit from `this`, and + // the parent scope is destroyed, the property `$$destroyed` is inherited + // prototypically. In all other cases, this property needs to be set + // when the parent scope is destroyed. + // The listener needs to be added after the parent is set + if (isolate || parent !== this) child.$on('$destroy', destroyChildScope); + + return child; + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$watch + * @kind function + * + * @description + * Registers a `listener` callback to be executed whenever the `watchExpression` changes. + * + * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest + * $digest()} and should return the value that will be watched. (`watchExpression` should not change + * its value when executed multiple times with the same input because it may be executed multiple + * times by {@link ng.$rootScope.Scope#$digest $digest()}. That is, `watchExpression` should be + * [idempotent](http://en.wikipedia.org/wiki/Idempotence).) + * - The `listener` is called only when the value from the current `watchExpression` and the + * previous call to `watchExpression` are not equal (with the exception of the initial run, + * see below). Inequality is determined according to reference inequality, + * [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) + * via the `!==` Javascript operator, unless `objectEquality == true` + * (see next point) + * - When `objectEquality == true`, inequality of the `watchExpression` is determined + * according to the {@link angular.equals} function. To save the value of the object for + * later comparison, the {@link angular.copy} function is used. This therefore means that + * watching complex objects will have adverse memory and performance implications. + * - This should not be used to watch for changes in objects that are + * or contain [File](https://developer.mozilla.org/docs/Web/API/File) objects due to limitations with {@link angular.copy `angular.copy`}. + * - The watch `listener` may change the model, which may trigger other `listener`s to fire. + * This is achieved by rerunning the watchers until no changes are detected. The rerun + * iteration limit is 10 to prevent an infinite loop deadlock. + * + * + * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called, + * you can register a `watchExpression` function with no `listener`. (Be prepared for + * multiple calls to your `watchExpression` because it will execute multiple times in a + * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.) + * + * After a watcher is registered with the scope, the `listener` fn is called asynchronously + * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the + * watcher. In rare cases, this is undesirable because the listener is called when the result + * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you + * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the + * listener was called due to initialization. + * + * + * + * # Example + * ```js + // let's assume that scope was dependency injected as the $rootScope + var scope = $rootScope; + scope.name = 'misko'; + scope.counter = 0; + + expect(scope.counter).toEqual(0); + scope.$watch('name', function(newValue, oldValue) { + scope.counter = scope.counter + 1; + }); + expect(scope.counter).toEqual(0); + + scope.$digest(); + // the listener is always called during the first $digest loop after it was registered + expect(scope.counter).toEqual(1); + + scope.$digest(); + // but now it will not be called unless the value changes + expect(scope.counter).toEqual(1); + + scope.name = 'adam'; + scope.$digest(); + expect(scope.counter).toEqual(2); + + + + // Using a function as a watchExpression + var food; + scope.foodCounter = 0; + expect(scope.foodCounter).toEqual(0); + scope.$watch( + // This function returns the value being watched. It is called for each turn of the $digest loop + function() { return food; }, + // This is the change listener, called when the value returned from the above function changes + function(newValue, oldValue) { + if ( newValue !== oldValue ) { + // Only increment the counter if the value changed + scope.foodCounter = scope.foodCounter + 1; + } + } + ); + // No digest has been run so the counter will be zero + expect(scope.foodCounter).toEqual(0); + + // Run the digest but since food has not changed count will still be zero + scope.$digest(); + expect(scope.foodCounter).toEqual(0); + + // Update food and run digest. Now the counter will increment + food = 'cheeseburger'; + scope.$digest(); + expect(scope.foodCounter).toEqual(1); + + * ``` + * + * + * + * @param {(function()|string)} watchExpression Expression that is evaluated on each + * {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers + * a call to the `listener`. + * + * - `string`: Evaluated as {@link guide/expression expression} + * - `function(scope)`: called with current `scope` as a parameter. + * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value + * of `watchExpression` changes. + * + * - `newVal` contains the current value of the `watchExpression` + * - `oldVal` contains the previous value of the `watchExpression` + * - `scope` refers to the current scope + * @param {boolean=} [objectEquality=false] Compare for object equality using {@link angular.equals} instead of + * comparing for reference equality. + * @returns {function()} Returns a deregistration function for this listener. + */ + $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) { + var get = $parse(watchExp); + + if (get.$$watchDelegate) { + return get.$$watchDelegate(this, listener, objectEquality, get, watchExp); + } + var scope = this, + array = scope.$$watchers, + watcher = { + fn: listener, + last: initWatchVal, + get: get, + exp: prettyPrintExpression || watchExp, + eq: !!objectEquality + }; + + lastDirtyWatch = null; + + if (!isFunction(listener)) { + watcher.fn = noop; + } + + if (!array) { + array = scope.$$watchers = []; + array.$$digestWatchIndex = -1; + } + // we use unshift since we use a while loop in $digest for speed. + // the while loop reads in reverse order. + array.unshift(watcher); + array.$$digestWatchIndex++; + incrementWatchersCount(this, 1); + + return function deregisterWatch() { + var index = arrayRemove(array, watcher); + if (index >= 0) { + incrementWatchersCount(scope, -1); + if (index < array.$$digestWatchIndex) { + array.$$digestWatchIndex--; + } + } + lastDirtyWatch = null; + }; + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$watchGroup + * @kind function + * + * @description + * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`. + * If any one expression in the collection changes the `listener` is executed. + * + * - The items in the `watchExpressions` array are observed via the standard `$watch` operation. Their return + * values are examined for changes on every call to `$digest`. + * - The `listener` is called whenever any expression in the `watchExpressions` array changes. + * + * @param {Array.} watchExpressions Array of expressions that will be individually + * watched using {@link ng.$rootScope.Scope#$watch $watch()} + * + * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any + * expression in `watchExpressions` changes + * The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching + * those of `watchExpression` + * and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching + * those of `watchExpression` + * The `scope` refers to the current scope. + * @returns {function()} Returns a de-registration function for all listeners. + */ + $watchGroup: function(watchExpressions, listener) { + var oldValues = new Array(watchExpressions.length); + var newValues = new Array(watchExpressions.length); + var deregisterFns = []; + var self = this; + var changeReactionScheduled = false; + var firstRun = true; + + if (!watchExpressions.length) { + // No expressions means we call the listener ASAP + var shouldCall = true; + self.$evalAsync(function() { + if (shouldCall) listener(newValues, newValues, self); + }); + return function deregisterWatchGroup() { + shouldCall = false; + }; + } + + if (watchExpressions.length === 1) { + // Special case size of one + return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) { + newValues[0] = value; + oldValues[0] = oldValue; + listener(newValues, (value === oldValue) ? newValues : oldValues, scope); + }); + } + + forEach(watchExpressions, function(expr, i) { + var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) { + newValues[i] = value; + oldValues[i] = oldValue; + if (!changeReactionScheduled) { + changeReactionScheduled = true; + self.$evalAsync(watchGroupAction); + } + }); + deregisterFns.push(unwatchFn); + }); + + function watchGroupAction() { + changeReactionScheduled = false; + + if (firstRun) { + firstRun = false; + listener(newValues, newValues, self); + } else { + listener(newValues, oldValues, self); + } + } + + return function deregisterWatchGroup() { + while (deregisterFns.length) { + deregisterFns.shift()(); + } + }; + }, + + + /** + * @ngdoc method + * @name $rootScope.Scope#$watchCollection + * @kind function + * + * @description + * Shallow watches the properties of an object and fires whenever any of the properties change + * (for arrays, this implies watching the array items; for object maps, this implies watching + * the properties). If a change is detected, the `listener` callback is fired. + * + * - The `obj` collection is observed via standard $watch operation and is examined on every + * call to $digest() to see if any items have been added, removed, or moved. + * - The `listener` is called whenever anything within the `obj` has changed. Examples include + * adding, removing, and moving items belonging to an object or array. + * + * + * # Example + * ```js + $scope.names = ['igor', 'matias', 'misko', 'james']; + $scope.dataCount = 4; + + $scope.$watchCollection('names', function(newNames, oldNames) { + $scope.dataCount = newNames.length; + }); + + expect($scope.dataCount).toEqual(4); + $scope.$digest(); + + //still at 4 ... no changes + expect($scope.dataCount).toEqual(4); + + $scope.names.pop(); + $scope.$digest(); + + //now there's been a change + expect($scope.dataCount).toEqual(3); + * ``` + * + * + * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The + * expression value should evaluate to an object or an array which is observed on each + * {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the + * collection will trigger a call to the `listener`. + * + * @param {function(newCollection, oldCollection, scope)} listener a callback function called + * when a change is detected. + * - The `newCollection` object is the newly modified data obtained from the `obj` expression + * - The `oldCollection` object is a copy of the former collection data. + * Due to performance considerations, the`oldCollection` value is computed only if the + * `listener` function declares two or more arguments. + * - The `scope` argument refers to the current scope. + * + * @returns {function()} Returns a de-registration function for this listener. When the + * de-registration function is executed, the internal watch operation is terminated. + */ + $watchCollection: function(obj, listener) { + $watchCollectionInterceptor.$stateful = true; + + var self = this; + // the current value, updated on each dirty-check run + var newValue; + // a shallow copy of the newValue from the last dirty-check run, + // updated to match newValue during dirty-check run + var oldValue; + // a shallow copy of the newValue from when the last change happened + var veryOldValue; + // only track veryOldValue if the listener is asking for it + var trackVeryOldValue = (listener.length > 1); + var changeDetected = 0; + var changeDetector = $parse(obj, $watchCollectionInterceptor); + var internalArray = []; + var internalObject = {}; + var initRun = true; + var oldLength = 0; + + function $watchCollectionInterceptor(_value) { + newValue = _value; + var newLength, key, bothNaN, newItem, oldItem; + + // If the new value is undefined, then return undefined as the watch may be a one-time watch + if (isUndefined(newValue)) return; + + if (!isObject(newValue)) { // if primitive + if (oldValue !== newValue) { + oldValue = newValue; + changeDetected++; + } + } else if (isArrayLike(newValue)) { + if (oldValue !== internalArray) { + // we are transitioning from something which was not an array into array. + oldValue = internalArray; + oldLength = oldValue.length = 0; + changeDetected++; + } + + newLength = newValue.length; + + if (oldLength !== newLength) { + // if lengths do not match we need to trigger change notification + changeDetected++; + oldValue.length = oldLength = newLength; + } + // copy the items to oldValue and look for changes. + for (var i = 0; i < newLength; i++) { + oldItem = oldValue[i]; + newItem = newValue[i]; + + // eslint-disable-next-line no-self-compare + bothNaN = (oldItem !== oldItem) && (newItem !== newItem); + if (!bothNaN && (oldItem !== newItem)) { + changeDetected++; + oldValue[i] = newItem; + } + } + } else { + if (oldValue !== internalObject) { + // we are transitioning from something which was not an object into object. + oldValue = internalObject = {}; + oldLength = 0; + changeDetected++; + } + // copy the items to oldValue and look for changes. + newLength = 0; + for (key in newValue) { + if (hasOwnProperty.call(newValue, key)) { + newLength++; + newItem = newValue[key]; + oldItem = oldValue[key]; + + if (key in oldValue) { + // eslint-disable-next-line no-self-compare + bothNaN = (oldItem !== oldItem) && (newItem !== newItem); + if (!bothNaN && (oldItem !== newItem)) { + changeDetected++; + oldValue[key] = newItem; + } + } else { + oldLength++; + oldValue[key] = newItem; + changeDetected++; + } + } + } + if (oldLength > newLength) { + // we used to have more keys, need to find them and destroy them. + changeDetected++; + for (key in oldValue) { + if (!hasOwnProperty.call(newValue, key)) { + oldLength--; + delete oldValue[key]; + } + } + } + } + return changeDetected; + } + + function $watchCollectionAction() { + if (initRun) { + initRun = false; + listener(newValue, newValue, self); + } else { + listener(newValue, veryOldValue, self); + } + + // make a copy for the next time a collection is changed + if (trackVeryOldValue) { + if (!isObject(newValue)) { + //primitive + veryOldValue = newValue; + } else if (isArrayLike(newValue)) { + veryOldValue = new Array(newValue.length); + for (var i = 0; i < newValue.length; i++) { + veryOldValue[i] = newValue[i]; + } + } else { // if object + veryOldValue = {}; + for (var key in newValue) { + if (hasOwnProperty.call(newValue, key)) { + veryOldValue[key] = newValue[key]; + } + } + } + } + } + + return this.$watch(changeDetector, $watchCollectionAction); + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$digest + * @kind function + * + * @description + * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and + * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change + * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} + * until no more listeners are firing. This means that it is possible to get into an infinite + * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of + * iterations exceeds 10. + * + * Usually, you don't call `$digest()` directly in + * {@link ng.directive:ngController controllers} or in + * {@link ng.$compileProvider#directive directives}. + * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within + * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`. + * + * If you want to be notified whenever `$digest()` is called, + * you can register a `watchExpression` function with + * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`. + * + * In unit tests, you may need to call `$digest()` to simulate the scope life cycle. + * + * # Example + * ```js + var scope = ...; + scope.name = 'misko'; + scope.counter = 0; + + expect(scope.counter).toEqual(0); + scope.$watch('name', function(newValue, oldValue) { + scope.counter = scope.counter + 1; + }); + expect(scope.counter).toEqual(0); + + scope.$digest(); + // the listener is always called during the first $digest loop after it was registered + expect(scope.counter).toEqual(1); + + scope.$digest(); + // but now it will not be called unless the value changes + expect(scope.counter).toEqual(1); + + scope.name = 'adam'; + scope.$digest(); + expect(scope.counter).toEqual(2); + * ``` + * + */ + $digest: function() { + var watch, value, last, fn, get, + watchers, + dirty, ttl = TTL, + next, current, target = this, + watchLog = [], + logIdx, asyncTask; + + beginPhase('$digest'); + // Check for changes to browser url that happened in sync before the call to $digest + $browser.$$checkUrlChange(); + + if (this === $rootScope && applyAsyncId !== null) { + // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then + // cancel the scheduled $apply and flush the queue of expressions to be evaluated. + $browser.defer.cancel(applyAsyncId); + flushApplyAsync(); + } + + lastDirtyWatch = null; + + do { // "while dirty" loop + dirty = false; + current = target; + + // It's safe for asyncQueuePosition to be a local variable here because this loop can't + // be reentered recursively. Calling $digest from a function passed to $applyAsync would + // lead to a '$digest already in progress' error. + for (var asyncQueuePosition = 0; asyncQueuePosition < asyncQueue.length; asyncQueuePosition++) { + try { + asyncTask = asyncQueue[asyncQueuePosition]; + asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals); + } catch (e) { + $exceptionHandler(e); + } + lastDirtyWatch = null; + } + asyncQueue.length = 0; + + traverseScopesLoop: + do { // "traverse the scopes" loop + if ((watchers = current.$$watchers)) { + // process our watches + watchers.$$digestWatchIndex = watchers.length; + while (watchers.$$digestWatchIndex--) { + try { + watch = watchers[watchers.$$digestWatchIndex]; + // Most common watches are on primitives, in which case we can short + // circuit it with === operator, only when === fails do we use .equals + if (watch) { + get = watch.get; + if ((value = get(current)) !== (last = watch.last) && + !(watch.eq + ? equals(value, last) + : (isNumberNaN(value) && isNumberNaN(last)))) { + dirty = true; + lastDirtyWatch = watch; + watch.last = watch.eq ? copy(value, null) : value; + fn = watch.fn; + fn(value, ((last === initWatchVal) ? value : last), current); + if (ttl < 5) { + logIdx = 4 - ttl; + if (!watchLog[logIdx]) watchLog[logIdx] = []; + watchLog[logIdx].push({ + msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp, + newVal: value, + oldVal: last + }); + } + } else if (watch === lastDirtyWatch) { + // If the most recently dirty watcher is now clean, short circuit since the remaining watchers + // have already been tested. + dirty = false; + break traverseScopesLoop; + } + } + } catch (e) { + $exceptionHandler(e); + } + } + } + + // Insanity Warning: scope depth-first traversal + // yes, this code is a bit crazy, but it works and we have tests to prove it! + // this piece should be kept in sync with the traversal in $broadcast + if (!(next = ((current.$$watchersCount && current.$$childHead) || + (current !== target && current.$$nextSibling)))) { + while (current !== target && !(next = current.$$nextSibling)) { + current = current.$parent; + } + } + } while ((current = next)); + + // `break traverseScopesLoop;` takes us to here + + if ((dirty || asyncQueue.length) && !(ttl--)) { + clearPhase(); + throw $rootScopeMinErr('infdig', + '{0} $digest() iterations reached. Aborting!\n' + + 'Watchers fired in the last 5 iterations: {1}', + TTL, watchLog); + } + + } while (dirty || asyncQueue.length); + + clearPhase(); + + // postDigestQueuePosition isn't local here because this loop can be reentered recursively. + while (postDigestQueuePosition < postDigestQueue.length) { + try { + postDigestQueue[postDigestQueuePosition++](); + } catch (e) { + $exceptionHandler(e); + } + } + postDigestQueue.length = postDigestQueuePosition = 0; + }, + + + /** + * @ngdoc event + * @name $rootScope.Scope#$destroy + * @eventType broadcast on scope being destroyed + * + * @description + * Broadcasted when a scope and its children are being destroyed. + * + * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to + * clean up DOM bindings before an element is removed from the DOM. + */ + + /** + * @ngdoc method + * @name $rootScope.Scope#$destroy + * @kind function + * + * @description + * Removes the current scope (and all of its children) from the parent scope. Removal implies + * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer + * propagate to the current scope and its children. Removal also implies that the current + * scope is eligible for garbage collection. + * + * The `$destroy()` is usually used by directives such as + * {@link ng.directive:ngRepeat ngRepeat} for managing the + * unrolling of the loop. + * + * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope. + * Application code can register a `$destroy` event handler that will give it a chance to + * perform any necessary cleanup. + * + * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to + * clean up DOM bindings before an element is removed from the DOM. + */ + $destroy: function() { + // We can't destroy a scope that has been already destroyed. + if (this.$$destroyed) return; + var parent = this.$parent; + + this.$broadcast('$destroy'); + this.$$destroyed = true; + + if (this === $rootScope) { + //Remove handlers attached to window when $rootScope is removed + $browser.$$applicationDestroyed(); + } + + incrementWatchersCount(this, -this.$$watchersCount); + for (var eventName in this.$$listenerCount) { + decrementListenerCount(this, this.$$listenerCount[eventName], eventName); + } + + // sever all the references to parent scopes (after this cleanup, the current scope should + // not be retained by any of our references and should be eligible for garbage collection) + if (parent && parent.$$childHead === this) parent.$$childHead = this.$$nextSibling; + if (parent && parent.$$childTail === this) parent.$$childTail = this.$$prevSibling; + if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; + if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling; + + // Disable listeners, watchers and apply/digest methods + this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop; + this.$on = this.$watch = this.$watchGroup = function() { return noop; }; + this.$$listeners = {}; + + // Disconnect the next sibling to prevent `cleanUpScope` destroying those too + this.$$nextSibling = null; + cleanUpScope(this); + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$eval + * @kind function + * + * @description + * Executes the `expression` on the current scope and returns the result. Any exceptions in + * the expression are propagated (uncaught). This is useful when evaluating Angular + * expressions. + * + * # Example + * ```js + var scope = ng.$rootScope.Scope(); + scope.a = 1; + scope.b = 2; + + expect(scope.$eval('a+b')).toEqual(3); + expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3); + * ``` + * + * @param {(string|function())=} expression An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with the current `scope` parameter. + * + * @param {(object)=} locals Local variables object, useful for overriding values in scope. + * @returns {*} The result of evaluating the expression. + */ + $eval: function(expr, locals) { + return $parse(expr)(this, locals); + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$evalAsync + * @kind function + * + * @description + * Executes the expression on the current scope at a later point in time. + * + * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only + * that: + * + * - it will execute after the function that scheduled the evaluation (preferably before DOM + * rendering). + * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after + * `expression` execution. + * + * Any exceptions from the execution of the expression are forwarded to the + * {@link ng.$exceptionHandler $exceptionHandler} service. + * + * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle + * will be scheduled. However, it is encouraged to always call code that changes the model + * from within an `$apply` call. That includes code evaluated via `$evalAsync`. + * + * @param {(string|function())=} expression An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with the current `scope` parameter. + * + * @param {(object)=} locals Local variables object, useful for overriding values in scope. + */ + $evalAsync: function(expr, locals) { + // if we are outside of an $digest loop and this is the first time we are scheduling async + // task also schedule async auto-flush + if (!$rootScope.$$phase && !asyncQueue.length) { + $browser.defer(function() { + if (asyncQueue.length) { + $rootScope.$digest(); + } + }); + } + + asyncQueue.push({scope: this, expression: $parse(expr), locals: locals}); + }, + + $$postDigest: function(fn) { + postDigestQueue.push(fn); + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$apply + * @kind function + * + * @description + * `$apply()` is used to execute an expression in angular from outside of the angular + * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). + * Because we are calling into the angular framework we need to perform proper scope life + * cycle of {@link ng.$exceptionHandler exception handling}, + * {@link ng.$rootScope.Scope#$digest executing watches}. + * + * ## Life cycle + * + * # Pseudo-Code of `$apply()` + * ```js + function $apply(expr) { + try { + return $eval(expr); + } catch (e) { + $exceptionHandler(e); + } finally { + $root.$digest(); + } + } + * ``` + * + * + * Scope's `$apply()` method transitions through the following stages: + * + * 1. The {@link guide/expression expression} is executed using the + * {@link ng.$rootScope.Scope#$eval $eval()} method. + * 2. Any exceptions from the execution of the expression are forwarded to the + * {@link ng.$exceptionHandler $exceptionHandler} service. + * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the + * expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method. + * + * + * @param {(string|function())=} exp An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with current `scope` parameter. + * + * @returns {*} The result of evaluating the expression. + */ + $apply: function(expr) { + try { + beginPhase('$apply'); + try { + return this.$eval(expr); + } finally { + clearPhase(); + } + } catch (e) { + $exceptionHandler(e); + } finally { + try { + $rootScope.$digest(); + } catch (e) { + $exceptionHandler(e); + // eslint-disable-next-line no-unsafe-finally + throw e; + } + } + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$applyAsync + * @kind function + * + * @description + * Schedule the invocation of $apply to occur at a later time. The actual time difference + * varies across browsers, but is typically around ~10 milliseconds. + * + * This can be used to queue up multiple expressions which need to be evaluated in the same + * digest. + * + * @param {(string|function())=} exp An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with current `scope` parameter. + */ + $applyAsync: function(expr) { + var scope = this; + if (expr) { + applyAsyncQueue.push($applyAsyncExpression); + } + expr = $parse(expr); + scheduleApplyAsync(); + + function $applyAsyncExpression() { + scope.$eval(expr); + } + }, + + /** + * @ngdoc method + * @name $rootScope.Scope#$on + * @kind function + * + * @description + * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for + * discussion of event life cycle. + * + * The event listener function format is: `function(event, args...)`. The `event` object + * passed into the listener has the following attributes: + * + * - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or + * `$broadcast`-ed. + * - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the + * event propagates through the scope hierarchy, this property is set to null. + * - `name` - `{string}`: name of the event. + * - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel + * further event propagation (available only for events that were `$emit`-ed). + * - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag + * to true. + * - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called. + * + * @param {string} name Event name to listen on. + * @param {function(event, ...args)} listener Function to call when the event is emitted. + * @returns {function()} Returns a deregistration function for this listener. + */ + $on: function(name, listener) { + var namedListeners = this.$$listeners[name]; + if (!namedListeners) { + this.$$listeners[name] = namedListeners = []; + } + namedListeners.push(listener); + + var current = this; + do { + if (!current.$$listenerCount[name]) { + current.$$listenerCount[name] = 0; + } + current.$$listenerCount[name]++; + } while ((current = current.$parent)); + + var self = this; + return function() { + var indexOfListener = namedListeners.indexOf(listener); + if (indexOfListener !== -1) { + namedListeners[indexOfListener] = null; + decrementListenerCount(self, 1, name); + } + }; + }, + + + /** + * @ngdoc method + * @name $rootScope.Scope#$emit + * @kind function + * + * @description + * Dispatches an event `name` upwards through the scope hierarchy notifying the + * registered {@link ng.$rootScope.Scope#$on} listeners. + * + * The event life cycle starts at the scope on which `$emit` was called. All + * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get + * notified. Afterwards, the event traverses upwards toward the root scope and calls all + * registered listeners along the way. The event will stop propagating if one of the listeners + * cancels it. + * + * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed + * onto the {@link ng.$exceptionHandler $exceptionHandler} service. + * + * @param {string} name Event name to emit. + * @param {...*} args Optional one or more arguments which will be passed onto the event listeners. + * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}). + */ + $emit: function(name, args) { + var empty = [], + namedListeners, + scope = this, + stopPropagation = false, + event = { + name: name, + targetScope: scope, + stopPropagation: function() {stopPropagation = true;}, + preventDefault: function() { + event.defaultPrevented = true; + }, + defaultPrevented: false + }, + listenerArgs = concat([event], arguments, 1), + i, length; + + do { + namedListeners = scope.$$listeners[name] || empty; + event.currentScope = scope; + for (i = 0, length = namedListeners.length; i < length; i++) { + + // if listeners were deregistered, defragment the array + if (!namedListeners[i]) { + namedListeners.splice(i, 1); + i--; + length--; + continue; + } + try { + //allow all listeners attached to the current scope to run + namedListeners[i].apply(null, listenerArgs); + } catch (e) { + $exceptionHandler(e); + } + } + //if any listener on the current scope stops propagation, prevent bubbling + if (stopPropagation) { + event.currentScope = null; + return event; + } + //traverse upwards + scope = scope.$parent; + } while (scope); + + event.currentScope = null; + + return event; + }, + + + /** + * @ngdoc method + * @name $rootScope.Scope#$broadcast + * @kind function + * + * @description + * Dispatches an event `name` downwards to all child scopes (and their children) notifying the + * registered {@link ng.$rootScope.Scope#$on} listeners. + * + * The event life cycle starts at the scope on which `$broadcast` was called. All + * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get + * notified. Afterwards, the event propagates to all direct and indirect scopes of the current + * scope and calls all registered listeners along the way. The event cannot be canceled. + * + * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed + * onto the {@link ng.$exceptionHandler $exceptionHandler} service. + * + * @param {string} name Event name to broadcast. + * @param {...*} args Optional one or more arguments which will be passed onto the event listeners. + * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on} + */ + $broadcast: function(name, args) { + var target = this, + current = target, + next = target, + event = { + name: name, + targetScope: target, + preventDefault: function() { + event.defaultPrevented = true; + }, + defaultPrevented: false + }; + + if (!target.$$listenerCount[name]) return event; + + var listenerArgs = concat([event], arguments, 1), + listeners, i, length; + + //down while you can, then up and next sibling or up and next sibling until back at root + while ((current = next)) { + event.currentScope = current; + listeners = current.$$listeners[name] || []; + for (i = 0, length = listeners.length; i < length; i++) { + // if listeners were deregistered, defragment the array + if (!listeners[i]) { + listeners.splice(i, 1); + i--; + length--; + continue; + } + + try { + listeners[i].apply(null, listenerArgs); + } catch (e) { + $exceptionHandler(e); + } + } + + // Insanity Warning: scope depth-first traversal + // yes, this code is a bit crazy, but it works and we have tests to prove it! + // this piece should be kept in sync with the traversal in $digest + // (though it differs due to having the extra check for $$listenerCount) + if (!(next = ((current.$$listenerCount[name] && current.$$childHead) || + (current !== target && current.$$nextSibling)))) { + while (current !== target && !(next = current.$$nextSibling)) { + current = current.$parent; + } + } + } + + event.currentScope = null; + return event; + } + }; + + var $rootScope = new Scope(); + + //The internal queues. Expose them on the $rootScope for debugging/testing purposes. + var asyncQueue = $rootScope.$$asyncQueue = []; + var postDigestQueue = $rootScope.$$postDigestQueue = []; + var applyAsyncQueue = $rootScope.$$applyAsyncQueue = []; + + var postDigestQueuePosition = 0; + + return $rootScope; + + + function beginPhase(phase) { + if ($rootScope.$$phase) { + throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase); + } + + $rootScope.$$phase = phase; + } + + function clearPhase() { + $rootScope.$$phase = null; + } + + function incrementWatchersCount(current, count) { + do { + current.$$watchersCount += count; + } while ((current = current.$parent)); + } + + function decrementListenerCount(current, count, name) { + do { + current.$$listenerCount[name] -= count; + + if (current.$$listenerCount[name] === 0) { + delete current.$$listenerCount[name]; + } + } while ((current = current.$parent)); + } + + /** + * function used as an initial value for watchers. + * because it's unique we can easily tell it apart from other values + */ + function initWatchVal() {} + + function flushApplyAsync() { + while (applyAsyncQueue.length) { + try { + applyAsyncQueue.shift()(); + } catch (e) { + $exceptionHandler(e); + } + } + applyAsyncId = null; + } + + function scheduleApplyAsync() { + if (applyAsyncId === null) { + applyAsyncId = $browser.defer(function() { + $rootScope.$apply(flushApplyAsync); + }); + } + } + }]; +} + +/** + * @ngdoc service + * @name $rootElement + * + * @description + * The root element of Angular application. This is either the element where {@link + * ng.directive:ngApp ngApp} was declared or the element passed into + * {@link angular.bootstrap}. The element represents the root element of application. It is also the + * location where the application's {@link auto.$injector $injector} service gets + * published, and can be retrieved using `$rootElement.injector()`. + */ + + +// the implementation is in angular.bootstrap + +/** + * @this + * @description + * Private service to sanitize uris for links and images. Used by $compile and $sanitize. + */ +function $$SanitizeUriProvider() { + var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/, + imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/; + + /** + * @description + * Retrieves or overrides the default regular expression that is used for whitelisting of safe + * urls during a[href] sanitization. + * + * The sanitization is a security measure aimed at prevent XSS attacks via html links. + * + * Any url about to be assigned to a[href] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * + * @param {RegExp=} regexp New regexp to whitelist urls with. + * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for + * chaining otherwise. + */ + this.aHrefSanitizationWhitelist = function(regexp) { + if (isDefined(regexp)) { + aHrefSanitizationWhitelist = regexp; + return this; + } + return aHrefSanitizationWhitelist; + }; + + + /** + * @description + * Retrieves or overrides the default regular expression that is used for whitelisting of safe + * urls during img[src] sanitization. + * + * The sanitization is a security measure aimed at prevent XSS attacks via html links. + * + * Any url about to be assigned to img[src] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * + * @param {RegExp=} regexp New regexp to whitelist urls with. + * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for + * chaining otherwise. + */ + this.imgSrcSanitizationWhitelist = function(regexp) { + if (isDefined(regexp)) { + imgSrcSanitizationWhitelist = regexp; + return this; + } + return imgSrcSanitizationWhitelist; + }; + + this.$get = function() { + return function sanitizeUri(uri, isImage) { + var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist; + var normalizedVal; + normalizedVal = urlResolve(uri).href; + if (normalizedVal !== '' && !normalizedVal.match(regex)) { + return 'unsafe:' + normalizedVal; + } + return uri; + }; + }; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Any commits to this file should be reviewed with security in mind. * + * Changes to this file can potentially create security vulnerabilities. * + * An approval from 2 Core members with history of modifying * + * this file is required. * + * * + * Does the change somehow allow for arbitrary javascript to be executed? * + * Or allows for someone to change the prototype of built-in objects? * + * Or gives undesired access to variables likes document or window? * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* exported $SceProvider, $SceDelegateProvider */ + +var $sceMinErr = minErr('$sce'); + +var SCE_CONTEXTS = { + HTML: 'html', + CSS: 'css', + URL: 'url', + // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a + // url. (e.g. ng-include, script src, templateUrl) + RESOURCE_URL: 'resourceUrl', + JS: 'js' +}; + +// Helper functions follow. + +var UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g; + +function snakeToCamel(name) { + return name + .replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace); +} + +function adjustMatcher(matcher) { + if (matcher === 'self') { + return matcher; + } else if (isString(matcher)) { + // Strings match exactly except for 2 wildcards - '*' and '**'. + // '*' matches any character except those from the set ':/.?&'. + // '**' matches any character (like .* in a RegExp). + // More than 2 *'s raises an error as it's ill defined. + if (matcher.indexOf('***') > -1) { + throw $sceMinErr('iwcard', + 'Illegal sequence *** in string matcher. String: {0}', matcher); + } + matcher = escapeForRegexp(matcher). + replace(/\\\*\\\*/g, '.*'). + replace(/\\\*/g, '[^:/.?&;]*'); + return new RegExp('^' + matcher + '$'); + } else if (isRegExp(matcher)) { + // The only other type of matcher allowed is a Regexp. + // Match entire URL / disallow partial matches. + // Flags are reset (i.e. no global, ignoreCase or multiline) + return new RegExp('^' + matcher.source + '$'); + } else { + throw $sceMinErr('imatcher', + 'Matchers may only be "self", string patterns or RegExp objects'); + } +} + + +function adjustMatchers(matchers) { + var adjustedMatchers = []; + if (isDefined(matchers)) { + forEach(matchers, function(matcher) { + adjustedMatchers.push(adjustMatcher(matcher)); + }); + } + return adjustedMatchers; +} + + +/** + * @ngdoc service + * @name $sceDelegate + * @kind function + * + * @description + * + * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict + * Contextual Escaping (SCE)} services to AngularJS. + * + * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of + * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS. This is + * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to + * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things + * work because `$sce` delegates to `$sceDelegate` for these operations. + * + * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service. + * + * The default instance of `$sceDelegate` should work out of the box with little pain. While you + * can override it completely to change the behavior of `$sce`, the common case would + * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting + * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as + * templates. Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist + * $sceDelegateProvider.resourceUrlWhitelist} and {@link + * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} + */ + +/** + * @ngdoc provider + * @name $sceDelegateProvider + * @this + * + * @description + * + * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate + * $sceDelegate} service. This allows one to get/set the whitelists and blacklists used to ensure + * that the URLs used for sourcing Angular templates are safe. Refer {@link + * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and + * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} + * + * For the general details about this service in Angular, read the main page for {@link ng.$sce + * Strict Contextual Escaping (SCE)}. + * + * **Example**: Consider the following case.
+ * + * - your app is hosted at url `http://myapp.example.com/` + * - but some of your templates are hosted on other domains you control such as + * `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc. + * - and you have an open redirect at `http://myapp.example.com/clickThru?...`. + * + * Here is what a secure configuration for this scenario might look like: + * + * ``` + * angular.module('myApp', []).config(function($sceDelegateProvider) { + * $sceDelegateProvider.resourceUrlWhitelist([ + * // Allow same origin resource loads. + * 'self', + * // Allow loading from our assets domain. Notice the difference between * and **. + * 'http://srv*.assets.example.com/**' + * ]); + * + * // The blacklist overrides the whitelist so the open redirect here is blocked. + * $sceDelegateProvider.resourceUrlBlacklist([ + * 'http://myapp.example.com/clickThru**' + * ]); + * }); + * ``` + */ + +function $SceDelegateProvider() { + this.SCE_CONTEXTS = SCE_CONTEXTS; + + // Resource URLs can also be trusted by policy. + var resourceUrlWhitelist = ['self'], + resourceUrlBlacklist = []; + + /** + * @ngdoc method + * @name $sceDelegateProvider#resourceUrlWhitelist + * @kind function + * + * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value + * provided. This must be an array or null. A snapshot of this array is used so further + * changes to the array are ignored. + * + * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items + * allowed in this array. + * + *
+ * **Note:** an empty whitelist array will block all URLs! + *
+ * + * @return {Array} the currently set whitelist array. + * + * The **default value** when no whitelist has been explicitly set is `['self']` allowing only + * same origin resource requests. + * + * @description + * Sets/Gets the whitelist of trusted resource URLs. + */ + this.resourceUrlWhitelist = function(value) { + if (arguments.length) { + resourceUrlWhitelist = adjustMatchers(value); + } + return resourceUrlWhitelist; + }; + + /** + * @ngdoc method + * @name $sceDelegateProvider#resourceUrlBlacklist + * @kind function + * + * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value + * provided. This must be an array or null. A snapshot of this array is used so further + * changes to the array are ignored. + * + * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items + * allowed in this array. + * + * The typical usage for the blacklist is to **block + * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as + * these would otherwise be trusted but actually return content from the redirected domain. + * + * Finally, **the blacklist overrides the whitelist** and has the final say. + * + * @return {Array} the currently set blacklist array. + * + * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there + * is no blacklist.) + * + * @description + * Sets/Gets the blacklist of trusted resource URLs. + */ + + this.resourceUrlBlacklist = function(value) { + if (arguments.length) { + resourceUrlBlacklist = adjustMatchers(value); + } + return resourceUrlBlacklist; + }; + + this.$get = ['$injector', function($injector) { + + var htmlSanitizer = function htmlSanitizer(html) { + throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); + }; + + if ($injector.has('$sanitize')) { + htmlSanitizer = $injector.get('$sanitize'); + } + + + function matchUrl(matcher, parsedUrl) { + if (matcher === 'self') { + return urlIsSameOrigin(parsedUrl); + } else { + // definitely a regex. See adjustMatchers() + return !!matcher.exec(parsedUrl.href); + } + } + + function isResourceUrlAllowedByPolicy(url) { + var parsedUrl = urlResolve(url.toString()); + var i, n, allowed = false; + // Ensure that at least one item from the whitelist allows this url. + for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) { + if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) { + allowed = true; + break; + } + } + if (allowed) { + // Ensure that no item from the blacklist blocked this url. + for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) { + if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) { + allowed = false; + break; + } + } + } + return allowed; + } + + function generateHolderType(Base) { + var holderType = function TrustedValueHolderType(trustedValue) { + this.$$unwrapTrustedValue = function() { + return trustedValue; + }; + }; + if (Base) { + holderType.prototype = new Base(); + } + holderType.prototype.valueOf = function sceValueOf() { + return this.$$unwrapTrustedValue(); + }; + holderType.prototype.toString = function sceToString() { + return this.$$unwrapTrustedValue().toString(); + }; + return holderType; + } + + var trustedValueHolderBase = generateHolderType(), + byType = {}; + + byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]); + + /** + * @ngdoc method + * @name $sceDelegate#trustAs + * + * @description + * Returns an object that is trusted by angular for use in specified strict + * contextual escaping contexts (such as ng-bind-html, ng-include, any src + * attribute interpolation, any dom event binding attribute interpolation + * such as for onclick, etc.) that uses the provided value. + * See {@link ng.$sce $sce} for enabling strict contextual escaping. + * + * @param {string} type The kind of context in which this value is safe for use. e.g. url, + * resourceUrl, html, js and css. + * @param {*} value The value that that should be considered trusted/safe. + * @returns {*} A value that can be used to stand in for the provided `value` in places + * where Angular expects a $sce.trustAs() return value. + */ + function trustAs(type, trustedValue) { + var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null); + if (!Constructor) { + throw $sceMinErr('icontext', + 'Attempted to trust a value in invalid context. Context: {0}; Value: {1}', + type, trustedValue); + } + if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') { + return trustedValue; + } + // All the current contexts in SCE_CONTEXTS happen to be strings. In order to avoid trusting + // mutable objects, we ensure here that the value passed in is actually a string. + if (typeof trustedValue !== 'string') { + throw $sceMinErr('itype', + 'Attempted to trust a non-string value in a content requiring a string: Context: {0}', + type); + } + return new Constructor(trustedValue); + } + + /** + * @ngdoc method + * @name $sceDelegate#valueOf + * + * @description + * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs + * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link + * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. + * + * If the passed parameter is not a value that had been returned by {@link + * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is. + * + * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} + * call or anything else. + * @returns {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs + * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns + * `value` unchanged. + */ + function valueOf(maybeTrusted) { + if (maybeTrusted instanceof trustedValueHolderBase) { + return maybeTrusted.$$unwrapTrustedValue(); + } else { + return maybeTrusted; + } + } + + /** + * @ngdoc method + * @name $sceDelegate#getTrusted + * + * @description + * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and + * returns the originally supplied value if the queried context type is a supertype of the + * created type. If this condition isn't satisfied, throws an exception. + * + *
+ * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting + * (XSS) vulnerability in your application. + *
+ * + * @param {string} type The kind of context in which this value is to be used. + * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs + * `$sceDelegate.trustAs`} call. + * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs + * `$sceDelegate.trustAs`} if valid in this context. Otherwise, throws an exception. + */ + function getTrusted(type, maybeTrusted) { + if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') { + return maybeTrusted; + } + var constructor = (byType.hasOwnProperty(type) ? byType[type] : null); + if (constructor && maybeTrusted instanceof constructor) { + return maybeTrusted.$$unwrapTrustedValue(); + } + // If we get here, then we may only take one of two actions. + // 1. sanitize the value for the requested type, or + // 2. throw an exception. + if (type === SCE_CONTEXTS.RESOURCE_URL) { + if (isResourceUrlAllowedByPolicy(maybeTrusted)) { + return maybeTrusted; + } else { + throw $sceMinErr('insecurl', + 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}', + maybeTrusted.toString()); + } + } else if (type === SCE_CONTEXTS.HTML) { + return htmlSanitizer(maybeTrusted); + } + throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); + } + + return { trustAs: trustAs, + getTrusted: getTrusted, + valueOf: valueOf }; + }]; +} + + +/** + * @ngdoc provider + * @name $sceProvider + * @this + * + * @description + * + * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service. + * - enable/disable Strict Contextual Escaping (SCE) in a module + * - override the default implementation with a custom delegate + * + * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}. + */ + +/** + * @ngdoc service + * @name $sce + * @kind function + * + * @description + * + * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS. + * + * # Strict Contextual Escaping + * + * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain + * contexts to result in a value that is marked as safe to use for that context. One example of + * such a context is binding arbitrary html controlled by the user via `ng-bind-html`. We refer + * to these contexts as privileged or SCE contexts. + * + * As of version 1.2, Angular ships with SCE enabled by default. + * + * Note: When enabled (the default), IE<11 in quirks mode is not supported. In this mode, IE<11 allow + * one to execute arbitrary javascript by the use of the expression() syntax. Refer + * to learn more about them. + * You can ensure your document is in standards mode and not quirks mode by adding `` + * to the top of your HTML document. + * + * SCE assists in writing code in a way that (a) is secure by default and (b) makes auditing for + * security vulnerabilities such as XSS, clickjacking, etc. a lot easier. + * + * Here's an example of a binding in a privileged context: + * + * ``` + * + *
+ * ``` + * + * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE + * disabled, this application allows the user to render arbitrary HTML into the DIV. + * In a more realistic example, one may be rendering user comments, blog articles, etc. via + * bindings. (HTML is just one example of a context where rendering user controlled input creates + * security vulnerabilities.) + * + * For the case of HTML, you might use a library, either on the client side, or on the server side, + * to sanitize unsafe HTML before binding to the value and rendering it in the document. + * + * How would you ensure that every place that used these types of bindings was bound to a value that + * was sanitized by your library (or returned as safe for rendering by your server?) How can you + * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some + * properties/fields and forgot to update the binding to the sanitized value? + * + * To be secure by default, you want to ensure that any such bindings are disallowed unless you can + * determine that something explicitly says it's safe to use a value for binding in that + * context. You can then audit your code (a simple grep would do) to ensure that this is only done + * for those values that you can easily tell are safe - because they were received from your server, + * sanitized by your library, etc. You can organize your codebase to help with this - perhaps + * allowing only the files in a specific directory to do this. Ensuring that the internal API + * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task. + * + * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs} + * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to + * obtain values that will be accepted by SCE / privileged contexts. + * + * + * ## How does it work? + * + * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted + * $sce.getTrusted(context, value)} rather than to the value directly. Directives use {@link + * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the + * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals. + * + * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link + * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly + * simplified): + * + * ``` + * var ngBindHtmlDirective = ['$sce', function($sce) { + * return function(scope, element, attr) { + * scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) { + * element.html(value || ''); + * }); + * }; + * }]; + * ``` + * + * ## Impact on loading templates + * + * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as + * `templateUrl`'s specified by {@link guide/directive directives}. + * + * By default, Angular only loads templates from the same domain and protocol as the application + * document. This is done by calling {@link ng.$sce#getTrustedResourceUrl + * $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or + * protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist + * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value. + * + * *Please note*: + * The browser's + * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest) + * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/) + * policy apply in addition to this and may further restrict whether the template is successfully + * loaded. This means that without the right CORS policy, loading templates from a different domain + * won't work on all browsers. Also, loading templates from `file://` URL does not work on some + * browsers. + * + * ## This feels like too much overhead + * + * It's important to remember that SCE only applies to interpolation expressions. + * + * If your expressions are constant literals, they're automatically trusted and you don't need to + * call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g. + * `
`) just works. + * + * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them + * through {@link ng.$sce#getTrusted $sce.getTrusted}. SCE doesn't play a role here. + * + * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load + * templates in `ng-include` from your application's domain without having to even know about SCE. + * It blocks loading templates from other domains or loading templates over http from an https + * served document. You can change these by setting your own custom {@link + * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link + * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs. + * + * This significantly reduces the overhead. It is far easier to pay the small overhead and have an + * application that's secure and can be audited to verify that with much more ease than bolting + * security onto an application later. + * + * + * ## What trusted context types are supported? + * + * | Context | Notes | + * |---------------------|----------------| + * | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. | + * | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. | + * | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`
Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. | + * | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. | + * + * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist}
+ * + * Each element in these arrays must be one of the following: + * + * - **'self'** + * - The special **string**, `'self'`, can be used to match against all URLs of the **same + * domain** as the application document using the **same protocol**. + * - **String** (except the special value `'self'`) + * - The string is matched against the full *normalized / absolute URL* of the resource + * being tested (substring matches are not good enough.) + * - There are exactly **two wildcard sequences** - `*` and `**`. All other characters + * match themselves. + * - `*`: matches zero or more occurrences of any character other than one of the following 6 + * characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'. It's a useful wildcard for use + * in a whitelist. + * - `**`: matches zero or more occurrences of *any* character. As such, it's not + * appropriate for use in a scheme, domain, etc. as it would match too much. (e.g. + * http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might + * not have been the intention.) Its usage at the very end of the path is ok. (e.g. + * http://foo.example.com/templates/**). + * - **RegExp** (*see caveat below*) + * - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax + * (and all the inevitable escaping) makes them *harder to maintain*. It's easy to + * accidentally introduce a bug when one updates a complex expression (imho, all regexes should + * have good test coverage). For instance, the use of `.` in the regex is correct only in a + * small number of cases. A `.` character in the regex used when matching the scheme or a + * subdomain could be matched against a `:` or literal `.` that was likely not intended. It + * is highly recommended to use the string patterns and only fall back to regular expressions + * as a last resort. + * - The regular expression must be an instance of RegExp (i.e. not a string.) It is + * matched against the **entire** *normalized / absolute URL* of the resource being tested + * (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags + * present on the RegExp (such as multiline, global, ignoreCase) are ignored. + * - If you are generating your JavaScript from some other templating engine (not + * recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)), + * remember to escape your regular expression (and be aware that you might need more than + * one level of escaping depending on your templating engine and the way you interpolated + * the value.) Do make use of your platform's escaping mechanism as it might be good + * enough before coding your own. E.g. Ruby has + * [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape) + * and Python has [re.escape](http://docs.python.org/library/re.html#re.escape). + * Javascript lacks a similar built in function for escaping. Take a look at Google + * Closure library's [goog.string.regExpEscape(s)]( + * http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962). + * + * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example. + * + * ## Show me an example using SCE. + * + * + * + *
+ *

+ * User comments
+ * By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when + * $sanitize is available. If $sanitize isn't available, this results in an error instead of an + * exploit. + *
+ *
+ * {{userComment.name}}: + * + *
+ *
+ *
+ *
+ *
+ * + * + * angular.module('mySceApp', ['ngSanitize']) + * .controller('AppController', ['$http', '$templateCache', '$sce', + * function AppController($http, $templateCache, $sce) { + * var self = this; + * $http.get('test_data.json', {cache: $templateCache}).then(function(response) { + * self.userComments = response.data; + * }); + * self.explicitlyTrustedHtml = $sce.trustAsHtml( + * 'Hover over this text.'); + * }]); + * + * + * + * [ + * { "name": "Alice", + * "htmlComment": + * "Is anyone reading this?" + * }, + * { "name": "Bob", + * "htmlComment": "Yes! Am I the only other one?" + * } + * ] + * + * + * + * describe('SCE doc demo', function() { + * it('should sanitize untrusted values', function() { + * expect(element.all(by.css('.htmlComment')).first().getAttribute('innerHTML')) + * .toBe('Is anyone reading this?'); + * }); + * + * it('should NOT sanitize explicitly trusted values', function() { + * expect(element(by.id('explicitlyTrustedHtml')).getAttribute('innerHTML')).toBe( + * 'Hover over this text.'); + * }); + * }); + * + *
+ * + * + * + * ## Can I disable SCE completely? + * + * Yes, you can. However, this is strongly discouraged. SCE gives you a lot of security benefits + * for little coding overhead. It will be much harder to take an SCE disabled application and + * either secure it on your own or enable SCE at a later stage. It might make sense to disable SCE + * for cases where you have a lot of existing code that was written before SCE was introduced and + * you're migrating them a module at a time. + * + * That said, here's how you can completely disable SCE: + * + * ``` + * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) { + * // Completely disable SCE. For demonstration purposes only! + * // Do not use in new projects. + * $sceProvider.enabled(false); + * }); + * ``` + * + */ + +function $SceProvider() { + var enabled = true; + + /** + * @ngdoc method + * @name $sceProvider#enabled + * @kind function + * + * @param {boolean=} value If provided, then enables/disables SCE. + * @return {boolean} true if SCE is enabled, false otherwise. + * + * @description + * Enables/disables SCE and returns the current value. + */ + this.enabled = function(value) { + if (arguments.length) { + enabled = !!value; + } + return enabled; + }; + + + /* Design notes on the default implementation for SCE. + * + * The API contract for the SCE delegate + * ------------------------------------- + * The SCE delegate object must provide the following 3 methods: + * + * - trustAs(contextEnum, value) + * This method is used to tell the SCE service that the provided value is OK to use in the + * contexts specified by contextEnum. It must return an object that will be accepted by + * getTrusted() for a compatible contextEnum and return this value. + * + * - valueOf(value) + * For values that were not produced by trustAs(), return them as is. For values that were + * produced by trustAs(), return the corresponding input value to trustAs. Basically, if + * trustAs is wrapping the given values into some type, this operation unwraps it when given + * such a value. + * + * - getTrusted(contextEnum, value) + * This function should return the a value that is safe to use in the context specified by + * contextEnum or throw and exception otherwise. + * + * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be + * opaque or wrapped in some holder object. That happens to be an implementation detail. For + * instance, an implementation could maintain a registry of all trusted objects by context. In + * such a case, trustAs() would return the same object that was passed in. getTrusted() would + * return the same object passed in if it was found in the registry under a compatible context or + * throw an exception otherwise. An implementation might only wrap values some of the time based + * on some criteria. getTrusted() might return a value and not throw an exception for special + * constants or objects even if not wrapped. All such implementations fulfill this contract. + * + * + * A note on the inheritance model for SCE contexts + * ------------------------------------------------ + * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types. This + * is purely an implementation details. + * + * The contract is simply this: + * + * getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value) + * will also succeed. + * + * Inheritance happens to capture this in a natural way. In some future, we + * may not use inheritance anymore. That is OK because no code outside of + * sce.js and sceSpecs.js would need to be aware of this detail. + */ + + this.$get = ['$parse', '$sceDelegate', function( + $parse, $sceDelegate) { + // Support: IE 9-11 only + // Prereq: Ensure that we're not running in IE<11 quirks mode. In that mode, IE < 11 allow + // the "expression(javascript expression)" syntax which is insecure. + if (enabled && msie < 8) { + throw $sceMinErr('iequirks', + 'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' + + 'mode. You can fix this by adding the text to the top of your HTML ' + + 'document. See http://docs.angularjs.org/api/ng.$sce for more information.'); + } + + var sce = shallowCopy(SCE_CONTEXTS); + + /** + * @ngdoc method + * @name $sce#isEnabled + * @kind function + * + * @return {Boolean} true if SCE is enabled, false otherwise. If you want to set the value, you + * have to do it at module config time on {@link ng.$sceProvider $sceProvider}. + * + * @description + * Returns a boolean indicating if SCE is enabled. + */ + sce.isEnabled = function() { + return enabled; + }; + sce.trustAs = $sceDelegate.trustAs; + sce.getTrusted = $sceDelegate.getTrusted; + sce.valueOf = $sceDelegate.valueOf; + + if (!enabled) { + sce.trustAs = sce.getTrusted = function(type, value) { return value; }; + sce.valueOf = identity; + } + + /** + * @ngdoc method + * @name $sce#parseAs + * + * @description + * Converts Angular {@link guide/expression expression} into a function. This is like {@link + * ng.$parse $parse} and is identical when the expression is a literal constant. Otherwise, it + * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*, + * *result*)} + * + * @param {string} type The kind of SCE context in which this result will be used. + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + sce.parseAs = function sceParseAs(type, expr) { + var parsed = $parse(expr); + if (parsed.literal && parsed.constant) { + return parsed; + } else { + return $parse(expr, function(value) { + return sce.getTrusted(type, value); + }); + } + }; + + /** + * @ngdoc method + * @name $sce#trustAs + * + * @description + * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. As such, + * returns an object that is trusted by angular for use in specified strict contextual + * escaping contexts (such as ng-bind-html, ng-include, any src attribute + * interpolation, any dom event binding attribute interpolation such as for onclick, etc.) + * that uses the provided value. See * {@link ng.$sce $sce} for enabling strict contextual + * escaping. + * + * @param {string} type The kind of context in which this value is safe for use. e.g. url, + * resourceUrl, html, js and css. + * @param {*} value The value that that should be considered trusted/safe. + * @returns {*} A value that can be used to stand in for the provided `value` in places + * where Angular expects a $sce.trustAs() return value. + */ + + /** + * @ngdoc method + * @name $sce#trustAsHtml + * + * @description + * Shorthand method. `$sce.trustAsHtml(value)` → + * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml + * $sce.getTrustedHtml(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the + * return value of {@link ng.$sce#trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name $sce#trustAsUrl + * + * @description + * Shorthand method. `$sce.trustAsUrl(value)` → + * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl + * $sce.getTrustedUrl(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the + * return value of {@link ng.$sce#trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name $sce#trustAsResourceUrl + * + * @description + * Shorthand method. `$sce.trustAsResourceUrl(value)` → + * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl + * $sce.getTrustedResourceUrl(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the return + * value of {@link ng.$sce#trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name $sce#trustAsJs + * + * @description + * Shorthand method. `$sce.trustAsJs(value)` → + * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs + * $sce.getTrustedJs(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the + * return value of {@link ng.$sce#trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name $sce#getTrusted + * + * @description + * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}. As such, + * takes the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the + * originally supplied value if the queried context type is a supertype of the created type. + * If this condition isn't satisfied, throws an exception. + * + * @param {string} type The kind of context in which this value is to be used. + * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`} + * call. + * @returns {*} The value the was originally provided to + * {@link ng.$sce#trustAs `$sce.trustAs`} if valid in this context. + * Otherwise, throws an exception. + */ + + /** + * @ngdoc method + * @name $sce#getTrustedHtml + * + * @description + * Shorthand method. `$sce.getTrustedHtml(value)` → + * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)` + */ + + /** + * @ngdoc method + * @name $sce#getTrustedCss + * + * @description + * Shorthand method. `$sce.getTrustedCss(value)` → + * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)` + */ + + /** + * @ngdoc method + * @name $sce#getTrustedUrl + * + * @description + * Shorthand method. `$sce.getTrustedUrl(value)` → + * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)` + */ + + /** + * @ngdoc method + * @name $sce#getTrustedResourceUrl + * + * @description + * Shorthand method. `$sce.getTrustedResourceUrl(value)` → + * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`} + * + * @param {*} value The value to pass to `$sceDelegate.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)` + */ + + /** + * @ngdoc method + * @name $sce#getTrustedJs + * + * @description + * Shorthand method. `$sce.getTrustedJs(value)` → + * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)` + */ + + /** + * @ngdoc method + * @name $sce#parseAsHtml + * + * @description + * Shorthand method. `$sce.parseAsHtml(expression string)` → + * {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name $sce#parseAsCss + * + * @description + * Shorthand method. `$sce.parseAsCss(value)` → + * {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name $sce#parseAsUrl + * + * @description + * Shorthand method. `$sce.parseAsUrl(value)` → + * {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name $sce#parseAsResourceUrl + * + * @description + * Shorthand method. `$sce.parseAsResourceUrl(value)` → + * {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name $sce#parseAsJs + * + * @description + * Shorthand method. `$sce.parseAsJs(value)` → + * {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + // Shorthand delegations. + var parse = sce.parseAs, + getTrusted = sce.getTrusted, + trustAs = sce.trustAs; + + forEach(SCE_CONTEXTS, function(enumValue, name) { + var lName = lowercase(name); + sce[snakeToCamel('parse_as_' + lName)] = function(expr) { + return parse(enumValue, expr); + }; + sce[snakeToCamel('get_trusted_' + lName)] = function(value) { + return getTrusted(enumValue, value); + }; + sce[snakeToCamel('trust_as_' + lName)] = function(value) { + return trustAs(enumValue, value); + }; + }); + + return sce; + }]; +} + +/* exported $SnifferProvider */ + +/** + * !!! This is an undocumented "private" service !!! + * + * @name $sniffer + * @requires $window + * @requires $document + * @this + * + * @property {boolean} history Does the browser support html5 history api ? + * @property {boolean} transitions Does the browser support CSS transition events ? + * @property {boolean} animations Does the browser support CSS animation events ? + * + * @description + * This is very simple implementation of testing browser's features. + */ +function $SnifferProvider() { + this.$get = ['$window', '$document', function($window, $document) { + var eventSupport = {}, + // Chrome Packaged Apps are not allowed to access `history.pushState`. + // If not sandboxed, they can be detected by the presence of `chrome.app.runtime` + // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by + // the presence of an extension runtime ID and the absence of other Chrome runtime APIs + // (see https://developer.chrome.com/apps/manifest/sandbox). + isChromePackagedApp = + $window.chrome && + ($window.chrome.app && $window.chrome.app.runtime || + !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), + hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, + android = + toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), + boxee = /Boxee/i.test(($window.navigator || {}).userAgent), + document = $document[0] || {}, + bodyStyle = document.body && document.body.style, + transitions = false, + animations = false; + + if (bodyStyle) { + // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x + // Mentioned browsers need a -webkit- prefix for transitions & animations. + transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle); + animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle); + } + + + return { + // Android has history.pushState, but it does not update location correctly + // so let's not use the history API at all. + // http://code.google.com/p/android/issues/detail?id=17471 + // https://github.com/angular/angular.js/issues/904 + + // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has + // so let's not use the history API also + // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined + history: !!(hasHistoryPushState && !(android < 4) && !boxee), + hasEvent: function(event) { + // Support: IE 9-11 only + // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have + // it. In particular the event is not fired when backspace or delete key are pressed or + // when cut operation is performed. + // IE10+ implements 'input' event but it erroneously fires under various situations, + // e.g. when placeholder changes, or a form is focused. + if (event === 'input' && msie) return false; + + if (isUndefined(eventSupport[event])) { + var divElm = document.createElement('div'); + eventSupport[event] = 'on' + event in divElm; + } + + return eventSupport[event]; + }, + csp: csp(), + transitions: transitions, + animations: animations, + android: android + }; + }]; +} + +var $templateRequestMinErr = minErr('$compile'); + +/** + * @ngdoc provider + * @name $templateRequestProvider + * @this + * + * @description + * Used to configure the options passed to the {@link $http} service when making a template request. + * + * For example, it can be used for specifying the "Accept" header that is sent to the server, when + * requesting a template. + */ +function $TemplateRequestProvider() { + + var httpOptions; + + /** + * @ngdoc method + * @name $templateRequestProvider#httpOptions + * @description + * The options to be passed to the {@link $http} service when making the request. + * You can use this to override options such as the "Accept" header for template requests. + * + * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the + * options if not overridden here. + * + * @param {string=} value new value for the {@link $http} options. + * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter. + */ + this.httpOptions = function(val) { + if (val) { + httpOptions = val; + return this; + } + return httpOptions; + }; + + /** + * @ngdoc service + * @name $templateRequest + * + * @description + * The `$templateRequest` service runs security checks then downloads the provided template using + * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request + * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the + * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the + * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted + * when `tpl` is of type string and `$templateCache` has the matching entry. + * + * If you want to pass custom options to the `$http` service, such as setting the Accept header you + * can configure this via {@link $templateRequestProvider#httpOptions}. + * + * @param {string|TrustedResourceUrl} tpl The HTTP request template URL + * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty + * + * @return {Promise} a promise for the HTTP response data of the given URL. + * + * @property {number} totalPendingRequests total amount of pending template requests being downloaded. + */ + this.$get = ['$exceptionHandler', '$templateCache', '$http', '$q', '$sce', + function($exceptionHandler, $templateCache, $http, $q, $sce) { + + function handleRequestFn(tpl, ignoreRequestError) { + handleRequestFn.totalPendingRequests++; + + // We consider the template cache holds only trusted templates, so + // there's no need to go through whitelisting again for keys that already + // are included in there. This also makes Angular accept any script + // directive, no matter its name. However, we still need to unwrap trusted + // types. + if (!isString(tpl) || isUndefined($templateCache.get(tpl))) { + tpl = $sce.getTrustedResourceUrl(tpl); + } + + var transformResponse = $http.defaults && $http.defaults.transformResponse; + + if (isArray(transformResponse)) { + transformResponse = transformResponse.filter(function(transformer) { + return transformer !== defaultHttpResponseTransform; + }); + } else if (transformResponse === defaultHttpResponseTransform) { + transformResponse = null; + } + + return $http.get(tpl, extend({ + cache: $templateCache, + transformResponse: transformResponse + }, httpOptions)) + .finally(function() { + handleRequestFn.totalPendingRequests--; + }) + .then(function(response) { + $templateCache.put(tpl, response.data); + return response.data; + }, handleError); + + function handleError(resp) { + if (!ignoreRequestError) { + resp = $templateRequestMinErr('tpload', + 'Failed to load template: {0} (HTTP status: {1} {2})', + tpl, resp.status, resp.statusText); + + $exceptionHandler(resp); + } + + return $q.reject(resp); + } + } + + handleRequestFn.totalPendingRequests = 0; + + return handleRequestFn; + } + ]; +} + +/** @this */ +function $$TestabilityProvider() { + this.$get = ['$rootScope', '$browser', '$location', + function($rootScope, $browser, $location) { + + /** + * @name $testability + * + * @description + * The private $$testability service provides a collection of methods for use when debugging + * or by automated test and debugging tools. + */ + var testability = {}; + + /** + * @name $$testability#findBindings + * + * @description + * Returns an array of elements that are bound (via ng-bind or {{}}) + * to expressions matching the input. + * + * @param {Element} element The element root to search from. + * @param {string} expression The binding expression to match. + * @param {boolean} opt_exactMatch If true, only returns exact matches + * for the expression. Filters and whitespace are ignored. + */ + testability.findBindings = function(element, expression, opt_exactMatch) { + var bindings = element.getElementsByClassName('ng-binding'); + var matches = []; + forEach(bindings, function(binding) { + var dataBinding = angular.element(binding).data('$binding'); + if (dataBinding) { + forEach(dataBinding, function(bindingName) { + if (opt_exactMatch) { + var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)'); + if (matcher.test(bindingName)) { + matches.push(binding); + } + } else { + if (bindingName.indexOf(expression) !== -1) { + matches.push(binding); + } + } + }); + } + }); + return matches; + }; + + /** + * @name $$testability#findModels + * + * @description + * Returns an array of elements that are two-way found via ng-model to + * expressions matching the input. + * + * @param {Element} element The element root to search from. + * @param {string} expression The model expression to match. + * @param {boolean} opt_exactMatch If true, only returns exact matches + * for the expression. + */ + testability.findModels = function(element, expression, opt_exactMatch) { + var prefixes = ['ng-', 'data-ng-', 'ng\\:']; + for (var p = 0; p < prefixes.length; ++p) { + var attributeEquals = opt_exactMatch ? '=' : '*='; + var selector = '[' + prefixes[p] + 'model' + attributeEquals + '"' + expression + '"]'; + var elements = element.querySelectorAll(selector); + if (elements.length) { + return elements; + } + } + }; + + /** + * @name $$testability#getLocation + * + * @description + * Shortcut for getting the location in a browser agnostic way. Returns + * the path, search, and hash. (e.g. /path?a=b#hash) + */ + testability.getLocation = function() { + return $location.url(); + }; + + /** + * @name $$testability#setLocation + * + * @description + * Shortcut for navigating to a location without doing a full page reload. + * + * @param {string} url The location url (path, search and hash, + * e.g. /path?a=b#hash) to go to. + */ + testability.setLocation = function(url) { + if (url !== $location.url()) { + $location.url(url); + $rootScope.$digest(); + } + }; + + /** + * @name $$testability#whenStable + * + * @description + * Calls the callback when $timeout and $http requests are completed. + * + * @param {function} callback + */ + testability.whenStable = function(callback) { + $browser.notifyWhenNoOutstandingRequests(callback); + }; + + return testability; + }]; +} + +/** @this */ +function $TimeoutProvider() { + this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler', + function($rootScope, $browser, $q, $$q, $exceptionHandler) { + + var deferreds = {}; + + + /** + * @ngdoc service + * @name $timeout + * + * @description + * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch + * block and delegates any exceptions to + * {@link ng.$exceptionHandler $exceptionHandler} service. + * + * The return value of calling `$timeout` is a promise, which will be resolved when + * the delay has passed and the timeout function, if provided, is executed. + * + * To cancel a timeout request, call `$timeout.cancel(promise)`. + * + * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to + * synchronously flush the queue of deferred functions. + * + * If you only want a promise that will be resolved after some specified delay + * then you can call `$timeout` without the `fn` function. + * + * @param {function()=} fn A function, whose execution should be delayed. + * @param {number=} [delay=0] Delay in milliseconds. + * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * @param {...*=} Pass additional parameters to the executed function. + * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise + * will be resolved with the return value of the `fn` function. + * + */ + function timeout(fn, delay, invokeApply) { + if (!isFunction(fn)) { + invokeApply = delay; + delay = fn; + fn = noop; + } + + var args = sliceArgs(arguments, 3), + skipApply = (isDefined(invokeApply) && !invokeApply), + deferred = (skipApply ? $$q : $q).defer(), + promise = deferred.promise, + timeoutId; + + timeoutId = $browser.defer(function() { + try { + deferred.resolve(fn.apply(null, args)); + } catch (e) { + deferred.reject(e); + $exceptionHandler(e); + } finally { + delete deferreds[promise.$$timeoutId]; + } + + if (!skipApply) $rootScope.$apply(); + }, delay); + + promise.$$timeoutId = timeoutId; + deferreds[timeoutId] = deferred; + + return promise; + } + + + /** + * @ngdoc method + * @name $timeout#cancel + * + * @description + * Cancels a task associated with the `promise`. As a result of this, the promise will be + * resolved with a rejection. + * + * @param {Promise=} promise Promise returned by the `$timeout` function. + * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully + * canceled. + */ + timeout.cancel = function(promise) { + if (promise && promise.$$timeoutId in deferreds) { + // Timeout cancels should not report an unhandled promise. + deferreds[promise.$$timeoutId].promise.catch(noop); + deferreds[promise.$$timeoutId].reject('canceled'); + delete deferreds[promise.$$timeoutId]; + return $browser.defer.cancel(promise.$$timeoutId); + } + return false; + }; + + return timeout; + }]; +} + +// NOTE: The usage of window and document instead of $window and $document here is +// deliberate. This service depends on the specific behavior of anchor nodes created by the +// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and +// cause us to break tests. In addition, when the browser resolves a URL for XHR, it +// doesn't know about mocked locations and resolves URLs to the real document - which is +// exactly the behavior needed here. There is little value is mocking these out for this +// service. +var urlParsingNode = window.document.createElement('a'); +var originUrl = urlResolve(window.location.href); + + +/** + * + * Implementation Notes for non-IE browsers + * ---------------------------------------- + * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM, + * results both in the normalizing and parsing of the URL. Normalizing means that a relative + * URL will be resolved into an absolute URL in the context of the application document. + * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related + * properties are all populated to reflect the normalized URL. This approach has wide + * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See + * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html + * + * Implementation Notes for IE + * --------------------------- + * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other + * browsers. However, the parsed components will not be set if the URL assigned did not specify + * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We + * work around that by performing the parsing in a 2nd step by taking a previously normalized + * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the + * properties such as protocol, hostname, port, etc. + * + * References: + * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement + * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html + * http://url.spec.whatwg.org/#urlutils + * https://github.com/angular/angular.js/pull/2902 + * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ + * + * @kind function + * @param {string} url The URL to be parsed. + * @description Normalizes and parses a URL. + * @returns {object} Returns the normalized URL as a dictionary. + * + * | member name | Description | + * |---------------|----------------| + * | href | A normalized version of the provided URL if it was not an absolute URL | + * | protocol | The protocol including the trailing colon | + * | host | The host and port (if the port is non-default) of the normalizedUrl | + * | search | The search params, minus the question mark | + * | hash | The hash string, minus the hash symbol + * | hostname | The hostname + * | port | The port, without ":" + * | pathname | The pathname, beginning with "/" + * + */ +function urlResolve(url) { + var href = url; + + // Support: IE 9-11 only + if (msie) { + // Normalize before parse. Refer Implementation Notes on why this is + // done in two steps on IE. + urlParsingNode.setAttribute('href', href); + href = urlParsingNode.href; + } + + urlParsingNode.setAttribute('href', href); + + // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils + return { + href: urlParsingNode.href, + protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', + host: urlParsingNode.host, + search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', + hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', + hostname: urlParsingNode.hostname, + port: urlParsingNode.port, + pathname: (urlParsingNode.pathname.charAt(0) === '/') + ? urlParsingNode.pathname + : '/' + urlParsingNode.pathname + }; +} + +/** + * Parse a request URL and determine whether this is a same-origin request as the application document. + * + * @param {string|object} requestUrl The url of the request as a string that will be resolved + * or a parsed URL object. + * @returns {boolean} Whether the request is for the same origin as the application document. + */ +function urlIsSameOrigin(requestUrl) { + var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl; + return (parsed.protocol === originUrl.protocol && + parsed.host === originUrl.host); +} + +/** + * @ngdoc service + * @name $window + * @this + * + * @description + * A reference to the browser's `window` object. While `window` + * is globally available in JavaScript, it causes testability problems, because + * it is a global variable. In angular we always refer to it through the + * `$window` service, so it may be overridden, removed or mocked for testing. + * + * Expressions, like the one defined for the `ngClick` directive in the example + * below, are evaluated with respect to the current scope. Therefore, there is + * no risk of inadvertently coding in a dependency on a global value in such an + * expression. + * + * @example + + + +
+ + +
+
+ + it('should display the greeting in the input box', function() { + element(by.model('greeting')).sendKeys('Hello, E2E Tests'); + // If we click the button it will block the test runner + // element(':button').click(); + }); + +
+ */ +function $WindowProvider() { + this.$get = valueFn(window); +} + +/** + * @name $$cookieReader + * @requires $document + * + * @description + * This is a private service for reading cookies used by $http and ngCookies + * + * @return {Object} a key/value map of the current cookies + */ +function $$CookieReader($document) { + var rawDocument = $document[0] || {}; + var lastCookies = {}; + var lastCookieString = ''; + + function safeGetCookie(rawDocument) { + try { + return rawDocument.cookie || ''; + } catch (e) { + return ''; + } + } + + function safeDecodeURIComponent(str) { + try { + return decodeURIComponent(str); + } catch (e) { + return str; + } + } + + return function() { + var cookieArray, cookie, i, index, name; + var currentCookieString = safeGetCookie(rawDocument); + + if (currentCookieString !== lastCookieString) { + lastCookieString = currentCookieString; + cookieArray = lastCookieString.split('; '); + lastCookies = {}; + + for (i = 0; i < cookieArray.length; i++) { + cookie = cookieArray[i]; + index = cookie.indexOf('='); + if (index > 0) { //ignore nameless cookies + name = safeDecodeURIComponent(cookie.substring(0, index)); + // the first value that is seen for a cookie is the most + // specific one. values for the same cookie name that + // follow are for less specific paths. + if (isUndefined(lastCookies[name])) { + lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1)); + } + } + } + } + return lastCookies; + }; +} + +$$CookieReader.$inject = ['$document']; + +/** @this */ +function $$CookieReaderProvider() { + this.$get = $$CookieReader; +} + +/* global currencyFilter: true, + dateFilter: true, + filterFilter: true, + jsonFilter: true, + limitToFilter: true, + lowercaseFilter: true, + numberFilter: true, + orderByFilter: true, + uppercaseFilter: true, + */ + +/** + * @ngdoc provider + * @name $filterProvider + * @description + * + * Filters are just functions which transform input to an output. However filters need to be + * Dependency Injected. To achieve this a filter definition consists of a factory function which is + * annotated with dependencies and is responsible for creating a filter function. + * + *
+ * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. + * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace + * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores + * (`myapp_subsection_filterx`). + *
+ * + * ```js + * // Filter registration + * function MyModule($provide, $filterProvider) { + * // create a service to demonstrate injection (not always needed) + * $provide.value('greet', function(name){ + * return 'Hello ' + name + '!'; + * }); + * + * // register a filter factory which uses the + * // greet service to demonstrate DI. + * $filterProvider.register('greet', function(greet){ + * // return the filter function which uses the greet service + * // to generate salutation + * return function(text) { + * // filters need to be forgiving so check input validity + * return text && greet(text) || text; + * }; + * }); + * } + * ``` + * + * The filter function is registered with the `$injector` under the filter name suffix with + * `Filter`. + * + * ```js + * it('should be the same instance', inject( + * function($filterProvider) { + * $filterProvider.register('reverse', function(){ + * return ...; + * }); + * }, + * function($filter, reverseFilter) { + * expect($filter('reverse')).toBe(reverseFilter); + * }); + * ``` + * + * + * For more information about how angular filters work, and how to create your own filters, see + * {@link guide/filter Filters} in the Angular Developer Guide. + */ + +/** + * @ngdoc service + * @name $filter + * @kind function + * @description + * Filters are used for formatting data displayed to the user. + * + * They can be used in view templates, controllers or services.Angular comes + * with a collection of [built-in filters](api/ng/filter), but it is easy to + * define your own as well. + * + * The general syntax in templates is as follows: + * + * ```html + * {{ expression [| filter_name[:parameter_value] ... ] }} + * ``` + * + * @param {String} name Name of the filter function to retrieve + * @return {Function} the filter function + * @example + + +
+

{{ originalText }}

+

{{ filteredText }}

+
+
+ + + angular.module('filterExample', []) + .controller('MainCtrl', function($scope, $filter) { + $scope.originalText = 'hello'; + $scope.filteredText = $filter('uppercase')($scope.originalText); + }); + +
+ */ +$FilterProvider.$inject = ['$provide']; +/** @this */ +function $FilterProvider($provide) { + var suffix = 'Filter'; + + /** + * @ngdoc method + * @name $filterProvider#register + * @param {string|Object} name Name of the filter function, or an object map of filters where + * the keys are the filter names and the values are the filter factories. + * + *
+ * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. + * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace + * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores + * (`myapp_subsection_filterx`). + *
+ * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered. + * @returns {Object} Registered filter instance, or if a map of filters was provided then a map + * of the registered filter instances. + */ + function register(name, factory) { + if (isObject(name)) { + var filters = {}; + forEach(name, function(filter, key) { + filters[key] = register(key, filter); + }); + return filters; + } else { + return $provide.factory(name + suffix, factory); + } + } + this.register = register; + + this.$get = ['$injector', function($injector) { + return function(name) { + return $injector.get(name + suffix); + }; + }]; + + //////////////////////////////////////// + + /* global + currencyFilter: false, + dateFilter: false, + filterFilter: false, + jsonFilter: false, + limitToFilter: false, + lowercaseFilter: false, + numberFilter: false, + orderByFilter: false, + uppercaseFilter: false + */ + + register('currency', currencyFilter); + register('date', dateFilter); + register('filter', filterFilter); + register('json', jsonFilter); + register('limitTo', limitToFilter); + register('lowercase', lowercaseFilter); + register('number', numberFilter); + register('orderBy', orderByFilter); + register('uppercase', uppercaseFilter); +} + +/** + * @ngdoc filter + * @name filter + * @kind function + * + * @description + * Selects a subset of items from `array` and returns it as a new array. + * + * @param {Array} array The source array. + * @param {string|Object|function()} expression The predicate to be used for selecting items from + * `array`. + * + * Can be one of: + * + * - `string`: The string is used for matching against the contents of the `array`. All strings or + * objects with string properties in `array` that match this string will be returned. This also + * applies to nested object properties. + * The predicate can be negated by prefixing the string with `!`. + * + * - `Object`: A pattern object can be used to filter specific properties on objects contained + * by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items + * which have property `name` containing "M" and property `phone` containing "1". A special + * property name (`$` by default) can be used (e.g. as in `{$: "text"}`) to accept a match + * against any property of the object or its nested object properties. That's equivalent to the + * simple substring match with a `string` as described above. The special property name can be + * overwritten, using the `anyPropertyKey` parameter. + * The predicate can be negated by prefixing the string with `!`. + * For example `{name: "!M"}` predicate will return an array of items which have property `name` + * not containing "M". + * + * Note that a named property will match properties on the same level only, while the special + * `$` property will match properties on the same level or deeper. E.g. an array item like + * `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but + * **will** be matched by `{$: 'John'}`. + * + * - `function(value, index, array)`: A predicate function can be used to write arbitrary filters. + * The function is called for each element of the array, with the element, its index, and + * the entire array itself as arguments. + * + * The final result is an array of those elements that the predicate returned true for. + * + * @param {function(actual, expected)|true|false} [comparator] Comparator which is used in + * determining if the expected value (from the filter expression) and actual value (from + * the object in the array) should be considered a match. + * + * Can be one of: + * + * - `function(actual, expected)`: + * The function will be given the object value and the predicate value to compare and + * should return true if both values should be considered equal. + * + * - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`. + * This is essentially strict comparison of expected and actual. + * + * - `false`: A short hand for a function which will look for a substring match in a case + * insensitive way. Primitive values are converted to strings. Objects are not compared against + * primitives, unless they have a custom `toString` method (e.g. `Date` objects). + * + * + * Defaults to `false`. + * + * @param {string} [anyPropertyKey] The special property name that matches against any property. + * By default `$`. + * + * @example + + +
+ + + + + + + + +
NamePhone
{{friend.name}}{{friend.phone}}
+
+
+
+
+
+ + + + + + +
NamePhone
{{friendObj.name}}{{friendObj.phone}}
+
+ + var expectFriendNames = function(expectedNames, key) { + element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) { + arr.forEach(function(wd, i) { + expect(wd.getText()).toMatch(expectedNames[i]); + }); + }); + }; + + it('should search across all fields when filtering with a string', function() { + var searchText = element(by.model('searchText')); + searchText.clear(); + searchText.sendKeys('m'); + expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend'); + + searchText.clear(); + searchText.sendKeys('76'); + expectFriendNames(['John', 'Julie'], 'friend'); + }); + + it('should search in specific fields when filtering with a predicate object', function() { + var searchAny = element(by.model('search.$')); + searchAny.clear(); + searchAny.sendKeys('i'); + expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj'); + }); + it('should use a equal comparison when comparator is true', function() { + var searchName = element(by.model('search.name')); + var strict = element(by.model('strict')); + searchName.clear(); + searchName.sendKeys('Julie'); + strict.click(); + expectFriendNames(['Julie'], 'friendObj'); + }); + +
+ */ + +function filterFilter() { + return function(array, expression, comparator, anyPropertyKey) { + if (!isArrayLike(array)) { + if (array == null) { + return array; + } else { + throw minErr('filter')('notarray', 'Expected array but received: {0}', array); + } + } + + anyPropertyKey = anyPropertyKey || '$'; + var expressionType = getTypeForFilter(expression); + var predicateFn; + var matchAgainstAnyProp; + + switch (expressionType) { + case 'function': + predicateFn = expression; + break; + case 'boolean': + case 'null': + case 'number': + case 'string': + matchAgainstAnyProp = true; + // falls through + case 'object': + predicateFn = createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp); + break; + default: + return array; + } + + return Array.prototype.filter.call(array, predicateFn); + }; +} + +// Helper functions for `filterFilter` +function createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp) { + var shouldMatchPrimitives = isObject(expression) && (anyPropertyKey in expression); + var predicateFn; + + if (comparator === true) { + comparator = equals; + } else if (!isFunction(comparator)) { + comparator = function(actual, expected) { + if (isUndefined(actual)) { + // No substring matching against `undefined` + return false; + } + if ((actual === null) || (expected === null)) { + // No substring matching against `null`; only match against `null` + return actual === expected; + } + if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) { + // Should not compare primitives against objects, unless they have custom `toString` method + return false; + } + + actual = lowercase('' + actual); + expected = lowercase('' + expected); + return actual.indexOf(expected) !== -1; + }; + } + + predicateFn = function(item) { + if (shouldMatchPrimitives && !isObject(item)) { + return deepCompare(item, expression[anyPropertyKey], comparator, anyPropertyKey, false); + } + return deepCompare(item, expression, comparator, anyPropertyKey, matchAgainstAnyProp); + }; + + return predicateFn; +} + +function deepCompare(actual, expected, comparator, anyPropertyKey, matchAgainstAnyProp, dontMatchWholeObject) { + var actualType = getTypeForFilter(actual); + var expectedType = getTypeForFilter(expected); + + if ((expectedType === 'string') && (expected.charAt(0) === '!')) { + return !deepCompare(actual, expected.substring(1), comparator, anyPropertyKey, matchAgainstAnyProp); + } else if (isArray(actual)) { + // In case `actual` is an array, consider it a match + // if ANY of it's items matches `expected` + return actual.some(function(item) { + return deepCompare(item, expected, comparator, anyPropertyKey, matchAgainstAnyProp); + }); + } + + switch (actualType) { + case 'object': + var key; + if (matchAgainstAnyProp) { + for (key in actual) { + if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) { + return true; + } + } + return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, anyPropertyKey, false); + } else if (expectedType === 'object') { + for (key in expected) { + var expectedVal = expected[key]; + if (isFunction(expectedVal) || isUndefined(expectedVal)) { + continue; + } + + var matchAnyProperty = key === anyPropertyKey; + var actualVal = matchAnyProperty ? actual : actual[key]; + if (!deepCompare(actualVal, expectedVal, comparator, anyPropertyKey, matchAnyProperty, matchAnyProperty)) { + return false; + } + } + return true; + } else { + return comparator(actual, expected); + } + case 'function': + return false; + default: + return comparator(actual, expected); + } +} + +// Used for easily differentiating between `null` and actual `object` +function getTypeForFilter(val) { + return (val === null) ? 'null' : typeof val; +} + +var MAX_DIGITS = 22; +var DECIMAL_SEP = '.'; +var ZERO_CHAR = '0'; + +/** + * @ngdoc filter + * @name currency + * @kind function + * + * @description + * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default + * symbol for current locale is used. + * + * @param {number} amount Input to filter. + * @param {string=} symbol Currency symbol or identifier to be displayed. + * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale + * @returns {string} Formatted number. + * + * + * @example + + + +
+
+ default currency symbol ($): {{amount | currency}}
+ custom currency identifier (USD$): {{amount | currency:"USD$"}}
+ no fractions (0): {{amount | currency:"USD$":0}} +
+
+ + it('should init with 1234.56', function() { + expect(element(by.id('currency-default')).getText()).toBe('$1,234.56'); + expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56'); + expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235'); + }); + it('should update', function() { + if (browser.params.browser === 'safari') { + // Safari does not understand the minus key. See + // https://github.com/angular/protractor/issues/481 + return; + } + element(by.model('amount')).clear(); + element(by.model('amount')).sendKeys('-1234'); + expect(element(by.id('currency-default')).getText()).toBe('-$1,234.00'); + expect(element(by.id('currency-custom')).getText()).toBe('-USD$1,234.00'); + expect(element(by.id('currency-no-fractions')).getText()).toBe('-USD$1,234'); + }); + +
+ */ +currencyFilter.$inject = ['$locale']; +function currencyFilter($locale) { + var formats = $locale.NUMBER_FORMATS; + return function(amount, currencySymbol, fractionSize) { + if (isUndefined(currencySymbol)) { + currencySymbol = formats.CURRENCY_SYM; + } + + if (isUndefined(fractionSize)) { + fractionSize = formats.PATTERNS[1].maxFrac; + } + + // if null or undefined pass it through + return (amount == null) + ? amount + : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize). + replace(/\u00A4/g, currencySymbol); + }; +} + +/** + * @ngdoc filter + * @name number + * @kind function + * + * @description + * Formats a number as text. + * + * If the input is null or undefined, it will just be returned. + * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively. + * If the input is not a number an empty string is returned. + * + * + * @param {number|string} number Number to format. + * @param {(number|string)=} fractionSize Number of decimal places to round the number to. + * If this is not provided then the fraction size is computed from the current locale's number + * formatting pattern. In the case of the default locale, it will be 3. + * @returns {string} Number rounded to `fractionSize` appropriately formatted based on the current + * locale (e.g., in the en_US locale it will have "." as the decimal separator and + * include "," group separators after each third digit). + * + * @example + + + +
+
+ Default formatting: {{val | number}}
+ No fractions: {{val | number:0}}
+ Negative number: {{-val | number:4}} +
+
+ + it('should format numbers', function() { + expect(element(by.id('number-default')).getText()).toBe('1,234.568'); + expect(element(by.binding('val | number:0')).getText()).toBe('1,235'); + expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679'); + }); + + it('should update', function() { + element(by.model('val')).clear(); + element(by.model('val')).sendKeys('3374.333'); + expect(element(by.id('number-default')).getText()).toBe('3,374.333'); + expect(element(by.binding('val | number:0')).getText()).toBe('3,374'); + expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330'); + }); + +
+ */ +numberFilter.$inject = ['$locale']; +function numberFilter($locale) { + var formats = $locale.NUMBER_FORMATS; + return function(number, fractionSize) { + + // if null or undefined pass it through + return (number == null) + ? number + : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP, + fractionSize); + }; +} + +/** + * Parse a number (as a string) into three components that can be used + * for formatting the number. + * + * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/) + * + * @param {string} numStr The number to parse + * @return {object} An object describing this number, containing the following keys: + * - d : an array of digits containing leading zeros as necessary + * - i : the number of the digits in `d` that are to the left of the decimal point + * - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d` + * + */ +function parse(numStr) { + var exponent = 0, digits, numberOfIntegerDigits; + var i, j, zeros; + + // Decimal point? + if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) { + numStr = numStr.replace(DECIMAL_SEP, ''); + } + + // Exponential form? + if ((i = numStr.search(/e/i)) > 0) { + // Work out the exponent. + if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i; + numberOfIntegerDigits += +numStr.slice(i + 1); + numStr = numStr.substring(0, i); + } else if (numberOfIntegerDigits < 0) { + // There was no decimal point or exponent so it is an integer. + numberOfIntegerDigits = numStr.length; + } + + // Count the number of leading zeros. + for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { /* empty */ } + + if (i === (zeros = numStr.length)) { + // The digits are all zero. + digits = [0]; + numberOfIntegerDigits = 1; + } else { + // Count the number of trailing zeros + zeros--; + while (numStr.charAt(zeros) === ZERO_CHAR) zeros--; + + // Trailing zeros are insignificant so ignore them + numberOfIntegerDigits -= i; + digits = []; + // Convert string to array of digits without leading/trailing zeros. + for (j = 0; i <= zeros; i++, j++) { + digits[j] = +numStr.charAt(i); + } + } + + // If the number overflows the maximum allowed digits then use an exponent. + if (numberOfIntegerDigits > MAX_DIGITS) { + digits = digits.splice(0, MAX_DIGITS - 1); + exponent = numberOfIntegerDigits - 1; + numberOfIntegerDigits = 1; + } + + return { d: digits, e: exponent, i: numberOfIntegerDigits }; +} + +/** + * Round the parsed number to the specified number of decimal places + * This function changed the parsedNumber in-place + */ +function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) { + var digits = parsedNumber.d; + var fractionLen = digits.length - parsedNumber.i; + + // determine fractionSize if it is not specified; `+fractionSize` converts it to a number + fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize; + + // The index of the digit to where rounding is to occur + var roundAt = fractionSize + parsedNumber.i; + var digit = digits[roundAt]; + + if (roundAt > 0) { + // Drop fractional digits beyond `roundAt` + digits.splice(Math.max(parsedNumber.i, roundAt)); + + // Set non-fractional digits beyond `roundAt` to 0 + for (var j = roundAt; j < digits.length; j++) { + digits[j] = 0; + } + } else { + // We rounded to zero so reset the parsedNumber + fractionLen = Math.max(0, fractionLen); + parsedNumber.i = 1; + digits.length = Math.max(1, roundAt = fractionSize + 1); + digits[0] = 0; + for (var i = 1; i < roundAt; i++) digits[i] = 0; + } + + if (digit >= 5) { + if (roundAt - 1 < 0) { + for (var k = 0; k > roundAt; k--) { + digits.unshift(0); + parsedNumber.i++; + } + digits.unshift(1); + parsedNumber.i++; + } else { + digits[roundAt - 1]++; + } + } + + // Pad out with zeros to get the required fraction length + for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0); + + + // Do any carrying, e.g. a digit was rounded up to 10 + var carry = digits.reduceRight(function(carry, d, i, digits) { + d = d + carry; + digits[i] = d % 10; + return Math.floor(d / 10); + }, 0); + if (carry) { + digits.unshift(carry); + parsedNumber.i++; + } +} + +/** + * Format a number into a string + * @param {number} number The number to format + * @param {{ + * minFrac, // the minimum number of digits required in the fraction part of the number + * maxFrac, // the maximum number of digits required in the fraction part of the number + * gSize, // number of digits in each group of separated digits + * lgSize, // number of digits in the last group of digits before the decimal separator + * negPre, // the string to go in front of a negative number (e.g. `-` or `(`)) + * posPre, // the string to go in front of a positive number + * negSuf, // the string to go after a negative number (e.g. `)`) + * posSuf // the string to go after a positive number + * }} pattern + * @param {string} groupSep The string to separate groups of number (e.g. `,`) + * @param {string} decimalSep The string to act as the decimal separator (e.g. `.`) + * @param {[type]} fractionSize The size of the fractional part of the number + * @return {string} The number formatted as a string + */ +function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { + + if (!(isString(number) || isNumber(number)) || isNaN(number)) return ''; + + var isInfinity = !isFinite(number); + var isZero = false; + var numStr = Math.abs(number) + '', + formattedText = '', + parsedNumber; + + if (isInfinity) { + formattedText = '\u221e'; + } else { + parsedNumber = parse(numStr); + + roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac); + + var digits = parsedNumber.d; + var integerLen = parsedNumber.i; + var exponent = parsedNumber.e; + var decimals = []; + isZero = digits.reduce(function(isZero, d) { return isZero && !d; }, true); + + // pad zeros for small numbers + while (integerLen < 0) { + digits.unshift(0); + integerLen++; + } + + // extract decimals digits + if (integerLen > 0) { + decimals = digits.splice(integerLen, digits.length); + } else { + decimals = digits; + digits = [0]; + } + + // format the integer digits with grouping separators + var groups = []; + if (digits.length >= pattern.lgSize) { + groups.unshift(digits.splice(-pattern.lgSize, digits.length).join('')); + } + while (digits.length > pattern.gSize) { + groups.unshift(digits.splice(-pattern.gSize, digits.length).join('')); + } + if (digits.length) { + groups.unshift(digits.join('')); + } + formattedText = groups.join(groupSep); + + // append the decimal digits + if (decimals.length) { + formattedText += decimalSep + decimals.join(''); + } + + if (exponent) { + formattedText += 'e+' + exponent; + } + } + if (number < 0 && !isZero) { + return pattern.negPre + formattedText + pattern.negSuf; + } else { + return pattern.posPre + formattedText + pattern.posSuf; + } +} + +function padNumber(num, digits, trim, negWrap) { + var neg = ''; + if (num < 0 || (negWrap && num <= 0)) { + if (negWrap) { + num = -num + 1; + } else { + num = -num; + neg = '-'; + } + } + num = '' + num; + while (num.length < digits) num = ZERO_CHAR + num; + if (trim) { + num = num.substr(num.length - digits); + } + return neg + num; +} + + +function dateGetter(name, size, offset, trim, negWrap) { + offset = offset || 0; + return function(date) { + var value = date['get' + name](); + if (offset > 0 || value > -offset) { + value += offset; + } + if (value === 0 && offset === -12) value = 12; + return padNumber(value, size, trim, negWrap); + }; +} + +function dateStrGetter(name, shortForm, standAlone) { + return function(date, formats) { + var value = date['get' + name](); + var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : ''); + var get = uppercase(propPrefix + name); + + return formats[get][value]; + }; +} + +function timeZoneGetter(date, formats, offset) { + var zone = -1 * offset; + var paddedZone = (zone >= 0) ? '+' : ''; + + paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) + + padNumber(Math.abs(zone % 60), 2); + + return paddedZone; +} + +function getFirstThursdayOfYear(year) { + // 0 = index of January + var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay(); + // 4 = index of Thursday (+1 to account for 1st = 5) + // 11 = index of *next* Thursday (+1 account for 1st = 12) + return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst); +} + +function getThursdayThisWeek(datetime) { + return new Date(datetime.getFullYear(), datetime.getMonth(), + // 4 = index of Thursday + datetime.getDate() + (4 - datetime.getDay())); +} + +function weekGetter(size) { + return function(date) { + var firstThurs = getFirstThursdayOfYear(date.getFullYear()), + thisThurs = getThursdayThisWeek(date); + + var diff = +thisThurs - +firstThurs, + result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week + + return padNumber(result, size); + }; +} + +function ampmGetter(date, formats) { + return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1]; +} + +function eraGetter(date, formats) { + return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1]; +} + +function longEraGetter(date, formats) { + return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1]; +} + +var DATE_FORMATS = { + yyyy: dateGetter('FullYear', 4, 0, false, true), + yy: dateGetter('FullYear', 2, 0, true, true), + y: dateGetter('FullYear', 1, 0, false, true), + MMMM: dateStrGetter('Month'), + MMM: dateStrGetter('Month', true), + MM: dateGetter('Month', 2, 1), + M: dateGetter('Month', 1, 1), + LLLL: dateStrGetter('Month', false, true), + dd: dateGetter('Date', 2), + d: dateGetter('Date', 1), + HH: dateGetter('Hours', 2), + H: dateGetter('Hours', 1), + hh: dateGetter('Hours', 2, -12), + h: dateGetter('Hours', 1, -12), + mm: dateGetter('Minutes', 2), + m: dateGetter('Minutes', 1), + ss: dateGetter('Seconds', 2), + s: dateGetter('Seconds', 1), + // while ISO 8601 requires fractions to be prefixed with `.` or `,` + // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions + sss: dateGetter('Milliseconds', 3), + EEEE: dateStrGetter('Day'), + EEE: dateStrGetter('Day', true), + a: ampmGetter, + Z: timeZoneGetter, + ww: weekGetter(2), + w: weekGetter(1), + G: eraGetter, + GG: eraGetter, + GGG: eraGetter, + GGGG: longEraGetter +}; + +var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/, + NUMBER_STRING = /^-?\d+$/; + +/** + * @ngdoc filter + * @name date + * @kind function + * + * @description + * Formats `date` to a string based on the requested `format`. + * + * `format` string can be composed of the following elements: + * + * * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010) + * * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) + * * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199) + * * `'MMMM'`: Month in year (January-December) + * * `'MMM'`: Month in year (Jan-Dec) + * * `'MM'`: Month in year, padded (01-12) + * * `'M'`: Month in year (1-12) + * * `'LLLL'`: Stand-alone month in year (January-December) + * * `'dd'`: Day in month, padded (01-31) + * * `'d'`: Day in month (1-31) + * * `'EEEE'`: Day in Week,(Sunday-Saturday) + * * `'EEE'`: Day in Week, (Sun-Sat) + * * `'HH'`: Hour in day, padded (00-23) + * * `'H'`: Hour in day (0-23) + * * `'hh'`: Hour in AM/PM, padded (01-12) + * * `'h'`: Hour in AM/PM, (1-12) + * * `'mm'`: Minute in hour, padded (00-59) + * * `'m'`: Minute in hour (0-59) + * * `'ss'`: Second in minute, padded (00-59) + * * `'s'`: Second in minute (0-59) + * * `'sss'`: Millisecond in second, padded (000-999) + * * `'a'`: AM/PM marker + * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200) + * * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year + * * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year + * * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD') + * * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini') + * + * `format` string can also be one of the following predefined + * {@link guide/i18n localizable formats}: + * + * * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale + * (e.g. Sep 3, 2010 12:05:08 PM) + * * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 PM) + * * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US locale + * (e.g. Friday, September 3, 2010) + * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010) + * * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010) + * * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10) + * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM) + * * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM) + * + * `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g. + * `"h 'in the morning'"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence + * (e.g. `"h 'o''clock'"`). + * + * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or + * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its + * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is + * specified in the string input, the time is considered to be in the local timezone. + * @param {string=} format Formatting rules (see Description). If not specified, + * `mediumDate` is used. + * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the + * continental US time zone abbreviations, but for general use, use a time zone offset, for + * example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian) + * If not specified, the timezone of the browser will be used. + * @returns {string} Formatted string or the input if input is not recognized as date/millis. + * + * @example + + + {{1288323623006 | date:'medium'}}: + {{1288323623006 | date:'medium'}}
+ {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}: + {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
+ {{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}: + {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
+ {{1288323623006 | date:"MM/dd/yyyy 'at' h:mma"}}: + {{'1288323623006' | date:"MM/dd/yyyy 'at' h:mma"}}
+
+ + it('should format date', function() { + expect(element(by.binding("1288323623006 | date:'medium'")).getText()). + toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/); + expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()). + toMatch(/2010-10-2\d \d{2}:\d{2}:\d{2} (-|\+)?\d{4}/); + expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()). + toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); + expect(element(by.binding("'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"")).getText()). + toMatch(/10\/2\d\/2010 at \d{1,2}:\d{2}(AM|PM)/); + }); + +
+ */ +dateFilter.$inject = ['$locale']; +function dateFilter($locale) { + + + var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; + // 1 2 3 4 5 6 7 8 9 10 11 + function jsonStringToDate(string) { + var match; + if ((match = string.match(R_ISO8601_STR))) { + var date = new Date(0), + tzHour = 0, + tzMin = 0, + dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear, + timeSetter = match[8] ? date.setUTCHours : date.setHours; + + if (match[9]) { + tzHour = toInt(match[9] + match[10]); + tzMin = toInt(match[9] + match[11]); + } + dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3])); + var h = toInt(match[4] || 0) - tzHour; + var m = toInt(match[5] || 0) - tzMin; + var s = toInt(match[6] || 0); + var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000); + timeSetter.call(date, h, m, s, ms); + return date; + } + return string; + } + + + return function(date, format, timezone) { + var text = '', + parts = [], + fn, match; + + format = format || 'mediumDate'; + format = $locale.DATETIME_FORMATS[format] || format; + if (isString(date)) { + date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date); + } + + if (isNumber(date)) { + date = new Date(date); + } + + if (!isDate(date) || !isFinite(date.getTime())) { + return date; + } + + while (format) { + match = DATE_FORMATS_SPLIT.exec(format); + if (match) { + parts = concat(parts, match, 1); + format = parts.pop(); + } else { + parts.push(format); + format = null; + } + } + + var dateTimezoneOffset = date.getTimezoneOffset(); + if (timezone) { + dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset); + date = convertTimezoneToLocal(date, timezone, true); + } + forEach(parts, function(value) { + fn = DATE_FORMATS[value]; + text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset) + : value === '\'\'' ? '\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\''); + }); + + return text; + }; +} + + +/** + * @ngdoc filter + * @name json + * @kind function + * + * @description + * Allows you to convert a JavaScript object into JSON string. + * + * This filter is mostly useful for debugging. When using the double curly {{value}} notation + * the binding is automatically converted to JSON. + * + * @param {*} object Any JavaScript object (including arrays and primitive types) to filter. + * @param {number=} spacing The number of spaces to use per indentation, defaults to 2. + * @returns {string} JSON string. + * + * + * @example + + +
{{ {'name':'value'} | json }}
+
{{ {'name':'value'} | json:4 }}
+
+ + it('should jsonify filtered objects', function() { + expect(element(by.id('default-spacing')).getText()).toMatch(/\{\n {2}"name": ?"value"\n}/); + expect(element(by.id('custom-spacing')).getText()).toMatch(/\{\n {4}"name": ?"value"\n}/); + }); + +
+ * + */ +function jsonFilter() { + return function(object, spacing) { + if (isUndefined(spacing)) { + spacing = 2; + } + return toJson(object, spacing); + }; +} + + +/** + * @ngdoc filter + * @name lowercase + * @kind function + * @description + * Converts string to lowercase. + * @see angular.lowercase + */ +var lowercaseFilter = valueFn(lowercase); + + +/** + * @ngdoc filter + * @name uppercase + * @kind function + * @description + * Converts string to uppercase. + * @see angular.uppercase + */ +var uppercaseFilter = valueFn(uppercase); + +/** + * @ngdoc filter + * @name limitTo + * @kind function + * + * @description + * Creates a new array or string containing only a specified number of elements. The elements are + * taken from either the beginning or the end of the source array, string or number, as specified by + * the value and sign (positive or negative) of `limit`. Other array-like objects are also supported + * (e.g. array subclasses, NodeLists, jqLite/jQuery collections etc). If a number is used as input, + * it is converted to a string. + * + * @param {Array|ArrayLike|string|number} input - Array/array-like, string or number to be limited. + * @param {string|number} limit - The length of the returned array or string. If the `limit` number + * is positive, `limit` number of items from the beginning of the source array/string are copied. + * If the number is negative, `limit` number of items from the end of the source array/string + * are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined, + * the input will be returned unchanged. + * @param {(string|number)=} begin - Index at which to begin limitation. As a negative index, + * `begin` indicates an offset from the end of `input`. Defaults to `0`. + * @returns {Array|string} A new sub-array or substring of length `limit` or less if the input had + * less than `limit` elements. + * + * @example + + + +
+ +

Output numbers: {{ numbers | limitTo:numLimit }}

+ +

Output letters: {{ letters | limitTo:letterLimit }}

+ +

Output long number: {{ longNumber | limitTo:longNumberLimit }}

+
+
+ + var numLimitInput = element(by.model('numLimit')); + var letterLimitInput = element(by.model('letterLimit')); + var longNumberLimitInput = element(by.model('longNumberLimit')); + var limitedNumbers = element(by.binding('numbers | limitTo:numLimit')); + var limitedLetters = element(by.binding('letters | limitTo:letterLimit')); + var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit')); + + it('should limit the number array to first three items', function() { + expect(numLimitInput.getAttribute('value')).toBe('3'); + expect(letterLimitInput.getAttribute('value')).toBe('3'); + expect(longNumberLimitInput.getAttribute('value')).toBe('3'); + expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]'); + expect(limitedLetters.getText()).toEqual('Output letters: abc'); + expect(limitedLongNumber.getText()).toEqual('Output long number: 234'); + }); + + // There is a bug in safari and protractor that doesn't like the minus key + // it('should update the output when -3 is entered', function() { + // numLimitInput.clear(); + // numLimitInput.sendKeys('-3'); + // letterLimitInput.clear(); + // letterLimitInput.sendKeys('-3'); + // longNumberLimitInput.clear(); + // longNumberLimitInput.sendKeys('-3'); + // expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]'); + // expect(limitedLetters.getText()).toEqual('Output letters: ghi'); + // expect(limitedLongNumber.getText()).toEqual('Output long number: 342'); + // }); + + it('should not exceed the maximum size of input array', function() { + numLimitInput.clear(); + numLimitInput.sendKeys('100'); + letterLimitInput.clear(); + letterLimitInput.sendKeys('100'); + longNumberLimitInput.clear(); + longNumberLimitInput.sendKeys('100'); + expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]'); + expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi'); + expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342'); + }); + +
+*/ +function limitToFilter() { + return function(input, limit, begin) { + if (Math.abs(Number(limit)) === Infinity) { + limit = Number(limit); + } else { + limit = toInt(limit); + } + if (isNumberNaN(limit)) return input; + + if (isNumber(input)) input = input.toString(); + if (!isArrayLike(input)) return input; + + begin = (!begin || isNaN(begin)) ? 0 : toInt(begin); + begin = (begin < 0) ? Math.max(0, input.length + begin) : begin; + + if (limit >= 0) { + return sliceFn(input, begin, begin + limit); + } else { + if (begin === 0) { + return sliceFn(input, limit, input.length); + } else { + return sliceFn(input, Math.max(0, begin + limit), begin); + } + } + }; +} + +function sliceFn(input, begin, end) { + if (isString(input)) return input.slice(begin, end); + + return slice.call(input, begin, end); +} + +/** + * @ngdoc filter + * @name orderBy + * @kind function + * + * @description + * Returns an array containing the items from the specified `collection`, ordered by a `comparator` + * function based on the values computed using the `expression` predicate. + * + * For example, `[{id: 'foo'}, {id: 'bar'}] | orderBy:'id'` would result in + * `[{id: 'bar'}, {id: 'foo'}]`. + * + * The `collection` can be an Array or array-like object (e.g. NodeList, jQuery object, TypedArray, + * String, etc). + * + * The `expression` can be a single predicate, or a list of predicates each serving as a tie-breaker + * for the preceding one. The `expression` is evaluated against each item and the output is used + * for comparing with other items. + * + * You can change the sorting order by setting `reverse` to `true`. By default, items are sorted in + * ascending order. + * + * The comparison is done using the `comparator` function. If none is specified, a default, built-in + * comparator is used (see below for details - in a nutshell, it compares numbers numerically and + * strings alphabetically). + * + * ### Under the hood + * + * Ordering the specified `collection` happens in two phases: + * + * 1. All items are passed through the predicate (or predicates), and the returned values are saved + * along with their type (`string`, `number` etc). For example, an item `{label: 'foo'}`, passed + * through a predicate that extracts the value of the `label` property, would be transformed to: + * ``` + * { + * value: 'foo', + * type: 'string', + * index: ... + * } + * ``` + * 2. The comparator function is used to sort the items, based on the derived values, types and + * indices. + * + * If you use a custom comparator, it will be called with pairs of objects of the form + * `{value: ..., type: '...', index: ...}` and is expected to return `0` if the objects are equal + * (as far as the comparator is concerned), `-1` if the 1st one should be ranked higher than the + * second, or `1` otherwise. + * + * In order to ensure that the sorting will be deterministic across platforms, if none of the + * specified predicates can distinguish between two items, `orderBy` will automatically introduce a + * dummy predicate that returns the item's index as `value`. + * (If you are using a custom comparator, make sure it can handle this predicate as well.) + * + * Finally, in an attempt to simplify things, if a predicate returns an object as the extracted + * value for an item, `orderBy` will try to convert that object to a primitive value, before passing + * it to the comparator. The following rules govern the conversion: + * + * 1. If the object has a `valueOf()` method that returns a primitive, its return value will be + * used instead.
+ * (If the object has a `valueOf()` method that returns another object, then the returned object + * will be used in subsequent steps.) + * 2. If the object has a custom `toString()` method (i.e. not the one inherited from `Object`) that + * returns a primitive, its return value will be used instead.
+ * (If the object has a `toString()` method that returns another object, then the returned object + * will be used in subsequent steps.) + * 3. No conversion; the object itself is used. + * + * ### The default comparator + * + * The default, built-in comparator should be sufficient for most usecases. In short, it compares + * numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to + * using their index in the original collection, and sorts values of different types by type. + * + * More specifically, it follows these steps to determine the relative order of items: + * + * 1. If the compared values are of different types, compare the types themselves alphabetically. + * 2. If both values are of type `string`, compare them alphabetically in a case- and + * locale-insensitive way. + * 3. If both values are objects, compare their indices instead. + * 4. Otherwise, return: + * - `0`, if the values are equal (by strict equality comparison, i.e. using `===`). + * - `-1`, if the 1st value is "less than" the 2nd value (compared using the `<` operator). + * - `1`, otherwise. + * + * **Note:** If you notice numbers not being sorted as expected, make sure they are actually being + * saved as numbers and not strings. + * **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e. + * `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to + * other values. + * + * @param {Array|ArrayLike} collection - The collection (array or array-like object) to sort. + * @param {(Function|string|Array.)=} expression - A predicate (or list of + * predicates) to be used by the comparator to determine the order of elements. + * + * Can be one of: + * + * - `Function`: A getter function. This function will be called with each item as argument and + * the return value will be used for sorting. + * - `string`: An Angular expression. This expression will be evaluated against each item and the + * result will be used for sorting. For example, use `'label'` to sort by a property called + * `label` or `'label.substring(0, 3)'` to sort by the first 3 characters of the `label` + * property.
+ * (The result of a constant expression is interpreted as a property name to be used for + * comparison. For example, use `'"special name"'` (note the extra pair of quotes) to sort by a + * property called `special name`.)
+ * An expression can be optionally prefixed with `+` or `-` to control the sorting direction, + * ascending or descending. For example, `'+label'` or `'-label'`. If no property is provided, + * (e.g. `'+'` or `'-'`), the collection element itself is used in comparisons. + * - `Array`: An array of function and/or string predicates. If a predicate cannot determine the + * relative order of two items, the next predicate is used as a tie-breaker. + * + * **Note:** If the predicate is missing or empty then it defaults to `'+'`. + * + * @param {boolean=} reverse - If `true`, reverse the sorting order. + * @param {(Function)=} comparator - The comparator function used to determine the relative order of + * value pairs. If omitted, the built-in comparator will be used. + * + * @returns {Array} - The sorted array. + * + * + * @example + * ### Ordering a table with `ngRepeat` + * + * The example below demonstrates a simple {@link ngRepeat ngRepeat}, where the data is sorted by + * age in descending order (expression is set to `'-age'`). The `comparator` is not set, which means + * it defaults to the built-in comparator. + * + + +
+ + + + + + + + + + + +
NamePhone NumberAge
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+
+ + angular.module('orderByExample1', []) + .controller('ExampleController', ['$scope', function($scope) { + $scope.friends = [ + {name: 'John', phone: '555-1212', age: 10}, + {name: 'Mary', phone: '555-9876', age: 19}, + {name: 'Mike', phone: '555-4321', age: 21}, + {name: 'Adam', phone: '555-5678', age: 35}, + {name: 'Julie', phone: '555-8765', age: 29} + ]; + }]); + + + .friends { + border-collapse: collapse; + } + + .friends th { + border-bottom: 1px solid; + } + .friends td, .friends th { + border-left: 1px solid; + padding: 5px 10px; + } + .friends td:first-child, .friends th:first-child { + border-left: none; + } + + + // Element locators + var names = element.all(by.repeater('friends').column('friend.name')); + + it('should sort friends by age in reverse order', function() { + expect(names.get(0).getText()).toBe('Adam'); + expect(names.get(1).getText()).toBe('Julie'); + expect(names.get(2).getText()).toBe('Mike'); + expect(names.get(3).getText()).toBe('Mary'); + expect(names.get(4).getText()).toBe('John'); + }); + +
+ *
+ * + * @example + * ### Changing parameters dynamically + * + * All parameters can be changed dynamically. The next example shows how you can make the columns of + * a table sortable, by binding the `expression` and `reverse` parameters to scope properties. + * + + +
+
Sort by = {{propertyName}}; reverse = {{reverse}}
+
+ +
+ + + + + + + + + + + +
+ + + + + + + + +
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+
+ + angular.module('orderByExample2', []) + .controller('ExampleController', ['$scope', function($scope) { + var friends = [ + {name: 'John', phone: '555-1212', age: 10}, + {name: 'Mary', phone: '555-9876', age: 19}, + {name: 'Mike', phone: '555-4321', age: 21}, + {name: 'Adam', phone: '555-5678', age: 35}, + {name: 'Julie', phone: '555-8765', age: 29} + ]; + + $scope.propertyName = 'age'; + $scope.reverse = true; + $scope.friends = friends; + + $scope.sortBy = function(propertyName) { + $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false; + $scope.propertyName = propertyName; + }; + }]); + + + .friends { + border-collapse: collapse; + } + + .friends th { + border-bottom: 1px solid; + } + .friends td, .friends th { + border-left: 1px solid; + padding: 5px 10px; + } + .friends td:first-child, .friends th:first-child { + border-left: none; + } + + .sortorder:after { + content: '\25b2'; // BLACK UP-POINTING TRIANGLE + } + .sortorder.reverse:after { + content: '\25bc'; // BLACK DOWN-POINTING TRIANGLE + } + + + // Element locators + var unsortButton = element(by.partialButtonText('unsorted')); + var nameHeader = element(by.partialButtonText('Name')); + var phoneHeader = element(by.partialButtonText('Phone')); + var ageHeader = element(by.partialButtonText('Age')); + var firstName = element(by.repeater('friends').column('friend.name').row(0)); + var lastName = element(by.repeater('friends').column('friend.name').row(4)); + + it('should sort friends by some property, when clicking on the column header', function() { + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + + phoneHeader.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Mary'); + + nameHeader.click(); + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('Mike'); + + ageHeader.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Adam'); + }); + + it('should sort friends in reverse order, when clicking on the same column', function() { + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + + ageHeader.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Adam'); + + ageHeader.click(); + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + }); + + it('should restore the original order, when clicking "Set to unsorted"', function() { + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + + unsortButton.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Julie'); + }); + +
+ *
+ * + * @example + * ### Using `orderBy` inside a controller + * + * It is also possible to call the `orderBy` filter manually, by injecting `orderByFilter`, and + * calling it with the desired parameters. (Alternatively, you could inject the `$filter` factory + * and retrieve the `orderBy` filter with `$filter('orderBy')`.) + * + + +
+
Sort by = {{propertyName}}; reverse = {{reverse}}
+
+ +
+ + + + + + + + + + + +
+ + + + + + + + +
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+
+ + angular.module('orderByExample3', []) + .controller('ExampleController', ['$scope', 'orderByFilter', function($scope, orderBy) { + var friends = [ + {name: 'John', phone: '555-1212', age: 10}, + {name: 'Mary', phone: '555-9876', age: 19}, + {name: 'Mike', phone: '555-4321', age: 21}, + {name: 'Adam', phone: '555-5678', age: 35}, + {name: 'Julie', phone: '555-8765', age: 29} + ]; + + $scope.propertyName = 'age'; + $scope.reverse = true; + $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse); + + $scope.sortBy = function(propertyName) { + $scope.reverse = (propertyName !== null && $scope.propertyName === propertyName) + ? !$scope.reverse : false; + $scope.propertyName = propertyName; + $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse); + }; + }]); + + + .friends { + border-collapse: collapse; + } + + .friends th { + border-bottom: 1px solid; + } + .friends td, .friends th { + border-left: 1px solid; + padding: 5px 10px; + } + .friends td:first-child, .friends th:first-child { + border-left: none; + } + + .sortorder:after { + content: '\25b2'; // BLACK UP-POINTING TRIANGLE + } + .sortorder.reverse:after { + content: '\25bc'; // BLACK DOWN-POINTING TRIANGLE + } + + + // Element locators + var unsortButton = element(by.partialButtonText('unsorted')); + var nameHeader = element(by.partialButtonText('Name')); + var phoneHeader = element(by.partialButtonText('Phone')); + var ageHeader = element(by.partialButtonText('Age')); + var firstName = element(by.repeater('friends').column('friend.name').row(0)); + var lastName = element(by.repeater('friends').column('friend.name').row(4)); + + it('should sort friends by some property, when clicking on the column header', function() { + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + + phoneHeader.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Mary'); + + nameHeader.click(); + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('Mike'); + + ageHeader.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Adam'); + }); + + it('should sort friends in reverse order, when clicking on the same column', function() { + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + + ageHeader.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Adam'); + + ageHeader.click(); + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + }); + + it('should restore the original order, when clicking "Set to unsorted"', function() { + expect(firstName.getText()).toBe('Adam'); + expect(lastName.getText()).toBe('John'); + + unsortButton.click(); + expect(firstName.getText()).toBe('John'); + expect(lastName.getText()).toBe('Julie'); + }); + +
+ *
+ * + * @example + * ### Using a custom comparator + * + * If you have very specific requirements about the way items are sorted, you can pass your own + * comparator function. For example, you might need to compare some strings in a locale-sensitive + * way. (When specifying a custom comparator, you also need to pass a value for the `reverse` + * argument - passing `false` retains the default sorting order, i.e. ascending.) + * + + +
+
+

Locale-sensitive Comparator

+ + + + + + + + + +
NameFavorite Letter
{{friend.name}}{{friend.favoriteLetter}}
+
+
+

Default Comparator

+ + + + + + + + + +
NameFavorite Letter
{{friend.name}}{{friend.favoriteLetter}}
+
+
+
+ + angular.module('orderByExample4', []) + .controller('ExampleController', ['$scope', function($scope) { + $scope.friends = [ + {name: 'John', favoriteLetter: 'Ä'}, + {name: 'Mary', favoriteLetter: 'Ü'}, + {name: 'Mike', favoriteLetter: 'Ö'}, + {name: 'Adam', favoriteLetter: 'H'}, + {name: 'Julie', favoriteLetter: 'Z'} + ]; + + $scope.localeSensitiveComparator = function(v1, v2) { + // If we don't get strings, just compare by index + if (v1.type !== 'string' || v2.type !== 'string') { + return (v1.index < v2.index) ? -1 : 1; + } + + // Compare strings alphabetically, taking locale into account + return v1.value.localeCompare(v2.value); + }; + }]); + + + .friends-container { + display: inline-block; + margin: 0 30px; + } + + .friends { + border-collapse: collapse; + } + + .friends th { + border-bottom: 1px solid; + } + .friends td, .friends th { + border-left: 1px solid; + padding: 5px 10px; + } + .friends td:first-child, .friends th:first-child { + border-left: none; + } + + + // Element locators + var container = element(by.css('.custom-comparator')); + var names = container.all(by.repeater('friends').column('friend.name')); + + it('should sort friends by favorite letter (in correct alphabetical order)', function() { + expect(names.get(0).getText()).toBe('John'); + expect(names.get(1).getText()).toBe('Adam'); + expect(names.get(2).getText()).toBe('Mike'); + expect(names.get(3).getText()).toBe('Mary'); + expect(names.get(4).getText()).toBe('Julie'); + }); + +
+ * + */ +orderByFilter.$inject = ['$parse']; +function orderByFilter($parse) { + return function(array, sortPredicate, reverseOrder, compareFn) { + + if (array == null) return array; + if (!isArrayLike(array)) { + throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array); + } + + if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; } + if (sortPredicate.length === 0) { sortPredicate = ['+']; } + + var predicates = processPredicates(sortPredicate); + + var descending = reverseOrder ? -1 : 1; + + // Define the `compare()` function. Use a default comparator if none is specified. + var compare = isFunction(compareFn) ? compareFn : defaultCompare; + + // The next three lines are a version of a Swartzian Transform idiom from Perl + // (sometimes called the Decorate-Sort-Undecorate idiom) + // See https://en.wikipedia.org/wiki/Schwartzian_transform + var compareValues = Array.prototype.map.call(array, getComparisonObject); + compareValues.sort(doComparison); + array = compareValues.map(function(item) { return item.value; }); + + return array; + + function getComparisonObject(value, index) { + // NOTE: We are adding an extra `tieBreaker` value based on the element's index. + // This will be used to keep the sort stable when none of the input predicates can + // distinguish between two elements. + return { + value: value, + tieBreaker: {value: index, type: 'number', index: index}, + predicateValues: predicates.map(function(predicate) { + return getPredicateValue(predicate.get(value), index); + }) + }; + } + + function doComparison(v1, v2) { + for (var i = 0, ii = predicates.length; i < ii; i++) { + var result = compare(v1.predicateValues[i], v2.predicateValues[i]); + if (result) { + return result * predicates[i].descending * descending; + } + } + + return compare(v1.tieBreaker, v2.tieBreaker) * descending; + } + }; + + function processPredicates(sortPredicates) { + return sortPredicates.map(function(predicate) { + var descending = 1, get = identity; + + if (isFunction(predicate)) { + get = predicate; + } else if (isString(predicate)) { + if ((predicate.charAt(0) === '+' || predicate.charAt(0) === '-')) { + descending = predicate.charAt(0) === '-' ? -1 : 1; + predicate = predicate.substring(1); + } + if (predicate !== '') { + get = $parse(predicate); + if (get.constant) { + var key = get(); + get = function(value) { return value[key]; }; + } + } + } + return {get: get, descending: descending}; + }); + } + + function isPrimitive(value) { + switch (typeof value) { + case 'number': /* falls through */ + case 'boolean': /* falls through */ + case 'string': + return true; + default: + return false; + } + } + + function objectValue(value) { + // If `valueOf` is a valid function use that + if (isFunction(value.valueOf)) { + value = value.valueOf(); + if (isPrimitive(value)) return value; + } + // If `toString` is a valid function and not the one from `Object.prototype` use that + if (hasCustomToString(value)) { + value = value.toString(); + if (isPrimitive(value)) return value; + } + + return value; + } + + function getPredicateValue(value, index) { + var type = typeof value; + if (value === null) { + type = 'string'; + value = 'null'; + } else if (type === 'object') { + value = objectValue(value); + } + return {value: value, type: type, index: index}; + } + + function defaultCompare(v1, v2) { + var result = 0; + var type1 = v1.type; + var type2 = v2.type; + + if (type1 === type2) { + var value1 = v1.value; + var value2 = v2.value; + + if (type1 === 'string') { + // Compare strings case-insensitively + value1 = value1.toLowerCase(); + value2 = value2.toLowerCase(); + } else if (type1 === 'object') { + // For basic objects, use the position of the object + // in the collection instead of the value + if (isObject(value1)) value1 = v1.index; + if (isObject(value2)) value2 = v2.index; + } + + if (value1 !== value2) { + result = value1 < value2 ? -1 : 1; + } + } else { + result = type1 < type2 ? -1 : 1; + } + + return result; + } +} + +function ngDirective(directive) { + if (isFunction(directive)) { + directive = { + link: directive + }; + } + directive.restrict = directive.restrict || 'AC'; + return valueFn(directive); +} + +/** + * @ngdoc directive + * @name a + * @restrict E + * + * @description + * Modifies the default behavior of the html a tag so that the default action is prevented when + * the href attribute is empty. + * + * For dynamically creating `href` attributes for a tags, see the {@link ng.ngHref `ngHref`} directive. + */ +var htmlAnchorDirective = valueFn({ + restrict: 'E', + compile: function(element, attr) { + if (!attr.href && !attr.xlinkHref) { + return function(scope, element) { + // If the linked element is not an anchor tag anymore, do nothing + if (element[0].nodeName.toLowerCase() !== 'a') return; + + // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute. + var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ? + 'xlink:href' : 'href'; + element.on('click', function(event) { + // if we have no href url, then don't navigate anywhere. + if (!element.attr(href)) { + event.preventDefault(); + } + }); + }; + } + } +}); + +/** + * @ngdoc directive + * @name ngHref + * @restrict A + * @priority 99 + * + * @description + * Using Angular markup like `{{hash}}` in an href attribute will + * make the link go to the wrong URL if the user clicks it before + * Angular has a chance to replace the `{{hash}}` markup with its + * value. Until Angular replaces the markup the link will be broken + * and will most likely return a 404 error. The `ngHref` directive + * solves this problem. + * + * The wrong way to write it: + * ```html + * link1 + * ``` + * + * The correct way to write it: + * ```html + * link1 + * ``` + * + * @element A + * @param {template} ngHref any string which can contain `{{}}` markup. + * + * @example + * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes + * in links and their different behaviors: + + +
+ link 1 (link, don't reload)
+ link 2 (link, don't reload)
+ link 3 (link, reload!)
+ anchor (link, don't reload)
+ anchor (no link)
+ link (link, change location) +
+ + it('should execute ng-click but not reload when href without value', function() { + element(by.id('link-1')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('1'); + expect(element(by.id('link-1')).getAttribute('href')).toBe(''); + }); + + it('should execute ng-click but not reload when href empty string', function() { + element(by.id('link-2')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('2'); + expect(element(by.id('link-2')).getAttribute('href')).toBe(''); + }); + + it('should execute ng-click and change url when ng-href specified', function() { + expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/); + + element(by.id('link-3')).click(); + + // At this point, we navigate away from an Angular page, so we need + // to use browser.driver to get the base webdriver. + + browser.wait(function() { + return browser.driver.getCurrentUrl().then(function(url) { + return url.match(/\/123$/); + }); + }, 5000, 'page should navigate to /123'); + }); + + it('should execute ng-click but not reload when href empty string and name specified', function() { + element(by.id('link-4')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('4'); + expect(element(by.id('link-4')).getAttribute('href')).toBe(''); + }); + + it('should execute ng-click but not reload when no href but name specified', function() { + element(by.id('link-5')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('5'); + expect(element(by.id('link-5')).getAttribute('href')).toBe(null); + }); + + it('should only change url when only ng-href', function() { + element(by.model('value')).clear(); + element(by.model('value')).sendKeys('6'); + expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/); + + element(by.id('link-6')).click(); + + // At this point, we navigate away from an Angular page, so we need + // to use browser.driver to get the base webdriver. + browser.wait(function() { + return browser.driver.getCurrentUrl().then(function(url) { + return url.match(/\/6$/); + }); + }, 5000, 'page should navigate to /6'); + }); + +
+ */ + +/** + * @ngdoc directive + * @name ngSrc + * @restrict A + * @priority 99 + * + * @description + * Using Angular markup like `{{hash}}` in a `src` attribute doesn't + * work right: The browser will fetch from the URL with the literal + * text `{{hash}}` until Angular replaces the expression inside + * `{{hash}}`. The `ngSrc` directive solves this problem. + * + * The buggy way to write it: + * ```html + * Description + * ``` + * + * The correct way to write it: + * ```html + * Description + * ``` + * + * @element IMG + * @param {template} ngSrc any string which can contain `{{}}` markup. + */ + +/** + * @ngdoc directive + * @name ngSrcset + * @restrict A + * @priority 99 + * + * @description + * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't + * work right: The browser will fetch from the URL with the literal + * text `{{hash}}` until Angular replaces the expression inside + * `{{hash}}`. The `ngSrcset` directive solves this problem. + * + * The buggy way to write it: + * ```html + * Description + * ``` + * + * The correct way to write it: + * ```html + * Description + * ``` + * + * @element IMG + * @param {template} ngSrcset any string which can contain `{{}}` markup. + */ + +/** + * @ngdoc directive + * @name ngDisabled + * @restrict A + * @priority 100 + * + * @description + * + * This directive sets the `disabled` attribute on the element if the + * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy. + * + * A special directive is necessary because we cannot use interpolation inside the `disabled` + * attribute. See the {@link guide/interpolation interpolation guide} for more info. + * + * @example + + +
+ +
+ + it('should toggle button', function() { + expect(element(by.css('button')).getAttribute('disabled')).toBeFalsy(); + element(by.model('checked')).click(); + expect(element(by.css('button')).getAttribute('disabled')).toBeTruthy(); + }); + +
+ * + * @element INPUT + * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy, + * then the `disabled` attribute will be set on the element + */ + + +/** + * @ngdoc directive + * @name ngChecked + * @restrict A + * @priority 100 + * + * @description + * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy. + * + * Note that this directive should not be used together with {@link ngModel `ngModel`}, + * as this can lead to unexpected behavior. + * + * A special directive is necessary because we cannot use interpolation inside the `checked` + * attribute. See the {@link guide/interpolation interpolation guide} for more info. + * + * @example + + +
+ +
+ + it('should check both checkBoxes', function() { + expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy(); + element(by.model('master')).click(); + expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy(); + }); + +
+ * + * @element INPUT + * @param {expression} ngChecked If the {@link guide/expression expression} is truthy, + * then the `checked` attribute will be set on the element + */ + + +/** + * @ngdoc directive + * @name ngReadonly + * @restrict A + * @priority 100 + * + * @description + * + * Sets the `readonly` attribute on the element, if the expression inside `ngReadonly` is truthy. + * Note that `readonly` applies only to `input` elements with specific types. [See the input docs on + * MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) for more information. + * + * A special directive is necessary because we cannot use interpolation inside the `readonly` + * attribute. See the {@link guide/interpolation interpolation guide} for more info. + * + * @example + + +
+ +
+ + it('should toggle readonly attr', function() { + expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeFalsy(); + element(by.model('checked')).click(); + expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeTruthy(); + }); + +
+ * + * @element INPUT + * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy, + * then special attribute "readonly" will be set on the element + */ + + +/** + * @ngdoc directive + * @name ngSelected + * @restrict A + * @priority 100 + * + * @description + * + * Sets the `selected` attribute on the element, if the expression inside `ngSelected` is truthy. + * + * A special directive is necessary because we cannot use interpolation inside the `selected` + * attribute. See the {@link guide/interpolation interpolation guide} for more info. + * + *
+ * **Note:** `ngSelected` does not interact with the `select` and `ngModel` directives, it only + * sets the `selected` attribute on the element. If you are using `ngModel` on the select, you + * should not use `ngSelected` on the options, as `ngModel` will set the select value and + * selected options. + *
+ * + * @example + + +
+ +
+ + it('should select Greetings!', function() { + expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy(); + element(by.model('selected')).click(); + expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy(); + }); + +
+ * + * @element OPTION + * @param {expression} ngSelected If the {@link guide/expression expression} is truthy, + * then special attribute "selected" will be set on the element + */ + +/** + * @ngdoc directive + * @name ngOpen + * @restrict A + * @priority 100 + * + * @description + * + * Sets the `open` attribute on the element, if the expression inside `ngOpen` is truthy. + * + * A special directive is necessary because we cannot use interpolation inside the `open` + * attribute. See the {@link guide/interpolation interpolation guide} for more info. + * + * ## A note about browser compatibility + * + * Edge, Firefox, and Internet Explorer do not support the `details` element, it is + * recommended to use {@link ng.ngShow} and {@link ng.ngHide} instead. + * + * @example + + +
+
+ Show/Hide me +
+
+ + it('should toggle open', function() { + expect(element(by.id('details')).getAttribute('open')).toBeFalsy(); + element(by.model('open')).click(); + expect(element(by.id('details')).getAttribute('open')).toBeTruthy(); + }); + +
+ * + * @element DETAILS + * @param {expression} ngOpen If the {@link guide/expression expression} is truthy, + * then special attribute "open" will be set on the element + */ + +var ngAttributeAliasDirectives = {}; + +// boolean attrs are evaluated +forEach(BOOLEAN_ATTR, function(propName, attrName) { + // binding to multiple is not supported + if (propName === 'multiple') return; + + function defaultLinkFn(scope, element, attr) { + scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) { + attr.$set(attrName, !!value); + }); + } + + var normalized = directiveNormalize('ng-' + attrName); + var linkFn = defaultLinkFn; + + if (propName === 'checked') { + linkFn = function(scope, element, attr) { + // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input + if (attr.ngModel !== attr[normalized]) { + defaultLinkFn(scope, element, attr); + } + }; + } + + ngAttributeAliasDirectives[normalized] = function() { + return { + restrict: 'A', + priority: 100, + link: linkFn + }; + }; +}); + +// aliased input attrs are evaluated +forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) { + ngAttributeAliasDirectives[ngAttr] = function() { + return { + priority: 100, + link: function(scope, element, attr) { + //special case ngPattern when a literal regular expression value + //is used as the expression (this way we don't have to watch anything). + if (ngAttr === 'ngPattern' && attr.ngPattern.charAt(0) === '/') { + var match = attr.ngPattern.match(REGEX_STRING_REGEXP); + if (match) { + attr.$set('ngPattern', new RegExp(match[1], match[2])); + return; + } + } + + scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) { + attr.$set(ngAttr, value); + }); + } + }; + }; +}); + +// ng-src, ng-srcset, ng-href are interpolated +forEach(['src', 'srcset', 'href'], function(attrName) { + var normalized = directiveNormalize('ng-' + attrName); + ngAttributeAliasDirectives[normalized] = function() { + return { + priority: 99, // it needs to run after the attributes are interpolated + link: function(scope, element, attr) { + var propName = attrName, + name = attrName; + + if (attrName === 'href' && + toString.call(element.prop('href')) === '[object SVGAnimatedString]') { + name = 'xlinkHref'; + attr.$attr[name] = 'xlink:href'; + propName = null; + } + + attr.$observe(normalized, function(value) { + if (!value) { + if (attrName === 'href') { + attr.$set(name, null); + } + return; + } + + attr.$set(name, value); + + // Support: IE 9-11 only + // On IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist + // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need + // to set the property as well to achieve the desired effect. + // We use attr[attrName] value since $set can sanitize the url. + if (msie && propName) element.prop(propName, attr[name]); + }); + } + }; + }; +}); + +/* global -nullFormCtrl, -PENDING_CLASS, -SUBMITTED_CLASS + */ +var nullFormCtrl = { + $addControl: noop, + $$renameControl: nullFormRenameControl, + $removeControl: noop, + $setValidity: noop, + $setDirty: noop, + $setPristine: noop, + $setSubmitted: noop +}, +PENDING_CLASS = 'ng-pending', +SUBMITTED_CLASS = 'ng-submitted'; + +function nullFormRenameControl(control, name) { + control.$name = name; +} + +/** + * @ngdoc type + * @name form.FormController + * + * @property {boolean} $pristine True if user has not interacted with the form yet. + * @property {boolean} $dirty True if user has already interacted with the form. + * @property {boolean} $valid True if all of the containing forms and controls are valid. + * @property {boolean} $invalid True if at least one containing control or form is invalid. + * @property {boolean} $pending True if at least one containing control or form is pending. + * @property {boolean} $submitted True if user has submitted the form even if its invalid. + * + * @property {Object} $error Is an object hash, containing references to controls or + * forms with failing validators, where: + * + * - keys are validation tokens (error names), + * - values are arrays of controls or forms that have a failing validator for given error name. + * + * Built-in validation tokens: + * + * - `email` + * - `max` + * - `maxlength` + * - `min` + * - `minlength` + * - `number` + * - `pattern` + * - `required` + * - `url` + * - `date` + * - `datetimelocal` + * - `time` + * - `week` + * - `month` + * + * @description + * `FormController` keeps track of all its controls and nested forms as well as the state of them, + * such as being valid/invalid or dirty/pristine. + * + * Each {@link ng.directive:form form} directive creates an instance + * of `FormController`. + * + */ +//asks for $scope to fool the BC controller module +FormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate']; +function FormController($element, $attrs, $scope, $animate, $interpolate) { + this.$$controls = []; + + // init state + this.$error = {}; + this.$$success = {}; + this.$pending = undefined; + this.$name = $interpolate($attrs.name || $attrs.ngForm || '')($scope); + this.$dirty = false; + this.$pristine = true; + this.$valid = true; + this.$invalid = false; + this.$submitted = false; + this.$$parentForm = nullFormCtrl; + + this.$$element = $element; + this.$$animate = $animate; + + setupValidity(this); +} + +FormController.prototype = { + /** + * @ngdoc method + * @name form.FormController#$rollbackViewValue + * + * @description + * Rollback all form controls pending updates to the `$modelValue`. + * + * Updates may be pending by a debounced event or because the input is waiting for a some future + * event defined in `ng-model-options`. This method is typically needed by the reset button of + * a form that uses `ng-model-options` to pend updates. + */ + $rollbackViewValue: function() { + forEach(this.$$controls, function(control) { + control.$rollbackViewValue(); + }); + }, + + /** + * @ngdoc method + * @name form.FormController#$commitViewValue + * + * @description + * Commit all form controls pending updates to the `$modelValue`. + * + * Updates may be pending by a debounced event or because the input is waiting for a some future + * event defined in `ng-model-options`. This method is rarely needed as `NgModelController` + * usually handles calling this in response to input events. + */ + $commitViewValue: function() { + forEach(this.$$controls, function(control) { + control.$commitViewValue(); + }); + }, + + /** + * @ngdoc method + * @name form.FormController#$addControl + * @param {object} control control object, either a {@link form.FormController} or an + * {@link ngModel.NgModelController} + * + * @description + * Register a control with the form. Input elements using ngModelController do this automatically + * when they are linked. + * + * Note that the current state of the control will not be reflected on the new parent form. This + * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine` + * state. + * + * However, if the method is used programmatically, for example by adding dynamically created controls, + * or controls that have been previously removed without destroying their corresponding DOM element, + * it's the developers responsibility to make sure the current state propagates to the parent form. + * + * For example, if an input control is added that is already `$dirty` and has `$error` properties, + * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form. + */ + $addControl: function(control) { + // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored + // and not added to the scope. Now we throw an error. + assertNotHasOwnProperty(control.$name, 'input'); + this.$$controls.push(control); + + if (control.$name) { + this[control.$name] = control; + } + + control.$$parentForm = this; + }, + + // Private API: rename a form control + $$renameControl: function(control, newName) { + var oldName = control.$name; + + if (this[oldName] === control) { + delete this[oldName]; + } + this[newName] = control; + control.$name = newName; + }, + + /** + * @ngdoc method + * @name form.FormController#$removeControl + * @param {object} control control object, either a {@link form.FormController} or an + * {@link ngModel.NgModelController} + * + * @description + * Deregister a control from the form. + * + * Input elements using ngModelController do this automatically when they are destroyed. + * + * Note that only the removed control's validation state (`$errors`etc.) will be removed from the + * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be + * different from case to case. For example, removing the only `$dirty` control from a form may or + * may not mean that the form is still `$dirty`. + */ + $removeControl: function(control) { + if (control.$name && this[control.$name] === control) { + delete this[control.$name]; + } + forEach(this.$pending, function(value, name) { + // eslint-disable-next-line no-invalid-this + this.$setValidity(name, null, control); + }, this); + forEach(this.$error, function(value, name) { + // eslint-disable-next-line no-invalid-this + this.$setValidity(name, null, control); + }, this); + forEach(this.$$success, function(value, name) { + // eslint-disable-next-line no-invalid-this + this.$setValidity(name, null, control); + }, this); + + arrayRemove(this.$$controls, control); + control.$$parentForm = nullFormCtrl; + }, + + /** + * @ngdoc method + * @name form.FormController#$setDirty + * + * @description + * Sets the form to a dirty state. + * + * This method can be called to add the 'ng-dirty' class and set the form to a dirty + * state (ng-dirty class). This method will also propagate to parent forms. + */ + $setDirty: function() { + this.$$animate.removeClass(this.$$element, PRISTINE_CLASS); + this.$$animate.addClass(this.$$element, DIRTY_CLASS); + this.$dirty = true; + this.$pristine = false; + this.$$parentForm.$setDirty(); + }, + + /** + * @ngdoc method + * @name form.FormController#$setPristine + * + * @description + * Sets the form to its pristine state. + * + * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes + * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted` + * state to false. + * + * This method will also propagate to all the controls contained in this form. + * + * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after + * saving or resetting it. + */ + $setPristine: function() { + this.$$animate.setClass(this.$$element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS); + this.$dirty = false; + this.$pristine = true; + this.$submitted = false; + forEach(this.$$controls, function(control) { + control.$setPristine(); + }); + }, + + /** + * @ngdoc method + * @name form.FormController#$setUntouched + * + * @description + * Sets the form to its untouched state. + * + * This method can be called to remove the 'ng-touched' class and set the form controls to their + * untouched state (ng-untouched class). + * + * Setting a form controls back to their untouched state is often useful when setting the form + * back to its pristine state. + */ + $setUntouched: function() { + forEach(this.$$controls, function(control) { + control.$setUntouched(); + }); + }, + + /** + * @ngdoc method + * @name form.FormController#$setSubmitted + * + * @description + * Sets the form to its submitted state. + */ + $setSubmitted: function() { + this.$$animate.addClass(this.$$element, SUBMITTED_CLASS); + this.$submitted = true; + this.$$parentForm.$setSubmitted(); + } +}; + +/** + * @ngdoc method + * @name form.FormController#$setValidity + * + * @description + * Sets the validity of a form control. + * + * This method will also propagate to parent forms. + */ +addSetValidityMethod({ + clazz: FormController, + set: function(object, property, controller) { + var list = object[property]; + if (!list) { + object[property] = [controller]; + } else { + var index = list.indexOf(controller); + if (index === -1) { + list.push(controller); + } + } + }, + unset: function(object, property, controller) { + var list = object[property]; + if (!list) { + return; + } + arrayRemove(list, controller); + if (list.length === 0) { + delete object[property]; + } + } +}); + +/** + * @ngdoc directive + * @name ngForm + * @restrict EAC + * + * @description + * Nestable alias of {@link ng.directive:form `form`} directive. HTML + * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a + * sub-group of controls needs to be determined. + * + * Note: the purpose of `ngForm` is to group controls, + * but not to be a replacement for the `
` tag with all of its capabilities + * (e.g. posting to the server, ...). + * + * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + * + */ + + /** + * @ngdoc directive + * @name form + * @restrict E + * + * @description + * Directive that instantiates + * {@link form.FormController FormController}. + * + * If the `name` attribute is specified, the form controller is published onto the current scope under + * this name. + * + * # Alias: {@link ng.directive:ngForm `ngForm`} + * + * In Angular, forms can be nested. This means that the outer form is valid when all of the child + * forms are valid as well. However, browsers do not allow nesting of `` elements, so + * Angular provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to + * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group + * of controls needs to be determined. + * + * # CSS classes + * - `ng-valid` is set if the form is valid. + * - `ng-invalid` is set if the form is invalid. + * - `ng-pending` is set if the form is pending. + * - `ng-pristine` is set if the form is pristine. + * - `ng-dirty` is set if the form is dirty. + * - `ng-submitted` is set if the form was submitted. + * + * Keep in mind that ngAnimate can detect each of these classes when added and removed. + * + * + * # Submitting a form and preventing the default action + * + * Since the role of forms in client-side Angular applications is different than in classical + * roundtrip apps, it is desirable for the browser not to translate the form submission into a full + * page reload that sends the data to the server. Instead some javascript logic should be triggered + * to handle the form submission in an application-specific way. + * + * For this reason, Angular prevents the default action (form submission to the server) unless the + * `` element has an `action` attribute specified. + * + * You can use one of the following two ways to specify what javascript method should be called when + * a form is submitted: + * + * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element + * - {@link ng.directive:ngClick ngClick} directive on the first + * button or input field of type submit (input[type=submit]) + * + * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit} + * or {@link ng.directive:ngClick ngClick} directives. + * This is because of the following form submission rules in the HTML specification: + * + * - If a form has only one input field then hitting enter in this field triggers form submit + * (`ngSubmit`) + * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter + * doesn't trigger submit + * - if a form has one or more input fields and one or more buttons or input[type=submit] then + * hitting enter in any of the input fields will trigger the click handler on the *first* button or + * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`) + * + * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is + * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit` + * to have access to the updated model. + * + * ## Animation Hooks + * + * Animations in ngForm are triggered when any of the associated CSS classes are added and removed. + * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any + * other validations that are performed within the form. Animations in ngForm are similar to how + * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well + * as JS animations. + * + * The following example shows a simple way to utilize CSS transitions to style a form element + * that has been rendered as invalid after it has been validated: + * + *
+ * //be sure to include ngAnimate as a module to hook into more
+ * //advanced animations
+ * .my-form {
+ *   transition:0.5s linear all;
+ *   background: white;
+ * }
+ * .my-form.ng-invalid {
+ *   background: red;
+ *   color:white;
+ * }
+ * 
+ * + * @example + + + + + + userType: + Required!
+ userType = {{userType}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ +
+ + it('should initialize to model', function() { + var userType = element(by.binding('userType')); + var valid = element(by.binding('myForm.input.$valid')); + + expect(userType.getText()).toContain('guest'); + expect(valid.getText()).toContain('true'); + }); + + it('should be invalid if empty', function() { + var userType = element(by.binding('userType')); + var valid = element(by.binding('myForm.input.$valid')); + var userInput = element(by.model('userType')); + + userInput.clear(); + userInput.sendKeys(''); + + expect(userType.getText()).toEqual('userType ='); + expect(valid.getText()).toContain('false'); + }); + +
+ * + * @param {string=} name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + */ +var formDirectiveFactory = function(isNgForm) { + return ['$timeout', '$parse', function($timeout, $parse) { + var formDirective = { + name: 'form', + restrict: isNgForm ? 'EAC' : 'E', + require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form + controller: FormController, + compile: function ngFormCompile(formElement, attr) { + // Setup initial state of the control + formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS); + + var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false); + + return { + pre: function ngFormPreLink(scope, formElement, attr, ctrls) { + var controller = ctrls[0]; + + // if `action` attr is not present on the form, prevent the default action (submission) + if (!('action' in attr)) { + // we can't use jq events because if a form is destroyed during submission the default + // action is not prevented. see #1238 + // + // IE 9 is not affected because it doesn't fire a submit event and try to do a full + // page reload if the form was destroyed by submission of the form via a click handler + // on a button in the form. Looks like an IE9 specific bug. + var handleFormSubmission = function(event) { + scope.$apply(function() { + controller.$commitViewValue(); + controller.$setSubmitted(); + }); + + event.preventDefault(); + }; + + formElement[0].addEventListener('submit', handleFormSubmission); + + // unregister the preventDefault listener so that we don't not leak memory but in a + // way that will achieve the prevention of the default action. + formElement.on('$destroy', function() { + $timeout(function() { + formElement[0].removeEventListener('submit', handleFormSubmission); + }, 0, false); + }); + } + + var parentFormCtrl = ctrls[1] || controller.$$parentForm; + parentFormCtrl.$addControl(controller); + + var setter = nameAttr ? getSetter(controller.$name) : noop; + + if (nameAttr) { + setter(scope, controller); + attr.$observe(nameAttr, function(newValue) { + if (controller.$name === newValue) return; + setter(scope, undefined); + controller.$$parentForm.$$renameControl(controller, newValue); + setter = getSetter(controller.$name); + setter(scope, controller); + }); + } + formElement.on('$destroy', function() { + controller.$$parentForm.$removeControl(controller); + setter(scope, undefined); + extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards + }); + } + }; + } + }; + + return formDirective; + + function getSetter(expression) { + if (expression === '') { + //create an assignable expression, so forms with an empty name can be renamed later + return $parse('this[""]').assign; + } + return $parse(expression).assign || noop; + } + }]; +}; + +var formDirective = formDirectiveFactory(); +var ngFormDirective = formDirectiveFactory(true); + + + +// helper methods +function setupValidity(instance) { + instance.$$classCache = {}; + instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS)); +} +function addSetValidityMethod(context) { + var clazz = context.clazz, + set = context.set, + unset = context.unset; + + clazz.prototype.$setValidity = function(validationErrorKey, state, controller) { + if (isUndefined(state)) { + createAndSet(this, '$pending', validationErrorKey, controller); + } else { + unsetAndCleanup(this, '$pending', validationErrorKey, controller); + } + if (!isBoolean(state)) { + unset(this.$error, validationErrorKey, controller); + unset(this.$$success, validationErrorKey, controller); + } else { + if (state) { + unset(this.$error, validationErrorKey, controller); + set(this.$$success, validationErrorKey, controller); + } else { + set(this.$error, validationErrorKey, controller); + unset(this.$$success, validationErrorKey, controller); + } + } + if (this.$pending) { + cachedToggleClass(this, PENDING_CLASS, true); + this.$valid = this.$invalid = undefined; + toggleValidationCss(this, '', null); + } else { + cachedToggleClass(this, PENDING_CLASS, false); + this.$valid = isObjectEmpty(this.$error); + this.$invalid = !this.$valid; + toggleValidationCss(this, '', this.$valid); + } + + // re-read the state as the set/unset methods could have + // combined state in this.$error[validationError] (used for forms), + // where setting/unsetting only increments/decrements the value, + // and does not replace it. + var combinedState; + if (this.$pending && this.$pending[validationErrorKey]) { + combinedState = undefined; + } else if (this.$error[validationErrorKey]) { + combinedState = false; + } else if (this.$$success[validationErrorKey]) { + combinedState = true; + } else { + combinedState = null; + } + + toggleValidationCss(this, validationErrorKey, combinedState); + this.$$parentForm.$setValidity(validationErrorKey, combinedState, this); + }; + + function createAndSet(ctrl, name, value, controller) { + if (!ctrl[name]) { + ctrl[name] = {}; + } + set(ctrl[name], value, controller); + } + + function unsetAndCleanup(ctrl, name, value, controller) { + if (ctrl[name]) { + unset(ctrl[name], value, controller); + } + if (isObjectEmpty(ctrl[name])) { + ctrl[name] = undefined; + } + } + + function cachedToggleClass(ctrl, className, switchValue) { + if (switchValue && !ctrl.$$classCache[className]) { + ctrl.$$animate.addClass(ctrl.$$element, className); + ctrl.$$classCache[className] = true; + } else if (!switchValue && ctrl.$$classCache[className]) { + ctrl.$$animate.removeClass(ctrl.$$element, className); + ctrl.$$classCache[className] = false; + } + } + + function toggleValidationCss(ctrl, validationErrorKey, isValid) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + + cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true); + cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false); + } +} + +function isObjectEmpty(obj) { + if (obj) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + return false; + } + } + } + return true; +} + +/* global + VALID_CLASS: false, + INVALID_CLASS: false, + PRISTINE_CLASS: false, + DIRTY_CLASS: false, + ngModelMinErr: false +*/ + +// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 +var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/; +// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987) +// Note: We are being more lenient, because browsers are too. +// 1. Scheme +// 2. Slashes +// 3. Username +// 4. Password +// 5. Hostname +// 6. Port +// 7. Path +// 8. Query +// 9. Fragment +// 1111111111111111 222 333333 44444 55555555555555555555555 666 77777777 8888888 999 +var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i; +// eslint-disable-next-line max-len +var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/; +var NUMBER_REGEXP = /^\s*(-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/; +var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/; +var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; +var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/; +var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/; +var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; + +var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown'; +var PARTIAL_VALIDATION_TYPES = createMap(); +forEach('date,datetime-local,month,time,week'.split(','), function(type) { + PARTIAL_VALIDATION_TYPES[type] = true; +}); + +var inputType = { + + /** + * @ngdoc input + * @name input[text] + * + * @description + * Standard HTML text input with angular data binding, inherited by most of the `input` elements. + * + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Adds `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * This parameter is ignored for input[type=password] controls, which will never trim the + * input. + * + * @example + + + +
+ +
+ + Required! + + Single word only! +
+ text = {{example.text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var text = element(by.binding('example.text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('example.text')); + + it('should initialize to model', function() { + expect(text.getText()).toContain('guest'); + expect(valid.getText()).toContain('true'); + }); + + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); + + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); + }); + + it('should be invalid if multi word', function() { + input.clear(); + input.sendKeys('hello world'); + + expect(valid.getText()).toContain('false'); + }); + +
+ */ + 'text': textInputType, + + /** + * @ngdoc input + * @name input[date] + * + * @description + * Input with date validation and transformation. In browsers that do not yet support + * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601 + * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many + * modern browsers do not yet support this input type, it is important to provide cues to users on the + * expected input format via a placeholder or label. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a + * valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute + * (e.g. `min="{{minDate | date:'yyyy-MM-dd'}}"`). Note that `min` will also add native HTML5 + * constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be + * a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute + * (e.g. `max="{{maxDate | date:'yyyy-MM-dd'}}"`). Note that `max` will also add native HTML5 + * constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "yyyy-MM-dd"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-MM-dd"')); + var valid = element(by.binding('myForm.input.$valid')); + + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (see https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } + + it('should initialize to model', function() { + expect(value.getText()).toContain('2013-10-22'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); + + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + + it('should be invalid if over max', function() { + setInput('2015-01-01'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'date': createDateInputType('date', DATE_REGEXP, + createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']), + 'yyyy-MM-dd'), + + /** + * @ngdoc input + * @name input[datetime-local] + * + * @description + * Input with datetime validation and transformation. In browsers that do not yet support + * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation + * inside this attribute (e.g. `min="{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`). + * Note that `min` will also add native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation + * inside this attribute (e.g. `max="{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`). + * Note that `max` will also add native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"')); + var valid = element(by.binding('myForm.input.$valid')); + + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } + + it('should initialize to model', function() { + expect(value.getText()).toContain('2010-12-28T14:57:00'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); + + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + + it('should be invalid if over max', function() { + setInput('2015-01-01T23:59:00'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP, + createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']), + 'yyyy-MM-ddTHH:mm:ss.sss'), + + /** + * @ngdoc input + * @name input[time] + * + * @description + * Input with time validation and transformation. In browsers that do not yet support + * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a + * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this + * attribute (e.g. `min="{{minTime | date:'HH:mm:ss'}}"`). Note that `min` will also add + * native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this + * attribute (e.g. `max="{{maxTime | date:'HH:mm:ss'}}"`). Note that `max` will also add + * native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the + * `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the + * `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "HH:mm:ss"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "HH:mm:ss"')); + var valid = element(by.binding('myForm.input.$valid')); + + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } + + it('should initialize to model', function() { + expect(value.getText()).toContain('14:57:00'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); + + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + + it('should be invalid if over max', function() { + setInput('23:59:00'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'time': createDateInputType('time', TIME_REGEXP, + createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']), + 'HH:mm:ss.sss'), + + /** + * @ngdoc input + * @name input[week] + * + * @description + * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support + * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * week format (yyyy-W##), for example: `2013-W02`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this + * attribute (e.g. `min="{{minWeek | date:'yyyy-Www'}}"`). Note that `min` will also add + * native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this + * attribute (e.g. `max="{{maxWeek | date:'yyyy-Www'}}"`). Note that `max` will also add + * native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "yyyy-Www"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-Www"')); + var valid = element(by.binding('myForm.input.$valid')); + + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } + + it('should initialize to model', function() { + expect(value.getText()).toContain('2013-W01'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); + + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + + it('should be invalid if over max', function() { + setInput('2015-W01'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'), + + /** + * @ngdoc input + * @name input[month] + * + * @description + * Input with month validation and transformation. In browsers that do not yet support + * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * month format (yyyy-MM), for example: `2009-01`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * If the model is not set to the first of the month, the next view to model update will set it + * to the first of the month. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this + * attribute (e.g. `min="{{minMonth | date:'yyyy-MM'}}"`). Note that `min` will also add + * native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this + * attribute (e.g. `max="{{maxMonth | date:'yyyy-MM'}}"`). Note that `max` will also add + * native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid month! +
+ value = {{example.value | date: "yyyy-MM"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-MM"')); + var valid = element(by.binding('myForm.input.$valid')); + + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } + + it('should initialize to model', function() { + expect(value.getText()).toContain('2013-10'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); + + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + + it('should be invalid if over max', function() { + setInput('2015-01'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'month': createDateInputType('month', MONTH_REGEXP, + createDateParser(MONTH_REGEXP, ['yyyy', 'MM']), + 'yyyy-MM'), + + /** + * @ngdoc input + * @name input[number] + * + * @description + * Text input with number validation and transformation. Sets the `number` validation + * error if not a valid number. + * + *
+ * The model must always be of type `number` otherwise Angular will throw an error. + * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt} + * error docs for more information and an example of how to convert your model if necessary. + *
+ * + * ## Issues with HTML5 constraint validation + * + * In browsers that follow the + * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29), + * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}. + * If a non-number is entered in the input, the browser will report the value as an empty string, + * which means the view / model values in `ngModel` and subsequently the scope value + * will also be an empty string. + * + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * Can be interpolated. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * Can be interpolated. + * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`, + * but does not trigger HTML5 native validation. Takes an expression. + * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`, + * but does not trigger HTML5 native validation. Takes an expression. + * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint. + * Can be interpolated. + * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint, + * but does not trigger HTML5 native validation. Takes an expression. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ +
+ + Required! + + Not valid number! +
+ value = {{example.value}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('example.value')); + + it('should initialize to model', function() { + expect(value.getText()).toContain('12'); + expect(valid.getText()).toContain('true'); + }); + + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('false'); + }); + + it('should be invalid if over max', function() { + input.clear(); + input.sendKeys('123'); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('false'); + }); + +
+ */ + 'number': numberInputType, + + + /** + * @ngdoc input + * @name input[url] + * + * @description + * Text input with URL validation. Sets the `url` validation error key if the content is not a + * valid URL. + * + *
+ * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex + * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify + * the built-in validators (see the {@link guide/forms Forms guide}) + *
+ * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+
+ + var text = element(by.binding('url.text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('url.text')); + + it('should initialize to model', function() { + expect(text.getText()).toContain('http://google.com'); + expect(valid.getText()).toContain('true'); + }); + + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); + + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); + }); + + it('should be invalid if not url', function() { + input.clear(); + input.sendKeys('box'); + + expect(valid.getText()).toContain('false'); + }); + +
+ */ + 'url': urlInputType, + + + /** + * @ngdoc input + * @name input[email] + * + * @description + * Text input with email validation. Sets the `email` validation error key if not a valid email + * address. + * + *
+ * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex + * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can + * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide}) + *
+ * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ +
+ + Required! + + Not valid email! +
+ text = {{email.text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ myForm.$error.email = {{!!myForm.$error.email}}
+
+
+ + var text = element(by.binding('email.text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('email.text')); + + it('should initialize to model', function() { + expect(text.getText()).toContain('me@example.com'); + expect(valid.getText()).toContain('true'); + }); + + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); + }); + + it('should be invalid if not email', function() { + input.clear(); + input.sendKeys('xxx'); + + expect(valid.getText()).toContain('false'); + }); + +
+ */ + 'email': emailInputType, + + + /** + * @ngdoc input + * @name input[radio] + * + * @description + * HTML radio button. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string} value The value to which the `ngModel` expression should be set when selected. + * Note that `value` only supports `string` values, i.e. the scope model needs to be a string, + * too. Use `ngValue` if you need complex models (`number`, `object`, ...). + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio + * is selected. Should be used instead of the `value` attribute if you need + * a non-string `ngModel` (`boolean`, `array`, ...). + * + * @example + + + +
+
+
+
+ color = {{color.name | json}}
+
+ Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`. +
+ + it('should change state', function() { + var inputs = element.all(by.model('color.name')); + var color = element(by.binding('color.name')); + + expect(color.getText()).toContain('blue'); + + inputs.get(0).click(); + expect(color.getText()).toContain('red'); + + inputs.get(1).click(); + expect(color.getText()).toContain('green'); + }); + +
+ */ + 'radio': radioInputType, + + /** + * @ngdoc input + * @name input[range] + * + * @description + * Native range input with validation and transformation. + * + * The model for the range input must always be a `Number`. + * + * IE9 and other browsers that do not support the `range` type fall back + * to a text input without any default values for `min`, `max` and `step`. Model binding, + * validation and number parsing are nevertheless supported. + * + * Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]` + * in a way that never allows the input to hold an invalid value. That means: + * - any non-numerical value is set to `(max + min) / 2`. + * - any numerical value that is less than the current min val, or greater than the current max val + * is set to the min / max val respectively. + * - additionally, the current `step` is respected, so the nearest value that satisfies a step + * is used. + * + * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range)) + * for more info. + * + * This has the following consequences for Angular: + * + * Since the element value should always reflect the current model value, a range input + * will set the bound ngModel expression to the value that the browser has set for the + * input element. For example, in the following input ``, + * if the application sets `model.value = null`, the browser will set the input to `'50'`. + * Angular will then set the model to `50`, to prevent input and model value being out of sync. + * + * That means the model for range will immediately be set to `50` after `ngModel` has been + * initialized. It also means a range input can never have the required error. + * + * This does not only affect changes to the model value, but also to the values of the `min`, + * `max`, and `step` attributes. When these change in a way that will cause the browser to modify + * the input value, Angular will also update the model value. + * + * Automatic value adjustment also means that a range input element can never have the `required`, + * `min`, or `max` errors. + * + * However, `step` is currently only fully implemented by Firefox. Other browsers have problems + * when the step value changes dynamically - they do not adjust the element value correctly, but + * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step` + * error on the input, and set the model to `undefined`. + * + * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do + * not set the `min` and `max` attributes, which means that the browser won't automatically adjust + * the input value based on their values, and will always assume min = 0, max = 100, and step = 1. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation to ensure that the value entered is greater + * than `min`. Can be interpolated. + * @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`. + * Can be interpolated. + * @param {string=} step Sets the `step` validation to ensure that the value entered matches the `step` + * Can be interpolated. + * @param {string=} ngChange Angular expression to be executed when the ngModel value changes due + * to user interaction with the input element. + * @param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the + * element. **Note** : `ngChecked` should not be used alongside `ngModel`. + * Checkout {@link ng.directive:ngChecked ngChecked} for usage. + * + * @example + + + +
+ + Model as range: +
+ Model as number:
+ Min:
+ Max:
+ value = {{value}}
+ myForm.range.$valid = {{myForm.range.$valid}}
+ myForm.range.$error = {{myForm.range.$error}} +
+
+
+ + * ## Range Input with ngMin & ngMax attributes + + * @example + + + +
+ Model as range: +
+ Model as number:
+ Min:
+ Max:
+ value = {{value}}
+ myForm.range.$valid = {{myForm.range.$valid}}
+ myForm.range.$error = {{myForm.range.$error}} +
+
+
+ + */ + 'range': rangeInputType, + + /** + * @ngdoc input + * @name input[checkbox] + * + * @description + * HTML checkbox. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {expression=} ngTrueValue The value to which the expression should be set when selected. + * @param {expression=} ngFalseValue The value to which the expression should be set when not selected. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+
+
+ value1 = {{checkboxModel.value1}}
+ value2 = {{checkboxModel.value2}}
+
+
+ + it('should change state', function() { + var value1 = element(by.binding('checkboxModel.value1')); + var value2 = element(by.binding('checkboxModel.value2')); + + expect(value1.getText()).toContain('true'); + expect(value2.getText()).toContain('YES'); + + element(by.model('checkboxModel.value1')).click(); + element(by.model('checkboxModel.value2')).click(); + + expect(value1.getText()).toContain('false'); + expect(value2.getText()).toContain('NO'); + }); + +
+ */ + 'checkbox': checkboxInputType, + + 'hidden': noop, + 'button': noop, + 'submit': noop, + 'reset': noop, + 'file': noop +}; + +function stringBasedInputType(ctrl) { + ctrl.$formatters.push(function(value) { + return ctrl.$isEmpty(value) ? value : value.toString(); + }); +} + +function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + stringBasedInputType(ctrl); +} + +function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { + var type = lowercase(element[0].type); + + // In composition mode, users are still inputting intermediate text buffer, + // hold the listener until composition is done. + // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent + if (!$sniffer.android) { + var composing = false; + + element.on('compositionstart', function() { + composing = true; + }); + + element.on('compositionend', function() { + composing = false; + listener(); + }); + } + + var timeout; + + var listener = function(ev) { + if (timeout) { + $browser.defer.cancel(timeout); + timeout = null; + } + if (composing) return; + var value = element.val(), + event = ev && ev.type; + + // By default we will trim the value + // If the attribute ng-trim exists we will avoid trimming + // If input type is 'password', the value is never trimmed + if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) { + value = trim(value); + } + + // If a control is suffering from bad input (due to native validators), browsers discard its + // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the + // control's value is the same empty value twice in a row. + if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) { + ctrl.$setViewValue(value, event); + } + }; + + // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the + // input event on backspace, delete or cut + if ($sniffer.hasEvent('input')) { + element.on('input', listener); + } else { + var deferListener = function(ev, input, origValue) { + if (!timeout) { + timeout = $browser.defer(function() { + timeout = null; + if (!input || input.value !== origValue) { + listener(ev); + } + }); + } + }; + + element.on('keydown', /** @this */ function(event) { + var key = event.keyCode; + + // ignore + // command modifiers arrows + if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; + + deferListener(event, this, this.value); + }); + + // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it + if ($sniffer.hasEvent('paste')) { + element.on('paste cut', deferListener); + } + } + + // if user paste into input using mouse on older browser + // or form autocomplete on newer browser, we need "change" event to catch it + element.on('change', listener); + + // Some native input types (date-family) have the ability to change validity without + // firing any input/change events. + // For these event types, when native validators are present and the browser supports the type, + // check for validity changes on various DOM events. + if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) { + element.on(PARTIAL_VALIDATION_EVENTS, /** @this */ function(ev) { + if (!timeout) { + var validity = this[VALIDITY_STATE_PROPERTY]; + var origBadInput = validity.badInput; + var origTypeMismatch = validity.typeMismatch; + timeout = $browser.defer(function() { + timeout = null; + if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) { + listener(ev); + } + }); + } + }); + } + + ctrl.$render = function() { + // Workaround for Firefox validation #12102. + var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue; + if (element.val() !== value) { + element.val(value); + } + }; +} + +function weekParser(isoWeek, existingDate) { + if (isDate(isoWeek)) { + return isoWeek; + } + + if (isString(isoWeek)) { + WEEK_REGEXP.lastIndex = 0; + var parts = WEEK_REGEXP.exec(isoWeek); + if (parts) { + var year = +parts[1], + week = +parts[2], + hours = 0, + minutes = 0, + seconds = 0, + milliseconds = 0, + firstThurs = getFirstThursdayOfYear(year), + addDays = (week - 1) * 7; + + if (existingDate) { + hours = existingDate.getHours(); + minutes = existingDate.getMinutes(); + seconds = existingDate.getSeconds(); + milliseconds = existingDate.getMilliseconds(); + } + + return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds); + } + } + + return NaN; +} + +function createDateParser(regexp, mapping) { + return function(iso, date) { + var parts, map; + + if (isDate(iso)) { + return iso; + } + + if (isString(iso)) { + // When a date is JSON'ified to wraps itself inside of an extra + // set of double quotes. This makes the date parsing code unable + // to match the date string and parse it as a date. + if (iso.charAt(0) === '"' && iso.charAt(iso.length - 1) === '"') { + iso = iso.substring(1, iso.length - 1); + } + if (ISO_DATE_REGEXP.test(iso)) { + return new Date(iso); + } + regexp.lastIndex = 0; + parts = regexp.exec(iso); + + if (parts) { + parts.shift(); + if (date) { + map = { + yyyy: date.getFullYear(), + MM: date.getMonth() + 1, + dd: date.getDate(), + HH: date.getHours(), + mm: date.getMinutes(), + ss: date.getSeconds(), + sss: date.getMilliseconds() / 1000 + }; + } else { + map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 }; + } + + forEach(parts, function(part, index) { + if (index < mapping.length) { + map[mapping[index]] = +part; + } + }); + return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0); + } + } + + return NaN; + }; +} + +function createDateInputType(type, regexp, parseDate, format) { + return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) { + badInputChecker(scope, element, attr, ctrl); + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + var timezone = ctrl && ctrl.$options.getOption('timezone'); + var previousDate; + + ctrl.$$parserName = type; + ctrl.$parsers.push(function(value) { + if (ctrl.$isEmpty(value)) return null; + if (regexp.test(value)) { + // Note: We cannot read ctrl.$modelValue, as there might be a different + // parser/formatter in the processing chain so that the model + // contains some different data format! + var parsedDate = parseDate(value, previousDate); + if (timezone) { + parsedDate = convertTimezoneToLocal(parsedDate, timezone); + } + return parsedDate; + } + return undefined; + }); + + ctrl.$formatters.push(function(value) { + if (value && !isDate(value)) { + throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value); + } + if (isValidDate(value)) { + previousDate = value; + if (previousDate && timezone) { + previousDate = convertTimezoneToLocal(previousDate, timezone, true); + } + return $filter('date')(value, format, timezone); + } else { + previousDate = null; + return ''; + } + }); + + if (isDefined(attr.min) || attr.ngMin) { + var minVal; + ctrl.$validators.min = function(value) { + return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal; + }; + attr.$observe('min', function(val) { + minVal = parseObservedDateValue(val); + ctrl.$validate(); + }); + } + + if (isDefined(attr.max) || attr.ngMax) { + var maxVal; + ctrl.$validators.max = function(value) { + return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal; + }; + attr.$observe('max', function(val) { + maxVal = parseObservedDateValue(val); + ctrl.$validate(); + }); + } + + function isValidDate(value) { + // Invalid Date: getTime() returns NaN + return value && !(value.getTime && value.getTime() !== value.getTime()); + } + + function parseObservedDateValue(val) { + return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val; + } + }; +} + +function badInputChecker(scope, element, attr, ctrl) { + var node = element[0]; + var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity); + if (nativeValidation) { + ctrl.$parsers.push(function(value) { + var validity = element.prop(VALIDITY_STATE_PROPERTY) || {}; + return validity.badInput || validity.typeMismatch ? undefined : value; + }); + } +} + +function numberFormatterParser(ctrl) { + ctrl.$$parserName = 'number'; + ctrl.$parsers.push(function(value) { + if (ctrl.$isEmpty(value)) return null; + if (NUMBER_REGEXP.test(value)) return parseFloat(value); + return undefined; + }); + + ctrl.$formatters.push(function(value) { + if (!ctrl.$isEmpty(value)) { + if (!isNumber(value)) { + throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value); + } + value = value.toString(); + } + return value; + }); +} + +function parseNumberAttrVal(val) { + if (isDefined(val) && !isNumber(val)) { + val = parseFloat(val); + } + return !isNumberNaN(val) ? val : undefined; +} + +function isNumberInteger(num) { + // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066 + // (minus the assumption that `num` is a number) + + // eslint-disable-next-line no-bitwise + return (num | 0) === num; +} + +function countDecimals(num) { + var numString = num.toString(); + var decimalSymbolIndex = numString.indexOf('.'); + + if (decimalSymbolIndex === -1) { + if (-1 < num && num < 1) { + // It may be in the exponential notation format (`1e-X`) + var match = /e-(\d+)$/.exec(numString); + + if (match) { + return Number(match[1]); + } + } + + return 0; + } + + return numString.length - decimalSymbolIndex - 1; +} + +function isValidForStep(viewValue, stepBase, step) { + // At this point `stepBase` and `step` are expected to be non-NaN values + // and `viewValue` is expected to be a valid stringified number. + var value = Number(viewValue); + + // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or + // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers. + if (!isNumberInteger(value) || !isNumberInteger(stepBase) || !isNumberInteger(step)) { + var decimalCount = Math.max(countDecimals(value), countDecimals(stepBase), countDecimals(step)); + var multiplier = Math.pow(10, decimalCount); + + value = value * multiplier; + stepBase = stepBase * multiplier; + step = step * multiplier; + } + + return (value - stepBase) % step === 0; +} + +function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { + badInputChecker(scope, element, attr, ctrl); + numberFormatterParser(ctrl); + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var minVal; + var maxVal; + + if (isDefined(attr.min) || attr.ngMin) { + ctrl.$validators.min = function(value) { + return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; + }; + + attr.$observe('min', function(val) { + minVal = parseNumberAttrVal(val); + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); + } + + if (isDefined(attr.max) || attr.ngMax) { + ctrl.$validators.max = function(value) { + return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; + }; + + attr.$observe('max', function(val) { + maxVal = parseNumberAttrVal(val); + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); + } + + if (isDefined(attr.step) || attr.ngStep) { + var stepVal; + ctrl.$validators.step = function(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) || + isValidForStep(viewValue, minVal || 0, stepVal); + }; + + attr.$observe('step', function(val) { + stepVal = parseNumberAttrVal(val); + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); + } +} + +function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) { + badInputChecker(scope, element, attr, ctrl); + numberFormatterParser(ctrl); + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range', + minVal = supportsRange ? 0 : undefined, + maxVal = supportsRange ? 100 : undefined, + stepVal = supportsRange ? 1 : undefined, + validity = element[0].validity, + hasMinAttr = isDefined(attr.min), + hasMaxAttr = isDefined(attr.max), + hasStepAttr = isDefined(attr.step); + + var originalRender = ctrl.$render; + + ctrl.$render = supportsRange && isDefined(validity.rangeUnderflow) && isDefined(validity.rangeOverflow) ? + //Browsers that implement range will set these values automatically, but reading the adjusted values after + //$render would cause the min / max validators to be applied with the wrong value + function rangeRender() { + originalRender(); + ctrl.$setViewValue(element.val()); + } : + originalRender; + + if (hasMinAttr) { + ctrl.$validators.min = supportsRange ? + // Since all browsers set the input to a valid value, we don't need to check validity + function noopMinValidator() { return true; } : + // non-support browsers validate the min val + function minValidator(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal; + }; + + setInitialValueAndObserver('min', minChange); + } + + if (hasMaxAttr) { + ctrl.$validators.max = supportsRange ? + // Since all browsers set the input to a valid value, we don't need to check validity + function noopMaxValidator() { return true; } : + // non-support browsers validate the max val + function maxValidator(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal; + }; + + setInitialValueAndObserver('max', maxChange); + } + + if (hasStepAttr) { + ctrl.$validators.step = supportsRange ? + function nativeStepValidator() { + // Currently, only FF implements the spec on step change correctly (i.e. adjusting the + // input element value to a valid value). It's possible that other browsers set the stepMismatch + // validity error instead, so we can at least report an error in that case. + return !validity.stepMismatch; + } : + // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would + function stepValidator(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) || + isValidForStep(viewValue, minVal || 0, stepVal); + }; + + setInitialValueAndObserver('step', stepChange); + } + + function setInitialValueAndObserver(htmlAttrName, changeFn) { + // interpolated attributes set the attribute value only after a digest, but we need the + // attribute value when the input is first rendered, so that the browser can adjust the + // input value based on the min/max value + element.attr(htmlAttrName, attr[htmlAttrName]); + attr.$observe(htmlAttrName, changeFn); + } + + function minChange(val) { + minVal = parseNumberAttrVal(val); + // ignore changes before model is initialized + if (isNumberNaN(ctrl.$modelValue)) { + return; + } + + if (supportsRange) { + var elVal = element.val(); + // IE11 doesn't set the el val correctly if the minVal is greater than the element value + if (minVal > elVal) { + elVal = minVal; + element.val(elVal); + } + ctrl.$setViewValue(elVal); + } else { + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + } + } + + function maxChange(val) { + maxVal = parseNumberAttrVal(val); + // ignore changes before model is initialized + if (isNumberNaN(ctrl.$modelValue)) { + return; + } + + if (supportsRange) { + var elVal = element.val(); + // IE11 doesn't set the el val correctly if the maxVal is less than the element value + if (maxVal < elVal) { + element.val(maxVal); + // IE11 and Chrome don't set the value to the minVal when max < min + elVal = maxVal < minVal ? minVal : maxVal; + } + ctrl.$setViewValue(elVal); + } else { + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + } + } + + function stepChange(val) { + stepVal = parseNumberAttrVal(val); + // ignore changes before model is initialized + if (isNumberNaN(ctrl.$modelValue)) { + return; + } + + // Some browsers don't adjust the input value correctly, but set the stepMismatch error + if (supportsRange && ctrl.$viewValue !== element.val()) { + ctrl.$setViewValue(element.val()); + } else { + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + } + } +} + +function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) { + // Note: no badInputChecker here by purpose as `url` is only a validation + // in browsers, i.e. we can always read out input.value even if it is not valid! + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + stringBasedInputType(ctrl); + + ctrl.$$parserName = 'url'; + ctrl.$validators.url = function(modelValue, viewValue) { + var value = modelValue || viewValue; + return ctrl.$isEmpty(value) || URL_REGEXP.test(value); + }; +} + +function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) { + // Note: no badInputChecker here by purpose as `url` is only a validation + // in browsers, i.e. we can always read out input.value even if it is not valid! + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + stringBasedInputType(ctrl); + + ctrl.$$parserName = 'email'; + ctrl.$validators.email = function(modelValue, viewValue) { + var value = modelValue || viewValue; + return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value); + }; +} + +function radioInputType(scope, element, attr, ctrl) { + var doTrim = !attr.ngTrim || trim(attr.ngTrim) !== 'false'; + // make the name unique, if not defined + if (isUndefined(attr.name)) { + element.attr('name', nextUid()); + } + + var listener = function(ev) { + var value; + if (element[0].checked) { + value = attr.value; + if (doTrim) { + value = trim(value); + } + ctrl.$setViewValue(value, ev && ev.type); + } + }; + + element.on('click', listener); + + ctrl.$render = function() { + var value = attr.value; + if (doTrim) { + value = trim(value); + } + element[0].checked = (value === ctrl.$viewValue); + }; + + attr.$observe('value', ctrl.$render); +} + +function parseConstantExpr($parse, context, name, expression, fallback) { + var parseFn; + if (isDefined(expression)) { + parseFn = $parse(expression); + if (!parseFn.constant) { + throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' + + '`{1}`.', name, expression); + } + return parseFn(context); + } + return fallback; +} + +function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) { + var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true); + var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false); + + var listener = function(ev) { + ctrl.$setViewValue(element[0].checked, ev && ev.type); + }; + + element.on('click', listener); + + ctrl.$render = function() { + element[0].checked = ctrl.$viewValue; + }; + + // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false` + // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert + // it to a boolean. + ctrl.$isEmpty = function(value) { + return value === false; + }; + + ctrl.$formatters.push(function(value) { + return equals(value, trueValue); + }); + + ctrl.$parsers.push(function(value) { + return value ? trueValue : falseValue; + }); +} + + +/** + * @ngdoc directive + * @name textarea + * @restrict E + * + * @description + * HTML textarea element control with angular data-binding. The data-binding and validation + * properties of this element are exactly the same as those of the + * {@link ng.directive:input input element}. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any + * length. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * + * @knownIssue + * + * When specifying the `placeholder` attribute of ` + *
{{ list | json }}
+ * + * + * it("should split the text by newlines", function() { + * var listInput = element(by.model('list')); + * var output = element(by.binding('list | json')); + * listInput.sendKeys('abc\ndef\nghi'); + * expect(output.getText()).toContain('[\n "abc",\n "def",\n "ghi"\n]'); + * }); + * + * + * + * @element input + * @param {string=} ngList optional delimiter that should be used to split the value. + */ +var ngListDirective = function() { + return { + restrict: 'A', + priority: 100, + require: 'ngModel', + link: function(scope, element, attr, ctrl) { + var ngList = attr.ngList || ', '; + var trimValues = attr.ngTrim !== 'false'; + var separator = trimValues ? trim(ngList) : ngList; + + var parse = function(viewValue) { + // If the viewValue is invalid (say required but empty) it will be `undefined` + if (isUndefined(viewValue)) return; + + var list = []; + + if (viewValue) { + forEach(viewValue.split(separator), function(value) { + if (value) list.push(trimValues ? trim(value) : value); + }); + } + + return list; + }; + + ctrl.$parsers.push(parse); + ctrl.$formatters.push(function(value) { + if (isArray(value)) { + return value.join(ngList); + } + + return undefined; + }); + + // Override the standard $isEmpty because an empty array means the input is empty. + ctrl.$isEmpty = function(value) { + return !value || !value.length; + }; + } + }; +}; + +/* global VALID_CLASS: true, + INVALID_CLASS: true, + PRISTINE_CLASS: true, + DIRTY_CLASS: true, + UNTOUCHED_CLASS: true, + TOUCHED_CLASS: true, + PENDING_CLASS: true, + addSetValidityMethod: true, + setupValidity: true, + defaultModelOptions: false +*/ + + +var VALID_CLASS = 'ng-valid', + INVALID_CLASS = 'ng-invalid', + PRISTINE_CLASS = 'ng-pristine', + DIRTY_CLASS = 'ng-dirty', + UNTOUCHED_CLASS = 'ng-untouched', + TOUCHED_CLASS = 'ng-touched', + EMPTY_CLASS = 'ng-empty', + NOT_EMPTY_CLASS = 'ng-not-empty'; + +var ngModelMinErr = minErr('ngModel'); + +/** + * @ngdoc type + * @name ngModel.NgModelController + * + * @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a + * String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue + * is set. + * @property {*} $modelValue The value in the model that the control is bound to. + * @property {Array.} $parsers Array of functions to execute, as a pipeline, whenever + the control reads value from the DOM. The functions are called in array order, each passing + its return value through to the next. The last return value is forwarded to the + {@link ngModel.NgModelController#$validators `$validators`} collection. + +Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue +`$viewValue`}. + +Returning `undefined` from a parser means a parse error occurred. In that case, +no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel` +will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`} +is set to `true`. The parse error is stored in `ngModel.$error.parse`. + + * + * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever + the model value changes. The functions are called in reverse array order, each passing the value through to the + next. The last return value is used as the actual DOM value. + Used to format / convert values for display in the control. + * ```js + * function formatter(value) { + * if (value) { + * return value.toUpperCase(); + * } + * } + * ngModel.$formatters.push(formatter); + * ``` + * + * @property {Object.} $validators A collection of validators that are applied + * whenever the model value changes. The key value within the object refers to the name of the + * validator while the function refers to the validation operation. The validation operation is + * provided with the model value as an argument and must return a true or false value depending + * on the response of that validation. + * + * ```js + * ngModel.$validators.validCharacters = function(modelValue, viewValue) { + * var value = modelValue || viewValue; + * return /[0-9]+/.test(value) && + * /[a-z]+/.test(value) && + * /[A-Z]+/.test(value) && + * /\W+/.test(value); + * }; + * ``` + * + * @property {Object.} $asyncValidators A collection of validations that are expected to + * perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided + * is expected to return a promise when it is run during the model validation process. Once the promise + * is delivered then the validation status will be set to true when fulfilled and false when rejected. + * When the asynchronous validators are triggered, each of the validators will run in parallel and the model + * value will only be updated once all validators have been fulfilled. As long as an asynchronous validator + * is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators + * will only run once all synchronous validators have passed. + * + * Please note that if $http is used then it is important that the server returns a success HTTP response code + * in order to fulfill the validation and a status level of `4xx` in order to reject the validation. + * + * ```js + * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) { + * var value = modelValue || viewValue; + * + * // Lookup user by username + * return $http.get('/api/users/' + value). + * then(function resolved() { + * //username exists, this means validation fails + * return $q.reject('exists'); + * }, function rejected() { + * //username does not exist, therefore this validation passes + * return true; + * }); + * }; + * ``` + * + * @property {Array.} $viewChangeListeners Array of functions to execute whenever the + * view value has changed. It is called with no arguments, and its return value is ignored. + * This can be used in place of additional $watches against the model value. + * + * @property {Object} $error An object hash with all failing validator ids as keys. + * @property {Object} $pending An object hash with all pending validator ids as keys. + * + * @property {boolean} $untouched True if control has not lost focus yet. + * @property {boolean} $touched True if control has lost focus. + * @property {boolean} $pristine True if user has not interacted with the control yet. + * @property {boolean} $dirty True if user has already interacted with the control. + * @property {boolean} $valid True if there is no error. + * @property {boolean} $invalid True if at least one error on the control. + * @property {string} $name The name attribute of the control. + * + * @description + * + * `NgModelController` provides API for the {@link ngModel `ngModel`} directive. + * The controller contains services for data-binding, validation, CSS updates, and value formatting + * and parsing. It purposefully does not contain any logic which deals with DOM rendering or + * listening to DOM events. + * Such DOM related logic should be provided by other directives which make use of + * `NgModelController` for data-binding to control elements. + * Angular provides this DOM logic for most {@link input `input`} elements. + * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example + * custom control example} that uses `ngModelController` to bind to `contenteditable` elements. + * + * @example + * ### Custom Control Example + * This example shows how to use `NgModelController` with a custom control to achieve + * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`) + * collaborate together to achieve the desired result. + * + * `contenteditable` is an HTML5 attribute, which tells the browser to let the element + * contents be edited in place by the user. + * + * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize} + * module to automatically remove "bad" content like inline event listener (e.g. ``). + * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks + * that content using the `$sce` service. + * + * + + [contenteditable] { + border: 1px solid black; + background-color: white; + min-height: 20px; + } + + .ng-invalid { + border: 1px solid red; + } + + + + angular.module('customControl', ['ngSanitize']). + directive('contenteditable', ['$sce', function($sce) { + return { + restrict: 'A', // only activate on element attribute + require: '?ngModel', // get a hold of NgModelController + link: function(scope, element, attrs, ngModel) { + if (!ngModel) return; // do nothing if no ng-model + + // Specify how UI should be updated + ngModel.$render = function() { + element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); + }; + + // Listen for change events to enable binding + element.on('blur keyup change', function() { + scope.$evalAsync(read); + }); + read(); // initialize + + // Write data to the model + function read() { + var html = element.html(); + // When we clear the content editable the browser leaves a
behind + // If strip-br attribute is provided then we strip this out + if (attrs.stripBr && html === '
') { + html = ''; + } + ngModel.$setViewValue(html); + } + } + }; + }]); +
+ +
+
Change me!
+ Required! +
+ +
+
+ + it('should data-bind and become invalid', function() { + if (browser.params.browser === 'safari' || browser.params.browser === 'firefox') { + // SafariDriver can't handle contenteditable + // and Firefox driver can't clear contenteditables very well + return; + } + var contentEditable = element(by.css('[contenteditable]')); + var content = 'Change me!'; + + expect(contentEditable.getText()).toEqual(content); + + contentEditable.clear(); + contentEditable.sendKeys(protractor.Key.BACK_SPACE); + expect(contentEditable.getText()).toEqual(''); + expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/); + }); + + *
+ * + * + */ +NgModelController.$inject = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$q', '$interpolate']; +function NgModelController($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $q, $interpolate) { + this.$viewValue = Number.NaN; + this.$modelValue = Number.NaN; + this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity. + this.$validators = {}; + this.$asyncValidators = {}; + this.$parsers = []; + this.$formatters = []; + this.$viewChangeListeners = []; + this.$untouched = true; + this.$touched = false; + this.$pristine = true; + this.$dirty = false; + this.$valid = true; + this.$invalid = false; + this.$error = {}; // keep invalid keys here + this.$$success = {}; // keep valid keys here + this.$pending = undefined; // keep pending keys here + this.$name = $interpolate($attr.name || '', false)($scope); + this.$$parentForm = nullFormCtrl; + this.$options = defaultModelOptions; + + this.$$parsedNgModel = $parse($attr.ngModel); + this.$$parsedNgModelAssign = this.$$parsedNgModel.assign; + this.$$ngModelGet = this.$$parsedNgModel; + this.$$ngModelSet = this.$$parsedNgModelAssign; + this.$$pendingDebounce = null; + this.$$parserValid = undefined; + + this.$$currentValidationRunId = 0; + + this.$$scope = $scope; + this.$$attr = $attr; + this.$$element = $element; + this.$$animate = $animate; + this.$$timeout = $timeout; + this.$$parse = $parse; + this.$$q = $q; + this.$$exceptionHandler = $exceptionHandler; + + setupValidity(this); + setupModelWatcher(this); +} + +NgModelController.prototype = { + $$initGetterSetters: function() { + if (this.$options.getOption('getterSetter')) { + var invokeModelGetter = this.$$parse(this.$$attr.ngModel + '()'), + invokeModelSetter = this.$$parse(this.$$attr.ngModel + '($$$p)'); + + this.$$ngModelGet = function($scope) { + var modelValue = this.$$parsedNgModel($scope); + if (isFunction(modelValue)) { + modelValue = invokeModelGetter($scope); + } + return modelValue; + }; + this.$$ngModelSet = function($scope, newValue) { + if (isFunction(this.$$parsedNgModel($scope))) { + invokeModelSetter($scope, {$$$p: newValue}); + } else { + this.$$parsedNgModelAssign($scope, newValue); + } + }; + } else if (!this.$$parsedNgModel.assign) { + throw ngModelMinErr('nonassign', 'Expression \'{0}\' is non-assignable. Element: {1}', + this.$$attr.ngModel, startingTag(this.$$element)); + } + }, + + + /** + * @ngdoc method + * @name ngModel.NgModelController#$render + * + * @description + * Called when the view needs to be updated. It is expected that the user of the ng-model + * directive will implement this method. + * + * The `$render()` method is invoked in the following situations: + * + * * `$rollbackViewValue()` is called. If we are rolling back the view value to the last + * committed value then `$render()` is called to update the input control. + * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and + * the `$viewValue` are different from last time. + * + * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of + * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue` + * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be + * invoked if you only change a property on the objects. + */ + $render: noop, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$isEmpty + * + * @description + * This is called when we need to determine if the value of an input is empty. + * + * For instance, the required directive does this to work out if the input has data or not. + * + * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`. + * + * You can override this for input directives whose concept of being empty is different from the + * default. The `checkboxInputType` directive does this because in its case a value of `false` + * implies empty. + * + * @param {*} value The value of the input to check for emptiness. + * @returns {boolean} True if `value` is "empty". + */ + $isEmpty: function(value) { + // eslint-disable-next-line no-self-compare + return isUndefined(value) || value === '' || value === null || value !== value; + }, + + $$updateEmptyClasses: function(value) { + if (this.$isEmpty(value)) { + this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS); + this.$$animate.addClass(this.$$element, EMPTY_CLASS); + } else { + this.$$animate.removeClass(this.$$element, EMPTY_CLASS); + this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS); + } + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$setPristine + * + * @description + * Sets the control to its pristine state. + * + * This method can be called to remove the `ng-dirty` class and set the control to its pristine + * state (`ng-pristine` class). A model is considered to be pristine when the control + * has not been changed from when first compiled. + */ + $setPristine: function() { + this.$dirty = false; + this.$pristine = true; + this.$$animate.removeClass(this.$$element, DIRTY_CLASS); + this.$$animate.addClass(this.$$element, PRISTINE_CLASS); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$setDirty + * + * @description + * Sets the control to its dirty state. + * + * This method can be called to remove the `ng-pristine` class and set the control to its dirty + * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed + * from when first compiled. + */ + $setDirty: function() { + this.$dirty = true; + this.$pristine = false; + this.$$animate.removeClass(this.$$element, PRISTINE_CLASS); + this.$$animate.addClass(this.$$element, DIRTY_CLASS); + this.$$parentForm.$setDirty(); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$setUntouched + * + * @description + * Sets the control to its untouched state. + * + * This method can be called to remove the `ng-touched` class and set the control to its + * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched + * by default, however this function can be used to restore that state if the model has + * already been touched by the user. + */ + $setUntouched: function() { + this.$touched = false; + this.$untouched = true; + this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$setTouched + * + * @description + * Sets the control to its touched state. + * + * This method can be called to remove the `ng-untouched` class and set the control to its + * touched state (`ng-touched` class). A model is considered to be touched when the user has + * first focused the control element and then shifted focus away from the control (blur event). + */ + $setTouched: function() { + this.$touched = true; + this.$untouched = false; + this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$rollbackViewValue + * + * @description + * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`, + * which may be caused by a pending debounced event or because the input is waiting for some + * future event. + * + * If you have an input that uses `ng-model-options` to set up debounced updates or updates that + * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of + * sync with the ngModel's `$modelValue`. + * + * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update + * and reset the input to the last committed view value. + * + * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue` + * programmatically before these debounced/future events have resolved/occurred, because Angular's + * dirty checking mechanism is not able to tell whether the model has actually changed or not. + * + * The `$rollbackViewValue()` method should be called before programmatically changing the model of an + * input which may have such events pending. This is important in order to make sure that the + * input field will be updated with the new model value and any pending operations are cancelled. + * + * + * + * angular.module('cancel-update-example', []) + * + * .controller('CancelUpdateController', ['$scope', function($scope) { + * $scope.model = {value1: '', value2: ''}; + * + * $scope.setEmpty = function(e, value, rollback) { + * if (e.keyCode === 27) { + * e.preventDefault(); + * if (rollback) { + * $scope.myForm[value].$rollbackViewValue(); + * } + * $scope.model[value] = ''; + * } + * }; + * }]); + * + * + *
+ *

Both of these inputs are only updated if they are blurred. Hitting escape should + * empty them. Follow these steps and observe the difference:

+ *
    + *
  1. Type something in the input. You will see that the model is not yet updated
  2. + *
  3. Press the Escape key. + *
      + *
    1. In the first example, nothing happens, because the model is already '', and no + * update is detected. If you blur the input, the model will be set to the current view. + *
    2. + *
    3. In the second example, the pending update is cancelled, and the input is set back + * to the last committed view value (''). Blurring the input does nothing. + *
    4. + *
    + *
  4. + *
+ * + *
+ *
+ *

Without $rollbackViewValue():

+ * + * value1: "{{ model.value1 }}" + *
+ * + *
+ *

With $rollbackViewValue():

+ * + * value2: "{{ model.value2 }}" + *
+ *
+ *
+ *
+ + div { + display: table-cell; + } + div:nth-child(1) { + padding-right: 30px; + } + + + *
+ */ + $rollbackViewValue: function() { + this.$$timeout.cancel(this.$$pendingDebounce); + this.$viewValue = this.$$lastCommittedViewValue; + this.$render(); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$validate + * + * @description + * Runs each of the registered validators (first synchronous validators and then + * asynchronous validators). + * If the validity changes to invalid, the model will be set to `undefined`, + * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`. + * If the validity changes to valid, it will set the model to the last available valid + * `$modelValue`, i.e. either the last parsed value or the last value set from the scope. + */ + $validate: function() { + // ignore $validate before model is initialized + if (isNumberNaN(this.$modelValue)) { + return; + } + + var viewValue = this.$$lastCommittedViewValue; + // Note: we use the $$rawModelValue as $modelValue might have been + // set to undefined during a view -> model update that found validation + // errors. We can't parse the view here, since that could change + // the model although neither viewValue nor the model on the scope changed + var modelValue = this.$$rawModelValue; + + var prevValid = this.$valid; + var prevModelValue = this.$modelValue; + + var allowInvalid = this.$options.getOption('allowInvalid'); + + var that = this; + this.$$runValidators(modelValue, viewValue, function(allValid) { + // If there was no change in validity, don't update the model + // This prevents changing an invalid modelValue to undefined + if (!allowInvalid && prevValid !== allValid) { + // Note: Don't check this.$valid here, as we could have + // external validators (e.g. calculated on the server), + // that just call $setValidity and need the model value + // to calculate their validity. + that.$modelValue = allValid ? modelValue : undefined; + + if (that.$modelValue !== prevModelValue) { + that.$$writeModelToScope(); + } + } + }); + }, + + $$runValidators: function(modelValue, viewValue, doneCallback) { + this.$$currentValidationRunId++; + var localValidationRunId = this.$$currentValidationRunId; + var that = this; + + // check parser error + if (!processParseErrors()) { + validationDone(false); + return; + } + if (!processSyncValidators()) { + validationDone(false); + return; + } + processAsyncValidators(); + + function processParseErrors() { + var errorKey = that.$$parserName || 'parse'; + if (isUndefined(that.$$parserValid)) { + setValidity(errorKey, null); + } else { + if (!that.$$parserValid) { + forEach(that.$validators, function(v, name) { + setValidity(name, null); + }); + forEach(that.$asyncValidators, function(v, name) { + setValidity(name, null); + }); + } + // Set the parse error last, to prevent unsetting it, should a $validators key == parserName + setValidity(errorKey, that.$$parserValid); + return that.$$parserValid; + } + return true; + } + + function processSyncValidators() { + var syncValidatorsValid = true; + forEach(that.$validators, function(validator, name) { + var result = Boolean(validator(modelValue, viewValue)); + syncValidatorsValid = syncValidatorsValid && result; + setValidity(name, result); + }); + if (!syncValidatorsValid) { + forEach(that.$asyncValidators, function(v, name) { + setValidity(name, null); + }); + return false; + } + return true; + } + + function processAsyncValidators() { + var validatorPromises = []; + var allValid = true; + forEach(that.$asyncValidators, function(validator, name) { + var promise = validator(modelValue, viewValue); + if (!isPromiseLike(promise)) { + throw ngModelMinErr('nopromise', + 'Expected asynchronous validator to return a promise but got \'{0}\' instead.', promise); + } + setValidity(name, undefined); + validatorPromises.push(promise.then(function() { + setValidity(name, true); + }, function() { + allValid = false; + setValidity(name, false); + })); + }); + if (!validatorPromises.length) { + validationDone(true); + } else { + that.$$q.all(validatorPromises).then(function() { + validationDone(allValid); + }, noop); + } + } + + function setValidity(name, isValid) { + if (localValidationRunId === that.$$currentValidationRunId) { + that.$setValidity(name, isValid); + } + } + + function validationDone(allValid) { + if (localValidationRunId === that.$$currentValidationRunId) { + + doneCallback(allValid); + } + } + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$commitViewValue + * + * @description + * Commit a pending update to the `$modelValue`. + * + * Updates may be pending by a debounced event or because the input is waiting for a some future + * event defined in `ng-model-options`. this method is rarely needed as `NgModelController` + * usually handles calling this in response to input events. + */ + $commitViewValue: function() { + var viewValue = this.$viewValue; + + this.$$timeout.cancel(this.$$pendingDebounce); + + // If the view value has not changed then we should just exit, except in the case where there is + // a native validator on the element. In this case the validation state may have changed even though + // the viewValue has stayed empty. + if (this.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !this.$$hasNativeValidators)) { + return; + } + this.$$updateEmptyClasses(viewValue); + this.$$lastCommittedViewValue = viewValue; + + // change to dirty + if (this.$pristine) { + this.$setDirty(); + } + this.$$parseAndValidate(); + }, + + $$parseAndValidate: function() { + var viewValue = this.$$lastCommittedViewValue; + var modelValue = viewValue; + var that = this; + + this.$$parserValid = isUndefined(modelValue) ? undefined : true; + + if (this.$$parserValid) { + for (var i = 0; i < this.$parsers.length; i++) { + modelValue = this.$parsers[i](modelValue); + if (isUndefined(modelValue)) { + this.$$parserValid = false; + break; + } + } + } + if (isNumberNaN(this.$modelValue)) { + // this.$modelValue has not been touched yet... + this.$modelValue = this.$$ngModelGet(this.$$scope); + } + var prevModelValue = this.$modelValue; + var allowInvalid = this.$options.getOption('allowInvalid'); + this.$$rawModelValue = modelValue; + + if (allowInvalid) { + this.$modelValue = modelValue; + writeToModelIfNeeded(); + } + + // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date. + // This can happen if e.g. $setViewValue is called from inside a parser + this.$$runValidators(modelValue, this.$$lastCommittedViewValue, function(allValid) { + if (!allowInvalid) { + // Note: Don't check this.$valid here, as we could have + // external validators (e.g. calculated on the server), + // that just call $setValidity and need the model value + // to calculate their validity. + that.$modelValue = allValid ? modelValue : undefined; + writeToModelIfNeeded(); + } + }); + + function writeToModelIfNeeded() { + if (that.$modelValue !== prevModelValue) { + that.$$writeModelToScope(); + } + } + }, + + $$writeModelToScope: function() { + this.$$ngModelSet(this.$$scope, this.$modelValue); + forEach(this.$viewChangeListeners, function(listener) { + try { + listener(); + } catch (e) { + // eslint-disable-next-line no-invalid-this + this.$$exceptionHandler(e); + } + }, this); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$setViewValue + * + * @description + * Update the view value. + * + * This method should be called when a control wants to change the view value; typically, + * this is done from within a DOM event handler. For example, the {@link ng.directive:input input} + * directive calls it when the value of the input changes and {@link ng.directive:select select} + * calls it when an option is selected. + * + * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers` + * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged + * value sent directly for processing, finally to be applied to `$modelValue` and then the + * **expression** specified in the `ng-model` attribute. Lastly, all the registered change listeners, + * in the `$viewChangeListeners` list, are called. + * + * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn` + * and the `default` trigger is not listed, all those actions will remain pending until one of the + * `updateOn` events is triggered on the DOM element. + * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions} + * directive is used with a custom debounce for this particular event. + * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce` + * is specified, once the timer runs out. + * + * When used with standard inputs, the view value will always be a string (which is in some cases + * parsed into another type, such as a `Date` object for `input[date]`.) + * However, custom controls might also pass objects to this method. In this case, we should make + * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not + * perform a deep watch of objects, it only looks for a change of identity. If you only change + * the property of the object then ngModel will not realize that the object has changed and + * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should + * not change properties of the copy once it has been passed to `$setViewValue`. + * Otherwise you may cause the model value on the scope to change incorrectly. + * + *
+ * In any case, the value passed to the method should always reflect the current value + * of the control. For example, if you are calling `$setViewValue` for an input element, + * you should pass the input DOM value. Otherwise, the control and the scope model become + * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change + * the control's DOM value in any way. If we want to change the control's DOM value + * programmatically, we should update the `ngModel` scope expression. Its new value will be + * picked up by the model controller, which will run it through the `$formatters`, `$render` it + * to update the DOM, and finally call `$validate` on it. + *
+ * + * @param {*} value value from the view. + * @param {string} trigger Event that triggered the update. + */ + $setViewValue: function(value, trigger) { + this.$viewValue = value; + if (this.$options.getOption('updateOnDefault')) { + this.$$debounceViewValueCommit(trigger); + } + }, + + $$debounceViewValueCommit: function(trigger) { + var debounceDelay = this.$options.getOption('debounce'); + + if (isNumber(debounceDelay[trigger])) { + debounceDelay = debounceDelay[trigger]; + } else if (isNumber(debounceDelay['default'])) { + debounceDelay = debounceDelay['default']; + } + + this.$$timeout.cancel(this.$$pendingDebounce); + var that = this; + if (debounceDelay > 0) { // this fails if debounceDelay is an object + this.$$pendingDebounce = this.$$timeout(function() { + that.$commitViewValue(); + }, debounceDelay); + } else if (this.$$scope.$root.$$phase) { + this.$commitViewValue(); + } else { + this.$$scope.$apply(function() { + that.$commitViewValue(); + }); + } + } +}; + +function setupModelWatcher(ctrl) { + // model -> value + // Note: we cannot use a normal scope.$watch as we want to detect the following: + // 1. scope value is 'a' + // 2. user enters 'b' + // 3. ng-change kicks in and reverts scope value to 'a' + // -> scope value did not change since the last digest as + // ng-change executes in apply phase + // 4. view should be changed back to 'a' + ctrl.$$scope.$watch(function ngModelWatch() { + var modelValue = ctrl.$$ngModelGet(ctrl.$$scope); + + // if scope model value and ngModel value are out of sync + // TODO(perf): why not move this to the action fn? + if (modelValue !== ctrl.$modelValue && + // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator + // eslint-disable-next-line no-self-compare + (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue) + ) { + ctrl.$modelValue = ctrl.$$rawModelValue = modelValue; + ctrl.$$parserValid = undefined; + + var formatters = ctrl.$formatters, + idx = formatters.length; + + var viewValue = modelValue; + while (idx--) { + viewValue = formatters[idx](viewValue); + } + if (ctrl.$viewValue !== viewValue) { + ctrl.$$updateEmptyClasses(viewValue); + ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue; + ctrl.$render(); + + // It is possible that model and view value have been updated during render + ctrl.$$runValidators(ctrl.$modelValue, ctrl.$viewValue, noop); + } + } + + return modelValue; + }); +} + +/** + * @ngdoc method + * @name ngModel.NgModelController#$setValidity + * + * @description + * Change the validity state, and notify the form. + * + * This method can be called within $parsers/$formatters or a custom validation implementation. + * However, in most cases it should be sufficient to use the `ngModel.$validators` and + * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically. + * + * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned + * to either `$error[validationErrorKey]` or `$pending[validationErrorKey]` + * (for unfulfilled `$asyncValidators`), so that it is available for data-binding. + * The `validationErrorKey` should be in camelCase and will get converted into dash-case + * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error` + * class and can be bound to as `{{someForm.someControl.$error.myError}}` . + * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined), + * or skipped (null). Pending is used for unfulfilled `$asyncValidators`. + * Skipped is used by Angular when validators do not run because of parse errors and + * when `$asyncValidators` do not run because any of the `$validators` failed. + */ +addSetValidityMethod({ + clazz: NgModelController, + set: function(object, property) { + object[property] = true; + }, + unset: function(object, property) { + delete object[property]; + } +}); + + +/** + * @ngdoc directive + * @name ngModel + * + * @element input + * @priority 1 + * + * @description + * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a + * property on the scope using {@link ngModel.NgModelController NgModelController}, + * which is created and exposed by this directive. + * + * `ngModel` is responsible for: + * + * - Binding the view into the model, which other directives such as `input`, `textarea` or `select` + * require. + * - Providing validation behavior (i.e. required, number, email, url). + * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors). + * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`, + * `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations. + * - Registering the control with its parent {@link ng.directive:form form}. + * + * Note: `ngModel` will try to bind to the property given by evaluating the expression on the + * current scope. If the property doesn't already exist on this scope, it will be created + * implicitly and added to the scope. + * + * For best practices on using `ngModel`, see: + * + * - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes) + * + * For basic examples, how to use `ngModel`, see: + * + * - {@link ng.directive:input input} + * - {@link input[text] text} + * - {@link input[checkbox] checkbox} + * - {@link input[radio] radio} + * - {@link input[number] number} + * - {@link input[email] email} + * - {@link input[url] url} + * - {@link input[date] date} + * - {@link input[datetime-local] datetime-local} + * - {@link input[time] time} + * - {@link input[month] month} + * - {@link input[week] week} + * - {@link ng.directive:select select} + * - {@link ng.directive:textarea textarea} + * + * # Complex Models (objects or collections) + * + * By default, `ngModel` watches the model by reference, not value. This is important to know when + * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the + * object or collection change, `ngModel` will not be notified and so the input will not be re-rendered. + * + * The model must be assigned an entirely new object or collection before a re-rendering will occur. + * + * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression + * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or + * if the select is given the `multiple` attribute. + * + * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the + * first level of the object (or only changing the properties of an item in the collection if it's an array) will still + * not trigger a re-rendering of the model. + * + * # CSS classes + * The following CSS classes are added and removed on the associated input/select/textarea element + * depending on the validity of the model. + * + * - `ng-valid`: the model is valid + * - `ng-invalid`: the model is invalid + * - `ng-valid-[key]`: for each valid key added by `$setValidity` + * - `ng-invalid-[key]`: for each invalid key added by `$setValidity` + * - `ng-pristine`: the control hasn't been interacted with yet + * - `ng-dirty`: the control has been interacted with + * - `ng-touched`: the control has been blurred + * - `ng-untouched`: the control hasn't been blurred + * - `ng-pending`: any `$asyncValidators` are unfulfilled + * - `ng-empty`: the view does not contain a value or the value is deemed "empty", as defined + * by the {@link ngModel.NgModelController#$isEmpty} method + * - `ng-not-empty`: the view contains a non-empty value + * + * Keep in mind that ngAnimate can detect each of these classes when added and removed. + * + * ## Animation Hooks + * + * Animations within models are triggered when any of the associated CSS classes are added and removed + * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`, + * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself. + * The animations that are triggered within ngModel are similar to how they work in ngClass and + * animations can be hooked into using CSS transitions, keyframes as well as JS animations. + * + * The following example shows a simple way to utilize CSS transitions to style an input element + * that has been rendered as invalid after it has been validated: + * + *
+ * //be sure to include ngAnimate as a module to hook into more
+ * //advanced animations
+ * .my-input {
+ *   transition:0.5s linear all;
+ *   background: white;
+ * }
+ * .my-input.ng-invalid {
+ *   background: red;
+ *   color:white;
+ * }
+ * 
+ * + * @example + * + + + +

+ Update input to see transitions when valid/invalid. + Integer is a valid value. +

+
+ +
+
+ *
+ * + * ## Binding to a getter/setter + * + * Sometimes it's helpful to bind `ngModel` to a getter/setter function. A getter/setter is a + * function that returns a representation of the model when called with zero arguments, and sets + * the internal state of a model when called with an argument. It's sometimes useful to use this + * for models that have an internal representation that's different from what the model exposes + * to the view. + * + *
+ * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more + * frequently than other parts of your code. + *
+ * + * You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that + * has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to + * a `
`, which will enable this behavior for all ``s within it. See + * {@link ng.directive:ngModelOptions `ngModelOptions`} for more. + * + * The following example shows how to use `ngModel` with a getter/setter: + * + * @example + * + +
+ + + +
user.name = 
+
+
+ + angular.module('getterSetterExample', []) + .controller('ExampleController', ['$scope', function($scope) { + var _name = 'Brian'; + $scope.user = { + name: function(newName) { + // Note that newName can be undefined for two reasons: + // 1. Because it is called as a getter and thus called with no arguments + // 2. Because the property should actually be set to undefined. This happens e.g. if the + // input is invalid + return arguments.length ? (_name = newName) : _name; + } + }; + }]); + + *
+ */ +var ngModelDirective = ['$rootScope', function($rootScope) { + return { + restrict: 'A', + require: ['ngModel', '^?form', '^?ngModelOptions'], + controller: NgModelController, + // Prelink needs to run before any input directive + // so that we can set the NgModelOptions in NgModelController + // before anyone else uses it. + priority: 1, + compile: function ngModelCompile(element) { + // Setup initial state of the control + element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS); + + return { + pre: function ngModelPreLink(scope, element, attr, ctrls) { + var modelCtrl = ctrls[0], + formCtrl = ctrls[1] || modelCtrl.$$parentForm, + optionsCtrl = ctrls[2]; + + if (optionsCtrl) { + modelCtrl.$options = optionsCtrl.$options; + } + + modelCtrl.$$initGetterSetters(); + + // notify others, especially parent forms + formCtrl.$addControl(modelCtrl); + + attr.$observe('name', function(newValue) { + if (modelCtrl.$name !== newValue) { + modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue); + } + }); + + scope.$on('$destroy', function() { + modelCtrl.$$parentForm.$removeControl(modelCtrl); + }); + }, + post: function ngModelPostLink(scope, element, attr, ctrls) { + var modelCtrl = ctrls[0]; + if (modelCtrl.$options.getOption('updateOn')) { + element.on(modelCtrl.$options.getOption('updateOn'), function(ev) { + modelCtrl.$$debounceViewValueCommit(ev && ev.type); + }); + } + + function setTouched() { + modelCtrl.$setTouched(); + } + + element.on('blur', function() { + if (modelCtrl.$touched) return; + + if ($rootScope.$$phase) { + scope.$evalAsync(setTouched); + } else { + scope.$apply(setTouched); + } + }); + } + }; + } + }; +}]; + +/* exported defaultModelOptions */ +var defaultModelOptions; +var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/; + +/** + * @ngdoc type + * @name ModelOptions + * @description + * A container for the options set by the {@link ngModelOptions} directive + */ +function ModelOptions(options) { + this.$$options = options; +} + +ModelOptions.prototype = { + + /** + * @ngdoc method + * @name ModelOptions#getOption + * @param {string} name the name of the option to retrieve + * @returns {*} the value of the option + * @description + * Returns the value of the given option + */ + getOption: function(name) { + return this.$$options[name]; + }, + + /** + * @ngdoc method + * @name ModelOptions#createChild + * @param {Object} options a hash of options for the new child that will override the parent's options + * @return {ModelOptions} a new `ModelOptions` object initialized with the given options. + */ + createChild: function(options) { + var inheritAll = false; + + // make a shallow copy + options = extend({}, options); + + // Inherit options from the parent if specified by the value `"$inherit"` + forEach(options, /* @this */ function(option, key) { + if (option === '$inherit') { + if (key === '*') { + inheritAll = true; + } else { + options[key] = this.$$options[key]; + // `updateOn` is special so we must also inherit the `updateOnDefault` option + if (key === 'updateOn') { + options.updateOnDefault = this.$$options.updateOnDefault; + } + } + } else { + if (key === 'updateOn') { + // If the `updateOn` property contains the `default` event then we have to remove + // it from the event list and set the `updateOnDefault` flag. + options.updateOnDefault = false; + options[key] = trim(option.replace(DEFAULT_REGEXP, function() { + options.updateOnDefault = true; + return ' '; + })); + } + } + }, this); + + if (inheritAll) { + // We have a property of the form: `"*": "$inherit"` + delete options['*']; + defaults(options, this.$$options); + } + + // Finally add in any missing defaults + defaults(options, defaultModelOptions.$$options); + + return new ModelOptions(options); + } +}; + + +defaultModelOptions = new ModelOptions({ + updateOn: '', + updateOnDefault: true, + debounce: 0, + getterSetter: false, + allowInvalid: false, + timezone: null +}); + + +/** + * @ngdoc directive + * @name ngModelOptions + * + * @description + * This directive allows you to modify the behaviour of {@link ngModel} directives within your + * application. You can specify an `ngModelOptions` directive on any element. All {@link ngModel} + * directives will use the options of their nearest `ngModelOptions` ancestor. + * + * The `ngModelOptions` settings are found by evaluating the value of the attribute directive as + * an Angular expression. This expression should evaluate to an object, whose properties contain + * the settings. For example: `
+ *
+ * + *
+ *
+ * ``` + * + * the `input` element will have the following settings + * + * ```js + * { allowInvalid: true, updateOn: 'default', debounce: 0 } + * ``` + * + * Notice that the `debounce` setting was not inherited and used the default value instead. + * + * You can specify that all undefined settings are automatically inherited from an ancestor by + * including a property with key of `"*"` and value of `"$inherit"`. + * + * For example given the following fragment of HTML + * + * + * ```html + *
+ *
+ * + *
+ *
+ * ``` + * + * the `input` element will have the following settings + * + * ```js + * { allowInvalid: true, updateOn: 'default', debounce: 200 } + * ``` + * + * Notice that the `debounce` setting now inherits the value from the outer `
` element. + * + * If you are creating a reusable component then you should be careful when using `"*": "$inherit"` + * since you may inadvertently inherit a setting in the future that changes the behavior of your component. + * + * + * ## Triggering and debouncing model updates + * + * The `updateOn` and `debounce` properties allow you to specify a custom list of events that will + * trigger a model update and/or a debouncing delay so that the actual update only takes place when + * a timer expires; this timer will be reset after another change takes place. + * + * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might + * be different from the value in the actual model. This means that if you update the model you + * should also invoke {@link ngModel.NgModelController#$rollbackViewValue} on the relevant input field in + * order to make sure it is synchronized with the model and that any debounced action is canceled. + * + * The easiest way to reference the control's {@link ngModel.NgModelController#$rollbackViewValue} + * method is by making sure the input is placed inside a form that has a `name` attribute. This is + * important because `form` controllers are published to the related scope under the name in their + * `name` attribute. + * + * Any pending changes will take place immediately when an enclosing form is submitted via the + * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit` + * to have access to the updated model. + * + * The following example shows how to override immediate updates. Changes on the inputs within the + * form will update the model only when the control loses focus (blur event). If `escape` key is + * pressed while the input field is focused, the value is reset to the value in the current model. + * + * + * + *
+ *
+ *
+ *
+ *
+ *
user.name = 
+ *
+ *
+ * + * angular.module('optionsExample', []) + * .controller('ExampleController', ['$scope', function($scope) { + * $scope.user = { name: 'say', data: '' }; + * + * $scope.cancel = function(e) { + * if (e.keyCode === 27) { + * $scope.userForm.userName.$rollbackViewValue(); + * } + * }; + * }]); + * + * + * var model = element(by.binding('user.name')); + * var input = element(by.model('user.name')); + * var other = element(by.model('user.data')); + * + * it('should allow custom events', function() { + * input.sendKeys(' hello'); + * input.click(); + * expect(model.getText()).toEqual('say'); + * other.click(); + * expect(model.getText()).toEqual('say hello'); + * }); + * + * it('should $rollbackViewValue when model changes', function() { + * input.sendKeys(' hello'); + * expect(input.getAttribute('value')).toEqual('say hello'); + * input.sendKeys(protractor.Key.ESCAPE); + * expect(input.getAttribute('value')).toEqual('say'); + * other.click(); + * expect(model.getText()).toEqual('say'); + * }); + * + *
+ * + * The next example shows how to debounce model changes. Model will be updated only 1 sec after last change. + * If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty. + * + * + * + *
+ *
+ * Name: + * + *
+ *
+ *
user.name = 
+ *
+ *
+ * + * angular.module('optionsExample', []) + * .controller('ExampleController', ['$scope', function($scope) { + * $scope.user = { name: 'say' }; + * }]); + * + *
+ * + * ## Model updates and validation + * + * The default behaviour in `ngModel` is that the model value is set to `undefined` when the + * validation determines that the value is invalid. By setting the `allowInvalid` property to true, + * the model will still be updated even if the value is invalid. + * + * + * ## Connecting to the scope + * + * By setting the `getterSetter` property to true you are telling ngModel that the `ngModel` expression + * on the scope refers to a "getter/setter" function rather than the value itself. + * + * The following example shows how to bind to getter/setters: + * + * + * + *
+ *
+ * + *
+ *
user.name = 
+ *
+ *
+ * + * angular.module('getterSetterExample', []) + * .controller('ExampleController', ['$scope', function($scope) { + * var _name = 'Brian'; + * $scope.user = { + * name: function(newName) { + * return angular.isDefined(newName) ? (_name = newName) : _name; + * } + * }; + * }]); + * + *
+ * + * + * ## Specifying timezones + * + * You can specify the timezone that date/time input directives expect by providing its name in the + * `timezone` property. + * + * @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and + * and its descendents. Valid keys are: + * - `updateOn`: string specifying which event should the input be bound to. You can set several + * events using an space delimited list. There is a special event called `default` that + * matches the default events belonging to the control. + * - `debounce`: integer value which contains the debounce model update value in milliseconds. A + * value of 0 triggers an immediate update. If an object is supplied instead, you can specify a + * custom value for each event. For example: + * ``` + * ng-model-options="{ + * updateOn: 'default blur', + * debounce: { 'default': 500, 'blur': 0 } + * }" + * ``` + * - `allowInvalid`: boolean value which indicates that the model can be set with values that did + * not validate correctly instead of the default behavior of setting the model to undefined. + * - `getterSetter`: boolean value which determines whether or not to treat functions bound to + * `ngModel` as getters/setters. + * - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for + * ``, ``, ... . It understands UTC/GMT and the + * continental US time zone abbreviations, but for general use, use a time zone offset, for + * example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian) + * If not specified, the timezone of the browser will be used. + * + */ +var ngModelOptionsDirective = function() { + NgModelOptionsController.$inject = ['$attrs', '$scope']; + function NgModelOptionsController($attrs, $scope) { + this.$$attrs = $attrs; + this.$$scope = $scope; + } + NgModelOptionsController.prototype = { + $onInit: function() { + var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions; + var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions); + + this.$options = parentOptions.createChild(modelOptionsDefinition); + } + }; + + return { + restrict: 'A', + // ngModelOptions needs to run before ngModel and input directives + priority: 10, + require: {parentCtrl: '?^^ngModelOptions'}, + bindToController: true, + controller: NgModelOptionsController + }; +}; + + +// shallow copy over values from `src` that are not already specified on `dst` +function defaults(dst, src) { + forEach(src, function(value, key) { + if (!isDefined(dst[key])) { + dst[key] = value; + } + }); +} + +/** + * @ngdoc directive + * @name ngNonBindable + * @restrict AC + * @priority 1000 + * + * @description + * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current + * DOM element. This is useful if the element contains what appears to be Angular directives and + * bindings but which should be ignored by Angular. This could be the case if you have a site that + * displays snippets of code, for instance. + * + * @element ANY + * + * @example + * In this example there are two locations where a simple interpolation binding (`{{}}`) is present, + * but the one wrapped in `ngNonBindable` is left alone. + * + * @example + + +
Normal: {{1 + 2}}
+
Ignored: {{1 + 2}}
+
+ + it('should check ng-non-bindable', function() { + expect(element(by.binding('1 + 2')).getText()).toContain('3'); + expect(element.all(by.css('div')).last().getText()).toMatch(/1 \+ 2/); + }); + +
+ */ +var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); + +/* exported ngOptionsDirective */ + +/* global jqLiteRemove */ + +var ngOptionsMinErr = minErr('ngOptions'); + +/** + * @ngdoc directive + * @name ngOptions + * @restrict A + * + * @description + * + * The `ngOptions` attribute can be used to dynamically generate a list of `` + * DOM element. + * * `disable`: The result of this expression will be used to disable the rendered `
diff --git a/api-wiaas/server/components/v1/users/UsersController.php b/api-wiaas/server/components/v1/users/UsersController.php new file mode 100644 index 0000000..a89476a --- /dev/null +++ b/api-wiaas/server/components/v1/users/UsersController.php @@ -0,0 +1,102 @@ +model = new UsersModel(); + } + + /** + * include users template + */ + public function usersTemplate(){ + global $user; + require_once('templates/UsersTemplate.php'); + } + + /** + * display and edit users + * @return array of users + */ + public function showEditUsersTemplate() { + require_once('templates/ShowEditUsersTemplate.php'); + } + + /** + * include create new user template + */ + public function createUserTemplate(){ + require_once('templates/CreateUserTemplate.php'); + } + + /** + * include link customers template + */ + public function linkCustomersTemplate(){ + require_once('templates/LinkCustomersTemplate.php'); + } + + /** + * returns json array with all the users from the webshop + * @return array with users info + */ + public function getUsers(){ + echo json_encode($this->model->getUsers()); + } + + /** + * get all the user types available in the webshop + * @return array of user types + */ + public function getUserTypes() { + echo json_encode($this->model->getUserTypes()); + } + + /** + * get all the commercial leads from the webshop + * @return array with all available commercial leads + */ + public function getCommercialLeads() { + echo json_encode($this->model->getCommercialLeads()); + } + + /** + * add new user in DB + * @return confirmation message + */ + public function saveUserInDB() { + $info = isset($_REQUEST['info']) ? $_REQUEST['info'] : ''; + $commercialLeads = isset($_REQUEST['cl']) ? $_REQUEST['cl'] : ''; + echo json_encode($this->model->saveUserInDB($info, $commercialLeads)); + } + + /** + * get the list of customers and commercial leads + * @return Array list of customers and comemrcial leads + */ + public function getCustomersAndCl() { + echo json_encode($this->model->getCustomersAndCl()); + } + + public function updateLinkedCustomers(){ + $idCommercialLead = isset($_REQUEST['idCommercialLead']) ? $_REQUEST['idCommercialLead'] : 0; + $customers = isset($_REQUEST['customers']) ? $_REQUEST['customers'] : '[]'; + echo json_encode($this->model->updateLinkedCustomers($idCommercialLead, $customers)); + } + + /** + * get the list of all the companies available + * @return Array all the companies available in the system + */ + public function getCompanies() { + echo json_encode($this->model->getCompanies()); + } + + /** + * open users page + */ + public function showPage(){ + global $user; + require_once('UsersPage.php'); + } +} diff --git a/api-wiaas/server/components/v1/users/UsersModel.php b/api-wiaas/server/components/v1/users/UsersModel.php new file mode 100644 index 0000000..7739302 --- /dev/null +++ b/api-wiaas/server/components/v1/users/UsersModel.php @@ -0,0 +1,630 @@ +query($sql); + while($row = $database->fetchArray($query)) { + $row['type'] = ucfirst($row['type']); + $row['type'] = str_replace('_', ' ', $row['type']); + $data[$row['type']][] = $row; + } + + return $data; + } + + /** + * gets all the user tyeps/roles from the DB + * @return Array of user types + */ + public function getUserTypes() { + global $database; + $data=[]; + + $sql = "SELECT + id, + type AS name + FROM ".TABLES['user_types']." + "; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['name'] = ucfirst($row['name']); + $row['name'] = str_replace('_', ' ', $row['name']); + $data[] = $row; + } + + return $data; + } + + /** + * gets all the commercial leads from the DB + * @return Array with all the commercial leads + */ + public function getCommercialLeads() { + global $database; + + $sql = "SELECT + id, + name + FROM ".TABLES['commercial_leads']." + "; + + return $database->fetchResultArray($sql); + } + + /** + * @param info - array with all the details regarding new user + * @param commercialLeads - array with all the commercial leads + * @return Array array with the code and the message of confirmation for adding the user in the DB + */ + public function saveUserInDB($info, $commercialLeads = '') { + global $database; + $info = (array) json_decode($info); + $commercialLeads = json_decode($commercialLeads); + $data = []; + + foreach($info as $key => $value) { + $info['$key'] = $database->escapeValue($value); + $checkMessage = $database->isEmpty($key, $value); + if($checkMessage){ + $data['messages'][] = $checkMessage; + + return $data; + } + } + + $messageData = $this->validateUserData($info, $commercialLeads); + if(!empty($messageData)){ + return $messageData; + } + + $token = bin2hex(random_bytes(16)); + $idUser = $this->getInsertedIdForUsers($info, $token); + if(is_array($idUser)) { + return $idUser; + } + + if($data = $this->insertUserTypeRelation($idUser, $info['idUserType'])) { + return $data; + } + + $data = $this->insertUserInfo($idUser, $info, $commercialLeads); + $info['type'] = $this->getUserTypeByIdForMail($info['idUserType']); + $data['messages'][] = UtilsModel::sendUserConfirmationMail($info, $info['mail'], 'create', $token); + + return $data; + } + + /** + * get user type by id for mail + * @param Int $idUserType the id of the user type + * @return String 'customer' or 'other' based on the user type + */ + private function getUserTypeByIdForMail($idUserType) { + global $database; + + $sql = "SELECT type FROM ".TABLES['user_types']." ut WHERE ut.id=".$idUserType; + $result = $database->fetchResultArray($sql); + + return $result && $result[0]['type'] === USER_TYPES['CUSTOMER'] ? 'customer' : 'other'; + } + + /** + * validate user data from GUI + * @param Array $info all information about the user to be inserted + * @param Array $commercialLeads all the commercial leads linked to a customer + * @return Array empty or error message + */ + private function validateUserData($info, $commercialLeads) { + global $database; + $data = []; + + if(!$info['idUserType']) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'SELECT_USER_TYPE' + ]; + + return $data; + } + + if($info['idUserType'] === '2' && empty($commercialLeads)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NO_COMMERCIAL_LEAD_LINK' + ]; + + return $data; + } + + if(!isset($info['name']) || empty($info['name'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_NAME' + ]; + + return $data; + } + $checkMessage = $database->invalidLength('name', $info['name'], 70); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(array_key_exists('selectedCompanyId', $info)) { + if(!$info['selectedCompanyId']) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'COMPANY_EMPTY' + ]; + + return $data; + } + } + + if(!array_key_exists('selectedCompanyId', $info)) { + if(!isset($info['companyName']) || empty($info['companyName'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_COMPANY_NAME' + ]; + + return $data; + } + $checkMessage = $database->invalidLength('companyName', $info['companyName'], 100); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!isset($info['vat']) || empty($info['vat'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_VAT' + ]; + + return $data; + } + } + + if(!isset($info['phone']) || empty($info['phone'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_PHONE' + ]; + + return $data; + } + if(!preg_match('/^([0-9\(\)\/\+ \-]*)$/', $info['phone'])){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_PHONE_NUMBER' + ]; + } + + $checkMessage = $database->invalidLength('phone', $info['phone'], 40); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!isset($info['username']) || empty($info['username'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_USERNAME' + ]; + + return $data; + } + $checkMessage = $database->invalidLength('username', $info['username'], 20); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!preg_match('/^[a-zA-Z\d\.\-_]+$/',$info['username'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_USERNAME' + ]; + } + + $sql = "SELECT username + FROM ".TABLES['users']." + WHERE username='".$info['username']."' + LIMIT 1"; + $result = $database->query($sql); + if($database->numRows($result) > 0) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'USERNAME_EXISTS' + ]; + } + + if(!isset($info['mail']) || empty($info['mail'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_MAIL' + ]; + + return $data; + } + if(!filter_var($info['mail'], FILTER_VALIDATE_EMAIL)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_MAIL' + ]; + } + + return $data; + } + + /** + * inserts username, password and mail into users table + * @param String $info the data array with all user info + * @param String $token the token for newly created user + * @return Int the id of the user inserted + */ + private function getInsertedIdForUsers($info, $token) { + global $database, $user; + $tokenTimestamp = new DateTime(); + + if(!array_key_exists('selectedCompanyId', $info)) { + $idCompany = $this->insertCompanyAndReturnId($info['companyName'], $info['vat']); + + if(is_array($idCompany)) { + return $idCompany; + } + } else { + $idCompany = $info['selectedCompanyId']; + } + $isCompanyAdmin = array_key_exists('companyAdmin', $info) && $info['companyAdmin'] ? 1 : 0; + + $sql = "INSERT INTO ".TABLES['users']." (idCompany, username, mail, token, tokenTS, isCompanyAdmin) + VALUES ( + $idCompany, + '".$info['username']."', + '".$info['mail']."', + '".$token."', + '".$tokenTimestamp->format('Y-m-d H:i:s')."', + $isCompanyAdmin + )"; + $result = $database->query($sql); + + return $database->getInsertId(); + } + + /** + * inserts the new company data + * @param String $name the name of the company + * @param String $vat the vat code for the company + * @return Int the id of the company inserted + */ + private function insertCompanyAndReturnId($name, $vat) { + global $database; + + $sql = "SELECT name FROM ".TABLES['company']." WHERE name='$name'"; + $query = $database->query($sql); + if($database->numRows($query)) { + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'COMPANY_EXISTS' + ]; + + return $data; + } + + $sql = "INSERT INTO ".TABLES['company']." + (vatCode, name) + VALUES + ('$vat', '$name') + "; + $result = $database->query($sql); + + return $database->getInsertId(); + } + + /** + * inserts the relation between user and user type + * @param Int $idUser id of the user inserted + * @param Int $idType id of the user type to be inserted + * @return Array empty or error message + */ + private function insertUserTypeRelation($idUser, $idType) { + global $database; + $data = []; + + $sql = "INSERT INTO ".TABLES['rel_user_type']." + VALUES( + $idUser, + $idType + )"; + $result = $database->query($sql); + + if(!$database->affectedRows()) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_USER_TYPE' + ]; + } + + return $data; + } + + /** + * insert user information + * @param Int $idUser id of the user inserted + * @param Array $info all the information needed for the user + * @param Array $commercialLeads commercial leads to link to customer + * @return Array confirmation message + */ + private function insertUserInfo($idUser, $info, $commercialLeads) { + global $database; + $data = []; + $shouldLinkCommercialLeads = false; + + switch ($info['idUserType']) { + // broker + case '1': + $table = TABLES['brokers']; + break; + // customer + case '2': + $table = TABLES['customers']; + $shouldLinkCommercialLeads = true; + break; + // commercial lead + case '3': + $table = TABLES['commercial_leads']; + break; + // supplier + case '4': + $table = TABLES['suppliers']; + break; + default: + break; + } + + $sql = "INSERT INTO $table (idUser, name, phone) + VALUES ( + ".$idUser.", + '".$info['name']."', + '".$info['phone']."' + )"; + $result = $database->query($sql); + if($database->affectedRows()) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'USER_INSERTED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_USER_INFO' + ]; + } + + if($shouldLinkCommercialLeads) { + $idCustomer = $database->getInsertId(); + $values = ''; + foreach($commercialLeads as $commercialLead) { + $values .= "(".$commercialLead->id.", $idCustomer),"; + } + $values = rtrim($values, ','); + + $sql = "INSERT INTO ".TABLES['rel_commercial_lead_customers']." + (idCommercialLead, idCustomer) + VALUES $values"; + $result = $database->query($sql); + + if(!$database->affectedRows()) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_USER_CL' + ]; + } + } + + return $data; + } + + /** + * get customers linked to comemrcial leads + * @return Array list of customers grouped by commercial lead id + */ + private function getCommercialLeadsCustomers(){ + global $database; + $data = []; + + $sql = "SELECT + rclc.idCommercialLead, + rclc.idCustomer as id, + c.name + FROM ".TABLES['rel_commercial_lead_customers']." rclc + INNER JOIN ".TABLES['customers']." c + ON c.id=rclc.idCustomer + WHERE rclc.isLinkEnabled=1 + ORDER BY name"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idCommercialLead']][] = $row; + } + + return $data; + } + + /** + * get all customers and commercial leads in the system (included linked custoemrs to commercial lead) + * @return Array list of customers and list of commercial leads + */ + public function getCustomersAndCl() { + global $database; + $data = []; + $clCustomers = $this->getCommercialLeadsCustomers(); + + $sql = "SELECT + c.id AS id, + c.name AS name, + 'customers' AS userType + FROM ".TABLES['customers']." c + UNION ALL + SELECT + cl.id AS id, + cl.name AS name, + 'commercialLeads' AS userType + FROM ".TABLES['commercial_leads']." cl + ORDER BY userType, name"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + if($row['userType'] === 'commercialLeads'){ + $row['linkedCustomers'] = isset($clCustomers[$row['id']]) ? $clCustomers[$row['id']] : []; + } + $data[$row['userType']][] = $row; + } + + return $data; + } + + /** + * update customers for a commercial lead + * @param INT $idCommercialLead id for the commercial lead + * @param Array $customers list of customers to be linked + * @return Array update message + */ + public function updateLinkedCustomers($idCommercialLead, $customers){ + global $database; + $data = []; + $idCommercialLead = $database->escapeValue($idCommercialLead); + $customers = json_decode($customers); + + if(intval($idCommercialLead) == 0){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_COMMERCIAL_LEAD' + ]; + } + + $sqlCustomers = "SELECT rclc.idCustomer + FROM ".TABLES['rel_commercial_lead_customers']." rclc + WHERE idCommercialLead=$idCommercialLead"; + $query = $database->query($sqlCustomers); + $availableCustomers = []; + while($row = $database->fetchArray($query)){ + $availableCustomers[] = $row['idCustomer']; + } + + $sqlIns = ""; + $customersToUpdate = []; + $updated = 0; + foreach ($customers as $customer) { + if(!in_array($customer->id, $availableCustomers)){ + $customer->id = $database->escapeValue($customer->id); + $sqlIns .= "($idCommercialLead, ".$customer->id."),"; + } + + $customersToUpdate[] = $customer->id; + } + $sqlIns = rtrim($sqlIns, ','); + + if(!empty($sqlIns)){ + $sql = "INSERT IGNORE INTO ".TABLES['rel_commercial_lead_customers']." + (idCommercialLead, idCustomer) + VALUES $sqlIns"; + $query = $database->query($sql); + $updated += $database->affectedRows(); + } + + if(!empty($customersToUpdate)){ + $customersToUpdate = implode(',', $customersToUpdate); + $sqlUpd = "UPDATE ".TABLES['rel_commercial_lead_customers']." + SET isLinkEnabled=1 + WHERE idCommercialLead=$idCommercialLead AND idCustomer IN($customersToUpdate)"; + $query = $database->query($sqlUpd); + $updated += $database->affectedRows(); + + $sqlUnlink = "UPDATE ".TABLES['rel_commercial_lead_customers']." + SET isLinkEnabled=0 + WHERE idCommercialLead=$idCommercialLead AND idCustomer NOT IN($customersToUpdate)"; + $query = $database->query($sqlUnlink); + $updated += $database->affectedRows(); + } + + + if($updated > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'CUSTOMERS_LINKED_TO_CL' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + } + + return $data; + + } + + /** + * returns the companies name and id + * @return Array companies available in the application + */ + public function getCompanies() { + global $database; + + $sql = " + SELECT + c.id, + c.name + FROM + ".TABLES['company']." c + ORDER BY name"; + + return $database->fetchResultArray($sql); + } +} diff --git a/api-wiaas/server/components/v1/users/UsersPage.php b/api-wiaas/server/components/v1/users/UsersPage.php new file mode 100644 index 0000000..8805232 --- /dev/null +++ b/api-wiaas/server/components/v1/users/UsersPage.php @@ -0,0 +1,9 @@ + + + + + +
+

{{ 'users.TITLE' | translate }}

+ +
diff --git a/api-wiaas/server/components/v1/users/templates/CreateUserButton.html b/api-wiaas/server/components/v1/users/templates/CreateUserButton.html new file mode 100644 index 0000000..ac39bbe --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/CreateUserButton.html @@ -0,0 +1,5 @@ + diff --git a/api-wiaas/server/components/v1/users/templates/CreateUserLayer.html b/api-wiaas/server/components/v1/users/templates/CreateUserLayer.html new file mode 100644 index 0000000..400bba6 --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/CreateUserLayer.html @@ -0,0 +1,4 @@ +
+ +
diff --git a/api-wiaas/server/components/v1/users/templates/CreateUserTemplate.php b/api-wiaas/server/components/v1/users/templates/CreateUserTemplate.php new file mode 100644 index 0000000..b3b846c --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/CreateUserTemplate.php @@ -0,0 +1,149 @@ +
+

{{ 'users.headers.CREATE_USER' | translate }}

+ +
+
+
+
+ + +
+
+ + +
+ +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+ + {{'users.headers.SET_COMMERCIAL_LEAD' | translate}} +
+
+
+
+ {{'users.headers.SELECT_CL' | translate}} +
+
+ {{'users.headers.SELECTED_CL' | translate}} +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+
+
+
+
+
+
+
+ + +
+
+
diff --git a/api-wiaas/server/components/v1/users/templates/LinkCustomersButton.html b/api-wiaas/server/components/v1/users/templates/LinkCustomersButton.html new file mode 100644 index 0000000..1673e00 --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/LinkCustomersButton.html @@ -0,0 +1,5 @@ + diff --git a/api-wiaas/server/components/v1/users/templates/LinkCustomersLayer.html b/api-wiaas/server/components/v1/users/templates/LinkCustomersLayer.html new file mode 100644 index 0000000..3411993 --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/LinkCustomersLayer.html @@ -0,0 +1,4 @@ + diff --git a/api-wiaas/server/components/v1/users/templates/LinkCustomersTemplate.php b/api-wiaas/server/components/v1/users/templates/LinkCustomersTemplate.php new file mode 100644 index 0000000..a13ff04 --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/LinkCustomersTemplate.php @@ -0,0 +1,65 @@ + diff --git a/api-wiaas/server/components/v1/users/templates/ShowEditUsersTemplate.php b/api-wiaas/server/components/v1/users/templates/ShowEditUsersTemplate.php new file mode 100644 index 0000000..3e404a3 --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/ShowEditUsersTemplate.php @@ -0,0 +1,73 @@ +
+
+ + +
+
+
+ {{type}} +
+
+
+
+
+
+ {{userInfo.name}} + + (
) +
+
+
+
+
+
+
+
{{userInfo.phone}}
+
+
+
+
{{userInfo.mail}}
+
+
+
+
{{type}}
+
+
+
+
{{userInfo.username}}
+
+
+
+ +
+ {{'users.buttons.EDIT_USER' | translate}} +
+
+
+ {{'users.buttons.FORGET_PASSWORD' | translate}} +
+
+
+
+
+
+
+

Legend:

+
+
is company admin +
+
+
+
+ +
+

{{'users.forms.messages.GENERATE_PASSWORD' | translate}}?

+
diff --git a/api-wiaas/server/components/v1/users/templates/UsersTemplate.php b/api-wiaas/server/components/v1/users/templates/UsersTemplate.php new file mode 100644 index 0000000..81fede4 --- /dev/null +++ b/api-wiaas/server/components/v1/users/templates/UsersTemplate.php @@ -0,0 +1,29 @@ + + + +getUserType() === USER_TYPES['BROKER']){ + require_once('CreateUserButton.html'); + require_once('LinkCustomersButton.html'); + } + ?> + +
+
+

{{ 'users.headers.SHOW_USERS' | translate }}

+ +
+
+ +getUserType() === USER_TYPES['BROKER']){ + require_once('CreateUserLayer.html'); + require_once('LinkCustomersLayer.html'); + } + ?> diff --git a/api-wiaas/server/components/v1/utils/UtilsController.php b/api-wiaas/server/components/v1/utils/UtilsController.php new file mode 100644 index 0000000..7d8988d --- /dev/null +++ b/api-wiaas/server/components/v1/utils/UtilsController.php @@ -0,0 +1,47 @@ +model = new UtilsModel(); + } + + public function saveJSError(){ + $message = isset($_REQUEST['message']) ? $_REQUEST['message'] : ''; + $stack = isset($_REQUEST['stack']) ? $_REQUEST['stack'] : ''; + $this->model->saveJSError($message, $stack); + } + + public function checkActivityStatus(){ + echo json_encode($this->model->checkActivityStatus()); + } + + public function sendTestMail(){ + echo $this->model->sendTestMail(); + } + + public function errorDialogTemplate(){ + require_once('templates/errorDialogTemplate.php'); + } + + public function activityCheckerTemplate(){ + require_once('templates/activityCheckerTemplate.php'); + } + + public function changePassword() { + $passwords = isset($_REQUEST['passwords']) ? $_REQUEST['passwords'] : ''; + echo json_encode($this->model->changePassword($passwords)); + } + + public function generateTokenForUserPassword() { + $userInfo = isset($_REQUEST['userInfo']) ? $_REQUEST['userInfo'] : ''; + echo json_encode($this->model->generateTokenForAllUsersPassword($userInfo)); + } + + public function downloadFile(){ + $fileName = isset($_REQUEST['fileName']) ? $_REQUEST['fileName'] : ''; + $idDocument = isset($_REQUEST['idDocument']) ? $_REQUEST['idDocument'] : ''; + $fileType = isset($_REQUEST['fileType']) ? $_REQUEST['fileType'] : ''; + echo $this->model->downloadFile($idDocument, $fileName, $fileType); + } +} diff --git a/api-wiaas/server/components/v1/utils/UtilsModel.php b/api-wiaas/server/components/v1/utils/UtilsModel.php new file mode 100644 index 0000000..de705a5 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/UtilsModel.php @@ -0,0 +1,477 @@ +escapeValue($message); + $stack = $database->escapeValue($stack); + + $errorHandler->addLog('JavaScript' . PHP_EOL . $message . PHP_EOL . $stack); + } + + public function checkActivityStatus(){ + global $user; + + $lastActivity = $user->getLastActivity(); + + $data['hasSessionExpired'] = (time() - $lastActivity) >= SESSION_LIFE_TIME; + + return $data; + } + + public function sendTestMail(){ + $response = Mail::sendMail('snr_dash@saguaronet.ro', 'test mail ', 'testTemplate.php', ['variable' => 'This is a dynamic value']); + + if($response){ + return "Mail has been sent!"; + } + + return "Mail send has failed!"; + } + + /** + * changes the password for the current user + * @param String $password if empty, a random pass will be generated + * @return Array confirmation message + */ + public static function changePassword($passwords, $username = '') { + global $database, $user; + $passwords = (array) json_decode($passwords); + if($userInfo = self::getUserData($username)) { + $userInfo = $userInfo[0]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'WRONG_USERNAME' + ]; + + return $data; + } + $isForReset = $username ? true : false; + + if($data = self::validatePassword($userInfo['username'], $passwords, $isForReset)) { + return $data; + } + + $password = $passwords['newPassword']; + $passwordHashed = $user->hashPassword($database->escapeValue($password)); + + $sql = "UPDATE + ".TABLES['users']." u + SET + u.password='".$passwordHashed."', + u.token=null, + u.tokenTS=null + WHERE u.username='".$database->escapeValue($userInfo['username'])."'"; + + $result = $database->query($sql); + if($database->affectedRows() == 1) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PASSWORD_GENERATED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_PASSWORD_GENERATED' + ]; + } + $data['messages'][] = self::sendUserConfirmationMail($userInfo, $userInfo['mail'], 'change'); + + return $data; + } + + public function generateTokenForAllUsersPassword($userInfo){ + global $database; + $userInfo = json_decode($userInfo); + $userInfo->mail = $database->escapeValue($userInfo->mail); + $data = ['messages' => []]; + + $sql = "SELECT + u.id AS idUser, + u.username + FROM ".TABLES['users']." u + WHERE u.mail='".$userInfo->mail."'"; + $query = $database->query($sql); + + while($row = $database->fetchArray($query)){ + $newMessage = $this->generateTokenForUserPassword(json_encode($row)); + if(isset($newMessage['messages'])){ + $data['messages'] = array_merge($data['messages'], $newMessage['messages']); + } + } + + return $data; + + } + + /** + * generates a new random password for the user provided + * @param Array $userInfo contains username and password for the user of the password to change + * @return Array confirmation message + */ + public static function generateTokenForUserPassword($userInfo) { + global $database, $user; + $userInfo = (array) json_decode($userInfo); + if($userInfo = self::getUserData($userInfo['username'])) { + $userInfo = $userInfo[0]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'WRONG_USERNAME' + ]; + + return $data; + } + + $token = bin2hex(random_bytes(16)); + $tokenTimestamp = new DateTime(); + $sql = "UPDATE + ".TABLES['users']." u + SET + u.token='".$token."', + u.tokenTS='".$tokenTimestamp->format('Y-m-d H:i:s')."' + WHERE u.username='".$database->escapeValue($userInfo['username'])."'"; + + $result = $database->query($sql); + if($database->affectedRows() == 1) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PASSWORD_GENERATED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_PASSWORD_GENERATED' + ]; + } + + $data['messages'][] = self::sendUserConfirmationMail($userInfo, $userInfo['mail'], 'generate', $token); + + return $data; + } + + /** + * send confirmation mail to user for creation + * @param String $userInfo + * @param String $password + * @param String $mail + * @return Array confirmation message + */ + public static function sendUserConfirmationMail($userInfo, $mail, $action, $token = '') { + + switch($action) { + case 'create': + $mailTitle = APPLICATION_NAME.' user created'; + $templateUrl = 'createUserTemplate.php'; + break; + case 'generate': + $mailTitle = APPLICATION_NAME.' password generated'; + $templateUrl = 'generatePasswordUserTemplate.php'; + break; + case 'change': + $mailTitle = APPLICATION_NAME.' password changed'; + $templateUrl = 'changedPasswordTemplate.php'; + break; + default: + return [ + 'code' => 'error', + 'message' => 'ACTION_NOT_SET' + ]; + + } + + $passwordValidationUrl = $userInfo['idUserType'] == self::ID_TYPE_CUSTOMER ? WIAAS_URL.'/changePassword/' . $token : WIAAS_URL.'/api-wiaas/login?token=' . $token; + + $params = [ + 'username' => $userInfo['username'], + 'wiaas' => $userInfo['type'] === USER_TYPES['CUSTOMER'] ? WIAAS_URL : WIAAS_URL.'/api-wiaas', + 'urlValidate' => $passwordValidationUrl + ]; + + $response = Mail::sendMail($mail, $mailTitle, $templateUrl, $params); + + if($response){ + return [ + 'code' => 'success', + 'message' => 'MAIL_SENT' + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + private static function validatePassword($username, $passwordData, $isForReset = false) { + global $database, $user; + $data = []; + + if ((!array_key_exists('newPassword', $passwordData) || $passwordData['newPassword'] === '') || + (!array_key_exists('confirmPassword', $passwordData) || $passwordData['confirmPassword'] === '')) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORDS_MISSING' + ]; + + return $data; + } + + $newPassword = $database->escapeValue($passwordData['newPassword']); + $confirmPassword = $database->escapeValue($passwordData['confirmPassword']); + + if(!$isForReset) { + if($data = self::validateOldPassword($passwordData, $username)) { + return $data; + } + $oldPassword = $database->escapeValue($passwordData['oldPassword']); + if($oldPassword === $newPassword) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORD_SAME' + ]; + return $data; + } + } + + if($newPassword !== $confirmPassword) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORD_MISMATCH' + ]; + + return $data; + } + + if((strlen($newPassword) < 8) || + !preg_match("/((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%-_]).{8,20})/", $newPassword) + ) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORD_INCORRECT' + ]; + } + + return $data; + } + + private static function validateOldPassword($passwordData, $username) { + global $database, $user; + $data = []; + + $oldPassword = $database->escapeValue($passwordData['oldPassword']); + + if (!array_key_exists('oldPassword', $passwordData) || $passwordData['oldPassword'] === '') { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORDS_MISSING' + ]; + + return $data; + } + + $sql = "SELECT u.password + FROM ".TABLES['users']." u + WHERE u.username='".$database->escapeValue($username)."' + LIMIT 1"; + $row = $database->fetchResultArray($sql); + + if($row[0] && $row[0]['password'] && !password_verify($oldPassword, $row[0]['password'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'OLD_PASSWORD_MISMATCH' + ]; + } + + return $data; + } + + /** + * fetches the username and the email for the user logged in + * @return Array username and mail + */ + private static function getUserData($username = '') { + global $database, $user; + + $username = $username ? $username : $user->getUser(); + + $sql = "SELECT + u.id AS idUser, + u.mail, + u.username, + ut.type, + rut.idType AS idUserType + FROM ".TABLES['users']." u + INNER JOIN ".TABLES['rel_user_type']." rut + ON rut.idUser=u.id + INNER JOIN ".TABLES['user_types']." ut + ON ut.id=rut.idType + WHERE u.username='".$database->escapeValue($username)."'"; + + return $database->fetchResultArray($sql); + } + + /** + * send order confirmation email to user + * @param Array $cartPackages contains the packages ordered + * @param String $userType customer or broker + * @param Array $orderInfo contains information about the order like id, order number and so on + * @return Array confirmation message + */ + public static function sendOrderConfirmationMail($cartPackages, $userType, $orderInfo) { + $mail = ''; + $orderUrl = WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$orderInfo['idOrder'].'&orderNumber='.$orderInfo['orderNumber']; + + if($userType === USER_TYPES['CUSTOMER']) { + $templateUrl = 'orderConfirmationTemplate.php'; + $mailTitle = 'Order successfully placed'; + $userData = self::getUserData(); + + if($userData && $userData[0]['mail']) { + $mail = $userData[0]['mail']; + } + $message = 'MAIL_SENT'; + $orderUrl = WIAAS_URL.'/orders/'.$orderInfo['idOrder']; + } else if($userType === USER_TYPES['BROKER']){ + $templateUrl = 'orderConfirmationBrokerTemplate.php'; + $mailTitle = 'New order placed'; + $brokerData = self::getBrokersMail(); + + if($brokerData) { + $mail = $brokerData; + } + $message = 'BROKER_MAIL_SENT'; + } + + $currentDate = new DateTime(); + $currentDate = $currentDate->format('d-m-Y H:i'); + + $params = [ + 'cartPackages' => $cartPackages, + 'currentDate' => $currentDate, + 'orderNumber' => $orderInfo['orderNumber'], + 'orderDate' => $orderInfo['orderDate'], + 'orderUrl' => $orderUrl + ]; + $response = Mail::sendMail($mail, $mailTitle, $templateUrl, $params); + + if($response){ + return [ + 'code' => 'success', + 'message' => $message + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + public static function getBrokersMail() { + global $database; + + $sql="SELECT u.mail + FROM ".TABLES['brokers']." b + INNER JOIN ".TABLES['users']." u + ON u.id = b.idUser"; + + $result = $database->query($sql); + while($row = $database->fetchArray($result)) { + if($row['mail'] !== '') { + $mailArray[] = $row['mail']; + } + } + return (count($mailArray) === 0 || count($mailArray) > 1) ? $mailArray : $mailArray[0]; + } + + public static function sendOrderUpdateMail($mailType, $params, $mailTitle, $mails) { + global $user; + $templateUrl = $mailType.'Template.php'; + $response = ''; + + if(array_key_exists('customer', $mails) && count($mails['customer'])) { + $response = Mail::sendMail($mails['customer'], $mailTitle, $templateUrl, $params); + } + + if($user->getUserType() !== USER_TYPES['BROKER']) { + $usersMails = array_key_exists('other', $mails) ? (array) $mails['other'] : []; + $brokerMails = (array) self::getBrokersMail(); + $mails['other'] = array_merge($usersMails, $brokerMails); + $params['orderUrl'] = $params['apiOrderUrl']; + } + + if(array_key_exists('other', $mails)) { + $response = Mail::sendMail($mails['other'], $mailTitle, $templateUrl, $params); + } + + if($response){ + return [ + 'code' => 'success', + 'message' => 'ORDER_UPDATE_MAIL_SENT' + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + public function downloadFile($idDocument, $fileName, $fileType){ + $fileManager = new FileManager(); + + return $fileManager->downloadFile($idDocument, $fileName, $fileType); + } + + /** + * returns the mail and order number for an order + * @param Int $idOrder the id of the order + * @return Array mail of the customer and the order number + */ + public static function getDataForMailToCustomer($idOrder) { + global $database; + + $sqlCustomerInfo = "SELECT u.mail, + o.orderNumber + FROM ".TABLES['customers']." c + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON c.id=rclc.idCustomer + INNER JOIN ".TABLES['users']." u + ON u.id = c.idUser + INNER JOIN ".TABLES['orders']." o + ON o.idCustomerInstance=rclc.id + WHERE o.id=$idOrder + LIMIT 1"; + $query = $database->query($sqlCustomerInfo); + + return $database->fetchArray($query); + } + + /** + * get the orderNumber based on the order id + * @param Int $idOrder the id of the order + * @return Int the order number of that order + */ + public static function getOrderNumberById($idOrder) { + global $database; + + $sql = " + SELECT + o.orderNumber + FROM + ".TABLES['orders']." o + WHERE o.id = $idOrder + LIMIT 1 + "; + $orderNumberArray = $database->fetchResultArray($sql); + if($orderNumberArray && $orderNumberArray[0]) { + return array_key_exists('orderNumber', $orderNumberArray[0]) ? $orderNumberArray[0]['orderNumber'] : ''; + } + + return ''; + } +} diff --git a/api-wiaas/server/components/v1/utils/mail_templates/changedPasswordTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/changedPasswordTemplate.php new file mode 100644 index 0000000..24e4ce6 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/changedPasswordTemplate.php @@ -0,0 +1,18 @@ + + + + + + + + Hello,

+ Welcome back to {APPLICATION_NAME}!
+ The password was changed successfully for {username}!

+ Please use this link to login: {wiaas}. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/createUserTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/createUserTemplate.php new file mode 100644 index 0000000..acb2d88 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/createUserTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ Welcome to {APPLICATION_NAME}!
+ Click on this link to set your password.
+ This link will expire after 5 days.

+ Please use this link to login: {wiaas}, after setting your password.
+ Your username is: {username}
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/customerScheduleInstallationEnabled.php b/api-wiaas/server/components/v1/utils/mail_templates/customerScheduleInstallationEnabled.php new file mode 100644 index 0000000..06194b5 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/customerScheduleInstallationEnabled.php @@ -0,0 +1,26 @@ + + + + + + + + Hello,

+ Welcome back to {APPLICATION_NAME}!
+ The schedule installation function for order {orderNumber} for package {packageName} is now active.

+ To propose a date for the installation, go to this link and click on Schedule installation button on the order details header.
+ There are displayed the earliest installation date (this is the date when all the products can be shipped in order to perform the installation),
+ the company which will perform the installation and the already proposed dates.
+ To propose a date, click on the Add optional date button and select a date which suites you to perform the installation.
+ Also the installation company user, {supplierName}, will propose a date/dates for its convenience.

+ After you propose a date, the installation company is notified, and he will accept or decline that date.
+ And reversed, if there is already a date proposed, you can accept or decline it.

+ Please note that there cannot be two dates accepted at the same time. If there is already an accepted date, and you accept another one, the first date accepted will be canceled and the last one will remain accepted.

+ You can access the application here.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/errorMailTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/errorMailTemplate.php new file mode 100644 index 0000000..be00a16 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/errorMailTemplate.php @@ -0,0 +1,11 @@ + + + + + + + + {errorMessage} + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/generatePasswordUserTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/generatePasswordUserTemplate.php new file mode 100644 index 0000000..4687f63 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/generatePasswordUserTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ Welcome back to {APPLICATION_NAME}!
+ You have requested a new password
+ Click on this link to reset your password. +
+ Your username is: {username}
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/installationAcceptedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/installationAcceptedTemplate.php new file mode 100644 index 0000000..f8d20fb --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/installationAcceptedTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ Installation date {acceptedDate} for order {orderNumber} was accepted by {actionDoneBy}.
+ You can go to {APPLICATION_NAME} to view more details.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/installationDateInvalidTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/installationDateInvalidTemplate.php new file mode 100644 index 0000000..af6fbf0 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/installationDateInvalidTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ The installation date accepted by both parties, {acceptedDate}, for order {orderNumber}, was marked invalid due to the confirmed shipping dates.
+ You can go to {APPLICATION_NAME} to propose new dates for the installation.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/installationDeclinedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/installationDeclinedTemplate.php new file mode 100644 index 0000000..0147075 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/installationDeclinedTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ All the proposed installation dates for order {orderNumber} were declined.
+ You can go to {APPLICATION_NAME} to propose new dates for the installation.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/installationProposedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/installationProposedTemplate.php new file mode 100644 index 0000000..5d8090e --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/installationProposedTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ {actionDoneBy} proposed a new installation date: {proposedDate} for order {orderNumber}.
+ Go to {APPLICATION_NAME} to plan the installation.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/installationSchedulingDisabled.php b/api-wiaas/server/components/v1/utils/mail_templates/installationSchedulingDisabled.php new file mode 100644 index 0000000..1716db8 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/installationSchedulingDisabled.php @@ -0,0 +1,18 @@ + + + + + + + + Hello,

+ The schedule installation function for order {orderNumber} is now disabled.

+ You will receive an email notification when this function will be re-actived.
+ Go to this link to see the status of your order.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/invalidQuestionnaireTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/invalidQuestionnaireTemplate.php new file mode 100644 index 0000000..d3785e6 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/invalidQuestionnaireTemplate.php @@ -0,0 +1,19 @@ + + + + + + + + Hello,

+ The questionnaire you have uploaded for the order {orderNumber} need to be modified! Please see the comments on order.
+ Reason:
+ {invalidQuestionaireReason}

+ You can download the file and upload it again using this link. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/lastStepCompletedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/lastStepCompletedTemplate.php new file mode 100644 index 0000000..ef35c47 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/lastStepCompletedTemplate.php @@ -0,0 +1,22 @@ + + + + + + + + Hello,
+
+ The order {orderNumber} has been updated in {currentDate}.
+ {prevStepMessage} + The delivery is now completed for the package: {packageName}. +
+
+ Access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/orderCommentAddedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/orderCommentAddedTemplate.php new file mode 100644 index 0000000..b85bfd8 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/orderCommentAddedTemplate.php @@ -0,0 +1,21 @@ + + + + + + + + Hello,
+
+ A new comment has been added by {userLoggedIn} for order {orderNumber} at {currentDate}:
+
+ {commentMessage}
+
+ You can access the order here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationBrokerTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationBrokerTemplate.php new file mode 100644 index 0000000..0c1a7d3 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationBrokerTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ An order has been placed successfully in {currentDate}.
+ Please go to {APPLICATION_NAME} to link a process to that package(s) from the order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationTemplate.php new file mode 100644 index 0000000..75ed3b8 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/orderConfirmationTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ Your order has been successfully submitted: {currentDate}.
+ The order {orderNumber}, date: {orderDate} includes the following order rows:
+ {cartPackages} +
+ Access {APPLICATION_NAME} here to see the progress of your order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/orderStatusChangedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/orderStatusChangedTemplate.php new file mode 100644 index 0000000..913b7ce --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/orderStatusChangedTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,
+
+ Your order {orderNumber} has been set to: {status} in {currentDate}.
+ {deliveryEstimationDateMessage} +
+ You can access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/orderStepUpdatedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/orderStepUpdatedTemplate.php new file mode 100644 index 0000000..a6ebbbe --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/orderStepUpdatedTemplate.php @@ -0,0 +1,21 @@ + + + + + + + + Hello,

+ The order {orderNumber} has been updated {currentDate}.
+
+ {prevStepMessage} + {currentStepMessage} +
+ Access {APPLICATION_NAME} here to check the progress of the order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/packageStatusChangedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/packageStatusChangedTemplate.php new file mode 100644 index 0000000..7ff49b5 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/packageStatusChangedTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,
+
+ The order row "{packageName}", of order {orderNumber}, has been changed to: {status} in {currentDate}.
+ {deliveryEstimationDateMessage} +
+ You can access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/processAssignedTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/processAssignedTemplate.php new file mode 100644 index 0000000..6cac2a8 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/processAssignedTemplate.php @@ -0,0 +1,19 @@ + + + + + + + + Hello,

+ We have now started processing the order {orderNumber} ({currentDate}).
+
+
+ Access {APPLICATION_NAME} here to check the progress of the order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/reUploadQuestionnaireTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/reUploadQuestionnaireTemplate.php new file mode 100644 index 0000000..79f9b1a --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/reUploadQuestionnaireTemplate.php @@ -0,0 +1,16 @@ + + + + + + + + Hello,

+ A new questionaire has been uploaded for the order {orderNumber} and needs validation! +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/scheduleMeetingTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/scheduleMeetingTemplate.php new file mode 100644 index 0000000..8e7a873 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/scheduleMeetingTemplate.php @@ -0,0 +1,21 @@ + + + + + + + + Hello,
+
+ The order's {orderNumber} follow-up meeting date has changed in {currentDate}.
+ {estimatedDateMessage} + {confirmedDateMessage} +
+ You can access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} team + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/supportMailTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/supportMailTemplate.php new file mode 100644 index 0000000..8f73a5e --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/supportMailTemplate.php @@ -0,0 +1,59 @@ + + + + + + + + Hello,

+ {customerName} has sent an email for support for order {orderNumber}.
+
+

Customer details

+
+ Name: + {customerName} +
+
+ Mail: + {customerMail} +
+
+ Phone: + {customerPhone} +
+
+
+

Order details

+
+
+ # + Order number: {orderNumber} +
+
+ + Location details: {reference} +
+
+ + Invoice reference: {tender} +
+
+ + Commercial lead: {commercialLead} +
+
+
+
+

Order Items

+ {orderItems} +
+
+

Customer's comment

+ {userText} +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + \ No newline at end of file diff --git a/api-wiaas/server/components/v1/utils/mail_templates/testTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/testTemplate.php new file mode 100644 index 0000000..ecd3278 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/testTemplate.php @@ -0,0 +1,13 @@ + + + + + + + + Hello,
+ This is a test message sent using SendGrid!
+ Variables can be used in templates: {variable} + + + diff --git a/api-wiaas/server/components/v1/utils/mail_templates/undoStepTemplate.php b/api-wiaas/server/components/v1/utils/mail_templates/undoStepTemplate.php new file mode 100644 index 0000000..26eeff6 --- /dev/null +++ b/api-wiaas/server/components/v1/utils/mail_templates/undoStepTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ The order {orderNumber} has been updated {currentDate}.
+
+ The step {processStepName} is currently in progress. +
+ Access {APPLICATION_NAME} here to check the progress of your order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v1/utils/templates/activityCheckerTemplate.php b/api-wiaas/server/components/v1/utils/templates/activityCheckerTemplate.php new file mode 100644 index 0000000..0595e6d --- /dev/null +++ b/api-wiaas/server/components/v1/utils/templates/activityCheckerTemplate.php @@ -0,0 +1,11 @@ +
+
+ + {{ 'activity.messages.SESSION_EXPIRED_MESSAGE' | translate }} + {{ 'activity.messages.LOGIN_LINK' | translate }} +
+
diff --git a/api-wiaas/server/components/v1/utils/templates/errorDialogTemplate.php b/api-wiaas/server/components/v1/utils/templates/errorDialogTemplate.php new file mode 100644 index 0000000..61cd1ca --- /dev/null +++ b/api-wiaas/server/components/v1/utils/templates/errorDialogTemplate.php @@ -0,0 +1,7 @@ +
+
+ + There seems to be an error! + A message has been sent to the support team. Please refresh the application by clicking here! +
+
diff --git a/api-wiaas/server/components/v2/bids/Bids.php b/api-wiaas/server/components/v2/bids/Bids.php new file mode 100644 index 0000000..3375194 --- /dev/null +++ b/api-wiaas/server/components/v2/bids/Bids.php @@ -0,0 +1,115 @@ +getInterestRate()['interestRate']; + $interestRateCustomers = $interestRate->getInterestRateForCustomers(); + + $sql = "SELECT + pb.id AS idBid, + pb.bidNumber, + pb.idPackage, + p.name AS packageName, + pb.idCustomerInstance, + pb.fixedExtra, + pb.recurrentExtra, + pb.servicesExtra, + c.id AS idCustomer, + c.name AS customer, + cl.name AS commercialLead, + pb.idPaymentType, + pt.payType, + pt.packagePayPeriod, + pt.periodUnit, + DATE_FORMAT(pb.startDate, '%D %b, %Y') AS startDate, + DATE_FORMAT(pb.endDate, '%D %b, %Y') AS endDate, + pb.fixedPrice, + pb.principalAmount, + pb.servicesPrice + FROM ".TABLES['packages_bids']." pb + INNER JOIN ( + SELECT wsc.idPackage, wsc.idCustomerInstance, plcl.idPaymentType + FROM ".TABLES['web_shop_cart']." wsc + INNER JOIN ".TABLES['price_list_commercial_lead']." plcl + ON plcl.id=wsc.idPrice + WHERE wsc.idUser=".$user->getUserId()." + ) wsc + ON wsc.idPackage=pb.idPackage AND wsc.idCustomerInstance=pb.idCustomerInstance AND wsc.idPaymentType=pb.idPaymentType + INNER JOIN ".TABLES['packages']." p + ON p.id=pb.idPackage + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=pb.idCustomerInstance + INNER JOIN ".TABLES['customers']." c + ON c.id=rclc.idCustomer + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['payment_types']." pt + ON pt.id=pb.idPaymentType + WHERE pb.endDate > NOW() + ORDER BY pb.bidNumber"; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $interestRateCust = $row['idCustomer'] && isset($interestRateCustomers[$row['idCustomer']]) ? + floatval($interestRateCustomers[$row['idCustomer']]) : + $interestRateValue; + $row['recurrentPrice'] = $row['packagePayPeriod'] > 0 + ? $pricesHandler->PMT($interestRateCust / 100, $row['packagePayPeriod'], $row['principalAmount']) + : 0; + + $row['fixedPrice'] = floatval($row['fixedPrice']) + floatval($row['fixedExtra']); + $row['recurrentPrice'] = floatval($row['recurrentPrice']) + floatval($row['recurrentExtra']); + $row['servicesPrice'] = floatval($row['servicesPrice']) + floatval($row['servicesExtra']); + unset($row['fixedExtra']); + unset($row['recurrentExtra']); + unset($row['servicesExtra']); + $bids[$row['idPackage']][] = $row; + } + + return $bids; + } + + public function setBidForCart($idBid, $idCart){ + global $database; + $data = []; + + if(!$idBid){ + $idBid = 'NULL'; + } + + if(!$idCart){ + $data['messages'][] =[ + 'code' => 'error', + 'message' => 'CART_REQUIRED' + ]; + + return $data; + } + + $idBid = $database->escapeValue($idBid); + $idCart = $database->escapeValue($idCart); + + $sql = "UPDATE ".TABLES['web_shop_cart']." + SET idBid=$idBid + WHERE id=$idCart"; + $query = $database->query($sql); + + if($database->affectedRows() !== 1){ + $data['messages'][] =[ + 'code' => 'error', + 'message' => 'BID_NOT_USED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'BID_SET' + ]; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/bids/SupplierBids.php b/api-wiaas/server/components/v2/bids/SupplierBids.php new file mode 100644 index 0000000..2937091 --- /dev/null +++ b/api-wiaas/server/components/v2/bids/SupplierBids.php @@ -0,0 +1,103 @@ +fetchResultArray($sql); + } + + public function getProducts($idSupplier){ + global $database; + + $sql = "SELECT + p.idProduct, + p.productName + FROM ".TABLES['suppliers_countries_products']." p + WHERE p.idSupplier=$idSupplier + ORDER BY p.productName"; + + return $database->fetchResultArray($sql); + } + + public function addSupplierBid($supplierBid){ + global $database; + + $supplierBid = json_decode($supplierBid); + + $sql = "INSERT INTO ".TABLES['supplier_bids']." + (idProduct, bidNumber) + VALUES(".$supplierBid->idProduct.", '".$supplierBid->bidNumber."')"; + + $query = $database->query($sql); + + if($database->affectedRows() !== 1){ + $data['messages'][] =[ + 'code' => 'error', + 'message' => 'SERVER_ERROR' + ]; + + return $data; + } + + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'SUPPLIER_BID_ADDED' + ]; + + return $data; + } + + public function getUnlinkedSupplierBids(){ + global $database; + $sql = "SELECT + sb.id AS idSupplierBid, + sb.bidNumber, + sb.idProduct, + p.productName, + s.name AS supplier + FROM ".TABLES['supplier_bids']." sb + INNER JOIN ".TABLES['suppliers_countries_products']." p + ON p.idProduct=sb.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=p.idSupplier + LEFT OUTER JOIN ".TABLES['rel_bid_supplier_bids']." rbsb + ON rbsb.idSupplierBid=sb.id + WHERE rbsb.idSupplierBid IS NULL"; + + return $database->fetchResultArray($sql); + } + + public function getLinkedSupplierBids(){ + global $database; + $data = []; + + $sql = "SELECT + sb.id AS idSupplierBid, + sb.bidNumber, + sb.idProduct, + p.productName, + s.name AS supplier, + rbsb.idBid + FROM ".TABLES['supplier_bids']." sb + INNER JOIN ".TABLES['suppliers_countries_products']." p + ON p.idProduct=sb.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=p.idSupplier + INNER JOIN ".TABLES['rel_bid_supplier_bids']." rbsb + ON rbsb.idSupplierBid=sb.id"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idBid']][] = $row; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/cart/CartController.php b/api-wiaas/server/components/v2/cart/CartController.php new file mode 100644 index 0000000..9793a56 --- /dev/null +++ b/api-wiaas/server/components/v2/cart/CartController.php @@ -0,0 +1,112 @@ +model = new CartModel(); + } + + /** + * get count of items in the cart + * @return json number of items in the cart + */ + public function getCartCount() { + echo json_encode($this->model->getCartCount(), JSON_NUMERIC_CHECK); + } + + /** + * get items in cart + * @return json with array list of items in the cart + */ + public function getCartItems() { + echo json_encode($this->model->getCartItems(), JSON_NUMERIC_CHECK); + } + + /** + * update the quantity in the cart for an item + * @return json update message + */ + public function updateQuantity() { + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + $idPrice = isset($_REQUEST['idPrice']) ? $_REQUEST['idPrice'] : 0; + $idCustomerInstance = isset($_REQUEST['idCustomerInstance']) ? $_REQUEST['idCustomerInstance'] : 0; + $quantity = isset($_REQUEST['quantity']) ? $_REQUEST['quantity'] : 1; + echo json_encode($this->model->updateQuantity($idPackage, $idCustomerInstance, $idPrice, $quantity)); + } + + /** + * remove items from carts + * @return json update message + */ + public function removeFromCart(){ + $idCart = isset($_REQUEST['idCart']) ? $_REQUEST['idCart'] : 0; + echo json_encode($this->model->removeFromCart($idCart)); + } + + /** + * upload a questionaire form the cart page + * @return json upload message + */ + public function uploadOrderDocument(){ + $file = isset($_FILES['file']) ? $_FILES['file'] : []; + $idDocumentType = isset($_REQUEST['idDocumentType']) ? $_REQUEST['idDocumentType'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + echo json_encode($this->model->uploadOrderDocument($file, $idDocumentType, $idPackage)); + } + + /** + * get document sfor packages in cart + * @return json Array of documents + */ + public function getCartDocuments(){ + $packages = isset($_REQUEST['packages']) ? $_REQUEST['packages'] : []; + echo json_encode($this->model->getCartDocuments($packages), JSON_NUMERIC_CHECK); + } + + public function setBidForCart(){ + $idBid = isset($_REQUEST['idBid']) ? $_REQUEST['idBid'] : 0; + $idCart = isset($_REQUEST['idCart']) ? $_REQUEST['idCart'] : 0; + + echo json_encode($this->model->setBidForCart($idBid, $idCart), JSON_NUMERIC_CHECK); + } + + /** + * get details of the customer logged in + * @return json array with neccessary details + */ + public function getCustomerDetails() { + echo json_encode($this->model->getCustomerDetails(), JSON_NUMERIC_CHECK); + } + + /** + * get all the countries + * @return json array with all countries + */ + public function getCountries() { + echo json_encode($this->model->getCountries()); + } + + /** + * save order delivery and billing addresses + * @return json Array messages + */ + public function saveOrderDetails(){ + $orderDetails = isset($_REQUEST['orderDetails']) ? $_REQUEST['orderDetails'] : []; + $cartItems = isset($_REQUEST['cartItems']) ? $_REQUEST['cartItems'] : []; + echo json_encode($this->model->saveOrderDetails($orderDetails, $cartItems), JSON_NUMERIC_CHECK); + } + + /** + * get document sfor packages in cart + * @return json Array of documents + */ + public function placeOrder(){ + $cartItems = isset($_REQUEST['cartItems']) ? $_REQUEST['cartItems'] : []; + $orderDetails = isset($_REQUEST['orderDetails']) ? $_REQUEST['orderDetails'] : []; + echo json_encode($this->model->placeOrder($cartItems, $orderDetails), JSON_NUMERIC_CHECK); + } + +} diff --git a/api-wiaas/server/components/v2/cart/CartModel.php b/api-wiaas/server/components/v2/cart/CartModel.php new file mode 100644 index 0000000..f9c097e --- /dev/null +++ b/api-wiaas/server/components/v2/cart/CartModel.php @@ -0,0 +1,1375 @@ + 1, + 'ID_OPTION_TYPE' => 2, + 'ID_ADDITONAL_TYPE' => 3 + ]; + + const DOCUMENT_TYPES = [ + 'ID_TEMPLATE_QUESIONNAIRE' => 1, + 'ID_CUSTOMER_QUESTIONNAIRE' => 2, + 'ID_TEMPLATE_AGREEMENT' => 6, + 'ID_CUSTOMER_AGREEMENT' => 7 + ]; + + const PRODUCT_CATEGORIES = [ + 'ITEMS' => 1, + 'INSTALLATION' => 2 + ]; + + /** + * get count of items in the cart + * @return Object number of items in the cart + */ + public function getCartCount(){ + global $database, $user; + + $sql = "SELECT COUNT(idPackage) as cartItemsCount + FROM ".TABLES['web_shop_cart']." + WHERE idUser=".$user->getUserId(); + + $data = $database->fetchResultArray($sql); + + return !empty($data) ? $data[0] : []; + } + + /** + * get items in cart + * @return array list of items in the cart + */ + public function getCartItems(){ + global $database, $user; + $data = [ + 'cartItems' => [] + ]; + $options = $this->getCartItemOptions(); + $additionalPackages = $this->getCartAdditionalPackages(); + $countries = new Countries(); + $packages = new Packages(); + $orderTypeInst = new OrderType(); + $interestRate = new InterestRate(); + $bidsHandler = new Bids(); + $bids = $bidsHandler->getCartBids(); + + $sql = "SELECT + cart.id as idCart, + cart.idPackage, + cart.idCustomerInstance, + cart.idPrice, + cart.packageInstance, + cart.idBid as idSelectedBid, + p.status, + rclc.isLinkEnabled, + p.name as packageName, + cl.id AS idCommercialLead, + cl.name as commercialLead, + pt.payType, + pt.periodUnit AS periodUnit, + pt.id AS idPayType, + cart.quantity + FROM ".TABLES['web_shop_cart']." cart + INNER JOIN ".TABLES['packages']." p + ON p.id=cart.idPackage + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=cart.idCustomerInstance + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['price_list_commercial_lead']." plcl + ON plcl.id=cart.idPrice + INNER JOIN ".TABLES['payment_types']." pt + ON pt.id=plcl.idPaymentType + INNER JOIN ".TABLES['price_list_broker']." plb + ON plb.idPackage=plcl.idPackage + AND plb.idPaymentType=plcl.idPaymentType + WHERE cart.idUser=".$user->getUserId(); + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $prices = $packages->getPricesForPackages($row['idCommercialLead'], $row['idPackage'], self::PACKAGE_TYPES['ID_STANDARD_TYPE'], $row['idPayType']); + if(count($prices[$row['idPackage']]) === 1){ + $price = $prices[$row['idPackage']][0]; + $row['fixedPrice'] = $price['fixedExtra']; + $row['recurentPrice'] = $price['recurentExtra']; + $row['servicesPrice'] = $price['servicesExtra']; + + $row['options'] = isset($options[$row['idCart']]) ? $options[$row['idCart']]['options'] : []; + $row['areOptionsAvailable'] = isset($options[$row['idCart']]) ? $options[$row['idCart']]['areOptionsAvailable'] : true; + $row['additionalPackages'] = isset($additionalPackages[$row['idCart']]) ? $additionalPackages[$row['idCart']]['additionalPackages'] : []; + $row['areAdditionalAvailable'] = isset($additionalPackages[$row['idCart']]) ? $additionalPackages[$row['idCart']]['areAdditionalAvailable'] : true; + $row['country'] = $countries->getCurrencyForPackage($row['idPackage']); + $row['bids'] = isset($bids[$row['idPackage']]) ? $bids[$row['idPackage']] : []; + $totalPackagePrice = $this->calculatePackageTotalPrice($row); + $row['totalPrices'] = $totalPackagePrice; + + $data['cartItems'][] = $row; + } + } + + $data['totalPrice'] = $this->getCartTotalPrice($data['cartItems']); + + return $data; + } + + /** + * get options for items in the cart + * @return Array list of options grouped by cart id + */ + private function getCartItemOptions(){ + global $database, $user; + $data = []; + $packages = new Packages(); + + $sql = "SELECT + wscep.idCart, + p.name AS packageName, + pog.name AS groupName, + rgo.idOptionPackage, + wsc.idPackage AS idParentPackage, + rclc.idCommercialLead AS idCommercialLead, + plcl.idPaymentType AS idPaymentType + FROM ".TABLES['web_shop_cart_extra_packages']." wscep + INNER JOIN ".TABLES['packages']." p + ON p.id=wscep.idExtraPackage + INNER JOIN ".TABLES['web_shop_cart']." wsc + ON wsc.id=wscep.idCart + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=wsc.idCustomerInstance + INNER JOIN ".TABLES['price_list_commercial_lead']." plcl + ON wsc.idPrice = plcl.id + INNER JOIN ".TABLES['rel_group_options']." rgo + ON rgo.idOptionPackage=wscep.idExtraPackage + INNER JOIN ".TABLES['package_option_groups']." pog + ON pog.id=rgo.idGroup AND pog.idPackage=wsc.idPackage + WHERE wsc.idUser=".$user->getUserId(); + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $packageOptionPrices = $packages->getPricesForPackages($row['idCommercialLead'], $row['idParentPackage'], self::PACKAGE_TYPES['ID_OPTION_TYPE']); + $allPrices = isset($packageOptionPrices[$row['idOptionPackage']]) ? $packageOptionPrices[$row['idOptionPackage']] : []; + $isPaymentTypePresent = array_search($row['idPaymentType'], array_column($allPrices, 'idPaymentType')); + $priceByPaymentTypeKey = $isPaymentTypePresent !== false ? $isPaymentTypePresent : -1; + $row['prices'] = $priceByPaymentTypeKey > -1 ? $allPrices[$priceByPaymentTypeKey] : []; + + $row['isAvailable'] = count($row['prices']) > 0; + $data[$row['idCart']]['options'][] = $row; + if(!isset($data[$row['idCart']]['areOptionsAvailable'])){ + $data[$row['idCart']]['areOptionsAvailable'] = true; + } + $data[$row['idCart']]['areOptionsAvailable'] = ($data[$row['idCart']]['areOptionsAvailable'] && $row['isAvailable']); + } + + + return $data; + } + + /** + * returns the additional packages from the cart + * @return [type] [description] + */ + private function getCartAdditionalPackages(){ + global $database, $user; + $packages = new Packages(); + + $data = []; + $sql = "SELECT + wscep.idCart, + p.name AS packageName, + wsc.idPackage AS idParentPackage, + rclc.idCommercialLead AS idCommercialLead, + plcl.idPaymentType AS idPaymentType, + rap.idAdditionalPackage AS idAdditionalPackage + FROM ".TABLES['web_shop_cart_extra_packages']." wscep + INNER JOIN ".TABLES['packages']." p + ON p.id=wscep.idExtraPackage + INNER JOIN ".TABLES['web_shop_cart']." wsc + ON wsc.id=wscep.idCart + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=wsc.idCustomerInstance + INNER JOIN ".TABLES['price_list_commercial_lead']." plcl + ON wsc.idPrice = plcl.id + INNER JOIN ".TABLES['rel_additional_packages']." rap + ON p.id=rap.idAdditionalPackage AND rap.idPackage=wsc.idPackage + WHERE wsc.idUser=".$user->getUserId()." AND p.idPackageType=".self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $additionalPackagesPrices = $packages->getPricesForPackages($row['idCommercialLead'], $row['idParentPackage'], self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']); + $allPrices = isset($additionalPackagesPrices[$row['idAdditionalPackage']]) ? $additionalPackagesPrices[$row['idAdditionalPackage']] : []; + $isPaymentTypePresent = array_search($row['idPaymentType'], array_column($allPrices, 'idPaymentType')); + $priceByPaymentTypeKey = $isPaymentTypePresent !== false ? $isPaymentTypePresent : -1; + $row['prices'] = $priceByPaymentTypeKey > -1 ? $allPrices[$priceByPaymentTypeKey] : []; + + $row['isAvailable'] = count($row['prices']) > 0; + $data[$row['idCart']]['additionalPackages'][] = $row; + if(!isset($data[$row['idCart']]['areAdditionalAvailable'])){ + $data[$row['idCart']]['areAdditionalAvailable'] = true; + } + $data[$row['idCart']]['areAdditionalAvailable'] = ($data[$row['idCart']]['areAdditionalAvailable'] && $row['isAvailable']); + } + + return $data; + } + + /** + * calculates and returns the total price for the order + * @param Array $cartItems all teh items in the cart with the details + * @return String total and recurrent price with it's currency + */ + private function getCartTotalPrice($cartItems) { + $totalPrice = 0; + $totalRecurrentPrice = 0; + $currency = ''; + $periodUnit = ''; + + foreach($cartItems as $item) { + $itemTotalPrice = $item['fixedPrice']; + $itemTotalRecurrentPrice = $item['recurentPrice'] + $item['servicesPrice']; + + if(count($item['options'])) { + foreach($item['options'] as $packageOption) { + if(count($packageOption['prices'])) { + $itemTotalPrice += (float) $packageOption['prices']['fixedExtra']; + $itemTotalRecurrentPrice += (float) $packageOption['prices']['recurentExtra'] + (float) $packageOption['prices']['servicesExtra']; + } + } + } + + if(count($item['additionalPackages'])) { + foreach($item['additionalPackages'] as $additionalPackage) { + if(count($additionalPackage['prices'])) { + $itemTotalPrice += (float) $additionalPackage['prices']['fixedExtra']; + $itemTotalRecurrentPrice += (float) $additionalPackage['prices']['recurentExtra'] + (float) $additionalPackage['prices']['servicesExtra']; + } + } + } + $itemTotalPrice *= $item['quantity']; + $itemTotalRecurrentPrice *= $item['quantity']; + + $totalPrice += $itemTotalPrice; + $totalRecurrentPrice += $itemTotalRecurrentPrice; + $currency = $item['country']['currency']; + $periodUnit = $item['periodUnit']; + } + + return $totalPrice . ' ' . $currency . ' ( '. $totalRecurrentPrice . ' ' . $currency . ' / ' . $periodUnit .' )'; + } + + /** + * update the quantity in the cart for an item + * @param INT $idPackage id for the package + * @param INT $idCustomerInstance id for the customer instance based on linking to cl + * @param INT $idPrice id for the price + * @param INT $quantity quantity value + * @return array update message + */ + public function updateQuantity($idPackage, $idCustomerInstance, $idPrice, $quantity){ + global $database, $user; + $data = []; + + $idPackage = $database->escapeValue($idPackage); + $idPrice = $database->escapeValue($idPrice); + $idCustomerInstance = $database->escapeValue($idCustomerInstance); + $quantity = $database->escapeValue($quantity); + + if($database->invalidNumber('QUANTITY', $quantity, 1, 100)){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_QUANTITY' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sqlUpd = "UPDATE ".TABLES['web_shop_cart']." + SET quantity=$quantity + WHERE idPackage=$idPackage + AND idPrice=$idPrice + AND idCustomerInstance=$idCustomerInstance + AND idUser=".$user->getUserId()." + "; + $query = $database->query($sqlUpd); + + if($database->affectedRows() !== 1){ + $err_mes = [ + 'code' => 'warning', + 'message' => 'NO_CHANGE' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $mes = [ + 'code' => 'success', + 'message' => 'QUANTITY_UPDATED' + ]; + $data['messages'][] = $mes; + + return $data; + } + + /** + * remove item from cart + * @param INT $idCart id for the cart + * @return array update message + */ + public function removeFromCart($idCart){ + global $database, $user; + $data = []; + + $idCart = $database->escapeValue($idCart); + + $sql = "DELETE FROM ".TABLES['web_shop_cart_extra_packages']." + WHERE idCart=$idCart "; + $query = $database->query($sql); + + $sql = "DELETE FROM ".TABLES['web_shop_cart']." + WHERE id=$idCart + AND idUser=".$user->getUserId(); + + $query = $database->query($sql); + if($database->affectedRows() !== 1){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_PACKAGE_FOR_REMOVE' + ]; + $data['messages'][] = $err_mes; + }else{ + $message = [ + 'code' => 'success', + 'message' => 'PACKAGE_REMOVED_FROM_CART' + ]; + $data['messages'][] = $message; + } + + return $data; + } + + /** + * upload questionaires for placing an order + * @param Array $file uploaded file + * @param String $idDocumentType type of the document + * @param String $documentName the name to be set for the file in database + * @param INT $idPackage id for the package + * @return Array upload message + */ + public function uploadOrderDocument($file, $idDocumentType, $idPackage){ + global $database, $user; + $isReUpload = false; + + $fileManager = new FileManager(); + $documentField = ''; + if(intval($idDocumentType) === self::DOCUMENT_TYPES['ID_CUSTOMER_QUESTIONNAIRE']){ + $documentField = 'idDocument'; + $documentName = 'customerQuestionaire_'; + }else{ + $documentField = 'idAgreementDocument'; + $documentName = 'customerAgreement_'; + } + $documentName .= $idPackage.'_'.date('Y_m_d'); + + $sql = "SELECT $documentField AS idDocument + FROM ".TABLES['web_shop_cart']." + WHERE idUser=".$user->getUserId()." AND idPackage=$idPackage AND $documentField IS NOT NULL"; + + $documents = $database->fetchResultArray($sql); + if(count($documents) > 0){ + $document = $documents[0]; + $data = $fileManager->updateDocument($document['idDocument'], $file); + $isReUpload = true; + }else{ + $uploadedBy = $user->getUserId(); + $data = $fileManager->uploadFile($file, $idDocumentType, $documentName, $uploadedBy); + $isReUpload = false; + } + + if(isset($data['messages'])){ + return $data; + } + + if(!$isReUpload){ + $idDocument = $data['idDocument']; + + $sql = "UPDATE ".TABLES['web_shop_cart']." + SET $documentField=$idDocument + WHERE idUser=".$user->getUserId()." AND idPackage=$idPackage"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'FILE_UPLOADED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NOT_LINKED_TO_CART' + ]; + } + }else{ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'FILE_UPLOADED' + ]; + } + + return $data; + } + + /** + * get files that have been uploaded before palcing an order and are found in the cart + * @param INT $packages id of the package + * @return Array array of uploaded documetns for a package + */ + private function getUploadedFilesForOrder($packages){ + global $database, $user; + $data = []; + + $sql = "SELECT + doc.id as idDocument, + doc.documentName, + doc.extension, + doc.idDocumentType, + wsc.idPackage + FROM ".TABLES['documents']." doc + INNER JOIN ".TABLES['web_shop_cart']." wsc + ON (doc.id=wsc.idDocument OR doc.id=wsc.idAgreementDocument) AND wsc.idUser=doc.uploadedBy + WHERE wsc.idPackage IN($packages) AND wsc.idUser=".$user->getUserId().""; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idDocumentType']][$row['idPackage']] = $row; + } + + return $data; + } + + /** + * get required template documents to place an order + * @param Array $packages ids for the packages in the cart + * @return Array array of documents + */ + private function getTempalteDocuments($packages){ + global $database; + + $data = []; + $sql = "SELECT + d.id as idDocument, + d.documentName, + d.documentPath, + d.extension, + p.id AS idPackage, + p.name AS packageName, + d.idDocumentType + FROM ".TABLES['documents']." d + INNER JOIN ".TABLES['rel_package_documents']." rpd + ON rpd.idDocument=d.id + INNER JOIN ".TABLES['packages']." p + ON p.id=rpd.idPackage + WHERE rpd.idPackage IN($packages) + AND d.idDocumentType IN(".self::DOCUMENT_TYPES['ID_TEMPLATE_QUESIONNAIRE'].", ".self::DOCUMENT_TYPES['ID_TEMPLATE_AGREEMENT'].")"; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idDocumentType']][$row['idPackage']] = $row; + $idCustomerDocType = $row['idDocumentType'] == self::DOCUMENT_TYPES['ID_TEMPLATE_QUESIONNAIRE'] ? self::DOCUMENT_TYPES['ID_CUSTOMER_QUESTIONNAIRE'] : self::DOCUMENT_TYPES['ID_CUSTOMER_AGREEMENT']; + $data['docsPackage'][$idCustomerDocType][$row['idPackage']] = $row; + } + + return $data; + } + + /** + * get required documents to place an order + * @param Array $packages ids for the packages in the cart + * @return Array array of documents + */ + public function getCartDocuments($packages){ + global $database; + + $data = []; + $areFilesUploaded = true; + $uploaded = []; + $templates = []; + $packages = implode(',', $packages); + $packages = $database->escapeValue($packages); + + if($packages) { + $uploaded = $this->getUploadedFilesForOrder($packages); + $templates = $this->getTempalteDocuments($packages); + } + + if(array_key_exists('docsPackage', $templates)) { + foreach($templates['docsPackage'] as $idDocType => $templateDoc) { + foreach ($templateDoc as $idPackage => $packageDocDetails) { + if(!isset($uploaded[$idDocType]) || !isset($uploaded[$idDocType][$idPackage])){ + $areFilesUploaded = false; + break; + } + } + } + unset($templates['docsPackage']); + } + + return ['templates' => $templates, 'uploaded' => $uploaded, 'areFilesUploaded' => $areFilesUploaded]; + } + + /** + * get details of the customer logged in + * @return Array with neccessary details + */ + public function getCustomerDetails() { + global $database, $user; + $userId = $user->getUserId(); + $data = []; + $addresHelper = new AddressHelper(); + + $sqlVatCode = " + SELECT c.vatCode, + c.name AS companyName + FROM ".TABLES['company']." c + INNER JOIN ".TABLES['users']." u + ON u.idCompany=c.id + WHERE u.id = ".$userId." + LIMIT 1"; + $result = $database->fetchResultArray($sqlVatCode); + $data['vat'] = $result ? $result[0]['vatCode'] : ''; + $data['companyName'] = $result ? $result[0]['companyName'] : ''; + + $data['deliveryAddresses'] = $addresHelper->getDeliveryAddress(); + $data['billing'] = $addresHelper->getBillingAddress(); + + if($result = $this->getReferenceAndTender()) { + $data['details'] = $result[0]; + } + + return ['customerDetails' => $data]; + } + + /** + * returns the reference and tender if exists + * @return Array reference and tender for the order + */ + private function getReferenceAndTender() { + global $database, $user; + + $sqlDetails = " + SELECT + reference, + tender, + idDeliveryAddress, + idBillingAddress, + idProject + FROM + ".TABLES['web_shop_cart']." wsc + WHERE wsc.idUser = ".$user->getUserId(); + + return $database->fetchResultArray($sqlDetails); + } + + /** + * gets the country name for the id provided + * @param Array $data all details + * @param String $addressType delivery or billing address + * @return String name of the country + */ + private function getCountryName($data, $addressType) { + if(array_key_exists($addressType, $data)) { + return $this->getCountryDetailsById($data[$addressType]['idCountrySelected'])[0]['countryName']; + } + + return ''; + } + + /** + * returns the name and code of the country by it's id + * @param int $idCountry id of the country + * @return string the name of the country + */ + public function getCountryDetailsById($idCountry) { + global $database; + $countryName = ''; + + $sql = " + SELECT name AS countryName, + UPPER(code) AS countryCode + FROM ".TABLES['countries']." + WHERE id=$idCountry + LIMIT 1"; + return $database->fetchResultArray($sql); + } + + /** + * get all the countries + * @return Array country names and ids + */ + public function getCountries() { + global $database; + + $sql = "SELECT c.id, c.name + FROM ".TABLES['countries']." c"; + + return ['countries' => $database->fetchResultArray($sql)]; + } + + /** + * checks whether the informations for the order are correct + * @param Array $cartPackages the packages to be placed in the order + * @param Array $deliveryInfo the delivery information for the order + * @param Array $billingInfo the billing information for the order + * @return Array error message ot empty + */ + private function validateOrderDetails($cartPackages, $deliveryInfo, $billingInfo, $details) { + global $database; + + if(count($cartPackages) < 1) { + return [ + 'code' => 'error', + 'message' => 'CART_EMPTY' + ]; + } + + if(empty($deliveryInfo)){ + return [ + 'code' => 'error', + 'message' => 'NO_DELIVERY_ADDRESS' + ]; + } + + if(empty($billingInfo)){ + return [ + 'code' => 'error', + 'message' => 'NO_BILLING_ADDRESS' + ]; + } + + return []; + } + + /** + * adds or updates the delivery address for the user logged in + * @param Array $deliveryInfo contaions the delivery address + * @return Int affected rows + */ + private function addUpdateOrderDeliveryAddress($deliveryInfo) { + global $database, $user; + + foreach($deliveryInfo as $deliveryIndex => $detail) { + $deliveryInfo[$deliveryIndex] = $database->escapeValue($detail); + } + + $sql = " + SELECT + id + FROM + ".TABLES['delivery_addresses']." + WHERE idUser = ".$user->getUserId()." + AND idCountry = ".$deliveryInfo['idCountrySelected']." + AND city = '".$deliveryInfo['city']."' + AND detailedAddress = '".$deliveryInfo['detailedAddress']."' + AND zip = '".$deliveryInfo['zipCode']."' + "; + $query = $database->query($sql); + if($database->numRows($query) === 0) { + $sqlDeliveryAddress = " + INSERT INTO ".TABLES['delivery_addresses']." + (idUser, idCountry, city, detailedAddress, zip) + VALUES ( + ".$user->getUserId().", + ".$deliveryInfo['idCountrySelected'].", + '".$deliveryInfo['city']."', + '".$deliveryInfo['detailedAddress']."', + '".$deliveryInfo['zipCode']."' + ) + "; + $query = $database->query($sqlDeliveryAddress); + + return $database->affectedRows(); + } + + return 0; + } + + /** + * adds or updates the billing information for the user + * @param Array $billingInfo array of billing info - names and address + * @return Int affected rows + */ + private function addUpdateOrderBillingAddress($billingInfo) { + global $database, $user; + + foreach($billingInfo as $billingIndex => $detail) { + $billingInfo[$billingIndex] = $database->escapeValue($detail); + } + + $sql = " + SELECT + id + FROM + ".TABLES['billing_information']." + WHERE idUser = ".$user->getUserId()." + AND idCountry = ".$billingInfo['idCountrySelected']." + AND company = '".$billingInfo['companyName']."' + AND firstName = '".$billingInfo['firstName']."' + AND lastname = '".$billingInfo['lastName']."' + AND city = '".$billingInfo['city']."' + AND detailedAddress = '".$billingInfo['detailedAddress']."' + AND zip = '".$billingInfo['zipCode']."' + "; + + $query = $database->query($sql); + if($database->numRows($query) === 0) { + $sqlBillingAddress = " + INSERT INTO ".TABLES['billing_information']." + (idUser, idCountry, company, firstName, lastName, city, detailedAddress, zip) + VALUES ( + ".$user->getUserId().", + ".$billingInfo['idCountrySelected'].", + '".$billingInfo['companyName']."', + '".$billingInfo['firstName']."', + '".$billingInfo['lastName']."', + '".$billingInfo['city']."', + '".$billingInfo['detailedAddress']."', + '".$billingInfo['zipCode']."' + ) + "; + $query = $database->query($sqlBillingAddress); + + return $database->affectedRows(); + } + + return 0; + } + + /** + * returns the name and code of the country by it's id + * @param array $details details of the order + * @param array $items items from the cart + * @return array update messages + */ + public function saveOrderDetails($details, $items) { + global $database; + $addressInserted = 0; + $deliveryInfo = $details['delivery']; + $billingInfo = $details['billing']; + $orderDetails = $details['details']; + $orderDetails['idDeliveryAddress'] = isset($deliveryInfo['id']) ? $deliveryInfo['id'] : 'null'; + $orderDetails['idBillingAddress'] = isset($billingInfo['id']) ? $billingInfo['id'] : 'null'; + + if($data['messages'][] = $this->validateOrderDetails($items, $deliveryInfo, $billingInfo, $orderDetails)) { + return $data; + } + + if($this->updateCartInfo($orderDetails) > 0) { + $addressInserted++; + } + + if($addressInserted) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'ADDRESS_INSERTED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_ADDRESS_CHANGES' + ]; + } + + return $data; + } + + /** + * updates the reference and tender for the order to be placed + * @param Array $details reference and tender + * @return Int number of rows affected + */ + private function updateCartInfo($details) { + global $database, $user; + + foreach($details as $key => $detail) { + $details[$key] = $database->escapeValue($detail); + } + + $idProject = isset($details['idProject']) && $details['idProject'] ? $details['idProject'] : 'NULL'; + + $sql = " + UPDATE + ".TABLES['web_shop_cart']." + SET + reference = '".$details['reference']."', + tender = '".$details['tender']."', + idDeliveryAddress = '".$details['idDeliveryAddress']."', + idBillingAddress = '".$details['idBillingAddress']."', + idProject = $idProject + WHERE idUser = ".$user->getUserId(); + $query = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * calculate the packages total price + * @param Array $cartPackage the details for the package in the cart + * @return float the total price per package + */ + private function calculatePackageTotalPrice($cartPackage){ + $totalPrice = [ + 'fixedPrice' => 0, + 'recurrentPrice' => 0, + 'servicesPrice' => 0 + ]; + + + if(!empty($cartPackage['bids']) && $cartPackage['idSelectedBid']){ + $selectedBid = null; + foreach ($cartPackage['bids'] as $bid) { + if($bid['idBid'] === $cartPackage['idSelectedBid']){ + $selectedBid = $bid; + break; + } + } + + $totalPrice['fixedPrice'] += $selectedBid ? $selectedBid['fixedPrice'] : $cartPackage['fixedPrice']; + $totalPrice['recurrentPrice'] += $selectedBid ? $selectedBid['recurrentPrice'] : $cartPackage['recurentPrice']; + $totalPrice['servicesPrice'] += $selectedBid ? $selectedBid['servicesPrice'] : $cartPackage['servicesPrice']; + }else{ + $totalPrice['fixedPrice'] += $cartPackage['fixedPrice']; + $totalPrice['recurrentPrice'] += $cartPackage['recurentPrice']; + $totalPrice['servicesPrice'] += $cartPackage['servicesPrice']; + } + + if(isset($cartPackage['options'])){ + foreach ($cartPackage['options'] as $option) { + if(count($option) && array_key_exists('prices', $option) && count($option['prices'])) { + $totalPrice['fixedPrice'] += $option['prices']['fixedExtra']; + $totalPrice['recurrentPrice'] += $option['prices']['recurentExtra']; + $totalPrice['servicesPrice'] += $option['prices']['servicesExtra']; + } + } + } + + if(isset($cartPackage['additionalPackages'])){ + foreach ($cartPackage['additionalPackages'] as $additionalPackage) { + if(count($additionalPackage) && array_key_exists('prices', $additionalPackage) && count($additionalPackage['prices'])) { + $totalPrice['fixedPrice'] += $additionalPackage['prices']['fixedExtra']; + $totalPrice['recurrentPrice'] += $additionalPackage['prices']['recurentExtra']; + $totalPrice['servicesPrice'] += $additionalPackage['prices']['servicesExtra']; + } + } + } + + return $totalPrice; + } + + /** + * genereate the order number using the id + * @param INT $idOrder id of the order + * @return INT order number containg the id value + */ + private function generateOrderNumber($idOrder){ + return 1000000000 + $idOrder; + } + + /** + * adds the relation between order and packages + * @param Array $orderPackages all the details for packages in order + * @param Int $idOrder the order id inserted + * @return Int the number of packages inserted + */ + private function addOrderPackageRelation($orderPackages, $idOrder) { + global $database; + $insertValues = ''; + + $sql = " + INSERT INTO ".TABLES['rel_order_packages']." + (idOrder, idPackage, packageInstance, idPaymentTerm, units, packageFixedPrice, packageRecuringPrice, packageServicePrice, idBid) + VALUES + "; + + foreach($orderPackages as $packageInfo) { + $totalPackagePrice = $this->calculatePackageTotalPrice($packageInfo); + $isPriceInRange = $this->checkIfPriceInRange($totalPackagePrice); + if($isPriceInRange) { + return $isPriceInRange; + } + + $packageInfo['idSelectedBid'] = $packageInfo['idSelectedBid'] ? $packageInfo['idSelectedBid'] : 'NULL'; + + $sqlPaymentType = " + SELECT id + FROM ".TABLES['payment_types']." pt + WHERE pt.payType='".$packageInfo['payType']."'"; + $result = $database->fetchResultArray($sqlPaymentType); + $idPayType = $result && $result[0]['id'] ? $result[0]['id'] : 0; + + $insertValues .= "( + $idOrder, + '".$packageInfo['idPackage']."', + '".$packageInfo['packageInstance']."', + ".$packageInfo['idPayType'].", + '".$packageInfo['quantity']."', + '".$totalPackagePrice['fixedPrice']."', + '".$totalPackagePrice['recurrentPrice']."', + '".$totalPackagePrice['servicesPrice']."', + ".$packageInfo['idSelectedBid']." + ),"; + } + + $insertValues = $insertValues ? rtrim($insertValues, ',') : ''; + if($insertValues) { + $sql .= $insertValues; + $query = $database->query($sql); + + return $database->affectedRows(); + } + + return 0; + } + + /** + * add order documents to relation table + * @param Int $idOrder id of the order + * @param Int $idCustomerInstance id customer instance + * @return Int affected rows or 1 + */ + private function addOrderDocuments($idOrder, $idCustomerInstance){ + global $database, $user; + $getDocSql = "SELECT wsc.idDocument, wsc.idAgreementDocument, wsc.idPackage + FROM ".TABLES['web_shop_cart']." wsc + WHERE idCustomerInstance=$idCustomerInstance"; + $query = $database->query($getDocSql); + $vals = ""; + while($row = $database->fetchArray($query)){ + if($row['idDocument']){ + $vals .= "(" . $idOrder . ", " . $row['idPackage'] . ", " . $row['idDocument'] . "),"; + } + + if($row['idAgreementDocument']){ + $vals .= "(" . $idOrder . ", " . $row['idPackage'] . ", " . $row['idAgreementDocument'] . "),"; + } + } + ; + if($vals){ + $vals = rtrim($vals, ','); + $sql = "INSERT INTO ".TABLES['rel_order_documents']." + (idOrder, idPackage, idDocument) + VALUES $vals"; + $query = $database->query($sql); + + return $database->affectedRows(); + } + + return 1; + } + + /** + * add extra option for order packages + * @param INT $idOrder id for the ORDER + * @return INT number of inserted elements + */ + private function addOrderExtraPackages($idOrder){ + global $database, $user; + + $sql = "INSERT INTO ".TABLES['rel_order_extra_packages']." + (idOrder, idPackage, idExtraPackage) + SELECT $idOrder, wsc.idPackage, wscep.idExtraPackage + FROM ".TABLES['web_shop_cart']." wsc + INNER JOIN ".TABLES['web_shop_cart_extra_packages']." wscep + ON wsc.id=wscep.idCart + WHERE wsc.idUser=".$user->getUserId(); + $query = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * remove the packages from the web shop cart after placing the order + * @param Int $idCustomerInstance id of the customer + * @return Int number of rows deleted + */ + private function removePackagesFromCartAfterOrder($idCustomerInstance) { + global $database; + + $sql = " + DELETE + FROM + ".TABLES['web_shop_cart']." + WHERE idCustomerInstance = $idCustomerInstance"; + + $result = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * adds the installation company in the selection relations table + * @param Array $cartPackages the packages from the cart + * @param Int $idOrder the id of the order + * @return Array with confirmation message + */ + private function addInstallationCompanySelection($cartPackages, $idOrder) { + global $database; + $message = []; + + foreach($cartPackages as $position => $package) { + $sql = " + SELECT + rpp.idProduct + FROM + ".TABLES['rel_package_products']." rpp + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct = rpp.idProduct + INNER JOIN ".TABLES['product_categories']." pc + ON scp.idProductCategory = pc.id + WHERE pc.id = ".self::PRODUCT_CATEGORIES['INSTALLATION']." + AND rpp.idPackage = ".$package['idPackage']." + AND rpp.packageInstance = ".$package['packageInstance']; + $products = $database->fetchResultArray($sql); + if(count($products) === 1) { + $installationScheduling = new InstallationScheduling(); + $message = $installationScheduling->changeInstallationCompany($idOrder, $package['idPackage'], $products[0]['idProduct']); + } + } + + return $message; + } + + /** + * adds the order with the whole details + * @param String $cartPackages Json string with object containing the packages to order + * @param String $details Json string with object containing the details like refenrence or tender numbers + * @return Array confirmation message + */ + public function placeOrder($cartItems, $orderDetails) { + global $database, $user; + $rowsAffected = 0; + $deletedFromCart = 0; + $totalFixedPrice = 0; + $totalServicePrice = 0; + $userId = $user->getUserId(); + $newCartPackages = []; + $packageToDisplay = ''; + $unavailablePackageKey = ''; + $idPackages = ''; + $orderTypeInst = new OrderType(); + $clCustomersInst = new ClCustomers(); + + $cartPackages = $cartItems; + $deliveryInfo = $orderDetails['delivery']; + $billingInfo = $orderDetails['billing']; + $details = $orderDetails['details']; + + $options = $this->getCartItemOptions(); + $additionalPackages = $this->getCartAdditionalPackages(); + + foreach($cartPackages as $packKey => $packageDetails) { + $packageDetails = (array) $packageDetails; + $areOptionsAvailable[$packageDetails['packageName']] = isset($options[$packageDetails['idCart']]) ? $options[$packageDetails['idCart']]['areOptionsAvailable'] : true; + $areAdditionalAvailable[$packageDetails['packageName']] = isset($additionalPackages[$packageDetails['idCart']]) ? $additionalPackages[$packageDetails['idCart']]['areAdditionalAvailable'] : true; + $packageNames[] = $packageDetails['packageName']; + foreach($packageDetails as $packDetailKey => $packageDetail) { + if(!is_array($packageDetail)){ + $newCartPackages[$packKey][$packDetailKey] = $database->escapeValue($packageDetail); + }else{ + $newCartPackages[$packKey][$packDetailKey] = $packageDetail; + } + } + $commercialLeadName = $packageDetails['commercialLead']; + $idCommercialLead = $packageDetails['idCommercialLead']; + $idPackages .= $packageDetails['idPackage'].','; + } + + $unavailablePackageKey = $this->getNameIfPackageUnavailable($idPackages); + $optionPackageKey = array_keys($areOptionsAvailable, false); + if(count($optionPackageKey)) { + $unavailablePackageKey = $optionPackageKey[0]; + } else { + $additionalPackageKey = array_keys($areAdditionalAvailable, false); + if(count($additionalPackageKey)) { + $unavailablePackageKey = $additionalPackageKey[0]; + } + } + + if($unavailablePackageKey) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UNAVAILABLE_PACKAGE_IN_CART', + 'key' => $unavailablePackageKey + ]; + + return $data; + } + + $cartPackages = $newCartPackages; + foreach ($cartPackages as $position => $cartPackage) { + $optionsToDisplay = ''; + if(isset($cartPackage['options'])){ + $optionsToDisplay .= '('; + foreach ($cartPackage['options'] as $key => $option) { + $optionsToDisplay .= $option['groupName'] . ' : ' . $option['packageName'] .','; + } + $optionsToDisplay = rtrim($optionsToDisplay, ','); + $optionsToDisplay .= ')'; + } + + if(isset($cartPackage['additionalPackages'])){ + $optionsToDisplay .= '('; + foreach ($cartPackage['additionalPackages'] as $key => $option) { + $optionsToDisplay .= $option['packageName'] .', '; + } + $optionsToDisplay = rtrim($optionsToDisplay, ','); + $optionsToDisplay .= ')'; + } + $packageTotalPrices = $this->calculatePackageTotalPrice($cartPackage); + + $packageToDisplay .= ($position + 1).'. '.$packageNames[$position].' + '.$optionsToDisplay.' +
+
Commercial lead: '.$cartPackage['commercialLead'].'
+
Payment type: '.$cartPackage['payType'].'
+
Quantity: '.$cartPackage['quantity'].'
+ +


+ '; + + $totalFixedPrice += $packageTotalPrices['fixedPrice'] * $cartPackage['quantity']; + $totalServicePrice += ($packageTotalPrices['recurrentPrice'] + $packageTotalPrices['servicesPrice']) * $cartPackage['quantity']; + $totalPeriodUnit = $cartPackage['periodUnit']; + + } + $packageToDisplay .= 'Total Price: '.$totalFixedPrice.' ('.$totalServicePrice.' / '.$totalPeriodUnit.')

'; + + foreach($deliveryInfo as $deliveryKey => $delivery) { + $deliveryInfo[$deliveryKey] = $database->escapeValue($delivery); + } + + foreach($billingInfo as $billingKey => $billing) { + $billingInfo[$billingKey] = $database->escapeValue($billing); + } + + foreach($details as $detailKey => $detail) { + $details[$detailKey] = $database->escapeValue($detail); + } + + $database->beginTransaction(); + + $sqlCustomerInstance = " + SELECT + rclc.id AS idCustomerInstance + FROM + ".TABLES['rel_commercial_lead_customers']." rclc + INNER JOIN ".TABLES['customers']." c + ON c.id = rclc.idCustomer + AND c.idUser = $userId + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id = rclc.idCommercialLead + AND cl.id = '".$idCommercialLead."' + WHERE rclc.isLinkEnabled=1 + LIMIT 1"; + $result = $database->fetchResultArray($sqlCustomerInstance); + if($result && $result[0]['idCustomerInstance']) { + $idCustomerInstance = $result[0]['idCustomerInstance']; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'LINK_CUSTOMER_CL' + ]; + $database->rollback(); + + return $data; + } + + $customerInfo = $clCustomersInst->getClCustomerInfo($idCommercialLead); + $orderType = $customerInfo['idOrderType'] ? $customerInfo['idOrderType'] : $orderTypeInst->getCLDefaultOrderType($idCommercialLead); + if($customerInfo['isSameCompanyAsCl'] == 1){ + $orderType = $orderTypeInst::ORDER_TYPES['reseller']; + } + + $sqlOrderNumber = " + SELECT + MAX(id) + 1 AS orderNumber + FROM + ".TABLES['orders']." + LIMIT 1"; + $result = $database->fetchResultArray($sqlOrderNumber); + $orderNumber = $result && $result[0]['orderNumber'] ? $this->generateOrderNumber($result[0]['orderNumber']) : '1000000000'; + + $today = new DateTime(); + $reference = array_key_exists('reference', $details) && $details['reference'] ? $details['reference'] : ''; + $tender = array_key_exists('tender', $details) && $details['tender'] ? $details['tender'] : ''; + $idProject = array_key_exists('idProject', $details) && $details['idProject'] ? $details['idProject'] : 'NULL'; + $countryDetails = $this->getCountryDetailsById($deliveryInfo['idCountrySelected'])[0]; + $countryName = $countryDetails['countryName']; + $countryCode = $countryDetails['countryCode']; + $concatenatedDeliveryAddress = $deliveryInfo['detailedAddress'].", ".$deliveryInfo['city'].", $countryName, ".$deliveryInfo['zipCode']; + $billingCountryDetails = $this->getCountryDetailsById($billingInfo['idCountrySelected'])[0]; + $concatenatedBillingAddress = $billingInfo['detailedAddress'].", ".$billingInfo['city'].", ".$billingCountryDetails['countryName'].", ".$billingInfo['zipCode']; + $projectNumber = $countryCode . $orderNumber; + $orderDate = $today->format('Y-m-d H:m:s'); + + $packageToDisplay .= 'Delivery address: '.$concatenatedDeliveryAddress.'
'; + $packageToDisplay .= 'Billing address: '.$concatenatedBillingAddress.'
'; + + $sql = "SELECT MAX(t.id) as idTemrs + FROM ".TABLES['terms']." t"; + $terms = $database->fetchResultArray($sql)[0]; + + $sql = " + INSERT INTO ".TABLES['orders']." + (idCustomerInstance, orderNumber, orderDate, reference, tender, projectNumber, deliveryAddress, billingAddress, idTerms, idOrderType, idProject) + VALUES ( + $idCustomerInstance, + '".$orderNumber."', + '".$orderDate."', + '".$reference."', + '".$tender."', + '".$projectNumber."', + '".$concatenatedDeliveryAddress."', + '".$concatenatedBillingAddress."', + '".$terms['idTemrs']."', + '".$orderType."', + ".$idProject." + ) + "; + + $query = $database->query($sql); + + if($database->affectedRows() === 1){ + $rowsAffected++; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_ORDER_INSERT' + ]; + $database->rollback(); + + return $data; + } + + $idOrder = $database->getInsertId(); + + $relationData = $this->addOrderPackageRelation($cartPackages, $idOrder); + if(is_array($relationData) || $relationData <= 0) { + $data['messages'][] = is_array($relationData) ? $relationData : [ + 'code' => 'error', + 'message' => 'ERROR_ORDER_PACK_RELATION' + ]; + $database->rollback(); + + return $data; + } else { + $rowsAffected++; + } + + if($this->addOrderDocuments($idOrder, $idCustomerInstance) > 0) { + $rowsAffected++; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_ON_ADDING_DOCUMENTS' + ]; + $database->rollback(); + + return $data; + } + + $addedOptions = $this->addOrderExtraPackages($idOrder); + $deletedFromCart = $this->removePackagesFromCartAfterOrder($idCustomerInstance, $userId); + if($this->addInstallationCompanySelection($cartPackages, $idOrder)) { + $data['messages'][] = $this->addInstallationCompanySelection($cartPackages, $idOrder); + } + + if($rowsAffected >= 3) { + $database->commit(); + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'ORDER_PLACED' + ]; + + if($deletedFromCart > 0) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PACKAGES_DELETED' + ]; + } + + $orderInfo['idOrder'] = $idOrder; + $orderInfo['orderNumber'] = $orderNumber; + $orderInfo['orderDate'] = $orderDate; + + $data['messages'][] = UtilsModel::sendOrderConfirmationMail($packageToDisplay, 'customer', $orderInfo); + $data['messages'][] = UtilsModel::sendOrderConfirmationMail($packageToDisplay, 'broker', $orderInfo); + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ORDER_ERROR' + ]; + $database->rollback(); + } + + return $data; + } + + /** + * return the name of the package unavailable or empty + * @param String $idPackages all the ids of the packages from the cart + * @return String the name of the package unavailable or empty + */ + private function getNameIfPackageUnavailable($idPackages) { + global $database; + if(!$idPackages) { + return ''; + } + $idPackages = rtrim($idPackages, ','); + + $sql = "SELECT + IF(p.status = 'available', 1, 0) AS isAvailable, + p.name + FROM + ".TABLES['packages']." p + WHERE p.id IN ($idPackages)"; + $query = $database->query($sql); + + while($row = $database->fetchArray($query)) { + if(intval($row['isAvailable']) === 0) { + return $row['name']; + } + } + + return ''; + } + + /** + * checks if the prices have more than 15 digits + * @return Bool true if all the prices have digits lower than 15 + */ + private function checkIfPriceInRange($packageTotalPrice) { + global $database; + $max_value = 1 * pow(10, 15); + + $fixPriceMessage = $database->invalidNumber('fixed price', $packageTotalPrice['fixedPrice'], 0, $max_value); + if($fixPriceMessage) { + return $fixPriceMessage; + } else { + $recurrentPriceMessage = $database->invalidNumber('recurrent price', $packageTotalPrice['recurrentPrice'], 0, $max_value); + if($recurrentPriceMessage) { + return $recurrentPriceMessage; + } else { + $servicePriceMessage = $database->invalidNumber('services price', $packageTotalPrice['servicesPrice'], 0, $max_value); + + return $servicePriceMessage ? $servicePriceMessage : null; + } + } + + return null; + } + + public function setBidForCart($idBid, $idCart){ + $bidsHandler = new Bids(); + + return $bidsHandler->setBidForCart($idBid, $idCart); + } + } diff --git a/api-wiaas/server/components/v2/coMarket/CoMarketController.php b/api-wiaas/server/components/v2/coMarket/CoMarketController.php new file mode 100644 index 0000000..d7d77c1 --- /dev/null +++ b/api-wiaas/server/components/v2/coMarket/CoMarketController.php @@ -0,0 +1,49 @@ +model = new CoMarketModel(); + } + + /** + * get all packages taht can be sold + * @return json all packages that can be sold in web shop + */ + public function getShopPackages(){ + $idCommercialLead = isset($_REQUEST['idCommercialLead']) ? $_REQUEST['idCommercialLead'] : 0; + $serach = isset($_REQUEST['search']) ? $_REQUEST['search'] : ''; + echo json_encode($this->model->getShopPackages($idCommercialLead, 0, $serach), JSON_NUMERIC_CHECK); + } + + /** + * get all comercial leads lined to the user + * @return json list of commercial leads + */ + public function getAllCommercialLeads(){ + echo json_encode($this->model->getAllCommercialLeads(), JSON_NUMERIC_CHECK); + } + + /** + * get web shop details for a package + * @return json package details + */ + public function getShopPackageDetails(){ + $idCommercialLead = isset($_REQUEST['idCommercialLead']) ? $_REQUEST['idCommercialLead'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + echo json_encode($this->model->getShopPackageDetails($idCommercialLead, $idPackage), JSON_NUMERIC_CHECK); + } + + /** + * add items to cart + */ + public function addToCart(){ + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + $idPrice = isset($_REQUEST['idPrice']) ? $_REQUEST['idPrice'] : 0; + $options = isset($_REQUEST['options']) ? $_REQUEST['options'] : '[]'; + echo json_encode($this->model->addToCart($idPackage, $idPrice, $options)); + } +} diff --git a/api-wiaas/server/components/v2/coMarket/CoMarketModel.php b/api-wiaas/server/components/v2/coMarket/CoMarketModel.php new file mode 100644 index 0000000..9da3181 --- /dev/null +++ b/api-wiaas/server/components/v2/coMarket/CoMarketModel.php @@ -0,0 +1,446 @@ + 1, + 'ID_OPTION_TYPE' => 2, + 'ID_ADDITONAL_TYPE' => 3 + ]; + + public function getShopPackages($idCommercialLead, $idPackage = 0, $search = ''){ + global $database, $user; + + $whereSql = "WHERE p.status='available' AND p.idPackageType=".self::PACKAGE_TYPES['ID_STANDARD_TYPE']." "; + $search = $database->escapeValue($search); + + if($idPackage !== 0){ + $whereSql .= " AND p.id=$idPackage"; + } + + if($search !== ''){ + $searchValues = explode(' ', $search); + $packageCondition = ''; + $descriptionCondition = ''; + $referenceCondition = ''; + $countryCondition = ''; + foreach ($searchValues as $valueToSearch) { + if($valueToSearch !== ''){ + $packageCondition .= "p.name like '%".$valueToSearch."%'"." OR "; + $descriptionCondition .= " p.description like '%".$valueToSearch."%'"." OR "; + $referenceCondition .= "p.reference='".$valueToSearch."' OR "; + $countryCondition .= "c.name='".$valueToSearch."' OR "; + } + } + $countryCondition = rtrim($countryCondition, ' OR '); + $whereSql .= " AND ( $packageCondition + $descriptionCondition + $referenceCondition + $countryCondition)"; + } + + $sql = "SELECT + p.id AS idPackage, + p.reference, + p.name, + p.photo, + p.photoPublicId, + p.description AS shortDescription, + price_selection.idCommercialLead, + c.name AS country, + c.code AS countryCode + FROM + ".TABLES['packages']." p + INNER JOIN + ".TABLES['countries']." c ON c.id = p.idCountry + INNER JOIN + (SELECT + idPackage, + plcl.idPaymentType, + plcl.idCommercialLead, + MAX(IFNULL(idCustomer, 0)) AS idCustomer + FROM + ".TABLES['price_list_commercial_lead']." plcl + LEFT OUTER JOIN ".TABLES['customers']." cust + ON cust.id = plcl.idCustomer + WHERE + (cust.idUser = ".$user->getUserId()." OR cust.idUser IS NULL) + AND plcl.idCommercialLead = $idCommercialLead + GROUP BY plcl.idPackage , plcl.idPaymentType + ) AS price_selection + ON price_selection.idPackage = p.id + INNER JOIN ".TABLES['price_list_commercial_lead']." plcl + ON plcl.idPackage = price_selection.idPackage + AND plcl.idPaymentType = price_selection.idPaymentType + AND plcl.idCommercialLead = price_selection.idCommercialLead + AND IFNULL(plcl.idCustomer, 0) = price_selection.idCustomer + AND plcl.visibleToCustomer = 1 + INNER JOIN + (SELECT + proc.idCountry + FROM ".TABLES['processes']." proc + GROUP BY proc.idCountry + ) proc_countries + ON proc_countries.idCountry=p.idCountry + $whereSql + GROUP BY p.id + ORDER BY p.name ASC"; + + $data = []; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + if(strlen($row['shortDescription']) > 300 && $idPackage === 0){ + $row['shortDescription'] = substr($row['shortDescription'], 0, 300) . '...'; + } + if($row['photoPublicId']) { + $row['photo'] = IMAGE_URL . $row['photoPublicId']; + } + $data[] = $row; + } + + return ['packages' => $data]; + } + + /** + * get all commercial leads linked to a customer + * @return Array list of commercial leads + */ + public function getAllCommercialLeads(){ + global $database, $user; + + $sql = "SELECT rclc.idCommercialLead, + cl.name as commercialLeadName, + u.mail as mail + FROM ".TABLES['rel_commercial_lead_customers']." rclc + INNER JOIN ".TABLES['customers']." c + ON c.id=rclc.idCustomer + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['users']." u + ON u.id = cl.idUser + WHERE rclc.isLinkEnabled=1 AND c.idUser=" . $user->getUserId(); + + return ['commercialLeads' => $database->fetchResultArray($sql)]; + } + + private function getCommercialLeadInfo($idCommercialLead){ + global $database; + + $sql = "SELECT + cl.name, + u.mail, + cl.phone + FROM ".TABLES['commercial_leads']." cl + INNER JOIN ".TABLES['users']." u + ON u.id = cl.idUser + WHERE cl.id=$idCommercialLead + "; + + return $database->fetchResultArray($sql); + } + + /** + * get package options + * @param INT $idPackage id for the pacakge + * @param INT $idCommercialLead id for the comemrcial lead + * @return HashArray list of option packages grouped by group id + */ + private function getPackageOptions($idPackage, $idCommercialLead){ + global $database; + $data = []; + $packages = new Packages(); + + $packageOptionPrices = $packages->getPricesForPackages($idCommercialLead, $idPackage, self::PACKAGE_TYPES['ID_OPTION_TYPE']); + + $sql = "SELECT + rgo.idOptionPackage, + p.name AS optionName, + rgo.isDefault, + pog.id AS idGroup, + pog.name AS groupName, + p.description AS shortDescription + FROM ".TABLES['package_option_groups']." pog + INNER JOIN ".TABLES['rel_group_options']." rgo + ON rgo.idGroup=pog.id + INNER JOIN ".TABLES['packages']." p + ON p.id=rgo.idOptionPackage + WHERE pog.idPackage=$idPackage"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $idGroup = $row['idGroup']; + $data[$idGroup]['idGroup'] = $row['idGroup']; + unset($row['idGroup']); + $data[$idGroup]['groupName'] = $row['groupName']; + unset($row['groupName']); + $row['prices'] = isset($packageOptionPrices[$row['idOptionPackage']]) ? $packageOptionPrices[$row['idOptionPackage']] : []; + $data[$idGroup]['options'][] = $row; + } + + return $data; + } + + /** + * get package additional pacakges + * @param INT $idPackage id for the pacakge + * @param INT $idCommercialLead id for the comemrcial lead + * @return Array list of additonal packages + */ + private function getAdditionalPackages($idPackage, $idCommercialLead){ + global $database; + $data = []; + $packages = new Packages(); + + $additionalPackagesPrices = $packages->getPricesForPackages($idCommercialLead, $idPackage, self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']); + $sql = "SELECT + rap.idAdditionalPackage, + p.name AS packageName, + p.description AS shortDescription + FROM ".TABLES['rel_additional_packages']." rap + INNER JOIN ".TABLES['packages']." p + ON p.id=rap.idAdditionalPackage + WHERE rap.idPackage=$idPackage"; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['prices'] = isset($additionalPackagesPrices[$row['idAdditionalPackage']]) ? $additionalPackagesPrices[$row['idAdditionalPackage']] : []; + $data[] = $row; + } + + return $data; + } + + /** + * get info for a pacakge that can be sold in the co-market + * @param INT $idCommercialLead id for the commetcial lead + * @param INT $idPackage id for the package + * @return HashArray pacakge details(country, prices, info, documents, options, additional package) + */ + public function getShopPackageDetails($idCommercialLead, $idPackage){ + global $database, $user; + $countries = new Countries(); + $packages = new Packages(); + $packageDocuments = new PackageDocuments(); + + $idPackage = $database->escapeValue($idPackage); + $data = []; + $data['country'] = $countries->getCurrencyForPackage($idPackage); + $data['prices'] = $packages->getPricesForPackages($idCommercialLead, $idPackage, self::PACKAGE_TYPES['ID_STANDARD_TYPE']); + $data['prices'] = isset($data['prices'][$idPackage]) ? $data['prices'][$idPackage] : []; + + if(empty( $data['prices'])){ + return []; + } + + $documents = $packageDocuments->getPackageDocuments($idPackage); + $data['documents'] = isset($documents[$idPackage]) ? $documents[$idPackage] : []; + $shopPackages = $this->getShopPackages($idCommercialLead, $idPackage); + $data['packageInfo'] = isset($shopPackages['packages'][0]) ? $shopPackages['packages'][0] : []; + $commerciaLeads = $this->getCommercialLeadInfo($idCommercialLead); + $data['commercialLead'] = isset($commerciaLeads[0]) ? $commerciaLeads[0] : []; + $data['groups'] = $this->getPackageOptions($idPackage, $idCommercialLead); + $data['additionalPackages'] = $this->getAdditionalPackages($idPackage, $idCommercialLead); + + return $data; + } + + /** + * insert new option when adding item to cart + * @param INT $idCart id for the cart + * @param Object $options options to be added + * @return INT number of inserted items + */ + private function insertOptionsToCart($idCart, $options){ + global $database; + + if($options === '[]' || empty((array) $options)){ + return 0; + } + + $sql = "INSERT INTO ".TABLES['web_shop_cart_extra_packages']." + (idCart, idExtraPackage) + VALUES "; + foreach ($options as $idOption => $idOptionValue) { + $idOptionValue = $database->escapeValue($idOptionValue); + $sql .= "($idCart, $idOptionValue),"; + } + $sql = rtrim($sql, ","); + + $query = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * add new items to the cart + * @param INT $idPackage id for the package + * @param INT $idPrice id for the price + * @return array action message + */ + public function addToCart($idPackage, $idPrice, $options){ + global $database, $user; + $data = []; + + if(!$idPackage || !$idPrice){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_SELECTION' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $idPackage = $database->escapeValue($idPackage); + $idPrice = $database->escapeValue($idPrice); + + $idUser = $user->getUserId(); + $sql = "SELECT plcl.idCommercialLead, availableCl.idCustomerInstance + FROM ".TABLES['price_list_commercial_lead']." plcl + INNER JOIN + ( + SELECT rclc.idCommercialLead, rclc.id as idCustomerInstance + FROM ".TABLES['customers']." cust + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON cust.id=rclc.idCustomer AND rclc.isLinkEnabled=1 + WHERE cust.idUser=$idUser + ) availableCl + ON availableCl.idCommercialLead = plcl.idCommercialLead + WHERE plcl.id=$idPrice + LIMIT 1"; + $customer = $database->fetchResultArray($sql); + + if(count($customer) !== 1){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_USER' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sql = "SELECT rclc.idCommercialLead + FROM ".TABLES['rel_commercial_lead_customers']." rclc + INNER JOIN ".TABLES['web_shop_cart']." wsc + ON wsc.idCustomerInstance=rclc.id + INNER JOIN ".TABLES['customers']." c + ON c.id=rclc.idCustomer + WHERE c.idUser=$idUser + LIMIT 1 + "; + $alreadySelectedCL = $database->fetchResultArray($sql); + if(count($alreadySelectedCL) > 0 && $alreadySelectedCL[0]['idCommercialLead'] !== $customer[0]['idCommercialLead']){ + $err_mes = [ + 'code' => 'warning', + 'message' => 'ONLY_ONE_CL' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sql = "SELECT + COUNT(DISTINCT idCountry) AS differentCountries + FROM + (SELECT DISTINCT + p.idCountry + FROM + ".TABLES['web_shop_cart']." wsc + INNER JOIN ".TABLES['packages']." p + ON wsc.idPackage = p.id + WHERE + idCustomerInstance = ".$customer[0]['idCustomerInstance']." AND idUser = $idUser + UNION ALL + SELECT + p.idCountry + FROM + ".TABLES['packages']." p + WHERE + p.id = $idPackage) countires"; + $countriesCount = $database->fetchResultArray($sql)[0]; + if(intval($countriesCount['differentCountries']) > 1){ + $err_mes = [ + 'code' => 'warning', + 'message' => 'ONLY_ONE_COUNTRY' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sqlCheckPackage = " + SELECT idPackage + FROM ".TABLES['web_shop_cart']." + WHERE idPackage = $idPackage + AND idCustomerInstance = ".$customer[0]['idCustomerInstance']." + AND idUser = $idUser + "; + $result = $database->query($sqlCheckPackage); + if($database->numRows($result) > 0){ + $err_mes = [ + 'code' => 'error', + 'message' => 'PACKAGE_ALREADY_IN_CART' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sqlPackageInstance = "SELECT MAX(rpp.packageInstance) as maxInstance + FROM ".TABLES['rel_package_products']." rpp + WHERE rpp.idPackage=$idPackage"; + $result = $database->fetchResultArray($sqlPackageInstance); + if(count($result) === 0){ + $err_mes = [ + 'code' => 'error', + 'message' => 'PACKAGE_ERROR' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + $maxPackageInstance = $result[0]['maxInstance']; + + $sqlIns = "INSERT INTO ".TABLES['web_shop_cart']." + (idPackage, idCustomerInstance, idPrice, idUser, quantity, packageInstance) + VALUES($idPackage, + ".$customer[0]['idCustomerInstance'].", + $idPrice, + $idUser, + 1, + $maxPackageInstance)"; + + $query = $database->query($sqlIns); + $idCart = $database->getInsertId(); + + if($database->affectedRows() !== 1){ + + $err_mes = [ + 'code' => 'error', + 'message' => 'PACKAGE_ALREADY_IN_CART' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $insertedOptions = $this->insertOptionsToCart($idCart, $options); + + if($insertedOptions){ + $mes = [ + 'code' => 'success', + 'message' => 'OPTIONS_ADDED' + ]; + $data['messages'][] = $mes; + } + + $mes = [ + 'code' => 'success', + 'message' => 'PACKAGE_ADDED' + ]; + $data['messages'][] = $mes; + + return $data; + } + } \ No newline at end of file diff --git a/api-wiaas/server/components/v2/customers/ClCustomers.php b/api-wiaas/server/components/v2/customers/ClCustomers.php new file mode 100644 index 0000000..b4641a8 --- /dev/null +++ b/api-wiaas/server/components/v2/customers/ClCustomers.php @@ -0,0 +1,75 @@ +getUserId(); + $data = []; + + $sql = "SELECT + rclc.id as idCustomerInstance, + c.name AS customerName, + rclc.idOrderType, + IF(u.idCompany = clCompany.idCompany, 1, 0) AS isSameCompanyAsCl + FROM + ".TABLES['customers']." c + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.idCustomer=c.id AND isLinkEnabled=1 + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['users']." u + ON u.id = c.idUser + INNER JOIN + (SELECT + us.idCompany, + us.id + FROM + ".TABLES['users']." us + WHERE us.id = $idUser) clCompany + ON clCompany.id = cl.idUser + WHERE cl.idUser=$idUser + "; + return $database->fetchResultArray($sql); + } + + public function getClCustomerInfo($idCommercialLead){ + global $database, $user; + $idUser = $user->getUserId(); + $data = []; + + $sql = "SELECT + rclc.id as idCustomerInstance, + c.name AS customerName, + c.id AS idCustomer, + rclc.idOrderType, + IF(u.idCompany = clCompany.idCompany, 1, 0) AS isSameCompanyAsCl + FROM + ".TABLES['customers']." c + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.idCustomer=c.id AND isLinkEnabled=1 + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['users']." u + ON u.id = c.idUser + INNER JOIN + (SELECT + us.idCompany, + cl.id + FROM + ".TABLES['users']." us + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.idUser=us.id + WHERE cl.id = $idCommercialLead) clCompany + ON clCompany.id = cl.id + WHERE c.idUser=$idUser AND rclc.idCommercialLead=$idCommercialLead"; + + $query = $database->query($sql); + $data = $database->fetchArray($query); + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/customers/OrderType.php b/api-wiaas/server/components/v2/customers/OrderType.php new file mode 100644 index 0000000..4f418db --- /dev/null +++ b/api-wiaas/server/components/v2/customers/OrderType.php @@ -0,0 +1,144 @@ + 1, + 'reseller' => 2 + ]; + + /** + * returns all the invoice processes existing in the application + * @return Array all the invoice processes from the application + */ + public function getOrderTypes() { + global $database; + + $sql = "SELECT + id AS idOrderType, + name, + details + FROM + ".TABLES['order_types']; + return $database->fetchResultArray($sql); + } + + /** + * save Default Order Type + * @param INT $defaultIdOrderType id for default order type + * @return Array update message + */ + public function saveDefaultOrderType($defaultIdOrderType){ + global $database, $user; + $idUser = $user->getUserId(); + $data = []; + $defaultIdOrderType = $database->escapeValue($defaultIdOrderType); + + if(!$defaultIdOrderType){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'DEFAULT_VALUE_REQUIRED' + ]; + + return $data; + } + + $sql = "UPDATE ".TABLES['commercial_leads']." + SET defaultIdOrderType=$defaultIdOrderType + WHERE idUser=$idUser"; + $query = $database->query($sql); + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'DEFAULT_VALUE_UPDATED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + } + + return $data; + } + + /** + * save Customers Order Types + * @param Object $customers list of customers containg alos the id for order type + * @return Array update message + */ + public function saveCustomersOrderTypes($customers){ + global $database, $user; + $idUser = $user->getUserId(); + $data = []; + $customers = json_decode($customers); + $idCustomerInstances = []; + foreach ($customers as $customer) { + if($customer->idOrderType){ + $idCustomerInstances[] = $database->escapeValue($customer->idCustomerInstance); + } + + } + $totalCustomers = count($idCustomerInstances); + $customerList = $totalCustomers > 0 ? implode($idCustomerInstances, ',') : '0'; + $sql = "SELECT COUNT(rclc.id) AS validCustomers + FROM ".TABLES['rel_commercial_lead_customers']." rclc + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + WHERE cl.idUser=$idUser AND rclc.id IN($customerList) "; + $query = $database->query($sql); + $row = $database->fetchArray($query); + if($row['validCustomers'] != $totalCustomers){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NOT_AUTHORIZED' + ]; + + return $data; + } + + $uppdated = 0; + foreach ($customers as $customer) { + if($customer->idOrderType){ + $customer->idOrderType = $database->escapeValue($customer->idOrderType); + $customer->idCustomerInstance = $database->escapeValue($customer->idCustomerInstance); + $sql = "UPDATE ".TABLES['rel_commercial_lead_customers']." + SET idOrderType=".$customer->idOrderType." + WHERE id=".$customer->idCustomerInstance; + $query = $database->query($sql); + $uppdated += $database->affectedRows($query); + } + } + + if($uppdated > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'ORDER_TYPES_UPDATED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + } + + return $data; + } + + public function getCLDefaultOrderType($idCommercialLead = 0){ + global $database, $user; + + $whereSql = $idCommercialLead ? "cl.id=$idCommercialLead" : "cl.idUser=".$user->getUserId(); + + $sql = "SELECT + cl.defaultIdOrderType + FROM ".TABLES['commercial_leads']." cl + WHERE $whereSql + LIMIT 1"; + + $query = $database->query($sql); + $row = $database->fetchArray($query); + + return $row['defaultIdOrderType']; + } + +} diff --git a/api-wiaas/server/components/v2/dashboards/DashboardsController.php b/api-wiaas/server/components/v2/dashboards/DashboardsController.php new file mode 100644 index 0000000..66ee632 --- /dev/null +++ b/api-wiaas/server/components/v2/dashboards/DashboardsController.php @@ -0,0 +1,39 @@ +model = new DashboardsModel(); + } + + /** + * get data required for order central gadget + * @return json orders info + */ + public function getOrderCentralInfo(){ + $viewAllOrders = isset($_REQUEST['viewAllOrders']) ? $_REQUEST['viewAllOrders'] : false; + $filters = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : ''; + $sortBy = isset($_REQUEST['sortBy']) ? $_REQUEST['sortBy'] : ''; + echo json_encode($this->model->getOrderCentralInfo($viewAllOrders, $filters, $sortBy), JSON_NUMERIC_CHECK); + } + + /** + * get selected dashbord info + * @return json info and gadgets for selected dashboards + */ + public function getMyDashboard(){ + $idDashboard = isset($_REQUEST['myDashboard']) ? $_REQUEST['myDashboard'] : 0; + echo json_encode($this->model->getMyDashboard($idDashboard)); + } + + /** + * get data required for the enxt action gadget + * @return json next actions info + */ + public function getNextActionsInfo(){ + $filters = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : ''; + $sortBy = isset($_REQUEST['sortBy']) ? $_REQUEST['sortBy'] : ''; + echo json_encode($this->model->getNextActionsInfo($filters, $sortBy), JSON_NUMERIC_CHECK); + } +} +?> diff --git a/api-wiaas/server/components/v2/dashboards/DashboardsModel.php b/api-wiaas/server/components/v2/dashboards/DashboardsModel.php new file mode 100644 index 0000000..8612cd9 --- /dev/null +++ b/api-wiaas/server/components/v2/dashboards/DashboardsModel.php @@ -0,0 +1,278 @@ +fetchResultArray($sql); + } + + /** + * get information to show for dashborad view + * @param INT $idDashboard id of the dashborad + * @return HASHARRAY dahsborad info + */ + public function getMyDashboard($idDashboard){ + global $database, $user; + $data = []; + $whereSql = $user->getUserType() === USER_TYPES['BROKER'] + ? "(d.idUser=".$user->getUserId()." OR d.visibility='public')" + : "(d.idUser=".$user->getUserId()." OR (d.visibility='public' AND d.idUserType=".$user->getIdUserType()."))"; + $isOwner = $user->getUserType() === USER_TYPES['BROKER'] + ? "1 AS isOwner" + : "CASE WHEN d.idUser=".$user->getUserId()." THEN 1 ELSE 0 END AS isOwner"; + $idDashboard = intval($database->escapeValue($idDashboard)); + if($idDashboard !== 0){ + $whereSql .= "AND d.id=$idDashboard"; + } + + $sql = "SELECT d.id AS idDashboard, + d.name, + $isOwner + FROM ".TABLES['dashboards']." d + WHERE $whereSql + ORDER BY d.lastUpdated DESC + LIMIT 1"; + $data['info'] = $database->fetchResultArray($sql); + $data['info'] = isset($data['info'][0]) ? $data['info'][0] : []; + if(!empty($data['info'])){ + $data['gadgets'] = $this->getGadgets($data['info']['idDashboard']); + }else{ + return $this->getMyDashboard(0); + } + + return $data; + } + + /** + * get information for next actions gadget + * @param Array $filters array of filters to be applied + * @return Array array with next actions + */ + public function getNextActionsInfo($filters, $sortBy){ + global $database, $user; + + $filters = json_decode($filters); + $whereSql = UtilsModel::setFilterSql($filters); + $orderBySql = UtilsModel::setOrderBySql($sortBy); + $data = []; + if(!$orderBySql){ + $orderBySql = "idOrder DESC"; + } + if($user->getUserType() === USER_TYPES['BROKER']){ + $sql = "SELECT * FROM( + SELECT + DISTINCT o.id as idOrder, + o.orderNumber, + ps.shortDesc as stepAction, + 'in-progress' AS status + FROM ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['orders']." o + ON o.id=rops.idOrder + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id=rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps + ON ps.id=rps.idStep + WHERE rops.status='in-progress' + ) actions + WHERE $whereSql + ORDER BY $orderBySql + LIMIT 7"; + + $data = $database->fetchResultArray($sql); + }else{ + $sqlTemp= "CREATE TEMPORARY TABLE temp_next_actions AS ( + SELECT * FROM( + SELECT + o.id as idOrder, + o.orderNumber, + ps.shortDesc as stepAction, + ps.idActionCode + FROM ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['orders']." o + ON o.id=rops.idOrder + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=o.idCustomerInstance + INNER JOIN ".TABLES['customers']." c + ON c.id=rclc.idCustomer + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id=rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps + ON ps.id=rps.idStep + WHERE c.idUser=" .$user->getUserId(). " AND rops.status='in-progress' AND ps.idActionCode IN(4,6,8) + ) actions + WHERE $whereSql + ORDER BY $orderBySql + LIMIT 7 + )"; + $query = $database->query($sqlTemp); + + //questionnaiire validation + $sql = "SELECT + tna.idOrder, + tna.orderNumber, + tna.stepAction, + rod.validation as status + FROM temp_next_actions tna + INNER JOIN ".TABLES['rel_order_documents']." rod + ON rod.idOrder=tna.idOrder + WHERE tna.idActionCode=4 AND rod.validation='invalid'"; + $data = $database->fetchResultArray($sql); + + //customer acceptance + $sql = "SELECT + tna.idOrder, + tna.orderNumber, + tna.stepAction, + 'not-accepted' as status + FROM temp_next_actions tna + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idOrder=tna.idOrder + WHERE tna.idActionCode=6 AND rop.customerAccepted=0"; + $data = array_merge($data, $database->fetchResultArray($sql) ); + + //schedule meeting + $sql = "SELECT + DISTINCT tna.idOrder, + tna.orderNumber, + tna.stepAction, + 'pending' as status + FROM temp_next_actions tna + INNER JOIN ".TABLES['rel_order_scheduled_dates']." rosd + ON rosd.idOrder=tna.idOrder + WHERE tna.idActionCode=8 AND rosd.isDateConfirmed=0"; + $data = array_merge($data, $database->fetchResultArray($sql) ); + + $delSql = "DROP TABLE temp_next_actions"; + $query = $database->query($delSql); + } + + return $data; + } + + /** + * get information for the order central gadget + * @param Bool $viewAllOrders true if the user is company admin and checks the view all orders + * @param Array $filters array of filters to be applied + * @return Array array with orders info + */ + public function getOrderCentralInfo($viewAllOrders, $filters, $sortBy){ + global $database, $user; + + $filters = json_decode($filters); + $sortBy = json_decode($sortBy); + $whereSql = UtilsModel::setFilterSql($filters); + $orderBySql = UtilsModel::setOrderBySql($sortBy); + $extraJoin = ''; + $extraWhere = ''; + $extraHeaders = ''; + $countries = new Countries(); + $userType = $user->getUserType(); + $data = []; + $idUser = $user->getUserId(); + + if(!$orderBySql){ + $orderBySql = "idOrder DESC"; + } + + if($userType === USER_TYPES['BROKER']) { + $extraWhere = "AND ( + b.idUser = $idUser + OR o.assignedTo IS NULL + )"; + } + + if($userType === USER_TYPES['CUSTOMER']) { + $extraJoin = "INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id = o.idCustomerInstance + INNER JOIN ".TABLES['customers']." c + ON rclc.idCustomer = c.id"; + if($viewAllOrders === 'true') { + $extraHeaders = "c.name AS placedBy,"; + $extraJoin .= " INNER JOIN ".TABLES['users']." u + ON u.id = c.idUser + INNER JOIN ".TABLES['users']." uc + ON uc.idCompany = u.idCompany + AND uc.id = $idUser"; + } else { + $extraJoin .= " AND c.idUser = $idUser"; + } + } + + if($userType === USER_TYPES['COMMERCIAL_LEAD']) { + $extraJoin = "INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id = o.idCustomerInstance + INNER JOIN ".TABLES['commercial_leads']." cl + ON rclc.idCommercialLead = cl.id"; + if($viewAllOrders === 'true') { + $extraHeaders = "cl.name AS placedBy,"; + $extraJoin .= " INNER JOIN ".TABLES['users']." u + ON u.id = cl.idUser + INNER JOIN ".TABLES['users']." ucl + ON ucl.idCompany = u.idCompany + AND ucl.id = $idUser"; + } else { + $extraJoin .= " AND cl.idUser = $idUser"; + } + } + + if($userType === USER_TYPES['SUPPLIER']) { + $extraJoin = "INNER JOIN ".TABLES['rel_package_products']." rpp + ON rpp.idPackage=rop.idPackage AND rop.packageInstance=rpp.packageInstance + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rpp.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=scp.idSupplier + AND s.idUser = $idUser"; + } + + $sql = "SELECT * FROM( + SELECT o.id AS idOrder, + o.orderNumber, + $extraHeaders + DATE_FORMAT(o.orderDate, '%D %b, %Y') AS orderDate, + o.reference, + IF(b.name IS NULL, 'unassigned', b.name) AS assignedTo, + SUM(rop.packageFixedPrice * rop.units) AS fixedPrice, + SUM((rop.packageRecuringPrice * rop.units) + (rop.packageServicePrice * rop.units)) AS recurringPrice, + o.status + FROM ".TABLES['orders']." o + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idOrder=o.id + $extraJoin + LEFT JOIN ".TABLES['brokers']." b + ON o.assignedTo = b.id + WHERE o.status!='production' AND o.status!='canceled' AND o.status!='end-of-life' + $extraWhere + GROUP BY o.id + ) orders + WHERE $whereSql + ORDER BY $orderBySql + LIMIT 5"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['currency'] = $countries->getCurrencyForOrder($row['idOrder']); + $data[] = $row; + } + + return $data; + } + +} +?> diff --git a/api-wiaas/server/components/v2/financing/FinancingController.php b/api-wiaas/server/components/v2/financing/FinancingController.php new file mode 100644 index 0000000..12e75dc --- /dev/null +++ b/api-wiaas/server/components/v2/financing/FinancingController.php @@ -0,0 +1,35 @@ +model = new FinancingModel(); + } + + /** + * get interest rate + * @return json value for intereset rate + */ + public function getInterestRate(){ + echo json_encode($this->model->getInterestRate(), JSON_NUMERIC_CHECK); + } + + /** + * get interest rate for customers + * @return json values for interest rate for each customer + */ + public function getInterestRateForCustomers(){ + echo json_encode($this->model->getInterestRateForCustomers(), JSON_NUMERIC_CHECK); + } + + /** + * save interest rate + * @return json update message + */ + public function saveInterestRate(){ + $interestRate = isset($_REQUEST['interestRate']) ? $_REQUEST['interestRate'] : 0; + echo json_encode($this->model->saveInterestRate($interestRate)); + } + +} diff --git a/api-wiaas/server/components/v2/financing/FinancingModel.php b/api-wiaas/server/components/v2/financing/FinancingModel.php new file mode 100644 index 0000000..4c56996 --- /dev/null +++ b/api-wiaas/server/components/v2/financing/FinancingModel.php @@ -0,0 +1,31 @@ +getInterestRate(); + } + + /** + * get interest rate for customers + * @return HashArray values for interest rate for each customer + */ + public function getInterestRateForCustomers(){ + $interestRate = new InterestRate(); + return $interestRate->getInterestRateForCustomers(); + } + + /** + * save interest rate + * @param Float $interestRateValue interest rate value + * @return Array update message + */ + public function saveInterestRate($interestRateValue){ + $interestRate = new InterestRate(); + return $interestRate->saveInterestRate($interestRateValue); + } +} diff --git a/api-wiaas/server/components/v2/financing/InterestRate.php b/api-wiaas/server/components/v2/financing/InterestRate.php new file mode 100644 index 0000000..4763b57 --- /dev/null +++ b/api-wiaas/server/components/v2/financing/InterestRate.php @@ -0,0 +1,154 @@ +query($sql); + $row = $database->fetchArray($query); + $data['interestRate'] = isset($row['interestRate']) ? $row['interestRate'] : 0; + + return $data; + } + + /** + * get interest rate for each customer + * @return HashArray interest rate value for every customer in the system + */ + public function getInterestRateForCustomers(){ + global $database; + $data = []; + $interestRate = $this->getInterestRate()['interestRate']; + + $sql = "SELECT + rcd.discount, + rcd.idCustomer + FROM + ".TABLES['rel_customer_discount']." rcd"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)) { + $data[$row['idCustomer']] = $interestRate - $row['discount']; + } + + return $data; + } + + /** + * save interest rate + * @param Float $interestRateValue interest rate value + * @return Array update message + */ + public function saveInterestRate($interestRate){ + global $database; + $interestRate = $database->escapeValue($interestRate); + $data = []; + + if(!$interestRate){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NO_INTEREST_RATE' + ]; + + return $data; + } + + $checkMessage = $database->invalidNumber('interestRate', $interestRate, 0, 100); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + $sql = "UPDATE ".TABLES['financing']." + SET interestRate = $interestRate + WHERE id=".self::SYSTEM_FINANCING_RATE_ID; + $query = $database->query($sql); + + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'INTEREST_RATE_UPDATED' + ]; + + return $data; + } + + /** + * get customers discounts + * @return HashArray interest rate value + */ + public function getCustomersAndDiscount() { + global $database; + $data = $this->getInterestRate(); + + $sql = "SELECT + c.id AS idCustomer, + c.name, + IFNULL(rcd.discount, 0) AS discount + FROM + ".TABLES['customers']." c + LEFT JOIN ".TABLES['rel_customer_discount']." rcd + ON c.id = rcd.idCustomer"; + $data['customers'] = $database->fetchResultArray($sql); + + return $data; + } + + /** + * save discount for customer - financing + * @param Array $details id of the customer and the discount applied for each + * @return Array update message + */ + public function saveCustomersDiscount($details) { + global $database; + $interestRate = $this->getInterestRate()['interestRate']; + $insertValues = ''; + $affectedRows = 0; + $data = []; + + if(!count($details)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'CUSTOMERS_DISCOUNT_EMPTY' + ]; + + return $data; + } + + foreach($details as $customerDiscounts) { + $discount = floatval($customerDiscounts['discount']); + if($discount > $interestRate || $discount < 0) { + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'DISCOUNT_NOT_VALID', + 'key' => $customerDiscounts['name'] + ]; + } else { + $sql = "INSERT INTO ".TABLES['rel_customer_discount']." + (idCustomer, discount) + VALUES (".$customerDiscounts['idCustomer'].", '$discount') + ON DUPLICATE KEY + UPDATE + discount = '$discount'"; + $row = $database->query($sql); + $affectedRows += $database->affectedRows(); + } + } + + if($affectedRows) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'DISCOUNT_UPDATED' + ]; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/helpers/AddressHelper.php b/api-wiaas/server/components/v2/helpers/AddressHelper.php new file mode 100644 index 0000000..2a6a879 --- /dev/null +++ b/api-wiaas/server/components/v2/helpers/AddressHelper.php @@ -0,0 +1,414 @@ +getUserId()." + ORDER BY da.id DESC + "; + + return $database->fetchResultArray($sqlDelivery); + } + + /** + * returns the billing address information for the user logged in + * @return Array billing address info + */ + public function getBillingAddress() { + global $database, $user; + + $sqlBillingAddress = "SELECT + bi.id AS id, + bi.firstName AS firstName, + bi.lastName AS lastName, + bi.invoiceMail AS invoiceMail, + bi.idCountry AS idCountrySelected, + bi.detailedAddress AS detailedAddress, + bi.city AS city, + co.name AS countryName, + bi.zip AS zipCode + FROM + ".TABLES['customers']." c + INNER JOIN ".TABLES['billing_information']." bi + ON bi.idUser = c.idUser + INNER JOIN ".TABLES['countries']." co + ON co.id = bi.idCountry + WHERE c.idUser = ".$user->getUserId()." + ORDER BY bi.id DESC + "; + + return $database->fetchResultArray($sqlBillingAddress); + } + + /** + * check the owner for the address + * @param INT $idProfileAddress id for delivery address + * @return boolean returns ture if the users is the address owner + */ + private function checkAddressOwner($idProfileAddress){ + global $database, $user; + + $sql = "SELECT da.idUser + FROM ".TABLES['delivery_addresses']." da + WHERE da.id=$idProfileAddress AND da.idUser=".$user->getUserId(); + $query = $database->query($sql); + + return $database->numRows($query) > 0; + } + + /** + * remove delivery address + * @param INT $idProfileAddress id delivery address + * @return Array update message + */ + public function removeProfileAddress($idProfileAddress){ + global $database, $user; + $idProfileAddress = $database->escapeValue($idProfileAddress); + $data = []; + + if(!$idProfileAddress){ + $err_mes = [ + 'code' => 'error', + 'message' => 'NO_ADDRESS_SELECTED' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + if(!$this->checkAddressOwner($idProfileAddress)){ + $err_mes = [ + 'code' => 'error', + 'message' => 'NOT_ADDRESS_OWNER' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sql = "DELETE FROM ".TABLES['delivery_addresses']." + WHERE id=$idProfileAddress "; + $query = $database->query($sql); + if($database->affectedRows() > 0){ + $mes = [ + 'code' => 'success', + 'message' => 'ADDRESS_REMOVED' + ]; + }else{ + $mes = [ + 'code' => 'error', + 'message' => 'ADDRESS_ERROR' + ]; + } + + $data['messages'][] = $mes; + + return $data; + } + + /** + * validate data for saving address + * @param Object $info address information + * @return Array validation messages or empty if data is valid + */ + private function validateAddressData($info, $type = 'profileAddress'){ + global $database; + $data = []; + + foreach (get_object_vars($info) as $key => $value) { + $info->{$key} = $database->escapeValue($value); + } + + if(!isset($info->idCountrySelected) || empty($info->idCountrySelected)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_COUNTRY' + ]; + + return $data; + } + + if(!isset($info->city) || empty($info->city)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_CITY' + ]; + + return $data; + } + + $checkMessage = $database->invalidLength('city', $info->city, 100); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!isset($info->detailedAddress) || empty($info->detailedAddress)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_ADDRESS' + ]; + + return $data; + } + + $checkMessage = $database->invalidLength('detailedAddress', $info->detailedAddress, 500); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!isset($info->zipCode) || empty($info->zipCode)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_ZIP' + ]; + + return $data; + } + + $checkMessage = $database->invalidLength('zipCode', $info->zipCode, 20); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if($type === 'billingAddress'){ + if(isset($info->invoiceMail) && !empty($info->invoiceMail)) { + $checkMessage = $database->invalidLength('invoiceMail', $info->invoiceMail, 300); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!filter_var($info->invoiceMail, FILTER_VALIDATE_EMAIL)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_INVOICE_MAIL' + ]; + } + } + } + + return $data; + } + + /** + * save delivery address + * @param Object $profileAddress delivery address information + * @return Array update message + */ + public function saveProfileAddress($profileAddress){ + global $database, $user; + $profileAddress = json_decode($profileAddress); + $idUser = $user->getUserId(); + $data = []; + $userHelper = new UsersHelper(); + + if(!$profileAddress){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_PROFILE_ADDRESS' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + if(!$userHelper->checkRightsToEdit($idUser)){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_USER' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $checkMessage = $this->validateAddressData($profileAddress); + if(!empty($checkMessage)){ + return $checkMessage; + } + + $idAddress = isset($profileAddress->id) ? $profileAddress->id : 'null'; + + $sql = "INSERT INTO ".TABLES['delivery_addresses']." (id, idUser, idCountry, city, detailedAddress, zip) + VALUES(".$idAddress.", + ".$idUser.", + ".$profileAddress->idCountrySelected.", + '".$profileAddress->city."', + '".$profileAddress->detailedAddress."', + '".$profileAddress->zipCode."') + ON DUPLICATE KEY UPDATE + idCountry= VALUES(idCountry), + city= VALUES(city), + detailedAddress=VALUES(detailedAddress), + zip=VALUES(zip)"; + + $query = $database->query($sql); + + if($database->affectedRows()) { + $mes = [ + 'code' => 'success', + 'message' => 'PROFILE_ADDRESS_UPDATED' + ]; + $data['messages'][] = $mes; + }else{ + $mes = [ + 'code' => 'warning', + 'message' => 'PROFILE_ADDRESS_NOT_CHANGED' + ]; + $data['messages'][] = $mes; + } + + return $data; + } + + /** + * check owner for billing address + * @param INT $idBillingAddress id for billing address + * @return Boolean true if use has rights to modify the billing address + */ + private function checkBillingAddressOwner($idBillingAddress){ + global $database, $user; + + $sql = "SELECT bi.idUser + FROM ".TABLES['billing_information']." bi + WHERE bi.id=$idBillingAddress AND bi.idUser=".$user->getUserId(); + $query = $database->query($sql); + + return $database->numRows($query) > 0; + } + + /** + * remove billing address + * @param INT $idBillingAddress billing address information + * @return Array update message + */ + public function removeBillingAddress($idBillingAddress){ + global $database, $user; + $idBillingAddress = $database->escapeValue($idBillingAddress); + $data = []; + + if(!$idBillingAddress){ + $err_mes = [ + 'code' => 'error', + 'message' => 'NO_ADDRESS_SELECTED' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + if(!$this->checkBillingAddressOwner($idBillingAddress)){ + $err_mes = [ + 'code' => 'error', + 'message' => 'NOT_ADDRESS_OWNER' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $sql = "DELETE FROM ".TABLES['billing_information']." + WHERE id=$idBillingAddress "; + $query = $database->query($sql); + if($database->affectedRows() > 0){ + $mes = [ + 'code' => 'success', + 'message' => 'BILLING_ADDRESS_REMOVED' + ]; + $data['messages'][] = $mes; + }else{ + $mes = [ + 'code' => 'error', + 'message' => 'ADDRESS_ERROR' + ]; + $data['messages'][] = $mes; + } + + return $data; + } + + /** + * save billing address + * @param INT $idCompany id for company + * @param Object $billingAddress billing address information + * @return Array update message + */ + public function saveBillingAddress($idCompany, $billingAddress){ + global $database, $user; + $billingAddress = json_decode($billingAddress); + $idCompany = $database->escapeValue($idCompany); + $idUser = $user->getUserId(); + $data = []; + $userHelper = new UsersHelper(); + + if(!$billingAddress){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_PROFILE_ADDRESS' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $checkMessage = $this->validateAddressData($billingAddress, 'billingAddress'); + if(!empty($checkMessage)){ + return $checkMessage; + } + + $idAddress = isset($billingAddress->id) ? $billingAddress->id : 'null'; + + $sql = "INSERT INTO ".TABLES['billing_information']." (id, idUser, idCountry, firstName, lastName, invoiceMail, city, detailedAddress, zip) + VALUES(".$idAddress.", + ".$idUser.", + ".$billingAddress->idCountrySelected.", + '".$billingAddress->firstName."', + '".$billingAddress->lastName."', + '".$billingAddress->invoiceMail."', + '".$billingAddress->city."', + '".$billingAddress->detailedAddress."', + '".$billingAddress->zipCode."') + ON DUPLICATE KEY UPDATE + idCountry= VALUES(idCountry), + firstName=VALUES(firstName), + lastName=VALUES(lastName), + invoiceMail=VALUES(invoiceMail), + city= VALUES(city), + detailedAddress=VALUES(detailedAddress), + zip=VALUES(zip)"; + + $query = $database->query($sql); + + if($database->affectedRows()) { + $mes = [ + 'code' => 'success', + 'message' => 'BILLING_ADDRESS_UPDATED' + ]; + $data['messages'][] = $mes; + }else{ + $mes = [ + 'code' => 'warning', + 'message' => 'BILLING_ADDRESS_NOT_CHANGED' + ]; + $data['messages'][] = $mes; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/helpers/Countries.php b/api-wiaas/server/components/v2/helpers/Countries.php new file mode 100644 index 0000000..c3a91a0 --- /dev/null +++ b/api-wiaas/server/components/v2/helpers/Countries.php @@ -0,0 +1,55 @@ +fetchResultArray($sql); + + return !empty($row) ? $row[0] : ''; + } + + public function getCurrencyForOrder($idOrder){ + global $database; + $data = []; + + $sql = "SELECT + c.currency + FROM ".TABLES['countries']." c + INNER JOIN ".TABLES['packages']." p + ON p.idCountry=c.id + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage=p.id + WHERE rop.idOrder=$idOrder LIMIT 1"; + $row = $database->fetchResultArray($sql); + + return !empty($row) ? $row[0]['currency'] : ''; + } + + /** + * get all countries in the system + * @return Array list of countries + */ + public function getCountries(){ + global $database; + $sql = "SELECT c.id AS idCountry, + c.name AS countryName + FROM ".TABLES['countries']." c"; + + return $database->fetchResultArray($sql); + } + +} diff --git a/api-wiaas/server/components/v2/home/apiTemplate.php b/api-wiaas/server/components/v2/home/apiTemplate.php new file mode 100644 index 0000000..820636c --- /dev/null +++ b/api-wiaas/server/components/v2/home/apiTemplate.php @@ -0,0 +1,17 @@ + diff --git a/api-wiaas/server/components/v2/login/LoginController.php b/api-wiaas/server/components/v2/login/LoginController.php new file mode 100644 index 0000000..46f29ac --- /dev/null +++ b/api-wiaas/server/components/v2/login/LoginController.php @@ -0,0 +1,84 @@ +model = new LoginModel(); + } + + /** + * get JWT Token for app + * @return json token + */ + public function getToken(){ + global $user; + if(isset($_POST['login'])){ + $login = $user->login($_POST['username'], $_POST['password'], true); + $login['userInfo'] = $user->getUserInfo(); + $login['serverTime'] = time(); + echo json_encode($login); + }else{ + echo json_encode(['status' => 'fail', 'errorMessage' => 'invalid request']); + } + } + + /** + * validate the token + * @return json status => status for token validation, errorMessage => error message + */ + public function validateToken(){ + global $user; + if($user->isLoggedIn()){ + $refreshToken = $user->getRefreshToken(); + $message = ['status' => 'success', 'userInfo' => $user->getUserInfo(), 'refreshToken' => $refreshToken, 'serverTime' => time()]; + }else{ + $message = ['status' => 'fail', 'errorMessage' => $user->getErrorMessage()]; + } + + echo json_encode($message); + } + + public function refreshToken(){ + global $user; + + $refreshToken = isset($_REQUEST['refreshToken']) ? $_REQUEST['refreshToken'] : ''; + $lastActivity = isset($_REQUEST['lastActivity']) ? $_REQUEST['lastActivity'] : '1000'; + $message = $user->refreshToken($refreshToken, $lastActivity); + $message['serverTime'] = time(); + $message['userInfo'] = $user->getUserInfo(); + + echo json_encode($message); + } + + /** + * get allowed modues for user type + * @return json modules array + */ + public function getModules(){ + global $user, $route; + if($user->isLoggedIn()){ + echo json_encode(['modules' => $route::getModules()]); + }else{ + echo json_encode(['modules' => []]); + } + } + + /** + * generate new token for user + * @return json update message + */ + public function forgotPassword(){ + $mail = isset($_POST['mail']) ? $_POST['mail'] : ''; + echo json_encode($this->model->forgotPassword($mail)); + } + + public function changePassword(){ + $token = isset($_REQUEST['token']) ? $_REQUEST['token'] : ''; + $passwords = [ + 'newPassword' => isset($_REQUEST['newPassword']) ? $_REQUEST['newPassword'] : '', + 'confirmPassword' => isset($_REQUEST['confirmPassword']) ? $_REQUEST['confirmPassword'] : '' + ]; + echo json_encode($this->model->changePassword($token, $passwords)); + } +} +?> diff --git a/api-wiaas/server/components/v2/login/LoginModel.php b/api-wiaas/server/components/v2/login/LoginModel.php new file mode 100644 index 0000000..1fd0994 --- /dev/null +++ b/api-wiaas/server/components/v2/login/LoginModel.php @@ -0,0 +1,123 @@ +escapeValue($mail); + $now = new DateTime(); + $now = $now->format('Y-m-d H:i:s'); + + $sql = "SELECT + u.username, + u.mail, + rut.idType AS idUserType, + ut.type AS type, + IF( + ADDTIME(u.tokenTS, '00:05') > '".$now."', + 0, + 1 + ) AS allowPasswordGeneration + FROM ".TABLES['users']." u + INNER JOIN ".TABLES['rel_user_type']." rut + ON rut.idUser=u.id + INNER JOIN ".TABLES['user_types']." ut + ON ut.id=rut.idType + WHERE mail = '".$mail."'"; + + $userInfo = $database->fetchResultArray($sql); + + if(count($userInfo) == 0) { + $data['messages'][] = [ + 'code' => 'danger', + 'message' => 'NO_USER' + ]; + + return $data; + } + + foreach ($userInfo as $info) { + if($info['allowPasswordGeneration'] == 1) { + $messageData = self::generateTokenForUserPassword(json_encode($info)); + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'GENERATED_SUCCESSFULLY' + ]; + } else { + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'CHANGE_LATER' + ]; + } + } + + return $data; + } + + /** + * generates a new random password for the user provided + * @param Array $userInfo contains username and password for the user of the password to change + * @return Array confirmation message + */ + public static function generateTokenForUserPassword($userInfo) { + global $database, $user; + $userInfo = (array) json_decode($userInfo); + + $token = bin2hex(random_bytes(16)); + $tokenTimestamp = new DateTime(); + $sql = "UPDATE + ".TABLES['users']." u + SET + u.token='".$token."', + u.tokenTS='".$tokenTimestamp->format('Y-m-d H:i:s')."' + WHERE u.username='".$database->escapeValue($userInfo['username'])."'"; + + $result = $database->query($sql); + if($database->affectedRows() == 1) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PASSWORD_GENERATED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_PASSWORD_GENERATED' + ]; + } + + $data['messages'][] = UtilsModel::sendUserConfirmationMail($userInfo, $userInfo['mail'], 'generate', $token); + + return $data; + } + + /** + * change password for a user based on token + * @param String $token token required to change the password + * @param HashArray $passwords new password and confirm password array + * @return HashArray update message + */ + public function changePassword($token, $passwords){ + global $user; + $data = []; + + $confirmTokenMessage = $user->checkPasswordToken($token); + if($confirmTokenMessage !== 'success') { + + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_CHANGE_TOKEN' + ]; + + return $data; + } + + $data = $user->resetPassword(json_encode($passwords)); + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/orderProjects/OrderProjects.php b/api-wiaas/server/components/v2/orderProjects/OrderProjects.php new file mode 100644 index 0000000..ed5abe1 --- /dev/null +++ b/api-wiaas/server/components/v2/orderProjects/OrderProjects.php @@ -0,0 +1,115 @@ +fetchResultArray($sql); + } + + private function validateProjectData($projectData){ + global $database; + $data = []; + + $checkMessage = $database->isEmpty('projectName', $projectData->projectName); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + $checkMessage = $database->invalidLength('projectName', $projectData->projectName, 100); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + return $data; + } + + public function editOrderProject($projectData){ + global $database; + $data = []; + $projectData = json_decode($projectData); + + if(empty($projectData)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_DATA' + ]; + + return $data; + } + + $checkMessages = $this->validateProjectData($projectData); + if(!empty($checkMessages)){ + return $checkMessages; + } + + $sql = "UPDATE ".TABLES['order_projects']." + SET name='".$database->escapeValue($projectData->projectName)."', + isAvailable=".$database->escapeValue($projectData->isAvailable)." + WHERE id=".$database->escapeValue($projectData->idProject); + $query = $database->query($sql); + + if($database->affectedRows() < 1){ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + + }else{ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PROJECT_UPDATED' + ]; + } + + return $data; + } + + public function addOrderProject($projectData){ + global $database; + $data = []; + $projectData = json_decode($projectData); + + if(empty($projectData)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_DATA' + ]; + + return $data; + } + + $checkMessages = $this->validateProjectData($projectData); + if(!empty($checkMessages)){ + return $checkMessages; + } + + $sql = "INSERT INTO ".TABLES['order_projects']." + (name) + VALUES('".$database->escapeValue($projectData->projectName)."')"; + $query = $database->query($sql); + + if($database->affectedRows() < 1){ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'INVALID_DATA' + ]; + + }else{ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PROJECT_ADDED' + ]; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/orderProjects/OrderProjectsController.php b/api-wiaas/server/components/v2/orderProjects/OrderProjectsController.php new file mode 100644 index 0000000..52557f2 --- /dev/null +++ b/api-wiaas/server/components/v2/orderProjects/OrderProjectsController.php @@ -0,0 +1,20 @@ +model = new OrderProjectsModel(); + } + + public function getOrderProjects(){ + $available = isset($_REQUEST['available']) ? $_REQUEST['available'] : 1; + echo json_encode($this->model->getOrderProjects($available), JSON_NUMERIC_CHECK); + } + + public function addOrderProject(){ + $projectData = isset($_REQUEST['projectData']) ? $_REQUEST['projectData'] : '[]'; + echo json_encode($this->model->addOrderProject($projectData), JSON_NUMERIC_CHECK); + } + +} diff --git a/api-wiaas/server/components/v2/orderProjects/OrderProjectsModel.php b/api-wiaas/server/components/v2/orderProjects/OrderProjectsModel.php new file mode 100644 index 0000000..406dc16 --- /dev/null +++ b/api-wiaas/server/components/v2/orderProjects/OrderProjectsModel.php @@ -0,0 +1,15 @@ +getOrderProjects($available); + } + + public function addOrderProject($projectData){ + $orderProjectsHandler = new OrderProjects(); + + return $orderProjectsHandler->addOrderProject($projectData); + } +} diff --git a/api-wiaas/server/components/v2/orders/CustomerAcceptance.php b/api-wiaas/server/components/v2/orders/CustomerAcceptance.php new file mode 100644 index 0000000..bbc05ae --- /dev/null +++ b/api-wiaas/server/components/v2/orders/CustomerAcceptance.php @@ -0,0 +1,184 @@ +escapeValue($idOrder); + $data = []; + $orderExtraActions = new orderExtraActions(); + + $sql = "SELECT o.id AS idOrder, + o.customerAccepted, + o.customerDeclineReason, + DATE_FORMAT(o.acceptanceDueDate, '%D %b, %y') as acceptanceDueDate, + o.acceptanceDueDate as acceptanceDueDateNoFormat + FROM ".TABLES['orders']." o + WHERE o.id=$idOrder"; + + $query = $database->query($sql); + if($database->numRows($query) > 0){ + $row = $database->fetchArray($query); + $dueDate = new DateTime($row['acceptanceDueDateNoFormat']); + $now = time(); + $timeDiff = ($dueDate->getTimestamp() - $now ) / (3600 *24); + $row['daysDiff'] = $timeDiff; + } + $data = $row; + + $sql = "SELECT + d.id AS idDocument, + d.documentName, + d.extension, + rod.idOrder + FROM ".TABLES['documents']." d + INNER JOIN ".TABLES['rel_order_documents']." rod + ON rod.idDocument=d.id + WHERE rod.idOrder=$idOrder AND d.idDocumentType=".$orderExtraActions::DOCUMENT_TYPES['ID_ACCEPTANCE_DOC_TYPE']; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)) { + $data['acceptanceDocuments'][] = $row; + } + + return $data; + } + + /** + * get the number of acceptance documents uploaded + * @param INT $idOrder id for the order + * @return INT number of uploaded documents + */ + private function getAcceptanceDocumentsCount($idOrder){ + global $database; + $orderExtraActions = new orderExtraActions(); + + $sql = "SELECT COUNT(idDocument) AS totalDocumentsUplaoded + FROM ".TABLES['rel_order_documents']." rod + INNER JOIN ".TABLES['documents']." d + ON d.id=rod.idDocument AND d.idDocumentType=".$orderExtraActions::DOCUMENT_TYPES['ID_ACCEPTANCE_DOC_TYPE']." + WHERE rod.idOrder=$idOrder + "; + $query = $database->query($sql); + $row = $database->fetchArray($query); + + return intval($row['totalDocumentsUplaoded']); + } + + /** + * customer change acceptance status for a package + * @param INT $idOrder id for the order + * @param String $actionType accept or decline the installation + * @param String $declineReason the reason why the customer declined the installation + * @return Array update message + */ + public function acceptDeclineInstallation($idOrder, $actionType, $declineReason){ + global $database; + $idOrder = $database->escapeValue($idOrder); + $actionType = trim($database->escapeValue($actionType)); + $declineReason = trim($database->escapeValue($declineReason)); + $data = []; + $customerAcceptanceStatus = 1; + $successMessage = 'INSTALLATION_ACCEPTED'; + + if($actionType === 'decline') { + if(!$declineReason) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'DECLINE_REASON_EMPTY' + ]; + + return $data; + } + $customerAcceptanceStatus = -1; + $successMessage = 'INSTALLATION_DECLINED'; + }else{ + $uploadedDocuments = $this->getAcceptanceDocumentsCount($idOrder); + if($uploadedDocuments === 0){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ACCEPTANCE_NOT_UPLOADED' + ]; + + return $data; + } + } + + $sql = "UPDATE ".TABLES['orders']." + SET customerAccepted=$customerAcceptanceStatus, + customerDeclineReason='$declineReason' + WHERE id=$idOrder"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => $successMessage + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'ACCEPTANCE_NOT_UPDATED' + ]; + } + + return $data; + } + + /** + * upload customer acceptance document + * @param INT $idOrder id for the order + * @param FILE $file file to be uploaded + * @return Array upload status + */ + public function uploadAcceptanceDocument($idOrder, $file){ + global $database, $user; + $orderExtraActions = new orderExtraActions(); + $idOrder = $database->escapeValue($idOrder); + + $fileManager = new FileManager(); + + $sql = "SELECT MAX(d.id)+1 AS maxIdDocument + FROM ".TABLES['documents']." d"; + $maxId = $database->fetchResultArray($sql); + $maxIdDocument = $maxId && $maxId[0] && $maxId[0]['maxIdDocument'] ? $maxId[0]['maxIdDocument'] : 1; + + $sql = "SELECT o.orderNumber + FROM orders o + WHERE id=$idOrder"; + $query = $database->query($sql); + $row = $database->fetchArray($query); + $documentName = 'customerAcceptance_'.$row['orderNumber'].'_' . $maxIdDocument; + $uploadedBy = $user->getUserId(); + $data = $fileManager->uploadFile($file, $orderExtraActions::DOCUMENT_TYPES['ID_ACCEPTANCE_DOC_TYPE'], $documentName, $uploadedBy); + + if(isset($data['messages'])){ + return $data; + } + + $idDocument = $data['idDocument']; + $sql = "INSERT INTO ".TABLES['rel_order_documents']." + (idOrder, idDocument, validation) + VALUES($idOrder, $idDocument, 'not-validated')"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'FILE_UPLOADED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NOT_LINKED_TO_ORDER' + ]; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/orders/InstallationScheduling.php b/api-wiaas/server/components/v2/orders/InstallationScheduling.php new file mode 100644 index 0000000..464afdd --- /dev/null +++ b/api-wiaas/server/components/v2/orders/InstallationScheduling.php @@ -0,0 +1,1136 @@ +escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $extraWhere = ''; + + if($idPackage) { + $extraWhere = "AND ics.idPackage = $idPackage"; + $data[$idOrder . '-' . $idPackage] = []; + } + + $sql = " + SELECT + ics.idPackage, + isd.date, + isd.status, + isd.idUser, + isd.currentDate, + u.username, + ut.type AS userType + FROM + ".TABLES['installation_schedule_dates']." isd + INNER JOIN ".TABLES['installation_company_selections']." ics + ON isd.idCompanySelection = ics.id + INNER JOIN ".TABLES['users']." u + ON u.id = isd.idUser + INNER JOIN ".TABLES['rel_user_type']." rut + ON rut.idUser = u.id + INNER JOIN ".TABLES['user_types']." ut + ON ut.id = rut.idType + WHERE ics.idOrder = $idOrder + $extraWhere + AND ics.isActive = 1 + ORDER BY isd.date, isd.currentDate + "; + $result = $database->query($sql); + while($row = $database->fetchArray($result)) { + $orderPackagePair = $idOrder . '-' . $row['idPackage']; + $data[$orderPackagePair][$row['date']]['isProposedByMe'] = intval($row['idUser']) === intval($user->getUserId()); + unset($row['idUser']); + $data[$orderPackagePair][$row['date']]['details'][] = $row; + $data[$orderPackagePair][$row['date']]['lastStatus'] = $row['status']; + } + + return ['confirmationDates' => $data]; + } + + /** + * get all installation companies for the order selected + * @param Int $idOrder id of the order + * @return Array array with all the installation companies + */ + public function getInstallCompaniesForOrder($idOrder) { + global $database, $user; + + $idOrder = $database->escapeValue($idOrder); + $availableCompanies = []; + $installationSelectedArray = []; + $installationSelected = []; + $isMyInstallationCompany = []; + $extraWhere = ''; + $extraJoin = ''; + + if(!$idOrder) { + return []; + } + + if($user->getUserType() === USER_TYPES['SUPPLIER']) { + $extraWhere = "AND u.id = ".$user->getUserId(); + $extraJoin = "INNER JOIN ".TABLES['installation_company_selections']." ics + ON ics.idProduct = rpp.idProduct + AND ics.idPackage = rpp.idPackage + AND ics.idOrder = rop.idOrder + AND ics.isActive = 1"; + } + + $sql = " + SELECT + os.idPackage, + scp.idProduct AS id, + scp.idSupplier, + scp.productName AS name + FROM + ".TABLES['order_selections']." os + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct = os.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id = scp.idSupplier + INNER JOIN ".TABLES['users']." u + ON u.id = s.idUser + WHERE os.idOrder = $idOrder + AND os.selectionFor = 'installation' + $extraWhere + "; + $query = $database->query($sql); + while($row = $database->fetchArray($query)) { + $installationSelectedArray[$idOrder . '-' . $row['idPackage']][] = $row; + } + + foreach ($installationSelectedArray as $orderPackagePair => $installInfo) { + if(count($installInfo) > 0) { + $installationSelected[$orderPackagePair] = $installInfo[0]; + $isMyInstallationCompany[$orderPackagePair] = true; + } else { + $isMyInstallationCompany[$orderPackagePair] = false; + } + } + + $sql = " + SELECT + rpp.idPackage, + scp.idProduct AS id, + scp.idSupplier, + scp.productName AS name + FROM + ".TABLES['rel_package_products']." rpp + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage = rpp.idPackage + AND rpp.packageInstance = rop.packageInstance + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct = rpp.idProduct + INNER JOIN ".TABLES['product_categories']." pc + ON pc.id = scp.idProductCategory + INNER JOIN ".TABLES['product_types']." pt + ON pt.id = pc.idType + INNER JOIN ".TABLES['suppliers']." s + ON s.id = scp.idSupplier + INNER JOIN ".TABLES['users']." u + ON u.id = s.idUser + $extraJoin + WHERE pt.type = 'installation' + AND rop.idOrder = $idOrder + $extraWhere + "; + $query = $database->query($sql); + while($row = $database->fetchArray($query)) { + $availableCompanies[$idOrder . '-' . $row['idPackage']][] = $row; + } + + foreach ($availableCompanies as $orderPackagePair => $installInfo) { + if(count($availableCompanies[$orderPackagePair]) === 1) { + $installationSelected[$orderPackagePair] = $availableCompanies[$orderPackagePair][0]; + $message = self::changeInstallationCompany($idOrder, $installationSelected[$orderPackagePair]['idPackage'], $installationSelected[$orderPackagePair]['id']); + if(array_key_exists($orderPackagePair, $isMyInstallationCompany) && !$isMyInstallationCompany[$orderPackagePair]) { + $isMyInstallationCompany[$orderPackagePair] = true; + } + } else { + $isMyInstallationCompany[$orderPackagePair] = false; + } + } + + return [ + 'available' => $availableCompanies, + 'selected' => $installationSelected, + 'isMyInstallationCompany' => $isMyInstallationCompany + ]; + } + + /** + * Update the estimation date for the installation + * @param Int $idOrder Id of the order to be modified + * @param Int $idPackage id of the package to be modified + * @param String $newDate the date set by the user for the installation + * @param String $status the status of the date to be added + * @return array response message for the update + */ + public function updateInstallationDate($idOrder, $idPackage, $newDate, $status) { + global $database, $user; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $newDate = $database->escapeValue($newDate); + $status = $database->escapeValue($status); + $data = []; + $userType = $user->getUserType(); + $mailTitle = ''; + $templateUrl = ''; + $idOrderPackagePair = $idOrder . '-' . $idPackage; + $ordersExtraActions = new orderExtraActions(); + + if(!$status) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'STATUS_NOT_SET' + ]; + + return $data; + } + + if($status === 'accept') { + $status = 'accepted'; + } else if($status === 'decline'){ + $status = 'declined'; + } + + if(!$newDate) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INSTALLATION_DATE_EMPTY' + ]; + + return $data; + } + $checkDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $newDate); + if($checkDate){ + $data['messages'][] = $checkDate; + + return $data; + } + + $earliestInstallationDate = $this->getInstallationScheduleEID($idOrder); + if(!$earliestInstallationDate[$idOrder]) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'EID_NOT_SET' + ]; + + return $data; + } + + $idCompanySelection = $this->getActiveInstallationCompanyId($idOrder, $idPackage); + if(!$idCompanySelection) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'RELATION_NOT_FOUND' + ]; + + return $data; + } + + if($userType === USER_TYPES['CUSTOMER']) { + $brokerMails = (array) UtilsModel::getBrokersMail(); + $supplierMail = (array) self::getSupplierMail($idCompanySelection); + $mail = array_merge($brokerMails, $supplierMail); + } else if($userType === USER_TYPES['SUPPLIER']){ + $mail = self::getCustomerMail($idOrder); + } else { + $customerMail = (array) self::getCustomerMail($idOrder); + $supplierMail = (array) self::getSupplierMail($idCompanySelection); + $mail = array_merge($customerMail, $supplierMail); + } + + $mailDetails = [ + 'idOrder' => $idOrder, + 'idCompanySelection' => $idCompanySelection, + 'orderNumber' => UtilsModel::getOrderNumberById($idOrder), + 'acceptedDate' => $newDate, + 'proposedDate' => $newDate, + 'actionDoneBy' => $user->getUserFullName(), + 'mail' => $mail + ]; + + if($status === 'proposed') { + $mailTitle = 'New installation date proposed'; + $templateUrl = 'installationProposedTemplate.php'; + + if($newDate < $earliestInstallationDate[$idOrder]) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PAST_DATE', + 'key' => $earliestInstallationDate[$idOrder] + ]; + + return $data; + } + + $sql = " + SELECT id + FROM ".TABLES['installation_schedule_dates']." + WHERE idCompanySelection = $idCompanySelection + AND date='$newDate' AND status='proposed'"; + $result = $database->query($sql); + if($database->numRows($result) === 1) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PROPOSED_DATE_EXISTS' + ]; + + return $data; + } + + if($userType === USER_TYPES['BROKER']) { + $earliestInstallationDate = new DateTime($earliestInstallationDate); + $maxSLAInstallDate = $earliestInstallationDate->add(new DateInterval('P'.ADDITIONAL_MAX_INSTALL_DAYS.'D')); + $maxSLAInstallDate = $maxSLAInstallDate->format('Y-m-d'); + if($maxSLAInstallDate < $newDate) { + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'MAX_SLA_EXCEEDED', + 'key' => $maxSLAInstallDate + ]; + } + } + } + + $lastStatuses = $this->getInstallationDateLastStatus($idCompanySelection); + + if($status === 'accepted') { + $mailTitle = 'Installation date accepted'; + $templateUrl = 'installationAcceptedTemplate.php'; + $isinstallationAccepted = $this->installationDateIsAlreadyAccepted($lastStatuses, $newDate, $idCompanySelection); + + if($isinstallationAccepted) { + $message = [ + 'code' => 'success', + 'message' => 'INSTALLATION_ALREADY_ACCEPTED' + ]; + } + + $sql = "UPDATE ".TABLES['orders']." + SET acceptanceDueDate=DATE_ADD('$newDate', INTERVAL ".self::CUSTOMER_ACCEPTANCE_DAYS_INTERVAL." DAY) + WHERE id=$idOrder"; + $query = $database->query($sql); + } + + $database->beginTransaction(); + $sql = " + INSERT INTO ".TABLES['installation_schedule_dates']." ( + idCompanySelection, + idUser, + date, + status + ) + VALUES( + $idCompanySelection, + ".$user->getUserId().", + '$newDate', + '$status' + )"; + $query = $database->query($sql); + if($query){ + $database->commit(); + $message = [ + 'code' => 'success', + 'message' => 'INSTALLATION_DATE_UPDATED' + ]; + }else{ + $database->rollback(); + $message = [ + 'code' => 'error', + 'message' => 'SERVER_ERROR' + ]; + } + $data['messages'][] = $message; + + if($status === 'declined') { + $confirmationDates = $this->getInstallationDates($idOrder, $idPackage)['confirmationDates'][$idOrderPackagePair]; + + if($confirmationDates) { + if(count($confirmationDates) > 0) { + $allDatesDeclined = true; + + forEach($confirmationDates as $date => $details) { + if($details['lastStatus'] !== 'declined') { + $allDatesDeclined = false; + } + } + + if($allDatesDeclined) { + $mailTitle = 'Installation dates declined'; + $templateUrl = 'installationDeclinedTemplate.php'; + } + } + } + } + + if($mailTitle && $templateUrl) { + $data['messages'][] = self::sendInstallationSchedulingMail($mailDetails, $mailTitle, $templateUrl); + } + + return $data; + } + + /** + * checks if an installation date is already accepted, and puts it in canceled state if so + * @param Array $lastStatuses the last status for each date + * @param String $newDate the date to be updated + * @param Int $idCompanySelected id of the installation company selected + * @return Boolean true or false if the installation date is accepted for the order package + */ + private function installationDateIsAlreadyAccepted($lastStatuses, $newDate, $idCompanySelected) { + global $database, $user; + $dateCanceled = 0; + + foreach($lastStatuses as $installationDate => $lastStatus) { + if($installationDate !== $newDate && $lastStatus === 'accepted') { + $sql = "INSERT INTO ".TABLES['installation_schedule_dates']." + (idCompanySelection, idUser, date, status) + VALUES ( + $idCompanySelected, + ".$user->getUserId().", + '$installationDate', + 'canceled' + ) + "; + $result = $database->query($sql); + + if($database->affectedRows()) { + $dateCanceled++; + } + } + } + + return false; + } + + /** + * gets the lastest status of the earliest installation date for an order + * @param Int $idCompanySelected the id of the insatllation company selected + * @return String the latest status or empty string + */ + private function getInstallationDateLastStatus($idCompanySelected) { + global $database; + $data = []; + + $sql = " + SELECT + isd.date AS installationDate, + isd.status AS lastStatus + FROM + ".TABLES['installation_schedule_dates']." isd + INNER JOIN + (SELECT + isdd.date AS installationDate, + MAX(isdd.currentDate) AS maxDate + FROM + ".TABLES['installation_schedule_dates']." isdd + WHERE isdd.idCompanySelection = $idCompanySelected + GROUP BY isdd.date) installations_max_dates + ON installations_max_dates.installationDate = isd.date + AND installations_max_dates.maxDate = isd.currentDate + WHERE isd.idCompanySelection = $idCompanySelected + ORDER BY isd.date"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)) { + $data[$row['installationDate']] = $row['lastStatus']; + } + + return $data; + } + + /** + * returns the id of the installation company active for order and package + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @return Int id of the relation + */ + private function getActiveInstallationCompanyId($idOrder, $idPackage) { + global $database; + + $sql = " + SELECT + ics.id AS selectionId + FROM + ".TABLES['installation_company_selections']." ics + WHERE ics.idOrder = $idOrder AND ics.idPackage = $idPackage AND ics.isActive = 1"; + $data = $database->fetchResultArray($sql); + + if($data && $data[0]['selectionId']) { + return $data[0]['selectionId']; + } + + return 0; + } + + /** + * checks if all dates for the package are declined and sends a mail + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @param Int $idCompanySelection id of the combination bwtween the order, package and installation company selected + * @return Array confirmation message + */ + private function checkIfAllDatesAreDeclined($idOrder, $idPackage, $idCompanySelection) { + global $database; + $idOrderPackage = $idOrder . '-' . $idPackage; + $allDatesDeclined = true; + + $confirmationDates = $this->getInstallationDates($idOrder, $idPackage)['confirmationDates']; + + if($confirmationDates && array_key_exists($idOrderPackage, $confirmationDates)) { + if(count($confirmationDates[$idOrderPackage]) === 0) { + return; + } + + forEach($confirmationDates[$idOrderPackage] as $date => $details) { + if($details['lastStatus'] !== 'declined' && $details['lastStatus'] !== 'canceled') { + $allDatesDeclined = false; + } + } + + if($allDatesDeclined) { + $mailTitle = APPLICATION_NAME.' installation dates declined'; + $templateUrl = 'installationDeclinedTemplate.php'; + + $info = [ + 'idOrder' => $idOrder, + 'idCompanySelection' => $idCompanySelection, + 'orderNumber' => UtilsModel::getOrderNumberById($idOrder) + ]; + + return self::sendInstallationSchedulingMail($info, $mailTitle, $templateUrl); + } + } + + return; + } + + /** + * remove the date from the order package + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @param String $installationDate the installation date to be removed + * @return Array confirmation messages + */ + public function removeMyDate($idOrder, $idPackage, $installationDate) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $installationDate = $database->escapeValue($installationDate); + + if(!$installationDate) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INSTALLATION_DATE_EMPTY' + ]; + + return $data; + } + $idCompanySelection = $this->getActiveInstallationCompanyId($idOrder, $idPackage); + if(!$idCompanySelection) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'RELATION_NOT_FOUND' + ]; + + return $data; + } + $lastStatus = $this->getInstallationDateLastStatus($idCompanySelection); + if($lastStatus[$installationDate] !== 'proposed') { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INSTALLATION_DATE_NOT_REMOVED' + ]; + + return $data; + } + + $sql = " + DELETE + FROM + ".TABLES['installation_schedule_dates']." + WHERE idCompanySelection = $idCompanySelection + AND date = '$installationDate'"; + + $result = $database->query($sql); + + if($database->affectedRows() === 1) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'INSTALLATION_DATE_REMOVED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INSTALLATION_DATE_REMOVE_ERROR' + ]; + } + + return $data; + } + + /** + * send mail for installation scheduling functionality + * @param Array $info array with all neccessary data about the order + * @param String $mailTitle the title of the mail + * @param String $templateUrl the mail template to be sent + * @return Array update message + */ + public function sendInstallationSchedulingMail($info, $mailTitle, $templateUrl) { + global $user; + $userType = $user->getUserType(); + $idOrder = array_key_exists('idOrder', $info) ? $info['idOrder'] : 0; + $idCompanySelection = array_key_exists('idCompanySelection', $info) ? $info['idCompanySelection'] : 0; + $orderNumber = array_key_exists('orderNumber', $info) ? $info['orderNumber'] : 0; + $acceptedDate = array_key_exists('acceptedDate', $info) ? $info['acceptedDate'] : ''; + $proposedDate = array_key_exists('proposedDate', $info) ? $info['proposedDate'] : ''; + $actionDoneBy = array_key_exists('actionDoneBy', $info) ? $info['actionDoneBy'] : '-'; + + if(array_key_exists('orderUrl', $info)) { + $orderUrl = $info['orderUrl']; + } else { + $orderUrl = $userType === USER_TYPES['CUSTOMER'] ? WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$idOrder.'&orderNumber='.$orderNumber : WIAAS_URL.'/'.$idOrder; + } + + if(array_key_exists('mail', $info)) { + $mail = $info['mail']; + } else { + if($userType === USER_TYPES['CUSTOMER']) { + $brokerMails = (array) self::getBrokersMail(); + $supplierMail = (array) self::getSupplierMail($idCompanySelection); + $mail = array_merge($brokerMails, $supplierMail); + } else { + $mail = self::getCustomerMail($idOrder); + } + } + + if($acceptedDate && $proposedDate) { + $acceptedDate = new DateTime($acceptedDate); + $acceptedDate = $acceptedDate->format('jS M, Y'); + $proposedDate = new DateTime($proposedDate); + $proposedDate = $proposedDate->format('jS M, Y'); + } + + $params = [ + 'wiaas' => $userType === USER_TYPES['CUSTOMER'] ? WIAAS_URL : WIAAS_URL.'/api-wiaas', + 'ordersUrl' => $orderUrl, + 'orderNumber' => $orderNumber, + 'acceptedDate' => $acceptedDate, + 'proposedDate' => $proposedDate, + 'actionDoneBy' => $actionDoneBy + ]; + + $response = Mail::sendMail($mail, $mailTitle, $templateUrl, $params); + if($response){ + $message = [ + 'code' => 'success', + 'message' => 'INSTALLATION_MAIL_SENT' + ]; + } else { + $message = [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + return $message; + } + + /** + * get all installation data for order + * @param Int $idOrder id of the order + * @param Array $stepIds actions id of the steps between which the step should be enabled + * @param String $fileType the type of the documents needed - Order Questionaire or Installation protocol + * @return Array array with all data needed for the installation scheduling + */ + public function getAllDataForInstallation($idOrder, $stepIds, $fileType) { + $data = []; + $idPackage = 0; + if(!$idOrder) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ID_ORDER_NOT_SET' + ]; + + return $data; + } + + $data['installCompanies'] = $this->getInstallCompaniesForOrder($idOrder); + $data['earliestInstallationDate'] = $this->getInstallationScheduleEID($idOrder); + $data['isNextStepWanted'] = $this->checkIfIsNextStepWanted($idOrder, $idPackage, $stepIds); + $data['installationDates'] = $this->getInstallationDates($idOrder, $idPackage); + $data['areAllShippingDatesConfirmed'] = $this->checkIfAllShippingDatesConfirmed($idOrder); + + return $data; + } + + /** + * returns the id of the installation info + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @return Array or Int error messages or id of the package + */ + public function getInstallationScheduleEID($idOrder, $idPackage = 0) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $eid = ''; + $extraWhere = ''; + + if(!$idOrder) { + $eid['messages'][] = [ + 'code' => 'error', + 'message' => 'ORDER_NOT_SET' + ]; + + return $eid; + } + + $sql = " + SELECT + MAX( + IFNULL(earliestInstallationDate, '-') + ) AS earliestInstallationDate + FROM + ".TABLES['rel_order_packages']." + WHERE idOrder = $idOrder"; + + $query = $database->query($sql); + $eid[$idOrder] = $database->fetchArray($query)['earliestInstallationDate']; + + return $eid; + } + + /** + * checks if the next step is the one needed for enabling the component + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @param Array $stepIds actions id of the steps between which the step should be enabled + * @return bool true if the next step should enable the component + */ + public function checkIfIsNextStepWanted($idOrder, $idPackage, $stepIds = []) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $stepIds = (array) $stepIds; + if(count($stepIds) === 0) { + $stepIds = [ + 'firstStepEnabled' => 5, + 'lastStepEnabled' => 6 + ]; + } + $firstStepEnabled = $database->escapeValue($stepIds['firstStepEnabled']); + $lastStepEnabled = $database->escapeValue($stepIds['lastStepEnabled']); + $extraWhere = ''; + $data = []; + $wantedPackageIds = []; + + if($idPackage) { + $extraWhere = "AND rops.idPackage = $idPackage"; + } + + $sql = " + SELECT + rops.idProcessStep + FROM + ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id = rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps + ON ps.id = rps.idStep + AND ps.idActionCode=$firstStepEnabled + WHERE rops.idOrder = $idOrder + $extraWhere + AND rops.status = 'inactive' + UNION ALL + SELECT + rops.idProcessStep + FROM + ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id = rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps + ON ps.id = rps.idStep + AND ps.idActionCode=$lastStepEnabled + WHERE rops.idOrder = $idOrder + $extraWhere + AND ( + rops.status = 'in-progress' + OR rops.status = 'done' + )"; + $query = $database->query($sql); + $data[$idOrder] = $database->numRows($query) > 0; + + return $data; + } + + /** + * check if all the delivery dates are confirmed + * @param Int $idOrder the id of the order + * @return Array array with info if the shipping dates are confirmed or not + */ + public function checkIfAllShippingDatesConfirmed($idOrder) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $data = []; + + if(!$idOrder) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ID_ORDER_NOT_SET' + ]; + + return $data; + } + + $sql = "SELECT + SUM(IF(rope.confirmedDate IS NULL, 0, 1)) AS nbOfDatesConfirmed, + COUNT(*) AS totalNbOfDates + FROM + ".TABLES['rel_order_supplier_estimations']." rope + WHERE rope.idOrder = $idOrder"; + $result = $database->query($sql); + + while($row = $database->fetchArray($result)) { + $data[$idOrder] = $row['nbOfDatesConfirmed'] === $row['totalNbOfDates']; + } + + return $data; + } + + /** + * return the mail of the supplier of the installation company + * @param Int $idCompanySelection the id of the company selection (install company-order-package) + * @return Array the email of the supplier for th installation company per order package + */ + public function getSupplierMail($idCompanySelection) { + global $database; + + $sql = " + SELECT + u.mail + FROM + ".TABLES['users']." u + INNER JOIN ".TABLES['suppliers']." s + ON s.idUser = u.id + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idSupplier = s.id + INNER JOIN ".TABLES['installation_company_selections']." ics + ON ics.idProduct = scp.idProduct + AND ics.id = $idCompanySelection"; + $mail = $database->fetchResultArray($sql); + + return count($mail) ? $mail[0]['mail'] : ''; + } + + /** + * returns the customer mail for the order selected + * @param Int $idOrder id of the order + * @return Array + */ + public function getCustomerMail($idOrder) { + global $database; + + $sql = " + SELECT + u.mail + FROM + ".TABLES['users']." u + INNER JOIN ".TABLES['customers']." c + ON c.idUser = u.id + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.idCustomer = c.id + INNER JOIN ".TABLES['orders']." o + ON o.idCustomerInstance = rclc.id + AND o.id = $idOrder"; + $mail = $database->fetchResultArray($sql); + + return count($mail) ? $mail[0]['mail'] : ''; + } + + /** + * send mail if scheduling is enabled for customer + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @return Array + */ + // the function is prepared for the future when we will have the other user types with the new interface as well + public function checkIfSchedulingEnabledForCustomer($idOrder, $idPackage) { + global $database; + $idOrderPackagePair = $idOrder . '-' . $idPackage; + $orderExtraActions = new orderExtraActions(); + $data = []; + + $installCompanySelected = $orderExtraActions->getInstallCompaniesForOrder($idOrder)['selected']; + $earliestInstallationDate = $orderExtraActions->getInstallationScheduleEID($idOrder); + $isNextStepWanted = $orderExtraActions->checkIfIsNextStepWanted($idOrder, $idPackage); + + if($earliestInstallationDate && $earliestInstallationDate[$idOrder] !== '-' && + $isNextStepWanted && array_key_exists($idOrderPackagePair, $isNextStepWanted) && $isNextStepWanted[$idOrderPackagePair] === false && + $installCompanySelected && array_key_exists($idOrderPackagePair, $installCompanySelected) && count($installCompanySelected[$idOrderPackagePair]) > 0) { + + $customerInfo = self::getDataForMailToCustomer($idOrder); + + $sqlPackageInfo = " + SELECT + p.name AS packageName, + s.name AS supplierName + FROM ".TABLES['packages']." p + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage = p.id + AND rop.idOrder = $idOrder + AND rop.idPackage = $idPackage + INNER JOIN ".TABLES['installation_company_selections']." ics + ON ics.idOrder = rop.idOrder + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct = ics.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id = scp.idSupplier"; + $query = $database->query($sqlPackageInfo); + $packageInfo = $database->fetchArray($query); + $params = [ + 'wiaas' => WIAAS_URL, + 'ordersUrl' => WIAAS_URL.'/orders/'.$idOrder, + 'orderNumber' => $customerInfo['orderNumber'], + 'packageName' => $packageInfo['packageName'], + 'supplierName' => $packageInfo['supplierName'] + ]; + $response = Mail::sendMail($customerInfo['mail'], 'Schedule installation function is now enabled', 'customerScheduleInstallationEnabled.php', $params); + + if($response){ + $data = [ + 'code' => 'success', + 'message' => 'SCHEDULING_ENABLED_MAIL' + ]; + } else { + $data = [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + } + + return $data; + } + + /** + * change the installation company for the order and package selected + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @param Int $idInstallationCompany id of the installation company product + * @return Array update messages + */ + public function changeInstallationCompany($idOrder, $idPackage, $idInstallationCompany) { + global $database; + + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idInstallationCompany = $database->escapeValue($idInstallationCompany); + $rowsAffected = 0; + + $sqlSelectProduct = " + SELECT + ics.id AS idCompany + FROM + ".TABLES['installation_company_selections']." ics + WHERE ics.idOrder = $idOrder AND ics.idPackage = $idPackage"; + + $data = $database->fetchResultArray($sqlSelectProduct); + if(count($data)) { + $idScheduleInfo = $data[0]['idCompany']; + $sqlUpdateCompanyStatus = " + UPDATE + ".TABLES['installation_company_selections']." + SET + isActive = 0 + WHERE idOrder = $idOrder AND idPackage = $idPackage"; + $query = $database->query($sqlUpdateCompanyStatus); + } + + $sqlInsertUpdateCompany = " + INSERT INTO + ".TABLES['installation_company_selections']." ( + idProduct, + idOrder, + idPackage + ) + VALUES + ($idInstallationCompany, $idOrder, $idPackage) + ON DUPLICATE KEY UPDATE + isActive = 1"; + $result = $database->query($sqlInsertUpdateCompany); + $rowsAffected += $database->affectedRows(); + + if($rowsAffected) { + return [ + 'code' => 'success', + 'message' => 'INSTALLATION_SAVED' + ]; + } + + return [ + 'code' => 'error', + 'message' => 'INSTALLATION_NOT_SAVED' + ]; + } + + /** + * send mail if scheduling is enabled for customer + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @return Array + */ + public function sendMailIfSchedulingEnabledForCustomer($idOrder, $idPackage) { + global $database; + $data = []; + $idOrderPackagePair = $idOrder . '-' . $idPackage; + $stepsName = json_encode([ + 'firstStepEnabled' => 5, + 'lastStepEnabled' => 6 + ]); + $orderExtraActions = new orderExtraActions(); + $installationScheduling = new InstallationScheduling(); + + $isSchedulingAlreadyEnabled = self::checkIfSchedulingAlreadyEnabledForCustomer($idOrder, $idPackage); + if(!intval($isSchedulingAlreadyEnabled)) { + $installCompanySelected = $installationScheduling->getInstallCompaniesForPackage($idOrder, $idPackage)['selected']; + $earliestInstallationDate = self::getInstallationScheduleEID($idOrder); + $isNextStepWanted = $orderExtraActions->checkIfIsNextStepWanted($idOrder, $idPackage, $stepsName); + + if($installCompanySelected && count($installCompanySelected) > 0 && + $earliestInstallationDate[$idOrder] && + $isNextStepWanted === false) { + + $message = self::setSchedulingFlagForCustomer($idOrder, $idPackage, 1); + if($message['code'] === 'warning') { + return; + } + + $customerInfo = self::getDataForMailToCustomer($idOrder); + + $sqlPackageInfo = " + SELECT + p.name AS packageName, + s.name AS supplierName + FROM ".TABLES['packages']." p + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage = p.id + AND rop.idOrder = $idOrder + AND rop.idPackage = $idPackage + INNER JOIN ".TABLES['installation_company_selections']." ics + ON ics.idOrder = rop.idOrder + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct = ics.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id = scp.idSupplier"; + $query = $database->query($sqlPackageInfo); + $packageInfo = $database->fetchArray($query); + $params = [ + 'wiaas' => WIAAS_URL, + 'ordersUrl' => WIAAS_URL.'/orders/'.$idOrder, + 'orderNumber' => $customerInfo['orderNumber'], + 'packageName' => $packageInfo['packageName'], + 'supplierName' => $packageInfo['supplierName'] + ]; + $response = Mail::sendMail($customerInfo['mail'], 'Schedule installation function is now enabled', 'customerScheduleInstallationEnabled.php', $params); + + if($response){ + $data = [ + 'code' => 'success', + 'message' => 'SCHEDULING_ENABLED_MAIL' + ]; + } else { + $data = [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + } + } + + return $data; + } + + /** + * check if the scheduling is already available for customer + * @param INT $idOrder id of the order + * @param INT $idPackage id of the package + * @return Bool 1 if the scheduling is already enabled + */ + public function checkIfSchedulingAlreadyEnabledForCustomer($idOrder, $idPackage) { + global $database; + $extraWhere = ''; + if($idPackage) { + $extraWhere = " AND rop.idPackage = $idPackage"; + } + + $sql = "SELECT + rop.isSchedulingEnabledForCustomer + FROM + ".TABLES['rel_order_packages']." rop + WHERE rop.idOrder = $idOrder + $extraWhere"; + $result = $database->fetchResultArray($sql); + + return $result ? $result[0]['isSchedulingEnabledForCustomer'] : 0; + } + + /** + * sets the scheduling available or not available for customer + * @param INT $idOrder id of the order + * @param INT $idPackage id of the package + * @return Bool 1 if the scheduling is already enabled + */ + public function setSchedulingFlagForCustomer($idOrder, $idPackage, $flag) { + global $database; + $flag = intval($database->escapeValue($flag)); + $extraWhere = ''; + + if($flag !== 0 && $flag !== 1) { + return [ + 'code' => 'error', + 'message' => 'FLAG_NOT_AVAILABLE' + ]; + } + + if($idPackage) { + $extraWhere = " AND idPackage = $idPackage"; + } + + $sql = "UPDATE + ".TABLES['rel_order_packages']." + SET + isSchedulingEnabledForCustomer = $flag + WHERE idOrder = $idOrder + $extraWhere"; + + $result = $database->query($sql); + $affectedRows = $database->affectedRows(); + + if($affectedRows > 0) { + return [ + 'code' => 'success', + 'key' => $flag ? 'enabled' : 'disabled', + 'message' => 'SCHEDULE_FLAG_UPDATED' + ]; + } + + return [ + 'code' => 'warning', + 'message' => 'SCHEDULE_FLAG_NO_UPDATE' + ]; + } + + } diff --git a/api-wiaas/server/components/v2/orders/OrderDocuments.php b/api-wiaas/server/components/v2/orders/OrderDocuments.php new file mode 100644 index 0000000..cde9a7d --- /dev/null +++ b/api-wiaas/server/components/v2/orders/OrderDocuments.php @@ -0,0 +1,100 @@ +getUserType() !== USER_TYPES['BROKER']){ + $whreSql = " AND visibleToCustomer=1"; + } + + $sql = "SELECT + d.id AS idDocument, + d.documentName, + d.documentPath, + d.extension, + dt.type AS documentType, + rpp.idPackage, + rpd.idProduct + FROM ".TABLES['rel_product_documents']." rpd + INNER JOIN ".TABLES['documents']." d + ON d.id=rpd.idDocument + INNER JOIN ".TABLES['document_types']." dt + ON dt.id=d.idDocumentType + INNER JOIN ".TABLES['rel_package_products']." rpp + ON rpp.idProduct=rpd.idProduct + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage=rpp.idPackage AND rop.packageInstance=rpp.packageInstance + WHERE rop.idOrder=$idOrder $whreSql + "; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][] = $row; + } + + return $data; + } + + /** + * get all docuemnts linked to an order + * @param INT $idOrder id for the order + * @return Array list of documetns for an order grouped by package id + */ + public function getOrderDocuments($idOrder){ + global $database; + $data = []; + + $sql = "SELECT + d.id AS idDocument, + d.documentName, + d.documentPath, + d.extension, + dt.type AS documentType, + dt.folderName AS documentTypeName, + IFNULL(rod.idPackage, 0) as idPackage + FROM ".TABLES['rel_order_documents']." rod + INNER JOIN ".TABLES['documents']." d + ON d.id=rod.idDocument + INNER JOIN ".TABLES['document_types']." dt + ON dt.id=d.idDocumentType + WHERE rod.idOrder=$idOrder + UNION all + SELECT + d.id AS idDocument, + d.documentName, + d.documentPath, + d.extension, + dt.type AS documentType, + dt.folderName AS documentTypeName, + rpd.idPackage + FROM ".TABLES['rel_package_documents']." rpd + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage=rpd.idPackage + INNER JOIN ".TABLES['documents']." d + ON d.id=rpd.idDocument + INNER JOIN ".TABLES['document_types']." dt + ON dt.id=d.idDocumentType + WHERE rop.idOrder=$idOrder"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][] = $row; + } + + + + $productDocuments = $this->getProductDocuments($idOrder); + if(!empty($productDocuments)){ + foreach ($productDocuments as $idPackage => &$documents) { + if(isset($data[$idPackage])){ + $data[$idPackage] = array_merge($data[$idPackage], $documents); + }else{ + $data[$idPackage] = $documents; + } + } + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/orders/OrderExtraActions.php b/api-wiaas/server/components/v2/orders/OrderExtraActions.php new file mode 100644 index 0000000..54579d9 --- /dev/null +++ b/api-wiaas/server/components/v2/orders/OrderExtraActions.php @@ -0,0 +1,1019 @@ + 2, // 2 => 'orderQuestionaire' + 'ID_CONFIGURATION_DOC_TYPE' => 3, // 3 => 'configuration' + 'ID_ACCEPTANCE_DOC_TYPE' => 5, // 5 => 'customerAcceptance' + 'ID_INSTALLATION_PROTOTCOL_DOC_TYPE' => 10 // 10 => 'installationProtocol' + ]; + const ID_INSTALLATION_CATEGORY = 2; + + /** + * add null values for products estimations in an order + * @param INT $idOrder id of the order + * @param INT $idPackage id of the order + */ + public function addStartEstimatisonForProducts($idOrder, $idPackage){ + global $database; + $installation = 2; + + $sql = "INSERT INTO ".TABLES['rel_order_products_estimation']." + (idOrder, idPackage, idProduct) + SELECT rop.idOrder, rop.idPackage, rpp.idProduct + FROM ".TABLES['rel_package_products']." rpp + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage=rpp.idPackage AND rop.packageInstance=rpp.packageInstance + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rpp.idProduct + WHERE rop.idOrder=$idOrder AND rop.idPackage=$idPackage AND scp.idProductCategory!=$installation"; + $query = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * get suppliers products + * @param INT $idOrder id for the order + * @param INT $idPackage id for the order + * @param String $documentType the type of the document + * @return Array Array of products estimations + */ + public function getSuppliersByPackageOrder($idOrder, $idPackage, $documentType){ + global $database, $user; + + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $documentType = $database->escapeValue($documentType); + $data = []; + $whereSql = ""; + + $documents = $this->getSupplierDocuments($idOrder, $idPackage, $documentType); + + if($user->getUserType() === USER_TYPES['SUPPLIER']){ + $whereSql = " AND s.idUser=".$user->getUserId(); + } + + $sql = "SELECT s.id AS idSupplier, + s.name AS supplierName + FROM ".TABLES['rel_order_products_estimation']." rope + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rope.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=scp.idSupplier + WHERE idOrder=$idOrder AND idPackage=$idPackage AND scp.idProductCategory!=".self::ID_INSTALLATION_CATEGORY." $whereSql + ORDER BY s.id"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['supplierName']]['idSupplier'] = $row['idSupplier']; + $data[$row['supplierName']]['documents'] = isset($documents[$row['supplierName']]) ? $documents[$row['supplierName']] : []; + } + + return $data; + } + + /** + * get estimations for products + * @param INT $idOrder id for the order + * @param INT $idPackage id for the order + * @return Array Array of products estimations + */ + public function getProductsEstimations($idOrder, $idPackage){ + global $database, $user; + $idInstallationCategory = 2; + + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $data = []; + $whereSql = ""; + + + $documents = $this->getSupplierDocuments($idOrder, $idPackage); + $trackingInfo = $this->getTrackingInfo($idOrder, $idPackage); + + if($user->getUserType() === USER_TYPES['SUPPLIER']){ + $whereSql = " AND s.idUser=".$user->getUserId(); + } + + $sql = "SELECT rope.idProduct, + rope.estimatedDate, + rope.confirmedDate, + s.id AS idSupplier, + s.name AS supplierName, + scp.productName + FROM ".TABLES['rel_order_products_estimation']." rope + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rope.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=scp.idSupplier + WHERE idOrder=$idOrder AND idPackage=$idPackage AND scp.idProductCategory!=$idInstallationCategory $whereSql + ORDER BY s.id, + scp.productName"; + + $query = $database->query($sql); + if($database->numRows($query) === 0){ + if($user->getUserType() === USER_TYPES['SUPPLIER']) { + return $data; + } + $addedStartValues = $this->addStartEstimatisonForProducts($idOrder, $idPackage); + if($addedStartValues > 0){ + return $this->getProductsEstimations($idOrder, $idPackage); + }else{ + return $data; + } + } + while($row = $database->fetchArray($query)){ + $data[$row['supplierName']]['idSupplier'] = $row['idSupplier']; + $data[$row['supplierName']]['documents'] = isset($documents[$row['supplierName']]) ? $documents[$row['supplierName']] : []; + $data[$row['supplierName']]['estimations'][] = $row; + $data[$row['supplierName']]['trackings'] = isset($trackingInfo[$row['idSupplier']]) ? $trackingInfo[$row['idSupplier']] : []; + } + + return $data; + } + + private function isProductOwner($idProduct){ + global $user, $database; + + if($user->getUserType() === USER_TYPES['BROKER']){ + return true; + }else if($user->getUserType() === USER_TYPES['SUPPLIER']){ + $sql = "SELECT s.id + FROM ".TABLES['suppliers']." s + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idSupplier=s.id + WHERE s.idUser=".$user->getUserId(); + $query = $database->query($sql); + + return $database->numRows($query) > 0; + } + + return false; + } + + private function getTrackingInfo($idOrder, $idPackage) { + global $database; + $data = []; + + $sql = " + SELECT + roso.id AS idTracking, + roso.idSupplier, + roso.trackingNumber, + roso.trackingUrl + FROM + ".TABLES['rel_order_supplier_options']." roso + WHERE roso.idOrder = $idOrder + AND roso.idPackage = $idPackage"; + $query = $database->query($sql); + + while($row = $database->fetchArray($query)) { + $data[$row['idSupplier']][] = $row; + } + + return $data; + } + + /** + * update dates for products in an order + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param INT $idProduct id for the product + * @param String $estimatedDate estimated date + * @param String $confirmedDate confirmed date + * @return Array update message + */ + public function updateProductEstimation($idOrder, $idPackage, $idProduct, $estimatedDate, $confirmedDate){ + global $database; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idProduct = $database->escapeValue($idProduct); + $estimatedDate = $database->escapeValue($estimatedDate); + $confirmedDate = $database->escapeValue($confirmedDate); + $data = []; + + if(!$this->isProductOwner($idProduct)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NOT_OWNER_OF_PROD' + ]; + + return $data; + } + + if(empty($estimatedDate) && empty($confirmedDate)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'EMPTY_DATES' + ]; + + return $data; + } + + $checkEstimatedDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $estimatedDate); + $checkConfirmedDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $confirmedDate); + if(($checkEstimatedDate && !empty($estimatedDate)) || ($checkConfirmedDate && !empty($confirmedDate))){ + $data['messages'][] = $checkEstimatedDate ? $checkEstimatedDate : []; + $data['messages'][] = $checkConfirmedDate ? $checkConfirmedDate : []; + + return $data; + } + + if(empty($estimatedDate)){ + $estimatedDate = $confirmedDate; + } + + $estimatedDate = !empty($estimatedDate) ? "'$estimatedDate'" : "null"; + $confirmedDate = !empty($confirmedDate) ? "'$confirmedDate'" : "null"; + + $sql = "UPDATE ".TABLES['rel_order_products_estimation']." + SET estimatedDate=$estimatedDate, + confirmedDate=$confirmedDate + WHERE idOrder=$idOrder AND idPackage=$idPackage AND idProduct=$idProduct"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PROD_ESTIMATION_UPDATED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + } + + return $data; + } + + /** + * add tracking number and url for order/package/supplier + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param INT $idSupplier id for the supplier + * @param String $trackingNumber traking id + * @param String $trackingUrl traking url + * @return Array update message + */ + public function addTracking($idOrder, $idPackage, $idSupplier, $trackingNumber, $trackingUrl) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idSupplier = $database->escapeValue($idSupplier); + $trackingNumber = $database->escapeValue($trackingNumber); + $trackingUrl = $database->escapeValue($trackingUrl); + $data = []; + + if (filter_var($trackingUrl, FILTER_VALIDATE_URL) === FALSE) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_URL' + ]; + + return $data; + } + + $sql = "INSERT INTO ".TABLES['rel_order_supplier_options']." ( + idOrder, + idPackage, + idSupplier, + trackingNumber, + trackingUrl + ) + VALUES + ($idOrder, $idPackage, $idSupplier, '$trackingNumber', '$trackingUrl')"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'TRAKING_ID_ADDED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + } + + return $data; + } + + /** + * update dates for products in an order + * @param INT $idTracking id for the tracking info + * @param String $trackingNumber traking id + * @param String $trackingUrl traking url + * @return Array update message + */ + public function updateTracking($idTracking, $trackingNumber, $trackingUrl){ + global $database; + $idTracking = $database->escapeValue($idTracking); + $trackingNumber = $database->escapeValue($trackingNumber); + $trackingUrl = $database->escapeValue($trackingUrl); + $data = []; + + if (filter_var($trackingUrl, FILTER_VALIDATE_URL) === FALSE) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_URL' + ]; + + return $data; + } + + $sql = "UPDATE ".TABLES['rel_order_supplier_options']." + SET trackingNumber='$trackingNumber', + trackingUrl='$trackingUrl' + WHERE id=$idTracking"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'TRAKING_ID_UPDATED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'NO_CHANGES' + ]; + } + + return $data; + } + + public function removeTracking($idTracking) { + global $database; + $idTracking = $database->escapeValue($idTracking); + $data = []; + + $sql = "DELETE FROM ".TABLES['rel_order_supplier_options']." WHERE id=$idTracking"; + $result = $database->query($sql); + + if($database->affectedRows()){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'TRACKING_REMOVED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'TRACKING_REMOVED_ERROR' + ]; + } + + return $data; + } + + /** + * upload a new file for configuration + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param INT $idSupplier id for supplier + * @param STRING $fileType the type of the file (configuration or installation) + * @param FILE $file file to be uploaded + * @return Array upload message + */ + public function uploadConfigurationDocument($idOrder, $idPackage, $idSupplier, $fileType, $file){ + global $database, $user; + + $idSupplier = $database->escapeValue($idSupplier); + $fileType = $database->escapeValue($fileType); + $idDocumentType = self::DOCUMENT_TYPES['ID_CONFIGURATION_DOC_TYPE']; + $nameSuffix = 'config'; + $maxCount = 1; + + if($fileType === 'installationProtocol') { + $idDocumentType = self::DOCUMENT_TYPES['ID_INSTALLATION_PROTOTCOL_DOC_TYPE']; + $nameSuffix = 'install_protocol'; + } + + $sql = "SELECT s.idUser + FROM ".TABLES['suppliers']." s + WHERE s.id=$idSupplier"; + $query = $database->query($sql); + $supplier = $database->fetchArray($query); + + $sql = "SELECT name + FROM ".TABLES['packages']." + WHERE id=$idPackage"; + $query = $database->query($sql); + $package = $database->fetchArray($query); + $documentName = isset($package['name']) ? str_replace(' ', '_', $package['name']) : ''; + $documentName .= '_'.$idSupplier.'_'.$nameSuffix; + + $sql = " + SELECT + d.documentName + FROM + ".TABLES['documents']." d + INNER JOIN ".TABLES['rel_order_documents']." rod + ON d.id = rod.idDocument + WHERE rod.idOrder = $idOrder + AND rod.idPackage = $idPackage + AND d.idDocumentType = $idDocumentType + ORDER BY d.id DESC + LIMIT 1"; + $lastDocName = $database->fetchResultArray($sql); + if($lastDocName && $lastDocName[0]['documentName']) { + $count = explode('_', $lastDocName[0]['documentName']); + $maxCount = intval(end($count)) + 1; + } + $documentName .= '_'.$maxCount; + + $fileManager = new FileManager(); + $data = $fileManager->uploadFile($file, $idDocumentType, $documentName, $supplier['idUser']); + if(isset($data['messages'])){ + return $data; + } + + $idDocument = $data['idDocument']; + + $sql = "INSERT INTO ".TABLES['rel_order_documents']." + (idOrder, idPackage, idDocument, validation) + VALUES($idOrder, $idPackage, $idDocument, 'not-required')"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'FILE_UPLOADED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NOT_UPLOADED' + ]; + } + + return $data; + } + + /** + * get documents grouped by suppliers + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param String $documentType the type of the document + * @return Array list of documents + */ + private function getSupplierDocuments($idOrder, $idPackage, $documentType = ''){ + global $database; + $data = []; + $extraWhere = ''; + + if($documentType) { + $extraWhere = " + AND d.idDocumentType = + (SELECT + dt.id + FROM + document_types dt + WHERE dt.folderName = '$documentType')"; + } + + $sql = "SELECT d.id as idDocument, + d.documentName, + d.extension, + s.name AS supplierName + FROM ".TABLES['documents']." d + INNER JOIN ".TABLES['rel_order_documents']." rod + ON rod.idDocument=d.id + INNER JOIN ".TABLES['suppliers']." s + ON s.idUser=d.uploadedBy + WHERE rod.idOrder=$idOrder AND rod.idPackage=$idPackage $extraWhere"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['supplierName']][] = $row; + } + + return $data; + } + + /** + * save the installation company + * @param [type] $idOrder [description] + * @param [type] $idPackage [description] + * @param [type] $idInstallation [description] + * @return [type] [description] + */ + public function saveInstallationCompany($idOrder, $idPackage, $idInstallation) { + global $database; + + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idInstallation = $database->escapeValue($idInstallation); + $installationScheduling = new InstallationScheduling(); + + if(!$idOrder || !$idPackage || !$idInstallation) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'DATA_NOT_SET' + ]; + + return $data; + } + + $sqlSelect = " + SELECT idProduct + FROM ".TABLES['order_selections']." + WHERE idOrder = $idOrder + AND idPackage = $idPackage + "; + $result = $database->query($sqlSelect); + + if($database->numRows($result) > 0) { + $sql = " + UPDATE + ".TABLES['order_selections']." + SET + idProduct = $idInstallation + WHERE idOrder = $idOrder AND idPackage = $idPackage"; + } else { + $sql = " + INSERT INTO ".TABLES['order_selections']." + (idOrder, idPackage, idProduct, selectionFor) + VALUES + ($idOrder, $idPackage, $idInstallation, 'installation') + "; + } + $result = $database->query($sql); + + $data['messages'][] = $installationScheduling->changeInstallationCompany($idOrder, $idPackage, $idInstallation); + + return $data; + } + + /** + * get scheduled dates for a step + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param INT $idProcessStep id for the process step + * @return Array array of schedueld dates + */ + public function getScheduledDates($idOrder, $idPackage, $idProcessStep){ + global $database; + $data = []; + $confirmations = $this->getUserConfirmationsForSchedules($idOrder, $idPackage, $idProcessStep); + + $sql = "SELECT rosd.id AS idSchedule, + rosd.scheduledDate, + rosd.isDateConfirmed, + rosd.idProcessStep, + rosd.idPackage + FROM ".TABLES['rel_order_scheduled_dates']." rosd + WHERE rosd.idOrder=$idOrder AND rosd.idPackage=$idPackage AND rosd.idProcessStep=$idProcessStep + ORDER BY rosd.scheduledDate ASC "; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['confirmations'] = isset($confirmations[$row['idSchedule']]) ? $confirmations[$row['idSchedule']] : []; + $data[] = $row; + } + + return $data; + } + + /** + * get user confirimations for the scheduled dates + * @param INT $idOrder id for the order + * @param INT $idPackage id for the pakage + * @param INT $idProcessStep id for the process step + * @return Array list of confirmations + */ + private function getUserConfirmationsForSchedules($idOrder, $idPackage, $idProcessStep){ + global $database; + $data = []; + + $sql = "SELECT rosc.idSchedule, + rosc.status, + u.username, + ut.type AS userType + FROM ".TABLES['rel_order_schedules_confirmations']." rosc + INNER JOIN ".TABLES['rel_order_scheduled_dates']." rosd + ON rosc.idSchedule=rosd.id + INNER JOIN ".TABLES['users']." u + ON u.id=rosc.idUser + INNER JOIN ".TABLES['rel_user_type']." rut + ON rut.idUser=u.id + INNER JOIN ".TABLES['user_types']." ut + ON ut.id=rut.idType + WHERE rosd.idOrder=$idOrder AND rosd.idPackage=$idPackage AND rosd.idProcessStep=$idProcessStep"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idSchedule']][] = $row; + } + + return $data; + } + + /** + * add users that need to confirm the schedule date for installation + * @param INT $idOrder id for the order + * @param INT $idSchedule id for the schedule + */ + private function addRequiredConfrimationUsers($idOrder, $idSchedule){ + global $database; + + $sql = "INSERT INTO ".TABLES['rel_order_schedules_confirmations']." + (idSchedule, idUser, status) + SELECT $idSchedule AS idSchedule, + c.idUser AS idUser, + 'pending' AS status + FROM ".TABLES['orders']." o + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=o.idCUstomerInstance + INNER JOIN ".TABLES['customers']." c + ON c.id=rclc.idCustomer + WHERE o.id=$idOrder"; + $query = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * Update the estimation date for the follow up meeting from an order + * @param Int $idOrder Id of the order to be modified + * @param Int $idProcessStep id of the porcess to be modified + * @param String $estimationDate new date to be added for a follow up meeting + * @param String $confirmedDate confirmed date with the customer to be added for a follow up meeting + * @return array response message for the update + */ + public function updateScheduledDates($idOrder, $idPackage, $idProcess, $idProcessStep, $idSchedule, $newDate) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idProcess = $database->escapeValue($idProcess); + $idProcessStep = $database->escapeValue($idProcessStep); + $idSchedule = $database->escapeValue($idSchedule); + $newDate = $database->escapeValue($newDate); + $orderDetailsParams = [ + 'idOrder' => $idOrder, + 'idPackage' => $idPackage, + 'idProcess' => $idProcess + ]; + $data = []; + + if($newDate !== '') { + $checkDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $newDate); + if($checkDate){ + $data['messages'][] = $checkDate; + return $data; + } + $newDate = "'$newDate'"; + } else { + $newDate = "null"; + } + + if(intval($idSchedule) === 0){ + $database->beginTransaction(); + $sql = " + INSERT INTO ".TABLES['rel_order_scheduled_dates']." ( + idOrder, + idPackage, + idProcessStep, + scheduledDate, + isDateConfirmed + ) + VALUES( + $idOrder, + $idPackage, + $idProcessStep, + $newDate, + 0 + )"; + $query = $database->query($sql); + $newIdSchedule = $database->getInsertId(); + $affectedRows = $database->affectedRows(); + $affectedRows += $this->addRequiredConfrimationUsers($idOrder, $newIdSchedule); + if($affectedRows > 0){ + $database->commit(); + }else{ + $database->rollback(); + $err_mes = [ + 'code' => 'error', + 'message' => 'SERVER_ERROR' + ]; + $data['messages'][] = $err_mes; + return $data; + } + }else{ + $sql = "UPDATE ".TABLES['rel_order_scheduled_dates']." + SET scheduledDate=$newDate + WHERE id=$idSchedule"; + $query = $database->query($sql); + $affectedRows = $database->affectedRows(); + } + + if(!$query){ + $err_mes = [ + 'code' => 'error', + 'message' => 'SERVER_ERROR' + ]; + $data['messages'][] = $err_mes; + } + + if($affectedRows > 0){ + $sqlProcessStep = " + SELECT ps.shortDesc + FROM ".TABLES['process_step']." ps + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.idStep = ps.id + AND rps.id = $idProcessStep + LIMIT 1 + "; + $result = $database->fetchResultArray($sqlProcessStep); + $procStep = $result ? $result[0]['shortDesc'] : ''; + + /*if($estimationDate) { + $orderDetailsParams['estimatedMeetingDate'] = $estimationDate; + } + if($confirmedDate) { + $orderDetailsParams['confirmedMeetingDate'] = $confirmedDate; + } + $data['messages'][] = $this->sendConfirmationMail('scheduleMeeting', $orderDetailsParams);*/ + + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'ORDER_STEP_MEETING_DATE_UPDATED' + ]; + } + + return $data; + } + + /** + * update the status for an existing schedule date + * @param INT $idSchedule id for schedule date + * @param string $status new status for the schedule date + * @return Array update message + */ + public function updateScheduleDateStatus($idSchedule, $status, $idOrder, $idPackage, $actionCode){ + global $database, $user; + $idSchedule = $database->escapeValue($idSchedule); + $data = []; + + $sql = "UPDATE ".TABLES['rel_order_schedules_confirmations']." + SET status='$status' + WHERE idSchedule=$idSchedule AND idUser=".$user->getUserId(); + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + if($status === 'accepted' && $actionCode === 'choose-installation'){ + $sql = "UPDATE ".TABLES['orders']." + SET acceptanceDueDate=DATE_ADD( + (SELECT scheduledDate + FROM ".TABLES['rel_order_scheduled_dates']." + WHERE id=$idSchedule), + INTERVAL 15 DAY) + WHERE id=$idOrder"; + $query = $database->query($sql); + } + $updatedMainStatus = $this->updateScheduleGlobalStatus($idSchedule, $status); + + $message = [ + 'code' => 'success', + 'message' => 'SCHEDULE_STATUS_UPDATED' + ]; + $data['messages'][] = $message; + + return $data; + }else{ + $message = [ + 'code' => 'error', + 'message' => 'SCHEDULE_STATUS_NOT_UPDATED' + ]; + $data['messages'][] = $message; + + return $data; + } + } + + /** + * update the status for the parent schedule date base on all users confirmation + * @param INT $idSchedule id for the scheduled date + * @param String $status new status addded to child + * @return INT number of affected rows + */ + private function updateScheduleGlobalStatus($idSchedule, $status){ + global $database; + $confirmation = $status === 'accepted' ? 1 : -1; + + $sql = "UPDATE ".TABLES['rel_order_scheduled_dates']." + SET isDateConfirmed=$confirmation + WHERE id=$idSchedule"; + $query = $database->query($sql); + + return $database->affectedRows(); + } + + /** + * get customer questionaires for a specific order + * @param INT $idOrder id for the order + * @param String $documentType the type of the documents needed - Order Questionaire or Installation protocol + * @return Array array of documents + */ + public function getOrderDocumentsPerType($idOrder, $documentType){ + global $database, $user; + + $idOrder = $database->escapeValue($idOrder); + $documentType = $database->escapeValue($documentType); + $data = []; + + if($documentType === 'orderQuestionaire') { + $idDocumentType = self::DOCUMENT_TYPES['ID_QUESTIONAIRE_DOC_TYPE']; + } else if($documentType === 'installationProtocol') { + $idDocumentType = self::DOCUMENT_TYPES['ID_INSTALLATION_PROTOTCOL_DOC_TYPE']; + } else { + return []; + } + + $sql = "SELECT d.id AS idDocument, + d.uploadedBy, + d.documentName, + d.extension, + dt.folderName AS documentTypeName, + rod.validation, + rod.idOrder, + rod.idPackage + FROM ".TABLES['documents']." d + INNER JOIN ".TABLES['rel_order_documents']." rod + ON rod.idDocument=d.id + INNER JOIN ".TABLES['document_types']." dt + ON d.idDocumentType=dt.id + WHERE d.idDocumentType=$idDocumentType + AND rod.idOrder=$idOrder"; + $query = $database->query($sql); + + while($row = $database->fetchArray($query)) { + $row['isUploadedByMe'] = $user->getUserId() === $row['uploadedBy']; + unset($row['uploadedBy']); + $data['documents'][$row['idOrder'].'-'.$row['idPackage']][] = $row; + } + + return $data; + } + + /** + * send mail to broker in case of new quesionnaire upload + * @param INT $idOrder id of the order + * @param INT $idDocument id of the document + * @return array mail send message + */ + private function sendQuesionnaireUploadMail($idOrder, $idDocument){ + global $database; + + $sqlCustomerInfo = " + SELECT o.orderNumber, + GROUP_CONCAT(DISTINCT b.mail) AS mailList + FROM ".TABLES['orders']." o + INNER JOIN ".TABLES['brokers']." b + ON CASE WHEN o.assignedTo is NOT NULL THEN b.id=o.assignedTo ELSE 1=1 END + WHERE o.id=$idOrder AND b.mail is NOT NULL + GROUP BY o.id"; + $query = $database->query($sqlCustomerInfo); + $brokerInfo = $database->fetchArray($query); + + $sqlDocInfo = " + SELECT d.id AS idDocument, + d.documentName, + d.extension + FROM ".TABLES['documents']." d + WHERE d.id=$idDocument + LIMIT 1"; + $query = $database->query($sqlDocInfo); + $documentInfo = $database->fetchArray($query); + $params = [ + 'url' => WIAAS_URL.'/api-wiaas/utils/api/downloadFile?idDocument='.$documentInfo['idDocument'].'&fileName='.$documentInfo['documentName'].'.'.$documentInfo['extension'], + 'ordersUrl' => WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$idOrder.'&orderNumber='.$brokerInfo['orderNumber'], + 'orderNumber' => $brokerInfo['orderNumber'], + 'idOrder' => $idOrder + ]; + + $mailList = trim($brokerInfo['mailList'], ','); + $mailList = explode(',', $mailList); + + $response = Mail::sendMail($mailList, 'Modified questionaire uploaded', 'reUploadQuestionnaireTemplate.php', $params); + + if($response){ + return [ + 'code' => 'success', + 'message' => 'RE_UPLOAD_MAIL' + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + /** + * upload again quesionnaire + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param INT $idDocument id for the document + * @param file $file file to be uploaded + * @return Array update message + */ + public function reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file){ + global $database, $user; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idDocument = $database->escapeValue($idDocument); + $documentName = 'customerQuestionaire_'.$idOrder.'_'.$idPackage.'_'.date('Y_m_d'); + + $fileManager = new FileManager(); + $data = $fileManager->updateDocument($idDocument, $file, $documentName); + + if(isset($data['messages'])){ + return $data; + } + $idDocument = $data['idDocument']; + + $sql = "UPDATE ".TABLES['rel_order_documents']." + SET validation='not-validated' + WHERE idOrder=$idOrder AND idPackage=$idPackage AND idDocument=$idDocument"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = $this->sendQuesionnaireUploadMail($idOrder, $idDocument); + + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'FILE_UPLOADED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NOT_UPLOADED' + ]; + } + + return $data; + } + + /** + * get comments by type e.g stepComment, invalidQuestionaireComment, ... + * @param Int $idOrder the id of the order + * @param Int $idPackage the id of the package + * @param Int $idProcessStep the id of the process step + * @param String $type the type of the comment: stepComment, invalidQuestionaireComment + * @return Array the comments wanted + */ + public function getCommentsByType($idOrder, $idPackage, $idProcessStep, $type) { + global $database; + $idOrder = $database->escapeValue($idOrder); + $idPackage = $database->escapeValue($idPackage); + $idProcessStep = $database->escapeValue($idProcessStep); + $type = $database->escapeValue($type); + $data = []; + + if(!$idOrder) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ORDER_ID_MISSING' + ]; + } + + if(!$idProcessStep) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PROCESS_STEP_MISSING' + ]; + } + + if(!$type) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'COMMENT_TYPE_MISSING' + ]; + } + + if(array_key_exists('messages', $data) && count($data['messages'])) { + return $data; + } + + $sql = " + SELECT rsc.comment, + DATE_FORMAT(rsc.addDate, '%D %b, %y') as addDate, + u.username AS user, + rsc.idOrder, + rsc.idPackage + FROM ".TABLES['rel_step_comments']." rsc + INNER JOIN ".TABLES['users']." u + ON u.id = rsc.idUser + WHERE rsc.idOrder=$idOrder + AND rsc.idProcessStep=$idProcessStep + AND rsc.type='$type' + "; + + $query = $database->query($sql); + + while($row = $database->fetchArray($query)) { + $data[$row['idOrder'].'-'.$row['idPackage']][] = $row; + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/orders/OrderProcessHelper.php b/api-wiaas/server/components/v2/orders/OrderProcessHelper.php new file mode 100644 index 0000000..4fd92f7 --- /dev/null +++ b/api-wiaas/server/components/v2/orders/OrderProcessHelper.php @@ -0,0 +1,122 @@ +getUserType(); + $extraWhereClause = ''; + $extraJoin = ''; + + $comments = $this->getStepComments($idOrder); + + if($userType === USER_TYPES['CUSTOMER']) { + $extraWhereClause = " AND ps.isVisibleForCustomer = 1"; + } + + if($userType === USER_TYPES['SUPPLIER']) { + $extraJoin = " INNER JOIN( + SELECT DISTINCT rop.idOrder, rop.idPackage + FROM ".TABLES['rel_order_packages']." rop + INNER JOIN ".TABLES['rel_package_products']." rpp + ON rpp.idPackage=rop.idPackage and rpp.packageInstance=rpp.packageInstance + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rpp.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=scp.idSupplier + WHERE s.idUSer=".$user->getUserId()." AND rop.idOrder=$idOrder + ) supplierPkg + ON rops.idOrder=supplierPkg.idOrder AND rops.idPackage=supplierPkg.idPackage"; + } + + $sql = "SELECT o.id AS idOrder, + ps.shortDesc, + ps.fullDesc, + ps.isVisibleForCustomer, + psa.actionCode, + psa.stepType, + rops.idProcessStep, + rops.status, + DATE_FORMAT(rops.actualDate, '%D %b, %y') as actualDate, + DATE_FORMAT(NOW(), '%D %b %y') as now, + rps.idProcess, + p.name AS processName + FROM ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['orders']." o + ON o.id=rops.idOrder + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id=rops.idProcessStep + INNER JOIN ".TABLES['processes']." p + ON p.id=rps.idProcess + INNER JOIN ".TABLES['process_step']." ps + ON ps.id=rps.idStep + INNER JOIN ".TABLES['process_step_actions']." psa + ON psa.id=ps.idActionCode + $extraJoin + WHERE o.id=".$idOrder." + $extraWhereClause + ORDER BY rps.idProcess, rops.idProcessStep DESC + "; + $query = $database->query($sql); + $data = []; + while($row = $database->fetchArray($query)){ + $idProcess = $row['idProcess']; + $data[$idProcess]['idProcess'] = $row['idProcess']; + $data[$idProcess]['processName'] = $row['processName']; + unset($row['processName']); + $row['comments'] = isset($comments[$row['idProcessStep']]) ? $comments[$row['idProcessStep']] : []; + $row['isNewCommentVisible'] = $row['isVisibleForCustomer']; + $data[$idProcess]['steps'][] = $row; + } + + return $data; + } + + /** + * get comments from an order + * @param INT $idOrder id of the order + * @return Array list of comments for an order grouped by idPackage and idProcessStep + */ + private function getStepComments($idOrder){ + global $database, $user; + + $extraFields = ''; + $whereSql = ''; + $userType = $user->getUserType(); + if($userType === USER_TYPES['BROKER']){ + $extraFields = ",rsc.isVisible "; + }else{ + $whereSql = " AND rsc.isVisible=1"; + } + + $sql = "SELECT rsc.id, rsc.idProcessStep, + rsc.idPackage, + rsc.comment, + DATE_FORMAT(rsc.addDate, '%D %b, %y') as addDate, + u.username as user + $extraFields + FROM ".TABLES['rel_step_comments']." rsc + INNER JOIN ".TABLES['users']." u + ON u.id=rsc.idUser + WHERE rsc.idOrder=$idOrder + AND rsc.type = 'stepComment' + $whereSql"; + $comments = []; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $idProcessStep = $row['idProcessStep']; + unset($row['idProcessStep']); + $idPackage = $row['idPackage']; + unset( $row['idPackage']); + $comments[$idPackage][$idProcessStep][] = $row; + } + + return $comments; + } + +} diff --git a/api-wiaas/server/components/v2/orders/OrdersController.php b/api-wiaas/server/components/v2/orders/OrdersController.php new file mode 100644 index 0000000..3554028 --- /dev/null +++ b/api-wiaas/server/components/v2/orders/OrdersController.php @@ -0,0 +1,159 @@ +model = new OrdersModel(); + } + + /** + * returns json response for ongoing orders + * @return list orders json + */ + public function getActiveOrders(){ + echo json_encode($this->model->getActiveOrders(), JSON_NUMERIC_CHECK); + } + + /** + * returns json response for completed orders + * @return list orders json + */ + public function getHistoryOrders(){ + echo json_encode($this->model->getHistoryOrders(), JSON_NUMERIC_CHECK); + } + + /** + * gets the info for an order + * @return [json] returns order info + */ + public function getOrderInfo() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + echo json_encode($this->model->getOrderInfo($idOrder), JSON_NUMERIC_CHECK); + } + + /** + * update comment for an order + * @return json update message + */ + public function addOrderComment() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $comment = isset($_REQUEST['comment']) ? $_REQUEST['comment'] : null; + echo json_encode($this->model->addOrderComment($idOrder, $comment)); + } + + /** + * get customer questionnaires documents + * @return json list of documents + */ + public function getOrderDocumentsPerType(){ + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $documentType = isset($_REQUEST['documentType']) ? $_REQUEST['documentType'] : ''; + echo json_encode($this->model->getOrderDocumentsPerType($idOrder, $documentType), JSON_NUMERIC_CHECK); + } + + /** + * upload againa questionnaire + * @return json upload message + */ + public function reUploadQuestionaire(){ + $file = isset($_FILES['file']) ? $_FILES['file'] : []; + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + $idDocument = isset($_REQUEST['idDocument']) ? $_REQUEST['idDocument'] : 0; + echo json_encode($this->model->reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file)); + } + + /** + * returns the comments and the user id based on the comment type + * @return json array with comments + */ + public function getCommentsByType() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + $idProcessStep = isset($_REQUEST['idProcessStep']) ? $_REQUEST['idProcessStep'] : 0; + $commentType = isset($_REQUEST['commentType']) ? $_REQUEST['commentType'] : ''; + echo json_encode($this->model->getCommentsByType($idOrder, $idPackage, $idProcessStep, $commentType), JSON_NUMERIC_CHECK); + } + + /** + * get information for customer acceptance + * @return json object with customer information + */ + public function getCustomerAcceptance(){ + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + echo json_encode($this->model->getCustomerAcceptance($idOrder), JSON_NUMERIC_CHECK); + } + + /** + * upload acceptance document + * @return json upload message + */ + public function uploadAcceptanceDocument(){ + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $file = isset($_FILES['file']) ? $_FILES['file'] : []; + echo json_encode($this->model->uploadAcceptanceDocument($idOrder, $file)); + } + + /** + * customer change acceptance status for a package + * @return Array message confirmation + */ + public function acceptDeclineInstallation(){ + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $actionType = isset($_REQUEST['actionType']) ? $_REQUEST['actionType'] : ''; + $declineReason = isset($_REQUEST['declineReason']) ? $_REQUEST['declineReason'] : ''; + echo json_encode($this->model->acceptDeclineInstallation($idOrder, $actionType, $declineReason)); + } + + /** + * returns the installation dates proposed/accepted/rejected by users + * @return json array with installation dates + */ + public function getInstallationDates() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + echo json_encode($this->model->getInstallationDates($idOrder, $idPackage), JSON_NUMERIC_CHECK); + } + + public function getAllDataForInstallation() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $stepIds = isset($_REQUEST['stepsNameForInstallation']) ? $_REQUEST['stepsNameForInstallation'] : '[]'; + $fileType = isset($_REQUEST['fileType']) ? $_REQUEST['fileType'] : ''; + + echo json_encode($this->model->getAllDataForInstallation($idOrder, $stepIds, $fileType)); + } + + /** + * returns a message if the new date for the installation was successfully added + * @return json array with confirmation messages + */ + public function updateInstallationDate() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + $installationDate = isset($_REQUEST['installationDate']) ? $_REQUEST['installationDate'] : ''; + $status = isset($_REQUEST['status']) ? $_REQUEST['status'] : ''; + echo json_encode($this->model->updateInstallationDate($idOrder, $idPackage, $installationDate, $status)); + } + + /** + * returns a message if the date was removed successfully + * @return json array with confirmation messages + */ + public function removeMyDate() { + $idOrder = isset($_REQUEST['idOrder']) ? $_REQUEST['idOrder'] : 0; + $idPackage = isset($_REQUEST['idPackage']) ? $_REQUEST['idPackage'] : 0; + $installationDate = isset($_REQUEST['installationDate']) ? $_REQUEST['installationDate'] : ''; + echo json_encode($this->model->removeMyDate($idOrder, $idPackage, $installationDate)); + } + + /** + * sends a mail to the support team + * @return json confirmation message + */ + public function sendSupportMail() { + $ordersInfo = isset($_REQUEST['orderInfo']) ? $_REQUEST['orderInfo'] : '[]'; + $orderPackages = isset($_REQUEST['orderPackages']) ? $_REQUEST['orderPackages'] : '[]'; + $userText = isset($_REQUEST['supportText']) ? $_REQUEST['supportText'] : ''; + echo json_encode($this->model->sendSupportMail($ordersInfo, $orderPackages, $userText)); + } +} diff --git a/api-wiaas/server/components/v2/orders/OrdersModel.php b/api-wiaas/server/components/v2/orders/OrdersModel.php new file mode 100644 index 0000000..2075fc3 --- /dev/null +++ b/api-wiaas/server/components/v2/orders/OrdersModel.php @@ -0,0 +1,1420 @@ +headersHelper = new HeadersHelper(); + } + + /** + * get the list of orders + * @return Array array of orders + */ + public function getActiveOrders(){ + global $database, $user; + + $userType = $user->getUserType(); + $idUser = $user->getUserId(); + $headersSql = $this->getActiveOrdersHeaders('sql')['headers']; + $whereSql = "WHERE o.status!='production' AND o.status!='canceled' AND o.status!='end-of-life'"; + $extraSql = ""; + $orders = []; + $isCustomer = false; + $isCommercialLead = false; + + switch($userType){ + case 'broker' : + $extraSql .= "LEFT OUTER JOIN ".TABLES['brokers']." b + ON b.id=o.assignedTo"; + break; + + case 'customer' : + $extraSql .= "INNER JOIN ".TABLES['users']." ucust + ON ucust.idCompany = uc.idCompany + AND ucust.id = $idUser"; + $isCustomer = true; + break; + + case 'commercial_lead': + $extraSql .= "INNER JOIN ".TABLES['users']." uclCompany + ON uclCompany.idCompany = ucl.idCompany + AND uclCompany.id = $idUser"; + $isCommercialLead = true; + break; + + case 'supplier' : + $extraSql .= "INNER JOIN ".TABLES['rel_package_products']." rpp + ON rpp.idPackage=rop.idPackage AND rop.packageInstance=rpp.packageInstance + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rpp.idProduct + INNER JOIN ".TABLES['suppliers']." s + ON s.id=scp.idSupplier"; + $whereSql .= " AND s.idUser=$idUser AND o.status='in-progress'"; + break; + } + + $sql = "SELECT + $headersSql + FROM + ".TABLES['orders']." o + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON o.idCustomerInstance = rclc.id + INNER JOIN ".TABLES['customers']." cust + ON cust.id = rclc.idCustomer + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id = rclc.idCommercialLead + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idOrder=o.id + INNER JOIN ".TABLES['users']." ucl + ON ucl.id = cl.idUser + INNER JOIN ".TABLES['users']." uc + ON uc.id = cust.idUser + $extraSql + $whereSql + GROUP BY o.id + ORDER BY o.orderNumber DESC"; + + $orderPackages = $this->getOrderPackages(0, 'ongoing'); + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['packages'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']] : []; + $row['orderCurrency'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']][0]['packageCurrency'] : ''; + if($isCustomer) { + $row['isMyOrder'] = $idUser === $row['idCustomerUser'] ? true : false; + } + if($isCommercialLead) { + $row['isMyOrder'] = $idUser === $row['idCommercialLeadUser'] ? true : false; + } + array_push($orders, $row); + } + + return ['orders' => $orders]; + } + + /** + * Get the headers requried for the orders + * @param string $type type of the headere, posible values array or sql + * @return string|array returns the sql header or the array of for the headers + */ + private function getActiveOrdersHeaders( $type = 'array'){ + global $user; + $userType = $user->getUserType(); + $data = []; + + switch($userType){ + case 'broker' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'o.idCustomerInstance' => 'idCustomerInstance', + 'rclc.IdCustomer' => 'idCustomer', + 'cust.name' => 'customer', + 'rclc.idCommercialLead' => 'idCommercialLead', + 'cl.name' => 'commercialLead', + 'IFNULL(b.name, \'\')' => 'assignedTo', + 'o.orderDate' => 'orderDate', + 'o.estimatedDeliveryDate' => 'estimatedDeliveryDate', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cust.phone' => 'customerPhone', + 'uc.mail' => 'customerMail', + 'cl.phone' => 'commercialLeadPhone', + 'ucl.mail' => 'commercialLeadMail', + ]; + break; + + case 'customer' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'rclc.idCommercialLead' => 'idCommercialLead', + 'uc.id' => 'idCustomerUser', + 'cust.name' => 'customerName', + 'cust.phone' => 'phone', + 'uc.mail' => 'mail', + 'cl.contactName' => 'clContactName', + 'cl.name' => 'clName', + 'DATE_FORMAT(o.orderDate, \'%D %b, %Y\')' => 'orderDate', + 'DATE_FORMAT(o.estimatedDeliveryDate, \'%D %b, %Y\')' => 'estimatedDeliveryDate', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cl.phone' => 'commercialLeadPhone', + 'ucl.mail' => 'commercialLeadMail' + ]; + break; + + case 'commercial_lead' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'cl.idUser' => 'idCommercialLeadUser', + 'cl.name' => 'commercialLeadName', + 'o.idCustomerInstance' => 'idCustomerInstance', + 'rclc.IdCustomer' => 'idCustomer', + 'cust.name' => 'customer', + 'o.orderDate' => 'orderDate', + 'o.estimatedDeliveryDate' => 'estimatedDeliveryDate', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cust.phone' => 'customerPhone', + 'uc.mail' => 'customerMail' + ]; + break; + + case 'supplier' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.orderDate' => 'orderDate', + '\'\'' => 'orderItems', + 'o.deliveryAddress' => 'deliveryAddress', + 'cust.phone' => 'customerPhone', + 'uc.mail' => 'customerMail' + ]; + break; + + default : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status' + ]; + } + $data['headers'] = $this->headersHelper->getHeader($headers, $type); + if($userType === USER_TYPES['BROKER']){ + $data['brokers'] = $this->getBrokers(); + } + + return $data; + } + + /** + * return id and name of the brokers from the system + * @return Array of id and name for brokers + */ + public function getBrokers(){ + global $database, $user; + + $userType = $user->getUserType(); + if($userType !== USER_TYPES['BROKER']){ + return []; + } + + $idUser = $user->getUserId(); + $sql = " SELECT b.id as idBroker, + CASE WHEN b.idUser=$idUser THEN 'Me' ELSE b.name END as brokerName + FROM ".TABLES['brokers']." b + ORDER BY b.name"; + + return $database->fetchResultArray($sql); + } + + + /** + * get the list of orders history + * @return Array array of orders + */ + public function getHistoryOrders(){ + global $database; + global $user; + + $userType = $user->getUserType(); + $idUser = $user->getUserId(); + $headersSql = $this->getHistoryOrdersHeaders('sql'); + $extraSql = ''; + $whereSql = "WHERE (o.status='production' OR o.status='canceled' OR o.status='end-of-life')"; + $orders = []; + $isCustomer = false; + $isCommercialLead = false; + + switch($userType){ + case 'customer' : + $extraSql .= " + INNER JOIN ".TABLES['users']." ucust + ON ucust.idCompany = uc.idCompany + AND ucust.id = $idUser"; + $isCustomer = true; + break; + + case 'commercial_lead': + $extraSql .= " + INNER JOIN ".TABLES['users']." uclCompany + ON uclCompany.idCompany = ucl.idCompany + AND uclCompany.id = $idUser"; + $isCommercialLead = true; + break; + } + + $sql = "SELECT + $headersSql, + SUM(rop.packageFixedPrice * rop.units) AS fixedPrice, + SUM((rop.packageRecuringPrice * rop.units) + (rop.packageServicePrice * rop.units)) AS recurringPrice + FROM + ".TABLES['orders']." o + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON o.idCustomerInstance=rclc.id + INNER JOIN ".TABLES['customers']." cust + ON cust.id=rclc.idCustomer + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idOrder=o.id + INNER JOIN ".TABLES['users']." ucl + ON ucl.id = cl.idUser + INNER JOIN ".TABLES['users']." uc + ON uc.id = cust.idUser + $extraSql + $whereSql + GROUP BY o.id + ORDER BY o.orderNumber DESC"; + + $orderPackages = $this->getOrderPackages(0, 'history'); + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['packages'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']] : []; + $row['orderCurrency'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']][0]['packageCurrency'] : ''; + if($isCustomer) { + $row['isMyOrder'] = $idUser === $row['idCustomerUser'] ? true : false; + } + if($isCommercialLead) { + $row['isMyOrder'] = $idUser === $row['idCommercialLeadUser'] ? true : false; + } + array_push($orders, $row); + } + + return ['orders' => $orders]; + } + + /** + * Get the headers requried for the orders history + * @param string $type type of the headere, posible values array or sql + * @return string|array returns the sql header or the array of for the headers + */ + private function getHistoryOrdersHeaders( $type = 'array'){ + global $user; + $userType = $user->getUserType(); + + switch($userType){ + case 'broker' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'o.idCustomerInstance' => 'idCustomerInstance', + 'rclc.IdCustomer' => 'idCustomer', + 'cust.name' => 'customer', + 'rclc.idCommercialLead' => 'idCommercialLead', + 'cl.name' => 'commercialLead', + 'o.orderDate' => 'orderDate', + 'o.estimatedDeliveryDate' => 'estimatedDeliveryDate', + 'o.deliveryDate' => 'deliveryDate', + 'MAX(rop.endOfLife)' => 'endOfLife', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cust.phone' => 'customerPhone', + 'uc.mail' => 'customerMail', + 'cl.phone' => 'commercialLeadPhone', + 'ucl.mail' => 'commercialLeadMail' + ]; + break; + + case 'customer' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'o.tender' => 'tender', + 'rclc.idCommercialLead' => 'idCommercialLead', + 'uc.id' => 'idCustomerUser', + 'cust.name' => 'customerName', + 'cust.phone' => 'phone', + 'uc.mail' => 'mail', + 'cl.name' => 'clName', + 'cl.contactName' => 'clContactName', + 'DATE_FORMAT(o.orderDate, \'%D %b, %Y\')' => 'orderDate', + 'DATE_FORMAT(o.estimatedDeliveryDate, \'%D %b, %Y\')' => 'estimatedDeliveryDate', + 'DATE_FORMAT(o.deliveryDate, \'%D %b, %Y\')' => 'deliveryDate', + 'DATE_FORMAT(MAX(rop.endOfLife), \'%D %b, %Y\')' => 'endOfLife', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cl.phone' => 'commercialLeadPhone', + 'ucl.mail' => 'commercialLeadMail' + ]; + break; + + case 'commercial_lead' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'cl.idUser' => 'idCommercialLeadUser', + 'cl.name' => 'commercialLeadName', + 'o.idCustomerInstance' => 'idCustomerInstance', + 'rclc.IdCustomer' => 'idCustomer', + 'cust.name' => 'customer', + 'o.orderDate' => 'orderDate', + 'o.estimatedDeliveryDate' => 'estimatedDeliveryDate', + 'o.deliveryDate' => 'deliveryDate', + 'MAX(rop.endOfLife)' => 'endOfLife', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cust.phone' => 'customerPhone', + 'uc.mail' => 'customerMail' + ]; + break; + + case 'supplier' : + $headers = [ + 'o.id' => 'id', + 'o.orderNumber' => 'orderNumber', + 'o.status' => 'status', + 'o.reference' => 'reference', + 'o.idCustomerInstance' => 'idCustomerInstance', + 'rclc.IdCustomer' => 'idCustomer', + 'cust.name' => 'customer', + 'o.orderDate' => 'orderDate', + 'o.estimatedDeliveryDate' => 'estimatedDeliveryDate', + 'o.deliveryDate' => 'deliveryDate', + 'MAX(rop.endOfLife)' => 'endOfLife', + '\'\'' => 'orderItems', + 'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice', + 'o.deliveryAddress' => 'deliveryAddress', + 'cust.phone' => 'customerPhone', + 'uc.mail' => 'customerMail' + ]; + break; + } + + return $this->headersHelper->getHeader($headers, $type); + } + + /** + * get packages for the order + * @param INT $idOrder id for order + * @return Array packages array + */ + private function getOrderPackages($idOrder = 0, $forOrders){ + global $database, $user; + + $countries = new Countries(); + $whereSql = $idOrder === 0 ? "WHERE 1=1 " : "WHERE rop.idOrder=$idOrder "; + $extraJoin = ""; + $extraFields = ""; + $userType = $user->getUserType(); + + if($forOrders === 'history'){ + $whereSql .= "AND (o.status='production' OR o.status='canceled' OR o.status='end-of-life')"; + $extraFields = "IFNULL(DATE_FORMAT(rop.endOfLife, '%D %b, %Y'), '') as endOfLife, + rop.units, + rop.packageFixedPrice, + rop.packageRecuringPrice, + rop.packageServicePrice, + rop.status, + pt.packagePayPeriod, + pt.servicesContractPeriod, + pt.maxContractPeriod, + pt.periodUnit,"; + } else if($forOrders === 'ongoing'){ + if($userType === USER_TYPES['BROKER']){ + $extraJoin = "LEFT OUTER JOIN + (SELECT + rops.idOrder, + rops.idPackage, + ps.shortDesc + FROM + ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id = rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps + ON ps.id = rps.idStep + WHERE + rops.status = 'in-progress' + ) ongoing_steps + ON ongoing_steps.idOrder = rop.idOrder AND ongoing_steps.idPackage = rop.idPackage"; + $extraFields = "IFNULL(ongoing_steps.shortDesc, rop.status) AS shortDesc, + rop.units, + rop.packageFixedPrice, + rop.packageRecuringPrice, + rop.packageServicePrice, + rop.status, + pt.packagePayPeriod, + pt.servicesContractPeriod, + pt.maxContractPeriod, + pt.periodUnit,"; + } else if($userType === USER_TYPES['SUPPLIER']){ + $extraJoin = "INNER JOIN + (SELECT + rops.idOrder, + rops.idPackage, + ps.shortDesc + FROM + ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['rel_process_steps']." rps + ON rps.id = rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps + ON ps.id = rps.idStep + INNER JOIN ".TABLES['process_step_actions']." psa + ON psa.id=ps.idActionCode + WHERE + rops.status ='in-progress' AND psa.actionCode='procurement' + ) ongoing_steps + ON ongoing_steps.idOrder = rop.idOrder AND ongoing_steps.idPackage = rop.idPackage"; + $extraFields = "IFNULL(ongoing_steps.shortDesc, rop.status) AS shortDesc, + rop.units, + rop.status,"; + } else { + $extraJoin = "LEFT OUTER JOIN + ( SELECT + done_steps.idOrder, + done_steps.idPackage, + ps.shortDesc + FROM + (SELECT + rops.idOrder, + rops.idPackage, + MAX(rops.idProcessStep) AS idProcessStep + FROM + ".TABLES['rel_order_process_step']." rops + INNER JOIN ".TABLES['rel_process_steps']." rps ON rps.id = rops.idProcessStep + INNER JOIN ".TABLES['process_step']." ps ON ps.id = rps.idStep + WHERE + (rops.status = 'done' + OR rops.status = 'in-progress') + AND ps.isVisibleForCustomer = 1 + GROUP BY rops.idOrder , rops.idPackage) AS done_steps + INNER JOIN + ".TABLES['rel_process_steps']." rps ON rps.id = done_steps.idProcessStep + INNER JOIN + ".TABLES['process_step']." ps ON ps.id = rps.idStep + ) ongoing_steps + ON ongoing_steps.idOrder = rop.idOrder AND ongoing_steps.idPackage = rop.idPackage"; + $extraFields = "IFNULL(ongoing_steps.shortDesc, rop.status) AS shortDesc, + rop.units, + rop.packageFixedPrice, + rop.packageRecuringPrice, + rop.packageServicePrice, + rop.status, + pt.packagePayPeriod, + pt.servicesContractPeriod, + pt.maxContractPeriod, + pt.periodUnit,"; + } + + $whereSql .= "AND (o.status!='production' AND o.status!='canceled' AND o.status!='end-of-life')"; + + }else{ + $extraFields = "IFNULL(rop.endOfLife, '') as endOfLife, + rop.units, + rop.packageFixedPrice, + rop.packageRecuringPrice, + rop.packageServicePrice, + rop.status, + pt.packagePayPeriod, + pt.servicesContractPeriod, + pt.maxContractPeriod, + pt.periodUnit,"; + } + + $sql = "SELECT + $extraFields + pt.payType AS paymentType, + rop.idOrder, + pkg.id AS idPackage, + pkg.name AS packageName + FROM ".TABLES['packages']." pkg + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage=pkg.id + INNER JOIN ".TABLES['orders']." o + ON o.id=rop.idOrder + INNER JOIN ".TABLES['payment_types']." pt + ON pt.id=rop.idPaymentTerm + $extraJoin + $whereSql"; + $data = []; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['packageCurrency'] = $countries->getCurrencyForPackage($row['idPackage']); + $data[$row['idOrder']][] = $row; + } + + return $data; + } + + /** + * get products for packages in an order + * @param INT $idOrder id for the order + * @return array array with all products grouped by package and category + */ + private function getOrderProducts($idOrder){ + global $database; + + $sql = "SELECT rcp.productName, pc.category, rpp.idPackage + FROM ".TABLES['suppliers_countries_products']." rcp + INNER JOIN product_categories pc + ON pc.id=rcp.idProductCategory + INNER JOIN ".TABLES['rel_package_products']." rpp + ON rpp.idProduct=rcp.idProduct + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idPackage=rpp.idPackage AND rop.packageInstance=rpp.packageInstance + WHERE rop.idOrder=$idOrder + "; + $query = $database->query($sql); + $data = []; + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][$row['category']][] = $row; + } + + return $data; + } + + private function getOrderSelections($idOrder){ + global $database; + $data = []; + + $sql = "SELECT + scp.productName, + os.idPackage, + pc.category + FROM ".TABLES['suppliers_countries_products']." scp + INNER JOIN ".TABLES['order_selections']." os + ON os.idProduct=scp.idProduct + INNER JOIN ".TABLES['product_categories']." pc + ON pc.id=scp.idProductCategory + WHERE os.idOrder=$idOrder"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][$row['category']][] = $row; + } + + return $data; + } + + /** + * get all comments for a specific order + * @param INT $idOrder id of the order + * @return Array Array of commnets for the order + */ + private function getOrderComments($idOrder){ + global $database, $user; + + $sql = "SELECT c.comment, + DATE_FORMAT(c.addDate, '%D %b, %y') as addDate, + u.username, + u.id=".$user->getUserId()." AS isOwner + FROM ".TABLES['rel_order_comments']." c + INNER JOIN ".TABLES['users']." u + ON u.id=c.idUser + WHERE c.idOrder=$idOrder + ORDER BY c.addDate DESC"; + + return $database->fetchResultArray($sql); + } + + /** + * get all options linked to a package in an order + * @param INT $idOrder id for the order + * @return Array list of options grouped by packages + */ + private function getOrderOptions($idOrder){ + global $database; + $data = []; + + $sql = "SELECT + roep.idPackage, + p.name AS packageName, + pog.name AS groupName + FROM ".TABLES['rel_order_extra_packages']." roep + INNER JOIN ".TABLES['packages']." p + ON p.id=roep.idExtraPackage + INNER JOIN ".TABLES['rel_group_options']." rgo + ON rgo.idOptionPackage=roep.idExtraPackage + INNER JOIN ".TABLES['package_option_groups']." pog + ON pog.id=rgo.idGroup and pog.idPackage=roep.idPackage + WHERE roep.idOrder=$idOrder"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][] = $row; + } + + return $data; + } + + private function getOrderAdditionalPackages($idOrder){ + global $database; + $data = []; + + $sql = "SELECT + roep.idPackage, + p.name AS packageName + FROM ".TABLES['rel_order_extra_packages']." roep + INNER JOIN ".TABLES['packages']." p + ON p.id=roep.idExtraPackage + WHERE roep.idOrder=$idOrder AND p.idPackageType=".self::ID_ADDITONAL_TYPE; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][] = $row; + } + + return $data; + } + + /** + * check if user has rights to see a specific order + * @param INT $idOrder id of the order + * @return Boolean retruns true if the user can see the order + */ + private function checkOrderOwner($idOrder){ + global $database, $user; + $idUser = $user->getUserId(); + $extraWhere = " AND u.idUser=$idUser"; + $isCompanyAdmin = UtilsModel::checkIfUserIsCompanyAdmin(); + + if($user->getUserType() === USER_TYPES['BROKER']){ + return true; + }else if($user->getUserType() === USER_TYPES['CUSTOMER']){ + $extraJoin = " INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=o.idCustomerInstance + INNER JOIN ".TABLES['customers']." u + ON u.id=rclc.idCustomer + INNER JOIN ".TABLES['users']." us + ON us.id = u.idUser"; + if($isCompanyAdmin) { + $extraJoin .= " INNER JOIN ".TABLES['users']." uc + ON uc.idCompany = us.idCompany + AND uc.id=$idUser"; + $extraWhere = ''; + } + }else if($user->getUserType() === USER_TYPES['COMMERCIAL_LEAD']){ + $extraJoin = "INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id=o.idCustomerInstance + INNER JOIN ".TABLES['commercial_leads']." u + ON u.id=rclc.idCommercialLead + INNER JOIN ".TABLES['users']." us + ON us.id = u.idUser"; + if($isCompanyAdmin) { + $extraJoin .= " INNER JOIN ".TABLES['users']." ucl + ON ucl.idCompany = us.idCompany + AND ucl.id=$idUser"; + $extraWhere = ''; + } + }else if($user->getUserType() === USER_TYPES['SUPPLIER']){ + $extraJoin = "INNER JOIN ".TABLES['rel_order_products_estimation']." rope + ON rope.idOrder=o.id + INNER JOIN ".TABLES['suppliers_countries_products']." scp + ON scp.idProduct=rope.idProduct + OR scp.idProductCategory = ".self::ID_INSTALLATION_CATEGORY." + INNER JOIN ".TABLES['suppliers']." u + ON u.id=scp.idSupplier"; + }else{ + return false; + } + + $sql = "SELECT o.id + FROM ".TABLES['orders']." o + $extraJoin + WHERE o.id=$idOrder + $extraWhere + LIMIT 1"; + $query = $database->query($sql); + + return $database->numRows($query) === 1; + } + + /** + * get info for orders (details, packages, available processes) + * @param INT $idOrder id for the order + * @return HashArray array containtg info, packages, availableProcesses + */ + public function getOrderInfo($idOrder){ + global $database; + $data = []; + $idOrder = $database->escapeValue($idOrder); + $isCompanyAdmin = UtilsModel::checkIfUserIsCompanyAdmin(); + $orderProcessHelper = new OrderProcessHelper(); + $orderDocuments = new OrderDocuments(); + + if(!$this->checkOrderOwner($idOrder, $isCompanyAdmin)){ + return []; + } + + $sql = "SELECT o.id, + o.orderNumber, + DATE_FORMAT(o.orderDate, '%D %b, %y') as orderDate, + o.estimatedDeliveryDate, + o.status, + o.reference, + o.tender, + o.idTerms, + o.idProject, + IFNULL(op.name, '') as projectName, + IFNULL(b.name, 'Unassigned') as assignedTo, + cust.name AS customer, + cust.phone, + u.mail, + cl.id AS idCommercialLead, + cl.name AS commercialLead, + MAX(rop.endOfLife) AS endOfLife + FROM + ".TABLES['orders']." o + LEFT OUTER JOIN ".TABLES['brokers']." b + ON b.id=o.assignedTo + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON o.idCustomerInstance=rclc.id + INNER JOIN ".TABLES['customers']." cust + ON cust.id=rclc.idCustomer + INNER JOIN ".TABLES['users']." u + ON u.id = cust.idUser + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=rclc.idCommercialLead + INNER JOIN ".TABLES['rel_order_packages']." rop + ON rop.idOrder=o.id + LEFT OUTER JOIN ".TABLES['order_projects']." op + ON op.id=o.idProject + WHERE o.id=$idOrder + GROUP BY o.id + LIMIT 1"; + $data['info'] = $database->fetchResultArray($sql); + $data['info'] = isset($data['info'][0]) ? $data['info'][0] : []; + $data['products'] = $this->getOrderProducts($idOrder); + $data['packages'] = $this->getOrderPackages($idOrder, 'all')[$idOrder]; + $data['process'] = $orderProcessHelper->getOrderSteps($idOrder); + $documents = $orderDocuments->getOrderDocuments($idOrder); + $options = $this->getOrderOptions($idOrder); + $additionalPackages = $this->getOrderAdditionalPackages($idOrder); + foreach($data['packages'] as &$package){ + $package['documents'] = isset($documents[$package['idPackage']]) ? $documents[$package['idPackage']] : []; + $package['options'] = isset($options[$package['idPackage']]) ? $options[$package['idPackage']] : []; + $package['additionalPackages'] = isset($additionalPackages[$package['idPackage']]) ? $additionalPackages[$package['idPackage']] : []; + } + $data['orderDocuments'] = isset($documents[0]) ? $documents[0] : []; + $data['selections'] = $this->getOrderSelections($idOrder); + $data['orderComments'] = $this->getOrderComments($idOrder); + + $data['availableProcesses'] = []; + + return $data; + } + + /** + * returns an array with all the system allowed languages + * @return Array all the system language allowed + */ + public function getSystemAllowedLanguages() { + global $database; + $data = []; + + $sql = " + SELECT + sal.languageCode AS languageCode, + sal.language AS language + FROM + ".TABLES['system_allowed_languages']." sal"; + $query = $database->query($sql); + + while($row = $database->fetchArray($query)) { + $data['code'][] = $row['languageCode']; + $data['languages'][] = $row['language']; + } + + return $data; + } + + /** + * get the language of the comment added or array if error + * @param String $comment the comment added by the user + * @return Array the language detected or error + */ + private function getLanguageDetectResponse($comment) { + $data = []; + $ch = curl_init(); + + $plainText = html_entity_decode(strip_tags($comment)); + $plainTextComment = urlencode($plainText); + $url = DETECT_LANGUAGE_API_URL.'?q='.$plainTextComment.'&key='.DETECT_LANGUAGE_API_KEY; + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + + $response = json_decode(curl_exec($ch)); + if(curl_errno($ch)){ + $data['error'] = 'Curl error: ' . curl_error($ch); + } + + curl_close($ch); + + if(gettype($response) === 'object' && $response->data && $response->data->detections) { + $firstLanguageDetected = $response->data->detections[0]; + if($firstLanguageDetected->isReliable) { + $data['language'] = $firstLanguageDetected->language; + } else { + $data['languageNotReliable'] = true; + } + } + + return $data; + } + + /** + * returns the mail addresses for cl and customer involved in the order process + * @param String $customerName customer's name + * @param String $commercialLeadName commercial lead's name + * @return Array mails of the customer and commercial lead + */ + private function orderParticipantsMails($idOrder) { + global $database, $user; + $mailArray = []; + + $sql = " + SELECT + c.idUser, + u.mail, + 'customer' AS type + FROM + ".TABLES['customers']." c + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.idCustomer=c.id + INNER JOIN ".TABLES['orders']." o + ON o.idCustomerInstance=rclc.id + INNER JOIN ".TABLES['users']." u + ON u.id = c.idUser + WHERE o.id=$idOrder + UNION + SELECT + cl.idUser, + u.mail, + 'other' AS type + FROM + ".TABLES['commercial_leads']." cl + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.idCommercialLead=cl.id + INNER JOIN ".TABLES['orders']." o + ON o.idCustomerInstance=rclc.id + INNER JOIN ".TABLES['users']." u + ON u.id = cl.idUser + WHERE o.id=$idOrder + UNION + SELECT + b.idUser, + u.mail, + 'other' AS type + FROM + ".TABLES['brokers']." b + INNER JOIN ".TABLES['orders']." o + ON CASE WHEN o.assignedTo is NULL THEN 1=1 ELSE o.assignedTo=b.id END + INNER JOIN ".TABLES['users']." u + ON u.id = b.idUser + WHERE o.id=$idOrder + "; + + $result = $database->query($sql); + while($row = $database->fetchArray($result)) { + if($row['mail'] !== '') { + if($row['idUser'] != $user->getUserId()) { + $mailArray[$row['type']][] = $row['mail']; + } + } + } + + return $mailArray; + } + + /** + * checks parameters and sends mail based on the action made + * @param String $mailType the action for which to send the mail + * @param Json string $orderData the details regarding the order for which to send the mail + * @return Array confirmation message + */ + private function sendConfirmationMail($mailType, $orderData) { + global $database, $user; + $mailType = $database->escapeValue($mailType); + $commentMessage = array_key_exists('commentMessage', $orderData) ? $orderData['commentMessage'] : ''; + foreach($orderData as $orderKey => $orderDetail) { + $orderData[$orderKey] = $database->escapeValue($orderDetail); + } + + $data = []; + $idOrder = array_key_exists('idOrder', $orderData) ? $orderData['idOrder'] : 0; + $orderNumber = array_key_exists('orderNumber', $orderData) ? $orderData['orderNumber'] : UtilsModel::getOrderNumberById($idOrder); + + if(!$mailType) { + return [ + 'code' => 'error', + 'message' => 'ACTION_NOT_SET' + ]; + } + + if(count($orderData) < 1) { + return [ + 'code' => 'error', + 'message' => 'ORDER_DATA_NOT_SET' + ]; + } + + if(!$idOrder) { + return [ + 'code' => 'error', + 'message' => 'ID_ORDER_NOT_SET' + ]; + } + + if(!$orderNumber) { + return [ + 'code' => 'error', + 'message' => 'ORDER_NUMBER_NOT_SET' + ]; + } + + $currentDate = new DateTime(); + $currentDate = $currentDate->format('d-m-Y H:i'); + + $params = [ + 'apiOrderUrl' => WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$idOrder.'&orderNumber='.$orderNumber, + 'orderUrl' => WIAAS_URL.'/orders/'.$idOrder, + 'mailType' => $mailType, + 'currentDate' => $currentDate, + 'idOrder' => $idOrder, + 'orderNumber' => $orderNumber + ]; + + switch($mailType) { + + case 'orderCommentAdded': + $mailTitle = "New comment for order $orderNumber ($currentDate)"; + $mailAddresses = $this->orderParticipantsMails($idOrder); + $params['commentMessage'] = $commentMessage; + $params['userLoggedIn'] = $user->getUserFullName(); + break; + default: + return $data; + } + + return UtilsModel::sendOrderUpdateMail($mailType, $params, $mailTitle, $mailAddresses); + } + + + /** + * add a new commnet for an order + * @param INT $idOrder Id of the order + * @param String $comment commnet text + * @return array update message + */ + public function addOrderComment($idOrder, $comment){ + global $database, $user; + + $data = []; + $idOrder = $database->escapeValue($idOrder); + $idUser = $user->getUserId(); + $ordersDetailsMail = ['idOrder' => $idOrder]; + + $checkMessage = $database->isEmpty('comment', $comment); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + $checkMessage = $database->invalidLength('comment',$comment, 1700); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if($data) { + return $data; + } + + $allowedLanguages = $this->getSystemAllowedLanguages(); + if(count($allowedLanguages) === 0) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'SYSTEM_ALLOWED_LANGUAGES_EMPTY' + ]; + } + + $languageDetected = $this->getLanguageDetectResponse($comment); + $allowedLang = implode(', ', $allowedLanguages['languages']); + + if(array_key_exists('language', $languageDetected)) { + if(!in_array($languageDetected['language'], $allowedLanguages['code'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ALLOWED_LANGUAGE', + 'key' => $allowedLang + ]; + } + } else if(array_key_exists('languageNotReliable', $languageDetected)) { + $data['messages'][] = [ + 'code' => 'warning', + 'message' => 'ALLOWED_LANGUAGE', + 'key' => $allowedLang + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ALLOWED_LANGUAGE_ERROR', + 'additionalMessage' => $languageDetected['error'] + ]; + return $data; + } + + $sql = "INSERT INTO ".TABLES['rel_order_comments']." + (idOrder, idUser, comment) + VALUES ($idOrder, $idUser, '".$database->escapeValue($comment)."')"; + $query = $database->query($sql); + + if(!$query){ + $err_mes = [ + 'code' => 'error', + 'message' => 'SERVER_ERROR' + ]; + $data['messages'][] = $err_mes; + } + + if($database->affectedRows() === 1){ + $message = [ + 'code' => 'success', + 'message' => 'ORDER_COMMENT_ADDED' + ]; + $data['messages'][] = $message; + + $ordersDetailsMail['commentMessage'] = $comment; + $data['messages'][] = $this->sendConfirmationMail('orderCommentAdded', $ordersDetailsMail); + } + + return $data; + } + + /** + * checks if the next step is the one needed for enabling the component + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @param Array $stepIds actions id of the steps between which the step should be enabled + * @return bool true if the next step should enable the component + */ + public function checkIfIsNextStepWanted($idOrder, $idPackage, $stepIds) { + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->checkIfIsNextStepWanted($idOrder, $idPackage, $stepIds); + } + + /** + * returns the earliest installation date based on the maximum delivery date plus the additional days + * @param Int $idOrder the id of the order + * @return Array the earliest installation date or error message + */ + public function getEarliestInstallationDateForOrder($idOrder) { + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->getInstallationScheduleEID($idOrder); + } + + /** + * get installation dates for each package in order + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @return Array array of installation dates + */ + public function getInstallationDates($idOrder, $idPackage){ + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->getInstallationDates($idOrder, $idPackage); + } + + /** + * get all installation companies for the order selected + * @param Int $idOrder id of the order + * @return Array array with all the installation companies + */ + public function getInstallCompaniesForOrder($idOrder) { + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->getInstallCompaniesForOrder($idOrder); + } + + /** + * Update the estimation date for the installation + * @param Int $idOrder Id of the order to be modified + * @param Int $idPackage id of the package to be modified + * @param String $newDate the date set by the user for the installation + * @param String $status the status of the date to be added + * @return array response message for the update + */ + public function updateInstallationDate($idOrder, $idPackage, $newDate, $status) { + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->updateInstallationDate($idOrder, $idPackage, $newDate, $status); + } + + /** + * remove the date from the order package + * @param Int $idOrder id of the order + * @param Int $idPackage id of the package + * @param String $installationDate the installation date to be removed + * @return Array confirmation messages + */ + public function removeMyDate($idOrder, $idPackage, $installationDate) { + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->removeMyDate($idOrder, $idPackage, $installationDate); + } + + /** + * get customer questionaires / installation protocol for a specific order + * @param INT $idOrder id for the order + * @param INT $idPackage id for the pacakge + * @param String $documentType the type of the documents needed - Order Questionaire or Installation protocol + * @return Array array of documents + */ + public function getOrderDocumentsPerType($idOrder, $documentType){ + $orderExtraActions = new orderExtraActions(); + + return $orderExtraActions->getOrderDocumentsPerType($idOrder, $documentType); + } + + /** + * upload again quesionnaire + * @param INT $idOrder id for the order + * @param INT $idPackage id for the package + * @param INT $idDocument id for the document + * @param file $file file to be uploaded + * @return Array update message + */ + public function reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file){ + $orderExtraActions = new orderExtraActions(); + + return $orderExtraActions->reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file); + } + + /** + * get comments by type e.g stepComment, invalidQuestionaireComment, ... + * @param Int $idOrder the id of the order + * @param Int $idPackage the id of the package + * @param Int $idProcessStep the id of the process step + * @param String $type the type of the comment: stepComment, invalidQuestionaireComment + * @return Array the comments wanted + */ + public function getCommentsByType($idOrder, $idPackage, $idProcessStep, $type) { + $orderExtraActions = new orderExtraActions(); + + return $orderExtraActions->getCommentsByType($idOrder, $idPackage, $idProcessStep, $type); + } + + /** + * get info for customer acceptance + * @param INT $idOrder id for the order + * @return Array custoemr acceptance info + */ + public function getCustomerAcceptance($idOrder){ + $customerAcceptance = new CustomerAcceptance(); + + return $customerAcceptance->getCustomerAcceptance($idOrder); + } + + /** + * upload customer acceptance document + * @param INT $idOrder id for the order + * @param FILE $file file to be uploaded + * @return Array upload status + */ + public function uploadAcceptanceDocument($idOrder, $file){ + $customerAcceptance = new CustomerAcceptance(); + + return $customerAcceptance->uploadAcceptanceDocument($idOrder, $file); + } + + /** + * customer change acceptance status for a package + * @param INT $idOrder id for the order + * @param String $actionType accept or decline the installation + * @param String $declineReason the reason for why the customer doesn't accept the installation + * @return Array update message + */ + public function acceptDeclineInstallation($idOrder, $actionType, $declineReason){ + $customerAcceptance = new CustomerAcceptance(); + + return $customerAcceptance->acceptDeclineInstallation($idOrder, $actionType, $declineReason); + } + + /** + * send an email to the support team from the customer + * @param Array $ordersInfo the order informations like orderNumber, so on + * @param Array $orderPackages the packages contained in the order + * @param String $userText the text writen by the customer + * @return Array confirmation message + */ + public function sendSupportMail($ordersInfo, $orderPackages, $userText) { + global $database, $user; + $ordersInfo = (array) $ordersInfo; + $orderPackages = $orderPackages; + $userText = $database->escapeValue($userText); + $mailSubject = ""; + + if($user->getUserType() !== USER_TYPES['CUSTOMER']) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'MAIL_NOT_AUTHORIZED' + ]; + + return $data; + } + + if(empty($userText)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'MAIL_TEXT_EMPTY' + ]; + + return $data; + } + + $orderItems = '
'; + foreach($orderPackages as $package) { + $orderItems .= '
+ + ' . $package['units'] . ' x ' . $package['packageName'] . ' +
+
+
+ Price: + '. $this->calculatePrice([$package['packageFixedPrice']], $package['units']) . ' + ( ' . $this->calculatePrice([$package['packageRecuringPrice'], $package['packageServicePrice']], $package['units']) . '/ ' . $package['periodUnit'] . ') +
+
'; + + if($package['packagePayPeriod'] > 0) { + $orderItems .= '
+ Package recurent price: ' . $package['units'] . ' x ' . $package['packageRecuringPrice'] . ' / ' . $package['periodUnit'] .' + for ' . $package['packagePayPeriod'] . ' ' . $package['periodUnit'] . ' +
'; + } + + $orderItems .= '
+ Services and support + ' . $package['units'] . ' x ' . $package['packageServicePrice'] . ' / ' . $package['periodUnit']; + if($package['servicesContractPeriod'] > 0) { + $orderItems .= 'for ' . $package['servicesContractPeriod'] . ' ' . $package['periodUnit'] . ''; + } + + $orderItems .= 'with possibility to extend each ' . $package['periodUnit'] . ' (Max ' . $package['maxContractPeriod'] . ') +
+
'; + + if(intval($package['packagePayPeriod']) > 0 || intval($package['servicesContractPeriod']) > 0) { + $orderItems .= '
+ Agreement period: '; + if(intval($package['packagePayPeriod']) > 0) { + $orderItems .= '
+ Agreement for package: + ' . $package['packagePayPeriod'] . ' ' . $package['periodUnit'] . ' +
'; + } + + if(intval($package['servicesContractPeriod']) > 0) { + $orderItems .= '
+ Agreement for services and support: + ' . $package['servicesContractPeriod'] . ' ' . $package['periodUnit'] . ' +
'; + } + $orderItems .= '
'; + } + + if(array_key_exists('shortDesc', $package) && $package['shortDesc']) { + $orderItems .= '
+ Delivery active step: ' . $package['shortDesc'] . ' +
'; + } + + if($package['endOfLife']) { + $orderItems .= '
+ End of life: ' . $package['endOfLife'] . ' +
'; + } + + $orderItems .= '
+ Status: '. $package['status'] . ' +
'; + } + $orderItems .= '

'; + + $params = [ + 'orderNumber' => $ordersInfo['orderNumber'], + 'idOrder' => $ordersInfo['id'], + 'customerName' => $ordersInfo['customerName'], + 'customerMail' => $ordersInfo['mail'], + 'customerPhone' => $ordersInfo['phone'], + 'reference' => $ordersInfo['reference'] ? $ordersInfo['reference'] : '-', + 'tender' => $ordersInfo['tender'] ? $ordersInfo['tender'] : '-', + 'commercialLead' => $ordersInfo['clName'], + 'orderItems' => $orderItems, + 'userText' => preg_replace('#(\\\r|\\\r\\\n|\\\n)#', '
', $userText) + ]; + + $currentDate = new DateTime(); + $currentDate = $currentDate->format('d-m-Y H:i'); + $mailSubject = "Support needed for " . $ordersInfo['orderNumber'] . " from " . $ordersInfo['customerName'] . "(" . $currentDate . ")"; + + $response = Mail::sendMail(SUPPORT_MAIL_LIST, $mailSubject, 'supportMailTemplate.php', $params); + + if($response){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'SUPPORT_MAIL_SENT' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + return $data; + } + + /** + * calculates the total price of given package and units + * @param Array $packagePrice the prices for each package in order + * @param Int $units the quantity of same packages in order + * @return Float the total price for the order + */ + private function calculatePrice($packagePrice, $units) { + $total = 0; + forEach($packagePrice as $val) { + $total += (float) $val; + } + + return $units ? ($total * intval($units)) : 0; + } + + /** + * get all installation data for order + * @param Int $idOrder id of the order + * @param Array $stepIds actions id of the steps between which the step should be enabled + * @param String $fileType the type of the documents needed - Order Questionaire or Installation protocol + * @return Array array with all data needed for the installation scheduling + */ + public function getAllDataForInstallation($idOrder, $stepIds, $fileType) { + $installationScheduling = new InstallationScheduling(); + + return $installationScheduling->getAllDataForInstallation($idOrder, $stepIds, $fileType); + } + } diff --git a/api-wiaas/server/components/v2/packages/PackageDocuments.php b/api-wiaas/server/components/v2/packages/PackageDocuments.php new file mode 100644 index 0000000..dbef8ad --- /dev/null +++ b/api-wiaas/server/components/v2/packages/PackageDocuments.php @@ -0,0 +1,86 @@ +getUserType() !== USER_TYPES['BROKER']){ + $whreSql = " AND visibleToCustomer=1"; + } + + if($idPackage !== 0){ + $whreSql .= " AND rpp.idPackage=$idPackage"; + $maxInstWhereSql = "AND idPackage=$idPackage"; + } + + $sql = "SELECT + d.id AS idDocument, + d.documentName, + d.documentPath, + d.extension, + dt.type AS documentType, + rpp.idPackage, + rpd.idProduct + FROM ".TABLES['rel_product_documents']." rpd + INNER JOIN ".TABLES['documents']." d + ON d.id=rpd.idDocument + INNER JOIN ".TABLES['document_types']." dt + ON dt.id=d.idDocumentType + INNER JOIN ".TABLES['rel_package_products']." rpp + ON rpp.idProduct=rpd.idProduct + INNER JOIN ( + SELECT MAX(packageInstance) as maxInstance + FROM ".TABLES['rel_package_products']." + WHERE 1=1 $maxInstWhereSql + GROUP BY idPackage + ) max_inst + ON max_inst.maxInstance=rpp.packageInstance + WHERE 1=1 $whreSql + "; + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][] = $row; + } + + return $data; + } + + /** + * get package documents + * @param INT $idPackage id for the pacakge + * @return Array list of documents + */ + public function getPackageDocuments($idPackage = 0){ + global $database; + $data[$idPackage] = []; + $whereSql = $idPackage !== 0 ? "WHERE rpd.idPackage=$idPackage" : ""; + + $sql = "SELECT + d.id AS idDocument, + d.documentName, + d.extension, + rpd.idPackage + FROM ".TABLES['documents']." d + INNER JOIN ".TABLES['document_types']." dt + ON dt.id=d.idDocumentType + INNER JOIN ".TABLES['rel_package_documents']." rpd + ON rpd.idDocument=d.id + $whereSql "; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $data[$row['idPackage']][] = $row; + } + $productDocuments = $this->getProductDocuments($idPackage); + foreach ($data as $idPackage => &$documents) { + if(isset($productDocuments[$idPackage])){ + $documents = array_merge($documents, $productDocuments[$idPackage]); + } + } + + return $data; + } +} diff --git a/api-wiaas/server/components/v2/packages/Packages.php b/api-wiaas/server/components/v2/packages/Packages.php new file mode 100644 index 0000000..487d6e5 --- /dev/null +++ b/api-wiaas/server/components/v2/packages/Packages.php @@ -0,0 +1,193 @@ + 1, + 'ID_OPTION_TYPE' => 2, + 'ID_ADDITONAL_TYPE' => 3 + ]; + + public function generatePackagePayRow($row, $orderType, $customerInfo, $commissionSplit, $totalCost, $interestRateValue){ + $prices = new Prices(); + + $row['idOrderType'] = $orderType; + $margins = $prices->getPriceMargins($commissionSplit, $row, $totalCost); + if($customerInfo['isSameCompanyAsCl'] == 1){ + if($row['packagePayPeriod'] > 0){ + $row['fixedExtra'] = $row['minimalFixedPrice']; + $row['recurentExtra'] = $prices->getRecurrentPriceMortage($row, $margins['clMargin'], $interestRateValue); + }else{ + $row['fixedExtra'] = $row['minimalFixedPrice'] - $margins['clMargin']; + $row['recurentExtra'] = 0; + } + $row['servicesExtra'] = $row['minimalServicesPrice']; + }else{ + $row['fixedExtra'] = $row['fixedExtra'] + $row['minimalFixedPrice']; + $row['recurentExtra'] = $row['packagePayPeriod'] > 0 + ? $row['recurentExtra'] + $prices->getRecurrentPriceMortage($row, 0, $interestRateValue) + : 0; + $row['servicesExtra'] = $row['servicesExtra'] + $row['minimalServicesPrice']; + } + unset($row['minimalFixedPrice']); + unset($row['minimalServicesPrice']); + unset($row['principalAmount']); + $row['isSameCompanyAsCl'] = $customerInfo['isSameCompanyAsCl']; + + return $row; + } + + /** + * get all prices types for a package by commercial lead + * @param INT $idCommercialLead id for commercial lead + * @param INT $idPackage id for package(in case of additional or optional it represents the parent package) + * @param INT $type id for package type => see self::PACKAGE_TYPES + * @return Array prices array + */ + public function getPricesForPackages($idCommercialLead, $idPackage, $type, $idPaymentType = 0){ + global $database, $user; + $data = []; + $whereSql = ""; + $extraJoin = ""; + $idUser = $user->getUserId(); + $prices = new Prices(); + $clCustomersInst = new ClCustomers(); + $orderTypeInst = new OrderType(); + $interestRate = new InterestRate(); + $customerInfo = $clCustomersInst->getClCustomerInfo($idCommercialLead); + $orderType = $customerInfo['idOrderType'] ? $customerInfo['idOrderType'] : $orderTypeInst->getCLDefaultOrderType($idCommercialLead); + + if($type === self::PACKAGE_TYPES['ID_STANDARD_TYPE']){ + $whereSql = "AND plcl.idPackage=$idPackage"; + } + + if($type === self::PACKAGE_TYPES['ID_OPTION_TYPE']){ + $whereSql = "AND pog.idPackage=$idPackage"; + $extraJoin = "INNER JOIN ".TABLES['rel_group_options']." rgo + ON rgo.idOptionPackage=plcl.idPackage + INNER JOIN ".TABLES['package_option_groups']." pog + ON pog.id=rgo.idGroup"; + } + + $productPrices = $prices->getPackageProductPrices($idPackage); + $totalCost = $prices->calculatePackageTotalCost($productPrices); + $commissionSplit = $prices->getCommissionSplit($idPackage); + $interestRateValue = $interestRate->getInterestRate(); + $interestRateCustomers = $interestRate->getInterestRateForCustomers(); + + if($type === self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']){ + $whereSql = "AND rap.idPackage=$idPackage"; + $extraJoin = " INNER JOIN ".TABLES['rel_additional_packages']." rap + ON rap.idAdditionalPackage=plcl.idPackage"; + } + + if($idPaymentType){ + $whereSql .= " AND plcl.idPaymentType=$idPaymentType"; + } + + $sql = "SELECT + IF(custom_prices.idCustomer != 0, custom_prices.idCustomer, c.id) AS idCustomer, + plcl.id as idPrice, + plb.idPackage, + plb.idPaymentType, + pt.payType, + pt.packagePayPeriod, + pt.servicesContractPeriod, + pt.periodUnit, + pt.maxContractPeriod, + plcl.fixedExtra, + plcl.recurentExtra, + plcl.servicesExtra, + plb.minimalFixedPrice, + plb.minimalServicesPrice, + plb.principalAmount + FROM ".TABLES['price_list_broker']." plb + INNER JOIN + (SELECT + plcl.idPackage, + plcl.idPaymentType, + plcl.idCommercialLead, + MAX(IFNULL(idCustomer, 0)) AS idCustomer + FROM + ".TABLES['price_list_commercial_lead']." plcl + $extraJoin + LEFT OUTER JOIN ".TABLES['customers']." cust + ON cust.id = plcl.idCustomer + WHERE + (cust.idUser = $idUser OR cust.idUser IS NULL) + $whereSql + AND plcl.idCommercialLead=$idCommercialLead + GROUP BY plcl.idPackage , plcl.idPaymentType + ) AS custom_prices + ON plb.idPackage = custom_prices.idPackage + AND plb.idPaymentType = custom_prices.idPaymentType + INNER JOIN ".TABLES['price_list_commercial_lead']." plcl + ON plcl.idPackage = custom_prices.idPackage + AND plcl.idPaymentType = custom_prices.idPaymentType + AND plcl.idCommercialLead = custom_prices.idCommercialLead + AND IFNULL(plcl.idCustomer, 0) = custom_prices.idCustomer + AND plcl.visibleToCustomer = 1 + INNER JOIN ".TABLES['payment_types']." pt + ON pt.id = plb.idPaymentType + INNER JOIN ".TABLES['customers']." c + ON c.idUser = ".$idUser; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $interestRateCust = array_key_exists($row['idCustomer'], $interestRateCustomers) ? $interestRateCustomers[$row['idCustomer']] : $interestRateValue['interestRate']; + $row = $this->generatePackagePayRow($row, $orderType, $customerInfo, $commissionSplit, $totalCost, $interestRateCust); + $data[$row['idPackage']][] = $row; + } + + return $data; + } + + /** + * checks if the customer is from the same company as the commercial lead + * @param Int $idUser id of the user + * @param Int $idCommercialLead id of the commercial lead + * @return Int 1 if they are from the same company + */ + public function checkIfCustomerIsFromCommercialLeadCompany($idCommercialLead, $isForCart = false) { + global $database, $user; + $extraJoin = ""; + $joinClause = ""; + $whereClause = ""; + $idUser = $user->getUserId(); + + if($user->getUserType() !== USER_TYPES['CUSTOMER']) { + return; + } + + if($isForCart) { + $extraJoin = "INNER JOIN ".TABLES['web_shop_cart']." cart + ON cart.idUser = $idUser + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON rclc.id = cart.idCustomerInstance"; + $joinClause = "AND cl.id = rclc.idCommercialLead"; + } else { + $whereClause = "WHERE cl.id = $idCommercialLead"; + } + + $sql = "SELECT + u.idCompany + FROM + ".TABLES['users']." u + $extraJoin + INNER JOIN ".TABLES['commercial_leads']." cl + ON u.id = cl.idUser + $joinClause + INNER JOIN + (SELECT + us.idCompany + FROM + ".TABLES['users']." us + WHERE us.id = $idUser) userCompany + ON userCompany.idCompany = u.idCompany + $whereClause"; + $result = $database->query($sql); + + return $database->numRows($result) > 0; + } +} diff --git a/api-wiaas/server/components/v2/prices/Prices.php b/api-wiaas/server/components/v2/prices/Prices.php new file mode 100644 index 0000000..d305b43 --- /dev/null +++ b/api-wiaas/server/components/v2/prices/Prices.php @@ -0,0 +1,323 @@ +query($sql); + $data['productsPrices'] = []; + + while($row = $database->fetchArray($query)){ + $productKey = $sumBy === 'type' ? $row['productType'] : $row['productCategory']; + if(!isset($data['productsPrices'][$productKey])){ + $data['productsPrices'][$productKey]['totalUnitCost'] = 0; + $data['productsPrices'][$productKey]['totalVatCost'] = 0; + } + + unset($totalCategoryUnitCost); + unset($totalCategoryVatCost); + + $totalCategoryUnitCost =& $data['productsPrices'][$productKey]['totalUnitCost']; + $totalCategoryVatCost =& $data['productsPrices'][$productKey]['totalVatCost']; + + if($sumBy === 'type' && $row['productType'] === 'service') { + $totalUnitCost = $this->calculateTotalPrice(0, $row['unitCostPrice'], $row['payPeriod'], $row['quantity']); + $totalVatCost = $this->calculateTotalPrice(0, $row['unitVatCost'], $row['payPeriod'], $row['quantity']); + + if($row['isPriceRecurring'] == 1) { + if(!isset($data['productsPrices'][$row['productType']]['recurringPrice'])) { + $data['productsPrices'][$row['productType']]['recurringPrice'] = 0; + $data['productsPrices'][$row['productType']]['recurringVatPrice'] = 0; + } + $data['productsPrices'][$row['productType']]['recurringPrice'] += $totalUnitCost; + $data['productsPrices'][$row['productType']]['recurringVatPrice'] += $totalVatCost; + } else { + if(!isset($data['productsPrices'][$row['productType']]['recurringPrice'])) { + $data['productsPrices'][$row['productType']]['fixedPrice'] = 0; + $data['productsPrices'][$row['productType']]['fixedVatPrice'] = 0; + } + $data['productsPrices'][$row['productType']]['fixedPrice'] += $totalUnitCost; + $data['productsPrices'][$row['productType']]['fixedVatPrice'] += $totalVatCost; + } + } else { + $totalUnitCost = $this->calculateTotalPrice($row['isPriceRecurring'], $row['unitCostPrice'], $row['payPeriod'], $row['quantity']); + $totalVatCost = $this->calculateTotalPrice($row['isPriceRecurring'], $row['unitVatCost'], $row['payPeriod'], $row['quantity']); + } + + if($row['productType'] === 'installation'){ + $totalCategoryUnitCost = $this->getMultiProductsTotal($totalCategoryUnitCost, $totalUnitCost); + $totalCategoryVatCost = $this->getMultiProductsTotal($totalCategoryVatCost, $totalVatCost); + } else { + $totalCategoryUnitCost += $totalUnitCost; + $totalCategoryVatCost += $totalVatCost; + } + } + + return $data['productsPrices']; + } + + /** + * get commission split + * @param INT $idPackage id for commission split + * @return HashArray commission split percentqages + */ + public function getCommissionSplit($idPackage){ + global $database; + + $sql = "SELECT bcs.brokerSplit as broker, + bcs.commercialLeadSplit as commercialLead, + bcs.payMargin + FROM ".TABLES['broker_commission_split']." bcs + WHERE idPackage=$idPackage"; + $commissionSplit = $database->fetchResultArray($sql); + + return !empty($commissionSplit) ? $commissionSplit[0] : []; + } + + /** + * get product prices list and comissions + * @param INT $idPackage id of the package + * @param BOOLEAN $getOnlySelectedTpes if true will return just prices set by the broker + * @return json list of prices and list of comission + */ + public function getPriceTypes($idPackage, $getOnlySelectedTpes = false){ + global $database; + $joinType = $getOnlySelectedTpes ? "INNER JOIN" : "LEFT OUTER JOIN"; + + $sql = "SELECT pt.id as idPaymentType, + pt.payType, + pt.packagePayPeriod, + pt.servicesContractPeriod, + pt.maxContractPeriod, + pt.periodUnit, + plb.minimalFixedPrice, + plb.principalAmount, + plb.minimalServicesPrice + FROM ".TABLES['payment_types']." pt + $joinType + (SELECT idPaymentType, + minimalFixedPrice, + principalAmount, + minimalServicesPrice + FROM ".TABLES['price_list_broker']." + WHERE idPackage=$idPackage) plb + ON pt.id=plb.idPaymentType"; + + $query = $database->query($sql); + while($row = $database->fetchArray($query)){ + $row['minimalRecurentPrice'] = $row['packagePayPeriod'] > 0 + ? $this->PMT($interestRateValue['interestRate'] / 100, $row['packagePayPeriod'], $row['principalAmount']) + : 0; + $row['minimalRecurentPrice'] = number_format($row['minimalRecurentPrice'], 2, '.', ''); + $data['priceTypes'][] = $row; + } + } + + /** + * get price list for commercial leads + * @param INT $idPackage id for packge + * @param INT $idCommercialLead id for commrcial lead or id for user , depends on $targetIdType + * @param String $targetIdType target for the id, userId=> id for the user, roleId => id for the role + * @return Array commercial lead price list + */ + public function getCommercialLeadPrices($idPackage = 0, $idCommercialLead = 0, $targetIdType = 'userId'){ + global $database, $user; + $idPackage = $database->escapeValue($idPackage); + $whereSql = ""; + $clPrices = []; + + if($idPackage){ + $whereSql .= " AND plcl.idPackage=$idPackage"; + } + + if($idCommercialLead){ + $whereSql .= $targetIdType === 'userId' ? " AND cl.idUser=$idCommercialLead" : " AND cl.id=$idCommercialLead"; + } + + $sql = "SELECT + plcl.id AS idPrice, + plcl.idPackage, + plcl.idPaymentType, + pt.payType, + IFNULL(plcl.idCustomer, 0) as idCustomer, + plcl.fixedExtra , + plcl.recurentExtra, + plcl.servicesExtra, + plcl.visibleToCustomer, + pt.packagePayPeriod + FROM ".TABLES['price_list_commercial_lead']." plcl + INNER JOIN ".TABLES['payment_types']." pt + ON pt.id = plcl.idPaymentType + INNER JOIN ".TABLES['commercial_leads']." cl + ON cl.id=plcl.idCommercialLead + WHERE 1=1 $whereSql"; + $query = $database->query($sql); + + while($row = $database->fetchArray($query)){ + $clPrices[$row['idPackage']][$row['idCustomer']][$row['idPaymentType']] = $row; + } + + return $clPrices; + } + + /** + * calculate total cost for a package + * @param HasArray $productsPrices product prices grouped by categoreis + * @return Float total cost + */ + public function calculatePackageTotalCost($productsPrices){ + $total = 0; + foreach ($productsPrices as $category) { + $total += $category['totalUnitCost']; + } + + return $total; + } + + /** + * calculate package total margin + * @param HashArray $payType pay type hash array (minimalFixedPrice and principalAmount keys required) + * @param Float $totalCost total cost for package + * @return Float package margin + */ + private function calculateMargin($payType, $totalCost){ + $totalGain = $payType['minimalFixedPrice'] + $payType['principalAmount']; + + return $totalGain - $totalCost; + } + + /** + * get price margins based on comission split + * @param HashArray $commisisonPercent commission split (commercialLead and broker keys requried) + * @param HashArray $payType pay type hash array (required to get the margin) + * @param Float $totalCost total cost for package + * @return HashArray margins per user role + */ + public function getPriceMargins($commisisonPercent, $payType, $totalCost){ + $margin = $this->calculateMargin($payType, $totalCost); + if($margin < 0){ + return [ + 'margin' => 0, + 'clMargin' => 0, + 'brokerMargin' => 0 + ]; + }else{ + return [ + 'margin' => $margin, + 'clMargin' => ($margin * $commisisonPercent['commercialLead'] / 100), + 'brokerMargin' => ($margin * $commisisonPercent['broker'] / 100) + ]; + } + } + + /** + * Copy of Excel's PMT function. + * Credit: http://thoughts-of-laszlo.blogspot.nl/2012/08/complete-formula-behind-excels-pmt.html + * + * @param double $interest The interest rate for the loan. + * @param int $num_of_payments The total number of payments for the loan in months. + * @param double $PV The present value, or the total amount that a series of future payments is worth now; + * Also known as the principal. + * @param double $FV The future value, or a cash balance you want to attain after the last payment is made. + * If fv is omitted, it is assumed to be 0 (zero), that is, the future value of a loan is 0. + * @param int $Type Optional, defaults to 0. The number 0 (zero) or 1 and indicates when payments are due. + * 0 = At the end of period + * 1 = At the beginning of the period + * + * @return float + */ + public function PMT($interest, $num_of_payments, $PV, $FV = 0.00, $Type = 0){ + /*$interest = $interest / 12; + $xp=pow((1+$interest),$num_of_payments); + return + ($PV* $interest*$xp/($xp-1)+$interest/($xp-1)*$FV)* + ($Type==0 ? 1 : 1/($interest+1));*/ + $rates = [ + 24 => 4.282, + 30 => 3.451, + 36 => 2.896, + 42 => 2.500, + 48 => 2.223, + 54 => 2.025, + 60 => 1.834 + ]; + + $interest = isset($rates[$num_of_payments]) ? $rates[$num_of_payments] : 10; + + return round($PV * ($interest / 100)); + } + + /** + * calculate fixed mortage based on principal amount + * @param HashArray $payType pay type hash array (principalAmount and packagePayPeriod keys required) + * @param Float $clMargin commercial lead margin + * @param Float $interestRate interest rate percent value + * @return Float fixed mortage formated to two decimals + */ + public function getRecurrentPriceMortage($payType, $clMargin, $interestRate){ + $newPrincipalAmount = $payType['principalAmount'] - $clMargin; + $interestRate = $interestRate / 100; + $fixedMortage = $this->PMT($interestRate, $payType['packagePayPeriod'], $newPrincipalAmount); + + return number_format($fixedMortage, 2, '.', ''); + } +} diff --git a/api-wiaas/server/components/v2/profileSettings/ProfileSettingsController.php b/api-wiaas/server/components/v2/profileSettings/ProfileSettingsController.php new file mode 100644 index 0000000..7417730 --- /dev/null +++ b/api-wiaas/server/components/v2/profileSettings/ProfileSettingsController.php @@ -0,0 +1,85 @@ +model = new ProfileSettingsModel(); + } + + /** + * get info for a user profile + * @return [type] json containg profile info + */ + public function getProfileInfo(){ + $idUser = isset($_REQUEST['idUser']) ? $_REQUEST['idUser'] : ''; + $json = json_encode($this->model->getProfileInfo($idUser), JSON_NUMERIC_CHECK); + echo preg_replace('/'.STRING_START.'/', '', $json); + } + + /** + * save info for profile + * @return [type] json containg update message + */ + public function saveProfileInfo(){ + $idUser = isset($_REQUEST['idUser']) ? $_REQUEST['idUser'] : ''; + $profile = isset($_REQUEST['profile']) ? $_REQUEST['profile'] : '[]'; + echo json_encode($this->model->saveProfileInfo($idUser, $profile), JSON_NUMERIC_CHECK); + } + + /** + * save company information + * @return [type] json containing update message + */ + public function saveCompanyInfo(){ + $companyInfo = isset($_REQUEST['companyInfo']) ? $_REQUEST['companyInfo'] : '[]'; + echo json_encode($this->model->saveCompanyInfo($companyInfo), JSON_NUMERIC_CHECK); + } + + /** + * remove delivery address + * @return json update message + */ + public function removeProfileAddress(){ + $idProfileAddress = isset($_REQUEST['idProfileAddress']) ? $_REQUEST['idProfileAddress'] : 0; + echo json_encode($this->model->removeProfileAddress($idProfileAddress), JSON_NUMERIC_CHECK); + } + + /** + * save delivery address + * @return json update message + */ + public function saveProfileAddress(){ + $profileAddress = isset($_REQUEST['profileAddress']) ? $_REQUEST['profileAddress'] : '[]'; + echo json_encode($this->model->saveProfileAddress($profileAddress), JSON_NUMERIC_CHECK); + } + + /** + * remove billing address + * @return json update message + */ + public function removeBillingAddress(){ + $idBillingAddress = isset($_REQUEST['idBillingAddress']) ? $_REQUEST['idBillingAddress'] : 0; + echo json_encode($this->model->removeBillingAddress($idBillingAddress), JSON_NUMERIC_CHECK); + } + + /** + * save billing address + * @return json update message + */ + public function saveBillingAddress(){ + $idCompany = isset($_REQUEST['idCompany']) ? $_REQUEST['idCompany'] : 0; + $billingAddress = isset($_REQUEST['billingAddress']) ? $_REQUEST['billingAddress'] : '[]'; + echo json_encode($this->model->saveBillingAddress($idCompany, $billingAddress), JSON_NUMERIC_CHECK); + } + + /** + * get countries array + * @return json countires array + */ + public function getCoutnries(){ + echo json_encode($this->model->getCoutnries(), JSON_NUMERIC_CHECK); + } +} diff --git a/api-wiaas/server/components/v2/profileSettings/ProfileSettingsModel.php b/api-wiaas/server/components/v2/profileSettings/ProfileSettingsModel.php new file mode 100644 index 0000000..4e63fff --- /dev/null +++ b/api-wiaas/server/components/v2/profileSettings/ProfileSettingsModel.php @@ -0,0 +1,238 @@ +query($sql); + $row = $database->fetchArray($query); + + return $row['type']; + } + + /** + * get profile info + * @param INT $idUser id user //broker can see data for all users + * @return HashArray user profile information including company information + */ + public function getProfileInfo($idUser){ + global $database, $user; + $userType = $user->getUserType(); + $targetUserType = ($userType === USER_TYPES['BROKER'] && $idUser != 0 ) ? $this->getUserTypeById($idUser) : $userType; + $idUser = $database->escapeValue($idUser); + if( intval($idUser) === 0){ + $idUser = $user->getUserId(); + } + $addresHelper = new AddressHelper(); + + $sql = "SELECT ui.id, + ui.name, + ui.phone, + u.mail, + u.isCompanyAdmin, + u.idCompany, + ut.idType AS idUserType, + c.name AS companyName, + c.vatCode + FROM ".$user->getTableByUser($targetUserType)." ui + INNER JOIN ".TABLES['users']." u + ON u.id=ui.idUser + INNER JOIN ".TABLES['rel_user_type']." ut + ON ut.idUser=u.id + LEFT OUTER JOIN ".TABLES['company']." c + ON u.idCompany=c.id + WHERE u.id=$idUser + "; + $query = $database->query($sql); + $row = $database->fetchArray($query); + if($row){ + $row['phone'] = STRING_START.$row['phone']; + if($userType === USER_TYPES['CUSTOMER']){ + $row['profileAddresses'] = $addresHelper->getDeliveryAddress(); + $row['billingAddresses'] = $addresHelper->getBillingAddress(); + } + $row['userType'] = $userType; + } + + return $row; + } + + /** + * save profile information + * @param INT $idUser id user + * @param Object $profile profile information to save + * @return Array save messages + */ + public function saveProfileInfo($idUser, $profile){ + global $database, $user; + $profile = json_decode($profile); + $userHelper = new UsersHelper(); + $userType = $user->getUserType(); + $targetUserType = ($userType === USER_TYPES['BROKER'] && $idUser != 0 ) ? $this->getUserTypeById($idUser) : $userType; + $idUser = $database->escapeValue($idUser); + if( intval($idUser) === 0){ + $idUser = $user->getUserId(); + } + $data = []; + + if(!$idUser || !$userHelper->checkRightsToEdit($idUser)) { + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_USER' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + if(!$profile){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_PROFILE_DATA' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $checkMessage = $userHelper->validateUserData('edit', $profile); + if(!empty($checkMessage)){ + return $checkMessage; + } + + $sql = "UPDATE ".$user->getTableByUser($targetUserType)." + SET name='".$profile->name."', + phone='".$profile->phone."' + WHERE id=".$profile->id; + + $query = $database->query($sql); + + if($database->affectedRows()) { + $mes = [ + 'code' => 'success', + 'message' => 'PROFILE_UPDATED' + ]; + }else{ + $mes = [ + 'code' => 'warning', + 'message' => 'PROFILE_NOT_CHANGED' + ]; + } + + $data['messages'][] = $mes; + + return $data; + } + + /** + * save company information + * @param Object $companyInfo copmany information + * @return Arary save messages + */ + public function saveCompanyInfo($companyInfo){ + global $database, $user; + $companyInfo = json_decode($companyInfo); + $userHelper = new UsersHelper(); + $data = []; + + if(!$userHelper->checkRightsToEditCompany($companyInfo->idCompany)){ + $err_mes = [ + 'code' => 'error', + 'message' => 'NOT_COMPANY_ADMIN' + ]; + $data['messages'][] = $err_mes; + + return $data; + } + + $checkMessage = $userHelper->validateCompanyData($companyInfo); + if(!empty($checkMessage)){ + return $checkMessage; + } + + $sql = "UPDATE ".TABLES['company']." + SET name='".$companyInfo->companyName."', + vatCode='".$companyInfo->vatCode."' + WHERE id=".$companyInfo->idCompany; + + $query = $database->query($sql); + + if($database->affectedRows()) { + $mes = [ + 'code' => 'success', + 'message' => 'COMPANY_UPDATED' + ]; + }else{ + $mes = [ + 'code' => 'warning', + 'message' => 'COMPANY_NOT_CHANGED' + ]; + } + + $data['messages'][] = $mes; + + return $data; + } + + /** + * remove delivery address + * @param INT $idProfileAddress id delivery address + * @return Array update message + */ + public function removeProfileAddress($idProfileAddress){ + $addresHelper = new AddressHelper(); + + return $addresHelper->removeProfileAddress($idProfileAddress); + } + + /** + * save delivery address + * @param Object $profileAddress delivery address information + * @return Array update message + */ + public function saveProfileAddress($profileAddress){ + $addresHelper = new AddressHelper(); + + return $addresHelper->saveProfileAddress($profileAddress); + } + + /** + * remove billing address + * @param INT $idBillingAddress billing address information + * @return Array update message + */ + public function removeBillingAddress($idBillingAddress){ + $addresHelper = new AddressHelper(); + + return $addresHelper->removeBillingAddress($idBillingAddress); + } + + /** + * save billing address + * @param INT $idCompany id for company + * @param Object $billingAddress billing address information\ + * @return Array update message + */ + public function saveBillingAddress($idCompany, $billingAddress){ + $addresHelper = new AddressHelper(); + + return $addresHelper->saveBillingAddress($idCompany, $billingAddress); + } + + /** + * get countires + * @return Array list of countries + */ + public function getCoutnries(){ + $countries= new Countries(); + + return $countries->getCountries(); + } + } diff --git a/api-wiaas/server/components/v2/terms/TermsController.php b/api-wiaas/server/components/v2/terms/TermsController.php new file mode 100644 index 0000000..13a701a --- /dev/null +++ b/api-wiaas/server/components/v2/terms/TermsController.php @@ -0,0 +1,30 @@ +model = new TermsModel(); + } + + /** + * output file content for pdf verison of terms and conditions + * @return file pdf file content + */ + public function pdfTerms(){ + header("Content-type: application/pdf"); + header("Content-Disposition: inline; filename=\"".APPLICATION_NAME." Terms and Conditions.pdf\""); + $idTerms = isset($_REQUEST['idTerms']) ? $_REQUEST['idTerms'] : 0; + echo $this->model->pdfTerms($idTerms); + } + + /** + * open shop page + */ + public function getTerms(){ + $idTerms = isset($_REQUEST['idTerms']) ? $_REQUEST['idTerms'] : 0; + echo json_encode($this->model->getTermsHTML($idTerms)); + } +} diff --git a/api-wiaas/server/components/v2/terms/TermsModel.php b/api-wiaas/server/components/v2/terms/TermsModel.php new file mode 100644 index 0000000..637b2fc --- /dev/null +++ b/api-wiaas/server/components/v2/terms/TermsModel.php @@ -0,0 +1,40 @@ +fetchResultArray($sql); + + return !empty($row) ? $row[0] : []; + } + + /** + * get pdf version for terms and conditions + * @return bloob hex for pdf file + */ + public function pdfTerms($idTerms){ + global $database; + $extraSql = intval($idTerms) === 0 ? "ORDER BY id DESC" : "WHERE id=$idTerms"; + + $sql = "SELECT pdf + FROM ".TABLES['terms']." + $extraSql + LIMIT 1"; + $pdf = $database->fetchResultArray($sql); + + return !empty($pdf) ? $pdf[0]['pdf'] : 'invalid pdf'; + } + } diff --git a/api-wiaas/server/components/v2/users/UsersHelper.php b/api-wiaas/server/components/v2/users/UsersHelper.php new file mode 100644 index 0000000..8585b8e --- /dev/null +++ b/api-wiaas/server/components/v2/users/UsersHelper.php @@ -0,0 +1,197 @@ +getUserType($idUser); + + if($userType === USER_TYPES['BROKER']){ + return true; + } + + return $idUser === $user->getUserId(); + } + + public function checkRightsToEditCompany($idCompany) { + global $database, $user; + $sql = "SELECT u.isCompanyAdmin + FROM ".TABLES['users']." u + WHERE u.id=".$user->getUserId()." AND u.idCompany=".$idCompany; + $query = $database->query($sql); + $row = $database->fetchArray($query); + + return $row ? $row['isCompanyAdmin'] === '1' : $user->getUserType() === USER_TYPES['BROKER']; + } + + /** + * validate user data from GUI + * @param Array $info all information about the company to be inserted/updated + * @return Array empty or error message + */ + public function validateCompanyData($info){ + global $database; + $data = []; + + foreach (get_object_vars($info) as $key => $value) { + $info->{$key} = $database->escapeValue($value); + } + + if(!isset($info->idCompany) || empty($info->idCompany)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_COMPANY' + ]; + + return $data; + } + + if(!isset($info->vatCode) || empty($info->vatCode)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_VAT' + ]; + + return $data; + } + + $checkMessage = $database->invalidLength('vatCode', $info->vatCode, 20); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!isset($info->companyName) || empty($info->companyName)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_COPMANY_NAME' + ]; + + return $data; + } + + $checkMessage = $database->invalidLength('companyName', $info->companyName, 100); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + return $data; + } + + /** + * validate user data from GUI + * @param String $action add or edit action + * @param Array $info all information about the user to be inserted/updated + * @param Array $commercialLeads all the commercial leads linked to a customer + * @return Array empty or error message + */ + public function validateUserData($action, $info, $commercialLeads = []) { + global $database; + $data = []; + + foreach (get_object_vars($info) as $key => $value) { + $info->{$key} = $database->escapeValue($value); + } + + if(!$info->idUserType) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'SELECT_USER_TYPE' + ]; + + return $data; + } + + if(!isset($info->name) || empty($info->name)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_NAME' + ]; + + return $data; + } + + $checkMessage = $database->invalidLength('name', $info->name, 200); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!isset($info->phone) || empty($info->phone)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_PHONE_NUMBER' + ]; + + return $data; + } + if(!preg_match('/^([0-9\(\)\/\+ \-]*)$/', $info->phone)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_PHONE_NUMBER' + ]; + } + + $checkMessage = $database->invalidLength('phone', $info->phone, 40); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if($action === 'add'){ + if($info->idUserType === '2' && empty($commercialLeads)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NO_COMMERCIAL_LEAD_LINK' + ]; + + return $data; + } + + if(!isset($info->username) || empty($info->username)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_USERNAME' + ]; + + return $data; + } + $checkMessage = $database->invalidLength('username', $info->username, 20); + if($checkMessage){ + $data['messages'][] = $checkMessage; + } + + if(!preg_match('/^[a-zA-Z\d\.\-_]+$/',$info->username)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_USERNAME' + ]; + } + + $sql = "SELECT username + FROM ".TABLES['users']." + WHERE username='".$info->username."' + LIMIT 1"; + $result = $database->query($sql); + if($database->numRows($result) > 0) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'USERNAME_EXISTS' + ]; + } + + if(!isset($info->mail) || empty($info->mail)) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ADD_MAIL' + ]; + + return $data; + } + if(!filter_var($info->mail, FILTER_VALIDATE_EMAIL)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_MAIL' + ]; + } + } + + return $data; + } + } diff --git a/api-wiaas/server/components/v2/utils/UtilsController.php b/api-wiaas/server/components/v2/utils/UtilsController.php new file mode 100644 index 0000000..c0cb06c --- /dev/null +++ b/api-wiaas/server/components/v2/utils/UtilsController.php @@ -0,0 +1,15 @@ +model = new UtilsModel(); + } + + public function downloadFile(){ + $fileName = isset($_REQUEST['fileName']) ? $_REQUEST['fileName'] : ''; + $idDocument = isset($_REQUEST['idDocument']) ? $_REQUEST['idDocument'] : 0; + $fileType = isset($_REQUEST['fileType']) ? $_REQUEST['fileType'] : ''; + echo $this->model->downloadFile($idDocument, $fileName, $fileType); + } +} diff --git a/api-wiaas/server/components/v2/utils/UtilsModel.php b/api-wiaas/server/components/v2/utils/UtilsModel.php new file mode 100644 index 0000000..e44d11d --- /dev/null +++ b/api-wiaas/server/components/v2/utils/UtilsModel.php @@ -0,0 +1,426 @@ +downloadFile($idDocument, $fileName, $fileType); + } + + public static function sendOrderUpdateMail($mailType, $params, $mailTitle, $mails) { + global $user; + $templateUrl = $mailType.'Template.php'; + + if(array_key_exists('customer', $mails) && count($mails['customer'])) { + $response = Mail::sendMail($mails['customer'], $mailTitle, $templateUrl, $params); + } + + if($user->getUserType() !== USER_TYPES['BROKER']) { + $usersMails = array_key_exists('other', $mails) ? (array) $mails['other'] : []; + $brokerMails = (array) self::getBrokersMail(); + $mails['other'] = array_merge($usersMails, $brokerMails); + $params['orderUrl'] = $params['apiOrderUrl']; + + $response = Mail::sendMail($mails['other'], $mailTitle, $templateUrl, $params); + } + + if($response){ + return [ + 'code' => 'success', + 'message' => 'ORDER_UPDATE_MAIL_SENT' + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + /** + * send order confirmation email to user + * @param Array $cartPackages contains the packages ordered + * @param String $userType customer or broker + * @param Array $orderInfo contains information about the order like id, order number and so on + * @return Array confirmation message + */ + public static function sendOrderConfirmationMail($cartPackages, $userType, $orderInfo) { + $mail = ''; + $orderUrl = WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$orderInfo['idOrder'].'&orderNumber='.$orderInfo['orderNumber']; + if($userType === USER_TYPES['CUSTOMER']) { + $templateUrl = 'orderConfirmationTemplate.php'; + $mailTitle = 'Order successfully placed'; + $userData = self::getUserData(); + + if($userData && $userData[0]['mail']) { + $mail = $userData[0]['mail']; + } + $message = 'MAIL_SENT'; + $orderUrl = WIAAS_URL.'/orders/'.$orderInfo['idOrder']; + } else if($userType === USER_TYPES['BROKER']){ + $templateUrl = 'orderConfirmationBrokerTemplate.php'; + $mailTitle = 'New order placed'; + $brokerData = self::getBrokersMail(); + + if($brokerData) { + $mail = $brokerData; + } + $message = 'BROKER_MAIL_SENT'; + } + $currentDate = new DateTime(); + $currentDate = $currentDate->format('d-m-Y H:i'); + + $params = [ + 'cartPackages' => $cartPackages, + 'currentDate' => $currentDate, + 'orderNumber' => $orderInfo['orderNumber'], + 'orderDate' => $orderInfo['orderDate'], + 'orderUrl' => $orderUrl + ]; + $response = Mail::sendMail($mail, $mailTitle, $templateUrl, $params); + + if($response){ + return [ + 'code' => 'success', + 'message' => $message + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + /** + * fetches the username and the email for the broker + * @return String mail of the broker + */ + public static function getBrokersMail() { + global $database; + + $sql=" + SELECT u.mail + FROM ".TABLES['brokers']." b + INNER JOIN ".TABLES['users']." u + ON u.id = b.idUser"; + + $result = $database->query($sql); + while($row = $database->fetchArray($result)) { + if($row['mail'] !== '') { + $mailArray[] = $row['mail']; + } + } + return (count($mailArray) === 0 || count($mailArray) > 1) ? $mailArray : $mailArray[0]; + } + + /** + * fetches the username and the email for the user logged in + * @return Array username and mail + */ + private static function getUserData($username = '') { + global $database, $user; + + $username = $username ? $username : $user->getUser(); + + $sql = "SELECT + u.mail, + u.username, + ut.type, + rut.idType AS idUserType + FROM ".TABLES['users']." u + INNER JOIN ".TABLES['rel_user_type']." rut + ON rut.idUser=u.id + INNER JOIN ".TABLES['user_types']." ut + ON ut.id = rut.idType + WHERE u.username='".$database->escapeValue($username)."'"; + + return $database->fetchResultArray($sql); + } + + /** + * generate a filter condition on gadget filter + * @param Array $filters array of filters + * @return string sql filter condtion + */ + public static function setFilterSql($filters){ + $whereSql = "1=1"; + + if(!empty($filters)){ + foreach ($filters as $key => $filterValue) { + $whereSql .= " AND $key like '%$filterValue%'"; + } + } + + return $whereSql; + } + + /** + * add sorting for orders central + * @param String $sortBy sql for order by + */ + public static function setOrderBySql($sortBy){ + $orderBySql = ""; + if(isset($sortBy->key) && isset($sortBy->direction) ){ + $orderBySql .= $sortBy->key." ".$sortBy->direction; + } + + return $orderBySql; + } + + /** + * changes the password for the current user + * @param String $password if empty, a random pass will be generated + * @return Array confirmation message + */ + public static function changePassword($passwords, $username = '') { + global $database, $user; + $passwords = (array) json_decode($passwords); + if($userInfo = self::getUserData($username)) { + $userInfo = $userInfo[0]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'WRONG_USERNAME' + ]; + + return $data; + } + $isForReset = $username ? true : false; + + if($data = self::validatePassword($userInfo['username'], $passwords, $isForReset)) { + return $data; + } + + $password = $passwords['newPassword']; + $passwordHashed = $user->hashPassword($database->escapeValue($password)); + + $sql = "UPDATE + ".TABLES['users']." u + SET + u.password='".$passwordHashed."', + u.token=null, + u.tokenTS=null + WHERE u.username='".$database->escapeValue($userInfo['username'])."'"; + + $result = $database->query($sql); + if($database->affectedRows() == 1) { + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'PASSWORD_GENERATED' + ]; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_PASSWORD_GENERATED' + ]; + } + $data['messages'][] = self::sendUserConfirmationMail($userInfo, $userInfo['mail'], 'change'); + + return $data; + } + + private static function validatePassword($username, $passwordData, $isForReset = false) { + global $database, $user; + $data = []; + + if ((!array_key_exists('newPassword', $passwordData) || $passwordData['newPassword'] === '') || + (!array_key_exists('confirmPassword', $passwordData) || $passwordData['confirmPassword'] === '')) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORDS_MISSING' + ]; + + return $data; + } + + $newPassword = $database->escapeValue($passwordData['newPassword']); + $confirmPassword = $database->escapeValue($passwordData['confirmPassword']); + + if(!$isForReset) { + if($data = self::validateOldPassword($passwordData, $username)) { + return $data; + } + $oldPassword = $database->escapeValue($passwordData['oldPassword']); + if($oldPassword === $newPassword) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORD_SAME' + ]; + return $data; + } + } + + if($newPassword !== $confirmPassword) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORD_MISMATCH' + ]; + + return $data; + } + + if((strlen($newPassword) < 8) || + !preg_match("/((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%-_]).{8,20})/", $newPassword) + ) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORD_INCORRECT' + ]; + } + + return $data; + } + + private static function validateOldPassword($passwordData, $username) { + global $database, $user; + $data = []; + + $oldPassword = $database->escapeValue($passwordData['oldPassword']); + + if (!array_key_exists('oldPassword', $passwordData) || $passwordData['oldPassword'] === '') { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'PASSWORDS_MISSING' + ]; + + return $data; + } + + $sql = "SELECT u.password + FROM ".TABLES['users']." u + WHERE u.username='".$database->escapeValue($username)."' + LIMIT 1"; + $row = $database->fetchResultArray($sql); + + if($row[0] && $row[0]['password'] && !password_verify($oldPassword, $row[0]['password'])) { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'OLD_PASSWORD_MISMATCH' + ]; + } + + return $data; + } + + /** + * send confirmation mail to user for creation + * @param Object $userInfo + * @param String $password + * @param String $mail + * @return Array confirmation message + */ + public static function sendUserConfirmationMail($userInfo, $mail, $action, $token = '') { + + switch($action) { + case 'create': + $mailTitle = APPLICATION_NAME.' user created'; + $templateUrl = 'createUserTemplate.php'; + break; + case 'generate': + $mailTitle = APPLICATION_NAME.' password generated'; + $templateUrl = 'generatePasswordUserTemplate.php'; + break; + case 'change': + $mailTitle = APPLICATION_NAME.' password changed'; + $templateUrl = 'changedPasswordTemplate.php'; + break; + default: + return [ + 'code' => 'error', + 'message' => 'ACTION_NOT_SET' + ]; + } + + $passwordValidationUrl = $userInfo['idUserType'] == self::ID_TYPE_CUSTOMER ? WIAAS_URL.'/changePassword/' . $token : WIAAS_URL.'/api-wiaas/login?token=' . $token; + + $params = [ + 'username' => $userInfo['username'], + 'wiaas' => $userInfo['type'] === USER_TYPES['CUSTOMER'] ? WIAAS_URL : WIAAS_URL.'/api-wiaas', + 'urlValidate' => $passwordValidationUrl + ]; + + $response = Mail::sendMail($mail, $mailTitle, $templateUrl, $params); + + if($response){ + return [ + 'code' => 'success', + 'message' => 'MAIL_SENT' + ]; + } + + return [ + 'code' => 'error', + 'message' => 'ERROR_MAIL_SENT' + ]; + } + + /** + * return true or false if the user logged in is a company admin or not + * @return Bool true if the user is company admin + */ + public static function checkIfUserIsCompanyAdmin() { + global $database, $user; + $idUser = $user->getUserId(); + + $sql = " + SELECT + u.isCompanyAdmin + FROM + ".TABLES['users']." u + WHERE u.id = $idUser"; + $data = $database->fetchResultArray($sql); + + return count($data) && $data[0]['isCompanyAdmin'] ? true : false; + } + + /** + * returns the mail and order number for an order + * @param Int $idOrder the id of the order + * @return Array mail of the customer and the order number + */ + public static function getDataForMailToCustomer($idOrder) { + global $database; + + $sqlCustomerInfo = " + SELECT u.mail, + o.orderNumber + FROM ".TABLES['customers']." c + INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc + ON c.id=rclc.idCustomer + INNER JOIN ".TABLES['users']." u + ON u.id = c.idUser + INNER JOIN ".TABLES['orders']." o + ON o.idCustomerInstance=rclc.id + WHERE o.id=$idOrder + LIMIT 1"; + $query = $database->query($sqlCustomerInfo); + + return $database->fetchArray($query); + } + + /** + * get the orderNumber based on the order id + * @param Int $idOrder the id of the order + * @return Int the order number of that order + */ + public static function getOrderNumberById($idOrder) { + global $database; + + $sql = " + SELECT + o.orderNumber + FROM + ".TABLES['orders']." o + WHERE o.id = $idOrder + LIMIT 1 + "; + $orderNumberArray = $database->fetchResultArray($sql); + if($orderNumberArray && $orderNumberArray[0]) { + return array_key_exists('orderNumber', $orderNumberArray[0]) ? $orderNumberArray[0]['orderNumber'] : ''; + } + + return ''; + } +} diff --git a/api-wiaas/server/components/v2/utils/mail_templates/changedPasswordTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/changedPasswordTemplate.php new file mode 100644 index 0000000..24e4ce6 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/changedPasswordTemplate.php @@ -0,0 +1,18 @@ + + + + + + + + Hello,

+ Welcome back to {APPLICATION_NAME}!
+ The password was changed successfully for {username}!

+ Please use this link to login: {wiaas}. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/createUserTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/createUserTemplate.php new file mode 100644 index 0000000..acb2d88 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/createUserTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ Welcome to {APPLICATION_NAME}!
+ Click on this link to set your password.
+ This link will expire after 5 days.

+ Please use this link to login: {wiaas}, after setting your password.
+ Your username is: {username}
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/customerScheduleInstallationEnabled.php b/api-wiaas/server/components/v2/utils/mail_templates/customerScheduleInstallationEnabled.php new file mode 100644 index 0000000..06194b5 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/customerScheduleInstallationEnabled.php @@ -0,0 +1,26 @@ + + + + + + + + Hello,

+ Welcome back to {APPLICATION_NAME}!
+ The schedule installation function for order {orderNumber} for package {packageName} is now active.

+ To propose a date for the installation, go to this link and click on Schedule installation button on the order details header.
+ There are displayed the earliest installation date (this is the date when all the products can be shipped in order to perform the installation),
+ the company which will perform the installation and the already proposed dates.
+ To propose a date, click on the Add optional date button and select a date which suites you to perform the installation.
+ Also the installation company user, {supplierName}, will propose a date/dates for its convenience.

+ After you propose a date, the installation company is notified, and he will accept or decline that date.
+ And reversed, if there is already a date proposed, you can accept or decline it.

+ Please note that there cannot be two dates accepted at the same time. If there is already an accepted date, and you accept another one, the first date accepted will be canceled and the last one will remain accepted.

+ You can access the application here.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/errorMailTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/errorMailTemplate.php new file mode 100644 index 0000000..be00a16 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/errorMailTemplate.php @@ -0,0 +1,11 @@ + + + + + + + + {errorMessage} + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/generatePasswordUserTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/generatePasswordUserTemplate.php new file mode 100644 index 0000000..4687f63 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/generatePasswordUserTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ Welcome back to {APPLICATION_NAME}!
+ You have requested a new password
+ Click on this link to reset your password. +
+ Your username is: {username}
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/installationAcceptedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/installationAcceptedTemplate.php new file mode 100644 index 0000000..f8d20fb --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/installationAcceptedTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ Installation date {acceptedDate} for order {orderNumber} was accepted by {actionDoneBy}.
+ You can go to {APPLICATION_NAME} to view more details.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/installationDateInvalidTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/installationDateInvalidTemplate.php new file mode 100644 index 0000000..af6fbf0 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/installationDateInvalidTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ The installation date accepted by both parties, {acceptedDate}, for order {orderNumber}, was marked invalid due to the confirmed shipping dates.
+ You can go to {APPLICATION_NAME} to propose new dates for the installation.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/installationDeclinedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/installationDeclinedTemplate.php new file mode 100644 index 0000000..0147075 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/installationDeclinedTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ All the proposed installation dates for order {orderNumber} were declined.
+ You can go to {APPLICATION_NAME} to propose new dates for the installation.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/installationProposedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/installationProposedTemplate.php new file mode 100644 index 0000000..5d8090e --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/installationProposedTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ {actionDoneBy} proposed a new installation date: {proposedDate} for order {orderNumber}.
+ Go to {APPLICATION_NAME} to plan the installation.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/installationSchedulingDisabled.php b/api-wiaas/server/components/v2/utils/mail_templates/installationSchedulingDisabled.php new file mode 100644 index 0000000..1716db8 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/installationSchedulingDisabled.php @@ -0,0 +1,18 @@ + + + + + + + + Hello,

+ The schedule installation function for order {orderNumber} is now disabled.

+ You will receive an email notification when this function will be re-actived.
+ Go to this link to see the status of your order.
+
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/invalidQuestionnaireTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/invalidQuestionnaireTemplate.php new file mode 100644 index 0000000..374705c --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/invalidQuestionnaireTemplate.php @@ -0,0 +1,19 @@ + + + + + + + + Hello,

+ The questionnaire you have uploaded for the order {orderNumber} need to be modified! Please see the comments on order.
+ Reason:
+ {invalidQuestionaireReason}

+ You can download the file using this link and upload it again using this link. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/lastStepCompletedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/lastStepCompletedTemplate.php new file mode 100644 index 0000000..ef35c47 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/lastStepCompletedTemplate.php @@ -0,0 +1,22 @@ + + + + + + + + Hello,
+
+ The order {orderNumber} has been updated in {currentDate}.
+ {prevStepMessage} + The delivery is now completed for the package: {packageName}. +
+
+ Access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/orderCommentAddedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/orderCommentAddedTemplate.php new file mode 100644 index 0000000..b85bfd8 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/orderCommentAddedTemplate.php @@ -0,0 +1,21 @@ + + + + + + + + Hello,
+
+ A new comment has been added by {userLoggedIn} for order {orderNumber} at {currentDate}:
+
+ {commentMessage}
+
+ You can access the order here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationBrokerTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationBrokerTemplate.php new file mode 100644 index 0000000..0c1a7d3 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationBrokerTemplate.php @@ -0,0 +1,17 @@ + + + + + + + + Hello,

+ An order has been placed successfully in {currentDate}.
+ Please go to {APPLICATION_NAME} to link a process to that package(s) from the order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationTemplate.php new file mode 100644 index 0000000..75ed3b8 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/orderConfirmationTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,

+ Your order has been successfully submitted: {currentDate}.
+ The order {orderNumber}, date: {orderDate} includes the following order rows:
+ {cartPackages} +
+ Access {APPLICATION_NAME} here to see the progress of your order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/orderStatusChangedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/orderStatusChangedTemplate.php new file mode 100644 index 0000000..913b7ce --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/orderStatusChangedTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,
+
+ Your order {orderNumber} has been set to: {status} in {currentDate}.
+ {deliveryEstimationDateMessage} +
+ You can access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/orderStepUpdatedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/orderStepUpdatedTemplate.php new file mode 100644 index 0000000..a6ebbbe --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/orderStepUpdatedTemplate.php @@ -0,0 +1,21 @@ + + + + + + + + Hello,

+ The order {orderNumber} has been updated {currentDate}.
+
+ {prevStepMessage} + {currentStepMessage} +
+ Access {APPLICATION_NAME} here to check the progress of the order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/packageStatusChangedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/packageStatusChangedTemplate.php new file mode 100644 index 0000000..7ff49b5 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/packageStatusChangedTemplate.php @@ -0,0 +1,20 @@ + + + + + + + + Hello,
+
+ The order row "{packageName}", of order {orderNumber}, has been changed to: {status} in {currentDate}.
+ {deliveryEstimationDateMessage} +
+ You can access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/processAssignedTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/processAssignedTemplate.php new file mode 100644 index 0000000..6cac2a8 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/processAssignedTemplate.php @@ -0,0 +1,19 @@ + + + + + + + + Hello,

+ We have now started processing the order {orderNumber} ({currentDate}).
+
+
+ Access {APPLICATION_NAME} here to check the progress of the order. +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/reUploadQuestionnaireTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/reUploadQuestionnaireTemplate.php new file mode 100644 index 0000000..79f9b1a --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/reUploadQuestionnaireTemplate.php @@ -0,0 +1,16 @@ + + + + + + + + Hello,

+ A new questionaire has been uploaded for the order {orderNumber} and needs validation! +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/scheduleMeetingTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/scheduleMeetingTemplate.php new file mode 100644 index 0000000..8e7a873 --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/scheduleMeetingTemplate.php @@ -0,0 +1,21 @@ + + + + + + + + Hello,
+
+ The order's {orderNumber} follow-up meeting date has changed in {currentDate}.
+ {estimatedDateMessage} + {confirmedDateMessage} +
+ You can access {APPLICATION_NAME} here to see more details. +
+
+ Best regards,
+ {APPLICATION_NAME} team + + + diff --git a/api-wiaas/server/components/v2/utils/mail_templates/supportMailTemplate.php b/api-wiaas/server/components/v2/utils/mail_templates/supportMailTemplate.php new file mode 100644 index 0000000..382257b --- /dev/null +++ b/api-wiaas/server/components/v2/utils/mail_templates/supportMailTemplate.php @@ -0,0 +1,59 @@ + + + + + + + + Hello,

+ {customerName} has sent an email for support for order {orderNumber}.
+
+

Customer details

+
+ Name: + {customerName} +
+
+ Mail: + {customerMail} +
+
+ Phone: + {customerPhone} +
+
+
+

Order details

+
+
+ # + Order number: {orderNumber} +
+
+ + Reference: {reference} +
+
+ + Tender: {tender} +
+
+ + Commercial lead: {commercialLead} +
+
+
+
+

Order Items

+ {orderItems} +
+
+

Customer's comment

+ {userText} +
+
+ Best regards,
+ {APPLICATION_NAME} administrators + + + diff --git a/api-wiaas/server/core/Database.php b/api-wiaas/server/core/Database.php new file mode 100644 index 0000000..ed36762 --- /dev/null +++ b/api-wiaas/server/core/Database.php @@ -0,0 +1,197 @@ +openConnection($server, $user, $password, $name); + } + + private function openConnection($server, $user, $password, $name){ + $this->mysqli = new mysqli($server, $user, $password, $name); + + if($this->mysqli->connect_error){ + trigger_error('Database connection failed!', E_USER_ERROR); + } + if (!$this->mysqli->set_charset("utf8")) { + trigger_error('Error loading character set '.$mysqli->error, E_USER_ERROR); + } + } + public function closeConnection(){ + if(isset($this->mysqli)){ + $closeResult = $this->mysqli->close(); + if($closeResult === false){ + trigger_error('Cannot close MySQL connection!', E_USER_ERROR); + } + } + } + + public function query($sql){ + $result= $this->mysqli->query($sql) ; + + if(!$result){ + $err_mes = 'Database query failed on line '.__LINE__.' in file '.__FILE__.'!
'; + $err_mes .= 'SQL:
'.$sql.'

'; + $err_mes .= 'Error: '.$this->mysqli->error.''; + var_dump(debug_backtrace()); + trigger_error($err_mes, E_USER_ERROR); + } + + return $result; + } + + public function escapeValue($value){ + $value=$this->mysqli->real_escape_string($value); + + return $value; + } + + public function prepare($sql){ + $query = $this->mysqli->prepare($sql); + + if(!$query) { + $err_mes = 'Database query failed on line '.__LINE__.' in file '.__FILE__.'!
'; + $err_mes .= 'SQL:
'.$sql.'

'; + $err_mes .= 'Error: '.$this->mysqli->error.''; + var_dump(debug_backtrace()); + trigger_error($err_mes, E_USER_ERROR); + } + + return $query; + } + + public function fetchArray($result_set){ + return $result_set->fetch_array(MYSQLI_ASSOC); + } + + public function fetchResultArray($sql){ + $query = $this->query($sql); + $data = []; + + while($row = $this->fetchArray($query)){ + array_push($data, $row); + } + + if($query){ + $query->close(); + } + + return $data; + } + + public function numRows($result_set){ + return $result_set->num_rows; + } + + public function affectedRows(){ + return $this->mysqli->affected_rows; + } + + public function getInsertId(){ + return $this->mysqli->insert_id; + } + + public function closeQuery($query){ + if($query){ + var_dump($query); + $query->close(); + } + } + + public function beginTransaction($mode = MYSQLI_TRANS_START_READ_WRITE){ + return $this->mysqli->begin_transaction(); + } + + public function commit(){ + return $this->mysqli->commit(); + } + + public function rollback(){ + return $this->mysqli->rollback(); + } + + /** + * check if empty value + * @param String $key key for translation + * @param String| INT| FLOAT $value value to be checked + * @return array error message array or null if passed + */ + public function isEmpty($key, $value){ + $err_mes = null; + + if($value === '' || $value === null){ + $err_mes = [ + 'code' => 'error', + 'message' => 'EMPTY_VALUE', + 'key' => $key + ]; + } + + return $err_mes; + } + + /** + * check lenght for value + * @param String $key key for translation + * @param String| INT| FLOAT $value value to be checked + * @param INT $maxChars maximum chatacters + * @return array error message array or null if passed + */ + public function invalidLength($key ,$value, $maxChars){ + $err_mes = null; + + if(strlen($value) > $maxChars){ + $err_mes = [ + 'code' => 'error', + 'message' => 'MAX_CHARACTERS', + 'key' => $key + ]; + } + + return $err_mes; + } + + /** + * check if number is to big or to low + * @param String $key key for translation + * @param INT| FLOAT $value value to be checked + * @param INT $min minimum value to cehck + * @param INT $max maximum value to cehck + * @return array error message array or null if passed + */ + public function invalidNumber($key, $value, $min, $max){ + $err_mes = null; + $value = filter_var($value, FILTER_VALIDATE_FLOAT); + + if(($value < $min || $value > $max) || $value === false){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_NUMBER', + 'key' => $key + ]; + } + + return $err_mes; + } + + public function invalidDate($key, $value, $delimiter = '-'){ + $err_mes = [ + 'code' => 'error', + 'message' => 'INVALID_DATE', + 'key' => $key + ]; + + $dateValues = explode($delimiter, $value); + + if(count($dateValues) !== 3){ + return $err_mes; + } + + if(!checkdate($dateValues[1], $dateValues[2], $dateValues[0])){ + return $err_mes; + } + + return null; + } + +} diff --git a/api-wiaas/server/core/ErrorHandler.php b/api-wiaas/server/core/ErrorHandler.php new file mode 100644 index 0000000..4cb4d0d --- /dev/null +++ b/api-wiaas/server/core/ErrorHandler.php @@ -0,0 +1,118 @@ +handler = set_error_handler(function($errno, $errstr, $errfile, $errline){ + self::myHandler($errno, $errstr, $errfile, $errline); + }); + error_reporting( E_ALL ); + ini_set('display_errors', 1); + } + + /** + * Custom error handler + * @param INT $errno error code + * @param String $errstr the error message + * @param String $errfile the file that triggered the error + * @param INT $errline line of code where error was triggered + * @return Boolean + */ + private static function myHandler($errno, $errstr, $errfile, $errline){ + if (!(error_reporting() & $errno)) { + return; + } + + header('Status: 500 Internal Server Error'); + header('HTTP/1.0 500 Internal Server Error'); + + switch ($errno) { + case E_USER_ERROR: + $err_mes = '
'; + $err_mes .= ''; + $err_mes .= "My ERROR [$errno] $errstr
". PHP_EOL; + $err_mes .= " Fatal error on line $errline in file $errfile"; + $err_mes .= ", PHP " . PHP_VERSION . " (" . PHP_OS . ")
". PHP_EOL; + $err_mes .= "Aborting...
" . PHP_EOL; + $err_mes .= '
'; + self::addLog($err_mes); + exit(1); + break; + + case E_USER_WARNING: + $err_mes = '
'; + $err_mes = "My WARNING [$errno] $errstr
". PHP_EOL; + $err_mes .= '
'; + self::addLog($err_mes); + break; + + case E_USER_NOTICE: + $err_mes = '
'; + $err_mes = "My NOTICE [$errno] $errstr
". PHP_EOL; + $err_mes .= '
'; + self::addLog($err_mes); + break; + + default: + $err_mes = '
'; + $err_mes .= ''; + $err_mes .= "My ERROR [$errno] $errstr
". PHP_EOL; + $err_mes .= " Fatal error on line $errline in file $errfile"; + $err_mes .= ", PHP " . PHP_VERSION . " (" . PHP_OS . ")
". PHP_EOL; + $err_mes .= "Aborting...
" . PHP_EOL; + $err_mes .= '
'; + self::addLog($err_mes); + exit(1); + break; + } + + return true; + } + + /** + * Subscribe fatal php errors + */ + private static function check_for_fatal(){ + $error = error_get_last(); + if ( $error["type"] == E_ERROR ) + self::myHandler( $error["type"], $error["message"], $error["file"], $error["line"] ); + } + + /** + * Adds the error message to a log file using the date of trigger + * @param String $err_mes the errror message to be added to the log + */ + public static function addLog($err_mes){ + if(APPLICATION_MODE !== 'PROD'){ + header('Content-Type: text/html; charset=utf-8'); + echo $err_mes; + }else{ + $errorDate = date('Y/m/d H:i:s'); + $today = getdate(); + $logDir = PATH_LOGS.$today['year'].'/'.$today['month'].'/'.$today['mday'].'/'; + if (!file_exists($logDir)) { + mkdir($logDir, 0777, true); + } + $logFile = $logDir.$today['hours'].'_'.$today['minutes'].'.log'; + $fileHandler = fopen($logFile, "a"); + + fwrite($fileHandler, $errorDate . PHP_EOL); + fwrite($fileHandler, $err_mes . PHP_EOL . PHP_EOL); + fclose($fileHandler); + + $friendlyErrorMessage = '
'; + $friendlyErrorMessage .= ''; + $friendlyErrorMessage .= ' There seems to be a problem with the page.'; + $friendlyErrorMessage .= ' An error message has been sent to the support team.'; + $friendlyErrorMessage .= ' In case the error persists please contact the support!'; + $friendlyErrorMessage .= '
'; + echo $friendlyErrorMessage; + } + } +} diff --git a/api-wiaas/server/core/FileManager.php b/api-wiaas/server/core/FileManager.php new file mode 100644 index 0000000..e5b3711 --- /dev/null +++ b/api-wiaas/server/core/FileManager.php @@ -0,0 +1,333 @@ +escapeValue($documentName); + $idDocumentType = $database->escapeValue($idDocumentType); + $visibleToCustomer = isset($visibleToCustomer) ? $database->escapeValue($visibleToCustomer) : 1; + + if(empty($file)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NO_FILE' + ]; + + return $data; + } + + $tmpName = $file['tmp_name']; + $ext = explode('.',$file['name']); + $ext = end($ext); + $errorCode = $file['error']; + + if($errorCode !== 0){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UPLOAD_ERROR' + ]; + + return $data; + } + + if(!$uploadedBy){ + $uploadedBy = $user->getUserId(); + } + + if(!$owner){ + $owner = "null"; + } + $sql = "SELECT dt.id AS idDocumentType, dt.folderName + FROM ".TABLES['document_types']." dt + WHERE id=$idDocumentType"; + $query = $database->query($sql); + if($database->numRows($query) !== 1){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'INVALID_DOCUMENT_TYPE' + ]; + + return $data; + } + $documentType = $database->fetchArray($query); + + $timestamp = time() . '_'. rand(1000,9999); + $documentPath = $documentType['folderName'].'/'.$timestamp. '.' .$ext; + $documentFullPath = PATH_UPLOAD.$documentPath; + $sql = "INSERT INTO ".TABLES['documents']." + (uploadedBy, idOwner, idDocumentType, documentName, documentPath, extension, visibleToCustomer) + VALUES($uploadedBy, $owner,'".$documentType['idDocumentType']."', '$documentName', '$documentPath', '$ext', $visibleToCustomer)"; + $query = $database->query($sql); + $idDocument = $database->getInsertId(); + $saveStatus = move_uploaded_file( $tmpName , $documentFullPath ); + if(!$saveStatus || $database->affectedRows() === 0){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UPLOAD_ERROR' + ]; + + return $data; + } + + $data['idDocument'] = $idDocument; + + return $data; + } + + /** + * update an existing document + * @param INT $idDocument id of the document + * @param file $file file to be uploaded + * @return Array Array with document id in case of success or error messages + */ + public function updateDocument($idDocument, $file, $documentName = ''){ + global $database, $user; + $data = []; + $idDocument = $database->escapeValue($idDocument); + $extraField = ''; + + if(empty($file)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'WRONG_FILE_TYPE' + ]; + + return $data; + } + + $sql = "SELECT d.documentPath + FROM ".TABLES['documents']." d + WHERE d.id=$idDocument + LIMIT 1"; + $query = $database->query($sql); + if($database->numRows($query) !== 1){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'FILE_NOT_EXISTS' + ]; + + return $data; + } + + $oldFile = $database->fetchArray($query); + $tmpName = $file['tmp_name']; + $ext = explode('.',$file['name']); + $ext = end($ext); + $errorCode = $file['error']; + + if($errorCode !== 0){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UPLOAD_ERROR' + ]; + + return $data; + } + + $documentPath = $oldFile['documentPath']; + $documentFullPath = PATH_UPLOAD.$documentPath; + $del_status = unlink($documentFullPath); + $saveStatus = move_uploaded_file($tmpName, $documentFullPath); + + if(!$saveStatus){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UPLOAD_ERROR' + ]; + + return $data; + } + + if($documentName) { + $extraField = ", documentName='".$documentName."'"; + } + + $sql = " + UPDATE ".TABLES['documents']." + SET extension='".$ext."' + $extraField + WHERE id=$idDocument"; + $query = $database->query($sql); + + $data['idDocument'] = $idDocument; + + return $data; + } + + /** + * download an existing file + * @param String $filePath path of the file + * @param String $fileName the name of the document after download + * @return octet-stream file to be downloaded + */ + public function downloadFile($idDocument, $fileName, $fileType=''){ + global $database, $user; + $whereSql = ""; + $userType = $user->getUserType(); + + if($userType !== USER_TYPES['BROKER'] && $fileType !== 'installationProtocol'){ + if($userType === USER_TYPES['CUSTOMER']) { + $whereSql = "AND d.visibleToCustomer = 1"; + } else { + $whereSql = "AND ( d.uploadedBy=".$user->getUserId()." OR d.uploadedBy IS NULL )"; + } + } + + $sql = "SELECT d.documentPath + FROM ".TABLES['documents']." d + WHERE d.id=$idDocument $whereSql"; + $query = $database->query($sql); + if($database->numRows($query) !== 1){ + trigger_error("Invalid document!", E_USER_ERROR); + } + + $document = $database->fetchArray($query); + + header('Content-Disposition: attachment;filename="'.$fileName.'"'); + header('Content-Type: application/octet-stream'); + ob_start(); + require(PATH_UPLOAD . $document['documentPath']); + + return ob_get_clean(); + } + + /** + * add a new type for a document + * @param String $documentNewType name for the new document type + */ + public function addNewDocumnetType($documentNewType){ + global $database; + $documentNewType = $database->escapeValue($documentNewType); + + if(!$documentNewType){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NO_TYPE_FOR_NEW' + ]; + + return $data; + } + + $folderName = ''; + $folderNamePieces = explode(' ',$documentNewType); + foreach ($folderNamePieces as $key => $value) { + $folderName .= $key === 0 ? $value : ucfirst($value) ; + } + $folderFullName = PATH_UPLOAD.$folderName; + if (file_exists($folderFullName)){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'TYPE_EXISTS' + ]; + + return $data; + } + + $createNewDir = mkdir($folderFullName, 0777); + + if(!$createNewDir){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'MKDIR_ERROR' + ]; + + return $data; + } + + $sql = "INSERT INTO ".TABLES['document_types']." + (type, folderName) + VALUES('$documentNewType', '$folderName')"; + $query = $database->query($sql); + + if($database->affectedRows() > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'NEW_TYPE_ADDED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'ERROR_NEW_TYPE' + ]; + } + + return $data; + } + + /** + * remove documents + * @param INT $idDocument id for the document + * @return Array delete message + */ + public function removeDocument($idDocument){ + global $database; + + if(!$idDocument){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'NO_SELECTION_FOR_REMOVE' + ]; + } + + $sql = "SELECT d.documentPath + FROM ".TABLES['documents']." d + WHERE d.id=$idDocument + LIMIT 1"; + $query = $database->query($sql); + if($database->numRows($query) !== 1){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'FILE_NOT_EXISTS' + ]; + + return $data; + } + + $documentPath = $database->fetchArray($query); + $documentFullPath = PATH_UPLOAD.$documentPath['documentPath']; + + $del_status = unlink($documentFullPath); + + if(!$del_status){ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UNABLE_TO_DELETE' + ]; + + return $data; + } + + $sqlDelete = "DELETE FROM ".TABLES['documents']." + WHERE id=$idDocument"; + $query = $database->query($sqlDelete); + $documentsDeleted = $database->affectedRows(); + + if($documentsDeleted > 0){ + $data['messages'][] = [ + 'code' => 'success', + 'message' => 'DOCUMENT_DELETED' + ]; + }else{ + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'UNABLE_TO_DELETE' + ]; + } + + return $data; + } + +} diff --git a/api-wiaas/server/core/HeadersHelper.php b/api-wiaas/server/core/HeadersHelper.php new file mode 100644 index 0000000..515f5ab --- /dev/null +++ b/api-wiaas/server/core/HeadersHelper.php @@ -0,0 +1,41 @@ + column_alias] + * @param string $type type of the return it can have values sql or array + * @return strin|array return sql header if type is sql and array of headers if type is array + */ + public function getHeader($headers = [], $type = 'array'){ + $method = 'generate' . ucfirst($type) . 'Header'; + return $this->{$method}($headers); + } + + /** + * generates required header string for an sql (columns to be fetch from DB) + * @param array $headers headers array + * @return string sql columns string + */ + private function generateSqlHeader($headers){ + $formattedHeader = ''; + foreach ($headers as $key => $value) { + $formattedHeader .= $key . ' AS ' . $value . ','; + } + return rtrim($formattedHeader, ','); + } + + /** + * generates an integer indexed array for the headers + * @param array $headers headers array + * @return array array of values for the header + */ + private function generateArrayHeader($headers){ + $formattedHeader = []; + foreach ($headers as $value) { + array_push($formattedHeader, $value); + } + + return $formattedHeader; + } + +} diff --git a/api-wiaas/server/core/Mail.php b/api-wiaas/server/core/Mail.php new file mode 100644 index 0000000..231b661 --- /dev/null +++ b/api-wiaas/server/core/Mail.php @@ -0,0 +1,76 @@ + $toMail) { + if($position === 0) { + $to = new SendGrid\Email(null, $toMail); + $multipleTos = true; + } else { + $email = new SendGrid\Email(null, $toMail); + $personalization->addTo($email); + } + } + } + } else { + $to = new SendGrid\Email(null, $toList); + } + + if(APPLICATION_MODE === 'PROD') { + $from = new SendGrid\Email(APPLICATION_NAME." Admin", ADMIN_MAIL); + $message = self::getTemplate($template); + $message = empty($tempalteParams) ? $message : self::replaceTemplateParams($message, $tempalteParams); + $content = new SendGrid\Content("text/html", $message); + + $mail = new SendGrid\Mail($from, $subject, $to, $content); + if($multipleTos) { + $mail->addPersonalization($personalization); + } + $sg = new \SendGrid(SENDGRID_API_KEY); + $response = $sg->client->mail()->send()->post($mail); + + $sendStatus = $response->statusCode() === 202; + + if(!$sendStatus){ + var_dump($response); + $err_mes = 'SendGrid failed to send the mail!'; + trigger_error($err_mes, E_USER_ERROR); + } + + return $sendStatus; + } else { + return true; + } + } +} diff --git a/api-wiaas/server/core/Routes.php b/api-wiaas/server/core/Routes.php new file mode 100644 index 0000000..a81071b --- /dev/null +++ b/api-wiaas/server/core/Routes.php @@ -0,0 +1,185 @@ +isLoggedIn() && !self::isAPiKeyValid($apiScriptKey)){ + $userInfo = self::$user->getUserInfo(); + $message = isset($userInfo) && isset($userInfo['errorMessage']) ? $userInfo['errorMessage'] : ''; + trigger_error("You need to login in order to access this module! $message", E_USER_ERROR); + } + + if (!method_exists ($controller, $action)){ + trigger_error("Module $action method not found for $controllerClassName!", E_USER_ERROR); + } + + if(!self::hasRightsForModule($module) && !self::isAPiKeyValid($apiScriptKey) && $module !== 'terms'){ + trigger_error("This module is not available!", E_USER_ERROR); + } + + if($action !== 'checkActivityStatus'){ + self::$user->setLastActivity(); + } + + $controller->{ $action }(); + } + + /** + * [loadClass description] + * @param String $fileName name of the full path to the file + * @return Boolean returns true if file is foound + */ + private static function loadClass($fileName){ + if ( file_exists($fileName) ){ + require_once($fileName); + return true; + } else { + return false; + } + } + + /** + *@param $className String name of the class to be autoloaded + */ + private static function autoloadClass($className){ + $isClassLoaded = false; + $apiPath = ROOT_DIR . PATH_COMPONENTS . self::$apiVersion .'/'; + $classFolders = scandir($apiPath); + + foreach ($classFolders as $folder) { + if (!in_array($folder, array(".",".."))){ + $fileName = $apiPath . $folder . '/' . ucfirst($className) .'.php'; + $isClassLoaded = self::loadClass($fileName); + if ($isClassLoaded){ + break; + } + } + } + + if(!$isClassLoaded){ + $fileName = ROOT_DIR . PATH_CORE . ucfirst($className) .'.php'; + if (!self::loadClass($fileName)){ + trigger_error("Module $fileName not found!", E_USER_ERROR); + } + } + } + + /** + * get all avaialable modules for user + * @return Array modules array + */ + public static function getModules(){ + global $database; + + $idUserType = self::$user->getIdUserType(); + $whereSql = self::$apiVersion === 'v1' ? "AND m.isInMenu=1" : "AND m.idParent IS NULL"; + + $sql = "SELECT + m.id, + m.name, + m.menuName, + m.url, + m.isInMenu + FROM ".TABLES['modules']." m + INNER JOIN ".TABLES['rel_user_types_modules']." um + ON m.id=um.idModule + WHERE + um.idUserType=".$idUserType." + AND um.idVersion='".self::$apiVersion."' + $whereSql + ORDER BY m.menuPosition"; + + $data['modules'] = $database->fetchResultArray($sql); + $data['subModules'] = self::$apiVersion === 'v1' ? [] : self::getSubModules(); + + return $data ? $data : []; + } + + /** + * get all avaialable subModules for selected module + * @return Array subModules array + */ + private static function getSubModules(){ + global $database; + $idUserType = self::$user->getIdUserType(); + + $sql = " + SELECT + parent.url AS moduleUrl, + m.menuName, + m.name, + m.url + FROM + ".TABLES['modules']." m + INNER JOIN + (SELECT + id, + url + FROM + ".TABLES['modules']." pm + INNER JOIN ".TABLES['rel_user_types_modules']." um + ON pm.id = um.idModule + WHERE um.idUserType = $idUserType + AND um.idVersion = '".self::$apiVersion."') parent + ON parent.id = m.idParent + WHERE m.isInMenu = 1 + ORDER BY m.menuPosition"; + $query = $database->query($sql); + while($row = $database->fetchArray($query)) { + $data[$row['moduleUrl']][] = $row; + } + + return $data ? $data : []; + } + + public static function hasRightsForModule($module){ + global $database; + + if($module === 'login' || $module === 'translate' || $module === 'utils') + return true; + + $idUserType = self::$user->getIdUserType(); + $sql = "SELECT m.id + FROM ".TABLES['modules']." m + INNER JOIN ".TABLES['rel_user_types_modules']." um + ON m.id=um.idModule + WHERE um.idUserType=".$idUserType." AND m.name='$module' + LIMIT 1"; + $query = $database->query($sql); + + return $database->numRows($query) === 1; + } + + public static function isAPiKeyValid($apiScriptKey){ + if($apiScriptKey === DASH_KEY){ + return true; + } + + return false; + } + +} diff --git a/api-wiaas/server/core/User.php b/api-wiaas/server/core/User.php new file mode 100644 index 0000000..bd13a18 --- /dev/null +++ b/api-wiaas/server/core/User.php @@ -0,0 +1,426 @@ + 'brokers', + 'customer' => 'customers', + 'commercial_lead' => 'commercial_leads', + 'supplier' => 'suppliers' + ]; + private static $validationUsername = ''; + + function __construct($authToken = null){ + if($authToken){ + self::$authToken = str_replace('Bearer ', '', $authToken); + self::$isLoggedIn = self::validateAccessToken(self::$authToken); + }else{ + self::$isLoggedIn = self::validateSession(); + } + } + + public function getTableByUser($userType){ + return self::$userTypesTableKeys[$userType]; + } + + private static function validateSession(){ + session_start(); + if(isset($_SESSION['data'])){ + self::$userInfo = $_SESSION['data']; + + return true; + } + + return false; + } + + private static function validateAccessToken($authToken){ + $secretKey = base64_decode(JWT_API_SECRET_KEY); + try { + $decodedJWT = JWT::decode($authToken, $secretKey, array(JWT_ALGORITHM)); + self::$userInfo = (array) $decodedJWT->data; + + return true; + + } catch (Exception $e) { + self::$userInfo['errorMessage'] = $e->getMessage(); + + return false; + } + } + + /** + * genereates a has for a password string. The value is 60 charactes MAX due to options + * @param String $password password to be hashed + * @return Sting 60 characters long hashed string + */ + public static function hashPassword($password){ + $hashOptions = [ + 'cost' => 12 + ]; + + return password_hash($password, PASSWORD_BCRYPT, $hashOptions); + } + + public static function generateApiToken($userInfo){ + $tokenId = base64_encode(random_bytes(32)); + $issuedAt = time(); + $notBefore = $issuedAt; + $expire = $notBefore + JWT_MAX_LIFE; // 1 hour + $serverName = WIAAS_URL; + $data = [ + 'iat' => $issuedAt, // Issued at: time when the token was generated + 'jti' => $tokenId, // Json Token Id: an unique identifier for the token + 'iss' => $serverName, // Issuer + 'nbf' => $notBefore, // Not before + 'exp' => $expire, // Expire + 'data' => $userInfo, + 'type' => 'authorization_token' //Token type + ]; + + $secretKey = base64_decode(JWT_API_SECRET_KEY); + $jwt = JWT::encode( + $data, + $secretKey, + JWT_ALGORITHM + ); + + return $jwt; + } + + public function getRefreshToken() { + global $database; + $sql = "SELECT u.refresh_token + FROM ".TABLES['users']." u + WHERE id=".self::$userInfo['wiaas_id_user']; + $result = $database->fetchResultArray($sql); + + return isset($result[0]) ? $result[0]['refresh_token'] : false; + } + + private static function saveRefreshToken($userInfo, $refreshJwt){ + global $database; + + $sql = "UPDATE ".TABLES['users']." + SET refresh_token='$refreshJwt' + WHERE id=".$userInfo['wiaas_id_user']; + $query = $database->query($sql); + + return $database->affectedRows() > 0; + } + + private static function generateRefreshToken($userInfo){ + global $user; + + $tokenId = base64_encode(random_bytes(32)); + $issuedAt = time(); + $notBefore = $issuedAt; + $expire = $notBefore + (JWT_MAX_LIFE * 2); // 1 hour + $serverName = WIAAS_URL; + $data = [ + 'iat' => $issuedAt, // Issued at: time when the token was generated + 'jti' => $tokenId, // Json Token Id: an unique identifier for the token + 'iss' => $serverName, // Issuer + 'nbf' => $notBefore, // Not before + 'exp' => $expire, // Expire + 'type' => 'refresh_token', //Token type + 'data' => $userInfo + ]; + + $secretKey = base64_decode(JWT_API_SECRET_KEY); + $jwt = JWT::encode( + $data, + $secretKey, + JWT_ALGORITHM + ); + + self::saveRefreshToken($userInfo, $jwt); + + return $jwt; + } + + public function getUserInfo() { + return self::$userInfo; + } + + /** + * reutnrs if user is logged in + * @return boolean returns if a user is logged in + */ + public static function isLoggedIn(){ + return self::$isLoggedIn; + } + + /** + * login processing + * @param String $username username + * @param String $password password + * @return boolean true if the user is logged in + */ + public static function login($username, $password, $withToken = false){ + global $database; + + $username = $database->escapeValue($username); + $password = $database->escapeValue($password); + + if(empty($username) OR empty($password)){ + return ['status' => 'fail', 'errorMessage' => 'INVALID_USERNAME_PASSWORD']; + } + + $sql = "SELECT u.id, u.username, u.password, ut.type, ut.id as idUserType, isCompanyAdmin + FROM ".TABLES['users']." u + INNER JOIN ".TABLES['rel_user_type']." rel_ut + ON rel_ut.idUser=u.id + INNER JOIN ".TABLES['user_types']." ut + ON ut.id=rel_ut.idType + WHERE u.username='".$username."' + LIMIT 1"; + $query = $database->query($sql); + + if($database->numRows($query) !== 1){ + self::$isLoggedIn = false; + + return ['status' => 'fail', 'errorMessage' => 'INVALID_USERNAME_PASSWORD']; + } + + $row = $database->fetchArray($query); + if(!password_verify($password, $row['password'])){ + return ['status' => 'fail', 'errorMessage' => 'INVALID_USERNAME_PASSWORD']; + } + + $userTypeInfo = self::getUserTypeInfo($row['id'], $row['type']); + + if(count($userTypeInfo) === 0){ + return ['status' => 'fail', 'errorMessage' => 'invalid user type '.$row['type'].'. Add type in User class or add the user in the correct table!']; + } + + self::$userInfo['wiaas_id_user'] = $row['id']; + self::$userInfo['wiaas_username'] = $row['username']; + self::$userInfo['wiaas_user_type'] = $row['type']; + self::$userInfo['wiaas_id_user_type'] = $row['idUserType']; + self::$userInfo['wiaas_user_full_name'] = $userTypeInfo['fullName']; + self::$userInfo['wiaas_is_company_admin'] = $row['isCompanyAdmin'] === '1' ? true : false; + + self::$isLoggedIn = true; + + if($withToken){ + self::$authToken = self::generateApiToken(self::$userInfo); + $refreshToken = self::generateRefreshToken(self::$userInfo); + + return ['status' => 'success', 'accessToken' => self::$authToken, 'refreshToken' => $refreshToken]; + }else{ + $_SESSION['data'] = self::$userInfo; + + return ['status' => 'success']; + } + + } + + public function refreshToken($refreshToken, $lastActivity){ + $inactivity = time() - (intval($lastActivity) / 1000); + $maxInactivity = 30 * 60; // 30 minutes + + if($inactivity > $maxInactivity){//session expires if invactivity is more than 30 minutes + return ['status' => 'error', 'errorMessage' => 'EXPIRED_SESSION']; + } + + if(self::validateAccessToken($refreshToken)){ + self::$authToken = self::generateApiToken(self::$userInfo); + $refreshToken = self::generateRefreshToken(self::$userInfo); + + return ['status' => 'success', 'accessToken' => self::$authToken, 'refreshToken' => $refreshToken]; + } + + return ['status' => 'error', 'errorMessage' => 'INVALID_REFRESH_TOKEN', 'extra' => $this->getErrorMessage()]; + } + + public static function setLastActivity(){ + $_SESSION['LAST_ACTIVITY'] = time(); + } + + public static function getLastActivity(){ + return $_SESSION['LAST_ACTIVITY']; + } + + /** + * get extra info for connected user by user type + * @param Int $idUser id of the user + * @param string $userType the type of the user + * @return [Array] retruns an empty array if no info or an array with the info + */ + private static function getUserTypeInfo($idUser, $userType){ + global $database; + + if(!array_key_exists($userType, self::$userTypesTableKeys)){ + return []; + } + + $sql = "SELECT info.name AS fullName + FROM ".TABLES[self::$userTypesTableKeys[$userType]]." info + WHERE idUser=".$idUser." + LIMIT 1"; + $query = $database->query($sql); + + if($database->numRows($query) !== 1){ + return []; + } + + $row = $database->fetchArray($query); + + return $row; + } + + public function logout(){ + session_unset(); + session_destroy(); + + header("location:index.php"); + } + + /** + * get the logged username + * @return String Username + */ + public function getUser(){ + return isset(self::$userInfo['wiaas_username']) ? self::$userInfo['wiaas_username'] : false; + } + + /** + * get the logged id user + * @return String id suer + */ + public function getUserId(){ + return isset(self::$userInfo['wiaas_id_user']) ? self::$userInfo['wiaas_id_user'] : 0; + } + + /** + * get the logged user full name + * @return String full name + */ + public function getUserFullName(){ + return isset(self::$userInfo['wiaas_user_full_name']) ? self::$userInfo['wiaas_user_full_name'] : false; + } + + /** + * get the user type + * @return String returns the user type + */ + public function getUserType(){ + return isset(self::$userInfo['wiaas_user_type']) ? self::$userInfo['wiaas_user_type'] : false; + } + + /** + * get the user type id + * @return String returns the user type id + */ + public function getIdUserType(){ + return isset(self::$userInfo['wiaas_id_user_type']) ? self::$userInfo['wiaas_id_user_type'] : 0; + } + + public function getErrorMessage(){ + return isset(self::$userInfo['errorMessage']) ? self::$userInfo['errorMessage'] : ''; + } + + + /** + * checks whether the token from the url provided is valid or not + * @param String $token the token to check the url for + * @return String confirmation message + */ + public function checkPasswordToken($token) { + global $database; + + $sql = "SELECT u.username + FROM ".TABLES['users']." u + WHERE u.token='".$database->escapeValue($token)."' + AND u.tokenTS <= DATE_ADD(u.tokenTS , INTERVAL 5 DAY)"; + + $result = $database->query($sql); + if($database->numRows($result) !== 1) { + return 'error'; + } + + self::$validationUsername = $database->fetchArray($result)['username']; + + return 'success'; + } + + /** + * gets the username of the user that wants to reset the password + * @return String username + */ + public function getSetPasswordUsername() { + return self::$validationUsername; + } + + /** + * Resets the password for the user with the right token number + * @param Array $passwords the new and confirmed passwords + * @return Array with confirmation message + */ + public function resetPassword($passwords) { + global $database; + $data = []; + + if(self::$validationUsername) { + $data = UtilsModel::changePassword($passwords, self::$validationUsername); + $data['username'] = self::$validationUsername; + self::$validationUsername = ''; + } else { + $data['messages'][] = [ + 'code' => 'error', + 'message' => 'USER_NOT_SET' + ]; + } + + return $data; + } + + /** + * generatates a new password for the user given + * @param String $mail email of the user + * @return String confirtmation message + */ + public static function forgotPassword($mail) { + global $database; + $mail = $database->escapeValue($mail); + $now = new DateTime(); + $now = $now->format('Y-m-d H:i:s'); + $data = []; + + $sql = "SELECT + u.username, + u.mail, + IF( + ADDTIME(u.tokenTS, '00:05') > '".$now."', + 0, + 1 + ) AS allowPasswordGeneration + FROM ".TABLES['users']." u + WHERE mail = '".$mail."'"; + + $userInfo = $database->fetchResultArray($sql); + + if(count($userInfo) == 0) { + $data[] = 'NO_USER'; + } + + foreach ($userInfo as $info) { + if($info['allowPasswordGeneration'] == 1) { + $messageData = UtilsModel::generateTokenForUserPassword(json_encode($info)); + + $data[] = 'SIGN_IN'; + } else { + $data[] = 'CHANGE_LATER'; + } + } + + return $data; + } +} diff --git a/client-wiaas/.gitignore b/client-wiaas/.gitignore new file mode 100644 index 0000000..f7373cf --- /dev/null +++ b/client-wiaas/.gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +/node_modules + +# testing +/coverage + +# production +/build + +# devBuild +*.css + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/client-wiaas/package-lock.json b/client-wiaas/package-lock.json new file mode 100644 index 0000000..fd4cc6d --- /dev/null +++ b/client-wiaas/package-lock.json @@ -0,0 +1,10989 @@ +{ + "name": "client-wiaas", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.32.tgz", + "integrity": "sha512-EVq4T1a2GviKiQ75OfxNrGPPhJyXzg9jjORuuwhloZbFdrhT4FHa73sv9OFWBwX7rl2b6bxBVmfxrBQYWYz9tA==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + } + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.32.tgz", + "integrity": "sha512-ysfIt7p72xm5fjSJsv7fMVN/j+EwIdqu8/MJjt6TqB4wM2r6rFRi0ujBTWDkLGQkRB/P5uDV8qcFCHAHnNzmsg==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.32", + "@babel/template": "7.0.0-beta.32", + "@babel/types": "7.0.0-beta.32" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.32.tgz", + "integrity": "sha512-bm7lIlizycJQY5SJ3HXWJV4XjSrOt1onzrDcOxUo9FEnKRZDEr/zfi5ar2s5tvvZvve/jGHwZKVKekRw2cjPCQ==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.32" + } + }, + "@babel/template": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.32.tgz", + "integrity": "sha512-DB9sLgX2mfE29vjAkxHlzLyWr31EO9HaYoAM/UsPSsL70Eudl0i25URwIfQT6S6ckeVFnFP1t6PhERVeV4EAHA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.32", + "@babel/types": "7.0.0-beta.32", + "babylon": "7.0.0-beta.32", + "lodash": "4.17.4" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.32.tgz", + "integrity": "sha512-PvAmyP2IJEBVAuE5yVzrTSWCCN9VMa1eGns8w3w6FYD/ivHSUmS7n+F40Fmjn+0nCQSUFR96wP0CqQ4jxTnF4Q==", + "dev": true + } + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.32.tgz", + "integrity": "sha512-dGe2CLduCIZ/iDkbmnqspQguRy5ARvI+zC8TiwFnsJ2YYO2TWK7x2aEwrbkSmi0iPlBP+Syiag7Idc1qNQq74g==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.32", + "@babel/helper-function-name": "7.0.0-beta.32", + "@babel/types": "7.0.0-beta.32", + "babylon": "7.0.0-beta.32", + "debug": "3.1.0", + "globals": "10.3.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.32.tgz", + "integrity": "sha512-PvAmyP2IJEBVAuE5yVzrTSWCCN9VMa1eGns8w3w6FYD/ivHSUmS7n+F40Fmjn+0nCQSUFR96wP0CqQ4jxTnF4Q==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-10.3.0.tgz", + "integrity": "sha512-1g6qO5vMbiPHbRTDtR9JVjRkAhkgH4nSANYGyx1eOfqgxcMnYMMD+7MjmjfzXjwFpVUE/7/NzF+jQxYE7P4r7A==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.32.tgz", + "integrity": "sha512-w8+wzVcYCMb9OfaBfay2Vg5hyj7UfBX6qQtA+kB0qsW1h1NH/7xHMwvTZNqkuFBwjz5wxGS2QmaIcC3HH+UoxA==", + "dev": true, + "requires": { + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@tinymce/tinymce-react": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tinymce/tinymce-react/-/tinymce-react-2.0.3.tgz", + "integrity": "sha512-3X9PSG+wET5jRMEUG0qFIuu91zcMiA7RbfFRBU3QrJcGkDB3mzjMIBI5+wBOXKTgI0vNps8wYJJrb2YOJ7Q9cw==", + "requires": { + "@types/prop-types": "15.5.2", + "@types/react": "16.0.25", + "@types/react-dom": "16.0.3", + "prop-types": "15.6.0", + "react": "16.0.0", + "react-dom": "16.0.0" + } + }, + "@types/lodash": { + "version": "4.14.85", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.85.tgz", + "integrity": "sha512-HrZiwDl62if0z31+rB99CLlg7WzS7b+KmyW75XAHEl/ZG0De2ACo6skZ89Zh3jOWkjKObN0Apq3MUezg7u9NKQ==" + }, + "@types/lodash.clonedeep": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.3.tgz", + "integrity": "sha512-307uNXpe90TSLRCZM2ggGtdzKZ2h4v1tDMDsahYI4/CvWd1+VhAmRQ+WJyA+wLF6kLLUae9JhpdKyLAzRaW3Qw==", + "requires": { + "@types/lodash": "4.14.85" + } + }, + "@types/node": { + "version": "8.0.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz", + "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ==" + }, + "@types/prop-types": { + "version": "15.5.2", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.2.tgz", + "integrity": "sha512-pQRkAVoxiuUrLq8+CDwiQX4pTCep/PmmNgBbjIwnnsd/HoYjGpR81+FFPE030lvNXgR0haaAU6eoRtztWDE4Xw==" + }, + "@types/react": { + "version": "16.0.25", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.0.25.tgz", + "integrity": "sha512-K79zMwWRzQ2db+nPoKpi3gA/KmLo6ZQgT4iO2QPEUdBO7as0PcgrmU9KHYzIO3V6lbD7gRjOM0/nUch6xBfOvQ==" + }, + "@types/react-dom": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.0.3.tgz", + "integrity": "sha512-xAvZiGhQlEhjStoKktoai8CelXVFBaSN6JX4vy1UQioRba3c2vum1TGzR0thHoEauZtIwzWg8mos0AHu2ne4jw==", + "requires": { + "@types/node": "8.0.53", + "@types/react": "16.0.25" + } + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==" + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + }, + "active-event-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/active-event-stack/-/active-event-stack-1.0.0.tgz", + "integrity": "sha1-a1uS661xmvrpgs1R9Jw4xbaADFA=", + "requires": { + "immutable": "3.8.2", + "lodash": "3.10.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "address": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.0.2.tgz", + "integrity": "sha1-SACB6CtYe6MZRZ/vUS9Rb+A9WK8=" + }, + "ajv": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.4.tgz", + "integrity": "sha1-Pa+ai2ciEpn9ro2C0RftjmyAJEs=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", + "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=" + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "anser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.1.tgz", + "integrity": "sha1-w2QYY6lizr75Qeoshwbyy08HFr0=" + }, + "ansi-align": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", + "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=", + "requires": { + "string-width": "1.0.2" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==" + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "requires": { + "default-require-extensions": "1.0.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.3" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "requires": { + "sprintf-js": "1.0.3" + } + }, + "aria-query": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.0.tgz", + "integrity": "sha512-/r2lHl09V3o74+2MLKEdewoj37YZqiQZnfen1O4iNlrOjUgeKuu1U2yF3iKh6HJxqF+OXkLMfQv65Z/cvxD6vA==", + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", + "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=" + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.9.0" + } + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "asn1.js": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "requires": { + "util": "0.10.3" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "ast-types": { + "version": "0.9.12", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.12.tgz", + "integrity": "sha1-sTYwDWcCZiWuFTJpgsqZGOXbc8k=", + "dev": true + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" + }, + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "requires": { + "lodash": "4.17.4" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "attr-accept": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.0.tgz", + "integrity": "sha1-tc01In8WOTWo8d4Q7T66FpQfa+Y=" + }, + "autoprefixer": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.2.tgz", + "integrity": "sha1-++rwfUj9h44Ggr98vurecorbKxg=", + "requires": { + "browserslist": "2.5.1", + "caniuse-lite": "1.0.30000749", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "axios": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.0.tgz", + "integrity": "sha1-fadHkW24A/dhZR1gkdcIeJuVPGo=", + "requires": { + "follow-redirects": "1.2.5", + "is-buffer": "1.1.5" + } + }, + "axobject-query": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz", + "integrity": "sha1-YvWdvFnJ+SQnWco0mWDnov48NsA=", + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-core": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", + "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.0", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-eslint": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.0.2.tgz", + "integrity": "sha512-yyl5U088oE+419+BNLJDKVWkUokuPLQeQt9ZTy9uM9kAzbtQgyYL3JkG425B8jxXA7MwTxnDAtRLMKJNH36qjA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.32", + "@babel/traverse": "7.0.0-beta.32", + "@babel/types": "7.0.0-beta.32", + "babylon": "7.0.0-beta.32" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.32", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.32.tgz", + "integrity": "sha512-PvAmyP2IJEBVAuE5yVzrTSWCCN9VMa1eGns8w3w6FYD/ivHSUmS7n+F40Fmjn+0nCQSUFR96wP0CqQ4jxTnF4Q==", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.7", + "trim-right": "1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "esutils": "2.0.2" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-20.0.3.tgz", + "integrity": "sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE=", + "requires": { + "babel-core": "6.25.0", + "babel-plugin-istanbul": "4.1.5", + "babel-preset-jest": "20.0.3" + } + }, + "babel-loader": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.1.tgz", + "integrity": "sha1-uHE0yLEuPkwqlOBUYIW8aAorhIg=", + "requires": { + "find-cache-dir": "1.0.0", + "loader-utils": "1.1.0", + "mkdirp": "0.5.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.0.2.tgz", + "integrity": "sha1-rbW8j0iokxFUA5WunwzD7UsQuy4=", + "requires": { + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-istanbul": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz", + "integrity": "sha1-Z2DN2Xf0EdPhdbsGTyvDJ9mbK24=", + "requires": { + "find-up": "2.1.0", + "istanbul-lib-instrument": "1.9.1", + "test-exclude": "4.1.1" + } + }, + "babel-plugin-jest-hoist": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz", + "integrity": "sha1-r+3IU70/jcNUjqZx++adA8wsF2c=" + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=" + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "requires": { + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "requires": { + "babel-plugin-syntax-flow": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz", + "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-constant-elements": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-constant-elements/-/babel-plugin-transform-react-constant-elements-6.23.0.tgz", + "integrity": "sha1-LxGb9NLN1F65uqrldAU8YE9hR90=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "requires": { + "babel-helper-builder-react-jsx": "6.26.0", + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", + "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", + "requires": { + "regenerator-transform": "0.9.11" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-preset-env": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.5.2.tgz", + "integrity": "sha1-zUrpCm6Utwn5c3SzPl+LmDVWre8=", + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1", + "browserslist": "2.5.1", + "invariant": "2.2.2", + "semver": "5.4.1" + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "requires": { + "babel-plugin-transform-flow-strip-types": "6.22.0" + } + }, + "babel-preset-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz", + "integrity": "sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o=", + "requires": { + "babel-plugin-jest-hoist": "20.0.3" + } + }, + "babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-plugin-transform-react-display-name": "6.25.0", + "babel-plugin-transform-react-jsx": "6.24.1", + "babel-plugin-transform-react-jsx-self": "6.22.0", + "babel-plugin-transform-react-jsx-source": "6.22.0", + "babel-preset-flow": "6.23.0" + } + }, + "babel-preset-react-app": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-3.0.3.tgz", + "integrity": "sha512-hK1hPq8xOFxmnNwpsOcQ2wSRAQwNBhDqsMV75gyKYQ7Z39KmTRpMN2Jx6Wp0Mberqd2QEWsUqd9ccP2jfd4z2Q==", + "requires": { + "babel-plugin-dynamic-import-node": "1.0.2", + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-plugin-transform-class-properties": "6.24.1", + "babel-plugin-transform-object-rest-spread": "6.23.0", + "babel-plugin-transform-react-constant-elements": "6.23.0", + "babel-plugin-transform-react-jsx": "6.24.1", + "babel-plugin-transform-react-jsx-self": "6.22.0", + "babel-plugin-transform-react-jsx-source": "6.22.0", + "babel-plugin-transform-regenerator": "6.24.1", + "babel-plugin-transform-runtime": "6.23.0", + "babel-preset-env": "1.5.2", + "babel-preset-react": "6.24.1" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "requires": { + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "core-js": "2.5.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + }, + "dependencies": { + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.0", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" + } + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + } + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + }, + "binary-extensions": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", + "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=" + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "2.0.3" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.15" + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "requires": { + "array-flatten": "2.1.1", + "deep-equal": "1.0.1", + "dns-equal": "1.0.0", + "dns-txt": "2.0.2", + "multicast-dns": "6.1.1", + "multicast-dns-service-types": "1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.0" + } + }, + "bootstrap": { + "version": "4.0.0-beta.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.0.0-beta.2.tgz", + "integrity": "sha512-DzGtdTlKbrMoGMpz0LigKSqJ+MgtFKxA791PU/q062OlRG0HybNZcTLH7rpDAmLS66Y3esN9yzKHLLbqa5UR3w==" + }, + "bowser": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.8.1.tgz", + "integrity": "sha512-NMPaR8ILtdLSWzxQtEs16XbxMcY8ohWGQ5V+TZSJS3fNUt/PBAGkF6YWO9B/4qWE23bK3o0moQKq8UyFEosYkA==" + }, + "boxen": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz", + "integrity": "sha1-g2TUJIrDT/DvGy8r9JpsYM4NgbY=", + "requires": { + "ansi-align": "1.1.0", + "camelcase": "2.1.1", + "chalk": "1.1.3", + "cli-boxes": "1.0.0", + "filled-array": "1.1.0", + "object-assign": "4.1.1", + "repeating": "2.0.1", + "string-width": "1.0.2", + "widest-line": "1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, + "browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "requires": { + "pako": "0.2.9" + } + }, + "browserslist": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.1.tgz", + "integrity": "sha512-jAvM2ku7YDJ+leAq3bFH1DE0Ylw+F+EQDq4GkqZfgPEqpWYw9ofQH85uKSB9r3Tv7XDbfqVtE+sdvKJW7IlPJA==", + "requires": { + "caniuse-lite": "1.0.30000749", + "electron-to-chromium": "1.3.27" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "requires": { + "node-int64": "0.4.0" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8", + "isarray": "1.0.0" + } + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "2.3.2", + "upper-case": "1.1.3" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + } + } + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000749", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "1.0.30000749", + "electron-to-chromium": "1.3.27" + } + } + } + }, + "caniuse-db": { + "version": "1.0.30000749", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000749.tgz", + "integrity": "sha1-VWdzqjqnBPWB10j6Y7RsoIeqxn0=" + }, + "caniuse-lite": { + "version": "1.0.30000749", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000749.tgz", + "integrity": "sha1-L/OChlrq2MyjXaz7qwT1jv+kwBw=" + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.1.tgz", + "integrity": "sha1-PSnO2MHxJL9vU4Rvs/WJRzH9yQk=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chain-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz", + "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "change-emitter": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", + "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "ci-info": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.1.tgz", + "integrity": "sha512-vHDDF/bP9RYpTWtUhpJRhCFdvvp3iDWvEbuDbWgvjUrNGV1MXJrE0MPcwGtEled04m61iwdBLUIHZtDgzWS4ZQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + }, + "clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "requires": { + "chalk": "1.1.3" + } + }, + "classnames": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", + "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" + }, + "clean-css": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz", + "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=", + "requires": { + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + } + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "requires": { + "q": "1.5.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "requires": { + "clone": "1.0.2", + "color-convert": "1.9.0", + "color-string": "0.3.0" + } + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "requires": { + "color-name": "1.1.3" + } + }, + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "requires": { + "color": "0.11.4", + "css-color-names": "0.0.4", + "has": "1.0.1" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "compressible": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz", + "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=", + "requires": { + "mime-db": "1.30.0" + } + }, + "compression": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz", + "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=", + "requires": { + "accepts": "1.3.4", + "bytes": "3.0.0", + "compressible": "2.0.12", + "debug": "2.6.9", + "on-headers": "1.0.1", + "safe-buffer": "5.1.1", + "vary": "1.1.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "configstore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", + "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=", + "requires": { + "dot-prop": "3.0.0", + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "os-tmpdir": "1.0.2", + "osenv": "0.1.4", + "uuid": "2.0.3", + "write-file-atomic": "1.3.4", + "xdg-basedir": "2.0.0" + }, + "dependencies": { + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + } + } + }, + "connect-history-api-fallback": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.4.0.tgz", + "integrity": "sha1-PbJPlz9LkjsOgvYZzg3wJBHKYj0=" + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "requires": { + "date-now": "0.1.4" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "content-type-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==" + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.7.0", + "minimist": "1.2.0", + "object-assign": "4.1.1", + "os-homedir": "1.0.2", + "parse-json": "2.2.0", + "require-from-string": "1.2.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "1.0.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "create-react-class": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz", + "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "crypto-browserify": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", + "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + }, + "css-in-js-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz", + "integrity": "sha512-yuWmPMD9FLi50Xf3k8W8oO3WM1eVnxEGCldCLyfusQ+CgivFk0s23yst4ooW6tfxMuSa03S6uUEga9UhX6GRrA==", + "requires": { + "hyphenate-style-name": "1.0.2" + } + }, + "css-loader": { + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.4.tgz", + "integrity": "sha1-bPNXkZLONV6LONX0Ldeh8uyJjQ8=", + "requires": { + "babel-code-frame": "6.26.0", + "css-selector-tokenizer": "0.7.0", + "cssnano": "3.10.0", + "icss-utils": "2.1.0", + "loader-utils": "1.1.0", + "lodash.camelcase": "4.3.0", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0", + "postcss-value-parser": "3.3.0", + "source-list-map": "0.1.8" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "1.0.0", + "css-what": "2.1.0", + "domutils": "1.5.1", + "nth-check": "1.0.1" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "requires": { + "cssesc": "0.1.0", + "fastparse": "1.1.1", + "regexpu-core": "1.0.0" + }, + "dependencies": { + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "requires": { + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + } + } + }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=" + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "requires": { + "autoprefixer": "6.7.7", + "decamelize": "1.2.0", + "defined": "1.0.0", + "has": "1.0.1", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-calc": "5.3.1", + "postcss-colormin": "2.2.2", + "postcss-convert-values": "2.6.1", + "postcss-discard-comments": "2.0.4", + "postcss-discard-duplicates": "2.1.0", + "postcss-discard-empty": "2.1.0", + "postcss-discard-overridden": "0.1.1", + "postcss-discard-unused": "2.2.3", + "postcss-filter-plugins": "2.0.2", + "postcss-merge-idents": "2.1.7", + "postcss-merge-longhand": "2.0.2", + "postcss-merge-rules": "2.1.2", + "postcss-minify-font-values": "1.0.5", + "postcss-minify-gradients": "1.0.5", + "postcss-minify-params": "1.2.2", + "postcss-minify-selectors": "2.1.1", + "postcss-normalize-charset": "1.1.1", + "postcss-normalize-url": "3.0.8", + "postcss-ordered-values": "2.2.3", + "postcss-reduce-idents": "2.4.0", + "postcss-reduce-initial": "1.0.1", + "postcss-reduce-transforms": "1.0.4", + "postcss-svgo": "2.1.6", + "postcss-unique-selectors": "2.0.2", + "postcss-value-parser": "3.3.0", + "postcss-zindex": "2.2.0" + }, + "dependencies": { + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000749", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "1.0.30000749", + "electron-to-chromium": "1.3.27" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "requires": { + "clap": "1.2.3", + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=" + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "requires": { + "cssom": "0.3.2" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "1.0.2" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "0.10.35" + } + }, + "damerau-levenshtein": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", + "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "date-fns": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", + "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==" + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-diff": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", + "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=" + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "default-gateway": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.6.1.tgz", + "integrity": "sha512-03hfY1Db+URp5NIrhlQPZrKlsr4jJbJAK1jnNSCvmNwzD0pPlvg2uqOwQpXQsDIGbUaBtkG2o7AKfBOLILzGXQ==", + "requires": { + "execa": "0.8.0", + "ip-regex": "2.1.0" + }, + "dependencies": { + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + } + } + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "requires": { + "strip-bom": "2.0.0" + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "requires": { + "repeating": "2.0.1" + } + }, + "detect-node": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", + "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=" + }, + "detect-port-alt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.3.tgz", + "integrity": "sha1-pNLwYddXoDTs83xRQmCph1DysTE=", + "requires": { + "address": "1.0.2", + "debug": "2.6.9" + } + }, + "diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==" + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.5" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + }, + "dns-packet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.2.2.tgz", + "integrity": "sha512-kN+DjfGF7dJGUL7nWRktL9Z18t1rWP3aQlyZdY8XlpvU3Nc6GeFTQApftcjtWKxAZfiggZSGrCEoszNgvnpwDg==", + "requires": { + "ip": "1.1.5", + "safe-buffer": "5.1.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "requires": { + "buffer-indexof": "1.1.1" + } + }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "dom-converter": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", + "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "requires": { + "utila": "0.3.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=" + } + } + }, + "dom-helpers": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.2.1.tgz", + "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo=" + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + } + } + }, + "dom-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dom-urls/-/dom-urls-1.1.0.tgz", + "integrity": "sha1-AB3fgWKM0ecGElxxdvU8zsVdkY4=", + "requires": { + "urijs": "1.19.0" + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=" + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" + }, + "domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "requires": { + "is-obj": "1.0.1" + } + }, + "dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "dynamics.js": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/dynamics.js/-/dynamics.js-1.1.5.tgz", + "integrity": "sha1-uQvcM2Bc7+ZSuEFucB95v27vzjI=" + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz", + "integrity": "sha1-eOy4o5kGYYe7N07t412ccFZagD0=" + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "emoji-regex": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", + "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==" + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.19" + } + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "requires": { + "prr": "0.0.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", + "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es5-ext": { + "version": "0.10.35", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", + "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", + "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==" + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", + "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "requires": { + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.5.7" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + } + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.4.1.tgz", + "integrity": "sha1-mc1+r8/8ov+Zpcj18qR01jZLS9M=", + "requires": { + "ajv": "5.2.4", + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "2.6.9", + "doctrine": "2.0.0", + "eslint-scope": "3.7.1", + "espree": "3.5.1", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.6", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "4.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.4.1", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + } + } + }, + "eslint-config-airbnb": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz", + "integrity": "sha512-zLyOhVWhzB/jwbz7IPSbkUuj7X2ox4PHXTcZkEmDqTvd0baJmJyuxlFPDlZOE/Y5bC+HQRaEkT3FoHo9wIdRiw==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "12.1.0" + } + }, + "eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "0.1.1" + } + }, + "eslint-config-react-app": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-2.0.1.tgz", + "integrity": "sha512-gHtkzfEjKXhgZJ0Bf+EmztFSWwTiMDgoy85sFaTqrxU1BHSJ9i4i/JJtXJofVCU/SOKxYs46LO3ajvuzFQH5rw==" + }, + "eslint-import-resolver-node": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", + "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", + "requires": { + "debug": "2.6.9", + "resolve": "1.4.0" + } + }, + "eslint-loader": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz", + "integrity": "sha512-40aN976qSNPyb9ejTqjEthZITpls1SVKtwguahmH1dzGCwQU/vySE+xX33VZmD8csU0ahVNCtFlsPgKqRBiqgg==", + "requires": { + "loader-fs-cache": "1.0.1", + "loader-utils": "1.1.0", + "object-assign": "4.1.1", + "object-hash": "1.2.0", + "rimraf": "2.6.2" + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "requires": { + "debug": "2.6.9", + "pkg-dir": "1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "1.1.2" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "2.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.35.0.tgz", + "integrity": "sha512-zjXGjOsHds8b84C0Ad3VViKh+sUA9PeXKHwPRlSLwwSX0v1iUJf/6IX7wxc+w2T2tnDH8PT6B/YgtcEuNI3ssA==", + "requires": { + "lodash": "4.17.4" + } + }, + "eslint-plugin-import": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", + "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.3.1", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.1.1.tgz", + "integrity": "sha512-5I9SpoP7gT4wBFOtXT8/tXNPYohHBVfyVfO17vkbC7r9kEIxYJF12D3pKqhk8+xnk12rfxKClS3WCFpVckFTPQ==", + "requires": { + "aria-query": "0.7.0", + "array-includes": "3.0.3", + "ast-types-flow": "0.0.7", + "axobject-query": "0.1.0", + "damerau-levenshtein": "1.0.4", + "emoji-regex": "6.5.1", + "jsx-ast-utils": "1.4.1" + } + }, + "eslint-plugin-node": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", + "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", + "requires": { + "ignore": "3.3.6", + "minimatch": "3.0.4", + "resolve": "1.4.0", + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "eslint-plugin-react": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", + "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", + "dev": true, + "requires": { + "doctrine": "2.0.0", + "has": "1.0.1", + "jsx-ast-utils": "2.0.1", + "prop-types": "15.6.0" + }, + "dependencies": { + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "3.0.3" + } + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", + "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", + "requires": { + "acorn": "5.1.2", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35" + } + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "requires": { + "duplexer": "0.1.1", + "from": "0.1.7", + "map-stream": "0.1.0", + "pause-stream": "0.0.11", + "split": "0.3.3", + "stream-combiner": "0.0.4", + "through": "2.3.8" + } + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=" + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "requires": { + "original": "1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "exec-sh": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", + "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", + "requires": { + "merge": "1.2.0" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "2.2.3" + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "1.0.1" + } + }, + "express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "requires": { + "accepts": "1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.2", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "1.3.1", + "type-is": "1.6.15", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + } + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "external-editor": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", + "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", + "requires": { + "iconv-lite": "0.4.19", + "jschardet": "1.5.1", + "tmp": "0.0.33" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "1.0.0" + } + }, + "extract-text-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.0.tgz", + "integrity": "sha1-kMqnkHvESfM1AF46x1MrQbAN5hI=", + "requires": { + "async": "2.5.0", + "loader-utils": "1.1.0", + "schema-utils": "0.3.0", + "webpack-sources": "1.0.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=" + }, + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "requires": { + "websocket-driver": "0.7.0" + } + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "requires": { + "bser": "2.0.0" + } + }, + "fbjs": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.17" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "file-loader": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.11.2.tgz", + "integrity": "sha512-N+uhF3mswIFeziHQjGScJ/yHXYt3DiLBeC+9vWW+WjUBiClMSOlV1YrXQi+7KM2aA3Rn4Bybgv+uXFQbfkzpvg==", + "requires": { + "loader-utils": "1.1.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "requires": { + "glob": "7.1.2", + "minimatch": "3.0.4" + } + }, + "filesize": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.10.tgz", + "integrity": "sha1-/I+iPdtO+eXgq24eZPZ5okpWdh8=" + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "filled-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz", + "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=" + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + } + }, + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "requires": { + "commondir": "1.0.1", + "make-dir": "1.1.0", + "pkg-dir": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "2.0.0" + } + }, + "flag-icon-css": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/flag-icon-css/-/flag-icon-css-2.8.0.tgz", + "integrity": "sha1-7BDCD+QXreeHoJUgBjAGnKQ2pWk=" + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + }, + "follow-redirects": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.5.tgz", + "integrity": "sha512-lMhwQTryFbG+wYsAIEKC1Kf5IGDlVNnONRogIBllh7LLoV7pNIxW0z9fhjRar9NBql+hd2Y49KboVVNxf6GEfg==", + "requires": { + "debug": "2.6.9" + } + }, + "font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "1.0.2" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "3.0.1", + "universalify": "0.1.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "gaze": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "requires": { + "globule": "1.2.0" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "2.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "1.0.2", + "is-windows": "1.0.1", + "resolve-dir": "1.0.1" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "2.0.2", + "homedir-polyfill": "1.0.1", + "ini": "1.3.4", + "is-windows": "1.0.1", + "which": "1.3.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "globule": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "requires": { + "glob": "7.1.2", + "lodash": "4.17.4", + "minimatch": "3.0.4" + } + }, + "got": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", + "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", + "requires": { + "create-error-class": "3.0.2", + "duplexer2": "0.1.4", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "node-status-codes": "1.0.0", + "object-assign": "4.1.1", + "parse-json": "2.2.0", + "pinkie-promise": "2.0.1", + "read-all-stream": "3.1.0", + "readable-stream": "2.3.3", + "timed-out": "3.1.3", + "unzip-response": "1.0.2", + "url-parse-lax": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + }, + "gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "requires": { + "duplexer": "0.1.1" + } + }, + "handle-thing": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", + "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=" + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + } + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.2.4", + "har-schema": "2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.0.2" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "history": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz", + "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==", + "requires": { + "invariant": "2.2.2", + "loose-envify": "1.3.1", + "resolve-pathname": "2.2.0", + "value-equal": "0.4.0", + "warning": "3.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + }, + "hoist-non-react-statics": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz", + "integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA=" + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "1.0.0" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "requires": { + "inherits": "2.0.3", + "obuf": "1.1.1", + "readable-stream": "2.3.3", + "wbuf": "1.7.2" + } + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=" + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "1.0.2" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, + "html-minifier": { + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.6.tgz", + "integrity": "sha512-88FjtKrlak2XjczhxrBomgzV4jmGzM3UnHRBScRkJcmcRum0kb+IwhVAETJ8AVp7j0p3xugjSaw9L+RmI5/QOA==", + "requires": { + "camel-case": "3.0.0", + "clean-css": "4.1.9", + "commander": "2.11.0", + "he": "1.1.1", + "ncname": "1.0.0", + "param-case": "2.1.1", + "relateurl": "0.2.7", + "uglify-js": "3.1.5" + } + }, + "html-webpack-plugin": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.29.0.tgz", + "integrity": "sha1-6Yf0IYU9O2k4yMTIFxhC5f0XryM=", + "requires": { + "bluebird": "3.5.1", + "html-minifier": "3.5.6", + "loader-utils": "0.2.17", + "lodash": "4.17.4", + "pretty-error": "2.1.1", + "toposort": "1.0.6" + }, + "dependencies": { + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" + } + } + } + }, + "htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.1.0", + "domutils": "1.1.6", + "readable-stream": "1.0.34" + }, + "dependencies": { + "domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "requires": { + "domelementtype": "1.3.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.3.1" + }, + "dependencies": { + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, + "http-parser-js": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", + "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=" + }, + "http-proxy": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "requires": { + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", + "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", + "requires": { + "http-proxy": "1.16.2", + "is-glob": "3.1.0", + "lodash": "4.17.4", + "micromatch": "2.3.11" + }, + "dependencies": { + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=" + }, + "hyphenate-style-name": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz", + "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=" + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "requires": { + "postcss": "6.0.13" + } + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + }, + "ignore": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.6.tgz", + "integrity": "sha512-HrxmNxKTGZ9a3uAl/FNG66Sdt0G9L4TtMbbUQjP1WhGmSj0FOyHvSgx7623aGJvXfPOur8MwmarlHT+37jmzlw==" + }, + "immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=" + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "2.0.1" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + }, + "inline-style-prefixer": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz", + "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=", + "requires": { + "bowser": "1.8.1", + "css-in-js-utils": "2.0.0" + } + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.2.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.0.5", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "chalk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz", + "integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "internal-ip": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-2.0.3.tgz", + "integrity": "sha512-XxJMiJOjXbb9LlwH6SVTsnUPymYACunXzKg3dqU+HIC+xYIkUhMyTiT/H6xxPmhlE4zHq50lKlx0CZlyN2C76Q==", + "requires": { + "default-gateway": "2.6.1", + "ipaddr.js": "1.5.2" + } + }, + "interpret": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", + "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=" + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "requires": { + "loose-envify": "1.3.1" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "1.10.0" + } + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "requires": { + "ci-info": "1.1.1" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "3.2.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "requires": { + "tryit": "1.0.3" + } + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, + "is-root": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", + "integrity": "sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "requires": { + "html-comment-regex": "1.1.1" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", + "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-api": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.2.1.tgz", + "integrity": "sha512-oFCwXvd65amgaPCzqrR+a2XjanS1MvpXN6l/MlMUTv6uiA1NOgGX+I0uyq8Lg3GDxsxPsaP1049krz3hIJ5+KA==", + "requires": { + "async": "2.5.0", + "fileset": "2.0.3", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-hook": "1.1.0", + "istanbul-lib-instrument": "1.9.1", + "istanbul-lib-report": "1.1.2", + "istanbul-lib-source-maps": "1.2.2", + "istanbul-reports": "1.1.3", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "once": "1.4.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==" + }, + "istanbul-lib-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz", + "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz", + "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==", + "requires": { + "babel-generator": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "istanbul-lib-coverage": "1.1.1", + "semver": "5.4.1" + } + }, + "istanbul-lib-report": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz", + "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==", + "requires": { + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz", + "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==", + "requires": { + "debug": "3.1.0", + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "source-map": "0.5.7" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "istanbul-reports": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz", + "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==", + "requires": { + "handlebars": "4.0.11" + } + }, + "jest": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-20.0.4.tgz", + "integrity": "sha1-PdJgwpidba1nix6cxNkZRPbWAqw=", + "requires": { + "jest-cli": "20.0.4" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, + "jest-cli": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.4.tgz", + "integrity": "sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM=", + "requires": { + "ansi-escapes": "1.4.0", + "callsites": "2.0.0", + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "is-ci": "1.0.10", + "istanbul-api": "1.2.1", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-instrument": "1.9.1", + "istanbul-lib-source-maps": "1.2.2", + "jest-changed-files": "20.0.3", + "jest-config": "20.0.4", + "jest-docblock": "20.0.3", + "jest-environment-jsdom": "20.0.3", + "jest-haste-map": "20.0.5", + "jest-jasmine2": "20.0.4", + "jest-message-util": "20.0.3", + "jest-regex-util": "20.0.3", + "jest-resolve-dependencies": "20.0.3", + "jest-runtime": "20.0.4", + "jest-snapshot": "20.0.3", + "jest-util": "20.0.3", + "micromatch": "2.3.11", + "node-notifier": "5.1.2", + "pify": "2.3.0", + "slash": "1.0.0", + "string-length": "1.0.1", + "throat": "3.2.0", + "which": "1.3.0", + "worker-farm": "1.5.0", + "yargs": "7.1.0" + } + } + } + }, + "jest-changed-files": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-20.0.3.tgz", + "integrity": "sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g=" + }, + "jest-config": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-20.0.4.tgz", + "integrity": "sha1-43kwqyIXyRNgXv8T5712PsSPruo=", + "requires": { + "chalk": "1.1.3", + "glob": "7.1.2", + "jest-environment-jsdom": "20.0.3", + "jest-environment-node": "20.0.3", + "jest-jasmine2": "20.0.4", + "jest-matcher-utils": "20.0.3", + "jest-regex-util": "20.0.3", + "jest-resolve": "20.0.4", + "jest-validate": "20.0.3", + "pretty-format": "20.0.3" + } + }, + "jest-diff": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-20.0.3.tgz", + "integrity": "sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc=", + "requires": { + "chalk": "1.1.3", + "diff": "3.4.0", + "jest-matcher-utils": "20.0.3", + "pretty-format": "20.0.3" + } + }, + "jest-docblock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz", + "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=" + }, + "jest-environment-jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz", + "integrity": "sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk=", + "requires": { + "jest-mock": "20.0.3", + "jest-util": "20.0.3", + "jsdom": "9.12.0" + } + }, + "jest-environment-node": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-20.0.3.tgz", + "integrity": "sha1-1Ii8RhKvLCRumG6K52caCZFj1AM=", + "requires": { + "jest-mock": "20.0.3", + "jest-util": "20.0.3" + } + }, + "jest-haste-map": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-20.0.5.tgz", + "integrity": "sha512-0IKAQjUvuZjMCNi/0VNQQF74/H9KB67hsHJqGiwTWQC6XO5Azs7kLWm+6Q/dwuhvDUvABDOBMFK2/FwZ3sZ07Q==", + "requires": { + "fb-watchman": "2.0.0", + "graceful-fs": "4.1.11", + "jest-docblock": "20.0.3", + "micromatch": "2.3.11", + "sane": "1.6.0", + "worker-farm": "1.5.0" + } + }, + "jest-jasmine2": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz", + "integrity": "sha1-/MWxQReA2RHQQpAu8YWehS5g1eE=", + "requires": { + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-matchers": "20.0.3", + "jest-message-util": "20.0.3", + "jest-snapshot": "20.0.3", + "once": "1.4.0", + "p-map": "1.2.0" + } + }, + "jest-matcher-utils": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz", + "integrity": "sha1-s6a443yld4A7CDKpixZPRLeBVhI=", + "requires": { + "chalk": "1.1.3", + "pretty-format": "20.0.3" + } + }, + "jest-matchers": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-20.0.3.tgz", + "integrity": "sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA=", + "requires": { + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-message-util": "20.0.3", + "jest-regex-util": "20.0.3" + } + }, + "jest-message-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-20.0.3.tgz", + "integrity": "sha1-auwoRDBvyw5udNV5bBAG2W/dgxw=", + "requires": { + "chalk": "1.1.3", + "micromatch": "2.3.11", + "slash": "1.0.0" + } + }, + "jest-mock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz", + "integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk=" + }, + "jest-regex-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz", + "integrity": "sha1-hburXRM+RGJbGfr4xqpRItCF12I=" + }, + "jest-resolve": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-20.0.4.tgz", + "integrity": "sha1-lEiz6La6/BVHlETGSZBFt//ll6U=", + "requires": { + "browser-resolve": "1.11.2", + "is-builtin-module": "1.0.0", + "resolve": "1.4.0" + } + }, + "jest-resolve-dependencies": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz", + "integrity": "sha1-bhSntxevDyyzZnxUneQK8Bexcjo=", + "requires": { + "jest-regex-util": "20.0.3" + } + }, + "jest-runtime": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-20.0.4.tgz", + "integrity": "sha1-osgCIZxCA/dU3xQE5JAYYWnRJNg=", + "requires": { + "babel-core": "6.25.0", + "babel-jest": "20.0.3", + "babel-plugin-istanbul": "4.1.5", + "chalk": "1.1.3", + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "jest-config": "20.0.4", + "jest-haste-map": "20.0.5", + "jest-regex-util": "20.0.3", + "jest-resolve": "20.0.4", + "jest-util": "20.0.3", + "json-stable-stringify": "1.0.1", + "micromatch": "2.3.11", + "strip-bom": "3.0.0", + "yargs": "7.1.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "jest-snapshot": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-20.0.3.tgz", + "integrity": "sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY=", + "requires": { + "chalk": "1.1.3", + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-util": "20.0.3", + "natural-compare": "1.4.0", + "pretty-format": "20.0.3" + } + }, + "jest-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-20.0.3.tgz", + "integrity": "sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0=", + "requires": { + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "jest-message-util": "20.0.3", + "jest-mock": "20.0.3", + "jest-validate": "20.0.3", + "leven": "2.1.0", + "mkdirp": "0.5.1" + } + }, + "jest-validate": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-20.0.3.tgz", + "integrity": "sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs=", + "requires": { + "chalk": "1.1.3", + "jest-matcher-utils": "20.0.3", + "leven": "2.1.0", + "pretty-format": "20.0.3" + } + }, + "js-base64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", + "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==" + }, + "js-file-download": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.1.tgz", + "integrity": "sha1-3g3S1mHVY19QanO5YqtY3bZQvts=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jschardet": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", + "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==" + }, + "jsdom": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", + "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", + "requires": { + "abab": "1.0.4", + "acorn": "4.0.13", + "acorn-globals": "3.1.0", + "array-equal": "1.0.0", + "content-type-parser": "1.0.2", + "cssom": "0.3.2", + "cssstyle": "0.2.37", + "escodegen": "1.9.0", + "html-encoding-sniffer": "1.0.2", + "nwmatcher": "1.4.3", + "parse5": "1.5.1", + "request": "2.83.0", + "sax": "1.2.4", + "symbol-tree": "3.2.2", + "tough-cookie": "2.3.3", + "webidl-conversions": "4.0.2", + "whatwg-encoding": "1.0.2", + "whatwg-url": "4.8.0", + "xml-name-validator": "2.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" + }, + "json-parse-better-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz", + "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=" + }, + "jwt-decode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", + "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" + }, + "keycode": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.1.9.tgz", + "integrity": "sha1-lkojxU5IiUBbSGGlyfBIDUUUHfo=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.5" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "latest-version": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", + "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=", + "requires": { + "package-json": "2.4.0" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lazy-req": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", + "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=" + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "1.0.0" + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "loader-fs-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz", + "integrity": "sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw=", + "requires": { + "find-cache-dir": "0.1.1", + "mkdirp": "0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "1.1.2" + } + } + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=" + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash-es": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz", + "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc=" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.isfunction": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.8.tgz", + "integrity": "sha1-TbcJ/IG8So/XEnpFilNGxc3OLGs=" + }, + "lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.mergewith": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=" + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.templatesettings": "4.1.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "requires": { + "lodash._reinterpolate": "3.0.0" + } + }, + "lodash.tonumber": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz", + "integrity": "sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "loglevel": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.5.1.tgz", + "integrity": "sha1-GJB4yUq5BT7iFaCs2/JCROoPZQI=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "macaddress": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", + "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=" + }, + "make-dir": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "requires": { + "pify": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.4" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=" + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mime": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz", + "integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA=" + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "moment": { + "version": "2.19.1", + "integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multicast-dns": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.1.1.tgz", + "integrity": "sha1-bn3oalcIcqsXBYrepxYLvsqBTd4=", + "requires": { + "dns-packet": "1.2.2", + "thunky": "0.1.0" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "nan": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", + "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=" + }, + "narcissus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/narcissus/-/narcissus-1.0.0.tgz", + "integrity": "sha1-JGKgfEWYzpBl60Gyq72zDQ4w9G4=", + "requires": { + "inline-style-prefixer": "3.0.8" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "ncname": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", + "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", + "requires": { + "xml-char-classes": "1.0.0" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "1.1.4" + } + }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "dev": true, + "requires": { + "minimatch": "3.0.4" + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "node-forge": { + "version": "0.6.33", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz", + "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=" + }, + "node-gyp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", + "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "requires": { + "fstream": "1.0.11", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.1.2", + "osenv": "0.1.4", + "request": "2.83.0", + "rimraf": "2.6.2", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-libs-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", + "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.1.4", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.11.1", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "0.0.1", + "os-browserify": "0.2.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.3", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "0.10.31", + "timers-browserify": "2.0.4", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "node-notifier": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", + "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", + "requires": { + "growly": "1.3.0", + "semver": "5.4.1", + "shellwords": "0.1.1", + "which": "1.3.0" + } + }, + "node-sass": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.6.0.tgz", + "integrity": "sha512-rh0CvkxpYdQdbWx4EQfunmG0+99BVyVwQHlFE+yUzc6lteF5K3WUcJ0bdmv9E9CqQA1RfuMyvmpDP99cmBObow==", + "requires": { + "async-foreach": "0.1.3", + "chalk": "1.1.3", + "cross-spawn": "3.0.1", + "gaze": "1.1.2", + "get-stdin": "4.0.1", + "glob": "7.1.2", + "in-publish": "2.0.0", + "lodash.assign": "4.2.0", + "lodash.clonedeep": "4.5.0", + "lodash.mergewith": "4.6.0", + "meow": "3.7.0", + "mkdirp": "0.5.1", + "nan": "2.7.0", + "node-gyp": "3.6.2", + "npmlog": "4.1.2", + "request": "2.83.0", + "sass-graph": "2.2.4", + "stdout-stream": "1.4.0" + }, + "dependencies": { + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "requires": { + "lru-cache": "4.1.1", + "which": "1.3.0" + } + } + } + }, + "node-sass-chokidar": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/node-sass-chokidar/-/node-sass-chokidar-0.0.3.tgz", + "integrity": "sha1-ukYO/kHI8UzoAKqjYGp6y7HmMNE=", + "requires": { + "async-foreach": "0.1.3", + "chokidar": "1.7.0", + "get-stdin": "4.0.1", + "glob": "7.1.2", + "meow": "3.7.0", + "node-sass": "4.6.0", + "sass-graph": "2.2.4", + "stdout-stream": "1.4.0" + } + }, + "node-status-codes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "4.1.1", + "prepend-http": "1.0.4", + "query-string": "4.3.4", + "sort-keys": "1.1.2" + } + }, + "npm-run-all": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz", + "integrity": "sha512-Z2aRlajMK4SQ8u19ZA75NZZu7wupfCNQWdYosIi8S6FgBdGf/8Y6Hgyjdc8zU2cYmIRVCx1nM80tJPkdEd+UYg==", + "requires": { + "ansi-styles": "3.2.0", + "chalk": "2.3.0", + "cross-spawn": "5.1.0", + "memorystream": "0.3.1", + "minimatch": "3.0.4", + "ps-tree": "1.1.0", + "read-pkg": "3.0.0", + "shell-quote": "1.6.1", + "string.prototype.padend": "3.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "4.0.0", + "pify": "3.0.0", + "strip-bom": "3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "requires": { + "load-json-file": "4.0.0", + "normalize-package-data": "2.4.0", + "path-type": "3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "2.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "requires": { + "boolbase": "1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nwmatcher": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.2.0.tgz", + "integrity": "sha512-smRWXzkvxw72VquyZ0wggySl7PFUtoDhvhpdwgESXxUrH7vVhhp9asfup1+rVLrhsl7L45Ee1Q/l5R2Ul4MwUg==" + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "obuf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz", + "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "1.1.0" + } + }, + "opn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", + "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "requires": { + "is-wsl": "1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "original": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", + "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=", + "requires": { + "url-parse": "1.0.5" + }, + "dependencies": { + "url-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz", + "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=", + "requires": { + "querystringify": "0.0.4", + "requires-port": "1.0.0" + } + } + } + }, + "os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==" + }, + "package-json": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", + "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", + "requires": { + "got": "5.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.4.1" + } + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "requires": { + "no-case": "2.3.2" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "requires": { + "asn1.js": "4.9.1", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=" + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "2.3.8" + } + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "2.1.0" + } + }, + "pluralize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz", + "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=" + }, + "popper.js": { + "version": "1.12.6", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.12.6.tgz", + "integrity": "sha512-wZlMkIJM1hFcM9F7nSrRCbKKfkH0kk/GrCoj3EUoKU8kx9xPtvnOZNHKsQOM12+xqbYv2HeBWI8Y8pxb6vmnRQ==" + }, + "portfinder": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", + "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "requires": { + "async": "1.5.2", + "debug": "2.6.9", + "mkdirp": "0.5.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + } + } + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "requires": { + "chalk": "2.2.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + }, + "dependencies": { + "chalk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz", + "integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + } + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "requires": { + "postcss": "5.2.18", + "postcss-message-helpers": "2.0.0", + "reduce-css-calc": "1.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "requires": { + "colormin": "1.1.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "requires": { + "postcss": "5.2.18", + "uniqs": "2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-filter-plugins": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", + "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "requires": { + "postcss": "5.2.18", + "uniqid": "4.1.1" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-flexbugs-fixes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-3.2.0.tgz", + "integrity": "sha512-0AuD9HG1Ey3/3nqPWu9yqf7rL0KCPu5VgjDsjf5mzEcuo9H/z8nco/fljKgjsOUrZypa95MI0kS4xBZeBzz2lw==", + "requires": { + "postcss": "6.0.13" + } + }, + "postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1", + "postcss-load-options": "1.2.0", + "postcss-load-plugins": "2.3.0" + } + }, + "postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-loader": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.6.tgz", + "integrity": "sha512-HIq7yy1hh9KI472Y38iSRV4WupZUNy6zObkxQM/ZuInoaE2+PyX4NcO6jjP5HG5mXL7j5kcNEl0fAG4Kva7O9w==", + "requires": { + "loader-utils": "1.1.0", + "postcss": "6.0.13", + "postcss-load-config": "1.2.0", + "schema-utils": "0.3.0" + } + }, + "postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "requires": { + "browserslist": "1.7.7", + "caniuse-api": "1.6.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3", + "vendors": "1.0.1" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "1.0.30000749", + "electron-to-chromium": "1.3.27" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "uniqs": "2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "requires": { + "alphanum-sort": "1.0.2", + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "requires": { + "postcss": "6.0.13" + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.13" + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.13" + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.13" + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "requires": { + "is-absolute-url": "2.1.0", + "normalize-url": "1.9.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "requires": { + "postcss": "5.2.18" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "requires": { + "is-svg": "2.1.0", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "svgo": "0.7.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "uniqs": "2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + }, + "postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "uniqs": "2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "pretty-bytes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=" + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "requires": { + "renderkid": "2.0.1", + "utila": "0.4.0" + } + }, + "pretty-format": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-20.0.3.tgz", + "integrity": "sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ=", + "requires": { + "ansi-regex": "2.1.1", + "ansi-styles": "3.2.0" + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" + } + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=" + }, + "ps-tree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", + "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "requires": { + "event-stream": "3.3.4" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "querystringify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", + "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=" + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "react": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz", + "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-addons-css-transition-group": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react-addons-css-transition-group/-/react-addons-css-transition-group-15.6.2.tgz", + "integrity": "sha1-nkN2vPQLUhfRTsaFUwgc7ksIptY=", + "requires": { + "react-transition-group": "1.2.1" + }, + "dependencies": { + "react-transition-group": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz", + "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==", + "requires": { + "chain-function": "1.0.0", + "dom-helpers": "3.2.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + } + } + }, + "react-autocomplete-cli": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/react-autocomplete-cli/-/react-autocomplete-cli-0.0.3.tgz", + "integrity": "sha1-DLy+GewtrpbIo3Y/yG+YDb3t/xo=", + "dev": true, + "requires": { + "react-docgen": "2.19.0", + "shelljs": "0.7.8", + "yargs": "4.8.1" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "lodash.assign": "4.2.0", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "lodash.assign": "4.2.0" + } + } + } + }, + "react-center-component": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-center-component/-/react-center-component-3.0.0.tgz", + "integrity": "sha1-0omGv0NOD46/9jyRJ38b9q0YnHI=", + "requires": { + "lodash": "4.17.4" + } + }, + "react-datepicker": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-0.61.0.tgz", + "integrity": "sha512-FJnqJCbYaU1ca7Jn9LaJ7iKTYHKAskVkVHCsOBDQd8vJZrESLAu3rtPbj3T6IB++dQO7qb0IlcCXtmC0geIAGA==", + "requires": { + "classnames": "2.2.5", + "eslint-plugin-import": "2.8.0", + "eslint-plugin-node": "5.2.1", + "moment": "2.19.3", + "prop-types": "15.6.0", + "react-onclickoutside": "6.7.0", + "react-popper": "0.7.4" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.3.1", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "moment": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz", + "integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "2.3.0" + } + }, + "react-onclickoutside": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.7.0.tgz", + "integrity": "sha512-IBivBP7xayM7SbbVlAnKgHgoWdfCVqnNBNgQRY5x9iFQm55tFdolR02hX1fCJJtTEKnbaL1stB72/TZc6+p2+Q==" + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "react-day-picker": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-7.0.5.tgz", + "integrity": "sha512-qebKK7d86OEuqpi4VlS7xrbyvVN1PJ4RIZE4gmnAAREWV8Iknw9VeeW/JxZ4Bu28D4Tp14CbtEhGsTqcuclECg==", + "requires": { + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-dev-utils": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-4.1.0.tgz", + "integrity": "sha512-41l8SUeYciCAiIyIpE/5e4ABeO7E6xhj5S3o+pBind9zKCue14Jaca+RcYwfwQtLA66BInCm5pgs1OzS5V7Wwg==", + "requires": { + "address": "1.0.2", + "babel-code-frame": "6.22.0", + "chalk": "1.1.3", + "cross-spawn": "5.1.0", + "detect-port-alt": "1.1.3", + "escape-string-regexp": "1.0.5", + "filesize": "3.5.10", + "global-modules": "1.0.0", + "gzip-size": "3.0.0", + "inquirer": "3.2.1", + "is-root": "1.0.0", + "opn": "5.1.0", + "react-error-overlay": "2.0.2", + "recursive-readdir": "2.2.1", + "shell-quote": "1.6.1", + "sockjs-client": "1.1.4", + "strip-ansi": "3.0.1", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", + "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "inquirer": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.1.tgz", + "integrity": "sha512-QgW3eiPN8gpj/K5vVpHADJJgrrF0ho/dZGylikGX7iqAdRgC9FVKYKWFLx6hZDBFcOLEoSqINYrVPeFAeG/PdA==", + "requires": { + "ansi-escapes": "2.0.0", + "chalk": "2.2.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.0.5", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "chalk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz", + "integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + } + } + }, + "react-dialog": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/react-dialog/-/react-dialog-1.0.2.tgz", + "integrity": "sha1-gT/tQPSSlGeTRqMpjUYPe5iCGAE=", + "requires": { + "active-event-stack": "1.0.0", + "classnames": "2.2.5", + "react-draggable": "2.2.6", + "react-onclickoutside": "5.11.1", + "react-resizable": "1.7.5" + } + }, + "react-docgen": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-2.19.0.tgz", + "integrity": "sha1-qeNWJ3qjH0LfFj8LSRfTsHeYX50=", + "dev": true, + "requires": { + "async": "2.5.0", + "babel-runtime": "6.26.0", + "babylon": "5.8.38", + "commander": "2.11.0", + "doctrine": "2.0.0", + "node-dir": "0.1.17", + "recast": "0.12.7" + }, + "dependencies": { + "babylon": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz", + "integrity": "sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=", + "dev": true + } + } + }, + "react-dom": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.0.0.tgz", + "integrity": "sha1-nMMHnD3NcNTG4BuEqrKn40wwP1g=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-draggable": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-2.2.6.tgz", + "integrity": "sha1-OoBuEPLaa6v+pBNr5lEOibDXaQE=", + "requires": { + "classnames": "2.2.5" + } + }, + "react-dropzone": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-4.2.3.tgz", + "integrity": "sha512-QAXuGDqBUPC0p560pskC3yyS8I1jJUnzvZC0PHrd5NayYBQRD4poQfM1D/bxg4jhUaFU4avNhOB3ehMQd4JMvA==", + "requires": { + "attr-accept": "1.1.0", + "prop-types": "15.6.0" + } + }, + "react-error-overlay": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-2.0.2.tgz", + "integrity": "sha512-TRt+Kqqa0YRJTYxnZ6syhZxLcfEQfnGuHrNxYNizs5FrxEHL8ZRVyb4wdkNzTJTMZxLwu6m+SIe/p9u5FgU6XQ==", + "requires": { + "anser": "1.4.1", + "babel-code-frame": "6.22.0", + "babel-runtime": "6.26.0", + "html-entities": "1.2.1", + "react": "16.0.0", + "react-dom": "16.0.0", + "settle-promise": "1.0.0", + "source-map": "0.5.6" + }, + "dependencies": { + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + } + } + }, + "react-infinite-calendar": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/react-infinite-calendar/-/react-infinite-calendar-2.3.1.tgz", + "integrity": "sha1-l/Y5g7PuHsDfR2s2uCJ8fbDtv4U=", + "requires": { + "classnames": "2.2.5", + "date-fns": "1.29.0", + "dom-helpers": "3.2.1", + "prop-types": "15.6.0", + "react-tiny-virtual-list": "2.1.4", + "react-transition-group": "1.2.1", + "recompose": "0.22.0" + }, + "dependencies": { + "react-transition-group": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz", + "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==", + "requires": { + "chain-function": "1.0.0", + "dom-helpers": "3.2.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + } + } + }, + "react-input-autosize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.0.1.tgz", + "integrity": "sha1-6SGQSXtAJsJ4CtDy/XA8g1ugPjM=", + "requires": { + "create-react-class": "15.6.2", + "prop-types": "15.6.0" + } + }, + "react-modal-dialog": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/react-modal-dialog/-/react-modal-dialog-4.0.7.tgz", + "integrity": "sha1-OSbaLfqR/wny0xSVSejW7ly62bU=", + "requires": { + "active-event-stack": "1.0.0", + "classnames": "2.2.5", + "dynamics.js": "1.1.5", + "immutable": "3.8.2", + "keycode": "2.1.9", + "lodash": "3.10.1", + "narcissus": "1.0.0", + "react-center-component": "3.0.0" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "react-notification": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/react-notification/-/react-notification-6.8.2.tgz", + "integrity": "sha512-7J0aSYWx4MLdiHOzLwRegH4kbDsYCTg/f/RVhk5SZhY8lc7lpy1OzHq5ENPD8hvc11OJrARlFRl+f+HzulAR0g==", + "requires": { + "prop-types": "15.6.0" + } + }, + "react-onclickoutside": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-5.11.1.tgz", + "integrity": "sha1-ADFOUlZ89V+rqUyrus0RlhkHBiM=", + "requires": { + "create-react-class": "15.6.2" + } + }, + "react-particles-js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-particles-js/-/react-particles-js-2.1.0.tgz", + "integrity": "sha512-rinI0uiH4C52ObZzGfg6113ygOH6tT1Gif0bTa8I21pUi3rCdupWSiMFWvu+MdnbRKssqfWAVY9I+5uO8qxPQg==", + "requires": { + "@types/lodash.clonedeep": "4.5.3", + "@types/node": "8.0.53", + "@types/react": "16.0.25", + "lodash.clonedeep": "4.5.0" + } + }, + "react-popper": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-0.7.4.tgz", + "integrity": "sha512-dx1fcKYYkidq7f71I1g+YX7g3QBLZ9taqiSRdJ7wbP7v/o7F6JsrUaNWGbVNul+TqdDDIZ5/k0xPUol9baqQJQ==", + "requires": { + "popper.js": "1.12.6", + "prop-types": "15.6.0" + } + }, + "react-redux": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz", + "integrity": "sha512-8taaaGu+J7PMJQDJrk/xiWEYQmdo3mkXw6wPr3K3LxvXis3Fymiq7c13S+Tpls/AyNUAsoONkU81AP0RA6y6Vw==", + "requires": { + "hoist-non-react-statics": "2.3.1", + "invariant": "2.2.2", + "lodash": "4.17.4", + "lodash-es": "4.17.4", + "loose-envify": "1.3.1", + "prop-types": "15.6.0" + } + }, + "react-resizable": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-1.7.5.tgz", + "integrity": "sha512-lauPcBsLqmxMHXHpTeOBpYenGalbSikYr8hK+lwtNYMQX1pGd2iYE+pDvZEV97nCnzuCtWM9htp7OpsBIY2Sjw==", + "requires": { + "prop-types": "15.6.0", + "react-draggable": "2.2.6" + } + }, + "react-router": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz", + "integrity": "sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg==", + "requires": { + "history": "4.7.2", + "hoist-non-react-statics": "2.3.1", + "invariant": "2.2.2", + "loose-envify": "1.3.1", + "path-to-regexp": "1.7.0", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + }, + "react-router-dom": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.2.2.tgz", + "integrity": "sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA==", + "requires": { + "history": "4.7.2", + "invariant": "2.2.2", + "loose-envify": "1.3.1", + "prop-types": "15.6.0", + "react-router": "4.2.0", + "warning": "3.0.0" + } + }, + "react-scripts": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-1.0.14.tgz", + "integrity": "sha512-+p0q2N2WW7L4WW6uObqN7fYwSQZ9fBI0StpMYl1Ukoz/lCbemf+yW6b8refyhTsGy62GAqxlpyEfVcTE3hJAxg==", + "requires": { + "autoprefixer": "7.1.2", + "babel-core": "6.25.0", + "babel-eslint": "7.2.3", + "babel-jest": "20.0.3", + "babel-loader": "7.1.1", + "babel-preset-react-app": "3.0.3", + "babel-runtime": "6.26.0", + "case-sensitive-paths-webpack-plugin": "2.1.1", + "chalk": "1.1.3", + "css-loader": "0.28.4", + "dotenv": "4.0.0", + "eslint": "4.4.1", + "eslint-config-react-app": "2.0.1", + "eslint-loader": "1.9.0", + "eslint-plugin-flowtype": "2.35.0", + "eslint-plugin-import": "2.7.0", + "eslint-plugin-jsx-a11y": "5.1.1", + "eslint-plugin-react": "7.1.0", + "extract-text-webpack-plugin": "3.0.0", + "file-loader": "0.11.2", + "fs-extra": "3.0.1", + "html-webpack-plugin": "2.29.0", + "jest": "20.0.4", + "object-assign": "4.1.1", + "postcss-flexbugs-fixes": "3.2.0", + "postcss-loader": "2.0.6", + "promise": "8.0.1", + "react-dev-utils": "4.1.0", + "style-loader": "0.18.2", + "sw-precache-webpack-plugin": "0.11.4", + "url-loader": "0.5.9", + "webpack": "3.5.1", + "webpack-dev-server": "2.8.2", + "webpack-manifest-plugin": "1.2.1", + "whatwg-fetch": "2.0.3" + }, + "dependencies": { + "babel-eslint": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "requires": { + "babel-code-frame": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0" + } + }, + "eslint-plugin-react": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.1.0.tgz", + "integrity": "sha1-J3cKzzn1/UnNCvQIPOWBBOs5DUw=", + "requires": { + "doctrine": "2.0.0", + "has": "1.0.1", + "jsx-ast-utils": "1.4.1" + } + }, + "promise": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.1.tgz", + "integrity": "sha1-5F1osAoXZHttpxG/he1u1HII9FA=", + "requires": { + "asap": "2.0.6" + } + } + } + }, + "react-select": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-1.0.0-rc.10.tgz", + "integrity": "sha1-8Tc0YlD5JVyXn7+iGGCJmSh3I1A=", + "requires": { + "classnames": "2.2.5", + "prop-types": "15.6.0", + "react-input-autosize": "2.0.1" + } + }, + "react-spinjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-spinjs/-/react-spinjs-3.0.0.tgz", + "integrity": "sha1-b9gY88kaXsbrwRc0ljEF+XGURzU=", + "requires": { + "spin.js": "2.3.2" + } + }, + "react-tiny-virtual-list": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/react-tiny-virtual-list/-/react-tiny-virtual-list-2.1.4.tgz", + "integrity": "sha512-9JvkWliho5SGHlv/uz3MuObUkg60SPvw3Ottvi/n4nl7qzBvxtb9oI8kJqI9sfZYYGy7xQLbTP0vGhqtnhA04Q==", + "requires": { + "prop-types": "15.6.0" + } + }, + "react-toastify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-2.2.0.tgz", + "integrity": "sha512-x06qactKsgVRggT2VMr0g/Q+GHCtxs+dsdFn+osLvNmoadSuCE4Gi35ZclsspxIwRyEHuxloYOeX0xILvuZxGg==", + "requires": { + "prop-types": "15.6.0", + "react-transition-group": "2.2.1" + } + }, + "react-transition-group": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.2.1.tgz", + "integrity": "sha512-q54UBM22bs/CekG8r3+vi9TugSqh0t7qcEVycaRc9M0p0aCEu+h6rp/RFiW7fHfgd1IKpd9oILFTl5QK+FpiPA==", + "requires": { + "chain-function": "1.0.0", + "classnames": "2.2.5", + "dom-helpers": "3.2.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + }, + "react-upload-file": { + "version": "2.0.0-beta.6", + "resolved": "https://registry.npmjs.org/react-upload-file/-/react-upload-file-2.0.0-beta.6.tgz", + "integrity": "sha1-cPOZDfEB6jed6q4rT+bgk4tUF7k=", + "requires": { + "react": "15.6.2" + }, + "dependencies": { + "react": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz", + "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=", + "requires": { + "create-react-class": "15.6.2", + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + } + } + }, + "reactjs-spinner": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reactjs-spinner/-/reactjs-spinner-2.0.0.tgz", + "integrity": "sha1-HBCc2DQ9xhDtDXxnVxNxpBvTFt8=", + "requires": { + "classnames": "2.2.5" + } + }, + "reactstrap": { + "version": "5.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-5.0.0-alpha.3.tgz", + "integrity": "sha1-0rRoIe/fjAUR1ZwQIPpM/aF0r8k=", + "requires": { + "classnames": "2.2.5", + "lodash.isfunction": "3.0.8", + "lodash.isobject": "3.0.2", + "lodash.tonumber": "4.0.3", + "prop-types": "15.6.0", + "react-popper": "0.7.4", + "react-transition-group": "2.2.1" + } + }, + "read-all-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", + "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", + "requires": { + "pinkie-promise": "2.0.1", + "readable-stream": "2.3.3" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "recast": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.12.7.tgz", + "integrity": "sha512-UgJBjELa0DaLUbblnIOPUj0UgdbetzYzrvWtHCXX8N5aCTHoMSx6ATkA2JH0hS7tP6dMJ5/CtVZEC4yW7V/8Dw==", + "dev": true, + "requires": { + "ast-types": "0.9.12", + "core-js": "2.5.1", + "esprima": "4.0.0", + "private": "0.1.8", + "source-map": "0.6.1" + }, + "dependencies": { + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", + "dev": true + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.4.0" + } + }, + "recompose": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.22.0.tgz", + "integrity": "sha1-8JnRg4WILKQdnuyJFxja3dwyBO8=", + "requires": { + "change-emitter": "0.1.6", + "fbjs": "0.8.16", + "hoist-non-react-statics": "1.2.0", + "symbol-observable": "1.0.4" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", + "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" + } + } + }, + "recursive-readdir": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.1.tgz", + "integrity": "sha1-kO8jHQd4xc4JPJpI105cVCLROpk=", + "requires": { + "minimatch": "3.0.3" + }, + "dependencies": { + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "1.1.8" + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "requires": { + "balanced-match": "0.4.2", + "math-expression-evaluator": "1.2.17", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "requires": { + "balanced-match": "0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + } + } + }, + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "requires": { + "lodash": "4.17.4", + "lodash-es": "4.17.4", + "loose-envify": "1.3.1", + "symbol-observable": "1.0.4" + } + }, + "redux-catch": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/redux-catch/-/redux-catch-1.3.1.tgz", + "integrity": "sha1-QDd3Yy5JXeOK2wlTwh9Eu6nR3gg=" + }, + "redux-logger": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", + "integrity": "sha1-91VZZvMJjzyIYExEnPC69XeCdL8=", + "requires": { + "deep-diff": "0.3.8" + } + }, + "redux-thunk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.2.0.tgz", + "integrity": "sha1-5hWhbha0ehmlFXZhM9Hj6Zt4UuU=" + }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==" + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + }, + "regenerator-transform": { + "version": "0.9.11", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", + "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "requires": { + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "registry-auth-token": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", + "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "requires": { + "rc": "1.2.2", + "safe-buffer": "5.1.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "1.2.2" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "renderkid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", + "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "requires": { + "css-select": "1.2.0", + "dom-converter": "0.1.4", + "htmlparser2": "3.3.0", + "strip-ansi": "3.0.1", + "utila": "0.3.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=" + } + } + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "2.0.2", + "global-modules": "1.0.0" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + }, + "resolve-pathname": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", + "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "sane": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-1.6.0.tgz", + "integrity": "sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U=", + "requires": { + "anymatch": "1.3.2", + "exec-sh": "0.2.1", + "fb-watchman": "1.9.2", + "minimatch": "3.0.4", + "minimist": "1.2.0", + "walker": "1.0.7", + "watch": "0.10.0" + }, + "dependencies": { + "bser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", + "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", + "requires": { + "node-int64": "0.4.0" + } + }, + "fb-watchman": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", + "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", + "requires": { + "bser": "1.0.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "requires": { + "glob": "7.1.2", + "lodash": "4.17.4", + "scss-tokenizer": "0.2.3", + "yargs": "7.1.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "requires": { + "ajv": "5.2.4" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "requires": { + "js-base64": "2.3.2", + "source-map": "0.4.4" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, + "selfsigned": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz", + "integrity": "sha1-v4y3uDJWxFUeMTR8YxF3jbme7FI=", + "requires": { + "node-forge": "0.6.33" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "5.4.1" + } + }, + "send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "requires": { + "debug": "2.6.9", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + }, + "dependencies": { + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + } + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "requires": { + "accepts": "1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "1.0.3", + "http-errors": "1.6.2", + "mime-types": "2.1.17", + "parseurl": "1.3.2" + } + }, + "serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.1" + } + }, + "serviceworker-cache-polyfill": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serviceworker-cache-polyfill/-/serviceworker-cache-polyfill-4.0.0.tgz", + "integrity": "sha1-3hnuc77yGrPAdAo3sz22JGS6ves=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "settle-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/settle-promise/-/settle-promise-1.0.0.tgz", + "integrity": "sha1-aXrbWLgh84fOJ1fAbvyd5fDuM9g=" + }, + "sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" + } + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.0.4", + "rechoir": "0.6.2" + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, + "sntp": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", + "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", + "requires": { + "hoek": "4.2.0" + } + }, + "sockjs": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz", + "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=", + "requires": { + "faye-websocket": "0.10.0", + "uuid": "2.0.3" + }, + "dependencies": { + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "requires": { + "websocket-driver": "0.7.0" + } + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + } + } + }, + "sockjs-client": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", + "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", + "requires": { + "debug": "2.6.9", + "eventsource": "0.1.6", + "faye-websocket": "0.11.1", + "inherits": "2.0.3", + "json3": "3.3.2", + "url-parse": "1.1.9" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "requires": { + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, + "spdy": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", + "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "requires": { + "debug": "2.6.9", + "handle-thing": "1.2.5", + "http-deceiver": "1.2.7", + "safe-buffer": "5.1.1", + "select-hose": "2.0.0", + "spdy-transport": "2.0.20" + } + }, + "spdy-transport": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz", + "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=", + "requires": { + "debug": "2.6.9", + "detect-node": "2.0.3", + "hpack.js": "2.1.6", + "obuf": "1.1.1", + "readable-stream": "2.3.3", + "safe-buffer": "5.1.1", + "wbuf": "1.7.2" + } + }, + "spin.js": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/spin.js/-/spin.js-2.3.2.tgz", + "integrity": "sha1-bKpW1SBnNFD9XPvGlx5tB3LDeho=" + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "requires": { + "through": "2.3.8" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + }, + "stdout-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "requires": { + "duplexer": "0.1.1" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "string-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "requires": { + "strip-ansi": "3.0.1" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.9.0", + "function-bind": "1.1.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "style-loader": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.18.2.tgz", + "integrity": "sha512-WPpJPZGUxWYHWIUMNNOYqql7zh85zGmr84FdTVWq52WTIkqlW9xSxD3QYWi/T31cqn9UNSsietVEgGn2aaSCzw==", + "requires": { + "loader-utils": "1.1.0", + "schema-utils": "0.3.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "2.0.0" + } + }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "requires": { + "coa": "1.0.4", + "colors": "1.1.2", + "csso": "2.3.2", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "sax": "1.2.4", + "whet.extend": "0.9.9" + } + }, + "sw-precache": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/sw-precache/-/sw-precache-5.2.0.tgz", + "integrity": "sha512-sKctdX+5hUxkqJ/1DM88ubQ+QRvyw7CnxWdk909N2DgvxMqc1gcQFrwL7zpVc87wFmCA/OvRQd0iMC2XdFopYg==", + "requires": { + "dom-urls": "1.1.0", + "es6-promise": "4.1.1", + "glob": "7.1.2", + "lodash.defaults": "4.2.0", + "lodash.template": "4.4.0", + "meow": "3.7.0", + "mkdirp": "0.5.1", + "pretty-bytes": "4.0.2", + "sw-toolbox": "3.6.0", + "update-notifier": "1.0.3" + } + }, + "sw-precache-webpack-plugin": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/sw-precache-webpack-plugin/-/sw-precache-webpack-plugin-0.11.4.tgz", + "integrity": "sha1-ppUBflTu1XVVFJOlGdwdqNotxeA=", + "requires": { + "del": "2.2.2", + "sw-precache": "5.2.0", + "uglify-js": "3.1.5" + } + }, + "sw-toolbox": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/sw-toolbox/-/sw-toolbox-3.6.0.tgz", + "integrity": "sha1-Jt8dHHA0hljk3qKIQxkUm3sxg7U=", + "requires": { + "path-to-regexp": "1.7.0", + "serviceworker-cache-polyfill": "4.0.0" + } + }, + "symbol-observable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", + "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "requires": { + "ajv": "5.2.4", + "ajv-keywords": "2.1.0", + "chalk": "2.2.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + }, + "dependencies": { + "chalk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz", + "integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + } + } + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=" + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "test-exclude": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "throat": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", + "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + }, + "time-stamp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz", + "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=" + }, + "timed-out": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", + "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=" + }, + "timers-browserify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", + "requires": { + "setimmediate": "1.0.5" + } + }, + "tinymce": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.7.4.tgz", + "integrity": "sha1-HX67GSqhwjjLn8g1A3bC6i77iJE=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + }, + "toposort": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", + "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=" + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "requires": { + "punycode": "1.4.1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=" + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "1.1.2" + } + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ua-parser-js": { + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" + }, + "uglify-js": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.5.tgz", + "integrity": "sha512-tSqlO7/GZHAVSw6mbtJt2kz0ZcUrKUH7Xg92o52aE+gL0r6cXiASZY4dpHqQ7RVGXmoQuPA2qAkG4TkP59f8XA==", + "requires": { + "commander": "2.11.0", + "source-map": "0.6.1" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "uniqid": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", + "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", + "requires": { + "macaddress": "0.2.8" + } + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unzip-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=" + }, + "update-notifier": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz", + "integrity": "sha1-j5LFFUgr1oMbfJMBPnD4dVLHz1o=", + "requires": { + "boxen": "0.6.0", + "chalk": "1.1.3", + "configstore": "2.1.0", + "is-npm": "1.0.0", + "latest-version": "2.0.0", + "lazy-req": "1.1.0", + "semver-diff": "2.1.0", + "xdg-basedir": "2.0.0" + } + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "urijs": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.0.tgz", + "integrity": "sha512-Qs2odXn0hST5VSPVjpi73CMqtbAoanahaqWBujGU+IyMrMqpWcIhDewxQRhCkmqYxuyvICDcSuLdv2O7ncWBGw==" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-loader": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.9.tgz", + "integrity": "sha512-B7QYFyvv+fOBqBVeefsxv6koWWtjmHaMFT6KZWti4KRw8YUD/hOU+3AECvXuzyVawIBx3z7zQRejXCDSO5kk1Q==", + "requires": { + "loader-utils": "1.1.0", + "mime": "1.3.6" + } + }, + "url-parse": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.9.tgz", + "integrity": "sha1-xn8dd11R8KGJEd17P/rSe7nlvRk=", + "requires": { + "querystringify": "1.0.0", + "requires-port": "1.0.0" + }, + "dependencies": { + "querystringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", + "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=" + } + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "1.0.4" + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "value-equal": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", + "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vendors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", + "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "requires": { + "indexof": "0.0.1" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.11" + } + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "1.3.1" + } + }, + "watch": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", + "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=" + }, + "watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "requires": { + "async": "2.5.0", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + } + }, + "wbuf": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", + "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=", + "requires": { + "minimalistic-assert": "1.0.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "webpack": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.5.1.tgz", + "integrity": "sha1-t0nuPStaEY2tU+jkFYWz9x51SZo=", + "requires": { + "acorn": "5.1.2", + "acorn-dynamic-import": "2.0.2", + "ajv": "5.2.4", + "ajv-keywords": "2.1.0", + "async": "2.5.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.0.4", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.0.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.4.0", + "webpack-sources": "1.0.1", + "yargs": "8.0.2" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz", + "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=", + "requires": { + "memory-fs": "0.4.1", + "mime": "1.3.6", + "path-is-absolute": "1.0.1", + "range-parser": "1.2.0", + "time-stamp": "2.0.0" + } + }, + "webpack-dev-server": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.8.2.tgz", + "integrity": "sha512-wD9bs+Z1uwvf3Jc+8ZkyMI0Xi+aJJYjC2UZplOWoo/vStelK5Mv62X2uXYEYIQEjy9wJQMzC0fEFqQsg7vVEIg==", + "requires": { + "ansi-html": "0.0.7", + "array-includes": "3.0.3", + "bonjour": "3.5.0", + "chokidar": "1.7.0", + "compression": "1.7.1", + "connect-history-api-fallback": "1.4.0", + "del": "3.0.0", + "express": "4.16.2", + "html-entities": "1.2.1", + "http-proxy-middleware": "0.17.4", + "internal-ip": "2.0.3", + "ip": "1.1.5", + "loglevel": "1.5.1", + "opn": "5.1.0", + "portfinder": "1.0.13", + "selfsigned": "1.10.1", + "serve-index": "1.9.1", + "sockjs": "0.3.18", + "sockjs-client": "1.1.4", + "spdy": "3.4.7", + "strip-ansi": "3.0.1", + "supports-color": "4.5.0", + "webpack-dev-middleware": "1.12.0", + "yargs": "6.6.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "requires": { + "globby": "6.1.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "p-map": "1.2.0", + "pify": "3.0.0", + "rimraf": "2.6.2" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "4.2.1" + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "requires": { + "camelcase": "3.0.0" + } + } + } + }, + "webpack-manifest-plugin": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-1.2.1.tgz", + "integrity": "sha512-9oLMhGlez5JSRv0dWCoxGHHdrYWrDJa8gIHeMFVuY8Fp4noQebXyFlE3fFE/BCYC4C1rG3RyEBPz0aWq1dtYDw==", + "requires": { + "fs-extra": "0.30.0", + "lodash": "4.17.4" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "4.1.11" + } + } + } + }, + "webpack-sources": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz", + "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==", + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.5.7" + }, + "dependencies": { + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "requires": { + "http-parser-js": "0.4.9", + "websocket-extensions": "0.1.2" + } + }, + "websocket-extensions": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.2.tgz", + "integrity": "sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0=" + }, + "whatwg-encoding": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.2.tgz", + "integrity": "sha512-9WQ+6BvuD7A1vaGMqMjyR5zhHnR/VXKrs2WHobV/YCfeKXKEk0SJbgwg4kjdpRRrenEQbYwZ/P9vQAVUEVAzUg==", + "requires": { + "iconv-lite": "0.4.13" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=" + } + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + }, + "whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "requires": { + "tr46": "0.0.3", + "webidl-conversions": "3.0.1" + }, + "dependencies": { + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + } + } + }, + "whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=" + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "requires": { + "string-width": "1.0.2" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "widest-line": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", + "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "requires": { + "string-width": "1.0.2" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "worker-farm": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.0.tgz", + "integrity": "sha512-DHRiUggxtbruaTwnLDm2/BRDKZIoOYvrgYUj5Bam4fU6Gtvc0FaEyoswFPBjMXAweGW2H4BDNIpy//1yXXuaqQ==", + "requires": { + "errno": "0.1.4", + "xtend": "4.0.1" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "requires": { + "mkdirp": "0.5.1" + } + }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "requires": { + "os-homedir": "1.0.2" + } + }, + "xml-char-classes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", + "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=" + }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "requires": { + "camelcase": "3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + } + } + } + } +} diff --git a/client-wiaas/package.json b/client-wiaas/package.json new file mode 100644 index 0000000..689c7f3 --- /dev/null +++ b/client-wiaas/package.json @@ -0,0 +1,58 @@ +{ + "name": "client-wiaas", + "version": "0.1.0", + "private": true, + "dependencies": { + "@tinymce/tinymce-react": "^2.0.3", + "axios": "^0.17.0", + "bootstrap": "^4.0.0-beta.2", + "flag-icon-css": "^2.8.0", + "font-awesome": "^4.7.0", + "js-file-download": "^0.4.1", + "jwt-decode": "^2.2.0", + "moment": "^2.19.1", + "node-sass-chokidar": "0.0.3", + "npm-run-all": "^4.1.2", + "react": "^16.0.0", + "react-addons-css-transition-group": "^15.6.2", + "react-datepicker": "^0.61.0", + "react-day-picker": "^7.0.5", + "react-dialog": "^1.0.2", + "react-dom": "^16.0.0", + "react-dropzone": "^4.2.3", + "react-infinite-calendar": "^2.3.1", + "react-modal-dialog": "^4.0.7", + "react-notification": "^6.8.2", + "react-particles-js": "^2.1.0", + "react-redux": "^5.0.6", + "react-router-dom": "^4.2.2", + "react-scripts": "^1.0.14", + "react-select": "^1.0.0-rc.10", + "react-spinjs": "^3.0.0", + "react-toastify": "^2.2.0", + "react-upload-file": "^2.0.0-beta.6", + "reactjs-spinner": "^2.0.0", + "reactstrap": "^5.0.0-alpha.3", + "redux": "^3.7.2", + "redux-catch": "^1.3.1", + "redux-logger": "^3.0.6", + "redux-thunk": "^2.2.0", + "tinymce": "^4.7.4" + }, + "scripts": { + "build-css": "node-sass-chokidar src/ -o src/ --linefeed crlf", + "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive --linefeed crlf", + "start-js": "react-scripts start", + "start": "npm-run-all -p watch-css start-js", + "build-js": "react-scripts build", + "build": "npm-run-all build-css build-js", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + }, + "devDependencies": { + "babel-eslint": "^8.0.2", + "eslint-config-airbnb": "^16.1.0", + "eslint-plugin-react": "^7.4.0", + "react-autocomplete-cli": "0.0.3" + } +} diff --git a/client-wiaas/public/.htaccess b/client-wiaas/public/.htaccess new file mode 100644 index 0000000..026ab71 --- /dev/null +++ b/client-wiaas/public/.htaccess @@ -0,0 +1,4 @@ +Options +FollowSymLinks + +RewriteEngine On # Turn on the rewriting engine +RewriteRule !^static index.html [L,NC] diff --git a/client-wiaas/public/index.html b/client-wiaas/public/index.html new file mode 100644 index 0000000..aada46b --- /dev/null +++ b/client-wiaas/public/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + + + Co-Market + + + +
+ + diff --git a/client-wiaas/public/manifest.json b/client-wiaas/public/manifest.json new file mode 100644 index 0000000..95b9c9b --- /dev/null +++ b/client-wiaas/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "Wiaas", + "name": "Wiaas client", + "icons": [ + { + "src": "favicon.ico", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/README.md b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/README.md new file mode 100644 index 0000000..b979207 --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/README.md @@ -0,0 +1,38 @@ +#Proxima Nova Web Fonts +----------------------- + +#####The package contains **5** variants of the proxima nova web fonts. + + + - Proxima Nova Thin [`'proxima_nova_scosfthin'` OR `'proxima_nova_ltthin'`] + - Proxima Nova Regular [`'Proxima Nova'`] + - Proxima Nova Semi-Bold [`'proxima_nova_ltsemibold'`] + - Proxima Nova Bold [`'proxima_nova_altbold'`] + - Proxima Nova Black [`'proxima_nova_altblack'`] + +----------- + +###USAGE + +To use the "Proxima Nova Web Fonts" Download the package as a zip file and extract the `fonts` folder. + + - Put the fonts folder anywhere on your server + - In your html file include the `fonts.css` or `fonts.min.css` as follows: +``` + + + + +``` + + - And finally in your CSS stylesheets use as follows: +``` +body { + font-family: 'Proxima Nova', Georgia, sans-serif; +} +``` +-------------- + +###Socialize +>Follow me on twitter [@mytharora](), [@techstricks]() ***OR*** +>Visit My Blog at [www.techstricks.com](http://www.techstricks.com) diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-demo.html b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-demo.html new file mode 100644 index 0000000..e831d38 --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-demo.html @@ -0,0 +1,611 @@ + + + + + + + + + + + + + Proxima Nova Alt Bl Regular Specimen + + + + + + +
+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyProxima Nova Alt Bl Regular +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of Proxima Nova Alt Bl Regular in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

+

Glyph Chart

+

The subset of Proxima Nova Alt Bl Regular in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +

&#13;

+

&#32;

+

&#33;

!
+

&#34;

"
+

&#35;

#
+

&#36;

$
+

&#37;

%
+

&#38;

&
+

&#39;

'
+

&#40;

(
+

&#41;

)
+

&#42;

*
+

&#43;

+
+

&#44;

,
+

&#45;

-
+

&#46;

.
+

&#47;

/
+

&#48;

0
+

&#49;

1
+

&#50;

2
+

&#51;

3
+

&#52;

4
+

&#53;

5
+

&#54;

6
+

&#55;

7
+

&#56;

8
+

&#57;

9
+

&#58;

:
+

&#59;

;
+

&#60;

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#165;

¥
+

&#166;

¦
+

&#167;

§
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#172;

¬
+

&#173;

­
+

&#174;

®
+

&#175;

¯
+

&#176;

°
+

&#177;

±
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#181;

µ
+

&#182;

+

&#183;

·
+

&#184;

¸
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#215;

×
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#247;

÷
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#338;

Œ
+

&#339;

œ
+

&#376;

Ÿ
+

&#710;

ˆ
+

&#732;

˜
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8218;

+

&#8220;

+

&#8221;

+

&#8222;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+

&#64257;

+

&#64258;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.svg b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.svg new file mode 100644 index 0000000..3988b90 --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.svg @@ -0,0 +1,545 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cec1ac951c935065f90f1f4b720a1056e138e01f GIT binary patch literal 45052 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 bYxcq3^v|56dIM`$T`B+o00C7XW#0e*9HrwB literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.woff2 b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Black-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..18021d66c49ce2009199f5bc00189f253a6044be GIT binary patch literal 18276 zcmV(=K-s@{Pew8T0RR9107qm16951J0I&Q207muz0suk)00000000000000000000 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 + + + + + + + + + + + + Proxima Nova Alt Rg Bold Specimen + + + + + + +
+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyProxima Nova Alt Rg Bold +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of Proxima Nova Alt Rg Bold in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

+

Glyph Chart

+

The subset of Proxima Nova Alt Rg Bold in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +

&#13;

+

&#32;

+

&#33;

!
+

&#34;

"
+

&#35;

#
+

&#36;

$
+

&#37;

%
+

&#38;

&
+

&#39;

'
+

&#40;

(
+

&#41;

)
+

&#42;

*
+

&#43;

+
+

&#44;

,
+

&#45;

-
+

&#46;

.
+

&#47;

/
+

&#48;

0
+

&#49;

1
+

&#50;

2
+

&#51;

3
+

&#52;

4
+

&#53;

5
+

&#54;

6
+

&#55;

7
+

&#56;

8
+

&#57;

9
+

&#58;

:
+

&#59;

;
+

&#60;

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#165;

¥
+

&#166;

¦
+

&#167;

§
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#172;

¬
+

&#173;

­
+

&#174;

®
+

&#175;

¯
+

&#176;

°
+

&#177;

±
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#181;

µ
+

&#182;

+

&#183;

·
+

&#184;

¸
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#215;

×
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#247;

÷
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#338;

Œ
+

&#339;

œ
+

&#376;

Ÿ
+

&#710;

ˆ
+

&#732;

˜
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8218;

+

&#8220;

+

&#8221;

+

&#8222;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+

&#64257;

+

&#64258;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.eot b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..52ac43d631e3162b3872c7b7c8043e4ac349b5ff GIT binary patch literal 20965 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

uq>m*j##o4q54D9I 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9675ba588d8039744c8daf8a0a78a7e6a575016f GIT binary patch literal 45724 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

-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 b(v=e?6F|nNnB?-2giX>8ZB)xC(J=x5P~Rp% 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 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.woff2 b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Bold-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..65d306638d871776979452c4cc5a0a23f16122aa GIT binary patch literal 18812 zcmV()K;OT2Pew8T0RR9107-lR6951J0J4+-07(!40suk)00000000000000000000 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 + + + + + + + + + + + + Proxima Nova Alt Cn Lt Bold Specimen + + + + + + +

+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyProxima Nova Alt Cn Lt Bold +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of Proxima Nova Alt Cn Lt Bold in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

+

Glyph Chart

+

The subset of Proxima Nova Alt Cn Lt Bold in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +

&#13;

+

&#32;

+

&#33;

!
+

&#34;

"
+

&#35;

#
+

&#36;

$
+

&#37;

%
+

&#38;

&
+

&#39;

'
+

&#40;

(
+

&#41;

)
+

&#42;

*
+

&#43;

+
+

&#44;

,
+

&#45;

-
+

&#46;

.
+

&#47;

/
+

&#48;

0
+

&#49;

1
+

&#50;

2
+

&#51;

3
+

&#52;

4
+

&#53;

5
+

&#54;

6
+

&#55;

7
+

&#56;

8
+

&#57;

9
+

&#58;

:
+

&#59;

;
+

&#60;

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#165;

¥
+

&#166;

¦
+

&#167;

§
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#172;

¬
+

&#173;

­
+

&#174;

®
+

&#175;

¯
+

&#176;

°
+

&#177;

±
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#181;

µ
+

&#182;

+

&#183;

·
+

&#184;

¸
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#215;

×
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#247;

÷
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#338;

Œ
+

&#339;

œ
+

&#376;

Ÿ
+

&#710;

ˆ
+

&#732;

˜
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8218;

+

&#8220;

+

&#8221;

+

&#8222;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+

&#64257;

+

&#64258;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.eot b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..9ed8c78620f4c950895891a58a2a91d5e625e6a0 GIT binary patch literal 21066 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 R`oZUyk5r|!V9A_GIGb>TU)2Br literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.svg b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.svg new file mode 100644 index 0000000..ee28169 --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.svg @@ -0,0 +1,547 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Condensed Semibold-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..74890ba2eef49ababf9d4f945cf118f6ec531b3c GIT binary patch literal 46144 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 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-demo.html b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-demo.html new file mode 100644 index 0000000..65896da --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-demo.html @@ -0,0 +1,611 @@ + + + + + + + + + + + + + Proxima Nova Alt Rg Regular Specimen + + + + + + +

+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyProxima Nova Alt Rg Regular +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of Proxima Nova Alt Rg Regular in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

+

Glyph Chart

+

The subset of Proxima Nova Alt Rg Regular in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +

&#13;

+

&#32;

+

&#33;

!
+

&#34;

"
+

&#35;

#
+

&#36;

$
+

&#37;

%
+

&#38;

&
+

&#39;

'
+

&#40;

(
+

&#41;

)
+

&#42;

*
+

&#43;

+
+

&#44;

,
+

&#45;

-
+

&#46;

.
+

&#47;

/
+

&#48;

0
+

&#49;

1
+

&#50;

2
+

&#51;

3
+

&#52;

4
+

&#53;

5
+

&#54;

6
+

&#55;

7
+

&#56;

8
+

&#57;

9
+

&#58;

:
+

&#59;

;
+

&#60;

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#165;

¥
+

&#166;

¦
+

&#167;

§
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#172;

¬
+

&#173;

­
+

&#174;

®
+

&#175;

¯
+

&#176;

°
+

&#177;

±
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#181;

µ
+

&#182;

+

&#183;

·
+

&#184;

¸
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#215;

×
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#247;

÷
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#338;

Œ
+

&#339;

œ
+

&#376;

Ÿ
+

&#710;

ˆ
+

&#732;

˜
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8218;

+

&#8220;

+

&#8221;

+

&#8222;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+

&#64257;

+

&#64258;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.eot b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..a0c18593327f5043557ec2fc0b85be636bfabed0 GIT binary patch literal 20765 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 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.svg b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.svg new file mode 100644 index 0000000..c39d0d0 --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.svg @@ -0,0 +1,618 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1736368787cc177ab08004df24020c0b7e025258 GIT binary patch literal 45880 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
  • +hW3P2R8$B`gk-hJQ5AiP%KDZT$H&DQoEh0M9?97>w0_9Yg2JJeR~_r? z3x^IZEEqaWpWViVG*MV8jTLM3i$L|0ggydpCb(pa#}@&a0uN3oW^ymyE<^N1*HFF2$OHg8~l5Bow2ycDLft+E(U?apL2V_{Zp!Joq?c=tHLpoF8od$nj~@`le5t z)~)*>?USv4vi~=>{?xR7-Q%Bb{gka(%=Rr}tJLlES)?vptnOqh=!4^gFOpE}_vq>k zS>X14g-W4W@B*eTIU8-1F3Kgv-aK8nt94LbuF2(%(cr2i;!JU|HztwJ#8^!j_knIX z>b#O~z9{Eglw9WW>MTXY=wA*Wajz}01bcFhMJWgD9p;Nl71sGt7;ILdILfUyB|eVE zKT&734GI@nR9w8H$WvaKnNT6eSmjt?L={V83D!bGN#D}45)XKaF+0baW{8V5i^e!- zNg<1gO%oHWX2u4xlD>svPHp3$<10!>&KXpl*Xyen*M0X`d49CK3?`!+g0JGT?$C+7AZ zSUtOZi)p${r89t*y|!bxNNxrI}D_^g@;Y3&<6VAZaB44>Ey| zPYPZLcP=laahH;-yXZ{<966FIak`7X!t_iDC{T#aXcOOz)?H+B5n-$^Qky%G7RAO~ zK7+Og6i&rnmbRB=QC!%|;Co6j;A)Gs+FDIgVltqoxU#G^UsAd=vlsRRr7#iaQc@im zbS^F$fHw#gfNsYuz=SJ{jrSCnmh{bbW*B0ahhB>g^)XOcuWcE|1)K5;b2@MGI>8>p<9?(!-U)%rg+Ij1@pUYc(=+oN$D~CS$ z*ou9dcJ^5?bk0pL*9@L8CAV(Ggr%%u-1@oInXPwj_Wk^4u5tYH+zS@PjyYvs7cFd4l|;EERWMar$+q(q>sr_ zLAs}a_9^D>1h13Eg%UR0vrb*eF6f&;Q)2{vA9h|bMg{LtYOw(-VqB~Z)39#u_E}37 zEm|^bdmFpN-aA=+PTlyoZ`2L%jXbHf&xw0I9(ph7yb|7Vub5I>NnbIiEZ$}jjZW=G zd-rZv<@eb7Z~n&CovS{n7O1gmKJLbZYAID*fxcRWV!^8iHu$2U+UP)oY}8j-EcQj1 zINdiDD>1-<2mwgW!a-dyzGXRO2{|5PS%NXan3LcvGgiO*Zo%u3vm(#9-+kA81{<$S z7j9luv*9m)*-*3S<_YWn@)vGmXF`ABtaMs;FXr_WK^7p(coe3)DC>*80wX#ogo8pd zfi{^$Br(!0hx6u`w0Wv4_L{=!w8@Ao!%egqE|`F<+NhK`tYExx4y)7JpKV*owyC$R z6xS_cht%3d>R1L=A*@o{*h1lL^u0g&PE#Vnh?#(nhn<&&VxQS0*mPjHe8oF&4nyZ9 zD`%~G%mp)$JYgU!Bfc6$bAxe}XRIMCF0Z1hplo#gs56em#kv9c1w*EcnDJBz!Mu_k z7V|_8xJ3r_U15fc^kK5jtq7n!l1VV>T#7!}k+@3W!QsttvocLyK%0%2(O#&anzRty zU~-sS24)2$2F1j0QA*4|){sG5e@J~{{ZOpwUhoi$v-IoHj(Fgtj#Eg{M57;gb{wb` z`+TjMoToo@xfaML3JXC`)&XDQ;aRU1yil%PN{V#RYal|BEuj-GK1UM3yAmvl9T*b{ z{*;fkJpsV88VGpVDG*X3B0(xODj|7_)1+9l1cD%yf$tO#6v1<(470Q_bK+|6lEvQD z6EkUR@eWhHUvAN@Mz9FoYYF6&B)}rQ0}^IHg2W{P3CSID(s?B;>Y^N7 z>`e+I3{3)i=fa3$w&D@C3OU8vDugAaYxHs;10X;K%#snPTQX3u5kupWaaZ*bikqy@J9&; zFfc3gFj#W5RnDxC<80o2?f$2a zJhC=6;kNCq&uzTrnQ^nmf4%?LOe&i`*Hd)U+$#0^KR(rdc2UjTZMQY879SFqFT3TA zn#niMzV+0h5x0#g2-6qbuyOn|9}y7|!OsL;374It5S8LJ(P)b3nNNr?iBT?D2O$u$ zl>s84*)5yS%aO%=G^AoL6l#n{m;t22#0Lgb4q%|}5`n|m%c7M_&M_sx08g9~SO6h@ zh&bxYlP6nL2m6@S?Ua_bHSbjqvbw$En}GFZzom6+6uWtiC}=b!P+XBVpD)4f?|S5 z58@ROnMB+-)+$>ug{oKwIE@L=d^FWX~(5)-siR-*|bg?*4|ilXwI~U*N#-b z{7?1F>06Kd@@Mxvw%#Rvyid(49p3NeLkr&eS8$$B1>R&K#^xr$Yp34i2j_VtdK2H* zZa{D1sW)YO%Eth6vWw*yi&BKvC!-f6ofgGFLW(rR+o`$9R>cI(L{R$X6HX<^0Ed*w zc=R*O)JX~wjD^gJxt|KrGcX@Sq6`UXIuEA|BuOpIo4(=2WtVnL?YC*(xVxrTrh4AL zedc4gR}WotWbrcJnu(dMy5!O^%ZHC`8lC&xw)w}zmgT?kZ5;c=`e7pmEZEjuQ!?@H zvPHjIH2twVMvcAe$Zz_WHa3oRmrQLazVE?h7|SXM^MB%WB17X1oK6rv5v?F1AwUZR zrbtA=N*r;_$*QC$+uuDQ=ICDDx9Uo|?q$*k76B(J0moF>{ss$+G%ZGP0Fse}7gcn> zAsl>Z0AHF#?n84Ak^w!X4?hIEf=fxj<^VbcoKc42z<@qh+w+l9FGufKju%x9>0wCR}_?%sI3c=U`>si~u8j4qCM53U`Qo<6vCh`VL|oxfyt8&332 zoVaz$^zD;eu1VXc-|9{VJaZsspuXmr{p-aYH=p8FnLUSB%Dag4iUN(1$u+W;hrmm>>t zCs&Uk1=kWPk|u`E(H|)jBJg|6OSKSH%w#p(!E^A9|j`^J#Q64 z2N&Xb7Fc*k1tgzv*c@W%c}euVWVdWRuLwq{oKcz(q^;!mVkHHDjso*iBn!>taFT<_ z#1NE&f-1kUvq`Ip$3Ytrk!@&QmpG=2eGLB$r4>tM+-?dJOIQYIx^n~dqd$|S)6yZ#G9!AzB`JuI5Tf*?(1f`I;t!vl zn4xr&HPRL)FImF2F9Gu=9v{VGQ0_RlFBI=^K4;C^KlWAi88GPR~n z(gZty``xhEDC% z^TSM@K(o?UY7t^_5wylcba<%cqCC{16hfkf%#IVvL`>JxUdIQv{=K&l=L(k{g=Trw zNxhO`_}(l#Ps*b#t@crl7+33P`u5_R40%oiOj;GPy+UZUJ4cN!#KN8@%eS^&SSSzb z#gxLKR@+ekE48R!Wfh$&!I7ckni+TxbTns1rkKU`_Ock_QihS6KW4pu@e<2>bYSBhLuwlI z<N>z+aavc{l^} z8Q|CfDK!wrM!1zo&c~qD$l;j69?1Jn$sxr!m`%)iPs}>Cw!L=kVR4uW^Zex&R;0ee z-Vi?}zIFhzS2LbrhF!)E<12p($&nhL1gZ8VCh$kWyv1Y(r`pk=+KI(-v_;b-p(3OZ zOVeY9WB_4OU_X(=FcT7JBcei1v|?Ablg$B*vpTq4k@GQwGs~gbR2(J2jRWFr`JEjN zOCEXe1$6*>^0rNPuU6~X{$+REu}oc{pL+7)rbF@8Gq?Zp*ZY39q+!d0x6hfq4xj-I zfKH=#ga0Ih|8U!qVheJg2x@!^*Qv~CCG12H5N*IF_~FCi;`vOqSqPi#FF{i=Ph!)nDg&$q0{%u0t z67}qNkNS7sGJU-I*M|Fl2c1;x`ply{0APmt{p7m<$3B zi~uw^^6-Z_tR0Wj9@f4KpyoL6xxNKBkRc4v>>#k6LmqPzD#(d$C5d|HqVeD@ z!=l>X5idTVo_l9!+lgDmmWNrykw$gu)J6>}hOK#E+Jo<_FTA+$2#e(H#hB=Ad`zk| z*ua9q!6WNEK8Z}eT>A))2qYwofgE8W$(1AsvOQ^*5@_}j;Iv3-EiG-I>8G~) z#IcuK#1-v3HTd9pY&4!Hfdlfn&L0-A8gRXtbZ5gT2`H0_s2~eHb1gKI@VTw z@7b9&c4(XKSq=+$EAU8H2P|}+t^nX&=5o6tafO4L$~-0r??yCPtUuTOhPe1#`{k{G zz##Et``Y#*vGE}lW*aGMqTwni$dy0oQen4PcV#1ecwY_xf5P#6Q}Fq+A>`?uQ_5sf zq`=cLlK?f46_GSj*%)YnB5};e^BG|g9{#LkYk9Km&v@=RoeR$$as{do=o!)3BbZ|m zh{YH!c*CjJP>j7glJhw|OX8Fk1|yJsy7WR%Sp3328c@ zznOL&terZ0CbSu5CmJU>GlYe|Vr6UxD{pC0-&9wsXT#S17t8;mN&WJ(KdE1{&)9uz z$O|v1FRRPcmtS~641c6;*RHllzGW3E1s7=aSGOE63I|6W5`y(a6MUu!KF2@_nH<9h zA0}8iqF4^MkR5?DwOB%FTLeHB%D|kCBnF-Ze}LnFnDzR9eQ`$J#2VM`+qYH)NB!!# zXTNIyR6KIuf8VFU>{Sjk3+CN)!HeJ{Zn)84mQD}P;4rfSX0RWSa859DVx0mZ-6!cH z%qDOq6Avi+bfq55>i!QJ{v0>GwM}PM^ zhvwd0D^9IGx&CT^zNx-*c5CC#1sY7N-)ngH;Xi3$duitBc#?6=kapzAlZwOoy_|UxJFQXCk&tlB z^esCqtr?C?>^kY&i|r7B*ID7kRV4aGRR~8Z`~xy?CW*haux>}V7@P(zgREC3YpX6k zxqwDK*QO*U5ulP`$a`L3F^NgJeAG4D9XGWaOZsMd?9ekH(L#bTYJzd*_{Py6Y@W7p zgrjWM+Iu#yomIvne#7#QHtxE7`=dCt`5qi9zxC{q~f`6F*|l}{NZRwuz$2NO0} zf*zz)Zy?*49?aZp(9G_|0#R({w4G*e zv$s#RfAAhCW`piwuuVo$e}?bShe+WW!3&m;ZbyJW(9K$zq%&kDbTA19H$2l!hepjS zMF@B*=dU}sk|hxSnQ?_Io;+UJ`n5_&^|FL01~ClB%u2ZJd%YZS^7yIIe~sWjF%>Ei z;bC$(&go-tPIpogyrMpwqn#+}^c0T7u@GNCJD4reB}ndpKJjjWsivM_Zq{!nt6&AM zsB2$P-&5Z^hCc4pt)LG$!}u#OEF;Q5&};H#c7P&;dAK1LvJCNWjcbc!+|gm0Lz=?_ z_`lP{lEhdw{2jKJ?Ri%X7vtVh$Est*6Jm4w$D*TsVfzrVy8SqwVFS*619*l}L<6}? zI4JqJn7G}W_-iu(WIZ+!*9+Fak3<+znGM2{>dkgp*!JxW?u45(eoojydAyN0=n$VToKhm-fy^BNI|r%WMw1W$)f?_QJ@=0V4@kwq`NGY@j<_1O z4sI`<+GO~4`S;%}r?&r~9|)}7xfYHf{d#zTnBYWv9_Q^D3LgrQLkaDHy%Hf8eEJ&C z%Tlq=pf$;0@iEP1$1t%i!G_`Tz(j@;P=b$>8Pv;cy}CiYWUws%o`=~oAxCVHh*lV2 z8w-e>0rM+xjb@LD<*>R{taiQn7xj|ZA|7s^EcS0dgMRrh`zv)@kzFW(*T@oYp4LP% z5pg0yUKWGy-Yd&%mJ=LwD*)$aT%SwV`045S-4lwsBeY1K2 zcpwV1L3;%0AD}%cV&7$ER!c|}(zo?`E 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 U2N_ooCg%n1IV8U2ZoxS5e+2A@l>h($ literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.woff b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..3563df1c41e92bea70e2b2ce050c8bd4c365ba77 GIT binary patch literal 24172 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 OX8-^I0aYMn;{X7*E*1v> literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.woff2 b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Alt Regular-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3563df1c41e92bea70e2b2ce050c8bd4c365ba77 GIT binary patch literal 24172 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 OX8-^I0aYMn;{X7*E*1v> literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.eot b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..e61c07dddcfa04c6c9d0a84e3c327a10969eecdf GIT binary patch literal 19571 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova ScOsf Thin-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f0f91e283616396a6f8793ef2c9b47a9c02dd12f GIT binary patch literal 43868 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 E0RK?h2mk;8 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.eot b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..4b929026cbf540c5e504df5482cd9a6ae7a38d5d GIT binary patch literal 22993 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 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.svg b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.svg new file mode 100644 index 0000000..4473c8f --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.svg @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d2dee6921ece3c45606ea164226ec4119bf8d5aa GIT binary patch literal 53640 zcmc${349dg{Xag>%pS?++TCQcxwD(iLCCRWHzy$wIl>(<1PF-84I-ypA|fJE1eC)Q z;zbp$May?)vjQqb6kDZAsa2uY`t@k7(o)OUZ@<)HGWowh&&(#9kO;Q^UjJ-%cV>3> zIX=(lKAshrAPDhzF$n$Y>Kez+d;IoPL0|)LHEsCNVRcdz`v&JtIQI=7KW@UIKVA42 z&hHU~?B|D1m^gUM=d1PzLT;rXm=eZK@cQm}?4epgC>(?PXUtwabD7h;Vjj+)$9F!P zy?Uj~HZ%TRK`7pZ&xg)iHh=Mip!X*@e@_s^x$|ePScdCXK`5dABjzt!JMZGgaj)Qf zs36=YESNiUPGtS6O@eR&=R)}cT!?+obQ0&c;XHf6;+41j?Bo9E@5DYqkPa+bI(z1f zLw8LQgf}oA_PfP1Z&@Zruxdd#nT`8hOJ**fJGSQ0H*t>k3_yuJ9pswCOipx!rL`Zo~HMcDZlj5`#W`x zWd2DkPWsXnK?Ho6a66tGgpD}6Q}{EEzYzYyKcUa*k6N<`8A74J7R_9_M2Nt*@YmkX zKVdh`y_v3Q_c44%-(t8TdfucvT?5<~h2cVfe50oQZ2PC}N80D%=m?IF2$?uK-+rQf zUHks_X1t!q=gsY(w||KDvvf!Me(LMr|3hCVcw771r=gFt?I$pf&3Jy=?nh6}_#BXJ zKiIVg+<9I|=z8tnIit42|IjPV5M${1k3R4DldHXYIlO3Ym^Ytc`>CsK=lk5(e)00V z+b_0XYCqfkIVALk=NhEK+W_`_iU-G+@atXM=>3zf_w{rJD27I_&#e6v zuIaGtRPU_11f5d*~soU#)HZ71#^- z5nt-kTGz8s5C1-NiE2ZX6Kd^;dIweLxX)?wRC_}=SRTY3{2pKlJ(g?h2fX$}mmuz5 zgXd1*_-4E|aC~n7&V%kkEnhy?p7{pNF&x(2zsISWb4IS49t>er_xrBq{A%H;@i}U- z=P_SRU)}G~bj|Kp!_Pw))iWlA-+B3Qh`tDt7(G@e{Et={*PDU2q+_4g_#>{=;2M_* z?IUoe@x@bE;mufm;-0iN-6Te5yFEiw(*Zi~>VCv^G))2!zwALv>;8@K^YHsItINhl z^adQHSJEBMYM4c{)bNHhC_XFFJPEV8&cdPA>qvT@QO{R9#|jvSNxJXL2Q(d4YYn4> zROt$B&K*WzrX;a9g97=Aw_5;Rt|RjGBwNmcaU?+c&Eu3yv&KsI{1*<}&O5F+&l-$R z!y)Jm=uOu)I$OBfqbtJ*tB5)MzxnHV_CI7_fKwNV0ciOFujTETKV&bVwnBP4df6P_ zFZ#oJ5yz)bLU;er?_FEw(n8lNyMFRR_lr4kt?SC|LS}95&L^+@t?)Yl#qR5w57=(L znh|uDcvq|EhWCH9$K6MHwcoq^z7SUe4w1dUap>~9v@6`U2VeO2)*E~|O#h-5!NE=e zx>sod_cp5UcU|Xe{}21bj5_A2@juAqgJhjtd8D1+yz;$2)E)nJpUZ_#Ub9*73k`T| z#^cJcZGhx%AZgy?92$gP<;~@ii|ZcEy-UCzd+7OM54L018$*~1E^!fZx|>GU?OxKg zNLpX9)vn*`{fz5!SLLPsPxR^V{(-Y(GlcmLx_sJ$2TEI?Ue-1I%eqDf_)G(L)h$Y# z0jkhd8@N@^d)7F_l{Jta`fLDC8*w?tbQ#7Ee8PIw#JYFHbvHx?x?lfc&ciiJ;ObTT zE3g{;-jG!29L>M0OM&yjS9!Ts-`R5L2&?{Y`7I!|xa|>YhvU?KT)isT_JB8?4SkOz z%#%DY|4;mV+AuE1!x?!fBoWF-}YU=?y{(+#u?dD+1rq`?E8&}g8^aS1Kb~Sf*-t+zOsq?!(;L*Rujens2uUcaLK>eYa zaGLz#TD@XR3Fwz0kKy-1xqfdpj)vek7f-)Xf~O$V;@SCk4GwFC0zAV1D8Ipk3z0$; zznm<@QXU8XOoAQH1i>LVg=8UBNEZeQnSz`5!f(KfN66!O5`{vs;KiAMSIVUD@K5q^ zRv}ahRmg0p76u4|g&G{uC_{f*jz#FKxA*?|prqS}rQOaA-OjZv4-;mfJ?K1He`MlV z8zYUA9)*}iq5cRpRHV-#4|B}J#XO8%d(_~V^n^md<4S)e7qCF}c=qLwc)o^&H}uyJkG}e|P)Nl3CjkQr0K0zt^U(KuTRVbn=brx40t3`zL048#kP#G=fJ~oMJR(6unYbfI=!4nx z1x#(An|^4+FAM^tham^ZBa9TrfQsvdak%4J;RayYTs*3UTksel+=@pHvXJfuHEzRW zm~cNHb;5(fUVQrz;m7#)Q^G-Eg3uzoh;P3vye7;OUKf5LED_EK9}CMcIvQoR&~#a@ z644MtZjvMz=G{DVwve*u#`!aatfe>4St9gVv1-{0j8@BdqBbaxiC!iBTV~9+4`x#- zEI==}03Nh%%Y=u7qrzt_f)%qyb}QS*uQPU#kAtx{`MHCgVc&=;;!tskxKI3zcu8_e zL#27rUD846J?R@milNdl%W${hdBY#HUJbw3-i;=$9ixwrLjtT*fLSyy0kCIyIQVNk ze@(oqyOMgn%Nf>I?{|gw=|G z`D)TPI(w&9Xa@GHxN|~}ccy{9v{@lv4=vN280evMY;>+cehkJb0a`9lBYh`)9Aj{W z=pi&C?OPJABq0}&M#w;C^bICV=C4|t+G`VsKnkuW;OW9MG?MUp=`Ml-wbvC2pkKXh z2frr~qhz}5rXEM&sm+q+(lfL}_w+pGhAu5=ZBjcujXC_@5xtI?`qSV+lqdq8J&jqz z=I)b9DeWBj9J6#(Ci5xLMukNBVv7Mg_3~X)Gq@k?rrTtnA80` z#rPKGj#_{_#K-=E7Dfr(FUtnejz8ISB!Q5eg67=_nDoLO+M2t1AjMM|K|M9?O^ z69pPTqoHFFnBe61i^5`IJw6pdO`tjHKCub>(qL>hLJMG-+Pn0QFi$){C~h=?%|ln* zCy0L^FMRSX=E?sSFIuqzeaC!jFg2(Rf?ysh&Ic+#K_5yV87JY*#W^)e33}3c)88L( zMn`G*^f=xN`F+tiib1w*JDb365q~NE!DVqJxKdmht}Ius%j@dzy216lJ1eL4TLW@y z=`RM~+s7L8y9JlkmE=m(@2={&n^7h%d=P(vb-cWNtSYqq^^-S0Iq}KyPhR=t=qE3J zqI~k~CwF~P`SFS0|Hb%ceT2OEt9fCNblRlwPMN(l&+tEdXfT@05s{Xt=$P0ztIZyt z;7D{PC8wmOrDtTi+*zLNoZP%V`F#rti;BJdN__s(vhs?`s{YjjY6cFfy=L$bBy=)CF=Ok;jlZ^GLgU0qlbfbYy>8m|({GqDbC$5>?rrxxu=k1mPd)vUXP!Oq{Bu7$ zDF2rd2p)Rj@QX)&e)QNY!iu@`7XJ6zCzmh!e9cY5)<=Yug0SEgKFG!Eg`d8B=bWW< zvgG!UXK(t^o)fR1Is4%se)qvk!fU?}{`Bc*UwkRt`umTB&G+85WBab%_w9V>Vd25Y z9)DE$ zxP=*@_nZ_CL2tQB7;3c1LZK|gkCw-bZ<0r?o+1mLK}oWyps8jGzqWpg>phvp7bg|T ztkCs)Il7=o77Ir=G!64iaTm!_;f+ZyxpsV$Tdti_BpV9pt8S0`)~1hAPfbb1eNAnt zf18r(am&VnCb@3)6#l`KDQM4F7&C2Zk!&hdve@0|-F5f0X{oY+X3T|3HosKcaVetE zZgW+6i{!{c*Lv#Yb+qr2rJRu-mu$!#B@5%5w$0r((?tiBsc!d_)NTB%K|7-kE!ya; zsa7{Si7IscmQN?T(B+lQ1=E^buHl}#nG0P_t~s-`Cg{Ex>KR?Twz-CHtDEWB=Gx}r z-Fal8p-HaAotPhWE7#7Y6MQF@_f&Hx$?Z;co!JI3;7cPhwu$=KFh1NCSLkt_(L49J znnq7Zb<1o@(>6?Kq-UGQwQb}!&rBK#O^04-JXTr;JC?yl6QBcow+UdNo;uIWg)_ou zLSKz9#3Z(DA+U{_u)~AWc zOU-6`)CI3`A!R$O1jQoR>~eHfzmkg5a$lk& z!IYI7@0L7^C#;+}apeRHGv&Orwz{#gx~j3!nAkdo=vowJNpA5O<3d;`$*=@4F`+=V z`h!sx!Hn*lJ|?Hom=sgoxfY9wMiLb*#NneTZ_uJ0nXF0-1{04vobfTZBT2iS$r zkL1VG6Hib2D6i<9weJ+1UGvoH)2sKdJ)Qsly0Zlzu6gQ~->lic=KWK*{+i9%!Is^_ z7N~pZd5^klhx#a+Lr+{M=`f<*Z`foaE6@uo|4|`;i51A%enpbb$^CqRJjqhfQk$0> zSrCY$x!L_n5k7JH0&zw3Nt`tjI8^SHqt7V$)^l>cRmo)q0V%G~hdJl)c?E3FemIkJ ztco8q%(R|UD)62kja6Y)N~YgtR~!kLuOj8)l29cV*$%O2M`od~3|J<|+2sVF*dUhZ zv=y7mO3N$C{E%7Z+&o)`(UA}tSwSQqe23(GU zE|Ust+ABOQ1d;&50JLq)(Qq!147hP5R~&|O!Q#wp320D^!?;K~48|D1p`^w8ob3Iw6c;=5}rR6T7Wfy(IKgcpw9erre zv15B4I{Ns$`tkGUj~_R;M7nWn>w|3D%dGI&G4;KdADgpp{``G&3<>w2IC1~3SB~wT zynI>HwB1h+!t zxj+=)rVKQkWAZhe9puNJYl+AQJ5WlaIHFZ!=CRS|l)-o}rAeB6RaJ7eEf|$sSe!_h z6KhvevI(&Yvw&FHRq{aF3qnL}rmq~I5)cMT6}dnt&J$vd=0s;uD+$B@If|?$T?=mCktYiQTU{Tvh&YRYik`HIz*$mS;>~zE}OSXv}l(9sk## zx6is|)8Q9W%F=ESfS$v^T9uDXJdPx2Em}sCD3*tdaB0!5Y`pStbLE*7@ak z@JuBZVA45acTU*J{K7e&fIcUw3q-4N9q=2rx*YA5*%`$gcaFF(8Y#Eh0WHyL2Qg0C zzkBmd^XA>OdH1*MEB0~AoRjKy)u-O`=6nV1c+>^#W3&^^+rfCHGfE`d!Jud`<#wx> zSCMFUB#36uqWSX|ZNBg6r|(lwzrj|r->{V@=d`Hqe}1E8Dm12QNffsN4mNPCfDu>{ zjN_t%$#$>@?>&Jr(Bax8ABe zZdnoYYSmkBRlORs!g5?Xwcy5C>puT{-K-lI%wGTb=VYH$3%`&~8g>H~6QNZ?H}WgY za1PxC1V+42uz*W4fex8OY!TqHoRLLeFj6C2gD((ip^qcYxYH6zhZZ5SK!;|0ncD_I z?r_^YwraL+4_l{h-XkvF&i1PFx2sL;S&U(!dVxK}A~1Kq5QrmEAxUn=0iQh>h{-O* z8o)XD8%-Z<74w%(nv~YWpE++Jt04SdIH79r^o5gW_$FKIwz9f){U^+sH2=kc<1&_( zn#e+~VfTyqB3X}FG-rjG&(V{~1}~PiASl^|NJuWDwv1(NM-4mA?tk$`TBn8W=h#+^ zH4^^OPOT%PelXdhVJ*}S6P{7L3Fr|RA?XndCsy}|5;19Q|A~#OCr(6r$Tt-?8_Al4 z7YG9&b}8CPY0&$3Fh66T?^9Frjn7_c;<`p-`xl00;7UBanWKaN!U+XRvUDzBBIe?j zFp+GI(+nG=h4o^RE287@}n0 zB9w5N`GGa&Ot$r%3m;1-*}azz7&5;^Q)sIZy2?<%APrss4QHYO0aCk^6zN<`TAUPt zmeakmlhby8(On=A3L<5(S6^%Pj?x1E?j=YiA~cE|GZ`CyGNHi(7b5bjFP#F z_G64CSf>h%u@HXZ0G#IqiUDIxp)n>%=Yp}3eN!McV`;&PKzV1Byts36o>fkFov|r4 z9NWA~I-pWa1C9h(K$CgUq2ySboK+*!#%ZlY4HR(E8*jEVgv={EE^=GiuZ?&K*?$@r%dC zPFX(VRq?Dib?UUadmfy%>X!$uSw5!3Vk{oFVYK|;w?SX5!Wt~ZdRm}^Hwl4AT2T?R z3kp$@VoZT-fKmv($^?}V3VGxiIohX0U|Nzd09zf)5n%$$h>YOegIET1aY2a^`1;GD zO^%@zDP!Ou4i7K^#z2)=!bTlB^mlaz+sDdYm1eXC-c{dXW$%h>G`v^=n6JT@(qMrH zQVHfz`T{Wob1Pt;5SbbSm?uO6=0FZ8cz|=j7EMF20XbxwRWShxlK^($iDH8i0xAZ~ zO|}*(GJ%v4@Sao*5h`7zt%XHJC*c|vL$>jS2!lRnd$a_EPzH}{#nzpl-QN7*`h)8a zNE_OgmF}Ou^7Y%)kH1h4zqJ3!ZS$6HUQ;5rzN@Y(9Ww9jE$_BsLZU#lz5zJof)=)1 zpHUuWWS|*YFr)aQR0C!dPc!1$79_(t+3k~Ktx8{gCZtaFjRmb+4DmDrISE*AA|0ZL zl+&atIo=i!Vy%Q*7Q1Y&k_|S_TjNXZpa-Y9n0dek98eZ$Hliaz@MINB&J06`j@9@h zmT>&<&CB}VdHs@S8b#l)ZoYp1hLP%*pR78zu_^DOA-Ug>IW@OG@Wk55Pl(T+WYxzW zK2$T{_P1_LjUIDz)lCN$o>0FTwK4eXO7Eme1M}{icFS$V>Oeykz%eW58Cj5vA)Y~a zMSO!8h5)M)laM&BxE;*RDx?qEzEUrV2E(RzpZRvYVH3FPB*1Yo;Ftk84(h;-EI^X0 zWHr=YE$7{t0AHq6?ngujYfUzJm45sZXP{0TI<2yeKJ5?w+TW|#z+0~Yg!}h{jvAGa zn$=gcBWs|ay&#xu&c3Aa1CycT7qha`fg)fCax|GaqXB4(Sx8+i7V}~a@!-83YT2ZN zn>Rc*dH2B^M%}w^MWMd^oMEkTF{EQZVW}=(5<@sw44li%wGz%{63&%ypm_ia zkChBmIp3#PKs`P{#Dj%V$n29-Z7tSBLnf!5L^$YVdzGANljE!8T)Sd{9xoTeJH>&- zQ4HXTl{{H_6&XOdfnp7d4Fgj}F+MWYulw>rj$9?Pcf7vx?|YW?-!yINy%P&df3@uP zQ+NF1i8Ygd>^J5PTRnRH{nC@S|7QKDJA=Powfa5zj^TTP)dR+Ed~8zw*p;(RJ+Nl| zq*2w2X7+!8&z;M6={)3nJTRqG!pD&DYqwy+2{d8yEkMA_ar{kj01dgnK$r7Y-E-i{ z3Q7D)a31up*5$tVr3Y z(vG$S@w_;rnH_jWJ*dk2316z&e(9tX1eKZLRp%NNR7faOMly6Fyhy_3radR5;DSUjD-+|IRM(#^#RZ_X>?FFQ^);z>#@(u8*XSQFA9#z zuCA-A&Ype4v#a(_T-}HjpJ>=OV`1>#;j2fFtQ=ENo;zUpeE;Nu6(zobp4!G;tt)gz zkk4&I`*PzYV=C;%F~a9UAQP)EyZkM2nW?b_$|!)e#v82UhBYB!j9(dwYq>tT*c&wH z_V!r9lVGW4DU@0jCnkJN^f~z&&Ag7#{7Cg6)AE#;20ruk-vmd2Mb0damFtch6<7Sf zVrBPnxz5^>QI{EC&@!A}19&CJpvMFeQYB|p2`w4!y5Yt6V=s_UBl@;p%Pr6e>H6NQA2I^LqdepQ&4KtSt7|715Bh?5wP@fGAA$-*qs%A z$>bnAexO)ZD!8*^!4>QfIWW(l$%r}hQAIq-Cew&Nu{FQ_IqUm)-SW*tCe4iyE1sUb z>$xo-thsKBE9upx25*jQXl=gwhN`akD7bCRLoDj)U$*4G`PpIh%(Lv5b0;_E{0t4$b5vE3Y zm1r)%BES$WV19lGFSq2D;BFMfWL6+1sTbz9?U?&4JAaWo98BsZ_JOz^l(rjk@g4LL z3m=UOPF&uL5(h3#II4qYWtS8mRw;~>0}d~%$XTad5`l;5G6hh zc|-_cC&+W%A^>HTR0UEOfA2+;`~o);UX>fBUjp!?w;^ zx@5MxhHaQSfBsZ;qjAzNAG+;XhwZiXPyPDcxl^uP^zN+sakBv$&^~k=V;$s8GV*W& z2my0djT^yA6b&ApQ&{M+7$xKj6hz367nop{1WVhO(wY%cEmVy8+bdn0E=+4T{ zZCrYsMLfjj9zW%O>87{Tf3WDc7QN^{bwYjoA@!T%qLr00%i#s;+Y6eOs^`=O_1uyv zbaohg2JkgD0lp*$`s>hzx}`xko<_yx0Es%;V&z_BVlX5Klz0pIZH%Ot6VMFs0~iQi z10noHk9#+3{Vl6&X;EMLEe&bc?-qaak@^qgq=V{7^=9=~KYMrMdw2et@pLi9*SQMg zh(cbMw#Jd6QNWl88Z~q>(tu!@!@&#(giJO$H`ybjpjC?|ADAHq#)kt-oUC!TW4H8d z+X(SM+a&Rbanif$;}Z z_0&eK(z<_cY{a@}2rD$72Q9ap>LpEGc6b%&9FQJN&g2ur`jbvez7J^Uf%qiS+2b9U zpo?%9yeSZ6OeN+G?KZ+p9Nhs-QDT#DDUtZO9ASq^AxGJu;gULbIogx~n{6htlf=g5 zuQBue?1ndgQT5VN4R>Z7EK_e3x7?`y@n^qOUw%zI@ED7FVV?TOrPt2m=<~&>lK0m;;tQCKSH1Zn&`Cl6CnIirA3eu=G4`no#4W4bZL*@eaNSeuN6b*!eWSaz}h$!GC zCqGOBtH?aewi{9P6>Jr2xS&p(r$Sz|u9r4lIv`zawa`&$SUKQiKjkMp%T-FN!b!{fjnWXX_X#h+a>(mH-jBy=goNnv8=! zI$Q|E5GH`#Y4#?ZOk5QOH@1QrtyU!w{Y8TBk&lV=dL@R>Iys&kOG0Esh(VK-PXr(2 zv=yIV_xtR`3$w&Vg$?@E!_0Vi!Ggo;w-5hHeRbG3Z@+cv(pztT!#-gTupx(TdRe`s z{#L#8@=b@tm^12^Ea}Wy=2ZVec+2^;;aLtN8)A)N+{y;-7@^Tv1PvQ*RGm9od@>+L zo?{Yx+?i-2j%~!ybuni(dEChif(`Kl_inN2^o9TVHNs6J=55+EPX)XDr~1%8RZ)EB zme+3KFbi^+*DD^0Uu8JG~n`A67qnW5f2% z4H`uAU)_3q<4Yl+YA~fZU>tOdi8{3+{>K#yM2v#5R?fP(<0^@Rl@tprS1b~AutIxL z5}-yX(H0^DE7&ts9NB3L*Ci0;0#$p$A${^<`Sr_dS-pB*ednuAfPZzY>Asl*ENx#f zH3WA?aVo*-r2h`Iw`pg5=y_)WO{)rPv+bXcc z!aR^I#}!w?zhuvGoU}y6SfKev)2r;Vwzyp$oMzE$0LNj9a8^|ScacgQRV5sz+!M+) zA+?zP*kxC^dYo?f-f(^D?=O@!A6ZHlEFsA1p+1`9h%6C*JkXSgv*6Lt_q=G|2Jen$@j@Ne1fvCPRijj}X<4#TWAN2-GF2ieFdxUG9VBhI zrws>I!R-=ufBnKwfAYfD>bvU4>VK=h6;q|^)>F^C`sy>1zx53;kl!%MuBLn}O*c1@ zjO25}B~s5j-AQoS5dVaRz=e)mWLEY#9@e%m)%PJD4jLLrYBI< zBa4+NO9ap}Rxw84GsAI72#7`tq1Pc%G8mEZ#F35LUT|E3-XfxbO4`^F^@KfvmuMD) z_qt$iof_hQ?XS;yO{Lzq3Pe_0ZtsrZ%^^Jourzqrba&9U|__iqOXdM#J zPXv5SJk-O%#@8W|`@%_|K`=m;Lv|Kx^H9toDaKVUii5=@ujvp>Fc&( z;>i=z@pn(O*6Mn}RCOJ@1R2TcgL6eBM3CD<_jiy9Zng^+WOpD=X5?`)3M$bBlP^Rc zx*9%}?Ne1Is_RT&KX9q+ej57~V?s7R^Xy}v?=x;dM2O;$>(~iC9@q%nF)U#`@QxxS zgOjWI41Dh7I^rX+2ALMRV<2Q}Xkb#vP2+@d04><p3*p{grxrxYE9cI0 zo2QI>GeynmTT#Y67~^Z^t{L>(#Tynpv!Usy|D3dQ<>0fGPtO{7%iNj|)=V3Ddv^Bi zBd4ul-i8gMb2r>SarSKw?#sJ&=Zv=H3kMDDJMNCr<7SqXJXBIPljgo1a&Z#Y$%-h* z^&0kT>?t8aW3vGh0U$X7AVm-av$kTEq7CURQ0d5J6d9|9Kb)k}nTVq(2}CGyRdTXT zj)ZQhIo!#LAYTo|xZ%IabJ)1BvgX1iW8QwY|1;BH{lEWv^@gYWXYU$y$KJhnjM|kA zLRIS<)jyrTpq`sJdJD_19DRsoAFhYcA>6OWx}C(jImq^mCz&3LK}$5=2pVr9A8!=K zhj9u@Ec7P?UgQYGFHAgsA!*)<_)_=*;IhL&xC@E8GKB( zSOn~>8qY!+loAP;W&)NLNPI;C<^YD!7RaxX%FzWQC58h#l$>3pmvg)bp@og3Mg9Ms znD)$ovjoZ$|M&6U+eh!p$=x~n_Py+@^DM2gUKB4K*fM$|b6(hWWOOClS~cb{!BHE3 z0f(at^(h)8qfOA`36g21bHT*Oc=F*V5{uBhLs)b>=9W*@4?h-*M0f4ty1_SHlfy3T_}g~%o%8-xk5u{Zts4d5RZ%=;d_V8FDH?8o ze#OtB?>Q(t4XNPJI!M=x!n7EsCC4G&XvQKyM**57P?mxc4|zI9x4;HXB_W;; z6G&6xC=>;$$x)h|U09AXKTn>~a3`Hrek{3ln5#<-$$+^FJZH5KKr&T!D;AH5P^_^S8MPl@O3Iao8{YtZ0^TxMjQ~f1Y|$(R zjn~8xooF62S`oN8Uudf@$XFp+h}8Ib!i$h_C+md6Gn5G07gLU4Bm z3|Ny5DH^tOEiopB>?;fdsT)cRMnegqq}D4D5>UNgiCxd$@MKA#(dFaHE60wlEH682 z*uSK{eo6he2c(Z$Jw$WuCF)Y%cP#1x8ijzJkkd(-EQFj;og`ZJWUf7fIlu^Q$&7Ts zwQse-dIDBpL=>oqg#M}6xkb>;)gsYqcDPz{g^rP(t{pgf@VK)-+1D_OS@aRAhxS!8 zHX0JY{mYLJyG#x~SdETot@5!}QK%)=)=KwFaqiIJjp6I0>3ask#>>4i+t0EWm_?n# z_N!kbqX5o?1MDNUw(XB>&kpq>I^%f3W}&ZMd{Th7glDHuYWvwvpA^Pv$^<>RQSrvd zsaTWA|3c(M5=@TvE9syp2M9ik^I*4zTW*b@l5v)7RcwGM2{;elQ`{WQbSZ}8XrLTR z51*Zb1X?1GbcdrJaFB!=P%!84yqmVBcwbzw?f$dlCJebf`*%+bUY{dIg~-8t1gv4x#9J%|Mvt~WcKcnx9{D1 zJ2;}c#W)GVR{hI`|53l3Fs@A%_gB;(xo_9uv6V#s!YGVA0b`Ga?+jz-u(fyL|4_NW zX7q5b5(gL~7Q?L^htB)Sk!B&ki4;SCwj(p0GzMs0g(5Uc)IHB z*<00H|M%lPw~yRSeEjx3?7{_>2z3kYV)03q^gs6o}aQEtcp=IA@~h6+WJpjC2=HGwC&e<1k-MW>o-pk*~%AUkw!sQDKm7JHuDg z{R;Qhq!Ov=z8ZTHcgkejl>`SZj6u)pPJ)jv&XG-i9D69Go2x%?*dSI6jla`j15MNf znOruz^5tpM=MKK{jyrA~{F@j4`1sV~$EG&U@i#77wy4qn``0#nwDHlZ38Mz&m8Pfk z8L)KhhJ*J!TsC-US!Q8Usr+ieg;TP6kl|IsVA5lfXMuRnl z21`yKO*eonAg2$4RdS>cWdoXS5JN_u4L~;$HE^>EgV6?p15Itt-F|l7%&~XppFKO^ zg~gBWV{Y+i+kH!}8&x45YV~XyGG!k?20Ij4RR#;j66XIQNz$YLM}ltyW~JeCa-)2q zF8)&bs4Z3e9MT>MvG9}7oT5?r&5bLhw88lU?+=;_GPr-t+0IV?4=6q4{{c7E{Xeg5 z|H{MtJc3n@J|2rZ;01bV!0GcAx@wdq6wHVbxE8Be5;fP*i4yHYIovfwpBaw7RI^HJ z4wMxE!(KKXH_B$K91-R;s*NPC5igVr;XXy}$zSA8W%N%*yvOqKJLiv{f9GTM)MuZ6 z{uyRnBA%vat4Dmlt$^bm<}ZDP`FHgb5h#226H)t-%o7P;)J^Jv|2co|YxMwI{58B$ zDr;q*sxlj|W~v6ZScMye)(ZMGt(6Ux{2Z=WCQ2uXA!X9;)m-;6TJRi*s)&fP^efR; zEtZ*)Jw)o#AQoCcPsy|EhLpQ=ipqvKO0>27cKI!H#n|K4++@nxhomX=pD2N}e+1T$2dghYM{GA_-HD6RO}>f3Is7(0FX*oxbbDptXQ z8^#S_>+e4Bz?5O?(j9&J>{OQyoqGRI?q(YXjML_`yZtQ7;knD{9l6Vr?(O1lx?V@N z?d}Ic`ODm2B^HI?KovMjECAr*P9d49ojT!QID`2H(=<55`vPeOf^MUj9U5E! zNvw~Z*~l$`EfrHX}+VB4NPxD{*r5xfJygm~#OuqvRf9Bn}P~Qvvg= zuNX6Z`k0FK>sSA*ytK6ZXRFtLJ#{GCy|YiB9c=foDGwaDTirBZ96+OPy!$7>molkQ zg35|DMUJl(b3u$w$$*b3miT}+6C@+)Hg?dZ%>*7MD-z9Z8kA@atu74N#FhS7awD+@qK;18!nR6Zb9)J~ z9?j8W(X^Dys_0@uRdlFbqbfSou7y|8p~|bXiY`L)bzs~b31}eyc)f})I_IT4X-?I| ziB(8|`gXb$XssulBEN+nIcJ+8)6#`Cf+i?Ps_7}Z@npc01mPa6D12awA~Y}=@Bs}z zq!&8Dah+PWfRuu&ExV48QP8uXA40%UAO>1tlr1Pk#-{MJSa`L#3!v2AS&hX@XHbik zOL`U+W7Yrlm3^-*-EqyVnS*yMeQn<>fBksz^y!P)g_A5L{lWX44{n;`Xj|u)y6HjZ zi!Z0Kl($zMNEcUSK0|V${d0pK{tHA^gg_}~(Gpi$1pANjd8uwuu|*(nvefE2?j^s0 z+?NXMN-fBwPT}QsavJccn(Rlp%%>#SFnP`hDC*KunP7q)n;CU3kXcC($xH)x7y!(w zggF@yOZ&rtqhux^btWY}E4!bM`xAVn075^6plnJ(8Bh%#1tgY(m1b7rZW}x!0TVer zIScU@BMnP4j(DmK#h@go+u@O<+ab0)yztsG4r(ni>{ekblrmuH{Y2m=IkuFW>M9eSLd%? zy?n@&b#pue2YQA@?@V>q-=1$B<;^@cH{Fvy{@Jo!6Dq4Y&iI9;2H9{9T6Z2YNk}qe z0(v=K#Xy3hk5^7UqohHzNV9S_5e2m(AAm_i^}`Ed0&_U|;%C{A{AVXOSCqZQ92pbG zA(RO{s3q2#z)P=kY%P&7+T8|wiy)e`_;x%(u+Z~RdIL!4(b+t69#vsgpn{Kh4)0-3dtdzuhItVBQ3Lnb6g$Op6gfd?MQ7q_&nMa?ZfqieBXxchp;^?7ym6@5z#np3%%(^RW^b6~rzIS6~&4`*lWf`gYHOuQK zZOI=c?|w$Iq~yC26D^jEh51ANhvWmH6wZ z0-3*4jqcR;bHsI@P8@lT!L)xT(d+M~y}9c}`wg1t;l(5}Um?I?^7WlA7ho6Z({f((`#P zDzDemQo!ui4AC`Ev=)o5SZ22pjfWUt2dkTUjMcreiXBE7*_ ze#ChnAeE{q9WboP(`s}>9BP^+XM?GvEJY#4BRixrfZZrBR}vC&H769TFmiuC zoDs2Fc|0$-y)3jv7H*fo)`+{W+cvs!@Un*570>pc*--rW*t@U0`?1meiyEBHhN7x5 z(u~l!a>cB{>dYaH%jc91@VKUCWYaEiA|gQ>rRSw-$mxorpJXH(LVK-Y zBi>Sv;Kjj)YX|IWworXY-N}|~@Ay7)%k}(pBkBwF?DSA|Bh&_l3J=tu>8vJT;Kktv z(yg`BFsfig?V_|}mz2M~?E<4+R{xV4LIc*&Bs~v30Ly|XyBGV3@$~gzqPBh(Z_pZA zQ`zkg=JAt2P9Cx595Mm2e6rUYOwkuvtFgw$2DF_3lHHMdLsivumgkf8!s-m|0=}8S zwW6R|BM~YM;>Fb#Yog?F^R>^*fy^_<#8X+I?6o1|n`?1e9aHD}YCi`mJlGPxJh!abwe#tjfx)Ez*$}+E%=| zCa9{x=HLIm`H|oKPQ8hJ-8f{#m^Xg$3nuwNumCk+Ef}_lUtlLP2|6LxPq&jg%%zS9 zvaQVR5Wg^N*|34W2X-$ti8X*T@wR#$#t9l^K_j6ObskZqeIa!4=_TsKKPV1H9yny4 z5Xa~FOqZ9Mmva$M629P(#Y-N2bjjjJ)?bUve^huFW-NZ}vBgW8n}52xVZzEu7!x!W z=(oo(mpEaL?$xG(TZFcw{1k{L`_90VX$-N@X^q_AF+w~u#0W@qLn>mh*jgb>dLsiT zOnL)%Aw|jW4a43KpfI4YmW<00x%K8yA@0_#V)It^h&p$xI*A=1ST{=3#dl1PL$?@< ziaxSoqBV%chxiLuA*`s$)dm5j!OGKstkEIgQ6xEB5d)96wIC=5Y{KuDd&M_%*hnZ8tL?YZ^Rko!gW=c*v$TH=f?QdF@L_#tj-gumIy4C5;!~ z$GCFg>q2>}Uhn{UrSm!&<4e*BB99VCpugz53CO8Fr4L}C7_u=g7*>%sg}K4mU>0Ve z+5_WM97r6Nlk7a>Dn2B`p~RMf(et62DR|GvPeofq1fv=YHe54q%4=hylLj7|He$oH z@oQe+_3YwNBi08VSn{m&?n1a8%2$d%k`|X%-7tIO+BswAL>q6MeA8Xnj+}5hl;6N{ zTIo5z0eKB@$*{~*>OtI}ry{ih-z6XUcK9e#v9lE4mqE4xb)fRXQNX=_k$&zW=S4$G zDl}ij+ra&)x|Wn*@-atH2_rHWkgebVY8#2&J5so!4^&AYO`hH{eXh|%ML{(d{JSSd z!^P&!k57m#?EglQ?~$f;UUG}K-S^fQc-q>$-U`E^7^QypC{?Q=s(?M`fvy@YjMgbI zg0E5_g7aCb00qYLTw2Q+U2Y>X7G%5zTSkfsay3zrNoh1hl5m|-Ob)`BxH3JmDo)?W zwl6=h>^^A@%l`GhJ~9R_)l0Jhr-f`D+bV8?uMTzIk%+%p5N#rzCW;4(s6d;ZRD+>2 zI9lM&DsA=;6l?c~kxJ{Ou3(3dyOIR`64B+5tc?iqYCW*0Yb6xNLseFyhHpqtU=|)g zw?fjwoWindkvxQyU?=#w@uXo@(a7t)Lx=WFYph*f?#{2SzvKELtJJ{s>O4 zImZngGd&yQNsy+qCr!KI$HdNcS_O4TS*B$UE26G|hty_HP)pJE6t|LgwnPdwCi{`Y>Ri#Aa z&}K;;du`MmYkutKKYy$_b;g02GY`y=#<8^5PpF@rU=7n(te8%FXLOVE74W@={vqep zBX7~meQdb;;;-mvV@Sk@-ihZMXoomc8Su@7Ri~X*pVqR=pw(&#h7s74C((?$7-S0s zqqHg8e1SynMM#W+A#E}vAk3E&&L?xo1R=LHa$8YxM@viq=`pK->MbaSOYjFxgQ+Cg zS|TE2hzTOKm-g<7rp#=p87NDDpH9zK(H4o4sB+3s^$tfn468g4AT8Uy(t>+h9~4b& z{GXRC+yB*9h9+$pTcasfdUS|V;VpHO=c)P!FL zAYwC|0EEs!TTD(qZv;}i&l^=Yx~mFCQy|qwdPu4hGo^@X=S)*=LHNL9sVE1slAKuJ zFB!HM3{f^Il{5>5QD!C85@DYoLQ1a1^(+{|CqBLMx$Ev$xRAJynSVZcaNRn0R~U#d z4IXl*E;0^7WYoY(ZNT0Lf~nOw3o@fGcGaj9KGb&tf|s6*LAj4V7|$^vSWupq1eEal zg9RE&l=uSW1vJm{qR4_^wt+sz8?hkN?envcjty(1o3xP;e=Y^CRQQ5^4OfbN0e>kq z=P!XwFZI)5X#pTe7K)n^8~awtrM8wn`9-vgi=dPj;94Ql5<5gzfVtt5`A>xw1vI*1 zSf?1X)Pkswzocn9|s@*`SRua|MoX=59Hdw@>SwyadBzo^jRd=W^=i= zd1TvDJ>jD$ATL7N2_Iu7)?uy?@Ib3j@?m18!}Cpf+69~)Cm>HdL5uxG!wg4VBdRJ~ zNSuXZxDa46!$TS{M%oAn(YBz)neNHwuyT_7JEcm_M-G@J86U$8FCA!r^Qi*-JQg-L zmtrKra}Q9A@+M&#b0!1#UFBi;P*ww0cl7S$m*#0L*NC4e_g8nd~dVNy?+QR{WD!qKWMe0 z{I5%&mY(_yt1|59^YSXgC_XwYBENu77<{H;I*HD0l zCoGTyJ2Y2v1AFq!-KV?$mDhi<_3^#ehfUaclKOr9bw24(-+u(0-Preaho(IvCd3(9 z(3BPGo2+7+M#mXmoyjx!1LcS_q!N;z4+;f04>~lZBA2KT;89FjoMQ(?7L~+fx(>t< zJf!mSaQpYNHU^Z#|dVD24WCbwVdoKD6xi@H)!A>BIgH~;oX(ze_B0PljQ*6PQ zSbMw$420q<-YKZ9Ehro~5Njz?JlZ@4vN{es(jtmam3Ok>hry|3>QY4u z>TQs~k4573p8Sy4d&Z*%{0y=kJ4!ye@0OzZi0MNSp=1ppIqV)ICT+)TJjiON(og*< zp%%>`jW9&C4d->BFSa(RrpK9$L7~?RLPHz?V})&~uH$vOKJ1R(S*MFV%VDNMp7QEV zxao9M0U0}&j&_CebX3)fM_PY=ie>EWST>Rr zmyZS20sq-px{ZO9iLf!W9n=MfjyoFn?g9_{mEi%b?j0UL=icBE&xK0(a3YWW;&lj= z4xogj31Fbr&sUiaV2zxRCWyy>7i3V3ENA+aIIz(auu(17uxsISsL;A4I+AwtvxCRN zaHaG)+QEqwWjoT3lsHNr>b8<0l?2?h(~BN9k=Fknrg73??D;zKsMmE&se_Mpy4Jx{ zuu}%x4E&@0IQr;2Z4rU;2n%-F!d`d88>qC(3_AsRTo@8EU_2CDnMYd3br%SOE>#fw z((q^}5PMzkZOVdHuH3avvS+Bxog6XtT+miPZ&qyo0&RNHCfO<2O^r5u<7pAxK*x4i zw2cf!94t_fA>)yG$Oo#eH2jXXWKCtr(i?vL_0Wi=_M>QfDqr6?>?<%u&(WcMpeV-S z)M6ZVEG9M=z%EcIV8pg)(O5YFz(FYw0v;_^e!+oJzyeaD$xlu>u-cZBcGzzOwy@Qs zA>mw)gA5JHzxOXBYtpY{wJsr3`qBYY=c0+={(|vd$blGmbs*144iLlF_BElROMyjW zV@){;kzkXChH&ph^K32>=-9k8mhWN}n*s|Xng{iw$q}fR%tvTNx)5_TjR>9%fmCSE{e6hQG5IZJUDsWkc1Y;s{xsj@=60Kw0ix;s|xS zwqb#~io%l`y&FqRe}r$rBQ)#syR&i`5ZBEv2y5Nzz;~?E$sS~bjL4uz6X70SW2|q0 zOA&nuOF^|^IfNLLg(y}ji5|=;2Hq>|tAQ(Bs-Bhj6kv}f16o{_5<@nGjjAn4wxebU zD~4+5o^`fRjkIHNPr6!o<+SlKT@7%M_`Vh=f!|b1ok=_O^-xU>edY3MYSL7wnz|*% zkftU6UwuJ!Jm|Qw_oC`1k`q^`td^FL^!Wd2{3KMqWBhC+=OtH|fjC?o33gaufN{07JuZpR3<#o11`yh9jcel8_d*I zFYIF6iC?teZka|`WmfWu2lKVF{LV`L3e39?GCN<0iBHZnP=T_bgwI^bDFh9r^+UP{ z@=1I+_Vmf;^n`s_dM)$snZmvUKUm#(*ewsA{-WV0?bbUgLT*ffEg|W7x}8M02bYn>XiN8 z0hTr0Re>u(M7b>X&V;p)^xF+((0zpXNCro%Gm@DjQA!JAdlpJK^Jb|Z@E5#oV)=A< zmgVE3dUi$^xgRJdnh@-xE zPbO*PpfGc;?FF+f!H`CdLOB{CH|$s;D2ON`qme$(u(d=BseR~EGYoaUGYGVQU>x>| zGIvDn^UR(KO4V|*TVSiEd#On#QQM9q2p5x zJ9xVdUgprgZC$F^wL-;iRqSMQOPDg%aAEVvIQ&ipVGJCi5JZ|;i348HPJFyuQTu14 zn)OuKZu|fY`#%{IRo1t}+2d(6aIRr%@*c;;75=V;_Uv8Gk9!)GA;6I(d|XM0fA&!E zkD4e5|8B4%H#&_g5NGFph@ODNbgjSJnEGklwf8}RrGlqwYj^-_n2v0UX_t=-dlAVw ze#HT%Kq;KaBk(^}Z8-;ps2wf$#T><5n@f3wu&?ceJ3)?$%L}zaBDmBGJS6rip#opUtkNi|9am1UvH!RS?1rV?a%VX znpan^I<`vvf}LMIbH-ZuE~qB@1LOi!;x~V|trtip72Aa(6wanfDOHds7Achom{#)r z@@OY^8WJT*MBr)!&oxpKQJMnBJugkU_0@A)X$to3%{i`EQJNBeyv1gXMBZysY4nVI*6m!|RS$dU$!YNZBXX2p3UMo!U~3gG z-Xm;EvWr+HRjAV~rM5ssqP8utA1U8j)&^~zN53mTE<0^gP0CS2fl6ricZY5JSHD~k zSXSLQp}J=F>NT@#&b)ZHeC>>)A73|Zj&`B)+VPc(>#n~|`t&EC4ZgE+(42vlgL6H_ zDai$cR*v7IG}J#-J+8houQW3)f54*A17;5@uS&0|U2=VECTNY<piKXv{Q4wqbHYyBu3 zE`7V;Nl7Q3lybhD2RzBs@uWz{lQO_1uM3_W*6<`dR|ky;py{iFri5p@eP475g)^=W zW8`DM_{Fxznx|g{&PewYR1p2R9B=Lg9aUjhu=m2@Q_}@LLqqVvuF%1JEgDkp4SICD zU^s_af55E2Rj$G=kW`vLK6BXQRoYR19hkKmFk1=}o%m6jBL1N=A{^rsXBC{dkpx;# ze!rTboCs@ls1EHJs!D!8(65VlS(V}`$8laE9K2xl-??W-&xXWRlI!*!qb_+@vlfqp zEQ-*3tK31&WMgRjtr6=|02wnFzrPhm(cUgAQ{J&MP>XB*w0*5y4fSFOUy{P8b1kky z@*(Czr6|%Jz%}_h|QrK;l?o7H)&q7 zUfG4zrmH!v8$+O%W_E;*I@aJTtU)1ko@<0t;cL*#zAtha@Li*hLEd0LojL~drO-Jo zwqppEYa~&wFNeM}ObhD7K@tPB4+nUIK8-krbRmxNV%RXL@LtLTY=@&feZBok%lNN$ zT!|+ugFse+;v)P4%$3NZOU5mBEYMaUJW|#BVubB4Q^2EF4uq!$3@9w9?R6GTfjMc7VQ(9NmWCEWEc5#U6;TzpmWk5 zJ_XP@9f$yAQ;di2C)BYEjtjfsq-eX~q!7Nr0|YqGE;uQC7aVf>(=IsVui!yAgvC>l z&J-Q*OiHFH!Vl5Yb~vG*66tw698xa7b4#49q*Jzj=e{_G`_vEG-VWOvCw#6h%=M=3 zbM3z4Pv=~_?)XD zXBupF{JvJ#HT7Uk)3r5Cr#00~c3RVPzNYk>9<-)ppNG~o!$uW8&ZLwyZBa4Z$1KE9hVz{%Wg=wa{5)ft~2k0nP+J;&jKgK zp2?+tB^j!P7pg@?2Wn^eS`vAL5~&{)p)3L*e28^2sD+rl18!0WXg>$g4-?L zz};>hyV4Kpn(X77K4C8k{Q6+GouIP53r1XZ3uz2GpgNU>o{{7Lf@s5rB8j9d9B3(xbYz2X*QYmxMF~v3(2TqAU2Ga^{X-AfkOwI^v?REV~9ULqXBCM3ePr zX>+-6?+xwuLqE(a&ih{Ng#w~Tv4UZ=^{kfE-O(gsx9_6ORJ7S8Cd$W%q-BbUVvOGz z6D`sVj1s-=*Iy5{F10_4w(EGUSC^P5N#h=4qR>Qt;FxGrC?@*Hv$5J5b`*zwJBi?G z_$aho@Ffxd9$|bQwNBai^>d!-u4GUxF#K3S$&+M*)*zAJM&o8_pmLOWQt-@yO%{li zr9m-3`fYR!QMTK5STY-9ZI+~XI(3j27Ira`xD*GrvXSwd4=8b>^pc1eE8RjGF!pA1 z=H?mm@XIa8B%vBl!A8G+BiOmlOH~Z@t;gS5ckTbGXN&%vJj1r?w$*2g_F;pA^MCoH z`o+h4@1iYl?qcu0&k|pHCa~$IIkx^$2S+tcUob*FuHOB3^$bg76V-zU)q^~CO38hy z@m}OU72#KVxu=Tnq=iN5*h!1(AJR23jwG8YL_|(=vCF$g9>Zdrv=0w*d>6&JuL+HtWFY42HX+hp$(X5 z*C--EitrHJGi`_{CL|`&FVD%5c3yQtiexX~4++%XSKtGU(QWKy3B<2-IU2SM9qVu} zaHs&g5AW6I;tkEE3`%mAH<+qXS08WCp<9HNoVp6}bDefF&VvP-%?JCOd~cX6_Hy&# zx?X38ywglgi>|`Q8OY{-A;w|M;--e6lzH`eE2#(^2JE>7L|=|RIL2?Ba{AJoAYtg( zBW-DZj~)>;7)EJ}J2Fg1^#-krAwmnix2@_#U)a_f?KSdPNj^Mt@ZfSRaEBn52go5@ zQlf=R3ZZmpZn+EsSqAwtC|ZKzLkg__f2~~$bXC=v{?FsSlAGk-OWuLxCO7Z*&CP=w zAd=TLAWb7gh^!2S2=WjDl8_OZq7EP+pr8(=SPHeaOOZ0UAwwMotz)f%Iu>_y6y`&wl*>_p!W+Z0R_ei<7xU!6GbV@M2xO z=#AMKE7y4>!jx)&E){rr{Fw#xwlV6~J}tOGI91e5AnlO3y2Ase4efB4CSKNFW7Zq+#97lvykQL@!+COsCnWIt(quB|PhS zR|vj&8i*hJ9SH+dUZJ0)9Ju`7)dhvMwXIX9w$|1b7Jx8wTi;$0tyW4~tE*dUjk=6^ zb}W2=GI`7|kTD#*ufb}u@;5`^x}m8`-SCRT_d&&KvI#YV9=&8Q8vfpg$ znu$*$#sLC93S**i*i)LR)w@v;q_mx+kqAwJFg^xoSDq_GvZ! zHw%049JW0kHP;MfoaJM{P54I(Ksmh#(Y&IRh<*kxTm#5rM>6c-SP!~!9u6iM=zo|T zERi>yoq|;p^b1%I>W**))3VVFGMqsVmXp4tkb}FSfnD99WnOB`X&4|O0E^C%rB`R` z^Oyk>LADiVJS?;WwmHbd*pLVAgAlP|;ZDPQrdNT8#ap_gqGH*_-tGu&EcK31{b77Y z?C*}iXT+FX8=(H3_>4NTG#fpLA=^7g1WMuP^2uGF0=Y@d=~tOK86 z=2o(d!|nr9e1v1|*3G_aQ7-td*&=W{3%|SJOB_@Mc9nyDvCz>*!51ruw`PGXffgkt z@~ojdU1MI-ETUrL@bwFMBM9j0bo|2Gt^%OA`EjZ2*^L+L2WYCkZK=Pw@!7r?ulwt( zJKicQJA3b|(mNoIuI^pE^m*Op{CCSbkIEnRHT8YGbCc9__YTNIj9)Ev_)ex{r*#tT zrye)2N00XfvoU6YN28sq0U&ZJ03^-vV4?MVuh-?aLn6SCk-8^~?l1$N?hMT?fXC?G z5(Y@+(VqjWCQ}gRVObd#1t_Qs{HnNbydzRsUg7`B2LertW}P?dXEz&;?@+3M&?DNgZXj zps!_%dAMP-t#ynzflgVgV7%PKYwjArH7t4)83UQS;n8>>2HRW@w4uQ!Dz6*+OVY0l zi}^v;D&LN1HNqcXZV>A(*^DuPepPeH2RAhkR6yRqjNDf4UIp7MJFz-7<0EYvqOIic z_llpjQr?9*d;)OF0ou@O(`FMPuW?~?j;Ctt>^xz@ijIyzp_!WVv{VsD>oypN^iVXa zj$inb_gHwJgWo>tgkaF1e_(n&+H9KhIlzMse$PQH=YQvK>RmE(tApnOcJza})lCqe zHt3zA)(Jv&kq7gN@4nt#tY1G{X$HsHGJJo)9mBxh0H+Pw*r^|`Zjh;6V~W>;poB;GDFZwt)+#gx&)G{`=KJP^+2hIrGeI1$MlSw!)%TKD`P7EhGZ(Tf zmMJr(-FT;yxkLn*I6OhFhMGP!8W=%MuXC`fZx5kg<#+XcjxNoLclm~~!CuV^HKuud zT}HgHWR4(xU8leA`^hUy%?)VH^MGF{i?VqbFI`A9#s`pkAkVN|h2J3P#wh@X_eM- zy2WNq($WJem^RTrbKz`5AtHq?9r=b%6o;N~Fh%J37A`s|=z2tsb+TMwp>n2s<3-ib z@~v>b&2Zrm`PGp?I%8G(n&C=sA7 z1o?^{FdQm3I+FnF&;ypAqwbh_6JKuUBoB_JqzTazjENK z5RwRBJ(@egc-$;qGQwHH&3o3`NzKiZ;K}VD2!Z+m&u-BV(p_?sz@CZ)&W2zR?3G<) z#n(WGhZ1;HAtWjTfNJQysm8tVyXsX#w+9(lAMU7}cg*H&(g4s!2;KrZ@WIx&1Gd(A zbQkqxvrw3~+>XvK=n|em*%+zthZlr8-N_}rR*N_RCnqaTFgkudgE|Bg9p`%z1)fl1 zGCYG~0W_4zqd5k<0@8)p3t|qkpbg^@e0Z@o70k%QhsVXf(UCfmtdC(0J!QUfGB{TS zrVr2{fdy$$f5@q6l;vxZ)tR@{NL^p+6s-5ZUm@pQ?p9T~>GJCp??0%MvHqoR>s0BD zt#Q8i@~!WJpNjcdci*+OWV|nK>xMmolU0g%AL>B6_b3l2%g(zsV`+U7v zqhj+VrNn^t0yYC_nu7%&4YfMQ(J~GOk$oyoVOd1*L0mq_&2~EQe9NAQHwV zvf3w%p=aPegjp>j3S8$rQpFv9Np9J&p~b(~vDcJZR@S!~NQkSY-!euSC~?>HZR11K zEBvRtr@V)jkfqzBN*H+>6i3>4!x(mG-%T&LKlv7zQ{t{9{P$<{e=)+M5(r|v_5-%) z0ZNnvt{=&upWp`vqf*hb40aUsj^E9W!dnGA`uD)(!UL)b&v-zU#(}CLt|&MjR2As| zgK=Q(2%2H3AM{{Y8%)M91^m417H^9c!`=iKqsB2QD+_HjVwC|73w9Jt`uXAQw^SFU zR0x_CIj5<-qOq|8WE;%5@^EkFfmnlaMcOc!eFMDUkO$lM@?Jl1V}&$geLZnvTFR0b zjU@)Ye^)05t^i<@5QDQ=qs%C&P8|c3;jyV>*vD*Gx#~ui=i7G-UrUwCVqPZ7k_S5` zKXZX|d4f6RKrUg*8*b|;53nnHinwg0x|WYb#bp5FP$(L1Zs3za-LJgbLc$*d?9jm+ z=sUfnCnuM?hMX+4qTC#g=EkCzfTK`3WZ}m(e$)wn3F<@v>O?_Nump92jdF4g`2-7c zP$$M?k`wg9zAsn`b7ja3kh4c@DftXQ3vjt3*5m?4)*P#Tq+V668BES2z4nM+iK?fa zJo$#4_kFDrl?tH`q3zM@)D72bEIvc)lxSn-nYtc|=(wSUd}yJ-s8@qj!R@RE8UPAB zx3rJ~fX{bzwd^Vtz+fmvsElltJ|OITL)coi4BE8a`=Ax_|J#JCRoE+uH1M6G)T=Y* zLg=%9cjCZ@7k>~n`AbT%;sntvffx*Sv=FR0ORTLxe2_4w#OzZ1!+n;z%ReTvKGpB- z-)wEguS5TREMI_a8UD$_K^Y-{aHTJ4g<_>P^$caHZ%~8jEApE%f&X}v+T=2tjl&~9 zOOsR;=f0$6^39k7aR^LD^;2Nqg;9$73^l7iBCq;$@~baVhx#(o)l`A=vk`CP>-pek z7>Dv0C7EmSzBZD9skO`0NzJCiv`gKGV?ENxkv>7YFmTwVoFRw$70##8E;Ft%J%cbA z?|54a0iv}_eH!oHhrBXM`SQJ<7VF{~PHOlwle* zslT9Y%3r7vVWZkfjdB+yp)8H+HrghAO1Da%_Iu&`#qn+C$7q|n7018f_x%X>({%Yc z-2WVv$vem;elz!f3)1>9jL-zdMX@Ca*kbIn1zD7Ak ze)-z|*TL;HSBazs(=`>xGh0F0Hsu1!%D#{wI zOrZeZZ(dE&=3^9XsQ@lu9(je_S@y#Y%c1^nSruQbf*3la$~uVa#+mNBy<5iur7=PI@k>PuS576jz@+34Lz_f z1|PAgXPoBW2OrRd&>2GOQ`BtPL5(bP`C7;dUO37FXhT^8q1=Y{aT14DJLm(1?Px%Y za6NQk9KfcWf_gDUx=6Eeh`O${W1iTKIoB$*mA7fL=^dQMy{IEo_~7T7_LEQf8S3ME zsD}$t=Wv)AqYz&+{L2shb<%06QaUT&rZ|-8O1tu)a!Pfn)72&FPW7P4Y|1ySH+^QF zXg*+ZTk0%ltu5A_)^pZB+oEmRw%uX3haC!cg|~(u2tR9&w6C`xwf}E~8Zj|qUc^r$ z-i$1cTpf8fsxa!TBh1m@Xm`Bnv^ys|mpS)3dz^oCsjl&^$*yDL;>Wd)J06`G-4*>s z%*2?km=|IxHaT`D(O_xsqyjS z@19UH;b3xPa%u9Z6nn~}?lgCed%63b)U?#9)GeuRrlqHCPdn%#PnBn(=aA>6^w{)? z>BlmvGUd$GnTIkz%F4_-m>r+JGy9J@x92>aE9cJ0J(l}HUS!_nya)5X$zPv;u3&1x zBZW1EFBD!VT3&RtST1fXK3@E_x2{Aj+3t(?JzCmXR$lf^`SFUXir$IY6Cd#h{O$fd z{^u%_EB8#woV0P$|4nX~{K1q}Qw~?9RdrUKxF+qIUtaUk)WFnZ)iu>0)il@KUi0!8 ze}Aa?xaR9xM{Ra(TkW3OQ+4@u8|&V!x7W|d-}?H8>mLqe2etJqUTc=Ie=wF1Aj;p}o;Z@ho_+bePB*iWj*^E>gL1)=Bg^+s;T zzK?UjB^{cF*&_cP$Q75HpHnEx?HiT@qa+0*o-p(APSYzhX0?7mn@Qt*Io}}IM5xm~+1)t_VdW;^C%ybXf?KjW^ z5@1Pbhh)S4_iyQ(6h=R#gY+eRL6_)Z`W2m|=jkvsbQA4_TwjFzPS6YVdwPlfhhC=h zkos$Mie90AM_u?FUb?5@JN7zi!6)=7ZKY+9`Yob9w9^4-!+@O24LOsh9o(yjh#+aVdeGqTfh~QW9;K#!C~x!j~es&5M_>UA4rk1tpd> z?MsV`i|e$ox>yhObdCOdjZZsYQ>KT04oh&O9(wgqT#xhOdW5C=d2t`o<$Ah84=3uO z@w{p+?bV;_^@iQNbn%+iixw{ESfc$@641i3fLgz1^-7T_3)FHLs3{itKq&HoP~-z) zDbW*B|E6wf2VK`~ZE6Wh(!DnZ1LnMz)NaR(*L6qFMC8sJCv=kuW9bi7+ITcr5`WCjB*b zoDF|a#(Hd^3vY?ww}#)*kGJY)B5^^)J)vY2l98pMqyx#Q+)&bqq$4GibRp@CGm; literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.woff2 b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Semibold-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..1ef7b6d17a1ef15c79e881086b2fcdd2d3460eda GIT binary patch literal 20400 zcmV(=K-s@{Pew8T0RR9108g+06951J0MUp508c;w0szGT00000000000000000000 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 LrQOM3cv8|F-l;*& literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.svg b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.svg new file mode 100644 index 0000000..45b371f --- /dev/null +++ b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.svg @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.ttf b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c89f2c68dd6ba09a2665b67308fb390e9ad9db2e GIT binary patch literal 53004 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�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%0D9;IG>Zt#qf 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

    5LltxM;9yVUJoZ+-c(T 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 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.woff2 b/client-wiaas/public/static/fonts/proxima-nova-web-fonts-master/fonts/Mark Simonson - Proxima Nova Thin-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..28d9720077b44a0d27b57a96d7b7097e27cfde8f GIT binary patch literal 19440 zcmV(+K;6H0Pew8T0RR91088)y6951J0M85n084`a0szGT00000000000000000000 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 HZPWSIhfq%e literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/img/CoMarketStartsida_MAIN.JPG b/client-wiaas/public/static/img/CoMarketStartsida_MAIN.JPG new file mode 100644 index 0000000000000000000000000000000000000000..802a690dda7634184795a91dcebc64f1bb053131 GIT binary patch literal 68107 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 OmBER>FdFE8&HR5TLGy3` literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/img/CoMarketStartsida_OFFERCoor.jpg b/client-wiaas/public/static/img/CoMarketStartsida_OFFERCoor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c0fa7592619646bd4b2a22724eb98d67a151747f GIT binary patch literal 59023 zcmeEtbx>SQo9|#r(BK4jf(`EO8r(fN0}Sr&?(Ptr;O>y%?mjpKf(LiFyzeKwTeWp- z_x^pmYEJd(ex8=cy8G8>UYB0C0H4I&KxP1dv@|W?1K>Z>>oEXL%-Pt=9RLM@eJkbz z0A9CX%q^Up?06U%Z5$a4O>B)!8H{bgjBbW@jLZy7i~v4CH#j(wga0w8Irhxt!*56 z-1y1W|5q_18Oh%yPFDP6!hiKjqA90HB5LbkO2W>-0W@Z2V*!~dQ|84SbFaLHLQ=2zW zad>ly*HZw>--Zq_`SIp@P_Ga`5a1mwEG!)CJ2<#^@bBJ!h#%g)`+$gqfPjdAfP{+l zcS1!%`H1=v1qlNK6B7f203RQpfcW1D>izro$VkYaP*FeOVWDB+{k!6SntA;JK>GmI z39SqRg$95|gMvYWdhG)&yp0bQ1`6swA_o8l7VaGs^!pF+Q2$K-Q3nP6S0yR{3I+xm z2JVdp0SO82js2|{fCh*Dj+7ZgScwety`jB-d@YMIIo7wIA`UaG*dL~i67uUD6YFOw z0z_4e0}I$xoha3C{%rM#1tm4Gi#tkyDY&Wd%eV$>rhp6^J(M#=u}bp?O~ z^VS9$3>rWXa80Hu-V&LCbcOf8_FlNUK*;I;XZ~M>@ag0RQ4#d36dMyaj~W5m?|=L# zJOdA=5B$oAMNkkgVoJr#MlSDDuk|dW5`mzuJ^)xH6v7%08SUPIl*{ry=?{@nx{V8Hpi+bVDn&tg$<& z7?N7&dso~|7NT9>*(?+9$g>}NQ|$Q)K>wDITkKizbo-=Y5HCLT%(_Or-@X0T2rluz zi-iL_Il1kxD!{o0I{_T}71}`+Z zLnW#~sfR@8h(frCFrLqE)hgdb-P><{XgH%&r>gTcqa@dCN>syqZ|e^!G!Q5!=?J&N zHlGI$<&NjXC<;8vIw&Y;xY3NCe?>lN(|V-nr|~G1dQRr9XuJZT2d|txelbCww`~P) zLhn)p$*OgWKfMCnJjY%E+k)GgFEQ1sX*L_BydzHzod2M2Y4`^5ymc#|F^cq{ zeLZjS)ub5sUAS@EZ#nrd3R0U=r5s;ep`bWvseb6Bvr~RO6oa3Z5le{_H#(RDdPIC_ zXha#A6J@1$H-EqRyt095sl2(Bw?H+DO5ZglS))3tY1G^Dq{h->QOPzO5+TE%gtXlw z>@JUPEj`27n=Q^q-z;XSrSO$ay_11&vaMJGk!Xa5m0%+miwNc?R2jx81vs6Q#zh&!k$ZJqW9*VO zc;w^&1}LlXG>xuJ_ za;mho>By8#Fl*A$TDV3SWUEYSWW_GSQc-F1cXK2AI_>_P9p*)sRq0(hc3~s7|5W0V zq7Tn69!O*zZt_Y{u6@N7=iI#9kit#*W3+r?X+l!%c(NA(D0ozj`ljLA8RpMKW)^%9 z>3k6d`UimrTnqD}-eP*wHlO5%k{z}$4ce4m2k7`wF{U)zKCD8Kt)+4(nLNAn-gvlF zs}(y(?bh!g$BUvg*zwflM|0T*jo6q!Q!ooWKjO3~Is8Pqq3~jdwiKBZZ0!jUWT%fg^e_JnqLV0s>YL(pUMfh%PXD2hBj{3n!WlI~xIhWbr+@qx`mVA}U92vv0BK9_Rl*quh+O`+PqI|hvEZ*ed-({k*j zEc#%S;w$<2`5(@T=NIQo6x5ANCiw(zcz{{P;UxzgkXL|}=qsRt{a&qi|Izm`=@r1{ zbE}ZL{LJxK*bp^A#G<2`KD{hEyfAD(M*{r(C((g{e}2~7@q5}~qcLASbAQHR$3=K< zZ3ABugJn{h)z=TgWe*$O`+7m?1YQ(HDwOQFv>ejz zeNFH;mSk0HbBnm0`Ca!v~93FiK^3-TdTMoH(7EVWKND**|T3$3Ujw8M)@;#Ln}Oocq(k|RwNcro2UhuVe5Betmo z6?28lEd{jmfRQI zHeWmn7H>FZdl$qWGA*WCl~M8(kZU`0W$ORNIY)HW@YPNa8#7yNxx966z0!%=iSKtZ zS&-Mj#hPQMHAdp;PJ>jDB51Tw2UsQF9u@X!Ph$u;tU0etr-dix3F8n5?^>0=3uO#P z@A#JSBh}O0;gBcwblO{Oz%$xgk5KLKV$A&1cBY9n{HJu{W{)*Di>Okj(oAwkLsLSz z{*TfaJ~|y&6nNVS?LfV#RT=Z`6O$UI;Zo`p?LC#;vRc{ zoBjn2=*{#68_xw)CfpbJvajxQzVm2wR#rXOYTajh^LwiuT#gx^SXa zYMSJTj=g!v1n)EPEzOIC)vp_0xvm3gjj}#P%s1~eMw(i4KQy?&4`C`2t41oRG;J14yQjk6>@g2ic- ze9YDlL-1&dAKj+4lc0uH0!4Dc(3a%MXTpTpb6Gkg%}|9ecS=+;={BW+par{D4S zE{Xut!=-oQtb&4o04`_$mCg^_4}S<$T0$y!7Yghhu*#)RHZgAL2)oD??6u{cC3|n> zeW`BDTr4xad??O|PfLzlx-DJ-saJ`6zN3QNwm4&dE>ElUnxD)|^t)rxa$|Fs+I_6P zd-xE440;84a{60wH)rMmLqri}LKpBk(4hs)7hE-}59ep`8wMtCY6ZMHxa}Q|_bz3} zefTmYB$o6~dS1fd4rL=$w|Q1XMHahtV#nu?tMCe%a`p{I_6N(if4zK`mEVwAuU;O# zFn9LO#&;j`bQJZ_XWyGjqXWyxC_{_CfW(i>S1s?54N4!JPm4VxR#x`NONfYX4&oU!_ zFzxlyF&kMpk95Cpgk-|N3%(mW&eu&A@ZdS}YH3Ki=86PZ%f)W#mzZ98^E&n4>@9Yf zbLV3CdV8!}>0?#He5xL?vaqqH2$kJ1p>7zB*q>1jle%@|(m-};^wfI*b6;Jeo&Ird z5Ib3Pdokm98r(TSYQk1Jk8&sx5tI&HnadMIGn?n-Pt;#DD|ftlD1U}%TqJsvxvHN( zYvy{%7~>>8GR{&J2b$x@6gEB?Ehxus;N4oB@)MWzKb7Cz@jbF%-?AE5;+shL+Ma%j z+eOD87m@uzgzcnfC~y@S8`2>tGtXc3Fyjs`_U+%ja!rYD+cUlg-cjwp0!~wSUjd97 zf3mAxCSL)@1}_Ht<~g~~joqD(sd$gEImM@J_j32mB{9%K4rG(Q(C8m~PQ2uAczDM- zUn&-FeXV|5JZm!=FbFoURt-A;?0~FlhZ#PVx4iH{$@{H*?6cZaHs9Ov4LZs2`4n0; z{SsTUgL%kf=iXo&mCN=DNNDno)+OF7ZvWyu=v@CK_$!p_Ss>YGqhl8B<ub-9K35MiZljH*i^KG6UMlxJ?A4_1&oRkNk@sf09&68R$=-*L_)SjA z3omKuk2!?ShYgZhrH|&OMwf01jgExU+yvn|!7us#l3|4)K+ugr82kOp;DPpIw0_m< z%I!|pqyF=ZZCOeNT)EgtGs}^6V=B_NI-7j-VD0^GnMwmzm*uq;tIE4E@Imh2 zg~x$Z@sXStC~;8V{y8?Lr{d6C>m$i^JNjsZ)?H$8`-<6G5!)p0HP7cK*2ixXWaQ4( zTeI`G8NN@luK<}>z@A3#+b-`Ffb(Lm@NBSrPeIyzfLLzWfHt_+z(889hXB=+PaE6#aoi~(FO)fU8#-4IoI4#e4c`F_UVW?rZxGh zK8W+zMqU`RxvW`4+pCYszq6zw?Zz~*1Q5Z!98i%^*buZ00}+pym<0<%XTY|1`T zv78IAO8L^_m-{r6OPyQv(fVBbbkyZqd&&k1NJBszw_2nIpJAqW2So$_Vfq;53EEt6 zWV8iVOObhhdgr%rooIi%EGHaKnWP+IEKBEEg5~JcTv+4wc7$vnW7|Hbl1Ai0m_Ma> zJF_UQ314jZtLft^t5QzJzV*e%A!MUEW20DWq!zh_LX;jDDxl8soCw9tjX5%-;^D%9 zd_Fcs$rN6$g;R%Y;gO;rQx&^SWASRCPGhe1OCf5l+Ie#=-buQND%~I3(pY9r=@P(a z#TfKg$#)X#hqzyvVrD&%13?7AF!ZA|`uu%4V#Tk3HY|9Vd|H5vq91$>RrFUswTswon20NLkKt@i~WOuLEBYkO9jrpxq!x=&JC zK7ifLv%~CrkBA?^IFv9{*G0G4Nq9_=ww}9yUJeIO_9pmLZrtmv+?6QR7IdD2cGIbs z($!f@Y+2~dF&5oja*`?o!*5&9##l5rTP?ZI_H?=?uyU9CN2im(qkfd1&pyX(e}5;m z{Y50Fq<3fXCb-`4m%#MOpH<~Xo*u9E&f*h0oZI4ouEiP8SdHe2yFvIzBBEOZiRIWv zgF)~rhq;>#b3*JQ64#{cK!c99TKOK0pqOKIW_j&=ciY;bggyHpZtO?ndGFiB;%wHa zU%V~nHO%ddl-P*yhCwxTs5vv>zQn#p~+Q)4l1s#Wk&lJ%{3LPM4nO z$VehHoJyMFgwVB%>BX|In%OdnO5IIe@4?p$BW*`ImgD*4th4&Qp1;8-uH(fgE`y?$_dFcMq6UQ!f|`4K1kOJ8XX`as7s|Kx@1&H>a=2TDAw_l4l>G{_ClBC`^G=mgJAgcEds<3lH#FK4 z6%=b);m4Vq+92hK*Nu(UvS1El(@2yTqPlzS^tLtXaaM!c&4&7$%B)qTlAU72zqs751M-` zrKd4nb2p;}N5+{4F5QDW65L&4w?Nf`i}}W1tYe%yWJ_j?sV=o%EX2Aa?5kys`6AQl zX>c)1FXu`a%Qr=i2EiBxCF;i8Rg8E0kCf{iVz;bB7!NwzY0BPA!!mYS%ROSjITvar zZKAp4p+T*h)o98YdT=8*UclG_9Jy|R(w4CPQOB3ysy8QhKyBi zPNQH-{oB?cqZZyuaA#AETJW4rw9g){MHv}uydl^>4c7NGY@i6jI(;h7``=E-m~e2s z?lS9OQ#^T$AzEBRN{h5$8gDtP&IsT4a^;nD7zDaa+D2|9A(C^v&o-PWe{SGDCaFL3 zv_7OzJ3uPPWoka{>k@c?XrR|_$#Rkvlt*H&m+=EVx)H}kB7>umN=uoN+Kz&C1zbaV zm$kC(H|MOA_pOBGH~hxT$b!oXgRYSiPQ=MgS_NGP(fmNa2`N+3t1sr^1(hXxT4LuK-(OtQS$C`PB?V%(fuXYb;8rcdvjD zun&1%Jy7JwxpfY;!jCvwHj@M6Xo&PHAha%>DRRi&99J1T0NvV)YBl=N_Dh0HJ`*>&!9dah_R10hO&LsO__|QyfV3}k_l(NkQj|2F_GH-QaUto7o7@l;t70VD zW#r2)B74KJt7c{RnTGNb`wf$zl`0%~1BE(n>1AnzR1UFF^ksOJs!9`R@gH+?)hhkr zdtD(Ip7Df+`NX5=fDNh7J){kxC|s4^cu~#8&k*wnrKoMdlz!T7pQOFvH z2XS-ShUC{QFfeLiOW*f4LxdHU{@|(4`N^FXd3SGMDU--$d3x`q;n5<1e~PL0f1qGp6phtr$WWF$Mytw1+8N5F##74qMi=GSLOAx`!Z- zhLvPo=I07=_JiTtL;3w7&86Vp2%AF#x*h>Avv{4IWFRhoEfxyhaP7nt%l zUiLqIi2dr{EjfQbVpYk_b-ZVSrehcv`{@?%bEI8HbQ64O#X%`Dn|cu&Qavu$rzqWu zV&S=36mm=FeXJjV_|bI*gtE{mZ{cfv&Q4Z_k+j2%!6GqXzXT5pAwGD8E&7{8-4pA! zK11xeWR6+tm`%DC*(R7jEf@DzIe0Q@N^8<_y=P*s@rXs4K zG$e$gVh1{v>f+7PH^o*-?tDziE3sDfJ&+=AFBKf1jSH`fpi_IuMethR{Fy`YGNgeVL%2LJ7_NF|9aqbspEybN+{nF6 z16{5HyrHJumZz%lF)$g%lo-$V(_bEjAkYSSxr^PK)eMasGdXKOo|gJ;Z~nj1n=o!7@dCzO;4k)ttSlEt zHuy>w;11D_0!)ABceW*ji1AWpOC&VmK0$5pz%j5f`e$7^Qs#(@LSvI;kQXi0HINUl zg0HPa`m72ZqOW5)7ij82Y>^iqndXgrU@xN*_CCM;9H;Y4*-$TWIz6gBGUKxNly8#; zdlyhmb-#UWQ4RN<3a+eufNiJ@OzT8c)7S{YYv;A5y=l(cdc&uX+F`)I!8DB(fST(3 zKb&Ae?brcg;G0_wzXE2a2JM}EqtwU~s75T>Pm66d{$=+GSB`(AA{zZ@bg`(Hn1--%?pi&3!E71>M8xXt$!8-lL-Q3{x8 zXr&R5@e5=4`oGwlnMW32@+rVlKfQ}g@yeP43t zl9DLOB!;D01%3(-aC8@Ydd@x3d!KhkRb(C4rP87Fm`cS=@X*-nYoS35!G4`kw93g2 zYQh>D>CgKSSBp-^P4VP>cJ5)CsScwlVHY7Bpr|LOwmNpMW}bC583lYo^Z2~jm9fs4 zYYE==SVO|@z-2BaT2@K6^yuwR9VN*?8jFqxG=#U3AtdcX)~+n1>m69kt7&h0z&{jN@L>oVALNb;*jX5Gw-6luNmn(ka@e1H8Mz~L zPFl89Mj5>!h}uoHhCPM^0k&DAtaV8zMq*9ouG^hOFws@n9Y$4^-2#5wx&|?eK9L!rfH2=%x^gj zzC$f+38plag(ATiOopZJ)~`P{qLP#E%h-AJ?k{j3ytJRmvebbxX*j@6lQq{w_5+SZ zPHEl>mZiHbbJXGsT6ecy473q7y*oLP zn|Dn=o9{^vAjxElfzbBF!RrMm$-$gk?g_!ArGQ*wv>$=oISn?sjmc4c$K39?ns>+i zEynJ@qogC6m%qd$qAfa)D(h(6v?Ko67oLS(%x+G2R6 z1UUDIB0EzsA{MZM*!dZTgPu=YCUsWr1+?RV;{RWwG}^=(^u{?Ct>20ax9iE4W;cdhKHqMy-(22{SHU?#aYN$_XIerM?M4P-Q3 zMe(6_7Q497kYmmiO?fm*WEgMbSYHT?)m{!kFVQ_1K(OzJy==ux@`c5FL@VxMoS1E0 z=GZG?#1B7Y(K9Tfq=n}f!h}}XF$lJrDM{=u_vKbN`J}nf9QeVo7&Y*nFb$X*dTRje zE%0#RsutE@#P|8agI8ADF+EjMj49s(xV|B#k$z;oB12H;PZ)$ZC(98Cf38EZ2G1vn zuX%Z+4n$s1cC(!{5sYm90LGO>^YmrCgMz2*{;rXyx;ef3RUr%5%IMd8Y39(3N2NCwT^OI3e zKu{o~Cg*q4SHWpMhqNOE>{-Duib;qBAQn)pCdWt_6e866ZmEo?l+bIb?C~9?c3bY$Sy9Zi>E(3&6X97~Cgj5YqHee^3I)Mk z7K6|Vk$n8n9Z+7lGpd}BgweBVK{zmGqqlJ=fWhZdtOFlrjGPjYY_gM*!$R;|7ub+| zHB-r9s|Dwx790$>Gd+Y+`;r27Q`u=pH}P^r9*TOvgj801j!+NwD~w+ihcoz`vZ{mV zeX2DMwl3ZsI4u%OhB_7nxitdQh9jCN^`wCu9@2`gVK{kKoS(az7B2fvI|k;HGZNE( z)JF`nHcv02nKx1n!;8!uWks9KhjHx1mLG_aMLI%vvqGnZVp8bH?TLpKxf zNqJSpw4ZHzYNC8&L)erzQ?RjFUe>X|!tCNM`-GU7g%`B|ZXy_%_A^)_t0#qrTt-=@ zx`=8g`dy|h$VS(C&7YhSYM_`mapG6qaRX1Kh`My>ny5UFe;$aT2xnJq#BXTRF>>Xl zfhEeRh(FmwYk&>c?z^HoP0Ea>T-C`!LVW&{o1!}BZAlu1jobY*q}HLm7lRiAnpM!) zJ$Njbffh4W$Ayxhc%!{avZ zcvSa+`E;`GLYa18N&}BL0nhylhTV%x2L?Zaw8z*A6cQXvHQRR0hCMwy*TxI3-w9_x z4z2r`9FZ1q#h9JTv_<&#A$2U4r4?CfZ}hteQN5rzXoa8p#KuQo?g~B)is;S@=-{Q~ z#v}CS0yu@oTt@(3C#>rXMhkNrpD6%F*oQ|_nr*^T0KyebO zszpnyCCMQfH@_OLn7DSuP{{4!m?wujcY+qjxf)dF`1Hd?=k*xch}Ktgx?>wbN`gC)p_OL03}DCe*$kw&fr>%)4K7Kvpbx!(=X zxLbR71pn+ke`nUEovSP-v9dSRt3he1J#9M=ByxMPfxmoh}5p1 zRk|>#U*P$34!4^1-Fl}>Y`A3ZmO1~}Q+33e+0}|`+F%qJFn^#`_HG0ra*Uk)4pB{a zBzcGJF?mq3>~UR9JNx<`p2%#+&Wt z8^so)@{L_0QUNa_Y_<1UT`=}Ps~?#V6UoFLlgI}8rLxp@Pmg#Yr7s(MszPM%%eQb%z{FwOAzngf=GCH&Fb*~ z*}M8$Mgxax0$qq7=&E(Lv#c+0=&Q=Fm*uEc;s+TK;zO5et;X!CG!KwPol$|J)MZa7 z_oOQ_4h$LIw#|~^0fLS-Hj1`rXreysaJ>Sq5neu26YwACsE2@sGZpDDeYMQbXD_C4 z&_+tB|60M{(|$;}oF6Cu&B!mF6pQS?WQ73(@LARixD$V8;Xyzhf6#T-8MZVXSw zBT@mPzz!Er?a0KgIXPRRd7W6L<_~*!S71akPhYlHIeI#Ws zPI*eLN=I9OL{JA6PoxqnNl_C>#C`ujtne%wp5+&xl^GkDmY6UkJorPl%ybYEOle)% zG+RY8h*d;Vu3-B$Z_(#W_hz-<<|#?CR{0&qr?DkenJnFgj{MWcFCaScbp4>K2q~(O z)4YMRYZUp#9-FAu=5yQHuwdLLAAZJ^U-zML^|MKsQc})_{HXEHTB_L5-K~GzhsIl@ zhsCnagiF@NBq5$M`YkeHB1s~uh13)|F8p&J4NdGXS9EGj8iB>DIt*MrGuz5XGSv2U z%2Eg-{xYFV7POg&bE^!;5}WpAaRGL%@XXd@DQhpKKWA1;J_um)7RktTf!pP(g-v>G zkWd_GQiF%ZN5m0k41yjV@DT_zGL(aVW9Fvy8ArSmadI>5Yia5|{g(e0plr%`hFV12 zN^ek{J`^~d^lvMrOQ_@3qF_>XgvCuq|K%Ho#6qQogZ_AaUd%B!RFw2g1X80{o zmLQ_+;!q|H%9a_($(7AiLJ9kzXRbd{6Oi)<>M-R^`yx~0}F}6(%RB8p>6(E#`fSRT1|EH&lsQ5=?)}R z2O(d%_NOG3r01%?=4rWGt2mPVbg=r6$&KiMsm9}XG-Lt2ogvJVf{KX{A&EGp>U#S< z4Y?Wxzcd$Wk#J0`Z(O!6Qz(kanaI=zP>qmo>M@69g^1A;Ff8Z{j`FO<%}otPKDfC+ z?xrkGdcJoOnL{}9{h6mh-eUKuAIMFgq)7`-meDrpf`~Iilogv}8mY#MWMyPpp@mNJ z);bn&R~1Ja1$fSBZ7Z?@^n_!y_vcUo3ly4e^1g3-3q9)0HFMl>|8}%{4?UsJcQi|=#ouT5PLy+isGo@w!m}+BEB0acMSF<-6Y|D+#7n1FsnTb+vp`h$}gjkPM=q&ezinMx52^r)^A@T1e+CHC!<&Nsf2t(uD;2+j>aA&0gE z_(tftzau(QiI1BP^}U=^$!Fe6&Pt|f8A4Uhw*Vdkp94Ho`Zf^A$&P8+jBfoNUEwPx z5y5pgqyM-^c+&9Kncp!NesRqJDBEV2g$96a;Q@B1*=gK28Y?Nhfu{L>+KO_#nK-A+ zZwA~{k?6SAT)(a9WG46K+%cA@86m7ZMQv#+7{xle?+V5cE>7kLnXZl?z37LYp62_U zNPC)5(-J^k;*7%b;smZzOXx-Z`R`WAO+#T5ZtXWbuu^FF;aCk#qcpM>@BnmFdPWsXP@Jt4%R?Y6~i#bPpwTCY_74p#3b>*kyrr z+N@@~_s6mkSj|@hA|HtGC{SRn{IZM8!qG#D)Qz*cb}gHCerbv zXI3!E!eU6cauC!T^ValkX7%NdtmO(&9@vfC+N}GI!on+~r8OVsp0Q$lp{i5}SgzFF zwrWPceUK4(vDi*r0*^G}Gxbd^ABQEHT+9gHjRSr1X@cu*&oLBU0m|KR8VN*mjo$<2 z;7YN>1S?tZc7EjpcajzVzNKK=-ukH_L%JO8wal4X7cd_f~a_+~n7%(ok~ zu!0uYp*w@h<1HXe0EP&A_MU+KTOD%>N7rk~6oz_-8F;HE;C158EBio7NyD1$G^DcX zh1z=oh-h_n_=6V5Ugau(W^cv#yMmsBTMNiM8T++=nn~Mgx#xGKiDXNu{XD}&Fm|b; z^8h244zRmf%Nrn)1Br+rLxsO;6WSaQl~W1RQQoVsU`ESTz|11d0I+Moe)h=QH#anz zEt=_R-Vb4k%Y7|JY4bxD@@>teq2X_bnLORHmlMl4=k3ZpRDFh`nE-abwtZ zGBm7YV>Yr80T2`)`)pZiMHyh}_vZ!--e=|1kMmfgu(Ik?y|{o&6k^V*r)~s)UnSCk zY0J26p?|;!i;TopC-RtXo4pZ@R{vd?Ue0h!*Ls$ zg1yAw%3GTRG-t1Yt$kJD@ydc4%(VFdcvo}lvyJYA&sVh$LJp?mF-7S)H?E* z)>e)+%Gr}Y0)p6vkcLb|oUNNpNKGo|fJ3*_w}5(K_lo#SOWIV@;m^^w;4*alaQM8uPV&@dHSle~B*Jcd`&eP0;%4aIR& zP||^XAjhh|thwZpnpT)^BqOl6D3SaMZH;vuMvaZ5go$WV#(ax1el6%;CmL@`86^Om za@J?yDs1_-yq)yejRhOPaWgbw)2(89_UYVUcqhjcZ6m#;{3Bi(GBDJ*OjiqTX1gt{ zIkG7r5C*s9QnOpe{?pPO?l7-|SXj&RMCz*F(SdzoOCj43&xWW8XpSCT4I;egjrPNw zNy!z7pfC&f6`*;I76GYhYl*`yRwOho{DbhdOtfsavntGXVcz4lb|5A&l6 zEs3ySSZ%X5r9km^+p_j*7=$M-&R_w%-Li%F1CS9XvHyYDKPD>)_i>gmN!dl`j?-(- zmyLoeNerX_o6Ir`H;^s!Vu@}ep8;FP1uluZ3N628QV z_$jZ^iH85O{Ya-MzS|UYysER|^T};3oj;5f1M6oiB&F4ED<5Axo}iA6nOK-sCegTD zDKDo7EamRKb@0OI)Q;#_Of{EMVnXWUg4xJUMvL#L5?+5WlUH6Q$oqz~I&IrcpCdpV zbVTui-Ae1B9C$Hl!;w=*H9cp;iSz}b45G;}*^sEdlgfi`$TB@UvKoL>@MiRm(bho=R;^>}!D-Y*vk!-ive4#6>&(!`qbbRr)S-e}Y#cpblD6X8AEKb9i%-2ZgWEVpJ?_Gu*kxL)GFt(+f0$ENmiA^NvV(@;{&1SPI+7&8gQ zIZ1`qAaFG(w_SutJZM&)P4Pmc!iIoPivPBvS9w96Fe#Y3K-D?7N`yObXK1hkCjwz-Uc^W)YrO0C(Ql?K_?)8Ic@Z6pj7C1ynFTo6 zOW`&wJlr2pQZB$)mX!1MC^5Sg4yV6#!uq(^%}i(F@AMz)`k<-5!5m?nVPbhFz5jhj zINANzNiu^hP)A9zz53Ai_*>@T@s+I(;^t;GU5~T%JOF$=QX8L^213wln2KJvd_Y>{A_Pj?O ztz8qJkuN^8B6`&C#A`Jiw6-4sE}<*M+lwd8(2?l+dmDW8HZqQMAHyddXzPpglY&Lz zZ#1OB$!-y-0=)tbvmWR7L(7;g^BSQn;qpHoeR<)^2NwKm!KsnKe9waXp86_vny@;k z7d*CLYs)lnHz+E~VuE#zKp;#)UDQ~`lLb%m9zc8ZC$HhOTdI?Dt<`Ngx;MbcM}`{S zMkHw)ApyBZPu5CA52l6-OQ`DNs($u)ACJO&IK<3K@m-pS>JB1^0_q#0p&UKA-=Fn4 zynTL}t26Fq(vyxH6y6qH?~W)jEAs-|QyZ4zRr%_kx(>bOJm;9JOEY78t}HPmWBb}A zX`0L^!$z*0tRPBhlrmxMEVV4PhhU9vybtleV~dO#KQg&oA`bm4F z;ROp+wB-b(`mDvQ^3|yql`%4nU_&fuXlF7h=Mf8G2BYDKIS;OahamVkADc6bXOG1~ zSgL>NrRnL|NVpG*Q7yTa-qUFbGgvhR6izwgA^f}=HNs6_j_hsNfuw(sa01E$TS?oK z4nZ=&!T{Scns-kYtaY92OAyk~<(0dT+I(pu!@jaXJ^jq2V4jOCJAX&R?>zy;b8?Xn z8f`9VnK2Tgwqo2AdvV)w=tmt_fDAosonea6?8F^T1pLzu8fUZSo9;o z2KpzoKVNPUQO+-pLSR{3FXv~tXc-k~mW2ZyQnFsrhld{!f1bOWDcKY6vSybm!Yq!B zfOSE<{*h0Xdxv~;jiqH)O3hf*iNaW&-tNuR9arkK6}esnS^a=*Qlc807pX}eybPOrTU zCNjZNru3?r4)zOs^ZETUgWSk~Tjd--=~TA7mZf^)HK-{QAl_e!cjEhngJ{8y+pmuk zPK3tKsd7G8k^x6Xoj|*1Si4HKyu9uv&#LK};A+%*Uw88B&6As!1{Ac2Yy|QlHb3@4 z5y$+`+JhoKYPN9?#seQ)c2>?r$gyBjPS1{P0_Ksag*}gYC9o161vAqbuxNu<$^d2y z$qb`Yv0>Oj32d8NyxVtyr zcw<3>HSUrGcW>NX8}~qP*WgZY4;n0x_v8KVb55PAvv<{Zvo3m7t&3hY<{WE2&+{9W zS>dOK51)VA;rqZ4f2TMgl;;Q90Y}6eFSLIJ>@q4Q`hOO)<`6@8APl*L%srgE{Zrw@ z7>YXCFgC3oAqxHc<7&}$5u0q>z>M;ZC|JmJ!?#N*Xmmsh%ic7!1PBV;3(fs=jZ&la z*0qgAi(c>=B|Ird2@;T}=oxQQ@u8mesh(4Qma({`6?H*43xM%=MAvy;MdZs#tq4KP z^ucNlJKK2X9Gjf=M{Jyr73m0(ZY;HRig=zIp4V{)xFGC9M8A#7o zw6GtAbxQf68(;1<{)*LZ>vE1(W(xv2!s4P(oG@^JP9#=bovzb^`~lg~r&7NfE8)6x z1nJfb(eey@Z4KveWtHFxz4rGMra867->v^TYOR6&u^J47+-`l!5c|Dm5W!idd9+3s z4baIBd$?JO?85$GO=M5f!><2&BTyG5U{ z?*sgQ6M!uvdh7EzE92pGCyJs9?9v%r*pn^Z!>N9I->#Pg-Bln>Ja&ll82vPhE6--K zkYUy$UW5ai{|hpJ((VvVI$<;c3#m|%G8^S6slyl}mx2UI0Z1CWjb?0v$A>1ixgH}b zAoP|+JnSLD2+sU}%mzY3QV{Zqh6ZND{!NYt#xVo$k{E%bW8wQ&VgxEJPjZ`4O}{gD zJa`XzflV6X|8uhog_Y;XUw^1;*v7mEi7afWJBe(ukf=n#zYXZK`gc9ag}ay>uoEq&g%k z$R|Jd$5|EH<|pk2;v-aznbXLfl(KqlSWx1%+m(aOd~7(eFBHF} z)=$1DT%RnZ#08aK$5Vf^`6>Mmf@59>(6zskJQ(fq_&y5b`>P(=p7J+^{=q#=OFn8o z3e9*?VnOENt~=D|Vze@sT~r*WOS4fyQ-;a0H0rwMg664J;BOB7W4{ib6d}1_93gSM zswhuM-o+PxZS&8Z_5R?81)HQaSpneF;y(yf5`Bbv9&7YZ)wQ=}uaDer8my9RMqwcd zlYloq^hGqq>HL=%NNV~PxNal5{nhF7&I@brQw6j4-r=4FAD+{;iC;yWFXEOA5IO`S zY-Omx1acCcEc7@xzv*g?+Z(%x?OFYzmSus=Ginw#6BeG2%s*}qDXmaAT{JdeZ0w;| z4|sdBu_ZF+>@eYf_Fcrv*AI_XWTs#*0M%vYVB3 zv~e56m61N4x9p?_fe(_vDJ)D&Kd}oxH3~w*zd5fMFC}2~ewqsp%vPrMW4rxi7q4bliNA2*c<3+l-uIH104BopvzdK-{y17h zL8Z8M0HF;1;CboHw%yX#w!+czAA~IfAs?#o_)nijvdoQ|wrO{MGM+b-7JYA7vE5@h z^=F}*7P<+FoEy<__x$-wb>U=4si@7hP1I9_Ds+TWMNipQ>jH4yvLW3&n-o&P!6>XG ztn^qI_)gc)MP)6^@RLXaOn|^Ja6;GI)mT5NEnR_#cFD*~xBHZhzsI0Ex@r{*$wwsI zLpj9rmTe%NyYbHwbCl4>nyMckhqP)d+Fn$pP-Vn;J(-@7k#cq^ynL`fSzw-d3kAQF8jn^RGjDpBNC`gU|47o%74Hfkq`if~WFb`{qMK^X-Tm z*7WFbtn{&m+C~?bIeOi0s;lC%{z2%^u}v0=V+1%L6LAyrZlx=oJ+OjuC=ugY0)?j+ zW#}*Grk2k5t7dcL8}>j(F67P(&5vm#4YPhJn}9qXYPGzh?E8i9{HO5BDH6i9?=uDv zRYxJ>@LC+GJgNHB>o%k3>EP--F3|eBf~LQiJL|gaSmWcM-fUrkmjgJPOSfv}ApYXj z-q)PVyn$Iv^YIaYyQx$|bsRD#>~50Y9iS8%>Eo-0=QFLvWR80wIW;D}WK^ab-Bu&) z$a%F`WmIw=;UV|Aa<(r*ZAS{JY3Thw2-qER_J8 z4<%YxeOs>MyB~N$Zpqa!U0b977~`-yC=~zpl@pfX;Em;PKU}Cd9?lZ4KIFkvx`pUD z>d=hlt(28v`OfXBJON(~a69FHRsK$j3Erqf{4?WaP3Kc6D@9o`o`0MPT$Ghj+n=f@ zt+a#|fv9G;Xz))bakLrFb>vW3h(rJCPw#3#v~KMFYj1id^w{hdi<HO89oXXBHBTg_QY zEjaBrrDLwZfslqC&t{^d(U826Uh6AzWhOg$%#Xe$$E<7}q6@b->kJP0K8NuhI~`@T zLqQy&W$(5~h~7nY;+%a0X!mXmqUK3~mjPRkixQR^@-6o9iuP1;q3W3dnRjsy?eO^7 zIdV&91h>>T)H}#Pe52h#S|ASixy+!aV=XHFtL}SNTdbT#A#Cx9DlmEE;76N_0gAqo zHb7OuQTPqi4s5ELrJL`*&bqn!HvdU3Sxws7kh6Vr!rE0|NMGp2G$w3THnarVHqHje z;tgx6I_Y7A)aXfhtSxheuaQpR`G4n{Ne{9tCWh7ZE7|M6k3zzPQeJCn z+Dx~2;3P#6cRNMMsl`pP%^j7(FCf?Hq&8xEkHqp>(xisfqYcgwD-k>$i$ob-tg6yG z8I=9)2ev^| ztut+D0f$6_dl$}F-D2t5u^{|YZqZbbh1FTkM&zha(gwwp^ zrvFOeUstk_!-1oZZaPEbCyM)*lj>>i-xMU}qCcLt%uCSMyg1%)2|LL_zTt0!brUa3 zm{K1Mi>AxIHoLgn*${mUa!&%Q)7vlL>?rFq25Hs)flMQ)yWB5CDg~=#;+85&V_@hC z$L94i=XAl6@E`o6Ok&c1m7^MHXkqG!Q>9dn^M~Y`i*R2}vmkinU;WakNhULAMq|%u zvo`0(J&<#gO|L;U5I9$Qi*zO$>sH(`zR^bcjVzn;T_a6KZXb=LL@UXoy%zST(Z~KR z4QYqdmxS|gOiDD}MSy9VhG1$5tG65%n1XWuAdoLz4q88F*78Pa{Zw!BhlP~{WmXq) z_xG?G*xi_{k^JtWd40qbYjf50Cnx4QqMP{d)k5_9ls{obL|h9biZhg~m`iJZp1MWv zrgS2)KjD;<*4=0ZmyvMyVi>69agpfpOgJ~&afNwT19i>EX6G16R~?HyFt57WFr*l= zP28k|4B~4x2`Y5EJxtK%6{kHY)RQes^cL&3FIS5rVmq=FQvRm?gK#JMi=mSvMhp3n%MK55dUnz}NiE+y>mDGbhyWg3)r9#rVqg#q1{54Q8} zjn#g($;HX%+)vU}@=eIdwxW@g3L6!oiZR@BnuVd-a{J*6^9>6J@D_=e%h#lkkl*8= zZu7&RjJ46z-~PK7RoJSk+LCHR<08{EDJ+PXq{lAV?&X-mH$N6bj=$FcY>i>3VO>J7 zf@GTG_-|S@IG{#PnaO)aa^*^p|^5&%;mR@w>E_-5UDTJtsBGSl)n0DuWy9A&_Q z3a73s>L#0O4L1Z1ZEhMmxtLp8)!m3LiUVsu{MisNoZb73U8Wo<9hZA4c&DLz_;his zg7qzW-Ss9%l;29dH8y468dzCAK65#fsvJ36L(LFGW9le6lfkZKYcT763HV ze6Ajd>u_0N{%|Cl-I$-SFl;a}F@m3gQE&KW5Lq2 zpB^mw4KoFUy!cK3gY`v&5U-tcy6oSDx#hbWg-;eTq~$QRh6O)<=+AtRVI~VkxfMxA zW;ngWetI@yK|9{w20&Rt+RI&0y(O)Wl0%=yKzyknuYOhV7|cyn4gP|Iy&E0nAFqm7OXBQj zySwfy&knSbm&F6E{O`-SAe!Ima$HjW;H&=lv$|gAcFI%bWXlaMOtNl4ry2Za)Z%KF zy+mq#MgI>1;nt;`qRo*eg$^<8cB4`GapH$=_*woMA^>wNPk# z*;SMa!z@@H)fYepkPc8Dv6wloG?~{<2TpXUnkj^n9-_QK4 z)G?u$OlBPq zfD==}N^)$Egp(SJzCYV=ZdFOVYRB_v2((b(ge2f14Bth^2YjoZQ6X2`|i=cw#>q65Zf@9mArVK z7i~jN1tcP28xljDEcB9ryEBU78@asC3kqufw!kw_RZqYYitu-Q1&@0)Dba(T;q<(% zfnWfq;_LT-zhl_(b^DE70UtO1qy)kvvi!(mLTMRbES3fYdS!Jh@>|a~Z2ursxzl6* zV6PtSjttM+efg_g>xEM$HCz6Foe2FG&EbD{HT13ur*jWQ`+RGr%vhb1Y`~&K0jF2p zgVaB)8Xx?d(4-(mVPQRg=*hOt(qzn)A~8##HBR!FK7N-YRxfMtPdMQ(ehU@hP+E1l zSil=uU@s%ABM-H0QlgPe0k4 zPKp@axkB8GKhm6Nc1Jlq&=vE#C(Amr@aT{>YgYbST?z~H^*Fre1^*yi_?f;oGyOVF zrt$4Low;3lQ{qoDi2%eiVN^to8j0o1@_YwpS)Y$t2|JE{k4vf4`8- zQZ#Mc6$56>mh*5#dR8~hvuC{Pg<5{-NOxhoE!h`U7Xtvs;#nFK03<$I`{o|mP|XTR z8oF5|`7Z=cYT7frG|A;L;O~Lk*uy}VRJjC~F zt)koaYy*4Qan0_1#{<#7lYn2V3MTOtB3JNKp2Bf~?# zp0%y|z}78gW~xzD+#`Ho)-0e*1@~=}t`@InkG=;b1ZcP%^9)*NWj#V3EL~=O;J<1&%KQmQxS+nQ3 z^*Zb~3Kc$+V|PfnIrR|M-XYhUG^N2pq^@`h$k=EPNa3Npwa#4g8F@4qO(?@JX&9R= zVT7YO6Rn6MHpN5VqIk`$sQX@o{bt6$wWe*tXml~+U|i@-)g3dkWWej$SZzK71`^DlPu#|Ky!ONSp}P_oA61x%tVFb zm#UdjTbQ7cjHkv)yL(` zadQ5(`kNjNqb~6QYv(l)vgnCML~&_y;<=ce6k3hhuR9%5B_LMs7u_7l^i;PMa@hYa zP_9I+F~IvI+}@?yon;_E*o_7-{X z8gE%qkC6}vw|LG`c6DExlzOq@U*w^PUv-q1&wz4w`hewvGGantrmGn7y#}4m_C_~8 z=e|jByU^={?dx;+ZLy)l+i6MgxdN-Ye zRO`>HDlSsRgE%NC=|sz1axdf(ohTwT?pmcK#-d9c4f%cYM1s9%+`EA*&o2v3bb*

    W==pD1zXv|SoOZJQqE*W%*y?EH^UC)u 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 z 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

    ZoZckCK*iK9jG9ommUth&7 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 literal 0 HcmV?d00001 diff --git a/client-wiaas/public/static/img/HC_FixedHuddle_interior.png b/client-wiaas/public/static/img/HC_FixedHuddle_interior.png new file mode 100644 index 0000000000000000000000000000000000000000..8ff013ecdabdd44bd859daf368f20bbfe76eb42c GIT binary patch literal 444649 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

  • '},postRender:function(){var a=this;a._super(),a.resizeDragHelper=new b(this._id,{start:function(){a.fire("ResizeStart")},drag:function(b){"both"!=a.settings.direction&&(b.deltaX=0),a.fire("Resize",b)},stop:function(){a.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),g("2f",["1h"],function(a){"use strict";function b(a){var b="";if(a)for(var c=0;c'+a[c]+"";return b}return a.extend({Defaults:{classes:"selectbox",role:"selectbox",options:[]},init:function(a){var b=this;b._super(a),b.settings.size&&(b.size=b.settings.size),b.settings.options&&(b._options=b.settings.options),b.on("keydown",function(a){var c;13==a.keyCode&&(a.preventDefault(),b.parents().reverse().each(function(a){if(a.toJSON)return c=a,!1}),b.fire("submit",{data:c.toJSON()}))})},options:function(a){return arguments.length?(this.state.set("options",a),this):this.state.get("options")},renderHtml:function(){var a,c=this,d="";return a=b(c._options),c.size&&(d=' size = "'+c.size+'"'),'"},bindStates:function(){var a=this;return a.state.on("change:options",function(c){a.getEl().innerHTML=b(c.value)}),a._super()}})}),g("2h",["1h","11","30"],function(a,b,c){"use strict";function d(a,b,c){return ac&&(a=c),a}function e(a,b,c){a.setAttribute("aria-"+b,c)}function f(a,b){var d,f,g,h,i,j;"v"==a.settings.orientation?(h="top",g="height",f="h"):(h="left",g="width",f="w"),j=a.getEl("handle"),d=(a.layoutRect()[f]||100)-c.getSize(j)[g],i=d*((b-a._minValue)/(a._maxValue-a._minValue))+"px",j.style[h]=i,j.style.height=a.layoutRect().h+"px",e(j,"valuenow",b),e(j,"valuetext",""+a.settings.previewFilter(b)),e(j,"valuemin",a._minValue),e(j,"valuemax",a._maxValue)}return a.extend({init:function(a){var b=this;a.previewFilter||(a.previewFilter=function(a){return Math.round(100*a)/100}),b._super(a),b.classes.add("slider"),"v"==a.orientation&&b.classes.add("vertical"),b._minValue=a.minValue||0,b._maxValue=a.maxValue||100,b._initValue=b.state.get("value")},renderHtml:function(){var a=this,b=a._id,c=a.classPrefix;return'
    '},reset:function(){this.value(this._initValue).repaint()},postRender:function(){function a(a,b,c){return(c+a)/(b-a)}function e(a,b,c){return c*(b-a)-a}function f(b,c){function f(f){var g;g=n.value(),g=e(b,c,a(b,c,g)+.05*f),g=d(g,b,c),n.value(g),n.fire("dragstart",{value:g}),n.fire("drag",{value:g}),n.fire("dragend",{value:g})}n.on("keydown",function(a){switch(a.keyCode){case 37:case 38:f(-1);break;case 39:case 40:f(1)}})}function g(a,e,f){var g,h,i,o,p;n._dragHelper=new b(n._id,{handle:n._id+"-handle",start:function(a){g=a[j],h=parseInt(n.getEl("handle").style[k],10),i=(n.layoutRect()[m]||100)-c.getSize(f)[l],n.fire("dragstart",{value:p})},drag:function(b){var c=b[j]-g;o=d(h+c,0,i),f.style[k]=o+"px",p=a+o/i*(e-a),n.value(p),n.tooltip().text(""+n.settings.previewFilter(p)).show().moveRel(f,"bc tc"),n.fire("drag",{value:p})},stop:function(){n.tooltip().hide(),n.fire("dragend",{value:p})}})}var h,i,j,k,l,m,n=this;h=n._minValue,i=n._maxValue,"v"==n.settings.orientation?(j="screenY",k="top",l="height",m="h"):(j="screenX",k="left",l="width",m="w"),n._super(),f(h,i,n.getEl("handle")),g(h,i,n.getEl("handle"))},repaint:function(){this._super(),f(this,this.value())},bindStates:function(){var a=this;return a.state.on("change:value",function(b){f(a,b.value)}),a._super()}})}),g("2i",["1h"],function(a){"use strict";return a.extend({renderHtml:function(){var a=this;return a.classes.add("spacer"),a.canFocus=!1,'
    '}})}),g("2j",["1","31","30","21"],function(a,b,c,d){return d.extend({Defaults:{classes:"widget btn splitbtn",role:"button"},repaint:function(){var a,d,e=this,f=e.getEl(),g=e.layoutRect();return e._super(),a=f.firstChild,d=f.lastChild,b(a).css({width:g.w-c.getSize(d).width,height:g.h-2}),b(d).css({height:g.h-2}),e},activeMenu:function(a){var c=this;b(c.getEl().lastChild).toggleClass(c.classPrefix+"active",a)},renderHtml:function(){var b,c,d=this,e=d._id,f=d.classPrefix,g=d.state.get("icon"),h=d.state.get("text"),i=d.settings,j="";return b=i.image,b?(g="none","string"!=typeof b&&(b=a.getSelection?b[0]:b[1]),b=" style=\"background-image: url('"+b+"')\""):b="",g=i.icon?f+"ico "+f+"i-"+g:"",h&&(d.classes.add("btn-has-text"),j=''+d.encode(h)+""),c="boolean"==typeof i.active?' aria-pressed="'+i.active+'"':"",'
    '},postRender:function(){var a=this,b=a.settings.onclick;return a.on("click",function(a){var c=a.target;if(a.control==this)for(;c;){if(a.aria&&"down"!=a.aria.key||"BUTTON"==c.nodeName&&c.className.indexOf("open")==-1)return a.stopImmediatePropagation(),void(b&&b.call(this,a));c=c.parentNode}}),delete a.settings.onclick,a._super()}})}),g("2k",["19"],function(a){"use strict";return a.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"},isNative:function(){return!0}})}),g("2l",["26","31","30"],function(a,b,c){"use strict";return a.extend({Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(a){var c;this.activeTabId&&(c=this.getEl(this.activeTabId),b(c).removeClass(this.classPrefix+"active"),c.setAttribute("aria-selected","false")),this.activeTabId="t"+a,c=this.getEl("t"+a),c.setAttribute("aria-selected","true"),b(c).addClass(this.classPrefix+"active"),this.items()[a].show().fire("showtab"),this.reflow(),this.items().each(function(b,c){a!=c&&b.hide()})},renderHtml:function(){var a=this,b=a._layout,c="",d=a.classPrefix;return a.preRender(),b.preRender(a),a.items().each(function(b,e){var f=a._id+"-t"+e;b.aria("role","tabpanel"),b.aria("labelledby",f),c+='"}),'
    '+c+'
    '+b.renderHtml(a)+"
    "},postRender:function(){var a=this;a._super(),a.settings.activeTab=a.settings.activeTab||0,a.activateTab(a.settings.activeTab),this.on("click",function(b){var c=b.target.parentNode;if(c&&c.id==a._id+"-head")for(var d=c.childNodes.length;d--;)c.childNodes[d]==b.target&&a.activateTab(d)})},initLayoutRect:function(){var a,b,d,e=this;b=c.getSize(e.getEl("head")).width,b=b<0?0:b,d=0,e.items().each(function(a){b=Math.max(b,a.layoutRect().minW),d=Math.max(d,a.layoutRect().minH)}),e.items().each(function(a){a.settings.x=0,a.settings.y=0,a.settings.w=b,a.settings.h=d,a.layoutRect({x:0,y:0,w:b,h:d})});var f=c.getSize(e.getEl("head")).height;return e.settings.minWidth=b,e.settings.minHeight=d+f,a=e._super(),a.deltaH+=f,a.innerH=a.h-a.deltaH,a}})}),g("2m",["1e","e","30","1h"],function(a,b,c,d){return d.extend({init:function(a){var b=this;b._super(a),b.classes.add("textbox"),a.multiline?b.classes.add("multiline"):(b.on("keydown",function(a){var c;13==a.keyCode&&(a.preventDefault(),b.parents().reverse().each(function(a){if(a.toJSON)return c=a,!1}),b.fire("submit",{data:c.toJSON()}))}),b.on("keyup",function(a){b.state.set("value",a.target.value)}))},repaint:function(){var b,c,d,e,f,g=this,h=0;b=g.getEl().style,c=g._layoutRect,f=g._lastRepaintRect||{};var i=a;return!g.settings.multiline&&i.all&&(!i.documentMode||i.documentMode<=8)&&(b.lineHeight=c.h-h+"px"),d=g.borderBox,e=d.left+d.right+8,h=d.top+d.bottom+(g.settings.multiline?8:0),c.x!==f.x&&(b.left=c.x+"px",f.x=c.x),c.y!==f.y&&(b.top=c.y+"px",f.y=c.y),c.w!==f.w&&(b.width=c.w-e+"px",f.w=c.w),c.h!==f.h&&(b.height=c.h-h+"px",f.h=c.h),g._lastRepaintRect=f,g.fire("repaint",{},!1),g},renderHtml:function(){var a,d,e=this,f=e.settings;return a={id:e._id,hidefocus:"1"},b.each(["rows","spellcheck","maxLength","size","readonly","min","max","step","list","pattern","placeholder","required","multiple"],function(b){a[b]=f[b]}),e.disabled()&&(a.disabled="disabled"),f.subtype&&(a.type=f.subtype),d=c.create(f.multiline?"textarea":"input",a),d.value=e.state.get("value"),d.className=e.classes,d.outerHTML},value:function(a){return arguments.length?(this.state.set("value",a),this):(this.state.get("rendered")&&this.state.set("value",this.getEl().value),this.state.get("value"))},postRender:function(){var a=this;a.getEl().value=a.state.get("value"),a._super(),a.$el.on("change",function(b){a.state.set("value",b.target.value),a.fire("change",b)})},bindStates:function(){var a=this;return a.state.on("change:value",function(b){a.getEl().value!=b.value&&(a.getEl().value=b.value)}),a.state.on("change:disabled",function(b){a.getEl().disabled=b.value}),a._super()},remove:function(){this.$el.off(),this._super()}})}),g("6",["d","e","p","q","r","s","t","u","v","w","x","y","z","10","11","12","13","14","15","16","17","18","19","1a","7","1r","1s","1t","1u","1v","1w","1x","1y","1z","20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f","2g","2h","2i","2j","2k","2l","2m","2n","2o","2p","1h","2q"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha){var ia=function(){return{Selector:Y,Collection:h,ReflowQueue:T,Control:n,Factory:a,KeyboardNavigation:D,Container:m,DragHelper:o,Scrollable:W,Panel:O,Movable:M,Resizable:U,FloatPanel:v,Window:ha,MessageBox:L,Tooltip:fa,Widget:ga,Progress:R,Notification:N,Layout:F,AbsoluteLayout:c,Button:e,ButtonGroup:f,Checkbox:g,ComboBox:l,ColorBox:i,PanelButton:P,ColorButton:j,ColorPicker:k,Path:Q,ElementPath:q,FormItem:z,Form:x,FieldSet:r,FilePicker:s,FitLayout:t,FlexLayout:u,FlowLayout:w,FormatControls:y,GridLayout:A,Iframe:B,InfoBox:C,Label:E,Toolbar:ea,MenuBar:I,MenuButton:J,MenuItem:K,Throbber:da,Menu:H,ListBox:G,Radio:S,ResizeHandle:V,SelectBox:X,Slider:Z,Spacer:$,SplitButton:_,StackLayout:aa,TabPanel:ba,TextBox:ca,DropZone:p,BrowseButton:d}},ja=function(a){a.ui?b.each(ia(),function(b,c){a.ui[c]=b}):a.ui=ia()},ka=function(){b.each(ia(),function(b,c){a.add(c,b)})},la={appendTo:ja,registerToFactory:ka};return la}),g("0",["1","2","3","4","5","6","7"],function(a,b,c,d,e,f,g){return f.registerToFactory(),f.appendTo(a.tinymce?a.tinymce:{}),b.add("inlite",function(a){var b=new e;return g.setup(a),d.addToEditor(a,b),c.get(a,b)}),function(){}}),d("0")()}(); \ No newline at end of file diff --git a/client-wiaas/public/static/js/tinymce/js/tinymce/themes/mobile/theme.min.js b/client-wiaas/public/static/js/tinymce/js/tinymce/themes/mobile/theme.min.js new file mode 100644 index 0000000..05f9c92 --- /dev/null +++ b/client-wiaas/public/static/js/tinymce/js/tinymce/themes/mobile/theme.min.js @@ -0,0 +1,8 @@ +!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e1)throw c.error("HTML does not have a single root node",a),"HTML must have a single root node";return h(f.childNodes[0])},f=function(a,b){var c=b||d,e=c.createElement(a);return h(e)},g=function(a,b){var c=b||d,e=c.createTextNode(a);return h(e)},h=function(c){if(null===c||void 0===c)throw new b("Node cannot be null or undefined");return{dom:a.constant(c)}};return{fromHtml:e,fromTag:f,fromText:g,fromDom:h}}),g("1d",[],function(){return{ATTRIBUTE:2,CDATA_SECTION:4,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,ELEMENT:1,TEXT:3,PROCESSING_INSTRUCTION:7,ENTITY_REFERENCE:5,ENTITY:6,NOTATION:12}}),g("2r",["y","z","a","1d","v","1b"],function(a,b,c,d,e,f){var g=d.ELEMENT,h=d.DOCUMENT,i=function(a,b){var c=a.dom();if(c.nodeType!==g)return!1;if(void 0!==c.matches)return c.matches(b);if(void 0!==c.msMatchesSelector)return c.msMatchesSelector(b);if(void 0!==c.webkitMatchesSelector)return c.webkitMatchesSelector(b);if(void 0!==c.mozMatchesSelector)return c.mozMatchesSelector(b);throw new e("Browser lacks native selectors")},j=function(a){return a.nodeType!==g&&a.nodeType!==h||0===a.childElementCount},k=function(b,d){var e=void 0===d?f:d.dom();return j(e)?[]:a.map(e.querySelectorAll(b),c.fromDom)},l=function(a,d){var e=void 0===d?f:d.dom();return j(e)?b.none():b.from(e.querySelector(a)).map(c.fromDom)};return{all:k,is:i,one:l}}),g("1a",["y","6","2q","7","2r"],function(a,b,c,d,e){var f=function(a,b){return a.dom()===b.dom()},g=function(a,b){return a.dom().isEqualNode(b.dom())},h=function(c,d){return a.exists(d,b.curry(f,c))},i=function(a,b){var c=a.dom(),d=b.dom();return c!==d&&c.contains(d)},j=function(a,b){return c.documentPositionContainedBy(a.dom(),b.dom())},k=d.detect().browser,l=k.isIE()?j:i;return{eq:f,isEqualNode:g,member:h,contains:l,is:e.is}}),g("43",["1a"],function(a){var b=function(b,c){return a.eq(b.element(),c.event().target())};return{isSource:b}}),g("2g",["6"],function(a){return{contextmenu:a.constant("contextmenu"),touchstart:a.constant("touchstart"),touchmove:a.constant("touchmove"),touchend:a.constant("touchend"),gesturestart:a.constant("gesturestart"),mousedown:a.constant("mousedown"),mousemove:a.constant("mousemove"),mouseout:a.constant("mouseout"),mouseup:a.constant("mouseup"),mouseover:a.constant("mouseover"),focusin:a.constant("focusin"),keydown:a.constant("keydown"),input:a.constant("input"),change:a.constant("change"),focus:a.constant("focus"),click:a.constant("click"),transitionend:a.constant("transitionend"),selectstart:a.constant("selectstart")}}),g("t",["2g","6","7"],function(a,b,c){var d={tap:b.constant("alloy.tap")};return{focus:b.constant("alloy.focus"),postBlur:b.constant("alloy.blur.post"),receive:b.constant("alloy.receive"),execute:b.constant("alloy.execute"),focusItem:b.constant("alloy.focus.item"),tap:d.tap,tapOrClick:c.detect().deviceType.isTouch()?d.tap:a.click,longpress:b.constant("alloy.longpress"),sandboxClose:b.constant("alloy.sandbox.close"),systemInit:b.constant("alloy.system.init"),windowScroll:b.constant("alloy.system.scroll"),attachedToDom:b.constant("alloy.system.attached"),detachedFromDom:b.constant("alloy.system.detached"),changeTab:b.constant("alloy.change.tab"),dismissTab:b.constant("alloy.dismiss.tab")}}),g("1i",["u","2m"],function(a,b){var c=function(c){if(null===c)return"null";var d=typeof c;return"object"===d&&a.prototype.isPrototypeOf(c)?"array":"object"===d&&b.prototype.isPrototypeOf(c)?"string":d},d=function(a){return function(b){return c(b)===a}};return{isString:d("string"),isObject:d("object"),isArray:d("array"),isNull:d("null"),isBoolean:d("boolean"),isUndefined:d("undefined"),isFunction:d("function"),isNumber:d("number")}}),g("w",["1i","u","v"],function(a,b,c){var d=function(a,b){return b},e=function(b,c){var d=a.isObject(b)&&a.isObject(c);return d?g(b,c):c},f=function(a){return function(){for(var d=new b(arguments.length),e=0;e0?g(c.errors):f(c.values,b)},i=function(a){var b=e.partition(a);return b.errors.length>0?g(b.errors):d.value(b.values)};return{consolidateObj:h,consolidateArr:i}}),g("2b",["y","x"],function(a,b){var c=function(b,c){var d={};return a.each(c,function(a){void 0!==b[a]&&b.hasOwnProperty(a)&&(d[a]=b[a])}),d},d=function(b,c){var d={};return a.each(b,function(a){var b=a[c];d[b]=a}),d},e=function(c,d){var e={};return b.each(c,function(b,c){a.contains(d,c)||(e[c]=b)}),e};return{narrow:c,exclude:e,indexOnKey:d}}),g("2c",["z"],function(a){var b=function(b){return function(c){return c.hasOwnProperty(b)?a.from(c[b]):a.none()}},c=function(a,c){return function(d){return b(a)(d).getOr(c)}},d=function(a,c){return b(c)(a)},e=function(a,b){return a.hasOwnProperty(b)&&void 0!==a[b]&&null!==a[b]};return{readOpt:b,readOr:c,readOptFrom:d,hasKey:e}}),g("2d",["y"],function(a){var b=function(a,b){var c={};return c[a]=b,c},c=function(b){var c={};return a.each(b,function(a){c[a.key]=a.value}),c};return{wrap:b,wrapAll:c}}),g("14",["2a","2b","2c","2d"],function(a,b,c,d){var e=function(a,c){return b.narrow(a,c)},f=function(a,c){return b.exclude(a,c)},g=function(a){return c.readOpt(a)},h=function(a,b){return c.readOr(a,b)},i=function(a,b){return c.readOptFrom(a,b)},j=function(a,b){return d.wrap(a,b)},k=function(a){return d.wrapAll(a)},l=function(a,c){return b.indexOnKey(a,c)},m=function(b,c){return a.consolidateObj(b,c)},n=function(a,b){return c.hasKey(a,b)};return{narrow:e,exclude:f,readOpt:g,readOr:h,readOptFrom:i,wrap:j,wrapAll:k,indexOnKey:l,hasKey:n,consolidate:m}}),g("6n",["4m"],function(a){var b=function(){return a.getOrDie("JSON")},c=function(a){return b().parse(a)},d=function(a,c,d){return b().stringify(a,c,d)};return{parse:c,stringify:d}}),g("4f",["y","x","1i","6n"],function(a,b,c,d){var e=function(a){return c.isObject(a)&&b.keys(a).length>100?" removed due to size":d.stringify(a,null,2)},f=function(b){var c=b.length>10?b.slice(0,10).concat([{path:[],getErrorInfo:function(){return"... (only showing first ten failures)"}}]):b;return a.map(c,function(a){return"Failed path: ("+a.path.join(" > ")+")\n"+a.getErrorInfo()})};return{formatObj:e,formatErrors:f}}),g("6l",["4f","48"],function(a,b){var c=function(a,c){return b.error([{path:a,getErrorInfo:c}])},d=function(b,d,e){return c(b,function(){return'Could not find valid *strict* value for "'+d+'" in '+a.formatObj(e)})},e=function(a,b){return c(a,function(){return'Choice schema did not contain choice key: "'+b+'"'})},f=function(b,d,e){return c(b,function(){return'The chosen schema: "'+e+'" did not exist in branches: '+a.formatObj(d)})},g=function(a,b){return c(a,function(){return"There are unsupported fields: ["+b.join(", ")+"] specified"})},h=function(a,b){return c(a,function(){return b})},i=function(a){return"Failed path: ("+a.path.join(" > ")+")\n"+a.getErrorInfo()};return{missingStrict:d,missingKey:e,missingBranch:f,unsupportedFields:g,custom:h,toString:i}}),g("6m",["6k"],function(a){var b=a.generate([{setOf:["validator","valueType"]},{arrOf:["valueType"]},{objOf:["fields"]},{itemOf:["validator"]},{choiceOf:["key","branches"]}]),c=a.generate([{field:["name","presence","type"]},{state:["name"]}]);return{typeAdt:b,fieldAdt:c}}),g("4d",["4c","14","2a","2c","2d","6l","6m","6k","y","6","w","x","z","48","1i"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=h.generate([{field:["key","okey","presence","prop"]},{state:["okey","instantiator"]}]),q=function(a,b){return p.state(a,j.constant(b))},r=function(a){return p.state(a,j.identity)},s=function(a,b,c){return d.readOptFrom(b,c).fold(function(){return f.missingStrict(a,c,b)},n.value)},t=function(a,b,c){var e=d.readOptFrom(a,b).fold(function(){return c(a)},j.identity);return n.value(e)},u=function(a,b){return n.value(d.readOptFrom(a,b))},v=function(a,b,c){var e=d.readOptFrom(a,b).map(function(b){return b===!0?c(a):b});return n.value(e)},w=function(a,b,c,d){return c.fold(function(c,f,g,h){var i=function(b){return h.extract(a.concat([c]),d,b).map(function(a){return e.wrap(f,d(a))})},l=function(b){return b.fold(function(){var a=e.wrap(f,d(m.none()));return n.value(a)},function(b){return h.extract(a.concat([c]),d,b).map(function(a){return e.wrap(f,d(m.some(a)))})})};return function(){return g.fold(function(){return s(a,b,c).bind(i)},function(a){return t(b,c,a).bind(i)},function(){return u(b,c).bind(l)},function(a){return v(b,c,a).bind(l)},function(a){var d=a(b);return t(b,c,j.constant({})).map(function(a){return k.deepMerge(d,a)}).bind(i)})}()},function(a,c){var f=c(b);return n.value(e.wrap(a,d(f)))})},x=function(a,b,d,e){var f=i.map(d,function(c){return w(a,b,c,e)});return c.consolidateObj(f,{})},y=function(a){var b=function(b,c,d){return a(d).fold(function(a){return f.custom(b,a)},n.value)},c=function(){return"val"},d=function(){return g.typeAdt.itemOf(a)};return{extract:b,toString:c,toDsl:d}},z=function(a){var c=l.keys(a);return i.filter(c,function(c){return b.hasKey(a,c)})},A=function(a){var c=B(a),d=i.foldr(a,function(a,c){return c.fold(function(c){return k.deepMerge(a,b.wrap(c,!0))},j.constant(a))},{}),e=function(a,e,g){var h=o.isBoolean(g)?[]:z(g),j=i.filter(h,function(a){return!b.hasKey(d,a)});return 0===j.length?c.extract(a,e,g):f.unsupportedFields(a,j)};return{extract:e,toString:c.toString,toDsl:c.toDsl}},B=function(a){var b=function(b,c,d){return x(b,d,a,c)},c=function(){var b=i.map(a,function(a){return a.fold(function(a,b,c,d){return a+" -> "+d.toString()},function(a,b){return"state("+a+")"})});return"obj{\n"+b.join("\n")+"}"},d=function(){return g.typeAdt.objOf(i.map(a,function(a){return a.fold(function(a,b,c,d){return g.fieldAdt.field(a,c,d)},function(a,b){return g.fieldAdt.state(a)})}))};return{extract:b,toString:c,toDsl:d}},C=function(a){var b=function(b,d,e){var f=i.map(e,function(c,e){return a.extract(b.concat(["["+e+"]"]),d,c)});return c.consolidateArr(f)},d=function(){return"array("+a.toString()+")"},e=function(){return g.typeAdt.arrOf(a)};return{extract:b,toString:d,toDsl:e}},D=function(b,c){var d=function(a,c){return C(y(b)).extract(a,j.identity,c)},e=function(b,e,f){var g=l.keys(f);return d(b,g).bind(function(d){var g=i.map(d,function(b){return p.field(b,b,a.strict(),c)});return B(g).extract(b,e,f)})},f=function(){return"setOf("+c.toString()+")"},h=function(){return g.typeAdt.setOf(b,c)};return{extract:e,toString:f,toDsl:h}},E=y(n.value),F=j.compose(C,B);return{anyValue:j.constant(E),value:y,obj:B,objOnly:A,arr:C,setOf:D,arrOfObj:F,state:p.state,field:p.field,output:q,snapshot:r}}),g("29",["4c","4d","48","1i"],function(a,b,c,d){var e=function(c){return b.field(c,c,a.strict(),b.anyValue())},f=function(c,d){return b.field(c,c,a.strict(),d)},g=function(e){return b.field(e,e,a.strict(),b.value(function(a){return d.isFunction(a)?c.value(a):c.error("Not a function")}))},h=function(d,e){return b.field(d,d,a.asOption(),b.value(function(a){return c.error("The field: "+d+" is forbidden. "+e)}))},i=function(a,b){return f(a,b)},j=function(c,d){return b.field(c,c,a.strict(),b.obj(d))},k=function(c,d){return b.field(c,c,a.strict(),b.arrOfObj(d))},l=function(c){return b.field(c,c,a.asOption(),b.anyValue())},m=function(c,d){return b.field(c,c,a.asOption(),d)},n=function(c,d){return b.field(c,c,a.asOption(),b.obj(d))},o=function(c,d){return b.field(c,c,a.asOption(),b.objOnly(d))},p=function(c,d){return b.field(c,c,a.defaulted(d),b.anyValue())},q=function(c,d,e){return b.field(c,c,a.defaulted(d),e)},r=function(c,d,e){return b.field(c,c,a.defaulted(d),b.obj(e))},s=function(a,c,d,e){return b.field(a,c,d,e)},t=function(a,c){return b.state(a,c)};return{strict:e,strictOf:f,strictObjOf:j,strictArrayOf:i,strictArrayOfObj:k,strictFunction:g,forbid:h,option:l,optionOf:m,optionObjOf:n,optionObjOfOnly:o,defaulted:p,defaultedOf:q,defaultedObjOf:r,field:s,state:t}}),g("4e",["14","6l","4d","6m","x"],function(a,b,c,d,e){var f=function(d,e,f,g,h){var i=a.readOptFrom(g,h);return i.fold(function(){return b.missingBranch(d,g,h)},function(a){return c.obj(a).extract(d.concat(["branch: "+h]),e,f)})},g=function(c,g){var h=function(d,e,h){var i=a.readOptFrom(h,c);return i.fold(function(){return b.missingKey(d,c)},function(a){return f(d,e,h,g,a)})},i=function(){return"chooseOn("+c+"). Possible values: "+e.keys(g)},j=function(){return d.typeAdt.choiceOf(c,g)};return{extract:h,toString:i,toDsl:j}};return{choose:g}}),g("2e",["4e","4d","4f","6","48","v"],function(a,b,c,d,e,f){var g=b.value(e.value),h=function(a){return b.arrOfObj(a)},i=function(){return b.arr(g)},j=b.arr,k=b.obj,l=b.objOnly,m=b.setOf,n=function(a){return b.value(a)},o=function(a,b,c,d){return b.extract([a],c,d).fold(function(a){return e.error({input:d,errors:a})},e.value)},p=function(a,b,c){return o(a,b,d.constant,c)},q=function(a,b,c){return o(a,b,d.identity,c)},r=function(a){return a.fold(function(a){throw new f(u(a))},d.identity)},s=function(a,b,c){return r(q(a,b,c))},t=function(a,b,c){return r(p(a,b,c))},u=function(a){return"Errors: \n"+c.formatErrors(a.errors)+"\n\nInput object: "+c.formatObj(a.input)},v=function(b,c){return a.choose(b,c)};return{anyValue:d.constant(g),arrOfObj:h,arrOf:j,arrOfVal:i,valueOf:n,setOf:m,objOf:k,objOfOnly:l,asStruct:p,asRaw:q,asStructOrDie:t,asRawOrDie:s,getOrDie:r,formatError:u,choose:v}}),g("47",["29","14","2e","1i","y","6n","6","u","v"],function(a,b,c,d,e,f,g,h,i){var j=function(d){if(!b.hasKey(d,"can")&&!b.hasKey(d,"abort")&&!b.hasKey(d,"run"))throw new i("EventHandler defined by: "+f.stringify(d,null,2)+" does not have can, abort, or run!");return c.asRawOrDie("Extracting event.handler",c.objOfOnly([a.defaulted("can",g.constant(!0)),a.defaulted("abort",g.constant(!1)),a.defaulted("run",g.noop)]),d)},k=function(a,b){return function(){var c=h.prototype.slice.call(arguments,0);return e.foldl(a,function(a,d){return a&&b(d).apply(void 0,c)},!0)}},l=function(a,b){return function(){var c=h.prototype.slice.call(arguments,0);return e.foldl(a,function(a,d){return a||b(d).apply(void 0,c)},!1)}},m=function(a){ +return d.isFunction(a)?{can:g.constant(!0),abort:g.constant(!1),run:a}:a},n=function(a){var b=k(a,function(a){return a.can}),c=l(a,function(a){return a.abort}),d=function(){var b=h.prototype.slice.call(arguments,0);e.each(a,function(a){a.run.apply(void 0,b)})};return j({can:b,abort:c,run:d})};return{read:m,fuse:n,nu:j}}),g("3d",["43","2","t","47","14"],function(a,b,c,d,e){var f=e.wrapAll,g=function(a,b){return{key:a,value:d.nu({abort:b})}},h=function(a,b){return{key:a,value:d.nu({can:b})}},i=function(a){return{key:a,value:d.nu({run:function(a,b){b.event().prevent()}})}},j=function(a,b){return{key:a,value:d.nu({run:b})}},k=function(a,b,c){return{key:a,value:d.nu({run:function(a){b.apply(void 0,[a].concat(c))}})}},l=function(a){return function(b){return j(a,b)}},m=function(b){return function(c){return{key:b,value:d.nu({run:function(b,d){a.isSource(b,d)&&c(b,d)}})}}},n=function(a,c){return j(a,function(d,e){d.getSystem().getByUid(c).each(function(c){b.dispatchEvent(c,c.element(),a,e)})})},o=function(a,b,c){var d=b.partUids()[c];return n(a,d)},p=function(a,b){return j(a,function(a,c){a.getSystem().getByDom(c.event().target()).each(function(d){b(a,d,c)})})},q=function(a){return j(a,function(a,b){b.cut()})},r=function(a){return j(a,function(a,b){b.stop()})};return{derive:f,run:j,preventDefault:i,runActionExtra:k,runOnAttached:m(c.attachedToDom()),runOnDetached:m(c.detachedFromDom()),runOnInit:m(c.systemInit()),runOnExecute:l(c.execute()),redirectToUid:n,redirectToPart:o,runWithTarget:p,abort:g,can:h,cutter:q,stopper:r}}),g("4a",["z"],function(a){var b=function(a,b,c){return a},c=function(a,b){return a},d=function(a,b){return a},e=a.none;return{markAsBehaviourApi:b,markAsExtraApi:c,markAsSketchApi:d,getAnnotation:e}}),g("4k",["y","6","u","v"],function(a,b,c,d){return function(){var e=arguments;return function(){for(var f=new c(arguments.length),g=0;g0&&e.unsuppMessage(m);var n={};return a.each(h,function(a){n[a]=b.constant(f[a])}),a.each(i,function(a){n[a]=b.constant(g.prototype.hasOwnProperty.call(f,a)?d.some(f[a]):d.none())}),n}}}),g("2o",["4k","4l"],function(a,b){return{immutable:a,immutableBag:b}}),g("6o",["6n","2o","2m"],function(a,b,c){var d=b.immutableBag(["tag"],["classes","attributes","styles","value","innerHtml","domChildren","defChildren"]),e=function(b){var c=f(b);return a.stringify(c,null,2)},f=function(a){return{tag:a.tag(),classes:a.classes().getOr([]),attributes:a.attributes().getOr({}),styles:a.styles().getOr({}),value:a.value().getOr(""),innerHtml:a.innerHtml().getOr(""),defChildren:a.defChildren().getOr(""),domChildren:a.domChildren().fold(function(){return""},function(a){return 0===a.length?"0 children, but still specified":c(a.length)})}};return{nu:d,defToStr:e,defToRaw:f}}),g("4b",["6o","14","y","x","w","6n","2o"],function(a,b,c,d,e,f,g){var h=["classes","attributes","styles","value","innerHtml","defChildren","domChildren"],i=g.immutableBag([],h),j=function(a){var b={},e=d.keys(a);return c.each(e,function(c){a[c].each(function(a){b[c]=a})}),i(b)},k=function(a){var b=l(a);return f.stringify(b,null,2)},l=function(a){return{classes:a.classes().getOr(""),attributes:a.attributes().getOr(""),styles:a.styles().getOr(""),value:a.value().getOr(""),innerHtml:a.innerHtml().getOr(""),defChildren:a.defChildren().getOr(""),domChildren:a.domChildren().fold(function(){return""},function(a){return 0===a.length?"0 children, but still specified":String(a.length)})}},m=function(a,c,d){return c.fold(function(){return d.fold(function(){return{}},function(c){return b.wrap(a,c)})},function(c){return d.fold(function(){return b.wrap(a,c)},function(c){return b.wrap(a,c)})})},n=function(c,d){var f=e.deepMerge({tag:c.tag(),classes:d.classes().getOr([]).concat(c.classes().getOr([])),attributes:e.merge(c.attributes().getOr({}),d.attributes().getOr({})),styles:e.merge(c.styles().getOr({}),d.styles().getOr({}))},d.innerHtml().or(c.innerHtml()).map(function(a){return b.wrap("innerHtml",a)}).getOr({}),m("domChildren",d.domChildren(),c.domChildren()),m("defChildren",d.defChildren(),c.defChildren()),d.value().or(c.value()).map(function(a){return b.wrap("value",a)}).getOr({}));return a.nu(f)};return{nu:i,derive:j,merge:n,modToStr:k,modToRaw:l}}),g("27",["3d","4a","4b","29","14","2e","6","w","x","z","17","u","16","v"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){var o=function(b,c,d){return a.runOnExecute(function(a){d(a,b,c)})},p=function(b,c,d){return a.runOnInit(function(a,e){d(a,b,c)})},q=function(a,b,c,e,g,h){var i=f.objOfOnly(a),j=d.optionObjOf(b,[d.optionObjOfOnly("config",a)]);return u(i,j,b,c,e,g,h)},r=function(a,b,c,e,f,g){var h=a,i=d.optionObjOf(b,[d.optionOf("config",a)]);return u(h,i,b,c,e,f,g)},s=function(a,c,d){var e=function(b){var e=arguments;return b.config({name:g.constant(a)}).fold(function(){throw new n("We could not find any behaviour configuration for: "+a+". Using API: "+d)},function(a){var d=l.prototype.slice.call(e,1);return c.apply(void 0,[b,a.config,a.state].concat(d))})};return b.markAsBehaviourApi(e,d,c)},t=function(a){return{key:a,value:void 0}},u=function(a,d,l,m,n,o,p){var q=function(a){return e.hasKey(a,l)?a[l]():j.none()},r=i.map(n,function(a,b){return s(l,a,b)}),u=i.map(o,function(a,c){return b.markAsExtraApi(a,c)}),v=h.deepMerge(u,r,{revoke:g.curry(t,l),config:function(b){var c=f.asStructOrDie(l+"-config",a,b);return{key:l,value:{config:c,me:v,configAsRaw:k.cached(function(){return f.asRawOrDie(l+"-config",a,b)}),initialConfig:b,state:p}}},schema:function(){return d},exhibit:function(a,b){return q(a).bind(function(a){return e.readOptFrom(m,"exhibit").map(function(c){return c(b,a.config,a.state)})}).getOr(c.nu({}))},name:function(){return l},handlers:function(a){return q(a).bind(function(a){return e.readOptFrom(m,"events").map(function(b){return b(a.config,a.state)})}).getOr({})}});return v};return{executeEvent:o,loadEvent:p,create:q,createModes:r}}),g("6q",["y","6","x","1i","6p","v"],function(a,b,c,d,e,f){var g=function(a,b){return h(a,b,{validate:d.isFunction,label:"function"})},h=function(b,d,g){if(0===d.length)throw new f("You must specify at least one required field.");return e.validateStrArr("required",d),e.checkDupes(d),function(f){var h=c.keys(f),i=a.forall(d,function(b){return a.contains(h,b)});i||e.reqMessage(d,h),b(d,h);var j=a.filter(d,function(a){return!g.validate(f[a],a)});return j.length>0&&e.invalidTypeMessage(j,g.label),f}},i=function(b,c){var d=a.filter(c,function(c){return!a.contains(b,c)});d.length>0&&e.unsuppMessage(d)},j=b.noop;return{exactly:b.curry(g,i),ensure:b.curry(g,j),ensureWith:b.curry(h,j)}}),g("4g",["6q"],function(a){return a.ensure(["readState"])}),h("1w",Math),g("28",["4g","1w"],function(a,b){var c=function(){return a({readState:function(){return"No State required"}})};return{init:c}}),g("q",["27","28","29","14","2e","6"],function(a,b,c,d,e,f){var g=function(a){return d.wrapAll(a)},h=e.objOfOnly([c.strict("fields"),c.strict("name"),c.defaulted("active",{}),c.defaulted("apis",{}),c.defaulted("extra",{}),c.defaulted("state",b)]),i=function(b){var c=e.asRawOrDie("Creating behaviour: "+b.name,h,b);return a.create(c.fields,c.name,c.active,c.apis,c.extra,c.state)},j=e.objOfOnly([c.strict("branchKey"),c.strict("branches"),c.strict("name"),c.defaulted("active",{}),c.defaulted("apis",{}),c.defaulted("extra",{}),c.defaulted("state",b)]),k=function(b){var c=e.asRawOrDie("Creating behaviour: "+b.name,j,b);return a.createModes(e.choose(c.branchKey,c.branches),c.name,c.active,c.apis,c.extra,c.state)};return{derive:g,revoke:f.constant(void 0),noActive:f.constant({}),noApis:f.constant({}),noExtra:f.constant({}),noState:f.constant(b),create:i,createModes:k}}),g("4h",[],function(){return function(a,b,c){var d=c||!1,e=function(){b(),d=!0},f=function(){a(),d=!1},g=function(){var a=d?f:e;a()},h=function(){return d};return{on:e,off:f,toggle:g,isOn:h}}}),g("b",["1d"],function(a){var b=function(a){var b=a.dom().nodeName;return b.toLowerCase()},c=function(a){return a.dom().nodeType},d=function(a){return a.dom().nodeValue},e=function(a){return function(b){return c(b)===a}},f=function(d){return c(d)===a.COMMENT||"#comment"===b(d)},g=e(a.ELEMENT),h=e(a.TEXT),i=e(a.DOCUMENT);return{name:b,type:c,value:d,isElement:g,isText:h,isDocument:i,isComment:f}}),g("4i",["1i","y","x","b","v","16"],function(a,b,c,d,e,f){var g=function(b,c,d){if(!(a.isString(d)||a.isBoolean(d)||a.isNumber(d)))throw f.error("Invalid call to Attr.set. Key ",c,":: Value ",d,":: Element ",b),new e("Attribute value was not simple");b.setAttribute(c,d+"")},h=function(a,b,c){g(a.dom(),b,c)},i=function(a,b){var d=a.dom();c.each(b,function(a,b){g(d,b,a)})},j=function(a,b){var c=a.dom().getAttribute(b);return null===c?void 0:c},k=function(a,b){var c=a.dom();return!(!c||!c.hasAttribute)&&c.hasAttribute(b)},l=function(a,b){a.dom().removeAttribute(b)},m=function(a){var b=a.dom().attributes;return void 0===b||null===b||0===b.length},n=function(a){return b.foldl(a.dom().attributes,function(a,b){return a[b.name]=b.value,a},{})},o=function(a,b,c){k(a,c)&&!k(b,c)&&h(b,c,j(a,c))},p=function(a,c,e){d.isElement(a)&&d.isElement(c)&&b.each(e,function(b){o(a,c,b)})};return{clone:n,set:h,setAll:i,get:j,has:k,remove:l,hasNone:m,transfer:p}}),g("6r",["y","4i"],function(a,b){var c=function(a,c){var d=b.get(a,c);return void 0===d||""===d?[]:d.split(" ")},d=function(a,d,e){var f=c(a,d),g=f.concat([e]);b.set(a,d,g.join(" "))},e=function(d,e,f){var g=a.filter(c(d,e),function(a){return a!==f});g.length>0?b.set(d,e,g.join(" ")):b.remove(d,e)};return{read:c,add:d,remove:e}}),g("4j",["y","6r"],function(a,b){var c=function(a){return void 0!==a.dom().classList},d=function(a){return b.read(a,"class")},e=function(a,c){return b.add(a,"class",c)},f=function(a,c){return b.remove(a,"class",c)},g=function(b,c){a.contains(d(b),c)?f(b,c):e(b,c)};return{get:d,add:e,remove:f,toggle:g,supports:c}}),g("2f",["4h","4i","4j"],function(a,b,c){var d=function(a,b){c.supports(a)?a.dom().classList.add(b):c.add(a,b)},e=function(a){var d=c.supports(a)?a.dom().classList:c.get(a);0===d.length&&b.remove(a,"class")},f=function(a,b){if(c.supports(a)){var d=a.dom().classList;d.remove(b)}else c.remove(a,b);e(a)},g=function(a,b){return c.supports(a)?a.dom().classList.toggle(b):c.toggle(a,b)},h=function(b,d){var e=c.supports(b),f=b.dom().classList,g=function(){e?f.remove(d):c.remove(b,d)},h=function(){e?f.add(d):c.add(b,d)};return a(g,h,i(b,d))},i=function(a,b){return c.supports(a)&&a.dom().classList.contains(b)};return{add:d,remove:f,toggle:g,toggler:h,has:i}}),g("r",["2f"],function(a){var b=function(b,c,d){a.remove(b,d),a.add(b,c)},c=function(a,c,d){b(a.element(),c.alpha(),c.omega())},d=function(a,c,d){b(a.element(),c.omega(),c.alpha())},e=function(b,c,d){a.remove(b.element(),c.alpha()),a.remove(b.element(),c.omega())},f=function(b,c,d){return a.has(b.element(),c.alpha())},g=function(b,c,d){return a.has(b.element(),c.omega())};return{toAlpha:c,toOmega:d,isAlpha:f,isOmega:g,clear:e}}),g("s",["29"],function(a){return[a.strict("alpha"),a.strict("omega")]}),g("1",["q","r","s"],function(a,b,c){return a.create({fields:c,name:"swapping",apis:b})}),g("2p",[],function(){var a=function(a,b){var c=[],d=function(a){return c.push(a),b(a)},e=b(a);do e=e.bind(d);while(e.isSome());return c};return{toArray:a}}),g("10",["1i","y","6","z","2o","2p","1a","a"],function(a,b,c,d,e,f,g,h){var i=function(a){return h.fromDom(a.dom().ownerDocument)},j=function(a){var b=i(a);return h.fromDom(b.dom().documentElement)},k=function(a){var b=a.dom(),c=b.ownerDocument.defaultView;return h.fromDom(c)},l=function(a){var b=a.dom();return d.from(b.parentNode).map(h.fromDom)},m=function(a){return l(a).bind(function(c){var d=u(c);return b.findIndex(d,function(b){return g.eq(a,b)})})},n=function(b,d){for(var e=a.isFunction(d)?d:c.constant(!1),f=b.dom(),g=[];null!==f.parentNode&&void 0!==f.parentNode;){var i=f.parentNode,j=h.fromDom(i);if(g.push(j),e(j)===!0)break;f=i}return g},o=function(a){var c=function(c){return b.filter(c,function(b){return!g.eq(a,b)})};return l(a).map(u).map(c).getOr([])},p=function(a){var b=a.dom();return d.from(b.offsetParent).map(h.fromDom)},q=function(a){var b=a.dom();return d.from(b.previousSibling).map(h.fromDom)},r=function(a){var b=a.dom();return d.from(b.nextSibling).map(h.fromDom)},s=function(a){return b.reverse(f.toArray(a,q))},t=function(a){return f.toArray(a,r)},u=function(a){var c=a.dom();return b.map(c.childNodes,h.fromDom)},v=function(a,b){var c=a.dom().childNodes;return d.from(c[b]).map(h.fromDom)},w=function(a){return v(a,0)},x=function(a){return v(a,a.dom().childNodes.length-1)},y=function(a,b){return a.dom().childNodes.length},z=e.immutable("element","offset"),A=function(a,b){var c=u(a);return c.length>0&&b0&&b.before(a,d),e(a)};return{empty:d,remove:e,unwrap:f}}),g("12",["17","a","b","1b"],function(a,b,c,d){var e=function(a){var b=c.isText(a)?a.dom().parentNode:a.dom();return void 0!==b&&null!==b&&b.ownerDocument.body.contains(b)},f=a.cached(function(){return g(b.fromDom(d))}),g=function(a){var c=a.dom().body;if(null===c||void 0===c)throw"Body is not available yet";return b.fromDom(c)};return{body:f,getBody:g,inBody:e}}),g("3",["2","t","y","z","9","11","12","10"],function(a,b,c,d,e,f,g,h){var i=function(d){a.emit(d,b.detachedFromDom());var e=d.components();c.each(e,i)},j=function(d){var e=d.components();c.each(e,j),a.emit(d,b.attachedToDom())},k=function(a,b){l(a,b,e.append)},l=function(a,b,c){a.getSystem().addToWorld(b),c(a.element(),b.element()),g.inBody(a.element())&&j(b),a.syncComponents()},m=function(a){i(a),f.remove(a.element()),a.getSystem().removeFromWorld(a)},n=function(a){var b=h.parent(a.element()).bind(function(b){return a.getSystem().getByDom(b).fold(d.none,d.some)});m(a),b.each(function(a){a.syncComponents()})},o=function(a){var b=a.components();c.each(b,m),f.empty(a.element()),a.syncComponents()},p=function(a,b){e.append(a,b.element());var d=h.children(b.element());c.each(d,function(a){b.getByDom(a).each(j)})},q=function(a){var b=h.children(a.element());c.each(b,function(b){a.getByDom(b).each(i)}),f.remove(a.element())};return{attach:k,attachWith:l,detach:n,detachChildren:o,attachSystem:p,detachSystem:q}}),g("6s",["y","a","10","1b"],function(a,b,c,d){var e=function(a,e){var f=e||d,g=f.createElement("div");return g.innerHTML=a,c.children(b.fromDom(g))},f=function(c,d){return a.map(c,function(a){return b.fromTag(a,d)})},g=function(c,d){return a.map(c,function(a){return b.fromText(a,d)})},h=function(c){return a.map(c,b.fromDom)};return{fromHtml:e,fromTags:f,fromText:g,fromDom:h}}),g("4n",["a","6s","9","2s","11","10"],function(a,b,c,d,e,f){var g=function(a){return a.dom().innerHTML},h=function(g,h){var i=f.owner(g),j=i.dom(),k=a.fromDom(j.createDocumentFragment()),l=b.fromHtml(h,j);d.append(k,l),e.empty(g),c.append(g,k)},i=function(b){var d=a.fromTag("div"),e=a.fromDom(b.dom().cloneNode(!0));return c.append(d,e),g(d)};return{get:g,set:h,getOuter:i}}),g("4o",["4i","a","9","2s","11","10"],function(a,b,c,d,e,f){var g=function(a,c){return b.fromDom(a.dom().cloneNode(c))},h=function(a){return g(a,!1)},i=function(a){return g(a,!0)},j=function(c,d){var e=b.fromTag(d),f=a.clone(c);return a.setAll(e,f),e},k=function(a,b){var c=j(a,b),e=f.children(i(a));return d.append(c,e),c},l=function(a,b){var g=j(a,b);c.before(a,g);var h=f.children(a);return d.append(g,h),e.remove(a),g};return{shallow:h,shallowAs:j,deep:i,copy:k,mutate:l}}),g("2t",["4n","4o"],function(a,b){var c=function(c){var d=b.shallow(c);return a.getOuter(d)};return{getHtml:c}}),g("13",["2t"],function(a){var b=function(b){return a.getHtml(b)};return{element:b}}),g("15",["z"],function(a){var b=function(a){for(var b=[],c=function(a){b.push(a)},d=0;d0&&!d.exists(n,function(b){return a.indexOf(b)>-1})}).getOr(j)}return j},p=function(a,b,c){},q={logEventCut:e.noop,logEventStopped:e.noop,logNoParent:e.noop,logEventNoHandlers:e.noop,logEventResponse:e.noop,write:e.noop},r=function(c,e,f){var g=k&&("*"===m||d.contains(m,c))?function(){var f=[];return{logEventCut:function(a,b,c){f.push({outcome:"cut",target:b,purpose:c})},logEventStopped:function(a,b,c){f.push({outcome:"stopped",target:b,purpose:c})},logNoParent:function(a,b,c){f.push({outcome:"no-parent",target:b,purpose:c})},logEventNoHandlers:function(a,b){f.push({outcome:"no-handlers-left",target:b})},logEventResponse:function(a,b,c){f.push({outcome:"response",purpose:c,target:b})},write:function(){d.contains(["mousemove","mouseover","mouseout",a.systemInit()],c)||h.log(c,{event:c,target:e.dom(),sequence:d.map(f,function(a){return d.contains(["cut","stopped","response"],a.outcome)?"{"+a.purpose+"} "+a.outcome+" at ("+b.element(a.target)+")":a.outcome})})}}}():q,i=f(g);return g.write(),i},s=function(a){var c=function(a){var e=a.spec();return{"(original.spec)":e,"(dom.ref)":a.element().dom(),"(element)":b.element(a.element()),"(initComponents)":d.map(void 0!==e.components?e.components:[],c),"(components)":d.map(a.components(),c),"(bound.events)":f.mapToArray(a.events(),function(a,b){return[b]}).join(", "),"(behaviours)":void 0!==e.behaviours?f.map(e.behaviours,function(b,c){return void 0===b?"--revoked--":{config:b.configAsRaw(),"original-config":b.initialConfig,state:a.readState(c)}}):"none"}};return c(a)},t=function(){return void 0!==window[l]?window[l]:(window[l]={systems:{},lookup:function(a){var d=window[l].systems,e=f.keys(d);return g.findMap(e,function(e){var f=d[e];return f.getByUid(a).toOption().map(function(a){return c.wrap(b.element(a.element()),s(a))})})}},window[l])},u=function(a,b){var c=t();c.systems[a]=b};return{logHandler:p,noLogger:e.constant(q),getTrace:o,monitorEvent:r,isDebugging:e.constant(k),registerInspector:u}}),g("5",[],function(){var a=function(b){var c=b,d=function(){return c},e=function(a){c=a},f=function(){return a(d())};return{get:d,set:e,clone:f}};return a}),g("4p",["1i","z"],function(a,b){return function(c,d,e,f,g){return c(e,f)?b.some(e):a.isFunction(g)&&g(e)?b.none():d(e,f,g)}}),g("2u",["1i","y","6","z","12","1a","a","4p"],function(a,b,c,d,e,f,g,h){var i=function(a){return n(e.body(),a)},j=function(b,e,f){for(var h=b.dom(),i=a.isFunction(f)?f:c.constant(!1);h.parentNode;){h=h.parentNode;var j=g.fromDom(h);if(e(j))return d.some(j);if(i(j))break}return d.none()},k=function(a,b,c){var d=function(a){return b(a)};return h(d,j,a,b,c)},l=function(a,b){var c=a.dom();return c.parentNode?m(g.fromDom(c.parentNode),function(c){return!f.eq(a,c)&&b(c)}):d.none()},m=function(a,d){var e=b.find(a.dom().childNodes,c.compose(d,g.fromDom));return e.map(g.fromDom)},n=function(a,b){var c=function(a){for(var e=0;ed?c:e=c?c:a};return{cycleBy:a,cap:b}}),g("7p",["y","12","10"],function(a,b,c){var d=function(a){return h(b.body(),a)},e=function(b,d,e){return a.filter(c.parents(b,e),d)},f=function(b,d){return a.filter(c.siblings(b),d)},g=function(b,d){return a.filter(c.children(b),d)},h=function(b,d){var e=[];return a.each(c.children(b),function(a){d(a)&&(e=e.concat([a])),e=e.concat(h(a,d))}),e};return{all:d,ancestors:e,siblings:f,children:g,descendants:h}}),g("5l",["7p","2r"],function(a,b){var c=function(a){return b.all(a)},d=function(c,d,e){return a.ancestors(c,function(a){return b.is(a,d)},e)},e=function(c,d){return a.siblings(c,function(a){return b.is(a,d)})},f=function(c,d){return a.children(c,function(a){return b.is(a,d)})},g=function(a,c){return b.all(c,a)};return{all:c,ancestors:d,siblings:e,children:f,descendants:g}}),g("7n",["95","y","z","48","2f","5l","4u","v"],function(a,b,c,d,e,f,g,h){var i=function(a,c,d){var g=f.descendants(a.element(),"."+c.highlightClass());b.each(g,function(b){e.remove(b,c.highlightClass()),a.getSystem().getByDom(b).each(function(b){c.onDehighlight()(a,b)})})},j=function(a,b,c,d){var f=o(a,b,c,d);e.remove(d.element(),b.highlightClass()),f&&b.onDehighlight()(a,d)},k=function(a,b,c,d){var f=o(a,b,c,d);i(a,b,c),e.add(d.element(),b.highlightClass()),f||b.onHighlight()(a,d)},l=function(a,b,c){r(a,b,c).each(function(d){k(a,b,c,d)})},m=function(a,b,c){s(a,b,c).each(function(d){k(a,b,c,d)})},n=function(a,b,c,d){q(a,b,c,d).fold(function(a){throw new h(a)},function(d){k(a,b,c,d)})},o=function(a,b,c,d){return e.has(d.element(),b.highlightClass())},p=function(a,b,c){return g.descendant(a.element(),"."+b.highlightClass()).bind(a.getSystem().getByDom)},q=function(a,b,e,g){var h=f.descendants(a.element(),"."+b.itemClass());return c.from(h[g]).fold(function(){return d.error("No element found with index "+g)},a.getSystem().getByDom)},r=function(a,b,c){return g.descendant(a.element(),"."+b.itemClass()).bind(a.getSystem().getByDom)},s=function(a,b,d){var e=f.descendants(a.element(),"."+b.itemClass()),g=e.length>0?c.some(e[e.length-1]):c.none();return g.bind(a.getSystem().getByDom)},t=function(c,d,g,h){var i=f.descendants(c.element(),"."+d.itemClass()),j=b.findIndex(i,function(a){return e.has(a,d.highlightClass())});return j.bind(function(b){var d=a.cycleBy(b,h,0,i.length-1);return c.getSystem().getByDom(i[d])})},u=function(a,b,c){return t(a,b,c,-1)},v=function(a,b,c){return t(a,b,c,1)};return{dehighlightAll:i,dehighlight:j,highlight:k,highlightFirst:l,highlightLast:m,highlightAt:n,isHighlighted:o,getHighlighted:p,getFirst:r,getLast:s,getPrevious:u,getNext:v}}),g("7o",["4q","29"],function(a,b){return[b.strict("highlightClass"),b.strict("itemClass"),a.onHandler("onHighlight"),a.onHandler("onDehighlight")]}),g("5j",["q","7n","7o","u"],function(a,b,c,d){return a.create({fields:c,name:"highlighting",apis:b})}),g("98",["5j","6","8"],function(a,b,c){var d=function(){var a=function(a){return c.search(a.element())},b=function(a,b){a.getSystem().triggerFocus(b,a.element())};return{get:a,set:b}},e=function(){var c=function(b){return a.getHighlighted(b).map(function(a){return a.element()})},d=function(c,d){c.getSystem().getByDom(d).fold(b.noop,function(b){a.highlight(c,b)})};return{get:c,set:d}};return{dom:d,highlights:e}}),g("8u",["y","6"],function(a,b){var c=function(b){return function(c){return a.contains(b,c.raw().which)}},d=function(b){return function(c){return a.forall(b,function(a){return a(c)})}},e=function(a){return function(b){return b.raw().which===a}},f=function(a){return a.raw().shiftKey===!0};return{inSet:c,and:d,is:e,isShift:f,isNotShift:b.not(f)}}),g("8v",["8u","y"],function(a,b){var c=function(b,c){return{matches:a.is(b),classification:c}},d=function(a,b){return{matches:a,classification:b}},e=function(a,c){var d=b.find(a,function(a){return a.matches(c)});return d.map(function(a){return a.classification})};return{basic:c,rule:d,choose:e}}),g("8s",["3d","2g","t","98","4q","8v","29","w"],function(a,b,c,d,e,f,g,h){var i=function(i,j,k,l,m,n){var o=function(){return i.concat([g.defaulted("focusManager",d.dom()),e.output("handler",r),e.output("state",j)])},p=function(a,b,c,d){var e=k(a,b,c,d);return f.choose(e,b.event()).bind(function(e){return e(a,b,c,d)})},q=function(d,e){var f=l(d,e),g=a.derive(n.map(function(b){return a.run(c.focus(),function(a,c){b(a,d,e,c),c.stop()})}).toArray().concat([a.run(b.keydown(),function(a,b){p(a,b,d,e).each(function(a){b.stop()})})]));return h.deepMerge(f,g)},r={schema:o,processKey:p,toEvents:q,toApis:m};return r};return{typical:i}}),g("8t",["y","1w"],function(a,b){var c=function(b,c,d){var e=a.reverse(b.slice(0,c)),f=a.reverse(b.slice(c+1));return a.find(e.concat(f),d)},d=function(b,c,d){var e=a.reverse(b.slice(0,c));return a.find(e,d)},e=function(b,c,d){var e=b.slice(0,c),f=b.slice(c+1);return a.find(f.concat(e),d)},f=function(b,c,d){var e=b.slice(c+1);return a.find(e,d)};return{cyclePrev:c,cycleNext:e,tryPrev:d,tryNext:f}}),g("57",[],function(){var a=function(a){return void 0!==a.style};return{isSupported:a}}),g("39",["1i","y","x","z","4i","12","a","b","57","37","v","16","1k"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=function(b,c,d){if(!a.isString(d))throw l.error("Invalid call to CSS.set. Property ",c,":: Value ",d,":: Element ",b),new k("CSS value must be a string: "+d);i.isSupported(b)&&b.style.setProperty(c,d)},o=function(a,b){i.isSupported(a)&&a.style.removeProperty(b)},p=function(a,b,c){var d=a.dom();n(d,b,c)},q=function(a,b){var d=a.dom();c.each(b,function(a,b){n(d,b,a)})},r=function(a,b){var d=a.dom();c.each(b,function(a,b){a.fold(function(){o(d,b)},function(a){n(d,b,a)})})},s=function(a,b){var c=a.dom(),d=m.getComputedStyle(c),e=d.getPropertyValue(b),g=""!==e||f.inBody(a)?e:t(c,b);return null===g?void 0:g},t=function(a,b){return i.isSupported(a)?a.style.getPropertyValue(b):""},u=function(a,b){var c=a.dom(),e=t(c,b);return d.from(e).filter(function(a){return a.length>0})},v=function(a){var b={},c=a.dom();if(i.isSupported(c))for(var d=0;dd?b-d:0;return e};return{set:g,get:h,getOuter:i,aggregate:j,max:k}}}),g("8b",["12","39","78"],function(a,b,c){var d=c("height",function(b){return a.inBody(b)?b.dom().getBoundingClientRect().height:b.dom().offsetHeight}),e=function(a,b){d.set(a,b)},f=function(a){return d.get(a)},g=function(a){return d.getOuter(a)},h=function(a,c){var e=["margin-top","border-top-width","padding-top","padding-bottom","border-bottom-width","margin-bottom"],f=d.max(a,c,e);b.set(a,"max-height",f+"px")};return{set:e,get:f,getOuter:g,setMax:h}}),g("6u",["8c","28","4q","8s","13","8t","8u","8v","29","y","6","z","1a","8","5l","4u","8b"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){var r=[i.defaulted("selector",'[data-alloy-tabstop="true"]'),i.option("onEscape"),i.option("onEnter"),i.defaulted("firstTabstop",0),i.defaulted("useTabstopAt",k.constant(!0)),i.option("visibilitySelector")],s=function(a,b,c){var d=o.descendants(a.element(),b.selector()),e=j.filter(d,function(a){return t(b,a)}),f=l.from(e[b.firstTabstop()]);f.each(function(b){var c=a.element();a.getSystem().triggerFocus(b,c)})},t=function(a,b){var c=a.visibilitySelector().bind(function(a){return p.closest(b,a)}).getOr(b);return q.get(c)>0},u=function(a,b){return n.search(a.element()).bind(function(a){return p.closest(a,b.selector())})},v=function(a,b,c,d,e){return e(b,c,function(a){return t(d,a)&&d.useTabstopAt(a)}).fold(function(){return l.some(!0)},function(b){var c=a.getSystem(),d=a.element();return c.triggerFocus(b,d),l.some(!0)})},w=function(a,b,c,d){var e=o.descendants(a.element(),c.selector());return u(a,c).bind(function(b){var f=j.findIndex(e,k.curry(m.eq,b));return f.bind(function(b){return v(a,e,b,c,d)})})},x=function(a,b,c,d){return w(a,b,c,f.cyclePrev)},y=function(a,b,c,d){return w(a,b,c,f.cycleNext)},z=function(a,b,c,d){return c.onEnter().bind(function(c){return c(a,b)})},A=function(a,b,c,d){return c.onEscape().bind(function(c){return c(a,b)})},B=k.constant([h.rule(g.and([g.isShift,g.inSet(a.TAB())]),x),h.rule(g.inSet(a.TAB()),y),h.rule(g.inSet(a.ESCAPE()),A),h.rule(g.and([g.isNotShift,g.inSet(a.ENTER())]),z)]),C=k.constant({}),D=k.constant({});return d.typical(r,b.init,B,C,D,l.some(s))}),g("8w",["4i","b"],function(a,b){var c=function(c){return"input"===b.name(c)&&"radio"!==a.get(c,"type")||"textarea"===b.name(c)};return{inside:c}}),g("8x",["8w","8c","2","t","8u","z"],function(a,b,c,d,e,f){var g=function(a,b,e){return c.dispatch(a,e,d.execute()),f.some(!0)},h=function(c,d,h){return a.inside(h)&&e.inSet(b.SPACE())(d.event())?f.none():g(c,d,h)};return{defaultExecute:h}}),g("6v",["8w","8c","28","8s","8x","13","8u","8v","29","6","z"],function(a,b,c,d,e,f,g,h,i,j,k){var l=[i.defaulted("execute",e.defaultExecute),i.defaulted("useSpace",!1),i.defaulted("useEnter",!0),i.defaulted("useDown",!1)],m=function(a,b,c,d){return c.execute()(a,b,a.element())},n=function(c,d,e,f){var i=e.useSpace()&&!a.inside(c.element())?b.SPACE():[],j=e.useEnter()?b.ENTER():[],k=e.useDown()?b.DOWN():[],l=i.concat(j).concat(k);return[h.rule(g.inSet(l),m)]},o=j.constant({}),p=j.constant({});return d.typical(l,c.init,n,o,p,k.none())}),g("4z",["4g","5","6","z"],function(a,b,c,d){var e=function(e){var f=b(d.none()),g=function(a,b){f.set(d.some({numRows:c.constant(a),numColumns:c.constant(b)}))},h=function(){return f.get().map(function(a){return a.numRows()})},i=function(){return f.get().map(function(a){return a.numColumns()})};return a({readState:c.constant({}),setGridSize:g,getNumRows:h,getNumColumns:i})},f=function(a){return a.state()(a)};return{flatgrid:e,init:f}}),g("9z",["39"],function(a){var b=function(a,b){return function(d){return"rtl"===c(d)?b:a}},c=function(b){return"rtl"===a.get(b,"direction")?"rtl":"ltr"};return{onDirection:b,getDirection:c}}),g("8y",["9z"],function(a){var b=function(a){return function(b,c,d,e){var g=a(b.element());return f(g,b,c,d,e)}},c=function(c,d){var e=a.onDirection(c,d);return b(e)},d=function(c,d){var e=a.onDirection(d,c);return b(e)},e=function(a){return function(b,c,d,e){return f(a,b,c,d,e)}},f=function(a,b,c,d,e){var f=d.focusManager().get(b).bind(function(c){return a(b.element(),c,d,e)});return f.map(function(a){return d.focusManager().set(b,a),!0})};return{east:d,west:c,north:e,south:e,move:e}}),g("a0",["y","2o"],function(a,b){var c=b.immutableBag(["index","candidates"],[]),d=function(b,d){return a.findIndex(b,d).map(function(a){return c({index:a,candidates:b})})};return{locate:d}}),g("a1",["6","4h","39"],function(a,b,c){var d=function(d,e,f,g){var h=c.get(d,e);void 0===h&&(h="");var i=h===f?g:f,j=a.curry(c.set,d,e,h),k=a.curry(c.set,d,e,i);return b(j,k,!1)},e=function(a){return d(a,"visibility","hidden","visible")},f=function(a,b){return d(a,"display","none",b)},g=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},h=function(a){var b=a.dom();return!g(b)};return{toggler:e,displayToggler:f,isVisible:h}}),g("8z",["a0","y","6","1a","5l","a1"],function(a,b,c,d,e,f){var g=function(a,b,c){var d=f.isVisible;return h(a,b,c,d)},h=function(g,h,i,j){var k=c.curry(d.eq,h),l=e.descendants(g,i),m=b.filter(l,f.isVisible);return a.locate(m,k)},i=function(a,c){return b.findIndex(a,function(a){return d.eq(c,a)})};return{locateVisible:g,locateIn:h,findIndex:i}}),g("90",["95","6","z","1w"],function(a,b,c,d){var e=function(a,b,e,f){var g=d.floor(b/e),h=b%e;return f(g,h).bind(function(b){var d=b.row()*e+b.column();return d>=0&&d"}),c.anyValue()),m=b.defaulted("defaults",e.constant({})),n=b.defaulted("overrides",e.constant({})),o=c.objOf([i,j,k,l,m,n]),p=c.objOf([i,j,k,m,n]),q=c.objOf([i,j,k,l,m,n]),r=c.objOf([i,j,k,b.strict("unit"),l,m,n]),s=function(a){return a.fold(g.some,g.none,g.some,g.some)},t=function(a){var b=function(a){return a.name()};return a.fold(b,b,b,b)},u=function(a){return a.fold(e.identity,e.identity,e.identity,e.identity)},v=function(a,b){return function(d){var e=c.asStructOrDie("Converting part type",b,d);return a(e)}};return{required:v(h.required,o),external:v(h.external,p),optional:v(h.optional,q),group:v(h.group,r),asNamedPart:s,name:t,asCommon:u,original:e.constant("entirety")}}),g("72",["14","y","x","w","6n","6","6k","v"],function(a,b,c,d,e,f,g,h){var i="placeholder",j=g.generate([{single:["required","valueThunk"]},{multiple:["required","valueThunks"]}]),k=function(a){return b.contains([i],a)},l=function(b,d,g,i){return b.exists(function(a){return a!==g.owner})?j.single(!0,f.constant(g)):a.readOptFrom(i,g.name).fold(function(){throw new h("Unknown placeholder component: "+g.name+"\nKnown: ["+c.keys(i)+"]\nNamespace: "+b.getOr("none")+"\nSpec: "+e.stringify(g,null,2))},function(a){return a.replace()})},m=function(a,b,c,d){return c.uiType===i?l(a,b,c,d):j.single(!1,f.constant(c))},n=function(c,e,f,g){var h=m(c,e,f,g);return h.fold(function(h,i){var j=i(e,f.config,f.validated),k=a.readOptFrom(j,"components").getOr([]),l=b.bind(k,function(a){return n(c,e,a,g)});return[d.deepMerge(j,{components:l})]},function(a,b){var c=b(e,f.config,f.validated);return c})},o=function(a,c,d,e){return b.bind(d,function(b){return n(a,c,b,e)})},p=function(a,b){var c=!1,d=function(){return c},e=function(){if(c===!0)throw new h("Trying to use the same placeholder more than once: "+a);return c=!0,b},g=function(){return b.fold(function(a,b){return a},function(a,b){return a})};return{name:f.constant(a),required:g,used:d,replace:e}},q=function(a,b,d,f){var g=c.map(f,function(a,b){return p(b,a)}),i=o(a,b,d,g);return c.each(g,function(c){if(c.used()===!1&&c.required())throw new h("Placeholder: "+c.name()+" was not found in components list\nNamespace: "+a.getOr("none")+"\nComponents: "+e.stringify(b.components(),null,2))}),i},r=function(a,b){var c=b;return c.fold(function(b,c){return[c(a)]},function(b,c){return c(a)})};return{single:j.single,multiple:j.multiple,isSubstitute:k,placeholder:f.constant(i),substituteAll:o,substitutePlaces:q,singleReplace:r}}),g("71",["53","72","14","y","6","w"],function(a,b,c,d,e,f){var g=function(a,b,d,e){var g=d;return f.deepMerge(b.defaults()(a,d,e),d,{uid:a.partUids()[b.name()]},b.overrides()(a,d,e),{"debug.sketcher":c.wrap("part-"+b.name(),g)})},h=function(c,h,i){var j={},k={};return d.each(i,function(c){c.fold(function(a){j[a.pname()]=b.single(!0,function(b,c,d){return a.factory().sketch(g(b,a,c,d))})},function(b){var c=h.parts()[b.name()]();k[b.name()]=e.constant(g(h,b,c[a.original()]()))},function(a){j[a.pname()]=b.single(!1,function(b,c,d){return a.factory().sketch(g(b,a,c,d))})},function(a){j[a.pname()]=b.multiple(!0,function(b,c,e){var g=b[a.name()]();return d.map(g,function(c){return a.factory().sketch(f.deepMerge(a.defaults()(b,c),c,a.overrides()(b,c)))})})})}),{internals:e.constant(j),externals:e.constant(k)}};return{subs:h}}),g("52",["4q","71","53","72","4c","29","14","2e","y","6","w","x","z"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=function(a,b){var d={};return i.each(b,function(b){c.asNamedPart(b).each(function(b){var c=o(a,b.pname());d[b.name()]=function(d){var e=h.asRawOrDie("Part: "+b.name()+" in "+a,h.objOf(b.schema()),d);return k.deepMerge(c,{config:d,validated:e})}})}),d},o=function(a,b){return{uiType:d.placeholder(),owner:a,name:b}},p=function(a,b,c){return{uiType:d.placeholder(),owner:a,name:b,config:c,validated:{}}},q=function(b){return i.bind(b,function(b){return b.fold(m.none,m.some,m.none,m.none).map(function(b){return f.strictObjOf(b.name(),b.schema().concat([a.snapshot(c.original())]))}).toArray()})},r=function(a){return i.map(a,c.name)},s=function(a,c,d){return b.subs(a,c,d)},t=function(a,b,c){return d.substitutePlaces(m.some(a),b,b.components(),c)},u=function(a,b,c){var d=b.partUids()[c];return a.getSystem().getByUid(d).toOption()},v=function(a,b,c){return u(a,b,c).getOrDie("Could not find part: "+c)},w=function(a,b,c){var d={},e=b.partUids(),f=a.getSystem();return i.each(c,function(a){d[a]=f.getByUid(e[a])}),l.map(d,j.constant)},x=function(a,b){var c=a.getSystem();return l.map(b.partUids(),function(a,b){return j.constant(c.getByUid(a))})},y=function(a,b,c){var d={},e=b.partUids(),f=a.getSystem();return i.each(c,function(a){d[a]=f.getByUid(e[a]).getOrDie()}),l.map(d,j.constant)},z=function(a,b){var c=r(b);return g.wrapAll(i.map(c,function(b){return{key:b,value:a+"-"+b}}))},A=function(a){return f.field("partUids","partUids",e.mergeWithThunk(function(b){return z(b.uid,a)}),h.anyValue())};return{generate:n,generateOne:p,schemas:q,names:r,substitutes:s,components:t,defaultUids:z,defaultUidsSchema:A,getAllParts:x,getPart:u,getPartOrDie:v,getParts:w,getPartsOrDie:y}}),g("73",["4q","72","29","14","2e","y","6","w","x","6n","v"],function(a,b,c,d,e,f,g,h,i,j,k){var l=function(e,g,h){var l=void 0!==h?h:"Unknown owner",m=function(){return[a.output("partUids",{})]},n=void 0!==g?g:m();if(0===e.length&&0===n.length)return m();var o=c.strictObjOf("parts",f.flatten([f.map(e,c.strict),f.map(n,function(a){return c.defaulted(a,b.single(!1,function(){throw new k("The optional part: "+a+" was not specified in the config, but it was used in components")}))})])),p=c.state("partUids",function(a){if(!d.hasKey(a,"parts"))throw new k("Part uid definition for owner: "+l+' requires "parts"\nExpected parts: '+e.join(", ")+"\nSpec: "+j.stringify(a,null,2));var b=i.map(a.parts,function(b,c){return d.readOptFrom(b,"uid").getOrThunk(function(){return a.uid+"-"+c})});return b});return[o,p]},m=function(b,d,e,f){var g=d.length>0?[c.strictObjOf("parts",d)]:[];return g.concat([c.strict("uid"),c.defaulted("dom",{}),c.defaulted("components",[]),a.snapshot("originalSpec"),c.defaulted("debug.sketcher",{})]).concat(e)},n=function(a,b,c,d){var f=m(a,d,c);return e.asRawOrDie(a+" [SpecSchema]",e.objOfOnly(f.concat(b)),c)},o=function(a,b,c,d,f){var g=m(a,d,f,c);return e.asStructOrDie(a+" [SpecSchema]",e.objOfOnly(g.concat(b)),c)},p=function(a,b,c){var d=h.deepMerge(b,c);return a(d)},q=function(a,b){return h.deepMerge(a,b)};return{asRawOrDie:n,asStructOrDie:o,addBehaviours:q,getPartsSchema:l,extend:p}}),g("51",["52","30","73","14","w"],function(a,b,c,d,e){var f=function(a,b,f,g){var i=h(g),j=c.asStructOrDie(a,b,i,[],[]);return e.deepMerge(f(j,i),{"debug.sketcher":d.wrap(a,g)})},g=function(b,f,g,i,j){var k=h(j),l=a.schemas(g),m=a.defaultUidsSchema(g),n=c.asStructOrDie(b,f,k,l,[m]),o=a.substitutes(b,n,g),p=a.components(b,n,o.internals());return e.deepMerge(i(n,p,k,o.externals()),{"debug.sketcher":d.wrap(b,j)})},h=function(a){return e.deepMerge({uid:b.generate("uid")},a)};return{supplyUid:h,single:f,composite:g}}),g("34",["50","51","4a","52","53","29","2e","6","w","x"],function(a,b,c,d,e,f,g,h,i,j){var k=g.objOfOnly([f.strict("name"),f.strict("factory"),f.strict("configFields"),f.defaulted("apis",{}),f.defaulted("extraApis",{})]),l=g.objOfOnly([f.strict("name"),f.strict("factory"),f.strict("configFields"),f.strict("partFields"),f.defaulted("apis",{}),f.defaulted("extraApis",{})]),m=function(d){var e=g.asRawOrDie("Sketcher for "+d.name,k,d),f=function(a){return b.single(e.name,e.configFields,e.factory,a)},l=j.map(e.apis,a.makeApi),m=j.map(e.extraApis,function(a,b){return c.markAsExtraApi(a,b)});return i.deepMerge({name:h.constant(e.name),partFields:h.constant([]),configFields:h.constant(e.configFields),sketch:f},l,m)},n=function(e){var f=g.asRawOrDie("Sketcher for "+e.name,l,e),k=function(a){return b.composite(f.name,f.configFields,f.partFields,f.factory,a)},m=d.generate(f.name,f.partFields),n=j.map(f.apis,a.makeApi),o=j.map(f.extraApis,function(a,b){return c.markAsExtraApi(a,b)});return i.deepMerge({name:h.constant(f.name),partFields:h.constant(f.partFields),configFields:h.constant(f.configFields),sketch:k,parts:h.constant(m)},n,o)};return{single:m,composite:n}}),g("35",["3d","2","2g","t","y","7"],function(a,b,c,d,e,f){var g=function(g){var h=function(b){return a.run(d.execute(),function(a,c){b(a),c.stop()})},i=function(a,c){c.stop(),b.emitExecute(a)},j=function(a,b){b.cut()},k=f.detect().deviceType.isTouch()?[a.run(d.tap(),i)]:[a.run(c.click(),i),a.run(c.mousedown(),j)];return a.derive(e.flatten([g.map(h).toArray(),k]))};return{events:g}}),g("1n",["q","32","33","34","35","29","w"],function(a,b,c,d,e,f,g){var h=function(d,f){var h=e.events(d.action());return{uid:d.uid(),dom:d.dom(),components:d.components(),events:h,behaviours:g.deepMerge(a.derive([b.config({}),c.config({mode:"execution",useSpace:!0,useEnter:!0})]),d.buttonBehaviours()),domModification:{attributes:{type:"button",role:d.role().getOr("button")}},eventOrder:d.eventOrder()}};return d.single({name:"Button",factory:h,configFields:[f.defaulted("uid",void 0),f.strict("dom"),f.defaulted("components",[]),f.defaulted("buttonBehaviours",{}),f.option("action"),f.option("role"),f.defaulted("eventOrder",{})]})}),g("36",["14","y","w","a","b","4n","10","u"],function(a,b,c,d,e,f,g,h){var i=function(d){var e=void 0!==d.dom().attributes?d.dom().attributes:[];return b.foldl(e,function(b,d){return"class"===d.name?b:c.deepMerge(b,a.wrap(d.name,d.value))},{})},j=function(a){return h.prototype.slice.call(a.dom().classList,0)},k=function(a){var b=d.fromHtml(a),h=g.children(b),k=i(b),l=j(b),m=0===h.length?{}:{innerHtml:f.get(b)};return c.deepMerge({tag:e.name(b),classes:l,attributes:k},m)},l=function(a,b,d){return a.sketch(c.deepMerge({dom:k(b)},d))};return{fromHtml:k,sketch:l}}),g("1o",["36","37","i"],function(a,b,c){var d=function(d){var e=b.supplant(d,{prefix:c.prefix()});return a.fromHtml(e)},e=function(a){var b=d(a);return{dom:b}};return{dom:d,spec:e}}),g("l",["q","1g","1m","1n","w","1l","i","1o"],function(a,b,c,d,e,f,g,h){var i=function(a,b){return m(b,function(){a.execCommand(b); +},{})},j=function(c){return a.derive([b.config({toggleClass:g.resolve("toolbar-button-selected"),toggleOnExecute:!1,aria:{mode:"pressed"}}),f.format(c,function(a,c){var d=c?b.on:b.off;d(a)})])},k=function(a,b){var c=j(b);return m(b,function(){a.execCommand(b)},c)},l=function(a,b,c,d){var e=j(c);return m(b,d,e)},m=function(b,f,g){return d.sketch({dom:h.dom(''),action:f,buttonBehaviours:e.deepMerge(a.derive([c.config({})]),g)})};return{forToolbar:m,forToolbarCommand:i,forToolbarStateAction:l,forToolbarStateCommand:k}}),g("93",["1w"],function(a){var b=function(b,c,d,e){return bd?d:b===c?c-1:a.max(c,b-e)},c=function(b,c,d,e){return b>d?b:bb.right)return f+1;var l=a.min(b.right,a.max(g,b.left))-b.left,m=d(l/b.width*k+c,c-1,f+1),n=a.round(m);return i&&m>=c&&m<=f?e(b,m,c,f,h,j):n};return{reduceBy:b,increaseBy:c,findValueOfX:f}}),g("74",["2","93","6","z","7","1w"],function(a,b,c,d,e,f){var g="slider.change.value",h=e.detect().deviceType.isTouch(),i=function(a){var b=a.event().raw();return h&&void 0!==b.touches&&1===b.touches.length?d.some(b.touches[0]):h&&void 0!==b.touches?d.none():h||void 0===b.clientX?d.none():d.some(b)},j=function(a){var b=i(a);return b.map(function(a){return a.clientX})},k=function(b,c){a.emitWith(b,g,{value:c})},l=function(a,b){k(a,b.min(),d.none())},m=function(a,b){k(a,b.max(),d.none())},n=function(a,b){k(a,b.max()+1,d.none())},o=function(a,b){k(a,b.min()-1,d.none())},p=function(a,c,d,e){var f=b.findValueOfX(c,d.min(),d.max(),e,d.stepSize(),d.snapToGrid(),d.snapStart());k(a,f)},q=function(a,b,c,d){return j(d).map(function(d){return p(a,c,b,d),d})},r=function(a,c){var e=b.reduceBy(c.value().get(),c.min(),c.max(),c.stepSize());k(a,e,d.none())},s=function(a,c){var e=b.increaseBy(c.value().get(),c.min(),c.max(),c.stepSize());k(a,e,d.none())};return{setXFromEvent:q,setToLedge:o,setToRedge:n,moveLeftFromRedge:m,moveRightFromLedge:l,moveLeft:r,moveRight:s,changeEvent:c.constant(g)}}),g("54",["q","32","33","3d","2g","53","74","29","5","6","z","7"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=l.detect(),n=m.deviceType.isTouch(),o=function(a,b){return f.optional({name:""+a+"-edge",overrides:function(a){var c=d.derive([d.runActionExtra(e.touchstart(),b,[a])]),f=d.derive([d.runActionExtra(e.mousedown(),b,[a]),d.runActionExtra(e.mousemove(),function(a,c){c.mouseIsDown().get()&&b(a,c)},[a])]);return{events:n?c:f}}})},p=o("left",g.setToLedge),q=o("right",g.setToRedge),r=f.required({name:"thumb",defaults:j.constant({dom:{styles:{position:"absolute"}}}),overrides:function(a){return{events:d.derive([d.redirectToPart(e.touchstart(),a,"spectrum"),d.redirectToPart(e.touchmove(),a,"spectrum"),d.redirectToPart(e.touchend(),a,"spectrum")])}}}),s=f.required({schema:[h.state("mouseIsDown",function(){return i(!1)})],name:"spectrum",overrides:function(f){var h=function(a,b){var c=a.element().dom().getBoundingClientRect();g.setXFromEvent(a,f,c,b)},i=d.derive([d.run(e.touchstart(),h),d.run(e.touchmove(),h)]),j=d.derive([d.run(e.mousedown(),h),d.run(e.mousemove(),function(a,b){f.mouseIsDown().get()&&h(a,b)})]);return{behaviours:a.derive(n?[]:[c.config({mode:"special",onLeft:function(a){return g.moveLeft(a,f),k.some(!0)},onRight:function(a){return g.moveRight(a,f),k.some(!0)}}),b.config({})]),events:n?i:j}}});return[p,q,r,s]}),g("55",["29","5","6","7"],function(a,b,c,d){var e=d.detect().deviceType.isTouch();return[a.strict("min"),a.strict("max"),a.defaulted("stepSize",1),a.defaulted("onChange",c.noop),a.defaulted("onInit",c.noop),a.defaulted("onDragStart",c.noop),a.defaulted("onDragEnd",c.noop),a.defaulted("snapToGrid",!1),a.option("snapStart"),a.strict("getInitialValue"),a.defaulted("sliderBehaviours",{}),a.state("value",function(a){return b(a.min)})].concat(e?[]:[a.state("mouseIsDown",function(){return b(!1)})])}),g("5b",[],function(){var a=function(a,b,c){b.store().manager().onLoad(a,b,c)},b=function(a,b,c){b.store().manager().onUnload(a,b,c)},c=function(a,b,c,d){b.store().manager().setValue(a,b,c,d)},d=function(a,b,c){return b.store().manager().getValue(a,b,c)};return{onLoad:a,onUnload:b,setValue:c,getValue:d}}),g("5a",["3d","27","5b"],function(a,b,c){var d=function(d,e){var f=d.resetOnDom()?[a.runOnAttached(function(a,b){c.onLoad(a,d,e)}),a.runOnDetached(function(a,b){c.onUnload(a,d,e)})]:[b.loadEvent(d,e,c.onLoad)];return a.derive(f)};return{events:d}}),g("5d",["4g","5"],function(a,b){var c=function(){var c=b(null),d=function(){return{mode:"memory",value:c.get()}},e=function(){return null===c.get()},f=function(){c.set(null)};return a({set:c.set,get:c.get,isNotSet:e,clear:f,readState:d})},d=function(){var b=function(){};return a({readState:b})},e=function(){var c=b({}),d=function(){return{mode:"dataset",dataset:c.get()}};return a({readState:d,set:c.set,get:c.get})},f=function(a){return a.store().manager().state(a)};return{memory:c,dataset:e,manual:d,init:f}}),g("75",["5d","4q","29","14","6"],function(a,b,c,d,e){var f=function(a,b,c,d){b.store().getDataKey();c.set({}),b.store().setData()(a,d),b.onSetValue()(a,d)},g=function(a,b,c){var e=b.store().getDataKey()(a),f=c.get();return d.readOptFrom(f,e).fold(function(){return b.store().getFallbackEntry()(e)},function(a){return a})},h=function(a,b,c){b.store().initialValue().each(function(d){f(a,b,c,d)})},i=function(a,b,c){c.set({})};return[c.option("initialValue"),c.strict("getFallbackEntry"),c.strict("getDataKey"),c.strict("setData"),b.output("manager",{setValue:f,getValue:g,onLoad:h,onUnload:i,state:a.dataset})]}),g("76",["28","4q","29","6"],function(a,b,c,d){var e=function(a,b,c){return b.store().getValue()(a)},f=function(a,b,c,d){b.store().setValue()(a,d),b.onSetValue()(a,d)},g=function(a,b,c){b.store().initialValue().each(function(c){b.store().setValue()(a,c)})};return[c.strict("getValue"),c.defaulted("setValue",d.noop),c.option("initialValue"),b.output("manager",{setValue:f,getValue:e,onLoad:g,onUnload:d.noop,state:a.init})]}),g("77",["5d","4q","29"],function(a,b,c){var d=function(a,b,c,d){c.set(d),b.onSetValue()(a,d)},e=function(a,b,c){return c.get()},f=function(a,b,c){b.store().initialValue().each(function(a){c.isNotSet()&&c.set(a)})},g=function(a,b,c){c.clear()};return[c.option("initialValue"),b.output("manager",{setValue:d,getValue:e,onLoad:f,onUnload:g,state:a.memory})]}),g("5c",["75","76","77","4q","29","2e"],function(a,b,c,d,e,f){return[e.defaultedOf("store",{mode:"memory"},f.choose("mode",{memory:c,manual:b,dataset:a})),d.onHandler("onSetValue"),e.defaulted("resetOnDom",!1)]}),g("3g",["q","5a","5b","5c","5d"],function(a,b,c,d,e){var f=a.create({fields:d,name:"representing",active:b,apis:c,extra:{setValueFrom:function(a,b){var c=f.getValue(b);f.setValue(a,c)}},state:e});return f}),g("5m",["39","78"],function(a,b){var c=b("width",function(a){return a.dom().offsetWidth}),d=function(a,b){c.set(a,b)},e=function(a){return c.get(a)},f=function(a){return c.getOuter(a)},g=function(b,d){var e=["margin-left","border-left-width","padding-left","padding-right","border-right-width","margin-right"],f=c.max(b,d,e);a.set(b,"max-width",f+"px")};return{set:d,get:e,getOuter:f,setMax:g}}),g("56",["q","33","3g","3d","2g","52","74","y","6","w","z","7","39","5m"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){var o=l.detect().deviceType.isTouch(),p=function(l,p,q,r){var s=l.max()-l.min(),t=function(a){var b=a.element().dom().getBoundingClientRect();return(b.left+b.right)/2},u=function(a){return f.getPartOrDie(a,l,"thumb")},v=function(a,b,c){var d=c.value().get();return dc.max()?f.getPart(a,c,"right-edge").fold(function(){return b.width},function(a){return t(a)-b.left}):(c.value().get()-c.min())/s*b.width},w=function(a){var b=f.getPartOrDie(a,l,"spectrum"),c=b.element().dom().getBoundingClientRect(),d=a.element().dom().getBoundingClientRect(),e=v(a,c,l);return c.left-d.left+e},x=function(a){var b=w(a),c=u(a),d=n.get(c.element())/2;m.set(c.element(),"left",b-d+"px")},y=function(a,b){var c=l.value().get(),d=u(a);return c!==b||m.getRaw(d.element(),"left").isNone()?(l.value().set(b),x(a),l.onChange()(a,d,b),k.some(!0)):k.none()},z=function(a){y(a,l.min(),k.none())},A=function(a){y(a,l.max(),k.none())},B=o?[d.run(e.touchstart(),function(a,b){l.onDragStart()(a,u(a))}),d.run(e.touchend(),function(a,b){l.onDragEnd()(a,u(a))})]:[d.run(e.mousedown(),function(a,b){b.stop(),l.onDragStart()(a,u(a)),l.mouseIsDown().set(!0)}),d.run(e.mouseup(),function(a,b){l.onDragEnd()(a,u(a)),l.mouseIsDown().set(!1)})];return{uid:l.uid(),dom:l.dom(),components:p,behaviours:j.deepMerge(a.derive(h.flatten([o?[]:[b.config({mode:"special",focusIn:function(a){return f.getPart(a,l,"spectrum").map(b.focusIn).map(i.constant(!0))}})],[c.config({store:{mode:"manual",getValue:function(a){return l.value().get()}}})]])),l.sliderBehaviours()),events:d.derive([d.run(g.changeEvent(),function(a,b){y(a,b.event().value())}),d.runOnAttached(function(a,b){l.value().set(l.getInitialValue()());var c=u(a);x(a),l.onInit()(a,c,l.value().get())})].concat(B)),apis:{resetToMin:z,resetToMax:A,refresh:x},domModification:{styles:{position:"relative"}}}};return{sketch:p}}),g("38",["34","54","55","56","1w"],function(a,b,c,d,e){return a.composite({name:"Slider",configFields:c,partFields:b,factory:d.sketch,apis:{resetToMin:function(a,b){a.resetToMin(b)},resetToMax:function(a,b){a.resetToMax(b)},refresh:function(a,b){a.refresh(b)}}})}),g("3a",["l"],function(a){var b=function(b,c,d){return a.forToolbar(c,function(){var a=d();b.setContextToolbar([{label:c+" group",items:a}])},{})};return{button:b}}),g("1p",["q","1f","1g","38","39","1l","i","3a","1o"],function(a,b,c,d,e,f,g,h,i){var j=-1,k=function(b){var h=function(a){return a<0?"black":a>360?"white":"hsl("+a+", 100%, 50%)"},j=function(a,b,c){var d=h(c);e.set(b.element(),"background-color",d)},k=function(a,c,d){var f=h(d);e.set(c.element(),"background-color",f),b.onChange(a,c,f)};return d.sketch({dom:i.dom('
    '),components:[d.parts()["left-edge"](i.spec('
    ')),d.parts().spectrum({dom:i.dom('
    '),components:[i.spec('
    ')],behaviours:a.derive([c.config({toggleClass:g.resolve("thumb-active")})])}),d.parts()["right-edge"](i.spec('
    ')),d.parts().thumb({dom:i.dom('
    '),behaviours:a.derive([c.config({toggleClass:g.resolve("thumb-active")})])})],onChange:k,onDragStart:function(a,b){c.on(b)},onDragEnd:function(a,b){c.off(b)},onInit:j,stepSize:10,min:0,max:360,getInitialValue:b.getInitialValue,sliderBehaviours:a.derive([f.orientation(d.refresh)])})},l=function(a){return[k(a)]},m=function(a,b){var c={onChange:function(a,c,d){b.undoManager.transact(function(){b.formatter.apply("forecolor",{value:d}),b.nodeChanged()})},getInitialValue:function(){return j}};return h.button(a,"color",function(){return l(c)})};return{makeItems:l,sketch:m}}),g("3b",["q","1f","1g","38","29","2e","1l","i","1o"],function(a,b,c,d,e,f,g,h,i){var j=f.objOfOnly([e.strict("getInitialValue"),e.strict("onChange"),e.strict("category"),e.strict("sizes")]),k=function(b){var e=f.asRawOrDie("SizeSlider",j,b),k=function(a){return a>=0&&a
    '),components:[i.spec('
    ')]}),d.parts().thumb({dom:i.dom('
    '),behaviours:a.derive([c.config({toggleClass:h.resolve("thumb-active")})])})]})};return{sketch:k}}),g("58",["1i","6","z","a"],function(a,b,c,d){var e=function(e,f,g){for(var h=e.dom(),i=a.isFunction(g)?g:b.constant(!1);h.parentNode;){h=h.parentNode;var j=d.fromDom(h),k=f(j);if(k.isSome())return k;if(i(j))break}return c.none()},f=function(a,b,d){var f=b(a);return f.orThunk(function(){return d(a)?c.none():e(a,b,d)})};return{ancestor:e,closest:f}}),g("3c",["y","6","z","1a","a","b","39","58","10"],function(a,b,c,d,e,f,g,h,i){var j=["9px","10px","11px","12px","14px","16px","18px","20px","24px","32px","36px"],k="medium",l=2,m=function(a){return c.from(j[a])},n=function(b){return a.findIndex(j,function(a){return a===b})},o=function(a,b){var d=f.isElement(b)?c.some(b):i.parent(b);return d.map(function(b){var c=h.closest(b,function(a){return g.getRaw(a,"font-size")},a);return c.getOrThunk(function(){return g.get(b,"font-size")})}).getOr("")},p=function(b){var c=b.selection.getStart(),f=e.fromDom(c),g=e.fromDom(b.getBody()),h=function(a){return d.eq(g,a)},i=o(h,f);return a.find(j,function(a){return i===a}).getOr(k)},q=function(a,b){var c=p(a);c!==b&&a.execCommand("fontSize",!1,b)},r=function(a){var b=p(a);return n(b).getOr(l)},s=function(a,b){m(b).each(function(b){q(a,b)})};return{candidates:b.constant(j),get:r,apply:s}}),g("1q",["3b","3a","3c","1o"],function(a,b,c,d){var e=c.candidates(),f=function(b){return a.sketch({onChange:b.onChange,sizes:e,category:"font",getInitialValue:b.getInitialValue})},g=function(a){return[d.spec(''),f(a),d.spec('')]},h=function(a,d){var e={onChange:function(a){c.apply(d,a)},getInitialValue:function(){return c.get(d)}};return b.button(a,"font-size",function(){return g(e)})};return{makeItems:g,sketch:h}});g("79",[],function(){function a(a,b){return e(document.createElement("canvas"),a,b)}function b(b){var d,e;return d=a(b.width,b.height),e=c(d),e.drawImage(b,0,0),d}function c(a){return a.getContext("2d")}function d(a){var b=null;try{b=a.getContext("webgl")||a.getContext("experimental-webgl")}catch(a){}return b||(b=null),b}function e(a,b,c){return a.width=b,a.height=c,a}return{create:a,clone:b,resize:e,get2dContext:c,get3dContext:d}});g("7a",[],function(){function a(a){return a.naturalWidth||a.width}function b(a){return a.naturalHeight||a.height}return{getWidth:a,getHeight:b}}),g("7b",[],function(){function a(a){var b=document.createElement("a");return b.href=a,b.pathname}function b(b){var c,d,e,f;return 0===b.indexOf("data:")?(b=b.split(","),f=/data:([^;]+)/.exec(b[0]),f?f[1]:""):(e={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png"},c=a(b).split("."),d=c[c.length-1],d&&(d=d.toLowerCase()),e[d])}return{guessMimeType:b}}),g("7c",[],function(){function a(a,b){return function(){a.apply(b,arguments)}}function b(b){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof b)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],h(b,a(d,this),a(e,this))}function c(a){var b=this;return null===this._state?void this._deferreds.push(a):void i(function(){var c=b._state?a.onFulfilled:a.onRejected;if(null===c)return void(b._state?a.resolve:a.reject)(b._value);var d;try{d=c(b._value)}catch(b){return void a.reject(b)}a.resolve(d)})}function d(b){try{if(b===this)throw new TypeError("A promise cannot be resolved with itself.");if(b&&("object"==typeof b||"function"==typeof b)){var c=b.then;if("function"==typeof c)return void h(a(c,b),a(d,this),a(e,this))}this._state=!0,this._value=b,f.call(this)}catch(a){e.call(this,a)}}function e(a){this._state=!1,this._value=a,f.call(this)}function f(){for(var a=0,b=this._deferreds.length;a'),components:[g.asSpec()],action:function(a){var b=g.get(a);b.element().dom().click()}})};return{sketch:k}}),g("5e",[],function(){var a=function(a){return a.dom().textContent},b=function(a,b){a.dom().textContent=b};return{get:a,set:b}}),g("3h",["6","z","a","4i","5e","4u"],function(a,b,c,d,e,f){var g=function(a){return a.length>0},h=function(a){return void 0===a||null===a?"":a},i=function(a){var c=a.selection.getContent({format:"text"});return{url:"",text:c,title:"",target:"",link:b.none()}},j=function(a){var c=e.get(a),f=d.get(a,"href"),g=d.get(a,"title"),i=d.get(a,"target");return{url:h(f),text:c!==f?h(c):"",title:h(g),target:h(i),link:b.some(a)}},k=function(a){return q(a).fold(function(){return i(a)},function(a){return j(a)})},l=function(a){var b=d.get(a,"href"),c=e.get(a);return b===c},m=function(a,c,d){return d.text.filter(g).fold(function(){return l(a)?b.some(c):b.none()},b.some)},n=function(b,c){var d=c.link.bind(a.identity);d.each(function(a){b.execCommand("unlink")})},o=function(a,b){var c={};return c.href=a,b.title.filter(g).each(function(a){c.title=a}),b.target.filter(g).each(function(a){c.target=a}),c},p=function(b,c){c.url.filter(g).fold(function(){n(b,c)},function(f){var h=o(f,c),i=c.link.bind(a.identity);i.fold(function(){var a=c.text.filter(g).getOr(f);b.insertContent(b.dom.createHTML("a",h,b.dom.encode(a)))},function(a){var b=m(a,f,c);d.setAll(a,h),b.each(function(b){e.set(a,b)})})})},q=function(a){var b=c.fromDom(a.selection.getStart());return f.closest(b,"a")};return{getInfo:k,applyInfo:p,query:q}}),g("3u",["q","3d","29","6"],function(a,b,c,d){var e=function(e,f){var g=b.derive(f);return a.create({fields:[c.strict("enabled")],name:e,active:{events:d.constant(g)}})},f=function(b,c){var f=e(b,c);return{key:b,value:{config:{},me:f,configAsRaw:d.constant({}),initialConfig:{},state:a.noState()}}};return{events:e,config:f}}),g("7h",[],function(){var a=function(a,b,c){return b.find()(a)};return{getCurrent:a}}),g("7i",["29"],function(a){return[a.strict("find")]}),g("5f",["q","7h","7i"],function(a,b,c){return a.create({fields:c,name:"composing",apis:b})}),g("3v",["34","29","w"],function(a,b,c){var d=function(a,b){return{uid:a.uid(),dom:c.deepMerge({tag:"div",attributes:{role:"presentation"}},a.dom()),components:a.components(),behaviours:a.containerBehaviours(),events:a.events(),domModification:a.domModification(),eventOrder:a.eventOrder()}};return a.single({name:"Container",factory:d,configFields:[b.defaulted("components",[]),b.defaulted("containerBehaviours",{}),b.defaulted("events",{}),b.defaulted("domModification",{}),b.defaulted("eventOrder",{})]})}),g("5g",["q","5f","3g","3d","34","29","z"],function(a,b,c,d,e,f,g){var h=function(e,f){return{uid:e.uid(),dom:e.dom(),behaviours:a.derive([c.config({store:{mode:"memory",initialValue:e.getInitialValue()()}}),b.config({find:g.some})]),events:d.derive([d.runOnAttached(function(a,b){c.setValue(a,e.getInitialValue()())})])}};return e.single({name:"DataField",factory:h,configFields:[f.strict("uid"),f.strict("dom"),f.strict("getInitialValue")]})}),g("88",["4b","14"],function(a,b){var c=function(c,d){return a.nu({attributes:b.wrapAll([{key:d.tabAttr(),value:"true"}])})};return{exhibit:c}}),g("89",["29"],function(a){return[a.defaulted("tabAttr","data-alloy-tabstop")]}),g("64",["q","88","89"],function(a,b,c){return a.create({fields:c,name:"tabstopping",active:b})}),g("94",["v"],function(a){var b=function(a){return a.dom().value},c=function(b,c){if(void 0===c)throw new a("Value.set was undefined");b.dom().value=c};return{set:c,get:b}}),g("7j",["q","32","3g","64","4q","29","14","6","w","94"],function(a,b,c,d,e,f,g,h,i,j){var k=[f.option("data"),f.defaulted("inputAttributes",{}),f.defaulted("inputStyles",{}),f.defaulted("type","input"),f.defaulted("tag","input"),e.onHandler("onSetValue"),f.defaulted("styles",{}),f.option("placeholder"),f.defaulted("eventOrder",{}),f.defaulted("hasTabstop",!0),f.defaulted("inputBehaviours",{}),f.defaulted("selectOnFocus",!0)],l=function(e){return i.deepMerge(a.derive([c.config({store:{mode:"manual",initialValue:e.data().getOr(void 0),getValue:function(a){return j.get(a.element())},setValue:function(a,b){var c=j.get(a.element());c!==b&&j.set(a.element(),b)}},onSetValue:e.onSetValue()}),b.config({onFocus:e.selectOnFocus()===!1?h.noop:function(a){var b=a.element(),c=j.get(b);b.dom().setSelectionRange(0,c.length)}}),e.hasTabstop()?d.config({}):d.revoke()]),e.inputBehaviours())},m=function(a){return{tag:a.tag(),attributes:i.deepMerge(g.wrapAll([{key:"type",value:a.type()}].concat(a.placeholder().map(function(a){return{key:"placeholder",value:a}}).toArray())),a.inputAttributes()),styles:a.inputStyles()}};return{schema:h.constant(k),behaviours:l,dom:m}}),g("5h",["34","7j"],function(a,b){var c=function(a,c){return{uid:a.uid(),dom:b.dom(a),components:[],behaviours:b.behaviours(a),eventOrder:a.eventOrder()}};return a.single({name:"Input",configFields:b.schema(),factory:c})}),g("3i",["3u","q","5f","3g","1g","1h","3d","2","2g","1n","3v","5g","5h","z","i","1o"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q="input-clearing",r=function(l,r){var s=f.record(m.sketch({placeholder:r,onSetValue:function(a,b){h.emit(a,i.input())},inputBehaviours:b.derive([c.config({find:n.some})]),selectOnFocus:!1})),t=f.record(j.sketch({dom:p.dom(''),action:function(a){var b=s.get(a);d.setValue(b,"")}}));return{name:l,spec:k.sketch({dom:p.dom('
    '),components:[s.asSpec(),t.asSpec()],containerBehaviours:b.derive([e.config({toggleClass:o.resolve("input-container-empty")}),c.config({find:function(a){return n.some(s.get(a))}}),a.config(q,[g.run(i.input(),function(a){var b=s.get(a),c=d.getValue(b),f=c.length>0?e.off:e.on;f(a)})])])})}},s=function(a){return{name:a,spec:l.sketch({dom:{tag:"span",styles:{display:"none"}},getInitialValue:function(){return n.none()}})}};return{field:r,hidden:s}}),g("7l",["y","4i","2f","b"],function(a,b,c,d){var e=["input","button","textarea"],f=function(a,b,c){b.disabled()&&n(a,b,c)},g=function(b){return a.contains(e,d.name(b.element()))},h=function(a){return b.has(a.element(),"disabled")},i=function(a){b.set(a.element(),"disabled","disabled")},j=function(a){b.remove(a.element(),"disabled")},k=function(a){return"true"===b.get(a.element(),"aria-disabled")},l=function(a){b.set(a.element(),"aria-disabled","true")},m=function(a){b.set(a.element(),"aria-disabled","false")},n=function(a,b,d){b.disableClass().each(function(b){c.add(a.element(),b)});var e=g(a)?i:l;e(a)},o=function(a,b,d){b.disableClass().each(function(b){c.remove(a.element(),b)});var e=g(a)?j:m;e(a)},p=function(a){return g(a)?h(a):k(a)};return{enable:o,disable:n,isDisabled:p,onLoad:f}}),g("7k",["3d","t","27","7l","4b","y"],function(a,b,c,d,e,f){var g=function(a,b,c){return e.nu({classes:b.disabled()?b.disableClass().map(f.pure).getOr([]):[]})},h=function(e,f){return a.derive([a.abort(b.execute(),function(a,b){return d.isDisabled(a,e,f)}),c.loadEvent(e,f,d.onLoad)])};return{exhibit:g,events:h}}),g("7m",["29"],function(a){return[a.defaulted("disabled",!1),a.option("disableClass")]}),g("5i",["q","7k","7l","7m"],function(a,b,c,d){return a.create({fields:d,name:"disabling",active:b,apis:c})}),g("5k",["q","5f","3g","51","52","53","29","y","w","x"],function(a,b,c,d,e,f,g,h,i,j){var k="form",l=[g.defaulted("formBehaviours",{})],m=function(a){return""},n=function(a){var b=function(){var a=[],b=function(b,c){return a.push(b),e.generateOne(k,m(b),c)};return{field:b,record:function(){return a}}}(),c=a(b),g=b.record(),i=h.map(g,function(a){return f.required({name:a,pname:m(a)})});return d.composite(k,l,i,o,c)},o=function(d,f,g){return i.deepMerge({"debug.sketcher":{Form:g},uid:d.uid(),dom:d.dom(),components:f,behaviours:i.deepMerge(a.derive([c.config({store:{mode:"manual",getValue:function(a){var f=e.getAllParts(a,d);return j.map(f,function(a,d){return a().bind(b.getCurrent).map(c.getValue)})},setValue:function(a,f){j.each(f,function(f,g){e.getPart(a,d,g).each(function(a){b.getCurrent(a).each(function(a){c.setValue(a,f)})})})}}})]),d.formBehaviours())})};return{sketch:n}}),g("1z",["z","5"],function(a,b){var c=function(c){var d=b(a.none()),e=function(){d.get().each(c)},f=function(){e(),d.set(a.none())},g=function(b){e(),d.set(a.some(b))},h=function(){return d.get().isSome()};return{clear:f,isSet:h,set:g}},d=function(){return c(function(a){a.destroy()})},e=function(){return c(function(a){a.unbind()})},f=function(){var c=b(a.none()),d=function(){c.get().each(function(a){a.destroy()})},e=function(){d(),c.set(a.none())},f=function(b){d(),c.set(a.some(b))},g=function(a){c.get().each(a)},h=function(){return c.get().isSome()};return{clear:e,isSet:h,set:f,run:g}},g=function(){var c=b(a.none()),d=function(){c.set(a.none())},e=function(b){c.set(a.some(b))},f=function(a){c.get().each(a)},g=function(){return c.get().isSome()};return{clear:d,set:e,isSet:g,on:f}};return{destroyable:d,unbindable:e,api:f,value:g}}),g("5n",[],function(){var a=1,b=-1,c=0,d=function(a){return{xValue:a,points:[]}},e=function(c,d){if(d===c.xValue)return c;var e=d-c.xValue>0?a:b,f={direction:e,xValue:d},g=function(){if(0===c.points.length)return[];var a=c.points[c.points.length-1];return a.direction===e?c.points.slice(0,c.points.length-1):c.points}();return{xValue:d,points:g.concat([f])}},f=function(d){if(0===d.points.length)return c;var e=d.points[0].direction,f=d.points[d.points.length-1].direction;return e===b&&f===b?b:e===a&&f==a?a:c};return{init:d,move:e,complete:f}}),g("3j",["3u","q","5i","5j","33","1f","3g","1h","3d","2","2g","1n","3v","5k","29","2e","y","5","z","1z","39","5l","4u","5m","1l","5n","i","1o"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B){var C=function(f){var C="navigateEvent",D="serializer-wrapper-events",E="form-events",F=p.objOf([o.strict("fields"),o.defaulted("maxFieldIndex",f.fields.length-1),o.strict("onExecute"),o.strict("getInitialValue"),o.state("state",function(){return{dialogSwipeState:t.value(),currentScreen:r(0)}})]),G=p.asRawOrDie("SerialisedDialog",F,f),H=function(a,d,e){return l.sketch({dom:B.dom(''),action:function(b){j.emitWith(b,C,{direction:a})},buttonBehaviours:b.derive([c.config({disableClass:A.resolve("toolbar-navigation-disabled"),disabled:!e})])})},I=function(a,b){w.descendant(a.element(),"."+A.resolve("serialised-dialog-chain")).each(function(a){u.set(a,"left",-G.state.currentScreen.get()*b.width+"px")})},J=function(a,b){var c=v.descendants(a.element(),"."+A.resolve("serialised-dialog-screen"));w.descendant(a.element(),"."+A.resolve("serialised-dialog-chain")).each(function(a){G.state.currentScreen.get()+b>=0&&G.state.currentScreen.get()+b'),components:[m.sketch({dom:B.dom('
    '),components:q.map(G.fields,function(a,b){return b<=G.maxFieldIndex?m.sketch({dom:B.dom('
    '),components:q.flatten([[H(-1,"previous",b>0)],[c.field(a.name,a.spec)],[H(1,"next",b'),behaviours:b.derive([d.config({highlightClass:A.resolve("dot-active"),itemClass:A.resolve("dot-item")})]),components:q.bind(G.fields,function(a,b){return b<=G.maxFieldIndex?[B.spec('
    ')]:[]})});return{dom:B.dom('
    '),components:[M.asSpec(),N.asSpec()],behaviours:b.derive([e.config({mode:"special",focusIn:function(a){var b=M.get(a);e.focusIn(b)}}),a.config(D,[i.run(k.touchstart(),function(a,b){G.state.dialogSwipeState.set(z.init(b.event().raw().touches[0].clientX))}),i.run(k.touchmove(),function(a,b){G.state.dialogSwipeState.on(function(a){b.event().prevent(),G.state.dialogSwipeState.set(z.move(a,b.event().raw().touches[0].clientX))})}),i.run(k.touchend(),function(a){G.state.dialogSwipeState.on(function(b){var c=M.get(a),d=-1*z.complete(b);J(c,d)})})])])}};return{sketch:C}}),g("3k",["6","7"],function(a,b){var c=b.detect(),d=function(a,b){var c=b.selection.getRng();a(),b.selection.setRng(c)},e=function(b,e){var f=c.os.isAndroid()?d:a.apply;f(e,b)};return{forAndroid:e}}),g("1s",["3g","z","17","3h","l","3i","3j","3k"],function(a,b,c,d,e,f,g,h){var i=c.cached(function(c,e){return[{label:"the link group",items:[g.sketch({fields:[f.field("url","Type or paste URL"),f.field("text","Link text"),f.field("title","Link title"),f.field("target","Link target"),f.hidden("link")],maxFieldIndex:["url","text","title","target"].length-1,getInitialValue:function(){return b.some(d.getInfo(e))},onExecute:function(b){var f=a.getValue(b);d.applyInfo(e,f),c.restoreToolbar(),e.focus()}})]}]}),j=function(a,b){return e.forToolbarStateAction(b,"link","link",function(){var c=i(a,b);a.setContextToolbar(c),h.forAndroid(b,function(){a.focusToolbar()}),d.query(b).each(function(a){b.selection.select(a.dom())})})};return{sketch:j}}),g("3l",[],function(){return[{title:"Headings",items:[{title:"Heading 1",format:"h1"},{title:"Heading 2",format:"h2"},{title:"Heading 3",format:"h3"},{title:"Heading 4",format:"h4"},{title:"Heading 5",format:"h5"},{title:"Heading 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}]}),g("7r",["14","6","z","4i","2f"],function(a,b,c,d,e){var f=function(c,d,e,f){return a.readOptFrom(d.routes(),f.start()).map(b.apply).bind(function(c){return a.readOptFrom(c,f.destination()).map(b.apply)})},g=function(a,b,c){var d=k(a,b,c);return d.bind(function(d){return h(a,b,c,d)})},h=function(a,c,d,e){return f(a,c,d,e).bind(function(a){return a.transition().map(function(c){return{transition:b.constant(c),route:b.constant(a)}})})},i=function(a,b,c){g(a,b,c).each(function(c){var f=c.transition();e.remove(a.element(),f.transitionClass()),d.remove(a.element(),b.destinationAttr())})},j=function(a,c,e,f){return{start:b.constant(d.get(a.element(),c.stateAttr())),destination:b.constant(f)}},k=function(a,e,f){var g=a.element();return d.has(g,e.destinationAttr())?c.some({start:b.constant(d.get(a.element(),e.stateAttr())),destination:b.constant(d.get(a.element(),e.destinationAttr()))}):c.none()},l=function(a,b,c,e){i(a,b,c),d.has(a.element(),b.stateAttr())&&d.get(a.element(),b.stateAttr())!==e&&b.onFinish()(a,e),d.set(a.element(),b.stateAttr(),e)},m=function(a,b,c,e){d.has(a.element(),b.destinationAttr())&&(d.set(a.element(),b.stateAttr(),d.get(a.element(),b.destinationAttr())),d.remove(a.element(),b.destinationAttr()))},n=function(a,b,c,f){m(a,b,c,f);var g=j(a,b,c,f);h(a,b,c,g).fold(function(){l(a,b,c,f)},function(g){i(a,b,c);var h=g.transition();e.add(a.element(),h.transitionClass()),d.set(a.element(),b.destinationAttr(),f)})},o=function(a,b,e){var f=a.element();return d.has(f,b.stateAttr())?c.some(d.get(f,b.stateAttr())):c.none()};return{findRoute:f,disableTransition:i,getCurrentRoute:k,jumpTo:l,progressTo:n,getState:o}}),g("7q",["3d","2g","7r"],function(a,b,c){var d=function(d,e){return a.derive([a.run(b.transitionend(),function(a,b){var f=b.event().raw();c.getCurrentRoute(a,d,e).each(function(b){c.findRoute(a,d,e,b).each(function(g){g.transition().each(function(g){f.propertyName===g.property()&&(c.jumpTo(a,d,e,b.destination()),d.onTransition()(a,b))})})})}),a.runOnAttached(function(a,b){c.jumpTo(a,d,e,d.initialState())})])};return{events:d}}),g("7s",["4q","29","2e","48"],function(a,b,c,d){return[b.defaulted("destinationAttr","data-transitioning-destination"),b.defaulted("stateAttr","data-transitioning-state"),b.strict("initialState"),a.onHandler("onTransition"),a.onHandler("onFinish"),b.strictOf("routes",c.setOf(d.value,c.setOf(d.value,c.objOfOnly([b.optionObjOfOnly("transition",[b.strict("property"),b.strict("transitionClass")])]))))]}),g("5o",["q","7q","7r","7s","14","x"],function(a,b,c,d,e,f){var g=function(a){var b={};return f.each(a,function(a,c){var d=c.split("<->");b[d[0]]=e.wrap(d[1],a),b[d[1]]=e.wrap(d[0],a)}),b},h=function(a,b,c){return e.wrapAll([{key:a,value:e.wrap(b,c)},{key:b,value:e.wrap(a,c)}])},i=function(a,b,c,d){return e.wrapAll([{key:a,value:e.wrapAll([{key:b,value:d},{key:c,value:d}])},{key:b,value:e.wrapAll([{key:a,value:d},{key:c,value:d}])},{key:c,value:e.wrapAll([{key:a,value:d},{key:b,value:d}])}])};return a.create({fields:d,name:"transitioning",active:b,apis:c,extra:{createRoutes:g,createBistate:h,createTristate:i}})}),g("7u",["28","4c","29","2e","y","6","x","6n","v"],function(a,b,c,d,e,f,g,h,i){var j=function(j,k){var l=e.map(k,function(e){return c.field(e.name(),e.name(),b.asOption(),d.objOf([c.strict("config"),c.defaulted("state",a)]))}),m=d.asStruct("component.behaviours",d.objOf(l),j.behaviours).fold(function(a){throw new i(d.formatError(a)+"\nComplete spec:\n"+h.stringify(j,null,2))},f.identity);return{list:k,data:g.map(m,function(a){var b=a();return f.constant(b.map(function(a){return{config:a.config(),state:a.state().init(a.config())}}))})}},k=function(a){return a.list},l=function(a){return a.data};return{generateFrom:j,getBehaviours:k,getData:l}}),g("7t",["7u","14","y","x","v"],function(a,b,c,d,e){var f=function(a){var e=b.readOptFrom(a,"behaviours").getOr({}),f=c.filter(d.keys(e),function(a){return void 0!==e[a]});return c.map(f,function(b){return a.behaviours[b].me})},g=function(b,c){return a.generateFrom(b,c)},h=function(a){var b=f(a);return g(a,b)};return{generate:h,generateFrom:g}}),g("5q",["6q"],function(a){return a.exactly(["getSystem","config","spec","connect","disconnect","element","syncComponents","readState","components","events"])}),g("6a",["6q"],function(a){return a.exactly(["debugInfo","triggerFocus","triggerEvent","triggerEscape","addToWorld","removeFromWorld","addToGui","removeFromGui","build","getByUid","getByDom","broadcast","broadcastOn"])}),g("5r",["6a","13","6","v"],function(a,b,c,d){return function(e){var f=function(a){return function(){throw new d("The component must be in a context to send: "+a+"\n"+b.element(e().element())+" is not in context.")}};return a({debugInfo:c.constant("fake"),triggerEvent:f("triggerEvent"),triggerFocus:f("triggerFocus"),triggerEscape:f("triggerEscape"),build:f("build"),addToWorld:f("addToWorld"),removeFromWorld:f("removeFromWorld"),addToGui:f("addToGui"),removeFromGui:f("removeFromGui"),getByUid:f("getByUid"),getByDom:f("getByDom"),broadcast:f("broadcast"),broadcastOn:f("broadcastOn")})}}),g("96",["14","x"],function(a,b){var c=function(c,d){var e={};return b.each(c,function(c,f){b.each(c,function(b,c){var g=a.readOr(c,[])(e);e[c]=g.concat([d(f,b)])})}),e};return{byInnerKey:c}}),g("7v",["96","4b","14","y","x","w","6n","6","48"],function(a,b,c,d,e,f,g,h,i){var j=function(a,b){return{name:h.constant(a),modification:b}},k=function(a,b){var e=d.bind(a,function(a){return a.modification().getOr([])});return i.value(c.wrap(b,e))},l=function(a,b,e){return a.length>1?i.error('Multiple behaviours have tried to change DOM "'+b+'". The guilty behaviours are: '+g.stringify(d.map(a,function(a){return a.name()}))+". At this stage, this is not supported. Future releases might provide strategies for resolving this."):0===a.length?i.value({}):i.value(a[0].modification().fold(function(){return{}},function(a){return c.wrap(b,a)}))},m=function(a,b,c,e){return i.error("Mulitple behaviours have tried to change the _"+b+'_ "'+a+'". The guilty behaviours are: '+g.stringify(d.bind(e,function(a){return void 0!==a.modification().getOr({})[b]?[a.name()]:[]}),null,2)+". This is not currently supported.")},n=function(a,b){var f=d.foldl(a,function(d,f){var g=f.modification().getOr({});return d.bind(function(d){var f=e.mapToArray(g,function(e,f){return void 0!==d[f]?m(b,f,g,a):i.value(c.wrap(f,e))});return c.consolidate(f,d)})},i.value({}));return f.map(function(a){return c.wrap(b,a)})},o={classes:k,attributes:n,styles:n,domChildren:l,defChildren:l,innerHtml:l,value:l},p=function(g,h,k,l){var m=f.deepMerge({},h);d.each(k,function(a){m[a.name()]=a.exhibit(g,l)});var n=a.byInnerKey(m,j),p=e.map(n,function(a,b){return d.bind(a,function(a){return a.modification().fold(function(){return[]},function(b){return[a]})})}),q=e.mapToArray(p,function(a,b){return c.readOptFrom(o,b).fold(function(){return i.error("Unknown field type: "+b)},function(c){return c(a,b)})}),r=c.consolidate(q,{});return r.map(b.nu)};return{combine:p}}),g("97",["6n","48","v"],function(a,b,c){var d=function(d,e,f,g){var h=f.slice(0);try{var i=h.sort(function(b,f){var h=b[e](),i=f[e](),j=g.indexOf(h),k=g.indexOf(i);if(j===-1)throw new c("The ordering for "+d+" does not have an entry for "+h+".\nOrder specified: "+a.stringify(g,null,2));if(k===-1)throw new c("The ordering for "+d+" does not have an entry for "+i+".\nOrder specified: "+a.stringify(g,null,2));return j1?f.filter(b,function(b){return f.contains(a,function(a){return a.name()===b})}).join(" > "):a[0].name();return e.wrap(c,d.nu(h,i))})});return e.consolidate(c,{})};return{combine:q}}),g("7x",["4q","6o","4b","4s","4c","29","14","2e","y","6","w","v"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=function(b){return h.asStruct("custom.definition",h.objOfOnly([f.field("dom","dom",e.strict(),h.objOfOnly([f.strict("tag"),f.defaulted("styles",{}),f.defaulted("classes",[]),f.defaulted("attributes",{}),f.option("value"),f.option("innerHtml")])),f.strict("components"),f.strict("uid"),f.defaulted("events",{}),f.defaulted("apis",j.constant({})),f.field("eventOrder","eventOrder",e.mergeWith({"alloy.execute":["disabling","alloy.base.behaviour","toggling"],"alloy.focus":["alloy.base.behaviour","keying","focusing"],"alloy.system.init":["alloy.base.behaviour","disabling","toggling","representing"],input:["alloy.base.behaviour","representing","streaming","invalidating"],"alloy.system.detached":["alloy.base.behaviour","representing"]}),h.anyValue()),f.option("domModification"),a.snapshot("originalSpec"),f.defaulted("debug.sketcher","unknown")]),b)},n=function(a){return g.wrap(d.idAttr(),a.uid())},o=function(a){var c={tag:a.dom().tag(),classes:a.dom().classes(),attributes:k.deepMerge(n(a),a.dom().attributes()),styles:a.dom().styles(),domChildren:i.map(a.components(),function(a){return a.element()})};return b.nu(k.deepMerge(c,a.dom().innerHtml().map(function(a){return g.wrap("innerHtml",a)}).getOr({}),a.dom().value().map(function(a){return g.wrap("value",a)}).getOr({})))},p=function(a){return a.domModification().fold(function(){return c.nu({})},c.nu)},q=function(a){return a.apis()},r=function(a){return a.events()};return{toInfo:m,toDefinition:o,toModification:p,toApis:q,toEvents:r}}),g("8a",["y","2f","4j","u"],function(a,b,c,d){var e=function(c,d){a.each(d,function(a){b.add(c,a)})},f=function(c,d){a.each(d,function(a){b.remove(c,a)})},g=function(c,d){a.each(d,function(a){b.toggle(c,a)})},h=function(c,d){return a.forall(d,function(a){return b.has(c,a)})},i=function(c,d){return a.exists(d,function(a){return b.has(c,a)})},j=function(a){for(var b=a.dom().classList,c=new d(b.length),e=0;e1?f.some(a.slice(1)):f.none()})},r=function(a){return b.readOptFrom(j.get(),a)},s=function(a){return b.readOptFrom(i.get(),a)},t=function(a){var b=l.get()(i.get());return c.difference(d.keys(b),a)},u=function(){return k.get().bind(s)},v=function(){return i.get()};return{setContents:o,expand:p,refresh:r,collapse:q,lookupMenu:s,otherMenus:t,getPrimary:u,getMenus:v,clear:m,isClear:n}}}),g("81",["8w","q","5f","5j","33","1y","3g","3q","3d","2","t","98","5u","9e","9c","9d","14","y","6","w","x","z","15","12","2f","8a","4u"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A){var B=function(s,B){var C=function(a,b){return u.map(b,function(b,c){var d=m.sketch(t.deepMerge(b,{value:c,items:b.items,markers:q.narrow(B.markers,["item","selectedItem"]),fakeFocus:s.fakeFocus(),onHighlight:s.onHighlight(),focusManager:s.fakeFocus()?l.highlights():l.dom()}));return a.getSystem().build(d)})},D=n(),E=function(a){var b=C(a,s.data().menus());return D.setContents(s.data().primary(),b,s.data().expansions(),function(b){return G(a,b)}),D.getPrimary()},F=function(a){return g.getValue(a).value},G=function(a,b){return u.map(s.data().menus(),function(a,b){return r.bind(a.items,function(a){return"separator"===a.type?[]:[a.data.value]})})},H=function(a,b){d.highlight(a,b),d.getHighlighted(b).orThunk(function(){return d.getFirst(b)}).each(function(b){j.dispatch(a,b.element(),k.focusItem())})},I=function(a,b){return w.cat(r.map(b,a.lookupMenu))},J=function(a,b,c){return v.from(c[0]).bind(b.lookupMenu).map(function(d){var e=I(b,c.slice(1));r.each(e,function(a){y.add(a.element(),s.markers().backgroundMenu())}),x.inBody(d.element())||f.append(a,h.premade(d)),z.remove(d.element(),[s.markers().backgroundMenu()]),H(a,d);var g=I(b,b.otherMenus(c));return r.each(g,function(b){z.remove(b.element(),[s.markers().backgroundMenu()]),s.stayInDom()||f.remove(a,b)}),d})},K=function(a,b){var c=F(b);return D.expand(c).bind(function(c){return v.from(c[0]).bind(D.lookupMenu).each(function(c){x.inBody(c.element())||f.append(a,h.premade(c)),s.onOpenSubmenu()(a,b,c),d.highlightFirst(c)}),J(a,D,c)})},L=function(a,b){var c=F(b);return D.collapse(c).bind(function(c){return J(a,D,c).map(function(c){return s.onCollapseMenu()(a,b,c),c})})},M=function(a,b){var c=F(b);return D.refresh(c).bind(function(b){return J(a,D,b)})},N=function(b,c){return a.inside(c.element())?v.none():K(b,c)},O=function(b,c){return a.inside(c.element())?v.none():L(b,c)},P=function(a,b){return L(a,b).orThunk(function(){return s.onEscape()(a,b)})},Q=function(a){return function(b,c){return A.closest(c.getSource(),"."+s.markers().item()).bind(function(c){return b.getSystem().getByDom(c).bind(function(c){return a(b,c)})})}},R=i.derive([i.run(p.focus(),function(a,b){var c=b.event().menu();d.highlight(a,c)}),i.runOnExecute(function(a,b){var c=b.event().target();return a.getSystem().getByDom(c).bind(function(b){var c=F(b);return 0===c.indexOf("collapse-item")?L(a,b):K(a,b).orThunk(function(){return s.onExecute()(a,b)})})}),i.runOnAttached(function(a,b){E(a).each(function(b){f.append(a,h.premade(b)),s.openImmediately()&&(H(a,b),s.onOpenMenu()(a,b))})})].concat(s.navigateOnHover()?[i.run(o.hover(),function(a,b){var c=b.event().item();M(a,c),K(a,c),s.onHover()(a,c)})]:[])),S=function(a){d.getHighlighted(a).each(function(b){d.getHighlighted(b).each(function(b){L(a,b)})})};return{uid:s.uid(),dom:s.dom(),behaviours:t.deepMerge(b.derive([e.config({mode:"special",onRight:Q(N),onLeft:Q(O),onEscape:Q(P),focusIn:function(a,b){D.getPrimary().each(function(b){j.dispatch(a,b.element(),k.focusItem())})}}),d.config({highlightClass:s.markers().selectedMenu(),itemClass:s.markers().menu()}),c.config({find:function(a){return d.getHighlighted(a)}}),f.config({})]),s.tmenuBehaviours()),eventOrder:s.eventOrder(),apis:{collapseMenu:S},events:R}};return{make:B,collapseItem:s.constant("collapse-item")}}),g("5v",["34","4q","81","29","14","3f"],function(a,b,c,d,e,f){var g=function(a,b,c){return{primary:a,menus:b,expansions:c}},h=function(a,b){return{primary:a,menus:e.wrap(a,b),expansions:{}}},i=function(a){return{value:f.generate(c.collapseItem()),text:a}};return a.single({name:"TieredMenu",configFields:[b.onStrictKeyboardHandler("onExecute"),b.onStrictKeyboardHandler("onEscape"),b.onStrictHandler("onOpenMenu"),b.onStrictHandler("onOpenSubmenu"),b.onHandler("onCollapseMenu"),d.defaulted("openImmediately",!0),d.strictObjOf("data",[d.strict("primary"),d.strict("menus"),d.strict("expansions")]),d.defaulted("fakeFocus",!1),b.onHandler("onHighlight"),b.onHandler("onHover"),b.tieredMenuMarkers(),d.strict("dom"),d.defaulted("navigateOnHover",!0),d.defaulted("stayInDom",!1),d.defaulted("tmenuBehaviours",{}),d.defaulted("eventOrder",{})],apis:{collapseMenu:function(a,b){a.collapseMenu(b)}},factory:c.make,extraApis:{tieredData:g,singleData:h,collapseItem:i}})}),g("3z",["6","2f","i"],function(a,b,c){var d=c.resolve("scrollable"),e=function(a){b.add(a,d)},f=function(a){b.remove(a,d)};return{register:e,deregister:f,scrollable:a.constant(d)}}),g("3m",["3u","q","3g","1g","5o","3q","1h","3d","1n","5u","5v","14","y","w","x","39","4u","5m","1l","i","3z"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){var v=function(a){return l.readOptFrom(a,"format").getOr(a.title)},w=function(a,b){var c=y("Styles",[].concat(m.map(a.items,function(b){return x(v(b),b.title,b.isSelected(),b.getPreview(),l.hasKey(a.expansions,v(b)))})),b,!1),d=o.map(a.menus,function(c,d){ +var e=m.map(c,function(b){return x(v(b),b.title,void 0!==b.isSelected&&b.isSelected(),void 0!==b.getPreview?b.getPreview():"",l.hasKey(a.expansions,v(b)))});return y(d,e,b,!0)}),e=n.deepMerge(d,l.wrap("styles",c)),f=k.tieredData("styles",e,a.expansions);return{tmenu:f}},x=function(a,c,e,f,g){return{data:{value:a,text:c},type:"item",dom:{tag:"div",classes:g?[t.resolve("styles-item-is-menu")]:[]},toggling:{toggleOnExecute:!1,toggleClass:t.resolve("format-matches"),selected:e},itemBehaviours:b.derive(g?[]:[s.format(a,function(a,b){var c=b?d.on:d.off;c(a)})]),components:[{dom:{tag:"div",attributes:{style:f},innerHtml:c}}]}},y=function(c,d,g,l){return{value:c,dom:{tag:"div"},components:[i.sketch({dom:{tag:"div",classes:[t.resolve("styles-collapser")]},components:l?[{dom:{tag:"span",classes:[t.resolve("styles-collapse-icon")]}},f.text(c)]:[f.text(c)],action:function(a){if(l){var b=g().get(a);k.collapseMenu(b)}}}),{dom:{tag:"div",classes:[t.resolve("styles-menu-items-container")]},components:[j.parts().items({})],behaviours:b.derive([a.config("adhoc-scrollable-menu",[h.runOnAttached(function(a,b){p.set(a.element(),"overflow-y","auto"),p.set(a.element(),"-webkit-overflow-scrolling","touch"),u.register(a.element())}),h.runOnDetached(function(a){p.remove(a.element(),"overflow-y"),p.remove(a.element(),"-webkit-overflow-scrolling"),u.deregister(a.element())})])])}],items:d,menuBehaviours:b.derive([e.config({initialState:"after",routes:e.createTristate("before","current","after",{transition:{property:"transform",transitionClass:"transitioning"}})})])}},z=function(a){var b=w(a.formats,function(){return d}),d=g.record(k.sketch({dom:{tag:"div",classes:[t.resolve("styles-menu")]},components:[],fakeFocus:!0,stayInDom:!0,onExecute:function(b,d){var e=c.getValue(d);a.handle(d,e.value)},onEscape:function(){},onOpenMenu:function(a,b){var c=r.get(a.element());r.set(b.element(),c),e.jumpTo(b,"current")},onOpenSubmenu:function(a,b,c){var d=r.get(a.element()),f=q.ancestor(b.element(),'[role="menu"]').getOrDie("hacky"),g=a.getSystem().getByDom(f).getOrDie();r.set(c.element(),d),e.progressTo(g,"before"),e.jumpTo(c,"after"),e.progressTo(c,"current")},onCollapseMenu:function(a,b,c){var d=q.ancestor(b.element(),'[role="menu"]').getOrDie("hacky"),f=a.getSystem().getByDom(d).getOrDie();e.progressTo(f,"after"),e.progressTo(c,"current")},navigateOnHover:!1,openImmediately:!0,data:b.tmenu,markers:{backgroundMenu:t.resolve("styles-background-menu"),menu:t.resolve("styles-menu"),selectedMenu:t.resolve("styles-selected-menu"),item:t.resolve("styles-item"),selectedItem:t.resolve("styles-selected-item")}}));return d.asSpec()};return{sketch:z}}),g("3n",["14","y","w"],function(a,b,c){var d=function(b){var d=c.deepMerge(a.exclude(b,["items"]),{menu:!0}),e=f(b.items,b.title),g=c.deepMerge(e.menus,a.wrap(b.title,e.items)),h=c.deepMerge(e.expansions,a.wrap(b.title,b.title));return{item:d,menus:g,expansions:h}},e=function(b){return a.hasKey(b,"items")?d(b):{item:b,menus:{},expansions:{}}},f=function(a){return b.foldr(a,function(a,b){var d=e(b);return{menus:c.deepMerge(a.menus,d.menus),items:[d.item].concat(a.items),expansions:c.deepMerge(a.expansions,d.expansions)}},{menus:{},expansions:{},items:[]})};return{expand:f}}),g("1t",["1g","14","y","6","3f","w","3l","3m","3n"],function(a,b,c,d,e,f,g,h,i){var j=function(a,h){var i=function(b){return function(){return a.formatter.match(b)}},j=function(b){return function(){var c=a.formatter.getCssText(b);return c}},k=function(a){return f.deepMerge(a,{isSelected:i(a.format),getPreview:j(a.format)})},l=function(a){return f.deepMerge(a,{isSelected:d.constant(!1),getPreview:d.constant("")})},m=function(b){var c=e.generate(b.title),d=f.deepMerge(b,{format:c,isSelected:i(c),getPreview:j(c)});return a.formatter.register(c,d),d},n=b.readOptFrom(h,"style_formats").getOr(g),o=function(a){return c.map(a,function(a){if(b.hasKey(a,"items")){var c=o(a.items);return f.deepMerge(l(a),{items:c})}return b.hasKey(a,"format")?k(a):m(a)})};return o(n)},k=function(a,d){var e=function(d){return c.bind(d,function(c){if(void 0!==c.items){var d=e(c.items);return d.length>0?[c]:[]}var f=!b.hasKey(c,"format")||a.formatter.canApply(c.format);return f?[c]:[]})},f=e(d);return i.expand(f)},l=function(b,c,d){var e=k(b,c);return h.sketch({formats:e,handle:function(c,e){b.undoManager.transact(function(){a.isOn(c)?b.formatter.remove(e):b.formatter.apply(e)}),d()}})};return{register:j,ui:l}}),g("h",["q","1f","1g","1h","14","y","6","z","1i","1j","1k","1l","g","i","l","1p","1q","1r","1s","1t"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){var u=["undo","bold","italic","link","image","bullist","styleselect"],v=function(a){var b=a.replace(/\|/g," ").trim();return b.length>0?b.split(/\s+/):[]},w=function(a){return f.bind(a,function(a){return i.isArray(a)?w(a):v(a)})},x=function(a){var b=void 0!==a.toolbar?a.toolbar:u;return i.isArray(b)?w(b):v(b)},y=function(d,f){var g=function(a){return function(){return o.forToolbarCommand(f,a)}},i=function(a){return function(){return o.forToolbarStateCommand(f,a)}},j=function(a,b,c){return function(){return o.forToolbarStateAction(f,a,b,c)}},k=g("undo"),u=g("redo"),v=i("bold"),w=i("italic"),x=i("underline"),y=g("removeformat"),z=function(){return s.sketch(d,f)},A=j("unlink","link",function(){f.execCommand("unlink",null,!1)}),B=function(){return r.sketch(f)},C=j("unordered-list","ul",function(){f.execCommand("InsertUnorderedList",null,!1)}),D=j("ordered-list","ol",function(){f.execCommand("InsertOrderedList",null,!1)}),E=function(){return q.sketch(d,f)},F=function(){return p.sketch(d,f)},G=t.register(f,f.settings),H=function(){return t.ui(f,G,function(){f.fire("scrollIntoView")})},I=function(){return o.forToolbar("style-formats",function(a){f.fire("toReading"),d.dropup().appear(H,c.on,a)},a.derive([c.config({toggleClass:n.resolve("toolbar-button-selected"),toggleOnExecute:!1,aria:{mode:"pressed"}}),b.config({channels:e.wrapAll([l.receive(m.orientationChanged(),c.off),l.receive(m.dropupDismissed(),c.off)])})]))},J=function(a,b){return{isSupported:function(){return a.forall(function(a){return e.hasKey(f.buttons,a)})},sketch:b}};return{undo:J(h.none(),k),redo:J(h.none(),u),bold:J(h.none(),v),italic:J(h.none(),w),underline:J(h.none(),x),removeformat:J(h.none(),y),link:J(h.none(),z),unlink:J(h.none(),A),image:J(h.none(),B),bullist:J(h.some("bullist"),C),numlist:J(h.some("numlist"),D),fontsizeselect:J(h.none(),E),forecolor:J(h.none(),F),styleselect:J(h.none(),I)}},z=function(a,b){var c=x(a),d={};return f.bind(c,function(a){var c=!e.hasKey(d,a)&&e.hasKey(b,a)&&b[a].isSupported()?[b[a].sketch()]:[];return d[a]=!0,c})};return{identify:x,setup:y,detect:z}}),g("3o",["6","a"],function(a,b){var c=function(b,c,d,e,f,g,h){return{target:a.constant(b),x:a.constant(c),y:a.constant(d),stop:e,prevent:f,kill:g,raw:a.constant(h)}},d=function(d,e){return function(f){if(d(f)){var g=b.fromDom(f.target),h=function(){f.stopPropagation()},i=function(){f.preventDefault()},j=a.compose(i,h),k=c(g,f.clientX,f.clientY,h,i,j,f);e(k)}}},e=function(b,c,e,f,g){var i=d(e,f);return b.dom().addEventListener(c,i,g),{unbind:a.curry(h,b,c,i,g)}},f=function(a,b,c,d){return e(a,b,c,d,!1)},g=function(a,b,c,d){return e(a,b,c,d,!0)},h=function(a,b,c,d){a.dom().removeEventListener(b,c,d)};return{bind:f,capture:g}}),g("1u",["6","3o"],function(a,b){var c=a.constant(!0),d=function(a,d,e){return b.bind(a,d,c,e)},e=function(a,d,e){return b.capture(a,d,c,e)};return{bind:d,capture:e}}),h("1v",clearInterval),h("1x",setInterval),g("j",["6","z","7","1u","a","1v","1w","1x"],function(a,b,c,d,e,f,g,h){var i=50,j=1e3/i,k=function(b){var c=b.matchMedia("(orientation: portrait)").matches;return{isPortrait:a.constant(c)}},l=function(a){var b=c.detect().os.isiOS(),d=k(a).isPortrait();return b&&!d?a.screen.height:a.screen.width},m=function(a,c){var g=e.fromDom(a),l=null,m=function(){f(l);var b=k(a);c.onChange(b),o(function(){c.onReady(b)})},n=d.bind(g,"orientationchange",m),o=function(c){f(l);var d=a.innerHeight,e=0;l=h(function(){d!==a.innerHeight?(f(l),c(b.some(a.innerHeight))):e>j&&(f(l),c(b.none())),e++},i)},p=function(){n.unbind()};return{onAdjustment:o,destroy:p}};return{get:k,onChange:m,getActualWidth:l}}),h("87",clearTimeout),g("9f",["87","1j"],function(a,b){return function(c,d){var e=null,f=function(){var a=arguments;e=b(function(){c.apply(null,a),e=null},d)},g=function(){null!==e&&(a(e),e=null)};return{cancel:g,schedule:f}}}),g("8d",["9f","2g","t","14","5","6","z","1a","1w"],function(a,b,c,d,e,f,g,h,i){var j=5,k=400,l=function(a){return void 0===a.raw().touches||1!==a.raw().touches.length?g.none():g.some(a.raw().touches[0])},m=function(a,b){var c=i.abs(a.clientX-b.x()),d=i.abs(a.clientY-b.y());return c>j||d>j},n=function(i){var j=e(g.none()),n=a(function(a){j.set(g.none()),i.triggerEvent(c.longpress(),a)},k),o=function(a){return l(a).each(function(b){n.cancel();var c={x:f.constant(b.clientX),y:f.constant(b.clientY),target:a.target};n.schedule(c),j.set(g.some(c))}),g.none()},p=function(a){return n.cancel(),l(a).each(function(a){j.get().each(function(b){m(a,b)&&j.set(g.none())})}),g.none()},q=function(a){n.cancel();var b=function(b){return h.eq(b.target(),a.target())};return j.get().filter(b).map(function(b){return i.triggerEvent(c.tap(),a)})},r=d.wrapAll([{key:b.touchstart(),value:o},{key:b.touchmove(),value:p},{key:b.touchend(),value:q}]),s=function(a,b){return d.readOptFrom(r,b).bind(function(b){return b(a)})};return{fireIfReady:s}};return{monitor:n}}),g("82",["8d","1u"],function(a,b){var c=function(c){var d=a.monitor({triggerEvent:function(a,b){c.onTapContent(b)}}),e=function(){return b.bind(c.body(),"touchend",function(a){d.fireIfReady(a,"touchend")})},f=function(){return b.bind(c.body(),"touchmove",function(a){d.fireIfReady(a,"touchmove")})},g=function(a){d.fireIfReady(a,"touchstart")};return{fireTouchstart:g,onTouchend:e,onTouchmove:f}};return{monitor:c}}),g("5x",["1g","y","6","7","1a","8","1u","a","b","10","82"],function(a,b,c,d,e,f,g,h,i,j,k){var l=d.detect().os.version.major>=6,m=function(d,m,n){var o=k.monitor(d),p=j.owner(m),q=function(a){return!e.eq(a.start(),a.finish())||a.soffset()!==a.foffset()},r=function(){return f.active(p).filter(function(a){return"input"===i.name(a)}).exists(function(a){return a.dom().selectionStart!==a.dom().selectionEnd})},s=function(){var b=d.doc().dom().hasFocus()&&d.getSelection().exists(q);n.getByDom(m).each((b||r())===!0?a.on:a.off)},t=[g.bind(d.body(),"touchstart",function(a){d.onTouchContent(),o.fireTouchstart(a)}),o.onTouchmove(),o.onTouchend(),g.bind(m,"touchstart",function(a){d.onTouchToolstrip()}),d.onToReading(function(){f.blur(d.body())}),d.onToEditing(c.noop),d.onScrollToCursor(function(a){a.preventDefault(),d.getCursorBox().each(function(a){var b=d.win(),c=a.top()>b.innerHeight||a.bottom()>b.innerHeight,e=c?a.bottom()-b.innerHeight+50:0;0!==e&&b.scrollTo(b.pageXOffset,b.pageYOffset+e)})})].concat(l===!0?[]:[g.bind(h.fromDom(d.win()),"blur",function(){n.getByDom(m).each(a.off)}),g.bind(p,"select",s),g.bind(d.doc(),"selectionchange",s)]),u=function(){b.each(t,function(a){a.unbind()})};return{destroy:u}};return{initEvents:m}}),g("83",["y","6","8","a","b","1j"],function(a,b,c,d,e,f){var g=function(){return function(a){f(function(){a()},0)}},h=function(f){f.focus();var h=d.fromDom(f.document.body),i=c.active().exists(function(b){return a.contains(["input","textarea"],e.name(b))}),j=i?g(h):b.apply;j(function(){c.active().each(c.blur),c.focus(h)})};return{resume:h}}),h("9g",isNaN),h("8i",parseInt),g("84",["4i","9g","8i"],function(a,b,c){var d=function(d,e){var f=c(a.get(d,e),10);return b(f)?0:f};return{safeParse:d}}),g("ab",["7","z","v"],function(a,b,c){return function(d,e){var f=function(a){if(!d(a))throw new c("Can only get "+e+" value of a "+e+" node");return j(a).getOr("")},g=function(a){try{return h(a)}catch(a){return b.none()}},h=function(a){return d(a)?b.from(a.dom().nodeValue):b.none()},i=a.detect().browser,j=i.isIE()&&10===i.version.major?g:h,k=function(a,b){if(!d(a))throw new c("Can only set raw "+e+" value of a "+e+" node");a.dom().nodeValue=b};return{get:f,getOption:j,set:k}}}),g("a4",["b","ab"],function(a,b){var c=b(a.isText,"text"),d=function(a){return c.get(a)},e=function(a){return c.getOption(a)},f=function(a,b){c.set(a,b)};return{get:d,getOption:e,set:f}}),g("9h",["y","b","a4","10"],function(a,b,c,d){var e=function(a){return"img"===b.name(a)?1:c.getOption(a).fold(function(){return d.children(a).length},function(a){return a.length})},f=function(a,b){return e(a)===b},g=function(a,b){return 0===b},h="\xa0",i=function(a){return c.getOption(a).filter(function(a){return 0!==a.trim().length||a.indexOf(h)>-1}).isSome()},j=["img","br"],k=function(c){var d=i(c);return d||a.contains(j,b.name(c))};return{getEnd:e,isEnd:f,isStart:g,isCursorPosition:k}}),g("a5",["6k","6"],function(a,b){var c=a.generate([{before:["element"]},{on:["element","offset"]},{after:["element"]}]),d=function(a,b,c,d){return a.fold(b,c,d)},e=function(a){return a.fold(b.identity,b.identity,b.identity)};return{before:c.before,on:c.on,after:c.after,cata:d,getStart:e}}),g("9i",["6k","2o","a","10","a5"],function(a,b,c,d,e){var f=a.generate([{domRange:["rng"]},{relative:["startSitu","finishSitu"]},{exact:["start","soffset","finish","foffset"]}]),g=b.immutable("start","soffset","finish","foffset"),h=function(a){return f.exact(a.start(),a.soffset(),a.finish(),a.foffset())},i=function(a){return a.match({domRange:function(a){return c.fromDom(a.startContainer)},relative:function(a,b){return e.getStart(a)},exact:function(a,b,c,d){return a}})},j=function(a){var b=i(a);return d.defaultView(b)};return{domRange:f.domRange,relative:f.relative,exact:f.exact,exactFromRange:h,range:g,getWin:j}}),g("9j",["1a","a","10"],function(a,b,c){var d=function(a,b,d,e){var f=c.owner(a),g=f.dom().createRange();return g.setStart(a.dom(),b),g.setEnd(d.dom(),e),g},e=function(a,c,e,f){var g=d(a,c,e,f);return b.fromDom(g.commonAncestorContainer)},f=function(b,c,e,f){var g=d(b,c,e,f),h=a.eq(b,e)&&c===f;return g.collapsed&&!h};return{after:f,commonAncestorContainer:e}}),g("9k",["y","a","1b"],function(a,b,c){var d=function(d,e){var f=e||c,g=f.createDocumentFragment();return a.each(d,function(a){g.appendChild(a.dom())}),b.fromDom(g)};return{fromElements:d}}),g("9l",["6","z","1a","a"],function(a,b,c,d){var e=function(a,b){var c=a.document.createRange();return f(c,b),c},f=function(a,b){a.selectNodeContents(b.dom())},g=function(a,b){return b.compareBoundaryPoints(a.END_TO_START,a)<1&&b.compareBoundaryPoints(a.START_TO_END,a)>-1},h=function(a){return a.document.createRange()},i=function(a,b){b.fold(function(b){a.setStartBefore(b.dom())},function(b,c){a.setStart(b.dom(),c)},function(b){a.setStartAfter(b.dom())})},j=function(a,b){b.fold(function(b){a.setEndBefore(b.dom())},function(b,c){a.setEnd(b.dom(),c)},function(b){a.setEndAfter(b.dom())})},k=function(a,b){o(a),a.insertNode(b.dom())},l=function(a,b,d,e){return c.eq(a,d)&&b===e},m=function(a,b,c){var d=a.document.createRange();return i(d,b),j(d,c),d},n=function(a,b,c,d,e){var f=a.document.createRange();return f.setStart(b.dom(),c),f.setEnd(d.dom(),e),f},o=function(a){a.deleteContents()},p=function(a){var b=a.cloneContents();return d.fromDom(b)},q=function(b){return{left:a.constant(b.left),top:a.constant(b.top),right:a.constant(b.right),bottom:a.constant(b.bottom),width:a.constant(b.width),height:a.constant(b.height)}},r=function(a){var c=a.getClientRects(),d=c.length>0?c[0]:a.getBoundingClientRect();return d.width>0||d.height>0?b.some(d).map(q):b.none()},s=function(a){var c=a.getBoundingClientRect();return c.width>0||c.height>0?b.some(c).map(q):b.none()},t=function(a){return a.toString()};return{create:h,replaceWith:k,selectNodeContents:e,selectNodeContentsUsing:f,isCollapsed:l,relativeToNative:m,exactToNative:n,deleteContents:o,cloneFragment:p,getFirstRect:r,getBounds:s,isWithin:g,toString:t}}),g("9m",["6k","6","z","17","a","9l"],function(a,b,c,d,e,f){var g=a.generate([{ltr:["start","soffset","finish","foffset"]},{rtl:["start","soffset","finish","foffset"]}]),h=function(a,b,c){return b(e.fromDom(c.startContainer),c.startOffset,e.fromDom(c.endContainer),c.endOffset)},i=function(a,e){return e.match({domRange:function(a){return{ltr:b.constant(a),rtl:c.none}},relative:function(b,e){return{ltr:d.cached(function(){return f.relativeToNative(a,b,e)}),rtl:d.cached(function(){return c.some(f.relativeToNative(a,e,b))})}},exact:function(b,e,g,h){return{ltr:d.cached(function(){return f.exactToNative(a,b,e,g,h)}),rtl:d.cached(function(){return c.some(f.exactToNative(a,g,h,b,e))})}}})},j=function(a,b){var c=b.ltr();if(c.collapsed){var d=b.rtl().filter(function(a){return a.collapsed===!1});return d.map(function(a){return g.rtl(e.fromDom(a.endContainer),a.endOffset,e.fromDom(a.startContainer),a.startOffset)}).getOrThunk(function(){return h(a,g.ltr,c)})}return h(a,g.ltr,c)},k=function(a,b){var c=i(a,b);return j(a,c)},l=function(a,b){var c=k(a,b);return c.match({ltr:function(b,c,d,e){var f=a.document.createRange();return f.setStart(b.dom(),c),f.setEnd(d.dom(),e),f},rtl:function(b,c,d,e){var f=a.document.createRange();return f.setStart(d.dom(),e),f.setEnd(b.dom(),c),f}})};return{ltr:g.ltr,rtl:g.rtl,diagnose:k,asLtrRange:l}}),g("ac",["1w"],function(a){var b=function(b,c,d,e,f){if(0===f)return 0;if(c===e)return f-1;for(var g=e,h=1;hi.bottom);else{if(dg)return h-1;g=j}}return 0},c=function(a,b,c){return b>=a.left&&b<=a.right&&c>=a.top&&c<=a.bottom};return{inRect:c,searchForPoint:b}}),g("ad",["z","15","a4","ac","1w"],function(a,b,c,d,e){var f=function(a,b,e,f,g){var h=function(c){var d=a.dom().createRange();return d.setStart(b.dom(),c),d.collapse(!0),d},i=function(a){var b=h(a);return b.getBoundingClientRect()},j=c.get(b).length,k=d.searchForPoint(i,e,f,g.right,j);return h(k)},g=function(c,e,g,h){var i=c.dom().createRange();i.selectNode(e.dom());var j=i.getClientRects(),k=b.findMap(j,function(b){return d.inRect(b,g,h)?a.some(b):a.none()});return k.map(function(a){return f(c,e,g,h,a)})};return{locate:g}}),g("a6",["z","15","b","10","ac","ad","1w"],function(a,b,c,d,e,f,g){var h=function(c,f,g,h){var j=c.dom().createRange(),k=d.children(f);return b.findMap(k,function(b){return j.selectNode(b.dom()),e.inRect(j.getBoundingClientRect(),g,h)?i(c,b,g,h):a.none()})},i=function(a,b,d,e){var g=c.isText(b)?f.locate:h;return g(a,b,d,e)},j=function(a,b,c,d){var e=a.dom().createRange();e.selectNode(b.dom());var f=e.getBoundingClientRect(),h=g.max(f.left,g.min(f.right,c)),j=g.max(f.top,g.min(f.bottom,d));return i(a,b,h,j)};return{locate:j}}),g("ae",["z","2u","10","9h"],function(a,b,c,d){var e=function(a){return b.descendant(a,d.isCursorPosition)},f=function(a){return g(a,d.isCursorPosition)},g=function(b,d){var e=function(b){for(var f=c.children(b),g=f.length-1;g>=0;g--){var h=f[g];if(d(h))return a.some(h);var i=e(h);if(i.isSome())return i}return a.none()};return e(b)};return{first:e,last:f}}),g("a7",["z","10","ae"],function(a,b,c){var d=!0,e=!1,f=function(a,b){return b-a.left0){var d=b.getRangeAt(0),e=b.getRangeAt(b.rangeCount-1);return a.some(f.range(c.fromDom(d.startContainer),d.startOffset,c.fromDom(e.endContainer),e.endOffset))}return a.none()},t=function(d){var e=c.fromDom(d.anchorNode),g=c.fromDom(d.focusNode);return b.after(e,d.anchorOffset,g,d.focusOffset)?a.some(f.range(c.fromDom(d.anchorNode),d.anchorOffset,c.fromDom(d.focusNode),d.focusOffset)):s(d)},u=function(a,b){var c=g.selectNodeContents(a,b);l(a,c)},v=function(a,b){var d=g.selectNodeContents(a,b);return f.range(c.fromDom(d.startContainer),d.startOffset,c.fromDom(d.endContainer),d.endOffset)},w=function(b){var c=b.getSelection();return c.rangeCount>0?t(c):a.none()},x=function(a){return w(a).map(function(a){return f.exact(a.start(),a.soffset(),a.finish(),a.foffset())})},y=function(a,b){var c=h.asLtrRange(a,b);return g.getFirstRect(c)},z=function(a,b){var c=h.asLtrRange(a,b);return g.getBounds(c)},A=function(a,b,c){return i.fromPoint(a,b,c)},B=function(a,b){var c=h.asLtrRange(a,b);return g.toString(c)},C=function(a){var b=a.getSelection();b.removeAllRanges()},D=function(a,b){var c=h.asLtrRange(a,b);return g.cloneFragment(c)},E=function(a,b,c){var e=h.asLtrRange(a,b),f=d.fromElements(c,a.document);g.replaceWith(e,f)},F=function(a,b){var c=h.asLtrRange(a,b);g.deleteContents(c)};return{setExact:p,getExact:w,get:x,setRelative:q,toNative:r,setToElement:u,clear:C,clone:D,replace:E,deleteAt:F,forElement:v,getFirstRect:y,getBounds:z,getAtPoint:A,findWithin:n,getAsString:B}}),g("85",["y","6","a","10","9h","9i","86"],function(a,b,c,d,e,f,g){var h=2,i=function(a){return{left:a.left,top:a.top,right:a.right,bottom:a.bottom,width:b.constant(h),height:a.height}},j=function(a){return{left:b.constant(a.left),top:b.constant(a.top),right:b.constant(a.right),bottom:b.constant(a.bottom),width:b.constant(a.width),height:b.constant(a.height)}},k=function(b){if(b.collapsed){var h=c.fromDom(b.startContainer);return d.parent(h).bind(function(c){var d=f.exact(h,b.startOffset,c,e.getEnd(c)),j=g.getFirstRect(b.startContainer.ownerDocument.defaultView,d);return j.map(i).map(a.pure)}).getOr([])}return a.map(b.getClientRects(),j)},l=function(a){var b=a.getSelection();return void 0!==b&&b.rangeCount>0?k(b.getRangeAt(0)):[]};return{getRectangles:l}}),g("5y",["6","z","1u","a","4i","1w","83","i","84","85"],function(a,b,c,d,e,f,g,h,i,j){var k=50,l="data-"+h.resolve("last-outer-height"),m=function(a,b){e.set(a,l,b)},n=function(a){return i.safeParse(a,l)},o=function(b){return{top:a.constant(b.top()),bottom:a.constant(b.top()+b.height())}},p=function(a){var c=j.getRectangles(a);return c.length>0?b.some(c[0]).map(o):b.none()},q=function(a,c){var d=n(c),e=a.innerHeight;return d>e?b.some(d-e):b.none()},r=function(a,b,c){var d=b.top()>a.innerHeight||b.bottom()>a.innerHeight;return d?f.min(c,b.bottom()-a.innerHeight+k):0},s=function(a,b){var e=d.fromDom(b.document.body),f=function(){g.resume(b)},h=c.bind(d.fromDom(a),"resize",function(){q(a,e).each(function(a){p(b).each(function(c){var d=r(b,c,a);0!==d&&b.scrollTo(b.pageXOffset,b.pageYOffset+d)})}),m(e,a.innerHeight)});m(e,a.innerHeight);var i=function(){h.unbind()};return{toEditing:f,destroy:i}};return{setup:s}}),g("5z",["6","z","1a","1u","a","86"],function(a,b,c,d,e,f){var g=function(a){return b.some(e.fromDom(a.dom().contentWindow.document.body))},h=function(a){return b.some(e.fromDom(a.dom().contentWindow.document))},i=function(a){return b.from(a.dom().contentWindow)},j=function(a){var b=i(a);return b.bind(f.getExact)},k=function(a){return a.getFrame()},l=function(a,b){return function(c){var d=c[a].getOrThunk(function(){var a=k(c);return function(){return b(a)}});return d()}},m=function(a,b,c,e){return a[c].getOrThunk(function(){return function(a){return d.bind(b,e,a)}})},n=function(b){return{left:a.constant(b.left),top:a.constant(b.top),right:a.constant(b.right),bottom:a.constant(b.bottom),width:a.constant(b.width),height:a.constant(b.height)}},o=function(d){var l=k(d),o=function(a){var d=function(a){return c.eq(a.start(),a.finish())&&a.soffset()===a.foffset()},e=function(a){var c=a.start().dom().getBoundingClientRect();return c.width>0||c.height>0?b.some(c).map(n):b.none()};return f.getExact(a).filter(d).bind(e)};return g(l).bind(function(b){return h(l).bind(function(c){return i(l).map(function(g){var h=e.fromDom(c.dom().documentElement),i=d.getCursorBox.getOrThunk(function(){return function(){return f.get(g).bind(function(a){return f.getFirstRect(g,a).orThunk(function(){return o(g)})})}}),k=d.setSelection.getOrThunk(function(){return function(a,b,c,d){f.setExact(g,a,b,c,d)}}),n=d.clearSelection.getOrThunk(function(){return function(){f.clear(g)}});return{body:a.constant(b),doc:a.constant(c),win:a.constant(g),html:a.constant(h),getSelection:a.curry(j,l),setSelection:k,clearSelection:n,frame:a.constant(l),onKeyup:m(d,c,"onKeyup","keyup"),onNodeChanged:m(d,c,"onNodeChanged","selectionchange"),onDomChanged:d.onDomChanged,onScrollToCursor:d.onScrollToCursor,onScrollToElement:d.onScrollToElement,onToReading:d.onToReading,onToEditing:d.onToEditing,onToolbarScrollStart:d.onToolbarScrollStart,onTouchContent:d.onTouchContent,onTapContent:d.onTapContent,onTouchToolstrip:d.onTouchToolstrip,getCursorBox:i}})})})};return{getBody:l("getBody",g),getDoc:l("getDoc",h),getWin:l("getWin",i),getSelection:l("getSelection",j),getFrame:k,getActiveApi:o}}),g("60",["y","7","4i","39","5l"],function(a,b,c,d,e){var f="data-ephox-mobile-fullscreen-style",g="display:none!important;",h="position:absolute!important;",i="top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;",j="background-color:rgb(255,255,255)!important;",k=b.detect().os.isAndroid(),l=function(a){var b=d.get(a,"background-color");return void 0!==b&&""!==b?"background-color:"+b+"!important":j},m=function(b,d){var j=function(a){var b=e.siblings(a,"*");return b},m=function(a){return function(b){var d=c.get(b,"style"),e=void 0===d?"no-styles":d.trim();e!==a&&(c.set(b,f,e),c.set(b,"style",a))}},n=e.ancestors(b,"*"),o=a.bind(n,j),p=l(d);a.each(o,m(g)),a.each(n,m(h+i+p));var q=k===!0?"":h;m(q+i+p)(b)},n=function(){var b=e.all("["+f+"]");a.each(b,function(a){var b=c.get(a,f);"no-styles"!==b?c.set(a,"style",b):c.remove(a,"style"),c.remove(a,f)})};return{clobberStyles:m,restoreStyles:n}}),g("61",["9","a","4i","4u"],function(a,b,c,d){var e=function(){var e=d.first("head").getOrDie(),f=function(){var d=b.fromTag("meta");return c.set(d,"name","viewport"),a.append(e,d),d},g=d.first('meta[name="viewport"]').getOrThunk(f),h=c.get(g,"content"),i=function(){c.set(g,"content","width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0")},j=function(){void 0!==h&&null!==h&&h.length>0?c.set(g,"content",h):c.set(g,"content","user-scalable=yes")};return{maximize:i,restore:j}};return{tag:e}}),g("3r",["1z","2f","5x","5y","5z","60","i","61"],function(a,b,c,d,e,f,g,h){var i=function(i,j){var k=h.tag(),l=a.api(),m=a.api(),n=function(){j.hide(),b.add(i.container,g.resolve("fullscreen-maximized")),b.add(i.container,g.resolve("android-maximized")),k.maximize(),b.add(i.body,g.resolve("android-scroll-reload")),l.set(d.setup(i.win,e.getWin(i.editor).getOrDie("no"))),e.getActiveApi(i.editor).each(function(a){f.clobberStyles(i.container,a.body()),m.set(c.initEvents(a,i.toolstrip,i.alloy))})},o=function(){k.restore(),j.show(),b.remove(i.container,g.resolve("fullscreen-maximized")),b.remove(i.container,g.resolve("android-maximized")),f.restoreStyles(),b.remove(i.body,g.resolve("android-scroll-reload")),m.clear(),l.clear()};return{enter:n,exit:o}};return{create:i}}),g("3s",["29","2e","6","a","10","1k"],function(a,b,c,d,e,f){return b.objOf([a.strictObjOf("editor",[a.strict("getFrame"),a.option("getBody"),a.option("getDoc"),a.option("getWin"),a.option("getSelection"),a.option("setSelection"),a.option("clearSelection"),a.option("cursorSaver"),a.option("onKeyup"),a.option("onNodeChanged"),a.option("getCursorBox"),a.strict("onDomChanged"),a.defaulted("onTouchContent",c.noop),a.defaulted("onTapContent",c.noop),a.defaulted("onTouchToolstrip",c.noop),a.defaulted("onScrollToCursor",c.constant({unbind:c.noop})),a.defaulted("onScrollToElement",c.constant({unbind:c.noop})),a.defaulted("onToEditing",c.constant({unbind:c.noop})),a.defaulted("onToReading",c.constant({unbind:c.noop})),a.defaulted("onToolbarScrollStart",c.identity)]),a.strict("socket"),a.strict("toolstrip"),a.strict("dropup"),a.strict("toolbar"),a.strict("container"),a.strict("alloy"),a.state("win",function(a){return e.owner(a.socket).dom().defaultView}),a.state("body",function(a){return d.fromDom(a.socket.dom().ownerDocument.body)}),a.defaulted("translate",c.identity),a.defaulted("setReadOnly",c.noop)])}),g("62",["87","1j"],function(a,b){var c=function(c,d){var e=null,f=null,g=function(){null!==e&&(a(e),e=null,f=null)},h=function(){f=arguments,null===e&&(e=b(function(){c.apply(null,f),e=null,f=null},d))};return{cancel:g,throttle:h}},d=function(c,d){var e=null,f=function(){null!==e&&(a(e),e=null)},g=function(){var a=arguments;null===e&&(e=b(function(){c.apply(null,a),e=null,a=null},d))};return{cancel:f,throttle:g}},e=function(c,d){var e=null,f=function(){null!==e&&(a(e),e=null)},g=function(){var f=arguments;null!==e&&a(e),e=b(function(){c.apply(null,f),e=null,f=null},d)};return{cancel:f,throttle:g}};return{adaptable:c,first:d,last:e}}),g("3t",["q","1g","1h","1n","3v","62","1j","i","1o"],function(a,b,c,d,e,f,g,h,i){var j=function(g,j){var k=c.record(e.sketch({dom:i.dom(''),containerBehaviours:a.derive([b.config({toggleClass:h.resolve("mask-tap-icon-selected"),toggleOnExecute:!1})])})),l=f.first(g,200);return e.sketch({dom:i.dom('
    '),components:[e.sketch({ +dom:i.dom('
    '),components:[d.sketch({dom:i.dom('
    '),components:[k.asSpec()],action:function(a){l.throttle()},buttonBehaviours:a.derive([b.config({toggleClass:h.resolve("mask-tap-icon-selected")})])})]})]})};return{sketch:j}}),g("20",["3q","2e","6","9","39","3r","3s","3t"],function(a,b,c,d,e,f,g,h){var i=function(i){var j=b.asRawOrDie("Getting AndroidWebapp schema",g,i);e.set(j.toolstrip,"width","100%");var k=function(){j.setReadOnly(!0),n.enter()},l=a.build(h.sketch(k,j.translate));j.alloy.add(l);var m={show:function(){j.alloy.add(l)},hide:function(){j.alloy.remove(l)}};d.append(j.container,l.element());var n=f.create(j,m);return{setReadOnly:j.setReadOnly,refreshStructure:c.noop,enter:n.enter,exit:n.exit,destroy:c.noop}};return{produce:i}}),g("63",["q","1y","4q","53","29","6"],function(a,b,c,d,e,f){var g=[e.defaulted("shell",!0),e.defaulted("toolbarBehaviours",{})],h=function(c){return{behaviours:a.derive([b.config({})])}},i=[d.optional({name:"groups",overrides:h})];return{name:f.constant("Toolbar"),schema:f.constant(g),parts:f.constant(i)}}),g("3w",["q","1y","34","52","63","w","z","16","v"],function(a,b,c,d,e,f,g,h,i){var j=function(c,e,j,k){var l=function(a,c){m(a).fold(function(){throw h.error("Toolbar was defined to not be a shell, but no groups container was specified in components"),new i("Toolbar was defined to not be a shell, but no groups container was specified in components")},function(a){b.set(a,c)})},m=function(a){return c.shell()?g.some(a):d.getPart(a,c,"groups")},n=c.shell()?{behaviours:[b.config({})],components:[]}:{behaviours:[],components:e};return{uid:c.uid(),dom:c.dom(),components:n.components,behaviours:f.deepMerge(a.derive(n.behaviours),c.toolbarBehaviours()),apis:{setGroups:l},domModification:{attributes:{role:"group"}}}};return c.composite({name:"Toolbar",configFields:e.schema(),partFields:e.parts(),factory:j,apis:{setGroups:function(a,b,c){a.setGroups(b,c)}}})}),g("65",["4q","53","29","6"],function(a,b,c,d){var e=[c.strict("items"),a.markers(["itemClass"]),c.defaulted("hasTabstop",!0),c.defaulted("tgroupBehaviours",{})],f=[b.group({name:"items",unit:"item",overrides:function(a){return{domModification:{classes:[a.markers().itemClass()]}}}})];return{name:d.constant("ToolbarGroup"),schema:d.constant(e),parts:d.constant(f)}}),g("3x",["q","33","64","34","65","w","v"],function(a,b,c,d,e,f,g){var h=function(d,e,g,h){return f.deepMerge({dom:{attributes:{role:"toolbar"}}},{uid:d.uid(),dom:d.dom(),components:e,behaviours:f.deepMerge(a.derive([b.config({mode:"flow",selector:"."+d.markers().itemClass()}),d.hasTabstop()?c.config({}):c.revoke()]),d.tgroupBehaviours()),"debug.sketcher":g["debug.sketcher"]})};return d.composite({name:"ToolbarGroup",configFields:e.schema(),partFields:e.parts(),factory:h})}),g("3y",["6","1u","4i","4u","i"],function(a,b,c,d,e){var f="data-"+e.resolve("horizontal-scroll"),g=function(a){a.dom().scrollTop=1;var b=0!==a.dom().scrollTop;return a.dom().scrollTop=0,b},h=function(a){a.dom().scrollLeft=1;var b=0!==a.dom().scrollLeft;return a.dom().scrollLeft=0,b},i=function(a){return a.dom().scrollTop>0||g(a)},j=function(a){return a.dom().scrollLeft>0||h(a)},k=function(a){c.set(a,f,"true")},l=function(a){return"true"===c.get(a,f)?j:i},m=function(c,e){return b.bind(c,"touchmove",function(b){d.closest(b.target(),e).filter(l).fold(function(){b.raw().preventDefault()},a.noop)})};return{exclusive:m,markAsHorizontal:k}}),g("21",["3u","q","33","1g","3q","3d","3v","3w","3x","y","5","6","39","3y","i","3z","1o"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){return function(){var r=function(c){var d=c.scrollable===!0?"${prefix}-toolbar-scrollable-group":"";return{dom:q.dom('
    '),tgroupBehaviours:b.derive([a.config("adhoc-scrollable-toolbar",c.scrollable===!0?[f.runOnInit(function(a,b){m.set(a.element(),"overflow-x","auto"),n.markAsHorizontal(a.element()),p.register(a.element())})]:[])]),components:[g.sketch({components:[i.parts().items({})]})],markers:{itemClass:o.resolve("toolbar-group-item")},items:c.items}},s=e.build(h.sketch({dom:q.dom('
    '),components:[h.parts().groups({})],toolbarBehaviours:b.derive([d.config({toggleClass:o.resolve("context-toolbar"),toggleOnExecute:!1,aria:{mode:"none"}}),c.config({mode:"cyclic"})]),shell:!0})),t=e.build(g.sketch({dom:{classes:[o.resolve("toolstrip")]},components:[e.premade(s)],containerBehaviours:b.derive([d.config({toggleClass:o.resolve("android-selection-context-toolbar"),toggleOnExecute:!1})])})),u=function(){h.setGroups(s,v.get()),d.off(s)},v=k([]),w=function(a){v.set(a),u()},x=function(a){return j.map(a,l.compose(i.sketch,r))},y=function(){h.refresh(s)},z=function(a){d.on(s),h.setGroups(s,a)},A=function(){d.isOn(s)&&u()},B=function(){c.focusIn(s)};return{wrapper:l.constant(t),toolbar:l.constant(s),createGroups:x,setGroups:w,setContextToolbar:z,restoreToolbar:A,refresh:y,focus:B}}}),g("22",["q","1y","1","3q","1n","3v","6","2f","i","1o"],function(a,b,c,d,e,f,g,h,i,j){var k=function(a){return d.build(e.sketch({dom:j.dom('
    '),action:function(){a.run(function(a){a.setReadOnly(!1)})}}))},l=function(){return d.build(f.sketch({dom:j.dom('
    '),components:[],containerBehaviours:a.derive([b.config({})])}))},m=function(a,c){b.append(a,d.premade(c))},n=function(a,c){b.remove(a,c)},o=function(a,b,d,e){var f=d===!0?c.toAlpha:c.toOmega;f(e);var g=d?m:n;g(a,b)};return{makeEditSwitch:k,makeSocket:l,updateMode:o}}),g("67",["2f","8a","39"],function(a,b,c){var d=function(a,b){return b.getAnimationRoot().fold(function(){return a.element()},function(b){return b(a)})},e=function(a){return a.dimension().property()},f=function(a,b){return a.dimension().getDimension()(b)},g=function(a,c){var e=d(a,c);b.remove(e,[c.shrinkingClass(),c.growingClass()])},h=function(b,d){a.remove(b.element(),d.openClass()),a.add(b.element(),d.closedClass()),c.set(b.element(),e(d),"0px"),c.reflow(b.element())},i=function(a,b){j(a,b);var c=f(b,a.element());return h(a,b),c},j=function(b,d){a.remove(b.element(),d.closedClass()),a.add(b.element(),d.openClass()),c.remove(b.element(),e(d))},k=function(a,b,d){d.setCollapsed(),c.set(a.element(),e(b),f(b,a.element())),c.reflow(a.element()),g(a,b),h(a,b),b.onStartShrink()(a),b.onShrunk()(a)},l=function(b,g,i){i.setCollapsed(),c.set(b.element(),e(g),f(g,b.element())),c.reflow(b.element());var j=d(b,g);a.add(j,g.shrinkingClass()),h(b,g),g.onStartShrink()(b)},m=function(b,f,g){var h=i(b,f),k=d(b,f);a.add(k,f.growingClass()),j(b,f),c.set(b.element(),e(f),h),g.setExpanded(),f.onStartGrow()(b)},n=function(a,b,c){c.isExpanded()||m(a,b,c)},o=function(a,b,c){c.isExpanded()&&l(a,b,c)},p=function(a,b,c){c.isExpanded()&&k(a,b,c)},q=function(a,b,c){return c.isExpanded()},r=function(a,b,c){return c.isCollapsed()},s=function(b,c,e){var f=d(b,c);return a.has(f,c.growingClass())===!0},t=function(b,c,e){var f=d(b,c);return a.has(f,c.shrinkingClass())===!0},u=function(a,b,c){return s(a,b,c)===!0||t(a,b,c)===!0},v=function(a,b,c){var d=c.isExpanded()?l:m;d(a,b,c)};return{grow:n,shrink:o,immediateShrink:p,hasGrown:q,hasShrunk:r,isGrowing:s,isShrinking:t,isTransitioning:u,toggleGrow:v,disableTransitions:g}}),g("66",["3d","2g","67","4b","14","39"],function(a,b,c,d,e,f){var g=function(a,b){var c=b.expanded();return c?d.nu({classes:[b.openClass()],styles:{}}):d.nu({classes:[b.closedClass()],styles:e.wrap(b.dimension().property(),"0px")})},h=function(d,e){return a.derive([a.run(b.transitionend(),function(a,b){var g=b.event().raw();if(g.propertyName===d.dimension().property()){c.disableTransitions(a,d,e),e.isExpanded()&&f.remove(a.element(),d.dimension().property());var h=e.isExpanded()?d.onGrown():d.onShrunk();h(a,b)}})])};return{exhibit:g,events:h}}),g("68",["4q","29","2e","8b","5m"],function(a,b,c,d,e){return[b.strict("closedClass"),b.strict("openClass"),b.strict("shrinkingClass"),b.strict("growingClass"),b.option("getAnimationRoot"),a.onHandler("onShrunk"),a.onHandler("onStartShrink"),a.onHandler("onGrown"),a.onHandler("onStartGrow"),b.defaulted("expanded",!1),b.strictOf("dimension",c.choose("property",{width:[a.output("property","width"),a.output("getDimension",function(a){return e.get(a)+"px"})],height:[a.output("property","height"),a.output("getDimension",function(a){return d.get(a)+"px"})]}))]}),g("69",["4g","5","6"],function(a,b,c){var d=function(d){var e=b(d.expanded()),f=function(){return"expanded: "+e.get()};return a({isExpanded:function(){return e.get()===!0},isCollapsed:function(){return e.get()===!1},setCollapsed:c.curry(e.set,!1),setExpanded:c.curry(e.set,!0),readState:f})};return{init:d}}),g("40",["q","66","67","68","69"],function(a,b,c,d,e){return a.create({fields:d,name:"sliding",active:b,apis:c,state:e})}),g("23",["q","1y","40","3q","3v","6","1k","1l","i"],function(a,b,c,d,e,f,g,h,i){var j=function(j,k){var l=d.build(e.sketch({dom:{tag:"div",classes:i.resolve("dropup")},components:[],containerBehaviours:a.derive([b.config({}),c.config({closedClass:i.resolve("dropup-closed"),openClass:i.resolve("dropup-open"),shrinkingClass:i.resolve("dropup-shrinking"),growingClass:i.resolve("dropup-growing"),dimension:{property:"height"},onShrunk:function(a){j(),k(),b.set(a,[])},onGrown:function(a){j(),k()}}),h.orientation(function(a,b){n(f.noop)})])})),m=function(a,d,e){c.hasShrunk(l)===!0&&c.isTransitioning(l)===!1&&g.requestAnimationFrame(function(){d(e),b.set(l,[a()]),c.grow(l)})},n=function(a){g.requestAnimationFrame(function(){a(),c.shrink(l)})};return{appear:m,disappear:n,component:f.constant(l),element:l.element}};return{build:j}}),g("6c",["8c","t","8d","29","2e","y","7","1u","b","10","1j"],function(a,b,c,d,e,f,g,h,i,j,k){var l=function(b){return b.raw().which===a.BACKSPACE()[0]&&!f.contains(["input","textarea"],i.name(b.target()))},m=g.detect().browser.isFirefox(),n=e.objOfOnly([d.strictFunction("triggerEvent"),d.strictFunction("broadcastEvent"),d.defaulted("stopBackspace",!0)]),o=function(a,b){return m?h.capture(a,"focus",b):h.bind(a,"focusin",b)},p=function(a,b){return m?h.capture(a,"blur",b):h.bind(a,"focusout",b)},q=function(a,d){var i=e.asRawOrDie("Getting GUI events settings",n,d),m=g.detect().deviceType.isTouch()?["touchstart","touchmove","touchend","gesturestart"]:["mousedown","mouseup","mouseover","mousemove","mouseout","click"],q=c.monitor(i),r=f.map(m.concat(["selectstart","input","contextmenu","change","transitionend","dragstart","dragover","drop"]),function(b){return h.bind(a,b,function(a){q.fireIfReady(a,b).each(function(b){b&&a.kill()});var c=i.triggerEvent(b,a);c&&a.kill()})}),s=h.bind(a,"keydown",function(a){var b=i.triggerEvent("keydown",a);b?a.kill():i.stopBackspace===!0&&l(a)&&a.prevent()}),t=o(a,function(a){var b=i.triggerEvent("focusin",a);b&&a.kill()}),u=p(a,function(a){var c=i.triggerEvent("focusout",a);c&&a.kill(),k(function(){i.triggerEvent(b.postBlur(),a)},0)}),v=j.defaultView(a),w=h.bind(v,"scroll",function(a){var c=i.broadcastEvent(b.windowScroll(),a);c&&a.kill()}),x=function(){f.each(r,function(a){a.unbind()}),s.unbind(),t.unbind(),u.unbind(),w.unbind()};return{unbind:x}};return{setup:q}}),g("8e",["14","5"],function(a,b){var c=function(c,d){var e=a.readOptFrom(c,"target").map(function(a){return a()}).getOr(d);return b(e)};return{derive:c}}),g("8f",["5","6","v"],function(a,b,c){var d=function(c,d){var e=a(!1),f=a(!1),g=function(){e.set(!0)},h=function(){f.set(!0)};return{stop:g,cut:h,isStopped:e.get,isCut:f.get,event:b.constant(c),setSource:d.set,getSource:d.get}},e=function(d){var e=a(!1),f=function(){e.set(!0)};return{stop:f,cut:b.noop,isStopped:e.get,isCut:b.constant(!1),event:b.constant(d),setTarget:b.die(new c("Cannot set target of a broadcasted event")),getTarget:b.die(new c("Cannot get target of a broadcasted event"))}},f=function(b,c){var e=a(c);return d(b,e)};return{fromSource:d,fromExternal:e,fromTarget:f}}),g("6d",["6b","8e","8f","6k","y","10","v"],function(a,b,c,d,e,f,g){var h=d.generate([{stopped:[]},{resume:["element"]},{complete:[]}]),i=function(b,d,e,g,i,j){var k=b(d,g),l=c.fromSource(e,i);return k.fold(function(){return j.logEventNoHandlers(d,g),h.complete()},function(b){var c=b.descHandler(),e=a.getHandler(c);return e(l),l.isStopped()?(j.logEventStopped(d,b.element(),c.purpose()),h.stopped()):l.isCut()?(j.logEventCut(d,b.element(),c.purpose()),h.complete()):f.parent(b.element()).fold(function(){return j.logNoParent(d,b.element(),c.purpose()),h.complete()},function(a){return j.logEventResponse(d,b.element(),c.purpose()),h.resume(a)})})},j=function(a,b,c,d,e,f){return i(a,b,c,d,e,f).fold(function(){return!0},function(d){return j(a,b,c,d,e,f)},function(){return!1})},k=function(a,c,d,e,f){var g=b.derive(d,e);return i(a,c,d,e,g,f)},l=function(b,d,f){var g=c.fromExternal(d);return e.each(b,function(b){var c=b.descHandler(),d=a.getHandler(c);d(g)}),g.isStopped()},m=function(a,b,c,d){var e=c.target();return n(a,b,c,e,d)},n=function(a,c,d,e,f){var g=b.derive(d,e);return j(a,c,d,e,g,f)};return{triggerHandler:k,triggerUntilStopped:m,triggerOnUntilStopped:n,broadcast:l}}),g("9q",["2u"],function(a){var b=function(b,c,d){var e=a.closest(b,function(a){return c(a).isSome()},d);return e.bind(c)};return{closest:b}}),g("8g",["9q","6b","30","14","6","x","z","2o","16"],function(a,b,c,d,e,f,g,h,i){var j=h.immutable("element","descHandler"),k=function(a,b){return{id:e.constant(a),descHandler:e.constant(b)}};return function(){var e={},h=function(a,c,d){f.each(d,function(d,f){var g=void 0!==e[f]?e[f]:{};g[c]=b.curryArgs(d,a),e[f]=g})},i=function(a,b){return c.read(b).fold(function(a){return g.none()},function(c){var e=d.readOpt(c);return a.bind(e).map(function(a){return j(b,a)})})},l=function(a){return d.readOptFrom(e,a).map(function(a){return f.mapToArray(a,function(a,b){return k(b,a)})}).getOr([])},m=function(b,c,f){var g=d.readOpt(c),h=g(e);return a.closest(f,function(a){return i(h,a)},b)},n=function(a){f.each(e,function(b,c){b.hasOwnProperty(a)&&delete b[a]})};return{registerId:h,unregisterId:n,filterByType:l,find:m}}}),g("6e",["8g","13","30","14","12","v"],function(a,b,c,d,e,f){return function(){var g=a(),h={},i=function(a){var b=a.element();return c.read(b).fold(function(){return c.write("uid-",a.element())},function(a){return a})},j=function(a,c){var d=h[c];if(d!==a)throw new f('The tagId "'+c+'" is already used by: '+b.element(d.element())+"\nCannot use it for: "+b.element(a.element())+"\nThe conflicting element is"+(e.inBody(d.element())?" ":" not ")+"already in the DOM");l(a)},k=function(a){var b=i(a);d.hasKey(h,b)&&j(a,b);var c=[a];g.registerId(c,b,a.events()),h[b]=a},l=function(a){c.read(a.element()).each(function(a){h[a]=void 0,g.unregisterId(a)})},m=function(a){return g.filterByType(a)},n=function(a,b,c){return g.find(a,b,c)},o=function(a){return d.readOpt(a)(h)};return{find:n,filter:m,register:k,unregister:l,getById:o}}}),g("41",["3q","t","3","6a","3v","4","6b","6c","6d","13","6e","30","y","6","48","1a","8","9","11","b","2f","10","v"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){var x=function(){var b=a.build(e.sketch({dom:{tag:"div"}}));return y(b)},y=function(e){var j=function(a){return v.parent(e.element()).fold(function(){return!0},function(b){return p.eq(a,b)})},r=k(),u=function(a,b){return r.find(j,a,b)},x=h.setup(e.element(),{triggerEvent:function(a,b){return f.monitorEvent(a,b.target(),function(c){return i.triggerUntilStopped(u,a,b,c)})},broadcastEvent:function(a,b){var c=r.filter(a);return i.broadcast(c,b)}}),y=d({debugInfo:n.constant("real"),triggerEvent:function(a,b,c){f.monitorEvent(a,b,function(d){i.triggerOnUntilStopped(u,a,c,b,d)})},triggerFocus:function(a,c){l.read(a).fold(function(){q.focus(a)},function(d){f.monitorEvent(b.focus(),a,function(d){i.triggerHandler(u,b.focus(),{originator:n.constant(c),target:n.constant(a)},a,d)})})},triggerEscape:function(a,b){y.triggerEvent("keydown",a.element(),b.event())},getByUid:function(a){return H(a)},getByDom:function(a){return I(a)},build:a.build,addToGui:function(a){B(a)},removeFromGui:function(a){C(a)},addToWorld:function(a){z(a)},removeFromWorld:function(a){A(a)},broadcast:function(a){F(a)},broadcastOn:function(a,b){G(a,b)}}),z=function(a){a.connect(y),t.isText(a.element())||(r.register(a),m.each(a.components(),z),y.triggerEvent(b.systemInit(),a.element(),{target:n.constant(a.element())}))},A=function(a){t.isText(a.element())||(m.each(a.components(),A),r.unregister(a)),a.disconnect()},B=function(a){c.attach(e,a)},C=function(a){c.detach(a)},D=function(){x.unbind(),s.remove(e.element())},E=function(a){var c=r.filter(b.receive());m.each(c,function(b){var c=b.descHandler(),d=g.getHandler(c);d(a)})},F=function(a){E({universal:n.constant(!0),data:n.constant(a)})},G=function(a,b){E({universal:n.constant(!1),channels:n.constant(a),data:n.constant(b)})},H=function(a){return r.getById(a).fold(function(){return o.error(new w('Could not find component with uid: "'+a+'" in system.'))},o.value)},I=function(a){return l.read(a).bind(H)};return z(e),{root:n.constant(e),element:e.element,destroy:D,add:B,remove:C,getByUid:H,getByDom:I,addToWorld:z,removeFromWorld:A,broadcast:F,broadcastOn:G}};return{create:x,takeover:y}}),g("24",["q","1","3q","41","3v","6","i"],function(a,b,c,d,e,f,g){var h=f.constant(g.resolve("readonly-mode")),i=f.constant(g.resolve("edit-mode"));return function(f){var j=c.build(e.sketch({dom:{classes:[g.resolve("outer-container")].concat(f.classes)},containerBehaviours:a.derive([b.config({alpha:h(),omega:i()})])}));return d.takeover(j)}}),g("k",["1y","1","6","1z","20","i","21","22","23","24"],function(a,b,c,d,e,f,g,h,i,j){return function(b){var k=j({classes:[f.resolve("android-container")]}),l=g(),m=d.api(),n=h.makeEditSwitch(m),o=h.makeSocket(),p=i.build(c.noop,b);k.add(l.wrapper()),k.add(o),k.add(p.component());var q=function(a){var b=l.createGroups(a);l.setGroups(b)},r=function(a){var b=l.createGroups(a);l.setContextToolbar(b)},s=function(){l.focus()},t=function(){l.restoreToolbar()},u=function(a){m.set(e.produce(a))},v=function(){m.run(function(b){b.exit(),a.remove(o,n)})},w=function(a){h.updateMode(o,n,a,k.root())};return{system:c.constant(k),element:k.element,init:u,exit:v,setToolbarGroups:q,setContextToolbar:r,focusToolbar:s,restoreToolbar:t,updateMode:w,socket:c.constant(o),dropup:c.constant(p)}}}),g("9r",["6"],function(a){var b=function(c,d){var e=function(a,e){return b(c+a,d+e)};return{left:a.constant(c),top:a.constant(d),translate:e}};return b}),g("9s",["6","1a","a","b","2u","1b"],function(a,b,c,d,e,f){var g=function(d,g){var h=g||c.fromDom(f.documentElement);return e.ancestor(d,a.curry(b.eq,h)).isSome()},h=function(a){var b=a.dom();return b===b.window?a:d.isDocument(a)?b.defaultView||b.parentWindow:null};return{attached:g,windowOf:h}}),g("8h",["9r","9s","a"],function(a,b,c){var d=function(b){var c=b.getBoundingClientRect();return a(c.left,c.top)},e=function(a,b){return void 0!==a?a:void 0!==b?b:0},f=function(a){var d=a.dom().ownerDocument,f=d.body,g=b.windowOf(c.fromDom(d)),i=d.documentElement,j=e(g.pageYOffset,i.scrollTop),k=e(g.pageXOffset,i.scrollLeft),l=e(i.clientTop,f.clientTop),m=e(i.clientLeft,f.clientLeft);return h(a).translate(k-m,j-l)},g=function(b){var c=b.dom();return a(c.offsetLeft,c.offsetTop)},h=function(e){var f=e.dom(),g=f.ownerDocument,h=g.body,i=c.fromDom(g.documentElement);return h===f?a(h.offsetLeft,h.offsetTop):b.attached(e,i)?d(f):a(0,0)};return{absolute:f,relative:g,viewport:h}}),g("6f",["8d","y","62","1a","1u","8b","8h","82"],function(a,b,c,d,e,f,g,h){var i=function(a,i,j,k,l){var m=function(){i.run(function(a){a.highlightSelection()})},n=function(){i.run(function(a){a.refreshSelection()})},o=function(a,b){var c=a-k.dom().scrollTop;i.run(function(a){a.scrollIntoView(c,c+b)})},p=function(a){var b=g.absolute(a).top(),c=f.get(a);o(i,k,b,c)},q=function(){a.getCursorBox().each(function(a){o(a.top(),a.height())})},r=function(){i.run(function(a){a.clearSelection()})},s=function(){r(),z.throttle()},t=function(){q(a,i,k),i.run(function(a){a.syncHeight()})},u=function(){var b=f.get(j);i.run(function(a){a.setViewportOffset(b)}),n(i),t(a,i,k)},v=function(){i.run(function(a){a.toEditing()})},w=function(){i.run(function(a){a.toReading()})},x=function(a){i.run(function(b){b.onToolbarTouch(a)})},y=h.monitor(a),z=c.last(t,300),A=[a.onKeyup(s),a.onNodeChanged(n),a.onDomChanged(z.throttle),a.onDomChanged(n),a.onScrollToCursor(function(a){a.preventDefault(),z.throttle()}),a.onScrollToElement(function(a){p(a.element())}),a.onToEditing(v),a.onToReading(w),e.bind(a.doc(),"touchend",function(b){d.eq(a.html(),b.target())||d.eq(a.body(),b.target())}),e.bind(j,"transitionend",function(a){"height"===a.raw().propertyName&&u()}),e.capture(j,"touchstart",function(b){m(),x(b),a.onTouchToolstrip()}),e.bind(a.body(),"touchstart",function(b){r(),a.onTouchContent(),y.fireTouchstart(b)}),y.onTouchmove(),y.onTouchend(),e.bind(a.body(),"click",function(a){a.kill()}),e.bind(j,"touchmove",function(){a.onToolbarScrollStart()})],B=function(){b.each(A,function(a){a.unbind()})};return{destroy:B}};return{initEvents:i}}),g("9t",["8","1j"],function(a,b){var c=function(c){var d=c.dom().selectionStart,e=c.dom().selectionEnd,f=c.dom().selectionDirection;b(function(){c.dom().setSelectionRange(d,e,f),a.focus(c)},50)},d=function(a){var b=a.getSelection();if(b.rangeCount>0){var c=b.getRangeAt(0),d=a.document.createRange();d.setStart(c.startContainer,c.startOffset),d.setEnd(c.endContainer,c.endOffset),b.removeAllRanges(),b.addRange(d)}};return{refreshInput:c,refresh:d}}),g("8q",["1a","8","a","9t"],function(a,b,c,d){var e=function(e,f){b.active().each(function(c){a.eq(c,f)||b.blur(c)}),e.focus(),b.focus(c.fromDom(e.document.body)),d.refresh(e)};return{resume:e}}),g("8j",["y","9","2s","11","1u","a","2f","8a","39","10","8q","i","85"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(n,o){var p=n.document,q=f.fromTag("div");g.add(q,l.resolve("unfocused-selections")),b.append(f.fromDom(p.documentElement),q);var r=e.bind(q,"touchstart",function(a){a.prevent(),k.resume(n,o),u()}),s=function(a){var b=f.fromTag("span");return h.add(b,[l.resolve("layer-editor"),l.resolve("unfocused-selection")]),i.setAll(b,{left:a.left()+"px",top:a.top()+"px",width:a.width()+"px",height:a.height()+"px"}),b},t=function(){u();var b=m.getRectangles(n),d=a.map(b,s);c.append(q,d)},u=function(){d.empty(q)},v=function(){r.unbind(),d.remove(q)},w=function(){return j.children(q).length>0};return{update:t,isActive:w,destroy:v,clear:u}}}),g("9x",["y","z","1j"],function(a,b,c){var d=function(e){var f=b.none(),g=[],h=function(a){return d(function(b){i(function(c){b(a(c))})})},i=function(a){k()?m(a):g.push(a)},j=function(a){f=b.some(a),l(g),g=[]},k=function(){return f.isSome()},l=function(b){a.each(b,m)},m=function(a){f.each(function(b){c(function(){a(b)},0)})};return e(j),{get:i,map:h,isReady:k}},e=function(a){return d(function(b){b(a)})};return{nu:d,pure:e}}),g("a8",["u","1j"],function(a,b){var c=function(c){return function(){var d=a.prototype.slice.call(arguments),e=this;b(function(){c.apply(e,d)},0)}};return{bounce:c}}),g("9u",["9x","a8"],function(a,b){var c=function(d){var e=function(a){d(b.bounce(a))},f=function(a){return c(function(b){e(function(c){var d=a(c);b(d)})})},g=function(a){return c(function(b){e(function(c){a(c).get(b)})})},h=function(a){return c(function(b){e(function(c){a.get(b)})})},i=function(){return a.nu(e)};return{map:f,bind:g,anonBind:h,toLazy:i,get:e}},d=function(a){return c(function(b){b(a)})};return{nu:c,pure:d}}),g("9v",["z","1v","1w","1x"],function(a,b,c,d){var e=function(b,d,e){return c.abs(b-d)<=e?a.none():bc.abs(d-g))&&(b(a),m(g))}})},k)};return{animate:f}};return{create:f,adjust:e}}),g("a9",["z","15"],function(a,b){var c=function(c,d){var e=[{width:320,height:480,keyboard:{portrait:300,landscape:240}},{width:320,height:568,keyboard:{portrait:300,landscape:240}},{width:375,height:667,keyboard:{portrait:305,landscape:240}},{width:414,height:736,keyboard:{portrait:320,landscape:240}},{width:768,height:1024,keyboard:{portrait:320,landscape:400}},{width:1024,height:1366,keyboard:{portrait:380,landscape:460}}];return b.findMap(e,function(b){return c<=b.width&&d<=b.height?a.some(b.keyboard):a.none()}).getOr({portrait:d/5,landscape:c/4})};return{findDevice:c}}),g("9w",["39","10","8b","a9","j"],function(a,b,c,d,e){var f=function(a){return d.findDevice(a.screen.width,a.screen.height)},g=function(a){var b=e.get(a).isPortrait(),c=f(a),d=b?c.portrait:c.landscape,g=b?a.screen.height:a.screen.width;return g-a.innerHeight>d?0:d},h=function(a,d){var e=b.owner(a).dom().defaultView,f=c.get(a)+c.get(d),h=g(e);return f-h},i=function(b,d,e){var f=h(d,e),g=c.get(d)+c.get(e)-f;a.set(b,"padding-bottom",g+"px")};return{getGreenzone:h,updatePadding:i}}),g("8o",["6k","y","6","4i","39","5l","10","8b","9w","i","3z","84"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=a.generate([{fixed:["element","property","offsetY"]},{scroller:["element","offsetY"]}]),n="data-"+j.resolve("position-y-fixed"),o="data-"+j.resolve("y-property"),p="data-"+j.resolve("scrolling"),q="data-"+j.resolve("last-window-height"),r=function(a){return l.safeParse(a,n)},s=function(a){return d.get(a,o)},t=function(a){return l.safeParse(a,q)},u=function(a,b){var c=s(a);return m.fixed(a,c,b)},v=function(a,b){return m.scroller(a,b)},w=function(a){var b=r(a),c="true"===d.get(a,p)?v:u;return c(a,b)},x=function(a){var c=f.descendants(a,"["+n+"]");return b.map(c,w)},y=function(a){var b=d.get(a,"style");e.setAll(a,{position:"absolute",top:"0px"}),d.set(a,n,"0px"),d.set(a,o,"top");var c=function(){d.set(a,"style",b||""),d.remove(a,n),d.remove(a,o)};return{restore:c}},z=function(a,b,c){var f=d.get(c,"style");k.register(c),e.setAll(c,{position:"absolute",height:b+"px",width:"100%",top:a+"px"}),d.set(c,n,a+"px"),d.set(c,p,"true"),d.set(c,o,"top");var g=function(){k.deregister(c),d.set(c,"style",f||""),d.remove(c,n),d.remove(c,p),d.remove(c,o)};return{restore:g}},A=function(a,b,c){var f=d.get(a,"style");e.setAll(a,{position:"absolute",bottom:"0px"}),d.set(a,n,"0px"),d.set(a,o,"bottom");var g=function(){d.set(a,"style",f||""),d.remove(a,n),d.remove(a,o)};return{restore:g}},B=function(a,b,c){var e=g.owner(a).dom().defaultView,f=e.innerHeight;return d.set(a,q,f+"px"),f-b-c},C=function(a,b,f,j){var k=g.owner(a).dom().defaultView,l=y(f),m=h.get(f),o=h.get(j),p=B(a,m,o),q=z(m,p,a),r=A(j,m,p),s=!0,u=function(){s=!1,l.restore(),q.restore(),r.restore()},v=function(){var b=k.innerHeight,c=t(a);return b>c},w=function(){if(s){var c=h.get(f),g=h.get(j),k=B(a,c,g);d.set(a,n,c+"px"),e.set(a,"height",k+"px"),e.set(j,"bottom",-(c+k+g)+"px"),i.updatePadding(b,a,j)}},x=function(b){var c=b+"px";d.set(a,n,c),w()};return i.updatePadding(b,a,j),{setViewportOffset:x,isExpanding:v,isShrinking:c.not(v),refresh:w,restore:u}};return{findFixtures:x,takeover:C,getYFixedData:r}}),g("8k",["6","9u","4i","8a","39","10","1w","9v","8o","i","84"],function(a,b,c,d,e,f,g,h,i,j,k){var l=h.create(),m=15,n=10,o=10,p="data-"+j.resolve("last-scroll-top"),q=function(a){var b=e.getRaw(a,"top").getOr(0);return parseInt(b,10)},r=function(a){return parseInt(a.dom().scrollTop,10)},s=function(c,d,f){return b.nu(function(b){var g=a.curry(r,c),h=function(a){c.dom().scrollTop=a,e.set(c,"top",q(c)+m+"px")},i=function(){c.dom().scrollTop=d,e.set(c,"top",f+"px"),b(d)};l.animate(g,d,m,h,i,o)})},t=function(d,e){return b.nu(function(b){var f=a.curry(r,d);c.set(d,p,f());var h=function(a,b){var e=k.safeParse(d,p);e!==d.dom().scrollTop?b(d.dom().scrollTop):(d.dom().scrollTop=a,c.set(d,p,a))},i=function(){d.dom().scrollTop=e,c.set(d,p,e),b(e)},j=g.abs(e-f()),m=g.ceil(j/n);l.animate(f,e,m,h,i,o)})},u=function(c,d){return b.nu(function(b){var f=a.curry(q,c),h=function(a){e.set(c,"top",a+"px")},i=function(){h(d),b(d)},j=g.abs(d-f()),k=g.ceil(j/n);l.animate(f,d,k,h,i,o)})},v=function(a,b){var c=b+i.getYFixedData(a)+"px";e.set(a,"top",c)},w=function(a,c,d){var e=f.owner(a).dom().defaultView;return b.nu(function(b){v(a,d),v(c,d),e.scrollTo(0,d),b(d)})};return{moveScrollAndTop:s,moveOnlyScroll:t,moveOnlyTop:u,moveWindowScroll:w}}),g("8l",["5","9x"],function(a,b){return function(c){var d=a(b.pure({})),e=function(a){var e=b.nu(function(b){return c(a).get(b)});d.set(e)},f=function(a){d.get().get(function(){a()})};return{start:e,idle:f}}}),g("8m",["6","8i","8k","9w","9t"],function(a,b,c,d,e){var f=function(b,f,g,h,i){var j=d.getGreenzone(f,g),k=a.curry(e.refresh,b);h>j||i>j?c.moveOnlyScroll(f,f.dom().scrollTop-j+i).get(k):h<0&&c.moveOnlyScroll(f,f.dom().scrollTop+h).get(k)};return{scrollIntoView:f}}),g("aa",["y"],function(a){var b=function(b,c){return c(function(c){var d=[],e=0,f=function(a){return function(f){d[a]=f,e++,e>=b.length&&c(d)}};0===b.length?c([]):a.each(b,function(a,b){a.get(f(b))})})};return{par:b}}),g("9y",["y","9u","aa"],function(a,b,c){var d=function(a){return c.par(a,b.nu)},e=function(b,c){var e=a.map(b,c);return d(e)},f=function(a,b){return function(c){return b(c).bind(a)}};return{par:d,mapM:e,compose:f}}),g("8n",["y","9u","9y","39","8k","8o"],function(a,b,c,d,e,f){var g=function(a,c,e,f){var g=e+f;return d.set(a,c,g+"px"),b.pure(f)},h=function(a,b,c){var f=b+c,g=d.getRaw(a,"top").getOr(c),h=f-parseInt(g,10),i=a.dom().scrollTop+h;return e.moveScrollAndTop(a,i,f)},i=function(a,b){return a.fold(function(a,c,d){return g(a,c,b,d)},function(a,c){return h(a,b,c)})},j=function(b,d){var e=f.findFixtures(b),g=a.map(e,function(a){return i(a,d)});return c.par(g)};return{updatePositions:j}}),g("8p",["8","9","11","a","39"],function(a,b,c,d,e){var f=function(f,g){var h=d.fromTag("input");e.setAll(h,{opacity:"0",position:"absolute",top:"-1000px",left:"-1000px"}),b.append(f,h),a.focus(h),g(h),c.remove(h)};return{input:f}}),g("6g",["6","z","62","8","1u","12","a","39","1v","87","16","1w","8i","1x","1j","8j","8k","8l","8m","8n","8o","j","8p","85"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){var y=5,z=function(d,f,h,i,j,k){var l=r(function(a){return q.moveWindowScroll(d,f,a)}),m=function(){var c=x.getRectangles(k);return b.from(c[0]).bind(function(c){var d=c.top()-f.dom().scrollTop,e=d>i.innerHeight+y||d<-y;return e?b.some({top:a.constant(d),bottom:a.constant(d+c.height())}):b.none()})},n=c.last(function(){l.idle(function(){t.updatePositions(h,i.pageYOffset).get(function(){var a=m();a.each(function(a){f.dom().scrollTop=f.dom().scrollTop+a.top()}),l.start(0),j.refresh()})})},1e3),o=e.bind(g.fromDom(i),"scroll",function(){i.pageYOffset<0||n.throttle()});return t.updatePositions(h,i.pageYOffset).get(a.identity),{unbind:o.unbind}},A=function(b){var c=b.cWin(),i=b.ceBody(),j=b.socket(),k=b.toolstrip(),l=b.toolbar(),m=b.contentElement(),n=b.keyboardType(),o=b.outerWindow(),r=b.dropup(),t=u.takeover(j,i,k,r),x=n(b.outerBody(),c,f.body(),m,k,l),y=function(){x.toEditing(),I()},A=function(){x.toReading()},B=function(a){x.onToolbarTouch(a)},C=v.onChange(o,{onChange:a.noop,onReady:t.refresh});C.onAdjustment(function(){t.refresh()});var D=e.bind(g.fromDom(o),"resize",function(){t.isExpanding()&&t.refresh()}),E=z(k,j,b.outerBody(),o,t,c),F=p(c,m),G=function(){F.isActive()&&F.update()},H=function(){F.update()},I=function(){F.clear()},J=function(a,b){s.scrollIntoView(c,j,r,a,b)},K=function(){h.set(m,"height",m.dom().contentWindow.document.body.scrollHeight+"px")},L=function(b){t.setViewportOffset(b),q.moveOnlyTop(j,b).get(a.identity)},M=function(){t.restore(),C.destroy(),E.unbind(),D.unbind(),x.destroy(),F.destroy(),w.input(f.body(),d.blur)};return{toEditing:y,toReading:A,onToolbarTouch:B,refreshSelection:G,clearSelection:I,highlightSelection:H,scrollIntoView:J,updateToolbarPadding:a.noop,setViewportOffset:L,syncHeight:K,refreshStructure:t.refresh,destroy:M}};return{ +setup:A}}),g("6h",["y","6","8","1u","12","b","8q","8p"],function(a,b,c,d,e,f,g,h){var i=function(b,e,i,j){var k=function(){g.resume(e,j)},l=function(){h.input(b,c.blur)},m=d.bind(i,"keydown",function(b){a.contains(["input","textarea"],f.name(b.target()))||k()}),n=function(){},o=function(){m.unbind()};return{toReading:l,toEditing:k,onToolbarTouch:n,destroy:o}},j=function(a,d,e,f){var h=function(){c.blur(f)},i=function(){h()},j=function(){h()},k=function(){g.resume(d,f)};return{toReading:j,toEditing:k,onToolbarTouch:i,destroy:b.noop}};return{stubborn:i,timid:j}}),g("42",["6","1z","2o","8","a","2f","39","1b","6f","6g","5z","3y","6h","60","i","3z","61"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){var r=function(r,s){var t=q.tag(),u=b.value(),v=b.value(),w=b.api(),x=b.api(),y=function(){s.hide();var b=e.fromDom(h);k.getActiveApi(r.editor).each(function(e){u.set({socketHeight:g.getRaw(r.socket,"height"),iframeHeight:g.getRaw(e.frame(),"height"),outerScroll:h.body.scrollTop}),v.set({exclusives:l.exclusive(b,"."+p.scrollable())}),f.add(r.container,o.resolve("fullscreen-maximized")),n.clobberStyles(r.container,e.body()),t.maximize(),g.set(r.socket,"overflow","scroll"),g.set(r.socket,"-webkit-overflow-scrolling","touch"),d.focus(e.body());var k=c.immutableBag(["cWin","ceBody","socket","toolstrip","toolbar","dropup","contentElement","cursor","keyboardType","isScrolling","outerWindow","outerBody"],[]);w.set(j.setup(k({cWin:e.win(),ceBody:e.body(),socket:r.socket,toolstrip:r.toolstrip,toolbar:r.toolbar,dropup:r.dropup.element(),contentElement:e.frame(),cursor:a.noop,outerBody:r.body,outerWindow:r.win,keyboardType:m.stubborn,isScrolling:function(){return v.get().exists(function(a){return a.socket.isScrolling()})}}))),w.run(function(a){a.syncHeight()}),x.set(i.initEvents(e,w,r.toolstrip,r.socket,r.dropup))})},z=function(){t.restore(),x.clear(),w.clear(),s.show(),u.on(function(a){a.socketHeight.each(function(a){g.set(r.socket,"height",a)}),a.iframeHeight.each(function(a){g.set(r.editor.getFrame(),"height",a)}),h.body.scrollTop=a.scrollTop}),u.clear(),v.on(function(a){a.exclusives.unbind()}),v.clear(),f.remove(r.container,o.resolve("fullscreen-maximized")),n.restoreStyles(),p.deregister(r.toolbar),g.remove(r.socket,"overflow"),g.remove(r.socket,"-webkit-overflow-scrolling"),d.blur(r.editor.getFrame()),k.getActiveApi(r.editor).each(function(a){a.clearSelection()})},A=function(){w.run(function(a){a.refreshStructure()})};return{enter:y,refreshStructure:A,exit:z}};return{create:r}}),g("25",["3q","2e","6","39","3s","42","3t"],function(a,b,c,d,e,f,g){var h=function(h){var i=b.asRawOrDie("Getting IosWebapp schema",e,h);d.set(i.toolstrip,"width","100%"),d.set(i.container,"position","relative");var j=function(){i.setReadOnly(!0),m.enter()},k=a.build(g.sketch(j,i.translate));i.alloy.add(k);var l={show:function(){i.alloy.add(k)},hide:function(){i.alloy.remove(k)}},m=f.create(i,l);return{setReadOnly:i.setReadOnly,refreshStructure:m.refreshStructure,enter:m.enter,exit:m.exit,destroy:c.noop}};return{produce:h}}),g("m",["1y","6","1z","25","i","21","22","23","24"],function(a,b,c,d,e,f,g,h,i){return function(j){var k=i({classes:[e.resolve("ios-container")]}),l=f(),m=c.api(),n=g.makeEditSwitch(m),o=g.makeSocket(),p=h.build(function(){m.run(function(a){a.refreshStructure()})},j);k.add(l.wrapper()),k.add(o),k.add(p.component());var q=function(a){var b=l.createGroups(a);l.setGroups(b)},r=function(a){var b=l.createGroups(a);l.setContextToolbar(b)},s=function(){l.focus()},t=function(){l.restoreToolbar()},u=function(a){m.set(d.produce(a))},v=function(){m.run(function(b){a.remove(o,n),b.exit()})},w=function(a){g.updateMode(o,n,a,k.root())};return{system:b.constant(k),element:k.element,init:u,exit:v,setToolbarGroups:q,setContextToolbar:r,focusToolbar:s,restoreToolbar:t,updateMode:w,socket:b.constant(o),dropup:b.constant(p)}}}),g("26",["1e"],function(a){return a("tinymce.EditorManager")}),g("n",["14","26"],function(a,b){var c=function(c){var d=a.readOptFrom(c.settings,"skin_url").fold(function(){return b.baseURL+"/skins/lightgray"},function(a){return a});return{content:d+"/content.mobile.min.css",ui:d+"/skin.mobile.min.css"}};return{derive:c}}),g("o",["y","6","x","g"],function(a,b,c,d){var e=["x-small","small","medium","large","x-large"],f=function(a,b,c){a.system().broadcastOn([d.formatChanged()],{command:b,state:c})},g=function(b,d){var e=c.keys(d.formatter.get());a.each(e,function(a){d.formatter.formatChanged(a,function(c){f(b,a,c)})}),a.each(["ul","ol"],function(a){d.selection.selectorChanged(a,function(c,d){f(b,a,c)})})};return{init:g,fontSizes:b.constant(e)}}),g("p",[],function(){var a=function(a){var b=function(){a._skinLoaded=!0,a.fire("SkinLoaded")};return function(){a.initialized?b():a.on("init",b)}};return{fireSkinLoaded:a}}),g("0",["1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y){var z=f.constant("toReading"),A=f.constant("toEditing");return l.add("mobile",function(l){var B=function(B){var C=w.derive(l);o.isSkinDisabled(l)===!1?(l.contentCSS.push(C.content),m.DOM.styleSheetLoader.load(C.ui,y.fireSkinLoaded(l))):y.fireSkinLoaded(l)();var D=function(){l.fire("scrollIntoView")},E=j.fromTag("div"),F=g.detect().os.isAndroid()?t(D):v(D),G=j.fromDom(B.targetNode);i.after(G,E),c.attachSystem(E,F.system());var H=function(a){return h.search(a).bind(function(a){return F.system().getByDom(a).toOption()})},I=B.targetNode.ownerDocument.defaultView,J=s.onChange(I,{onChange:function(){var a=F.system();a.broadcastOn([p.orientationChanged()],{width:s.getActualWidth(I)})},onReady:f.noop}),K=function(a,b,c){c===!1&&l.selection.collapse(),F.setToolbarGroups(c?a.get():b.get()),l.setMode(c===!0?"readonly":"design"),l.fire(c===!0?z():A()),F.updateMode(c)},L=function(a,b){return l.on(a,b),{unbind:function(){l.off(a)}}};return l.on("init",function(){F.init({editor:{getFrame:function(){return j.fromDom(l.contentAreaContainer.querySelector("iframe"))},onDomChanged:function(){return{unbind:f.noop}},onToReading:function(a){return L(z(),a)},onToEditing:function(a){return L(A(),a)},onScrollToCursor:function(a){l.on("scrollIntoView",function(b){a(b)});var b=function(){l.off("scrollIntoView"),J.destroy()};return{unbind:b}},onTouchToolstrip:function(){c()},onTouchContent:function(){var a=j.fromDom(l.editorContainer.querySelector("."+r.resolve("toolbar")));H(a).each(b.emitExecute),F.restoreToolbar(),c()},onTapContent:function(b){var c=b.target();if("img"===k.name(c))l.selection.select(c.dom()),b.kill();else if("a"===k.name(c)){var d=F.system().getByDom(j.fromDom(l.editorContainer));d.each(function(b){a.isAlpha(b)&&n.openLink(c.dom())})}}},container:j.fromDom(l.editorContainer),socket:j.fromDom(l.contentAreaContainer),toolstrip:j.fromDom(l.editorContainer.querySelector("."+r.resolve("toolstrip"))),toolbar:j.fromDom(l.editorContainer.querySelector("."+r.resolve("toolbar"))),dropup:F.dropup(),alloy:F.system(),translate:f.noop,setReadOnly:function(a){K(w,v,a)}});var c=function(){F.dropup().disappear(function(){F.system().broadcastOn([p.dropupDismissed()],{})})};d.registerInspector("remove this",F.system());var g={label:"The first group",scrollable:!1,items:[u.forToolbar("back",function(){l.selection.collapse(),F.exit()},{})]},h={label:"Back to read only",scrollable:!1,items:[u.forToolbar("readonly-back",function(){K(w,v,!0)},{})]},i={label:"The read only mode group",scrollable:!0,items:[]},m=q.setup(F,l),o=q.detect(l.settings,m),s={label:"the action group",scrollable:!0,items:o},t={label:"The extra group",scrollable:!1,items:[]},v=e([h,s,t]),w=e([g,i,t]);x.init(F,l)}),{iframeContainer:F.socket().element().dom(),editorContainer:F.element().dom()}};return{getNotificationManagerImpl:function(){return{open:f.identity,close:f.noop,reposition:f.noop,getArgs:f.identity}},renderUI:B}}),function(){}}),d("0")()}(); \ No newline at end of file diff --git a/client-wiaas/public/static/js/tinymce/js/tinymce/themes/modern/theme.min.js b/client-wiaas/public/static/js/tinymce/js/tinymce/themes/modern/theme.min.js new file mode 100644 index 0000000..19a50ce --- /dev/null +++ b/client-wiaas/public/static/js/tinymce/js/tinymce/themes/modern/theme.min.js @@ -0,0 +1,5 @@ +!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i0?c:f},v=function(a){var c=a.getParam("toolbar"),d="undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image";return c===!1?[]:b.isArray(c)?b.grep(c,function(a){return a.length>0}):u(a.settings,d)};return{isBrandingEnabled:c,hasMenubar:d,getMenubar:e,hasStatusbar:f,getToolbarSize:g,getResize:h,isReadOnly:i,getFixedToolbarContainer:j,getInlineToolbarPositionHandler:k,getMenu:l,getRemovedMenuItems:m,getMinWidth:n,getMinHeight:o,getMaxWidth:p,getMaxHeight:q,getSkinUrl:r,isSkinDisabled:s,isInline:t,getToolbars:v}}),g("2j",["6"],function(a){return a("tinymce.dom.DOMUtils")}),g("b",["6"],function(a){return a("tinymce.ui.Factory")}),g("37",["6"],function(a){return a("tinymce.util.I18n")}),g("2k",[],function(){var a=function(a){return a.fire("SkinLoaded")},b=function(a){return a.fire("ResizeEditor")},c=function(a){return a.fire("BeforeRenderUI")};return{fireSkinLoaded:a,fireResizeEditor:b,fireBeforeRenderUI:c}}),g("38",[],function(){var a=function(a,b){return function(){var c=a.find(b)[0];c&&c.focus(!0)}},b=function(b,c){b.shortcuts.add("Alt+F9","",a(c,"menubar")),b.shortcuts.add("Alt+F10,F10","",a(c,"toolbar")),b.shortcuts.add("Alt+F11","",a(c,"elementpath")),c.on("cancel",function(){b.focus()})};return{addKeys:b}}),g("14",["6"],function(a){return a("tinymce.Env")}),g("3p",["6"],function(a){return a("tinymce.geom.Rect")}),g("2u",["6"],function(a){return a("tinymce.util.Delay")}),h("2y",Array),h("2z",Error),g("z",["2y","2z"],function(a,b){var c=function(){},d=function(a,b){return function(){return a(b.apply(null,arguments))}},e=function(a){return function(){return a}},f=function(a){return a},g=function(a,b){return a===b},h=function(b){for(var c=new a(arguments.length-1),d=1;d=0;c--)for(d=f.length-1;d>=0;d--)if(f[d].predicate(e[c]))return{toolbar:f[d],element:e[c]};return null};b.on("click keyup setContent ObjectResized",function(a){("setcontent"!==a.type||a.selection)&&e.setEditorTimeout(b,function(){var a;a=w(b.selection.getNode()),a?(v(),u(a)):v()})}),b.on("blur hide contextmenu",v),b.on("ObjectResizeStart",function(){var a=w(b.selection.getNode());a&&a.toolbar.panel&&a.toolbar.panel.hide()}),b.on("ResizeEditor ResizeWindow",s(!0)),b.on("nodeChange",s(!1)),b.on("remove",function(){f.each(p(),function(a){a.panel&&a.panel.remove()}),b.contextToolbars={}}),b.shortcuts.add("ctrl+shift+e > ctrl+shift+p","",function(){var a=w(b.selection.getNode());a&&a.toolbar.panel&&a.toolbar.panel.items()[0].focus()})};return{addContextualToolbars:p}}),h("3h",String),g("2l",["3g","2y","2z","3h"],function(a,b,c,d){var e=function(){var a=b.prototype.indexOf,c=function(b,c){return a.call(b,c)},d=function(a,b){return u(a,b)};return void 0===a?d:c}(),f=function(b,c){var d=e(b,c);return d===-1?a.none():a.some(d)},g=function(a,b){return e(a,b)>-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e0&&b=11},l=function(a){return!(!k()||!a.sidebars)&&a.sidebars.length>0},m=function(a){var b=c.map(a.sidebars,function(b){var c=b.settings;return{type:"button",icon:c.icon,image:c.image,tooltip:c.tooltip,onclick:j(a,b.name,a.sidebars)}});return{type:"panel",name:"sidebar",layout:"stack",classes:"sidebar",items:[{type:"toolbar",layout:"stack",classes:"sidebar-toolbar",items:b}]}};return{hasSidebar:l,createSidebar:m}}),g("3c",["2k"],function(a){var b=function(b){var c=function(){b._skinLoaded=!0,a.fireSkinLoaded(b)};return function(){b.initialized?c():b.on("init",c)}};return{fireSkinLoaded:b}}),g("2g",["2j","b","37","c","2k","2f","38","39","3a","8","3b","3c","3d"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=a.DOM,o=function(a){return function(b){a.find("*").disabled("readonly"===b.mode)}},p=function(a){return{type:"panel",name:"iframe",layout:"stack",classes:"edit-area",border:a,html:""}},q=function(a){return{type:"panel",layout:"stack",classes:"edit-aria-container",border:"1 0 0 0",items:[p("0"),k.createSidebar(a)]}},r=function(a,d,r){var s,t,u;if(f.isSkinDisabled(a)===!1&&r.skinUiCss?n.styleSheetLoader.load(r.skinUiCss,l.fireSkinLoaded(a)):l.fireSkinLoaded(a)(),s=d.panel=b.create({type:"panel",role:"application",classes:"tinymce",style:"visibility: hidden",layout:"stack",border:1,items:[{type:"container",classes:"top-part",items:[f.hasMenubar(a)===!1?null:{type:"menubar",border:"0 0 1 0",items:i.createMenuButtons(a)},m.createToolbars(a,f.getToolbarSize(a))]},k.hasSidebar(a)?q(a):p("1 0 0 0")]}),"none"!==f.getResize(a)&&(t={type:"resizehandle",direction:f.getResize(a),onResizeStart:function(){var b=a.getContentAreaContainer().firstChild;u={width:b.clientWidth,height:b.clientHeight}},onResize:function(b){"both"===f.getResize(a)?j.resizeTo(a,u.width+b.deltaX,u.height+b.deltaY):j.resizeTo(a,null,u.height+b.deltaY)}}),f.hasStatusbar(a)){var v='tinymce',w=c.translate(["Powered by {0}",v]),x=f.isBrandingEnabled(a)?{type:"label",classes:"branding",html:" "+w}:null;s.add({type:"panel",name:"statusbar",classes:"statusbar",layout:"flow",border:"1 0 0 0",ariaRoot:!0,items:[{type:"elementpath",editor:a},t,x]})}return e.fireBeforeRenderUI(a),a.on("SwitchMode",o(s)),s.renderBefore(r.targetNode).reflow(),f.isReadOnly(a)&&a.setMode("readonly"),r.width&&n.setStyle(s.getEl(),"width",r.width),a.on("remove",function(){s.remove(),s=null}),g.addKeys(a,s),h.addContextualToolbars(a),{iframeContainer:s.find("#iframe")[0].getEl(),editorContainer:s.getEl()}};return{render:r}}),h("12",document),g("2o",["6"],function(a){return a("tinymce.dom.DomQuery")}),g("2n",["12","2j","14","c"],function(a,b,c,d){"use strict";var e=0,f={id:function(){return"mceu_"+e++},create:function(c,e,f){var g=a.createElement(c);return b.DOM.setAttribs(g,e),"string"==typeof f?g.innerHTML=f:d.each(f,function(a){a.nodeType&&g.appendChild(a)}),g},createFragment:function(a){return b.DOM.createFragment(a)},getWindowSize:function(){return b.DOM.getViewPort()},getSize:function(a){var b,c;if(a.getBoundingClientRect){var d=a.getBoundingClientRect();b=Math.max(d.width||d.right-d.left,a.offsetWidth),c=Math.max(d.height||d.bottom-d.bottom,a.offsetHeight)}else b=a.offsetWidth,c=a.offsetHeight;return{width:b,height:c}},getPos:function(a,c){return b.DOM.getPos(a,c||f.getContainer())},getContainer:function(){return c.container?c.container:a.body},getViewPort:function(a){return b.DOM.getViewPort(a)},get:function(b){return a.getElementById(b)},addClass:function(a,c){return b.DOM.addClass(a,c)},removeClass:function(a,c){return b.DOM.removeClass(a,c)},hasClass:function(a,c){return b.DOM.hasClass(a,c)},toggleClass:function(a,c,d){return b.DOM.toggleClass(a,c,d)},css:function(a,c,d){return b.DOM.setStyle(a,c,d)},getRuntimeStyle:function(a,c){return b.DOM.getStyle(a,c,!0)},on:function(a,c,d,e){return b.DOM.bind(a,c,d,e)},off:function(a,c,d){return b.DOM.unbind(a,c,d)},fire:function(a,c,d){return b.DOM.fire(a,c,d)},innerHtml:function(a,c){b.DOM.setHTML(a,c)}};return f}),g("1s",["12","1","2n"],function(a,b,c){"use strict";function d(b,d,e){var f,g,h,i,j,k,l,m,n,o;return n=c.getViewPort(),g=c.getPos(d),h=g.x,i=g.y,b.state.get("fixed")&&"static"==c.getRuntimeStyle(a.body,"position")&&(h-=n.x,i-=n.y),f=b.getEl(),o=c.getSize(f),j=o.width,k=o.height,o=c.getSize(d),l=o.width,m=o.height,e=(e||"").split(""),"b"===e[0]&&(i+=m),"r"===e[1]&&(h+=l),"c"===e[0]&&(i+=Math.round(m/2)),"c"===e[1]&&(h+=Math.round(l/2)),"b"===e[3]&&(i-=k),"r"===e[4]&&(h-=j),"c"===e[3]&&(i-=Math.round(k/2)),"c"===e[4]&&(h-=Math.round(j/2)),{x:h,y:i,w:j,h:k}}return{testMoveRel:function(a,b){for(var e=c.getViewPort(),f=0;f0&&g.x+g.w0&&g.y+g.he.x&&g.x+g.we.y&&g.y+g.hb?(a=b-c,a<0?0:a):a}var f=this;if(f.settings.constrainToViewport){var g=c.getViewPort(b),h=f.layoutRect();a=e(a,g.w+g.x,h.w),d=e(d,g.h+g.y,h.h)}return f.state.get("rendered")?f.layoutRect({x:a,y:d}).repaint():(f.settings.x=a,f.settings.y=d),f.fire("move",{x:a,y:d}),f}}}),g("2p",["6"],function(a){return a("tinymce.util.Class")}),g("2q",["6"],function(a){return a("tinymce.util.EventDispatcher")}),g("2r",["12"],function(a){"use strict";return{parseBox:function(a){var b,c=10;if(a)return"number"==typeof a?(a=a||0,{top:a,left:a,bottom:a,right:a}):(a=a.split(" "),b=a.length,1===b?a[1]=a[2]=a[3]=a[0]:2===b?(a[2]=a[0],a[3]=a[1]):3===b&&(a[3]=a[1]),{top:parseInt(a[0],c)||0,right:parseInt(a[1],c)||0,bottom:parseInt(a[2],c)||0,left:parseInt(a[3],c)||0})},measureBox:function(b,c){function d(c){var d=a.defaultView;return d?(c=c.replace(/[A-Z]/g,function(a){return"-"+a}),d.getComputedStyle(b,null).getPropertyValue(c)):b.currentStyle[c]}function e(a){var b=parseFloat(d(a),10);return isNaN(b)?0:b}return{top:e(c+"TopWidth"),right:e(c+"RightWidth"),bottom:e(c+"BottomWidth"),left:e(c+"LeftWidth")}}}}),g("2s",["c"],function(a){"use strict";function b(){}function c(a){this.cls=[],this.cls._map={},this.onchange=a||b,this.prefix=""}return a.extend(c.prototype,{add:function(a){return a&&!this.contains(a)&&(this.cls._map[a]=!0,this.cls.push(a),this._change()),this},remove:function(a){if(this.contains(a)){for(var b=0;b0&&(a+=" "),a+=this.prefix+this.cls[b];return a},c}),g("24",["2p"],function(a){"use strict";function b(a){for(var b,c=[],d=a.length;d--;)b=a[d],b.__checked||(c.push(b),b.__checked=1);for(d=c.length;d--;)delete c[d].__checked;return c}var c,d=/^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,e=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,f=/^\s*|\s*$/g,g=a.extend({init:function(a){function b(a){if(a)return a=a.toLowerCase(),function(b){return"*"===a||b.type===a}}function c(a){if(a)return function(b){return b._name===a}}function g(a){if(a)return a=a.split("."),function(b){for(var c=a.length;c--;)if(!b.classes.contains(a[c]))return!1;return!0}}function h(a,b,c){if(a)return function(d){var e=d[a]?d[a]():"";return b?"="===b?e===c:"*="===b?e.indexOf(c)>=0:"~="===b?(" "+e+" ").indexOf(" "+c+" ")>=0:"!="===b?e!=c:"^="===b?0===e.indexOf(c):"$="===b&&e.substr(e.length-c.length)===c:!!c}}function i(a){var b;if(a)return a=/(?:not\((.+)\))|(.+)/i.exec(a),a[1]?(b=k(a[1],[]),function(a){return!l(a,b)}):(a=a[2],function(b,c,d){return"first"===a?0===c:"last"===a?c===d-1:"even"===a?c%2===0:"odd"===a?c%2===1:!!b[a]&&b[a]()})}function j(a,e,j){function k(a){a&&e.push(a)}var l;return l=d.exec(a.replace(f,"")),k(b(l[1])),k(c(l[2])),k(g(l[3])),k(h(l[4],l[5],l[6])),k(i(l[7])),e.pseudo=!!l[7],e.direct=j,e}function k(a,b){var c,d,f,g=[];do if(e.exec(""),d=e.exec(a),d&&(a=d[3],g.push(d[1]),d[2])){c=d[3];break}while(d);for(c&&k(c,b),a=[],f=0;f"!=g[f]&&a.push(j(g[f],[],">"===g[f-1]));return b.push(a),b}var l=this.match;this._selectors=k(a,[])},match:function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;for(b=b||this._selectors,c=0,d=b.length;c=0;e--)for(j=g[e];o;){if(j.pseudo)for(m=o.parent().items(),k=l=m.length;k--&&m[k]!==o;);for(h=0,i=j.length;h1&&(h=b(h))}return c||(c=g.Collection),new c(h)}});return g}),g("i",["c","24","2p"],function(a,b,c){"use strict";var d,e,f=Array.prototype.push,g=Array.prototype.slice;return e={length:0,init:function(a){a&&this.add(a)},add:function(b){var c=this;return a.isArray(b)?f.apply(c,b):b instanceof d?c.add(b.toArray()):f.call(c,b),c},set:function(a){var b,c=this,d=c.length;for(c.length=0,c.add(a),b=c.length;b0}function f(a,b){var c,g;if(a===b)return!0;if(null===a||null===b)return a===b;if("object"!=typeof a||"object"!=typeof b)return a===b;if(d.isArray(b)){if(a.length!==b.length)return!1;for(c=a.length;c--;)if(!f(a[c],b[c]))return!1}if(e(a)||e(b))return a===b;g={};for(c in b){if(!f(a[c],b[c]))return!1;g[c]=!0}for(c in a)if(!g[c]&&!f(a[c],b[c]))return!1;return!0}return b.extend({Mixins:[c],init:function(b){var c,d;b=b||{};for(c in b)d=b[c],d instanceof a&&(b[c]=d.create(this,c));this.data=b},set:function(b,c){var d,e,g=this.data[b];if(c instanceof a&&(c=c.create(this,b)),"object"==typeof b){for(d in b)this.set(d,b[d]);return this}return f(g,c)||(this.data[b]=c,e={target:this,name:b,value:c,oldValue:g},this.fire("change:"+b,e),this.fire("change",e)),this},get:function(a){return this.data[a]},has:function(a){return a in this.data},bind:function(b){return a.create(this,b)},destroy:function(){this.fire("destroy")}})}),g("1z",["12","2u"],function(a,b){var c,d={};return{add:function(e){var f=e.parent();if(f){if(!f._layout||f._layout.isNative())return;d[f._id]||(d[f._id]=f),c||(c=!0,b.requestAnimationFrame(function(){var a,b;c=!1;for(a in d)b=d[a],b.state.get("rendered")&&b.reflow();d={}},a.body))}},remove:function(a){d[a._id]&&delete d[a._id]}}}),g("o",["12","2o","2p","2q","c","2r","2s","i","2t","2n","1z"],function(a,b,c,d,e,f,g,h,i,j,k){"use strict";function l(a){return a._eventDispatcher||(a._eventDispatcher=new d({scope:a,toggleEvent:function(b,c){c&&d.isNative(b)&&(a._nativeEvents||(a._nativeEvents={}),a._nativeEvents[b]=!0,a.state.get("rendered")&&m(a))}})),a._eventDispatcher}function m(a){function c(b){var c=a.getParentCtrl(b.target);c&&c.fire(b.type,b)}function d(){var a=j._lastHoverCtrl;a&&(a.fire("mouseleave",{target:a.getEl()}),a.parents().each(function(a){a.fire("mouseleave",{target:a.getEl()})}),j._lastHoverCtrl=null)}function e(b){var c,d,e,f=a.getParentCtrl(b.target),g=j._lastHoverCtrl,h=0;if(f!==g){if(j._lastHoverCtrl=f,d=f.parents().toArray().reverse(),d.push(f),g){for(e=g.parents().toArray().reverse(),e.push(g),h=0;h=h;c--)g=e[c],g.fire("mouseleave",{target:g.getEl()})}for(c=h;ci.maxW?i.maxW:c,i.w=c,i.innerW=c-d),c=a.h,c!==f&&(c=ci.maxH?i.maxH:c,i.h=c,i.innerH=c-e),c=a.innerW,c!==f&&(c=ci.maxW-d?i.maxW-d:c,i.innerW=c,i.w=c+d),c=a.innerH,c!==f&&(c=ci.maxH-e?i.maxH-e:c,i.innerH=c,i.h=c+e),a.contentW!==f&&(i.contentW=a.contentW),a.contentH!==f&&(i.contentH=a.contentH),b=h._lastLayoutRect,b.x===i.x&&b.y===i.y&&b.w===i.w&&b.h===i.h||(g=n.repaintControls,g&&g.map&&!g.map[h._id]&&(g.push(h),g.map[h._id]=!0),b.x=i.x,b.y=i.y,b.w=i.w,b.h=i.h),h):i},repaint:function(){var b,c,d,e,f,g,h,i,j,k,l=this;j=a.createRange?function(a){return a}:Math.round,b=l.getEl().style,e=l._layoutRect,i=l._lastRepaintRect||{},f=l.borderBox,g=f.left+f.right,h=f.top+f.bottom,e.x!==i.x&&(b.left=j(e.x)+"px",i.x=e.x),e.y!==i.y&&(b.top=j(e.y)+"px",i.y=e.y),e.w!==i.w&&(k=j(e.w-g),b.width=(k>=0?k:0)+"px",i.w=e.w),e.h!==i.h&&(k=j(e.h-h),b.height=(k>=0?k:0)+"px",i.h=e.h),l._hasBody&&e.innerW!==i.innerW&&(k=j(e.innerW),d=l.getEl("body"),d&&(c=d.style,c.width=(k>=0?k:0)+"px"),i.innerW=e.innerW),l._hasBody&&e.innerH!==i.innerH&&(k=j(e.innerH),d=d||l.getEl("body"),d&&(c=c||d.style,c.height=(k>=0?k:0)+"px"),i.innerH=e.innerH),l._lastRepaintRect=i,l.fire("repaint",{},!1)},updateLayoutRect:function(){var a=this;a.parent()._lastRect=null,j.css(a.getEl(),{width:"",height:""}),a._layoutRect=a._lastRepaintRect=a._lastLayoutRect=null,a.initLayoutRect()},on:function(a,b){function c(a){var b,c;return"string"!=typeof a?a:function(e){return b||d.parentsAndSelf().each(function(d){var e=d.settings.callbacks;if(e&&(b=e[a]))return c=d,!1}),b?b.call(c,e):(e.action=a,void this.fire("execute",e))}}var d=this;return l(d).on(a,c(b)),d},off:function(a,b){return l(this).off(a,b),this},fire:function(a,b,c){var d=this;if(b=b||{},b.control||(b.control=d),b=l(d).fire(a,b),c!==!1&&d.parent)for(var e=d.parent();e&&!b.isPropagationStopped();)e.fire(a,b,!1),e=e.parent();return b},hasEventListeners:function(a){return l(this).has(a)},parents:function(a){var b,c=this,d=new h;for(b=c.parent();b;b=b.parent())d.add(b);return a&&(d=d.filter(a)),d},parentsAndSelf:function(a){return new h(this).add(this.parents(a))},next:function(){var a=this.parent().items();return a[a.indexOf(this)+1]},prev:function(){var a=this.parent().items();return a[a.indexOf(this)-1]},innerHtml:function(a){return this.$el.html(a),this},getEl:function(a){var c=a?this._id+"-"+a:this._id;return this._elmCache[c]||(this._elmCache[c]=b("#"+c)[0]),this._elmCache[c]},show:function(){return this.visible(!0)},hide:function(){return this.visible(!1)},focus:function(){try{this.getEl().focus()}catch(a){}return this},blur:function(){return this.getEl().blur(),this},aria:function(a,b){var c=this,d=c.getEl(c.ariaTarget);return"undefined"==typeof b?c._aria[a]:(c._aria[a]=b,c.state.get("rendered")&&d.setAttribute("role"==a?a:"aria-"+a,b),c)},encode:function(a,b){return b!==!1&&(a=this.translate(a)),(a||"").replace(/[&<>"]/g,function(a){return"&#"+a.charCodeAt(0)+";"})},translate:function(a){return n.translate?n.translate(a):a},before:function(a){var b=this,c=b.parent();return c&&c.insert(a,c.items().indexOf(b),!0),b},after:function(a){var b=this,c=b.parent();return c&&c.insert(a,c.items().indexOf(b)),b},remove:function(){var a,c,d=this,e=d.getEl(),f=d.parent();if(d.items){var g=d.items().toArray();for(c=g.length;c--;)g[c].remove()}f&&f.items&&(a=[],f.items().each(function(b){b!==d&&a.push(b)}),f.items().set(a),f._lastRect=null),d._eventsRoot&&d._eventsRoot==d&&b(e).off();var h=d.getRoot().controlIdLookup;return h&&delete h[d._id],e&&e.parentNode&&e.parentNode.removeChild(e),d.state.set("rendered",!1),d.state.destroy(),d.fire("remove"),d},renderBefore:function(a){return b(a).before(this.renderHtml()),this.postRender(),this},renderTo:function(a){return b(a||this.getContainerElm()).append(this.renderHtml()),this.postRender(),this},preRender:function(){},render:function(){},renderHtml:function(){return'
    '},postRender:function(){var a,c,d,e,f,g=this,h=g.settings;g.$el=b(g.getEl()),g.state.set("rendered",!0);for(e in h)0===e.indexOf("on")&&g.on(e.substr(2),h[e]);if(g._eventsRoot){for(d=g.parent();!f&&d;d=d.parent())f=d._eventsRoot;if(f)for(e in f._nativeEvents)g._nativeEvents[e]=!0}m(g),h.style&&(a=g.getEl(),a&&(a.setAttribute("style",h.style),a.style.cssText=h.style)),g.settings.border&&(c=g.borderBox,g.$el.css({"border-top-width":c.top,"border-right-width":c.right,"border-bottom-width":c.bottom,"border-left-width":c.left}));var i=g.getRoot();i.controlIdLookup||(i.controlIdLookup={}),i.controlIdLookup[g._id]=g;for(var j in g._aria)g.aria(j,g._aria[j]);g.state.get("visible")===!1&&(g.getEl().style.display="none"),g.bindStates(),g.state.on("change:visible",function(a){var b,c=a.value;g.state.get("rendered")&&(g.getEl().style.display=c===!1?"none":"",g.getEl().getBoundingClientRect()),b=g.parent(),b&&(b._lastRect=null),g.fire(c?"show":"hide"),k.add(g)}),g.fire("postrender",{},!1)},bindStates:function(){},scrollIntoView:function(a){function b(a,b){var c,d,e=a;for(c=d=0;e&&e!=b&&e.nodeType;)c+=e.offsetLeft||0,d+=e.offsetTop||0,e=e.offsetParent;return{x:c,y:d}}var c,d,e,f,g,h,i=this.getEl(),j=i.parentNode,k=b(i,j);return c=k.x,d=k.y,e=i.offsetWidth,f=i.offsetHeight,g=j.clientWidth,h=j.clientHeight,"end"==a?(c-=g-e,d-=h-f):"center"==a&&(c-=g/2-e/2,d-=h/2-f/2),j.scrollLeft=c,j.scrollTop=d,this},getRoot:function(){for(var a,b=this,c=[];b;){if(b.rootControl){a=b.rootControl;break}c.push(b),a=b,b=b.parent()}a||(a=this);for(var d=c.length;d--;)c[d].rootControl=a;return a},reflow:function(){k.remove(this);var a=this.parent();return a&&a._layout&&!a._layout.isNative()&&a.reflow(),this}};return e.each("text title visible disabled active value".split(" "),function(a){s[a]=function(b){return 0===arguments.length?this.state.get(a):("undefined"!=typeof b&&this.state.set(a,b),this)}}),n=c.extend(s)}),g("1j",["12"],function(a){"use strict";var b=function(a){return!!a.getAttribute("data-mce-tabstop")};return function(c){function d(a){return a&&1===a.nodeType}function e(a){return a=a||v,d(a)?a.getAttribute("role"):null}function f(a){for(var b,c=a||v;c=c.parentNode;)if(b=e(c))return b}function g(a){var b=v;if(d(b))return b.getAttribute("aria-"+a)}function h(a){var b=a.tagName.toUpperCase();return"INPUT"==b||"TEXTAREA"==b||"SELECT"==b}function i(a){return!(!h(a)||a.hidden)||(!!b(a)||!!/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(e(a)))}function j(a){function b(a){if(1==a.nodeType&&"none"!=a.style.display&&!a.disabled){i(a)&&c.push(a);for(var d=0;d=b.length&&(a=0),b[a]&&b[a].focus(),a}function n(a,b){var c=-1,d=k();b=b||j(d.getEl());for(var e=0;e=0&&(c=b.getEl(),c&&c.parentNode.removeChild(c),c=a.getEl(),c&&c.parentNode.removeChild(c)),b.parent(this)},create:function(b){var c,e=this,g=[];return f.isArray(b)||(b=[b]),f.each(b,function(b){b&&(b instanceof a||("string"==typeof b&&(b={type:b}),c=f.extend({},e.settings.defaults,b),b.type=c.type=c.type||b.type||e.settings.defaultType||(c.defaults?c.defaults.type:null),b=d.create(c)),g.push(b))}),g},renderNew:function(){var a=this;return a.items().each(function(b,c){var d;b.parent(a),b.state.get("rendered")||(d=a.getEl("body"),d.hasChildNodes()&&c<=d.childNodes.length-1?g(d.childNodes[c]).before(b.renderHtml()):g(d).append(b.renderHtml()),b.postRender(),i.add(b))}),a._layout.applyClasses(a.items().filter(":visible")),a._lastRect=null,a},append:function(a){return this.add(a).renderNew()},prepend:function(a){var b=this;return b.items().set(b.create(a).concat(b.items().toArray())),b.renderNew()},insert:function(a,b,c){var d,e,f,g=this;return a=g.create(a),d=g.items(),!c&&b=0&&b
    '+(a.settings.html||"")+b.renderHtml(a)+"
    "},postRender:function(){var a,b=this;return b.items().exec("postRender"),b._super(),b._layout.postRender(b),b.state.set("rendered",!0),b.settings.style&&b.$el.css(b.settings.style),b.settings.border&&(a=b.borderBox,b.$el.css({"border-top-width":a.top,"border-right-width":a.right,"border-bottom-width":a.bottom,"border-left-width":a.left})),b.parent()||(b.keyboardNav=new e({root:b})),b},initLayoutRect:function(){var a=this,b=a._super();return a._layout.recalc(a),b},recalc:function(){var a=this,b=a._layoutRect,c=a._lastRect;if(!c||c.w!=b.w||c.h!=b.h)return a._layout.recalc(a),b=a.layoutRect(),a._lastRect={x:b.x,y:b.y,w:b.w,h:b.h},!0},reflow:function(){var b;if(i.remove(this),this.visible()){for(a.repaintControls=[],a.repaintControls.map={},this.recalc(),b=a.repaintControls.length;b--;)a.repaintControls[b].repaint();"flow"!==this.settings.layout&&"stack"!==this.settings.layout&&this.repaint(),a.repaintControls=[]}return this}})}),g("p",["12","1","2o"],function(a,b,c){"use strict";function d(a){var b,c,d,e,f,g,h,i,j=Math.max;return b=a.documentElement,c=a.body,d=j(b.scrollWidth,c.scrollWidth),e=j(b.clientWidth,c.clientWidth),f=j(b.offsetWidth,c.offsetWidth),g=j(b.scrollHeight,c.scrollHeight),h=j(b.clientHeight,c.clientHeight),i=j(b.offsetHeight,c.offsetHeight),{width:d").css({position:"absolute",top:0,left:0,width:q.width,height:q.height,zIndex:2147483647,opacity:1e-4,cursor:k}).appendTo(p.body),c(p).on("mousemove touchmove",m).on("mouseup touchend",l),g.start(a)},m=function(a){return e(a),a.button!==j?l(a):(a.deltaX=a.screenX-n,a.deltaY=a.screenY-o,a.preventDefault(),void g.drag(a))},l=function(a){e(a),c(p).off("mousemove touchmove",m).off("mouseup touchend",l),i.remove(),g.stop&&g.stop(a)},this.destroy=function(){c(h()).off()},c(h()).on("mousedown touchstart",k)}}),g("22",["2o","p"],function(a,b){"use strict";return{init:function(){var a=this;a.on("repaint",a.renderScroll)},renderScroll:function(){function c(){function b(b,g,h,i,j,k){var l,m,n,o,p,q,r,s,t;if(m=e.getEl("scroll"+b)){if(s=g.toLowerCase(),t=h.toLowerCase(),a(e.getEl("absend")).css(s,e.layoutRect()[i]-1),!j)return void a(m).css("display","none");a(m).css("display","block"),l=e.getEl("body"),n=e.getEl("scroll"+b+"t"),o=l["client"+h]-2*f,o-=c&&d?m["client"+k]:0,p=l["scroll"+h],q=o/p,r={},r[s]=l["offset"+g]+f,r[t]=o,a(m).css(r),r={},r[s]=l["scroll"+g]*q,r[t]=o*q,a(n).css(r)}}var c,d,g;g=e.getEl("body"),c=g.scrollWidth>g.clientWidth,d=g.scrollHeight>g.clientHeight,b("h","Left","Width","contentW",c,"Height"),b("v","Top","Height","contentH",d,"Width")}function d(){function c(c,d,g,h,i){var j,k=e._id+"-scroll"+c,l=e.classPrefix;a(e.getEl()).append('
    '),e.draghelper=new b(k+"t",{start:function(){j=e.getEl("body")["scroll"+d],a("#"+k).addClass(l+"active")},drag:function(a){var b,k,l,m,n=e.layoutRect();k=n.contentW>n.innerW,l=n.contentH>n.innerH,m=e.getEl("body")["client"+g]-2*f,m-=k&&l?e.getEl("scroll"+c)["client"+i]:0,b=m/e.getEl("body")["scroll"+g],e.getEl("body")["scroll"+d]=j+a["delta"+h]/b},stop:function(){a("#"+k).removeClass(l+"active")}})}e.classes.add("scroll"),c("v","Top","Height","Y","Width"),c("h","Left","Width","X","Height")}var e=this,f=2;e.settings.autoScroll&&(e._hasScroll||(e._hasScroll=!0,d(),e.on("wheel",function(a){var b=e.getEl("body");b.scrollLeft+=10*(a.deltaX||0),b.scrollTop+=10*a.deltaY,c()}),a(e.getEl("body")).on("scroll",c)),c())}}}),g("1u",["n","22"],function(a,b){"use strict";return a.extend({Defaults:{layout:"fit",containerCls:"panel"},Mixins:[b],renderHtml:function(){var a=this,b=a._layout,c=a.settings.html;return a.preRender(),b.preRender(a),"undefined"==typeof c?c='
    '+b.renderHtml(a)+"
    ":("function"==typeof c&&(c=c.call(a)),a._hasBody=!1),'
    '+(a._preBodyHtml||"")+c+"
    "}})}),g("20",["2n"],function(a){"use strict";return{resizeToContent:function(){this._layoutRect.autoResize=!0,this._lastRect=null,this.reflow()},resizeTo:function(b,c){if(b<=1||c<=1){var d=a.getWindowSize();b=b<=1?b*d.w:b,c=c<=1?c*d.h:c}return this._layoutRect.autoResize=!1,this.layoutRect({minW:b,minH:c,w:b,h:c}).reflow()},resizeBy:function(a,b){var c=this,d=c.layoutRect();return c.resizeTo(d.w+a,d.h+b)}}}),g("w",["12","1","2o","2u","2n","1s","1u","20"],function(a,b,c,d,e,f,g,h){"use strict";function i(a,b){for(;a;){if(a==b)return!0;a=a.parent()}}function j(a){for(var b=u.length;b--;){var c=u[b],d=c.getParentCtrl(a.target);if(c.settings.autohide){if(d&&(i(d,c)||c.parent()===d))continue;a=c.fire("autohide",{target:a.target}),a.isDefaultPrevented()||c.hide()}}}function k(){q||(q=function(a){2!=a.button&&j(a)},c(a).on("click touchstart",q))}function l(){r||(r=function(){var a;for(a=u.length;a--;)n(u[a])},c(b).on("scroll",r))}function m(){if(!s){var d=a.documentElement,e=d.clientWidth,f=d.clientHeight;s=function(){a.all&&e==d.clientWidth&&f==d.clientHeight||(e=d.clientWidth,f=d.clientHeight,w.hideAll())},c(b).on("resize",s)}}function n(a){function b(b,c){for(var d,e=0;ec&&(a.fixed(!1).layoutRect({y:a._autoFixY}).repaint(),b(!1,a._autoFixY-c)):(a._autoFixY=a.layoutRect().y,a._autoFixY').appendTo(b.getContainerElm())),d.setTimeout(function(){e.addClass(f+"in"),c(b.getEl()).addClass(f+"in")}),t=!0),o(!0,b)}}),b.on("show",function(){b.parents().each(function(a){if(a.state.get("fixed"))return b.fixed(!0),!1})}),a.popover&&(b._preBodyHtml='
    ',b.classes.add("popover").add("bottom").add(b.isRtl()?"end":"start")),b.aria("label",a.ariaLabel),b.aria("labelledby",b._id),b.aria("describedby",b.describedBy||b._id+"-none")},fixed:function(a){var b=this;if(b.state.get("fixed")!=a){if(b.state.get("rendered")){var c=e.getViewPort();a?b.layoutRect().y-=c.y:b.layoutRect().y+=c.y}b.classes.toggle("fixed",a),b.state.set("fixed",a)}return b},show:function(){var a,b=this,c=b._super();for(a=u.length;a--&&u[a]!==b;);return a===-1&&u.push(b),c},hide:function(){return p(this),o(!1,this),this._super()},hideAll:function(){w.hideAll()},close:function(){var a=this;return a.fire("close").isDefaultPrevented()||(a.remove(),o(!1,a)),a},remove:function(){p(this),this._super()},postRender:function(){var a=this;return a.settings.bodyRole&&this.getEl("body").setAttribute("role",a.settings.bodyRole),a._super()}});return w.hideAll=function(){for(var a=u.length;a--;){var b=u[a];b&&b.settings.autohide&&(b.hide(),u.splice(a,1))}},w}),g("2h",["12","14","2j","b","2k","2f","38","39","3a","3c","3d","w"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=function(a){return!(!a||b.container)},n=function(a,b,n){var o,p,q=c.DOM,r=f.getFixedToolbarContainer(a);r&&(p=q.select(r)[0]);var s=function(){if(o&&o.moveRel&&o.visible()&&!o._fixed){var b=a.selection.getScrollContainer(),c=a.getBody(),d=0,e=0;if(b){var f=q.getPos(c),g=q.getPos(b);d=Math.max(0,g.x-f.x),e=Math.max(0,g.y-f.y)}o.fixed(!1).moveRel(c,a.rtl?["tr-br","br-tr"]:["tl-bl","bl-tl","tr-br"]).moveBy(d,e)}},t=function(){o&&(o.show(),s(),q.addClass(a.getBody(),"mce-edit-focus"))},u=function(){o&&(o.hide(),l.hideAll(),q.removeClass(a.getBody(),"mce-edit-focus"))},v=function(){return o?void(o.visible()||t()):(o=b.panel=d.create({type:p?"panel":"floatpanel",role:"application",classes:"tinymce tinymce-inline",layout:"flex",direction:"column",align:"stretch",autohide:!1,autofix:m(p),fixed:m(p),border:1,items:[f.hasMenubar(a)===!1?null:{type:"menubar",border:"0 0 1 0",items:i.createMenuButtons(a)},k.createToolbars(a,f.getToolbarSize(a))]}),e.fireBeforeRenderUI(a),p?o.renderTo(p).reflow():o.renderTo().reflow(),g.addKeys(a,o),t(),h.addContextualToolbars(a),a.on("nodeChange",s),a.on("activate",t),a.on("deactivate",u),void a.nodeChanged())};return a.settings.content_editable=!0,a.on("focus",function(){f.isSkinDisabled(a)===!1&&n.skinUiCss?q.styleSheetLoader.load(n.skinUiCss,v,v):v()}),a.on("blur hide",u),a.on("remove",function(){o&&(o.remove(),o=null)}),f.isSkinDisabled(a)===!1&&n.skinUiCss?q.styleSheetLoader.load(n.skinUiCss,j.fireSkinLoaded(a)):j.fireSkinLoaded(a)(),{}};return{render:n}}),g("2b",["2o","o","2u"],function(a,b,c){"use strict";return function(d,e){var f,g,h=this,i=b.classPrefix;h.show=function(b,j){function k(){f&&(a(d).append('
    '),j&&j())}return h.hide(),f=!0,b?g=c.setTimeout(k,b):k(),h},h.hide=function(){var a=d.lastChild;return c.clearTimeout(g),a&&a.className.indexOf("throbber")!=-1&&a.parentNode.removeChild(a),f=!1,h}}}),g("2i",["2b"],function(a){var b=function(b,c){var d;b.on("ProgressState",function(b){d=d||new a(c.panel.getEl("body")),b.state?d.show(b.time):d.hide()})};return{setup:b}}),g("7",["2f","2g","2h","2i"],function(a,b,c,d){var e=function(e,f,g){var h=a.getSkinUrl(e);return h&&(g.skinUiCss=h+"/skin.min.css",e.contentCSS.push(h+"/content"+(e.inline?".inline":"")+".min.css")),d.setup(e,f),a.isInline(e)?c.render(e,f,g):b.render(e,f,g)};return{renderUI:e}}),h("2m",setTimeout),g("2d",["o","1s"],function(a,b){return a.extend({Mixins:[b],Defaults:{classes:"widget tooltip tooltip-n"},renderHtml:function(){var a=this,b=a.classPrefix;return'"},bindStates:function(){var a=this;return a.state.on("change:text",function(b){a.getEl().lastChild.innerHTML=a.encode(b.value)}),a._super()},repaint:function(){var a,b,c=this;a=c.getEl().style,b=c._layoutRect,a.left=b.x+"px",a.top=b.y+"px",a.zIndex=131070}})}),g("15",["o","2d"],function(a,b){"use strict";var c,d=a.extend({init:function(a){var b=this;b._super(a),a=b.settings,b.canFocus=!0,a.tooltip&&d.tooltips!==!1&&(b.on("mouseenter",function(c){var d=b.tooltip().moveTo(-65535);if(c.control==b){var e=d.text(a.tooltip).show().testMoveRel(b.getEl(),["bc-tc","bc-tl","bc-tr"]);d.classes.toggle("tooltip-n","bc-tc"==e),d.classes.toggle("tooltip-nw","bc-tl"==e),d.classes.toggle("tooltip-ne","bc-tr"==e),d.moveRel(b.getEl(),e)}else d.hide()}),b.on("mouseleave mousedown click",function(){b.tooltip().hide()})),b.aria("label",a.ariaLabel||a.tooltip)},tooltip:function(){return c||(c=new b({type:"tooltip"}),c.renderTo()),c},postRender:function(){var a=this,b=a.settings;a._super(),a.parent()||!b.width&&!b.height||(a.initLayoutRect(),a.repaint()),b.autofocus&&a.focus()},bindStates:function(){function a(a){c.aria("disabled",a),c.classes.toggle("disabled",a)}function b(a){c.aria("pressed",a),c.classes.toggle("active",a)}var c=this;return c.state.on("change:disabled",function(b){a(b.value)}),c.state.on("change:active",function(a){b(a.value)}),c.state.get("disabled")&&a(!0),c.state.get("active")&&b(!0),c._super()},remove:function(){this._super(),c&&(c.remove(),c=null)}});return d}),g("1x",["15"],function(a){"use strict";return a.extend({Defaults:{value:0},init:function(a){var b=this;b._super(a),b.classes.add("progress"),b.settings.filter||(b.settings.filter=function(a){return Math.round(a)})},renderHtml:function(){var a=this,b=a._id,c=this.classPrefix;return'
    0%
    '},postRender:function(){var a=this;return a._super(),a.value(a.settings.value),a},bindStates:function(){function a(a){a=b.settings.filter(a),b.getEl().lastChild.innerHTML=a+"%",b.getEl().firstChild.firstChild.style.width=a+"%"}var b=this;return b.state.on("change:value",function(b){a(b.value)}),a(b.state.get("value")),b._super()}})}),g("1t",["o","1s","1x","2u"],function(a,b,c,d){var e=function(a,b){a.getEl().lastChild.textContent=b+(a.progressBar?" "+a.progressBar.value()+"%":"")};return a.extend({Mixins:[b],Defaults:{classes:"widget notification"},init:function(a){var b=this;b._super(a),b.maxWidth=a.maxWidth,a.text&&b.text(a.text),a.icon&&(b.icon=a.icon),a.color&&(b.color=a.color),a.type&&b.classes.add("notification-"+a.type),a.timeout&&(a.timeout<0||a.timeout>0)&&!a.closeButton?b.closeButton=!1:(b.classes.add("has-close"),b.closeButton=!0),a.progressBar&&(b.progressBar=new c),b.on("click",function(a){a.target.className.indexOf(b.classPrefix+"close")!=-1&&b.close()})},renderHtml:function(){var a=this,b=a.classPrefix,c="",d="",e="",f="";return a.icon&&(c=''),f=' style="max-width: '+a.maxWidth+"px;"+(a.color?"background-color: "+a.color+';"':'"'),a.closeButton&&(d=''),a.progressBar&&(e=a.progressBar.renderHtml()),''},postRender:function(){var a=this;return d.setTimeout(function(){a.$el.addClass(a.classPrefix+"in"),e(a,a.state.get("text"))},100),a._super()},bindStates:function(){var a=this;return a.state.on("change:text",function(b){a.getEl().firstChild.innerHTML=b.value,e(a,b.value)}),a.progressBar&&(a.progressBar.bindStates(),a.progressBar.state.on("change:value",function(b){e(a,a.state.get("text"))})),a._super()},close:function(){var a=this;return a.fire("close").isDefaultPrevented()||a.remove(),a},repaint:function(){var a,b,c=this;a=c.getEl().style,b=c._layoutRect,a.left=b.x+"px",a.top=b.y+"px",a.zIndex=65534}})}),g("9",["2l","2m","c","2n","1t"],function(a,b,c,d,e){return function(f){var g=function(a){return a.inline?a.getElement():a.getContentAreaContainer()},h=function(){var a=g(f);return d.getSize(a).width},i=function(b){a.each(b,function(a){a.moveTo(0,0)})},j=function(b){if(b.length>0){var c=b.slice(0,1)[0],d=g(f);c.moveRel(d,"tc-tc"),a.each(b,function(a,c){c>0&&a.moveRel(b[c-1].getEl(),"bc-tc")})}},k=function(a){i(a),j(a)},l=function(a,d){var f=c.extend(a,{maxWidth:h()}),g=new e(f);return g.args=f,f.timeout>0&&(g.timer=b(function(){g.close(),d()},f.timeout)),g.on("close",function(){d()}),g.renderTo(),g},m=function(a){a.close()},n=function(a){return a.args};return{open:l,close:m,reposition:k,getArgs:n}}}),g("2e",["12","2m","1","2o","14","2u","2r","2n","p","w","1u"],function(a,b,c,d,e,f,g,h,i,j,k){"use strict";function l(b){var c,f="width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0",g=d("meta[name=viewport]")[0];e.overrideViewPort!==!1&&(g||(g=a.createElement("meta"),g.setAttribute("name","viewport"),a.getElementsByTagName("head")[0].appendChild(g)),c=g.getAttribute("content"),c&&"undefined"!=typeof q&&(q=c),g.setAttribute("content",b?f:q))}function m(b,c){n()&&c===!1&&d([a.documentElement,a.body]).removeClass(b+"fullscreen")}function n(){for(var a=0;aa.w&&(c=a.x-Math.max(0,b/2),e.layoutRect({w:b,x:c}),d=!0)),f&&(f.layoutRect({w:e.layoutRect().innerW}).recalc(),b=f.layoutRect().minW+a.deltaW,b>a.w&&(c=a.x-Math.max(0,b-a.w),e.layoutRect({w:b,x:c}),d=!0)),d&&e.recalc()},initLayoutRect:function(){var a,b=this,c=b._super(),d=0;if(b.settings.title&&!b._fullscreen){a=b.getEl("head");var e=h.getSize(a);c.headerW=e.width,c.headerH=e.height,d+=c.headerH}b.statusbar&&(d+=b.statusbar.layoutRect().h),c.deltaH+=d,c.minH+=d,c.h+=d;var f=h.getWindowSize();return c.x=b.settings.x||Math.max(0,f.w/2-c.w/2),c.y=b.settings.y||Math.max(0,f.h/2-c.h/2),c},renderHtml:function(){var a=this,b=a._layout,c=a._id,d=a.classPrefix,e=a.settings,f="",g="",h=e.html;return a.preRender(),b.preRender(a),e.title&&(f='
    '+a.encode(e.title)+'
    '),e.url&&(h=''),"undefined"==typeof h&&(h=b.renderHtml(a)),a.statusbar&&(g=a.statusbar.renderHtml()),'
    '+f+'
    '+h+"
    "+g+"
    "},fullscreen:function(b){var e,i,j=this,k=a.documentElement,l=j.classPrefix;if(b!=j._fullscreen)if(d(c).on("resize",function(){var a;if(j._fullscreen)if(e)j._timer||(j._timer=f.setTimeout(function(){var a=h.getWindowSize();j.moveTo(0,0).resizeTo(a.w,a.h),j._timer=0},50));else{a=(new Date).getTime();var b=h.getWindowSize();j.moveTo(0,0).resizeTo(b.w,b.h),(new Date).getTime()-a>50&&(e=!0)}}),i=j.layoutRect(),j._fullscreen=b,b){j._initial={x:i.x,y:i.y,w:i.w,h:i.h},j.borderBox=g.parseBox("0"), +j.getEl("head").style.display="none",i.deltaH-=i.headerH+2,d([k,a.body]).addClass(l+"fullscreen"),j.classes.add("fullscreen");var m=h.getWindowSize();j.moveTo(0,0).resizeTo(m.w,m.h)}else j.borderBox=g.parseBox(j.settings.border),j.getEl("head").style.display="",i.deltaH+=i.headerH,d([k,a.body]).removeClass(l+"fullscreen"),j.classes.remove("fullscreen"),j.moveTo(j._initial.x,j._initial.y).resizeTo(j._initial.w,j._initial.h);return j.reflow()},postRender:function(){var a,c=this;b(function(){c.classes.add("in"),c.fire("open")},0),c._super(),c.statusbar&&c.statusbar.postRender(),c.focus(),this.dragHelper=new i(c._id+"-dragh",{start:function(){a={x:c.layoutRect().x,y:c.layoutRect().y}},drag:function(b){c.moveTo(a.x+b.deltaX,a.y+b.deltaY)}}),c.on("submit",function(a){a.isDefaultPrevented()||c.close()}),p.push(c),l(!0)},submit:function(){return this.fire("submit",{data:this.toJSON()})},remove:function(){var a,b=this;for(b.dragHelper.destroy(),b._super(),b.statusbar&&this.statusbar.remove(),m(b.classPrefix,!1),a=p.length;a--;)p[a]===b&&p.splice(a,1);l(p.length>0)},getContentWindow:function(){var a=this.getEl().getElementsByTagName("iframe")[0];return a?a.contentWindow:null}});return o(),r}),g("1r",["12","2e"],function(a,b){"use strict";var c=b.extend({init:function(a){a={border:1,padding:20,layout:"flex",pack:"center",align:"center",containerCls:"panel",autoScroll:!0,buttons:{type:"button",text:"Ok",action:"ok"},items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200}},this._super(a)},Statics:{OK:1,OK_CANCEL:2,YES_NO:3,YES_NO_CANCEL:4,msgBox:function(d){function e(a,b,c){return{type:"button",text:a,subtype:c?"primary":"",onClick:function(a){a.control.parents()[1].close(),g(b)}}}var f,g=d.callback||function(){};switch(d.buttons){case c.OK_CANCEL:f=[e("Ok",!0,!0),e("Cancel",!1)];break;case c.YES_NO:case c.YES_NO_CANCEL:f=[e("Yes",1,!0),e("No",0)],d.buttons==c.YES_NO_CANCEL&&f.push(e("Cancel",-1));break;default:f=[e("Ok",!0,!0)]}return new b({padding:20,x:d.x,y:d.y,minWidth:300,minHeight:100,layout:"flex",pack:"center",align:"center",buttons:f,title:d.title,role:"alertdialog",items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200,text:d.text},onPostRender:function(){this.aria("describedby",this.items()[0]._id)},onClose:d.onClose,onCancel:function(){g(!1)}}).renderTo(a.body).reflow()},alert:function(a,b){return"string"==typeof a&&(a={text:a}),a.callback=b,c.msgBox(a)},confirm:function(a,b){return"string"==typeof a&&(a={text:a}),a.callback=b,a.buttons=c.OK_CANCEL,c.msgBox(a)}}});return c}),g("a",["2e","1r"],function(a,b){return function(c){var d=function(b,c,d){var e;return b.title=b.title||" ",b.url=b.url||b.file,b.url&&(b.width=parseInt(b.width||320,10),b.height=parseInt(b.height||240,10)),b.body&&(b.items={defaults:b.defaults,type:b.bodyType||"form",items:b.body,data:b.data,callbacks:b.commands}),b.url||b.buttons||(b.buttons=[{text:"Ok",subtype:"primary",onclick:function(){e.find("form")[0].submit()}},{text:"Cancel",onclick:function(){e.close()}}]),e=new a(b),e.on("close",function(){d(e)}),b.data&&e.on("postRender",function(){this.find("*").each(function(a){var c=a.name();c in b.data&&a.value(b.data[c])})}),e.features=b||{},e.params=c||{},e=e.renderTo().reflow()},e=function(a,c,d){var e;return e=b.alert(a,function(){c()}),e.on("close",function(){d(e)}),e},f=function(a,c,d){var e;return e=b.confirm(a,function(a){c(a)}),e.on("close",function(){d(e)}),e},g=function(a){a.close()},h=function(a){return a.params},i=function(a,b){a.params=b};return{open:d,alert:e,confirm:f,close:g,getParams:h,setParams:i}}}),g("3",["7","8","9","a"],function(a,b,c,d){var e=function(e){var f=function(b){return a.renderUI(e,this,b)},g=function(a,c){return b.resizeTo(e,a,c)},h=function(a,c){return b.resizeBy(e,a,c)},i=function(){return c(e)},j=function(){return d(e)};return{renderUI:f,resizeTo:g,resizeBy:h,getNotificationManagerImpl:i,getWindowManagerImpl:j}};return{get:e}}),g("1l",["2p","c"],function(a,b){"use strict";return a.extend({Defaults:{firstControlClass:"first",lastControlClass:"last"},init:function(a){this.settings=b.extend({},this.Defaults,a)},preRender:function(a){a.bodyClasses.add(this.settings.containerClass)},applyClasses:function(a){var b,c,d,e,f=this,g=f.settings;b=g.firstControlClass,c=g.lastControlClass,a.each(function(a){a.classes.remove(b).remove(c).add(g.controlClass),a.visible()&&(d||(d=a),e=a)}),d&&d.classes.add(b),e&&e.classes.add(c)},renderHtml:function(a){var b=this,c="";return b.applyClasses(a.items()),a.items().each(function(a){c+=a.renderHtml()}),c},recalc:function(){},postRender:function(){},isNative:function(){return!1}})}),g("d",["1l"],function(a){"use strict";return a.extend({Defaults:{containerClass:"abs-layout",controlClass:"abs-layout-item"},recalc:function(a){a.items().filter(":visible").each(function(a){var b=a.settings;a.layoutRect({x:b.x,y:b.y,w:b.w,h:b.h}),a.recalc&&a.recalc()})},renderHtml:function(a){return'
    '+this._super(a)}})}),g("f",["12","1","15"],function(a,b,c){"use strict";return c.extend({Defaults:{classes:"widget btn",role:"button"},init:function(a){var b,c=this;c._super(a),a=c.settings,b=c.settings.size,c.on("click mousedown",function(a){a.preventDefault()}),c.on("touchstart",function(a){c.fire("click",a),a.preventDefault()}),a.subtype&&c.classes.add(a.subtype),b&&c.classes.add("btn-"+b),a.icon&&c.icon(a.icon)},icon:function(a){return arguments.length?(this.state.set("icon",a),this):this.state.get("icon")},repaint:function(){var a,b=this.getEl().firstChild;b&&(a=b.style,a.width=a.height="100%"),this._super()},renderHtml:function(){var a,c,d=this,e=d._id,f=d.classPrefix,g=d.state.get("icon"),h=d.state.get("text"),i="",j=d.settings;return a=j.image,a?(g="none","string"!=typeof a&&(a=b.getSelection?a[0]:a[1]),a=" style=\"background-image: url('"+a+"')\""):a="",h&&(d.classes.add("btn-has-text"),i=''+d.encode(h)+""),g=g?f+"ico "+f+"i-"+g:"",c="boolean"==typeof j.active?' aria-pressed="'+j.active+'"':"",'
    "},bindStates:function(){function b(a){var b=d("span."+e,c.getEl());a?(b[0]||(d("button:first",c.getEl()).append(''),b=d("span."+e,c.getEl())),b.html(c.encode(a))):b.remove(),c.classes.toggle("btn-has-text",!!a)}var c=this,d=c.$,e=c.classPrefix+"txt";return c.state.on("change:text",function(a){b(a.value)}),c.state.on("change:icon",function(d){var e=d.value,f=c.classPrefix;c.settings.icon=e,e=e?f+"ico "+f+"i-"+c.settings.icon:"";var g=c.getEl().firstChild,h=g.getElementsByTagName("i")[0];e?(h&&h==g.firstChild||(h=a.createElement("i"),g.insertBefore(h,g.firstChild)),h.className=e):h&&g.removeChild(h),b(c.state.get("text"))}),c._super()}})}),h("2v",RegExp),g("e",["f","c","2n","2o","2v"],function(a,b,c,d,e){return a.extend({init:function(a){var c=this;a=b.extend({text:"Browse...",multiple:!1,accept:null},a),c._super(a),c.classes.add("browsebutton"),a.multiple&&c.classes.add("multiple")},postRender:function(){var a=this,b=c.create("input",{type:"file",id:a._id+"-browse",accept:a.settings.accept});a._super(),d(b).on("change",function(b){var c=b.target.files;a.value=function(){return c.length?a.settings.multiple?c:c[0]:null},b.preventDefault(),c.length&&a.fire("change",b)}),d(b).on("click",function(a){a.stopPropagation()}),d(a.getEl("button")).on("click",function(a){a.stopPropagation(),b.click()}),a.getEl().appendChild(b)},remove:function(){d(this.getEl("button")).off(),d(this.getEl("input")).off(),this._super()}})}),g("g",["n"],function(a){"use strict";return a.extend({Defaults:{defaultType:"button",role:"group"},renderHtml:function(){var a=this,b=a._layout;return a.classes.add("btn-group"),a.preRender(),b.preRender(a),'
    '+(a.settings.html||"")+b.renderHtml(a)+"
    "}})}),g("h",["12","15"],function(a,b){"use strict";return b.extend({Defaults:{classes:"checkbox",role:"checkbox",checked:!1},init:function(a){var b=this;b._super(a),b.on("click mousedown",function(a){a.preventDefault()}),b.on("click",function(a){a.preventDefault(),b.disabled()||b.checked(!b.checked())}),b.checked(b.settings.checked)},checked:function(a){return arguments.length?(this.state.set("checked",a),this):this.state.get("checked")},value:function(a){return arguments.length?this.checked(a):this.checked()},renderHtml:function(){var a=this,b=a._id,c=a.classPrefix;return'
    '+a.encode(a.state.get("text"))+"
    "},bindStates:function(){function b(a){c.classes.toggle("checked",a),c.aria("checked",a)}var c=this;return c.state.on("change:text",function(a){c.getEl("al").firstChild.data=c.translate(a.value)}),c.state.on("change:checked change:value",function(a){c.fire("change"),b(a.value)}),c.state.on("change:icon",function(b){var d=b.value,e=c.classPrefix;if("undefined"==typeof d)return c.settings.icon;c.settings.icon=d,d=d?e+"ico "+e+"i-"+c.settings.icon:"";var f=c.getEl().firstChild,g=f.getElementsByTagName("i")[0];d?(g&&g==f.firstChild||(g=a.createElement("i"),f.insertBefore(g,f.firstChild)),g.className=d):g&&f.removeChild(g)}),c.state.get("checked")&&b(!0),c._super()}})}),g("2w",["6"],function(a){return a("tinymce.util.VK")}),g("m",["12","2o","b","c","2w","2n","15"],function(a,b,c,d,e,f,g){"use strict";return g.extend({init:function(a){var c=this;c._super(a),a=c.settings,c.classes.add("combobox"),c.subinput=!0,c.ariaTarget="inp",a.menu=a.menu||a.values,a.menu&&(a.icon="caret"),c.on("click",function(d){var e=d.target,f=c.getEl();if(b.contains(f,e)||e==f)for(;e&&e!=f;)e.id&&e.id.indexOf("-open")!=-1&&(c.fire("action"),a.menu&&(c.showMenu(),d.aria&&c.menu.items()[0].focus())),e=e.parentNode}),c.on("keydown",function(a){var b;13==a.keyCode&&"INPUT"===a.target.nodeName&&(a.preventDefault(),c.parents().reverse().each(function(a){if(a.toJSON)return b=a,!1}),c.fire("submit",{data:b.toJSON()}))}),c.on("keyup",function(a){if("INPUT"==a.target.nodeName){var b=c.state.get("value"),d=a.target.value;d!==b&&(c.state.set("value",d),c.fire("autocomplete",a))}}),c.on("mouseover",function(a){var b=c.tooltip().moveTo(-65535);if(c.statusLevel()&&a.target.className.indexOf(c.classPrefix+"status")!==-1){var d=c.statusMessage()||"Ok",e=b.text(d).show().testMoveRel(a.target,["bc-tc","bc-tl","bc-tr"]);b.classes.toggle("tooltip-n","bc-tc"==e),b.classes.toggle("tooltip-nw","bc-tl"==e),b.classes.toggle("tooltip-ne","bc-tr"==e),b.moveRel(a.target,e)}})},statusLevel:function(a){return arguments.length>0&&this.state.set("statusLevel",a),this.state.get("statusLevel")},statusMessage:function(a){return arguments.length>0&&this.state.set("statusMessage",a),this.state.get("statusMessage")},showMenu:function(){var a,b=this,d=b.settings;b.menu||(a=d.menu||[],a.length?a={type:"menu",items:a}:a.type=a.type||"menu",b.menu=c.create(a).parent(b).renderTo(b.getContainerElm()),b.fire("createmenu"),b.menu.reflow(),b.menu.on("cancel",function(a){a.control===b.menu&&b.focus()}),b.menu.on("show hide",function(a){a.control.items().each(function(a){a.active(a.value()==b.value())})}).fire("show"),b.menu.on("select",function(a){b.value(a.control.value())}),b.on("focusin",function(a){"INPUT"==a.target.tagName.toUpperCase()&&b.menu.hide()}),b.aria("expanded",!0)),b.menu.show(),b.menu.layoutRect({w:b.layoutRect().w}),b.menu.moveRel(b.getEl(),b.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"])},focus:function(){this.getEl("inp").focus()},repaint:function(){var c,d,e=this,g=e.getEl(),h=e.getEl("open"),i=e.layoutRect(),j=0,k=g.firstChild;e.statusLevel()&&"none"!==e.statusLevel()&&(j=parseInt(f.getRuntimeStyle(k,"padding-right"),10)-parseInt(f.getRuntimeStyle(k,"padding-left"),10)),c=h?i.w-f.getSize(h).width-10:i.w-10;var l=a;return l.all&&(!l.documentMode||l.documentMode<=8)&&(d=e.layoutRect().h-2+"px"),b(k).css({width:c-j,lineHeight:d}),e._super(),e},postRender:function(){var a=this;return b(this.getEl("inp")).on("change",function(b){a.state.set("value",b.target.value),a.fire("change",b)}),a._super()},renderHtml:function(){var a,b,c=this,d=c._id,e=c.settings,f=c.classPrefix,g=c.state.get("value")||"",h="",i="",j="";return"spellcheck"in e&&(i+=' spellcheck="'+e.spellcheck+'"'),e.maxLength&&(i+=' maxlength="'+e.maxLength+'"'),e.size&&(i+=' size="'+e.size+'"'),e.subtype&&(i+=' type="'+e.subtype+'"'),j='',c.disabled()&&(i+=' disabled="disabled"'),a=e.icon,a&&"caret"!=a&&(a=f+"ico "+f+"i-"+e.icon),b=c.state.get("text"),(a||b)&&(h='
    ",c.classes.add("has-open")),'
    '+j+h+"
    "},value:function(a){return arguments.length?(this.state.set("value",a),this):(this.state.get("rendered")&&this.state.set("value",this.getEl("inp").value),this.state.get("value"))},showAutoComplete:function(a,b){var e=this;if(0===a.length)return void e.hideMenu();var f=function(a,b){return function(){e.fire("selectitem",{title:b,value:a})}};e.menu?e.menu.items().remove():e.menu=c.create({type:"menu",classes:"combobox-menu",layout:"flow"}).parent(e).renderTo(),d.each(a,function(a){e.menu.add({text:a.title,url:a.previewUrl,match:b,classes:"menu-item-ellipsis",onclick:f(a.value,a.title)})}),e.menu.renderNew(),e.hideMenu(),e.menu.on("cancel",function(a){a.control.parent()===e.menu&&(a.stopPropagation(),e.focus(),e.hideMenu())}),e.menu.on("select",function(){e.focus()});var g=e.layoutRect().w;e.menu.layoutRect({w:g,minW:0,maxW:g}),e.menu.reflow(),e.menu.show(),e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"])},hideMenu:function(){this.menu&&this.menu.hide()},bindStates:function(){var a=this;a.state.on("change:value",function(b){a.getEl("inp").value!=b.value&&(a.getEl("inp").value=b.value)}),a.state.on("change:disabled",function(b){a.getEl("inp").disabled=b.value}),a.state.on("change:statusLevel",function(b){var c=a.getEl("status"),d=a.classPrefix,e=b.value;f.css(c,"display","none"===e?"none":""),f.toggleClass(c,d+"i-checkmark","ok"===e),f.toggleClass(c,d+"i-warning","warn"===e),f.toggleClass(c,d+"i-error","error"===e),a.classes.toggle("has-status","none"!==e),a.repaint()}),f.on(a.getEl("status"),"mouseleave",function(){a.tooltip().hide()}),a.on("cancel",function(b){a.menu&&a.menu.visible()&&(b.stopPropagation(),a.hideMenu())});var b=function(a,b){b&&b.items().length>0&&b.items().eq(a)[0].focus()};return a.on("keydown",function(c){var d=c.keyCode;"INPUT"===c.target.nodeName&&(d===e.DOWN?(c.preventDefault(),a.fire("autocomplete"),b(0,a.menu)):d===e.UP&&(c.preventDefault(),b(-1,a.menu)))}),a._super()},remove:function(){b(this.getEl("inp")).off(),this.menu&&this.menu.remove(),this._super()}})}),g("j",["m"],function(a){"use strict";return a.extend({init:function(a){var b=this;a.spellcheck=!1,a.onaction&&(a.icon="none"),b._super(a),b.classes.add("colorbox"),b.on("change keyup postrender",function(){b.repaintColor(b.value())})},repaintColor:function(a){var b=this.getEl("open"),c=b?b.getElementsByTagName("i")[0]:null;if(c)try{c.style.background=a}catch(a){}},bindStates:function(){var a=this;return a.state.on("change:value",function(b){a.state.get("rendered")&&a.repaintColor(b.value)}),a._super()}})}),g("1v",["f","w"],function(a,b){"use strict";return a.extend({showPanel:function(){var a=this,c=a.settings;if(a.classes.add("opened"),a.panel)a.panel.show();else{var d=c.panel;d.type&&(d={layout:"grid",items:d}),d.role=d.role||"dialog",d.popover=!0,d.autohide=!0,d.ariaRoot=!0,a.panel=new b(d).on("hide",function(){a.classes.remove("opened")}).on("cancel",function(b){b.stopPropagation(),a.focus(),a.hidePanel()}).parent(a).renderTo(a.getContainerElm()),a.panel.fire("show"),a.panel.reflow()}var e=a.panel.testMoveRel(a.getEl(),c.popoverAlign||(a.isRtl()?["bc-tc","bc-tl","bc-tr"]:["bc-tc","bc-tr","bc-tl"]));a.panel.classes.toggle("start","bc-tl"===e),a.panel.classes.toggle("end","bc-tr"===e),a.panel.moveRel(a.getEl(),e)},hidePanel:function(){var a=this;a.panel&&a.panel.hide()},postRender:function(){var a=this;return a.aria("haspopup",!0),a.on("click",function(b){b.control===a&&(a.panel&&a.panel.visible()?a.hidePanel():(a.showPanel(),a.panel.focus(!!b.aria)))}),a._super()},remove:function(){return this.panel&&(this.panel.remove(),this.panel=null),this._super()}})}),g("k",["1v","2j"],function(a,b){"use strict";var c=b.DOM;return a.extend({init:function(a){this._super(a),this.classes.add("splitbtn"),this.classes.add("colorbutton")},color:function(a){return a?(this._color=a,this.getEl("preview").style.backgroundColor=a,this):this._color},resetColor:function(){return this._color=null,this.getEl("preview").style.backgroundColor=null,this},renderHtml:function(){var a=this,b=a._id,c=a.classPrefix,d=a.state.get("text"),e=a.settings.icon?c+"ico "+c+"i-"+a.settings.icon:"",f=a.settings.image?" style=\"background-image: url('"+a.settings.image+"')\"":"",g="";return d&&(a.classes.add("btn-has-text"),g=''+a.encode(d)+""),'
    '},postRender:function(){var a=this,b=a.settings.onclick;return a.on("click",function(d){d.aria&&"down"===d.aria.key||d.control!=a||c.getParent(d.target,"."+a.classPrefix+"open")||(d.stopImmediatePropagation(),b.call(a,d))}),delete a.settings.onclick,a._super()}})}),g("2x",["6"],function(a){return a("tinymce.util.Color")}),g("l",["15","p","2n","2x"],function(a,b,c,d){"use strict";return a.extend({Defaults:{classes:"widget colorpicker"},init:function(a){this._super(a)},postRender:function(){function a(a,b){var d,e,f=c.getPos(a);return d=b.pageX-f.x,e=b.pageY-f.y,d=Math.max(0,Math.min(d/a.clientWidth,1)),e=Math.max(0,Math.min(e/a.clientHeight,1)),{x:d,y:e}}function e(a,b){var e=(360-a.h)/360;c.css(j,{top:100*e+"%"}),b||c.css(l,{left:a.s+"%",top:100-a.v+"%"}),k.style.background=new d({s:100,v:100,h:a.h}).toHex(),m.color().parse({s:a.s,v:a.v,h:a.h})}function f(b){var c;c=a(k,b),h.s=100*c.x,h.v=100*(1-c.y),e(h),m.fire("change")}function g(b){var c;c=a(i,b),h=n.toHsv(),h.h=360*(1-c.y),e(h,!0),m.fire("change")}var h,i,j,k,l,m=this,n=m.color();i=m.getEl("h"),j=m.getEl("hp"),k=m.getEl("sv"),l=m.getEl("svp"),m._repaint=function(){h=n.toHsv(),e(h)},m._super(),m._svdraghelper=new b(m._id+"-sv",{start:f,drag:f}),m._hdraghelper=new b(m._id+"-h",{start:g,drag:g}),m._repaint()},rgb:function(){return this.color().toRgb()},value:function(a){var b=this;return arguments.length?(b.color().parse(a),void(b._rendered&&b._repaint())):b.color().toHex()},color:function(){return this._color||(this._color=new d),this._color},renderHtml:function(){function a(){var a,b,c,d,g="";for(c="filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=",d=f.split(","),a=0,b=d.length-1;a';return g}var b,c=this,d=c._id,e=c.classPrefix,f="#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000",g="background: -ms-linear-gradient(top,"+f+");background: linear-gradient(to bottom,"+f+");";return b='
    '+a()+'
    ','
    '+b+"
    "}})}),g("q",["15","c","2n","2v"],function(a,b,c,d){return a.extend({init:function(a){var c=this;a=b.extend({height:100,text:"Drop an image here",multiple:!1,accept:null},a),c._super(a),c.classes.add("dropzone"),a.multiple&&c.classes.add("multiple")},renderHtml:function(){var a,b,d=this,e=d.settings;return a={id:d._id,hidefocus:"1"},b=c.create("div",a,""+this.translate(e.text)+""),e.height&&c.css(b,"height",e.height+"px"),e.width&&c.css(b,"width",e.width+"px"),b.className=d.classes,b.outerHTML},postRender:function(){var a=this,c=function(b){b.preventDefault(),a.classes.toggle("dragenter"),a.getEl().className=a.classes},e=function(c){var e=a.settings.accept;if("string"!=typeof e)return c;var f=new d("("+e.split(/\s*,\s*/).join("|")+")$","i");return b.grep(c,function(a){return f.test(a.name)})};a._super(),a.$el.on("dragover",function(a){a.preventDefault()}),a.$el.on("dragenter",c),a.$el.on("dragleave",c),a.$el.on("drop",function(b){if(b.preventDefault(),!a.state.get("disabled")){var c=e(b.dataTransfer.files);a.value=function(){return c.length?a.settings.multiple?c:c[0]:null},c.length&&a.fire("change",b)}})},remove:function(){this.$el.off(),this._super()}})}),g("1w",["15"],function(a){"use strict";return a.extend({init:function(a){var b=this;a.delimiter||(a.delimiter="\xbb"),b._super(a),b.classes.add("path"),b.canFocus=!0,b.on("click",function(a){var c,d=a.target;(c=d.getAttribute("data-index"))&&b.fire("select",{value:b.row()[c],index:c})}),b.row(b.settings.row)},focus:function(){var a=this;return a.getEl().firstChild.focus(),a},row:function(a){return arguments.length?(this.state.set("row",a),this):this.state.get("row")},renderHtml:function(){var a=this;return'
    '+a._getDataPathHtml(a.state.get("row"))+"
    "},bindStates:function(){var a=this;return a.state.on("change:row",function(b){a.innerHtml(a._getDataPathHtml(b.value))}),a._super()},_getDataPathHtml:function(a){var b,c,d=this,e=a||[],f="",g=d.classPrefix;for(b=0,c=e.length;b0?'":"")+'
    '+e[b].name+"
    ";return f||(f='
    \xa0
    '),f}})}),g("r",["1w"],function(a){return a.extend({postRender:function(){function a(a){if(1===a.nodeType){if("BR"==a.nodeName||a.getAttribute("data-mce-bogus"))return!0;if("bookmark"===a.getAttribute("data-mce-type"))return!0}return!1}var b=this,c=b.settings.editor;return c.settings.elementpath!==!1&&(b.on("select",function(a){c.focus(),c.selection.select(this.row()[a.index].element),c.nodeChanged()}),c.on("nodeChange",function(d){for(var e=[],f=d.parents,g=f.length;g--;)if(1==f[g].nodeType&&!a(f[g])){var h=c.fire("ResolveName",{name:f[g].nodeName.toLowerCase(),target:f[g]});if(h.isDefaultPrevented()||e.push({name:h.name,element:f[g]}),h.isPropagationStopped())break}b.row(e)})),b._super()}})}),g("1f",["n"],function(a){"use strict";return a.extend({Defaults:{layout:"flex",align:"center",defaults:{flex:1}},renderHtml:function(){var a=this,b=a._layout,c=a.classPrefix;return a.classes.add("formitem"),b.preRender(a),'
    '+(a.settings.title?'
    '+a.settings.title+"
    ":"")+'
    '+(a.settings.html||"")+b.renderHtml(a)+"
    "}})}),g("y",["n","1f","c"],function(a,b,c){"use strict";return a.extend({Defaults:{containerCls:"form",layout:"flex",direction:"column",align:"stretch",flex:1,padding:15,labelGap:30,spacing:10,callbacks:{submit:function(){this.submit()}}},preRender:function(){var a=this,d=a.items();a.settings.formItemDefaults||(a.settings.formItemDefaults={layout:"flex",autoResize:"overflow",defaults:{flex:1}}),d.each(function(d){var e,f=d.settings.label;f&&(e=new b(c.extend({items:{type:"label",id:d._id+"-l",text:f,flex:0,forId:d._id,disabled:d.disabled()}},a.settings.formItemDefaults)),e.type="formitem",d.aria("labelledby",d._id+"-l"),"undefined"==typeof d.settings.flex&&(d.settings.flex=1),a.replace(d,e),e.add(d))})},submit:function(){return this.fire("submit",{data:this.toJSON()})},postRender:function(){var a=this;a._super(),a.fromJSON(a.settings.data)},bindStates:function(){function a(){var a,c,d,e=0,f=[];if(b.settings.labelGapCalc!==!1)for(d="children"==b.settings.labelGapCalc?b.find("formitem"):b.items(),d.filter("formitem").each(function(a){var b=a.items()[0],c=b.getEl().clientWidth;e=c>e?c:e,f.push(b)}),c=b.settings.labelGap||0,a=f.length;a--;)f[a].settings.minWidth=e+c}var b=this;b._super(),b.on("show",a),a()}})}),g("s",["y"],function(a){"use strict";return a.extend({Defaults:{containerCls:"fieldset",layout:"flex",direction:"column",align:"stretch",flex:1,padding:"25 15 5 15",labelGap:30,spacing:10,border:1},renderHtml:function(){var a=this,b=a._layout,c=a.classPrefix;return a.preRender(),b.preRender(a),'
    '+(a.settings.title?''+a.settings.title+"":"")+'
    '+(a.settings.html||"")+b.renderHtml(a)+"
    "}})}),h("3s",Date),h("3t",Math),g("3i",["3s","3t","3h"],function(a,b,c){var d=0,e=function(e){var f=new a,g=f.getTime(),h=b.floor(1e9*b.random());return d++,e+"_"+h+d+c(g)};return{generate:e}}),g("31",[],function(){return"undefined"==typeof console&&(console={log:function(){}}),console}),g("10",["z","2z","31","12"],function(a,b,c,d){var e=function(a,b){var e=b||d,f=e.createElement("div");if(f.innerHTML=a,!f.hasChildNodes()||f.childNodes.length>1)throw c.error("HTML does not have a single root node",a),"HTML must have a single root node";return h(f.childNodes[0])},f=function(a,b){var c=b||d,e=c.createElement(a);return h(e)},g=function(a,b){var c=b||d,e=c.createTextNode(a);return h(e)},h=function(c){if(null===c||void 0===c)throw new b("Node cannot be null or undefined");return{dom:a.constant(c)}};return{fromHtml:e,fromTag:f,fromText:g,fromDom:h}}),g("3v",[],function(){var a=function(a){var b,c=!1;return function(){return c||(c=!0,b=a.apply(null,arguments)),b}};return{cached:a}}),g("3n",[],function(){return{ATTRIBUTE:2,CDATA_SECTION:4,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,ELEMENT:1,TEXT:3,PROCESSING_INSTRUCTION:7,ENTITY_REFERENCE:5,ENTITY:6,NOTATION:12}}),g("3o",["3n"],function(a){var b=function(a){var b=a.dom().nodeName;return b.toLowerCase()},c=function(a){return a.dom().nodeType},d=function(a){return a.dom().nodeValue},e=function(a){return function(b){return c(b)===a}},f=function(d){return c(d)===a.COMMENT||"#comment"===b(d)},g=e(a.ELEMENT),h=e(a.TEXT),i=e(a.DOCUMENT);return{name:b,type:c,value:d,isElement:g,isText:h,isDocument:i,isComment:f}}),g("3l",["3v","10","3o","12"],function(a,b,c,d){var e=function(a){var b=c.isText(a)?a.dom().parentNode:a.dom();return void 0!==b&&null!==b&&b.ownerDocument.body.contains(b)},f=a.cached(function(){return g(b.fromDom(d))}),g=function(a){var c=a.dom().body;if(null===c||void 0===c)throw"Body is not available yet";return b.fromDom(c)};return{body:f,getBody:g,inBody:e}}),g("3k",["2y","3h"],function(a,b){var c=function(c){if(null===c)return"null";var d=typeof c;return"object"===d&&a.prototype.isPrototypeOf(c)?"array":"object"===d&&b.prototype.isPrototypeOf(c)?"string":d},d=function(a){return function(b){return c(b)===a}};return{isString:d("string"),isObject:d("object"),isArray:d("array"),isNull:d("null"),isBoolean:d("boolean"),isUndefined:d("undefined"),isFunction:d("function"),isNumber:d("number")}}),g("4a",["2l","z","2y","2z"],function(a,b,c,d){return function(){var e=arguments;return function(){for(var f=new c(arguments.length),g=0;g0&&e.unsuppMessage(m);var n={};return a.each(h,function(a){n[a]=b.constant(f[a])}),a.each(i,function(a){n[a]=b.constant(g.prototype.hasOwnProperty.call(f,a)?d.some(f[a]):d.none())}),n}}}),g("42",["4a","4b"],function(a,b){return{immutable:a,immutableBag:b}}),g("43",[],function(){var a=function(a,b){var c=[],d=function(a){return c.push(a),b(a)},e=b(a);do e=e.bind(d);while(e.isSome());return c};return{toArray:a}}),g("4c",[],function(){return"undefined"!=typeof window?window:Function("return this;")()}),g("44",["4c"],function(a){var b=function(b,c){for(var d=void 0!==c?c:a,e=0;e0&&b0},C=function(b){var c=A(b);return a.filter(y(c).concat(z(c)),B)};return{find:C}}),g("t",["2l","z","1","30","13","m","c"],function(a,b,c,d,e,f,g){"use strict";var h=function(){return c.tinymce?c.tinymce.activeEditor:e.activeEditor},i={},j=5,k=function(){i={}},l=function(a){return{title:a.title,value:{title:{raw:a.title},url:a.url,attach:a.attach}}},m=function(a){return g.map(a,l)},n=function(a,c){return{title:a,value:{title:a,url:c,attach:b.noop}}},o=function(b,c){var d=a.exists(c,function(a){return a.url===b});return!d},p=function(a,b,c){var d=b in a?a[b]:c;return d===!1?null:d},q=function(c,d,e,f){var h={title:"-"},j=function(c){var f=c.hasOwnProperty(e)?c[e]:[],h=a.filter(f,function(a){return o(a,d)});return g.map(h,function(a){return{title:a,value:{title:a,url:a,attach:b.noop}}})},k=function(b){var c=a.filter(d,function(a){return a.type===b});return m(c)},l=function(){var a=k("anchor"),b=p(f,"anchor_top","#top"),c=p(f,"anchor_bottom","#bottom");return null!==b&&a.unshift(n("",b)),null!==c&&a.push(n("",c)),a},q=function(b){return a.foldl(b,function(a,b){var c=0===a.length||0===b.length;return c?a.concat(b):a.concat(h,b)},[])};return f.typeahead_urls===!1?[]:"file"===e?q([s(c,j(i)),s(c,k("header")),s(c,l())]):s(c,j(i))},r=function(b,c){var d=i[c];/^https?/.test(b)&&(d?a.indexOf(d,b)===-1&&(i[c]=d.slice(0,j).concat(b)):i[c]=[b])},s=function(a,b){var c=a.toLowerCase(),d=g.grep(b,function(a){return a.title.toLowerCase().indexOf(c)!==-1});return 1===d.length&&d[0].title===a?[]:d},t=function(a){var b=a.title;return b.raw?b.raw:b},u=function(a,b,c,e){var f=function(f){var g=d.find(c),h=q(f,g,e,b);a.showAutoComplete(h,f)};a.on("autocomplete",function(){f(a.value())}),a.on("selectitem",function(b){var c=b.value;a.value(c.url);var d=t(c);"image"===e?a.fire("change",{meta:{alt:d,attach:c.attach}}):a.fire("change",{meta:{text:d,attach:c.attach}}),a.focus()}),a.on("click",function(b){0===a.value().length&&"INPUT"===b.target.nodeName&&f("")}),a.on("PostRender",function(){a.getRoot().on("submit",function(b){b.isDefaultPrevented()||r(a.value(),e)})})},v=function(a){var b=a.status,c=a.message;return"valid"===b?{status:"ok",message:c}:"unknown"===b?{status:"warn",message:c}:"invalid"===b?{status:"warn",message:c}:{status:"none",message:""}},w=function(a,b,c){var d=b.filepicker_validator_handler;if(d){var e=function(b){return 0===b.length?void a.statusLevel("none"):void d({url:b,type:c},function(b){var c=v(b);a.statusMessage(c.message),a.statusLevel(c.status)})};a.state.on("change:value",function(a){e(a.value)})}};return f.extend({Statics:{clearHistory:k},init:function(a){var b,d,e,f=this,i=h(),j=i.settings,k=a.filetype;a.spellcheck=!1,e=j.file_picker_types||j.file_browser_callback_types,e&&(e=g.makeMap(e,/[, ]/)),e&&!e[k]||(d=j.file_picker_callback,!d||e&&!e[k]?(d=j.file_browser_callback,!d||e&&!e[k]||(b=function(){d(f.getEl("inp").id,f.value(),k,c)})):b=function(){var a=f.fire("beforecall").meta;a=g.extend({filetype:k},a),d.call(i,function(a,b){f.value(a).fire("change",{meta:b})},f.value(),a)}),b&&(a.icon="browse",a.onaction=b),f._super(a),u(f,j,i.getBody(),k),w(f,j,k)}})}),g("u",["d"],function(a){"use strict";return a.extend({recalc:function(a){var b=a.layoutRect(),c=a.paddingBox;a.items().filter(":visible").each(function(a){a.layoutRect({x:c.left,y:c.top,w:b.innerW-c.right-c.left,h:b.innerH-c.top-c.bottom}),a.recalc&&a.recalc()})}})}),g("v",["d"],function(a){"use strict";return a.extend({recalc:function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N=[],O=Math.max,P=Math.min;for(d=a.items().filter(":visible"),e=a.layoutRect(),f=a.paddingBox,g=a.settings,m=a.isRtl()?g.direction||"row-reversed":g.direction,h=g.align,i=a.isRtl()?g.pack||"end":g.pack,j=g.spacing||0,"row-reversed"!=m&&"column-reverse"!=m||(d=d.set(d.toArray().reverse()),m=m.split("-")[0]),"column"==m?(z="y",x="h",y="minH",A="maxH",C="innerH",B="top",D="deltaH",E="contentH",J="left",H="w",F="x",G="innerW",I="minW",K="right",L="deltaW",M="contentW"):(z="x",x="w",y="minW",A="maxW",C="innerW",B="left",D="deltaW",E="contentW",J="top",H="h",F="y",G="innerH",I="minH",K="bottom",L="deltaH",M="contentH"),l=e[C]-f[B]-f[B],w=k=0,b=0,c=d.length;b0&&(k+=q,o[A]&&N.push(n),o.flex=q),l-=o[y],r=f[J]+o[I]+f[K],r>w&&(w=r);if(u={},l<0?u[y]=e[y]-l+e[D]:u[y]=e[C]-l+e[D],u[I]=w+e[L],u[E]=e[C]-l,u[M]=w,u.minW=P(u.minW,e.maxW),u.minH=P(u.minH,e.maxH),u.minW=O(u.minW,e.startMinWidth),u.minH=O(u.minH,e.startMinHeight),!e.autoResize||u.minW==e.minW&&u.minH==e.minH){for(t=l/k,b=0,c=N.length;bs?(l-=o[A]-o[y],k-=o.flex,o.flex=0,o.maxFlexSize=s):o.maxFlexSize=0;for(t=l/k,v=f[B],u={},0===k&&("end"==i?v=l+f[B]:"center"==i?(v=Math.round(e[C]/2-(e[C]-l)/2)+f[B],v<0&&(v=f[B])):"justify"==i&&(v=f[B],j=Math.floor(l/(d.length-1)))),u[F]=f[J],b=0,c=d.length;b0&&(r+=o.flex*t),u[x]=r,u[z]=v,n.layoutRect(u),n.recalc&&n.recalc(),v+=r+j}else if(u.w=u.minW,u.h=u.minH,a.layoutRect(u),this.recalc(a),null===a._lastRect){var Q=a.parent();Q&&(Q._lastRect=null,Q.recalc())}}})}),g("x",["1l"],function(a){return a.extend({Defaults:{containerClass:"flow-layout",controlClass:"flow-layout-item",endClass:"break"},recalc:function(a){a.items().filter(":visible").each(function(a){a.recalc&&a.recalc()})},isNative:function(){return!0}})}),g("34",["3k","3g"],function(a,b){return function(c,d,e,f,g){return c(e,f)?b.some(e):a.isFunction(g)&&g(e)?b.none():d(e,f,g)}}),g("32",["3k","2l","z","3g","3l","3m","10","34"],function(a,b,c,d,e,f,g,h){var i=function(a){return n(e.body(),a)},j=function(b,e,f){for(var h=b.dom(),i=a.isFunction(f)?f:c.constant(!1);h.parentNode;){h=h.parentNode;var j=g.fromDom(h);if(e(j))return d.some(j);if(i(j))break}return d.none()},k=function(a,b,c){var d=function(a){return b(a)};return h(d,j,a,b,c)},l=function(a,b){var c=a.dom();return c.parentNode?m(g.fromDom(c.parentNode),function(c){return!f.eq(a,c)&&b(c)}):d.none()},m=function(a,d){var e=b.find(a.dom().childNodes,c.compose(d,g.fromDom));return e.map(g.fromDom)},n=function(a,b){var c=function(a){for(var e=0;e=0;i--)h=b.toPt(g,i),j=c(d,h,g);e.value(j?j:null),j||e.text(h)})}},e=function(b){var c="8pt 10pt 12pt 14pt 18pt 24pt 36pt",d=b.settings.fontsize_formats||c;return a.map(d.split(" "),function(a){var b=a,c=a,d=a.split("=");return d.length>1&&(b=d[0],c=d[1]),{text:b,value:c}})},f=function(a){a.addButton("fontsizeselect",function(){var b=e(a);return{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:b,fixedWidth:!0,onPostRender:d(a,b),onclick:function(b){b.control.settings.value&&a.execCommand("FontSize",!1,b.control.settings.value)}}})},g=function(a){f(a)};return{register:g}}),g("19",["c","35"],function(a,b){var c="Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Preformatted=pre",d=function(a){a=a.replace(/;$/,"").split(";");for(var b=a.length;b--;)a[b]=a[b].split("=");return a},e=function(b,c,d){return function(){var e=this;b.on("nodeChange",function(f){var g=b.formatter,h=null;a.each(f.parents,function(b){if(a.each(c,function(a){if(d?g.matchNode(b,d,{value:a.value})&&(h=a.value):g.matchNode(b,a.value)&&(h=a.value),h)return!1}),h)return!1}),e.value(h)})}},f=function(c,d){return function(){var f=[];return a.each(d,function(a){f.push({text:a[0],value:a[1],textStyle:function(){return c.formatter.getCssText(a[1])}})}),{type:"listbox",text:d[0][0],values:f,fixedWidth:!0,onselect:function(a){if(a.control){var d=a.control.value();b.toggleFormat(c,d)()}},onPostRender:e(c,f)}}},g=function(c,d){return a.map(d,function(a){return{text:a[0],onclick:b.toggleFormat(c,a[1]),textStyle:function(){return c.formatter.getCssText(a[1])}}})},h=function(a){var b=d(a.settings.block_formats||c);a.addMenuItem("blockformats",{text:"Blocks",menu:g(a,b)}),a.addButton("formatselect",f(a,b))};return{register:h}}),g("1a",["c","35"],function(a,b){var c=function(b,d){var e=d.length;return a.each(d,function(a){a.menu&&(a.hidden=0===c(b,a.menu));var d=a.format;d&&(a.hidden=!b.formatter.canApply(d)),a.hidden&&e--}),e},d=function(a,b){var e=b.items().length;return b.items().each(function(b){b.menu&&b.visible(d(a,b.menu)>0),!b.menu&&b.settings.menu&&b.visible(c(a,b.settings.menu)>0);var f=b.settings.format;f&&b.visible(a.formatter.canApply(f)),b.visible()||e--}),e},e=function(c){var d=0,e=[],f=[{title:"Headings",items:[{title:"Heading 1",format:"h1"},{title:"Heading 2",format:"h2"},{title:"Heading 3",format:"h3"},{title:"Heading 4",format:"h4"},{title:"Heading 5",format:"h5"},{title:"Heading 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}],g=function(b){var c=[];if(b)return a.each(b,function(a){var b={text:a.title,icon:a.icon};if(a.items)b.menu=g(a.items);else{var f=a.format||"custom"+d++;a.format||(a.name=f,e.push(a)),b.format=f,b.cmd=a.cmd}c.push(b)}),c},h=function(){var a;return a=g(c.settings.style_formats_merge?c.settings.style_formats?f.concat(c.settings.style_formats):f:c.settings.style_formats||f)};return c.on("init",function(){a.each(e,function(a){c.formatter.register(a.name,a)})}),{type:"menu",items:h(),onPostRender:function(a){c.fire("renderFormatsMenu",{control:a.control})},itemDefaults:{preview:!0,textStyle:function(){if(this.settings.format)return c.formatter.getCssText(this.settings.format)},onPostRender:function(){var a=this;a.parent().on("show",function(){var b,d;b=a.settings.format,b&&(a.disabled(!c.formatter.canApply(b)),a.active(c.formatter.match(b))),d=a.settings.cmd,d&&a.active(c.queryCommandState(d))})},onclick:function(){this.settings.format&&b.toggleFormat(c,this.settings.format)(),this.settings.cmd&&c.execCommand(this.settings.cmd)}}}},f=function(a,b){a.addMenuItem("formats",{text:"Formats",menu:b})},g=function(a,b){a.addButton("styleselect",{type:"menubutton",text:"Formats",menu:b,onShowMenu:function(){a.settings.style_formats_autohide&&d(a,this.menu)}})},h=function(a){var b=e(a);f(a,b),g(a,b)};return{register:h}}),g("1b",["2l","c"],function(a,b){var c=function(d,e){var f,g;if("string"==typeof e)g=e.split(" ");else if(b.isArray(e))return a.flatten(b.map(e,function(a){return c(d,a)}));return f=b.grep(g,function(a){return"|"===a||a in d.menuItems}),b.map(f,function(a){return"|"===a?{text:"-"}:d.menuItems[a]})},d=function(a){return a&&"-"===a.text},e=function(b){var c=a.filter(b,function(a,b,c){return!d(a)||!d(c[b-1])});return a.filter(c,function(a,b,c){return!d(a)||b>0&&bE[l]?y:E[l],F[m]=z>F[m]?z:F[m];for(A=f.innerW-q.left-q.right,w=0,l=0;l0?s:0),A-=(l>0?s:0)+E[l];for(B=f.innerH-q.top-q.bottom,x=0,m=0;m0?t:0),B-=(m>0?t:0)+F[m];if(w+=q.left+q.right,x+=q.top+q.bottom,i={},i.minW=w+(f.w-f.innerW),i.minH=x+(f.h-f.innerH),i.contentW=i.minW-f.deltaW,i.contentH=i.minH-f.deltaH,i.minW=Math.min(i.minW,f.maxW),i.minH=Math.min(i.minH,f.maxH),i.minW=Math.max(i.minW,f.startMinWidth), +i.minH=Math.max(i.minH,f.startMinHeight),!f.autoResize||i.minW==f.minW&&i.minH==f.minH){f.autoResize&&(i=a.layoutRect(i),i.contentW=i.minW-f.deltaW,i.contentH=i.minH-f.deltaH);var G;G="start"==b.packV?0:B>0?Math.floor(B/c):0;var H=0,I=b.flexWidths;if(I)for(l=0;l'},src:function(a){this.getEl().src=a},html:function(a,c){var d=this,e=this.getEl().contentWindow.document.body;return e?(e.innerHTML=a,c&&c()):b.setTimeout(function(){d.html(a)}),this}})}),g("1i",["15"],function(a){"use strict";return a.extend({init:function(a){var b=this;b._super(a),b.classes.add("widget").add("infobox"),b.canFocus=!1},severity:function(a){this.classes.remove("error"),this.classes.remove("warning"),this.classes.remove("success"),this.classes.add(a)},help:function(a){this.state.set("help",a)},renderHtml:function(){var a=this,b=a.classPrefix;return'
    '+a.encode(a.state.get("text"))+'
    '},bindStates:function(){var a=this;return a.state.on("change:text",function(b){a.getEl("body").firstChild.data=a.encode(b.value),a.state.get("rendered")&&a.updateLayoutRect()}),a.state.on("change:help",function(b){a.classes.toggle("has-help",b.value),a.state.get("rendered")&&a.updateLayoutRect()}),a._super()}})}),g("1k",["15","2n"],function(a,b){"use strict";return a.extend({init:function(a){var b=this;b._super(a),b.classes.add("widget").add("label"),b.canFocus=!1,a.multiline&&b.classes.add("autoscroll"),a.strong&&b.classes.add("strong")},initLayoutRect:function(){var a=this,c=a._super();if(a.settings.multiline){var d=b.getSize(a.getEl());d.width>c.maxW&&(c.minW=c.maxW,a.classes.add("multiline")),a.getEl().style.width=c.minW+"px",c.startMinH=c.h=c.minH=Math.min(c.maxH,b.getSize(a.getEl()).height)}return c},repaint:function(){var a=this;return a.settings.multiline||(a.getEl().style.lineHeight=a.layoutRect().h+"px"),a._super()},severity:function(a){this.classes.remove("error"),this.classes.remove("warning"),this.classes.remove("success"),this.classes.add(a)},renderHtml:function(){var a,b,c=this,d=c.settings.forId,e=c.settings.html?c.settings.html:c.encode(c.state.get("text"));return!d&&(b=c.settings.forName)&&(a=c.getRoot().find("#"+b)[0],a&&(d=a._id)),d?'":''+e+""},bindStates:function(){var a=this;return a.state.on("change:text",function(b){a.innerHtml(a.encode(b.value)),a.state.get("rendered")&&a.updateLayoutRect()}),a._super()}})}),g("2c",["n"],function(a){"use strict";return a.extend({Defaults:{role:"toolbar",layout:"flow"},init:function(a){var b=this;b._super(a),b.classes.add("toolbar")},postRender:function(){var a=this;return a.items().each(function(a){a.classes.add("toolbar-item")}),a._super()}})}),g("1o",["2c"],function(a){"use strict";return a.extend({Defaults:{role:"menubar",containerCls:"menubar",ariaRoot:!0,defaults:{type:"menubutton"}}})}),g("1p",["1","b","f","1o"],function(a,b,c,d){"use strict";function e(a,b){for(;a;){if(b===a)return!0;a=a.parentNode}return!1}var f=c.extend({init:function(a){var b=this;b._renderOpen=!0,b._super(a),a=b.settings,b.classes.add("menubtn"),a.fixedWidth&&b.classes.add("fixed-width"),b.aria("haspopup",!0),b.state.set("menu",a.menu||b.render())},showMenu:function(a){var c,d=this;return d.menu&&d.menu.visible()&&a!==!1?d.hideMenu():(d.menu||(c=d.state.get("menu")||[],d.classes.add("opened"),c.length?c={type:"menu",animate:!0,items:c}:(c.type=c.type||"menu",c.animate=!0),c.renderTo?d.menu=c.parent(d).show().renderTo():d.menu=b.create(c).parent(d).renderTo(),d.fire("createmenu"),d.menu.reflow(),d.menu.on("cancel",function(a){a.control.parent()===d.menu&&(a.stopPropagation(),d.focus(),d.hideMenu())}),d.menu.on("select",function(){d.focus()}),d.menu.on("show hide",function(a){a.control===d.menu&&(d.activeMenu("show"==a.type),d.classes.toggle("opened","show"==a.type)),d.aria("expanded","show"==a.type)}).fire("show")),d.menu.show(),d.menu.layoutRect({w:d.layoutRect().w}),d.menu.moveRel(d.getEl(),d.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"]),void d.fire("showmenu"))},hideMenu:function(){var a=this;a.menu&&(a.menu.items().each(function(a){a.hideMenu&&a.hideMenu()}),a.menu.hide())},activeMenu:function(a){this.classes.toggle("active",a)},renderHtml:function(){var b,c=this,e=c._id,f=c.classPrefix,g=c.settings.icon,h=c.state.get("text"),i="";return b=c.settings.image,b?(g="none","string"!=typeof b&&(b=a.getSelection?b[0]:b[1]),b=" style=\"background-image: url('"+b+"')\""):b="",h&&(c.classes.add("btn-has-text"),i=''+c.encode(h)+""),g=c.settings.icon?f+"ico "+f+"i-"+g:"",c.aria("role",c.parent()instanceof d?"menuitem":"button"),'
    '},postRender:function(){var a=this;return a.on("click",function(b){b.control===a&&e(b.target,a.getEl())&&(a.focus(),a.showMenu(!b.aria),b.aria&&a.menu.items().filter(":visible")[0].focus())}),a.on("mouseenter",function(b){var c,d=b.control,e=a.parent();d&&e&&d instanceof f&&d.parent()==e&&(e.items().filter("MenuButton").each(function(a){a.hideMenu&&a!=d&&(a.menu&&a.menu.visible()&&(c=!0),a.hideMenu())}),c&&(d.focus(),d.showMenu()))}),a._super()},bindStates:function(){var a=this;return a.state.on("change:menu",function(){a.menu&&a.menu.remove(),a.menu=null}),a._super()},remove:function(){this._super(),this.menu&&this.menu.remove()}});return f}),g("1q",["15","b","14","2u"],function(a,b,c,d){"use strict";var e=function(a,b){var c=a._textStyle;if(c){var d=a.getEl("text");d.setAttribute("style",c),b&&(d.style.color="",d.style.backgroundColor="")}};return a.extend({Defaults:{border:0,role:"menuitem"},init:function(a){var b,c=this;c._super(a),a=c.settings,c.classes.add("menu-item"),a.menu&&c.classes.add("menu-item-expand"),a.preview&&c.classes.add("menu-item-preview"),b=c.state.get("text"),"-"!==b&&"|"!==b||(c.classes.add("menu-item-sep"),c.aria("role","separator"),c.state.set("text","-")),a.selectable&&(c.aria("role","menuitemcheckbox"),c.classes.add("menu-item-checkbox"),a.icon="selected"),a.preview||a.selectable||c.classes.add("menu-item-normal"),c.on("mousedown",function(a){a.preventDefault()}),a.menu&&!a.ariaHideMenu&&c.aria("haspopup",!0)},hasMenus:function(){return!!this.settings.menu},showMenu:function(){var a,c=this,d=c.settings,e=c.parent();if(e.items().each(function(a){a!==c&&a.hideMenu()}),d.menu){a=c.menu,a?a.show():(a=d.menu,a.length?a={type:"menu",animate:!0,items:a}:(a.type=a.type||"menu",a.animate=!0),e.settings.itemDefaults&&(a.itemDefaults=e.settings.itemDefaults),a=c.menu=b.create(a).parent(c).renderTo(),a.reflow(),a.on("cancel",function(b){b.stopPropagation(),c.focus(),a.hide()}),a.on("show hide",function(a){a.control.items&&a.control.items().each(function(a){a.active(a.settings.selected)})}).fire("show"),a.on("hide",function(b){b.control===a&&c.classes.remove("selected")}),a.submenu=!0),a._parentMenu=e,a.classes.add("menu-sub");var f=a.testMoveRel(c.getEl(),c.isRtl()?["tl-tr","bl-br","tr-tl","br-bl"]:["tr-tl","br-bl","tl-tr","bl-br"]);a.moveRel(c.getEl(),f),a.rel=f,f="menu-sub-"+f,a.classes.remove(a._lastRel).add(f),a._lastRel=f,c.classes.add("selected"),c.aria("expanded",!0)}},hideMenu:function(){var a=this;return a.menu&&(a.menu.items().each(function(a){a.hideMenu&&a.hideMenu()}),a.menu.hide(),a.aria("expanded",!1)),a},renderHtml:function(){function a(a){var b,d,e={};for(e=c.mac?{alt:"⌥",ctrl:"⌘",shift:"⇧",meta:"⌘"}:{meta:"Ctrl"},a=a.split("+"),b=0;b").replace(new RegExp(b("]mce~match!"),"g"),"
    ")}var f=this,g=f._id,h=f.settings,i=f.classPrefix,j=f.state.get("text"),k=f.settings.icon,l="",m=h.shortcut,n=f.encode(h.url),o="";return k&&f.parent().classes.add("menu-has-icons"),h.image&&(l=" style=\"background-image: url('"+h.image+"')\""),m&&(m=a(m)),k=i+"ico "+i+"i-"+(f.settings.icon||"none"),o="-"!==j?'\xa0":"",j=e(f.encode(d(j))),n=e(f.encode(d(n))),'
    '+o+("-"!==j?''+j+"":"")+(m?'
    '+m+"
    ":"")+(h.menu?'
    ':"")+(n?'":"")+"
    "},postRender:function(){var a=this,b=a.settings,c=b.textStyle;if("function"==typeof c&&(c=c.call(this)),c){var e=a.getEl("text");e&&(e.setAttribute("style",c),a._textStyle=c)}return a.on("mouseenter click",function(c){c.control===a&&(b.menu||"click"!==c.type?(a.showMenu(),c.aria&&a.menu.focus(!0)):(a.fire("select"),d.requestAnimationFrame(function(){a.parent().hideAll()})))}),a._super(),a},hover:function(){var a=this;return a.parent().items().each(function(a){a.classes.remove("selected")}),a.classes.toggle("selected",!0),a},active:function(a){return e(this,a),"undefined"!=typeof a&&this.aria("checked",a),this._super(a)},remove:function(){this._super(),this.menu&&this.menu.remove()}})}),g("1n",["14","2u","c","w","1q","2b"],function(a,b,c,d,e,f){"use strict";return d.extend({Defaults:{defaultType:"menuitem",border:1,layout:"stack",role:"application",bodyRole:"menu",ariaRoot:!0},init:function(b){var d=this;if(b.autohide=!0,b.constrainToViewport=!0,"function"==typeof b.items&&(b.itemsFactory=b.items,b.items=[]),b.itemDefaults)for(var e=b.items,f=e.length;f--;)e[f]=c.extend({},b.itemDefaults,e[f]);d._super(b),d.classes.add("menu"),b.animate&&11!==a.ie&&d.classes.add("animate")},repaint:function(){return this.classes.toggle("menu-align",!0),this._super(),this.getEl().style.height="",this.getEl("body").style.height="",this},cancel:function(){var a=this;a.hideAll(),a.fire("select")},load:function(){function a(){d.throbber&&(d.throbber.hide(),d.throbber=null)}var b,c,d=this;c=d.settings.itemsFactory,c&&(d.throbber||(d.throbber=new f(d.getEl("body"),!0),0===d.items().length?(d.throbber.show(),d.fire("loading")):d.throbber.show(100,function(){d.items().remove(),d.fire("loading")}),d.on("hide close",a)),d.requestTime=b=(new Date).getTime(),d.settings.itemsFactory(function(c){return 0===c.length?void d.hide():void(d.requestTime===b&&(d.getEl().style.width="",d.getEl("body").style.width="",a(),d.items().remove(),d.getEl("body").innerHTML="",d.add(c),d.renderNew(),d.fire("loaded")))}))},hideAll:function(){var a=this;return this.find("menuitem").exec("hideMenu"),a._super()},preRender:function(){var a=this;return a.items().each(function(b){var c=b.settings;if(c.icon||c.image||c.selectable)return a._hasIcons=!0,!1}),a.settings.itemsFactory&&a.on("postrender",function(){a.settings.itemsFactory&&a.load()}),a.on("show hide",function(c){c.control===a&&("show"===c.type?b.setTimeout(function(){a.classes.add("in")},0):a.classes.remove("in"))}),a._super()}})}),g("1m",["1p","1n"],function(a,b){"use strict";return a.extend({init:function(a){function b(c){for(var f=0;f0&&(e=c[0].text,g.state.set("value",c[0].value)),g.state.set("menu",c)),g.state.set("text",a.text||e),g.classes.add("listbox"),g.on("select",function(b){var c=b.control;f&&(b.lastControl=f),a.multiple?c.active(!c.active()):g.value(b.control.value()),f=c})},bindStates:function(){function a(a,c){a instanceof b&&a.items().each(function(a){a.hasMenus()||a.active(a.value()===c)})}function c(a,b){var d;if(a)for(var e=0;e'},postRender:function(){var a=this;a._super(),a.resizeDragHelper=new b(this._id,{start:function(){a.fire("ResizeStart")},drag:function(b){"both"!=a.settings.direction&&(b.deltaX=0),a.fire("Resize",b)},stop:function(){a.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),g("23",["15"],function(a){"use strict";function b(a){var b="";if(a)for(var c=0;c'+a[c]+"";return b}return a.extend({Defaults:{classes:"selectbox",role:"selectbox",options:[]},init:function(a){var b=this;b._super(a),b.settings.size&&(b.size=b.settings.size),b.settings.options&&(b._options=b.settings.options),b.on("keydown",function(a){var c;13==a.keyCode&&(a.preventDefault(),b.parents().reverse().each(function(a){if(a.toJSON)return c=a,!1}),b.fire("submit",{data:c.toJSON()}))})},options:function(a){return arguments.length?(this.state.set("options",a),this):this.state.get("options")},renderHtml:function(){var a,c=this,d="";return a=b(c._options),c.size&&(d=' size = "'+c.size+'"'),'"},bindStates:function(){var a=this;return a.state.on("change:options",function(c){a.getEl().innerHTML=b(c.value)}),a._super()}})}),g("25",["15","p","2n"],function(a,b,c){"use strict";function d(a,b,c){return ac&&(a=c),a}function e(a,b,c){a.setAttribute("aria-"+b,c)}function f(a,b){var d,f,g,h,i,j;"v"==a.settings.orientation?(h="top",g="height",f="h"):(h="left",g="width",f="w"),j=a.getEl("handle"),d=(a.layoutRect()[f]||100)-c.getSize(j)[g],i=d*((b-a._minValue)/(a._maxValue-a._minValue))+"px",j.style[h]=i,j.style.height=a.layoutRect().h+"px",e(j,"valuenow",b),e(j,"valuetext",""+a.settings.previewFilter(b)),e(j,"valuemin",a._minValue),e(j,"valuemax",a._maxValue)}return a.extend({init:function(a){var b=this;a.previewFilter||(a.previewFilter=function(a){return Math.round(100*a)/100}),b._super(a),b.classes.add("slider"),"v"==a.orientation&&b.classes.add("vertical"),b._minValue=a.minValue||0,b._maxValue=a.maxValue||100,b._initValue=b.state.get("value")},renderHtml:function(){var a=this,b=a._id,c=a.classPrefix;return'
    '},reset:function(){this.value(this._initValue).repaint()},postRender:function(){function a(a,b,c){return(c+a)/(b-a)}function e(a,b,c){return c*(b-a)-a}function f(b,c){function f(f){var g;g=n.value(),g=e(b,c,a(b,c,g)+.05*f),g=d(g,b,c),n.value(g),n.fire("dragstart",{value:g}),n.fire("drag",{value:g}),n.fire("dragend",{value:g})}n.on("keydown",function(a){switch(a.keyCode){case 37:case 38:f(-1);break;case 39:case 40:f(1)}})}function g(a,e,f){var g,h,i,o,p;n._dragHelper=new b(n._id,{handle:n._id+"-handle",start:function(a){g=a[j],h=parseInt(n.getEl("handle").style[k],10),i=(n.layoutRect()[m]||100)-c.getSize(f)[l],n.fire("dragstart",{value:p})},drag:function(b){var c=b[j]-g;o=d(h+c,0,i),f.style[k]=o+"px",p=a+o/i*(e-a),n.value(p),n.tooltip().text(""+n.settings.previewFilter(p)).show().moveRel(f,"bc tc"),n.fire("drag",{value:p})},stop:function(){n.tooltip().hide(),n.fire("dragend",{value:p})}})}var h,i,j,k,l,m,n=this;h=n._minValue,i=n._maxValue,"v"==n.settings.orientation?(j="screenY",k="top",l="height",m="h"):(j="screenX",k="left",l="width",m="w"),n._super(),f(h,i,n.getEl("handle")),g(h,i,n.getEl("handle"))},repaint:function(){this._super(),f(this,this.value())},bindStates:function(){var a=this;return a.state.on("change:value",function(b){f(a,b.value)}),a._super()}})}),g("26",["15"],function(a){"use strict";return a.extend({renderHtml:function(){var a=this;return a.classes.add("spacer"),a.canFocus=!1,'
    '}})}),g("27",["1","2o","2n","1p"],function(a,b,c,d){return d.extend({Defaults:{classes:"widget btn splitbtn",role:"button"},repaint:function(){var a,d,e=this,f=e.getEl(),g=e.layoutRect();return e._super(),a=f.firstChild,d=f.lastChild,b(a).css({width:g.w-c.getSize(d).width,height:g.h-2}),b(d).css({height:g.h-2}),e},activeMenu:function(a){var c=this;b(c.getEl().lastChild).toggleClass(c.classPrefix+"active",a)},renderHtml:function(){var b,c,d=this,e=d._id,f=d.classPrefix,g=d.state.get("icon"),h=d.state.get("text"),i=d.settings,j="";return b=i.image,b?(g="none","string"!=typeof b&&(b=a.getSelection?b[0]:b[1]),b=" style=\"background-image: url('"+b+"')\""):b="",g=i.icon?f+"ico "+f+"i-"+g:"",h&&(d.classes.add("btn-has-text"),j=''+d.encode(h)+""),c="boolean"==typeof i.active?' aria-pressed="'+i.active+'"':"",'
    '},postRender:function(){var a=this,b=a.settings.onclick;return a.on("click",function(a){var c=a.target;if(a.control==this)for(;c;){if(a.aria&&"down"!=a.aria.key||"BUTTON"==c.nodeName&&c.className.indexOf("open")==-1)return a.stopImmediatePropagation(),void(b&&b.call(this,a));c=c.parentNode}}),delete a.settings.onclick,a._super()}})}),g("28",["x"],function(a){"use strict";return a.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"},isNative:function(){return!0}})}),g("29",["1u","2o","2n"],function(a,b,c){"use strict";return a.extend({Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(a){var c;this.activeTabId&&(c=this.getEl(this.activeTabId),b(c).removeClass(this.classPrefix+"active"),c.setAttribute("aria-selected","false")),this.activeTabId="t"+a,c=this.getEl("t"+a),c.setAttribute("aria-selected","true"),b(c).addClass(this.classPrefix+"active"),this.items()[a].show().fire("showtab"),this.reflow(),this.items().each(function(b,c){a!=c&&b.hide()})},renderHtml:function(){var a=this,b=a._layout,c="",d=a.classPrefix;return a.preRender(),b.preRender(a),a.items().each(function(b,e){var f=a._id+"-t"+e;b.aria("role","tabpanel"),b.aria("labelledby",f),c+='"}),'
    '+c+'
    '+b.renderHtml(a)+"
    "},postRender:function(){var a=this;a._super(),a.settings.activeTab=a.settings.activeTab||0,a.activateTab(a.settings.activeTab),this.on("click",function(b){var c=b.target.parentNode;if(c&&c.id==a._id+"-head")for(var d=c.childNodes.length;d--;)c.childNodes[d]==b.target&&a.activateTab(d)})},initLayoutRect:function(){var a,b,d,e=this;b=c.getSize(e.getEl("head")).width,b=b<0?0:b,d=0,e.items().each(function(a){b=Math.max(b,a.layoutRect().minW),d=Math.max(d,a.layoutRect().minH)}),e.items().each(function(a){a.settings.x=0,a.settings.y=0,a.settings.w=b,a.settings.h=d,a.layoutRect({x:0,y:0,w:b,h:d})});var f=c.getSize(e.getEl("head")).height;return e.settings.minWidth=b,e.settings.minHeight=d+f,a=e._super(),a.deltaH+=f,a.innerH=a.h-a.deltaH,a}})}),g("2a",["12","c","2n","15"],function(a,b,c,d){return d.extend({init:function(a){var b=this;b._super(a),b.classes.add("textbox"),a.multiline?b.classes.add("multiline"):(b.on("keydown",function(a){var c;13==a.keyCode&&(a.preventDefault(),b.parents().reverse().each(function(a){if(a.toJSON)return c=a,!1}),b.fire("submit",{data:c.toJSON()}))}),b.on("keyup",function(a){b.state.set("value",a.target.value)}))},repaint:function(){var b,c,d,e,f,g=this,h=0;b=g.getEl().style,c=g._layoutRect,f=g._lastRepaintRect||{};var i=a;return!g.settings.multiline&&i.all&&(!i.documentMode||i.documentMode<=8)&&(b.lineHeight=c.h-h+"px"),d=g.borderBox,e=d.left+d.right+8,h=d.top+d.bottom+(g.settings.multiline?8:0),c.x!==f.x&&(b.left=c.x+"px",f.x=c.x),c.y!==f.y&&(b.top=c.y+"px",f.y=c.y),c.w!==f.w&&(b.width=c.w-e+"px",f.w=c.w),c.h!==f.h&&(b.height=c.h-h+"px",f.h=c.h),g._lastRepaintRect=f,g.fire("repaint",{},!1),g},renderHtml:function(){var a,d,e=this,f=e.settings;return a={id:e._id,hidefocus:"1"},b.each(["rows","spellcheck","maxLength","size","readonly","min","max","step","list","pattern","placeholder","required","multiple"],function(b){a[b]=f[b]}),e.disabled()&&(a.disabled="disabled"),f.subtype&&(a.type=f.subtype),d=c.create(f.multiline?"textarea":"input",a),d.value=e.state.get("value"),d.className=e.classes,d.outerHTML},value:function(a){return arguments.length?(this.state.set("value",a),this):(this.state.get("rendered")&&this.state.set("value",this.getEl().value),this.state.get("value"))},postRender:function(){var a=this;a.getEl().value=a.state.get("value"),a._super(),a.$el.on("change",function(b){a.state.set("value",b.target.value),a.fire("change",b)})},bindStates:function(){var a=this;return a.state.on("change:value",function(b){a.getEl().value!=b.value&&(a.getEl().value=b.value)}),a.state.on("change:disabled",function(b){a.getEl().disabled=b.value}),a._super()},remove:function(){this.$el.off(),this._super()}})}),g("4",["b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","5","1f","1g","1h","1i","1j","1k","1l","1m","1n","1o","1p","1q","1r","1s","1t","1u","1v","1w","1x","1y","1z","20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","15","2e"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha){var ia=function(){return{Selector:Y,Collection:h,ReflowQueue:T,Control:n,Factory:a,KeyboardNavigation:D,Container:m,DragHelper:o,Scrollable:W,Panel:O,Movable:M,Resizable:U,FloatPanel:v,Window:ha,MessageBox:L,Tooltip:fa,Widget:ga,Progress:R,Notification:N,Layout:F,AbsoluteLayout:c,Button:e,ButtonGroup:f,Checkbox:g,ComboBox:l,ColorBox:i,PanelButton:P,ColorButton:j,ColorPicker:k,Path:Q,ElementPath:q,FormItem:z,Form:x,FieldSet:r,FilePicker:s,FitLayout:t,FlexLayout:u,FlowLayout:w,FormatControls:y,GridLayout:A,Iframe:B,InfoBox:C,Label:E,Toolbar:ea,MenuBar:I,MenuButton:J,MenuItem:K,Throbber:da,Menu:H,ListBox:G,Radio:S,ResizeHandle:V,SelectBox:X,Slider:Z,Spacer:$,SplitButton:_,StackLayout:aa,TabPanel:ba,TextBox:ca,DropZone:p,BrowseButton:d}},ja=function(a){a.ui?b.each(ia(),function(b,c){a.ui[c]=b}):a.ui=ia()},ka=function(){b.each(ia(),function(b,c){a.add(c,b)})},la={appendTo:ja,registerToFactory:ka};return la}),g("0",["1","2","3","4","5"],function(a,b,c,d,e){return d.registerToFactory(),d.appendTo(a.tinymce?a.tinymce:{}),b.add("modern",function(a){return e.setup(a),c.get(a)}),function(){}}),d("0")()}(); \ No newline at end of file diff --git a/client-wiaas/public/static/js/tinymce/js/tinymce/tinymce.min.js b/client-wiaas/public/static/js/tinymce/js/tinymce/tinymce.min.js new file mode 100644 index 0000000..0c1d1b1 --- /dev/null +++ b/client-wiaas/public/static/js/tinymce/js/tinymce/tinymce.min.js @@ -0,0 +1,13 @@ +// 4.7.3 (2017-11-23) +!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e=534;return{opera:f,webkit:g,ie:h,gecko:k,mac:l,iOS:m,android:n,contentEditable:v,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=h,range:e.getSelection&&"Range"in e,documentMode:h&&!j?b.documentMode||7:10,fileApi:o,ceFalse:h===!1||h>8,canHaveCSP:h===!1||h>11,desktop:!p&&!q,windowsPhone:r}}),h("1n",clearInterval),h("1o",clearTimeout),h("1p",setInterval),h("1q",setTimeout),g("1d",[],function(){function a(a,b){return function(){a.apply(b,arguments)}}function b(b){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof b)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],h(b,a(d,this),a(e,this))}function c(a){var b=this;return null===this._state?void this._deferreds.push(a):void i(function(){var c=b._state?a.onFulfilled:a.onRejected;if(null===c)return void(b._state?a.resolve:a.reject)(b._value);var d;try{d=c(b._value)}catch(b){return void a.reject(b)}a.resolve(d)})}function d(b){try{if(b===this)throw new TypeError("A promise cannot be resolved with itself.");if(b&&("object"==typeof b||"function"==typeof b)){var c=b.then;if("function"==typeof c)return void h(a(c,b),a(d,this),a(e,this))}this._state=!0,this._value=b,f.call(this)}catch(a){e.call(this,a)}}function e(a){this._state=!1,this._value=a,f.call(this)}function f(){for(var a=0,b=this._deferreds.length;a0&&(d=c[0]),a.deepPath&&(c=a.deepPath(),c&&c.length>0&&(d=c[0])),d},n=function(b,d){var e,k,l=d||{};for(e in b)g[e]||(l[e]=b[e]);if(l.target||(l.target=l.srcElement||a),c.experimentalShadowDom&&(l.target=m(b,l.target)),b&&f.test(b.type)&&b.pageX===k&&b.clientX!==k){var n=l.target.ownerDocument||a,o=n.documentElement,p=n.body;l.pageX=b.clientX+(o&&o.scrollLeft||p&&p.scrollLeft||0)-(o&&o.clientLeft||p&&p.clientLeft||0),l.pageY=b.clientY+(o&&o.scrollTop||p&&p.scrollTop||0)-(o&&o.clientTop||p&&p.clientTop||0)}return l.preventDefault=function(){l.isDefaultPrevented=j,b&&(b.preventDefault?b.preventDefault():b.returnValue=!1)},l.stopPropagation=function(){l.isPropagationStopped=j,b&&(b.stopPropagation?b.stopPropagation():b.cancelBubble=!0)},l.stopImmediatePropagation=function(){l.isImmediatePropagationStopped=j,l.stopPropagation()},h(l)===!1&&(l.isDefaultPrevented=i,l.isPropagationStopped=i,l.isImmediatePropagationStopped=i),"undefined"==typeof l.metaKey&&(l.metaKey=!1),l},o=function(a,b,e){var f=a.document,g={type:"ready"};if(e.domLoaded)return void b(g);var h=function(){return"complete"===f.readyState||"interactive"===f.readyState&&f.body},i=function(){e.domLoaded||(e.domLoaded=!0,b(g))},j=function(){h()&&(l(f,"readystatechange",j),i())},m=function(){try{f.documentElement.doScroll("left")}catch(a){return void d.setTimeout(m)}i()};!f.addEventListener||c.ie&&c.ie<11?(k(f,"readystatechange",j),f.documentElement.doScroll&&a.self===a.top&&m()):h()?i():k(a,"DOMContentLoaded",i),k(a,"load",i)},p=function(){var c,d,f,g,h,i=this,j={};d=e+(+new Date).toString(32),g="onmouseenter"in a.documentElement,f="onfocusin"in a.documentElement,h={mouseenter:"mouseover",mouseleave:"mouseout"},c=1,i.domLoaded=!1,i.events=j;var m=function(a,b){var c,d,e,f,g=j[b];if(c=g&&g[a.type])for(d=0,e=c.length;dt.cacheLength&&delete a[b.shift()],a[c+" "]=d}var b=[];return a}function c(a){return a[K]=!0,a}function d(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||T)-(~a.sourceIndex||T);if(d)return d;if(c)for(;c=c.nextSibling;)if(c===b)return-1;return a?1:-1}function e(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function f(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function g(a){return c(function(b){return b=+b,c(function(c,d){for(var e,f=a([],c.length,b),g=f.length;g--;)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function h(a){return a&&typeof a.getElementsByTagName!==S&&a}function i(){}function j(a){for(var b=0,c=a.length,d="";b1?function(b,c,d){for(var e=a.length;e--;)if(!a[e](b,c,d))return!1;return!0}:a[0]}function m(b,c,d){for(var e=0,f=c.length;e-1&&(c[j]=!(g[j]=l))}}else t=n(t===g?t.splice(q,t.length):t),f?f(null,g,t,i):Y.apply(g,t)})}function p(a){for(var b,c,d,e=a.length,f=t.relative[a[0].type],g=f||t.relative[" "],h=f?1:0,i=k(function(a){return a===b},g,!0),m=k(function(a){return $.call(b,a)>-1},g,!0),n=[function(a,c,d){return!f&&(d||c!==z)||((b=c).nodeType?i(a,c,d):m(a,c,d))}];h1&&l(n),h>1&&j(a.slice(0,h-1).concat({value:" "===a[h-2].type?"*":""})).replace(ea,"$1"),c,h0,f=b.length>0,g=function(c,g,h,i,j){var k,l,m,o=0,p="0",q=c&&[],r=[],s=z,u=c||f&&t.find.TAG("*",j),v=M+=null==s?1:Math.random()||.1,w=u.length;for(j&&(z=g!==D&&g);p!==w&&null!=(k=u[p]);p++){if(f&&k){for(l=0;m=b[l++];)if(m(k,g,h)){i.push(k);break}j&&(M=v)}e&&((k=!m&&k)&&o--,c&&q.push(k))}if(o+=p,e&&p!==o){for(l=0;m=d[l++];)m(q,r,g,h);if(c){if(o>0)for(;p--;)q[p]||r[p]||(r[p]=W.call(i));r=n(r)}Y.apply(i,r),j&&!c&&r.length>0&&o+d.length>1&&a.uniqueSort(i)}return j&&(M=v,z=s),q};return e?c(g):g}var r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K="sizzle"+-new Date,L=window.document,M=0,N=0,O=b(),P=b(),Q=b(),R=function(a,b){return a===b&&(B=!0),0},S="undefined",T=1<<31,U={}.hasOwnProperty,V=[],W=V.pop,X=V.push,Y=V.push,Z=V.slice,$=V.indexOf||function(a){for(var b=0,c=this.length;b+~]|"+aa+")"+aa+"*"),ha=new RegExp("="+aa+"*([^\\]'\"]*?)"+aa+"*\\]","g"),ia=new RegExp(da),ja=new RegExp("^"+ba+"$"),ka={ID:new RegExp("^#("+ba+")"),CLASS:new RegExp("^\\.("+ba+")"),TAG:new RegExp("^("+ba+"|[*])"),ATTR:new RegExp("^"+ca),PSEUDO:new RegExp("^"+da),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+aa+"*(even|odd|(([+-]|)(\\d*)n|)"+aa+"*(?:([+-]|)"+aa+"*(\\d+)|))"+aa+"*\\)|)","i"),bool:new RegExp("^(?:"+_+")$","i"),needsContext:new RegExp("^"+aa+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+aa+"*((?:-\\d)?\\d*)"+aa+"*\\)|)(?=[^-]|$)","i")},la=/^(?:input|select|textarea|button)$/i,ma=/^h\d$/i,na=/^[^{]+\{\s*\[native \w/,oa=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,pa=/[+~]/,qa=/'|\\/g,ra=new RegExp("\\\\([\\da-f]{1,6}"+aa+"?|("+aa+")|.)","ig"),sa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{Y.apply(V=Z.call(L.childNodes),L.childNodes),V[L.childNodes.length].nodeType}catch(a){Y={apply:V.length?function(a,b){X.apply(a,Z.call(b))}:function(a,b){for(var c=a.length,d=0;a[c++]=b[d++];);a.length=c-1}}}s=a.support={},v=a.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},C=a.setDocument=function(a){function b(a){try{return a.top}catch(a){}return null}var c,e=a?a.ownerDocument||a:L,f=e.defaultView;return e!==D&&9===e.nodeType&&e.documentElement?(D=e,E=e.documentElement,F=!v(e),f&&f!==b(f)&&(f.addEventListener?f.addEventListener("unload",function(){C()},!1):f.attachEvent&&f.attachEvent("onunload",function(){C()})),s.attributes=!0,s.getElementsByTagName=!0,s.getElementsByClassName=na.test(e.getElementsByClassName),s.getById=!0,t.find.ID=function(a,b){if(typeof b.getElementById!==S&&F){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},t.filter.ID=function(a){var b=a.replace(ra,sa);return function(a){return a.getAttribute("id")===b}},t.find.TAG=s.getElementsByTagName?function(a,b){if(typeof b.getElementsByTagName!==S)return b.getElementsByTagName(a)}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){for(;c=f[e++];)1===c.nodeType&&d.push(c);return d}return f},t.find.CLASS=s.getElementsByClassName&&function(a,b){if(F)return b.getElementsByClassName(a)},H=[],G=[],s.disconnectedMatch=!0,G=G.length&&new RegExp(G.join("|")),H=H.length&&new RegExp(H.join("|")),c=na.test(E.compareDocumentPosition),J=c||na.test(E.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b=b.parentNode;)if(b===a)return!0;return!1},R=c?function(a,b){if(a===b)return B=!0,0;var c=!a.compareDocumentPosition-!b.compareDocumentPosition;return c?c:(c=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&c||!s.sortDetached&&b.compareDocumentPosition(a)===c?a===e||a.ownerDocument===L&&J(L,a)?-1:b===e||b.ownerDocument===L&&J(L,b)?1:A?$.call(A,a)-$.call(A,b):0:4&c?-1:1)}:function(a,b){if(a===b)return B=!0,0;var c,f=0,g=a.parentNode,h=b.parentNode,i=[a],j=[b];if(!g||!h)return a===e?-1:b===e?1:g?-1:h?1:A?$.call(A,a)-$.call(A,b):0;if(g===h)return d(a,b);for(c=a;c=c.parentNode;)i.unshift(c);for(c=b;c=c.parentNode;)j.unshift(c);for(;i[f]===j[f];)f++;return f?d(i[f],j[f]):i[f]===L?-1:j[f]===L?1:0},e):D},a.matches=function(b,c){return a(b,null,null,c)},a.matchesSelector=function(b,c){if((b.ownerDocument||b)!==D&&C(b),c=c.replace(ha,"='$1']"),s.matchesSelector&&F&&(!H||!H.test(c))&&(!G||!G.test(c)))try{var d=I.call(b,c);if(d||s.disconnectedMatch||b.document&&11!==b.document.nodeType)return d}catch(a){}return a(c,D,null,[b]).length>0},a.contains=function(a,b){return(a.ownerDocument||a)!==D&&C(a),J(a,b)},a.attr=function(a,b){(a.ownerDocument||a)!==D&&C(a);var c=t.attrHandle[b.toLowerCase()],d=c&&U.call(t.attrHandle,b.toLowerCase())?c(a,b,!F):void 0;return void 0!==d?d:s.attributes||!F?a.getAttribute(b):(d=a.getAttributeNode(b))&&d.specified?d.value:null},a.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},a.uniqueSort=function(a){var b,c=[],d=0,e=0;if(B=!s.detectDuplicates,A=!s.sortStable&&a.slice(0),a.sort(R),B){for(;b=a[e++];)b===a[e]&&(d=c.push(e));for(;d--;)a.splice(c[d],1)}return A=null,a},u=a.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(1===e||9===e||11===e){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=u(a)}else if(3===e||4===e)return a.nodeValue}else for(;b=a[d++];)c+=u(b);return c},t=a.selectors={cacheLength:50,createPseudo:c,match:ka,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ra,sa),a[3]=(a[3]||a[4]||a[5]||"").replace(ra,sa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(b){return b[1]=b[1].toLowerCase(),"nth"===b[1].slice(0,3)?(b[3]||a.error(b[0]),b[4]=+(b[4]?b[5]+(b[6]||1):2*("even"===b[3]||"odd"===b[3])),b[5]=+(b[7]+b[8]||"odd"===b[3])):b[3]&&a.error(b[0]),b},PSEUDO:function(a){var b,c=!a[6]&&a[2];return ka.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&ia.test(c)&&(b=w(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ra,sa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=O[a+" "];return b||(b=new RegExp("(^|"+aa+")"+a+"("+aa+"|$)"))&&O(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==S&&a.getAttribute("class")||"")})},ATTR:function(b,c,d){return function(e){var f=a.attr(e,b);return null==f?"!="===c:!c||(f+="","="===c?f===d:"!="===c?f!==d:"^="===c?d&&0===f.indexOf(d):"*="===c?d&&f.indexOf(d)>-1:"$="===c?d&&f.slice(-d.length)===d:"~="===c?(" "+f+" ").indexOf(d)>-1:"|="===c&&(f===d||f.slice(0,d.length+1)===d+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){for(;p;){for(l=b;l=l[p];)if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){for(k=q[K]||(q[K]={}),j=k[a]||[],n=j[0]===M&&j[1],m=j[0]===M&&j[2],l=n&&q.childNodes[n];l=++n&&l&&l[p]||(m=n=0)||o.pop();)if(1===l.nodeType&&++m&&l===b){k[a]=[M,n,m];break}}else if(s&&(j=(b[K]||(b[K]={}))[a])&&j[0]===M)m=j[1];else for(;(l=++n&&l&&l[p]||(m=n=0)||o.pop())&&((h?l.nodeName.toLowerCase()!==r:1!==l.nodeType)||!++m||(s&&((l[K]||(l[K]={}))[a]=[M,m]),l!==b)););return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(b,d){var e,f=t.pseudos[b]||t.setFilters[b.toLowerCase()]||a.error("unsupported pseudo: "+b);return f[K]?f(d):f.length>1?(e=[b,b,"",d],t.setFilters.hasOwnProperty(b.toLowerCase())?c(function(a,b){for(var c,e=f(a,d),g=e.length;g--;)c=$.call(a,e[g]),a[c]=!(b[c]=e[g])}):function(a){return f(a,0,e)}):f}},pseudos:{not:c(function(a){var b=[],d=[],e=x(a.replace(ea,"$1"));return e[K]?c(function(a,b,c,d){for(var f,g=e(a,null,d,[]),h=a.length;h--;)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,c,f){return b[0]=a,e(b,null,f,d),!d.pop()}}),has:c(function(b){return function(c){return a(b,c).length>0}}),contains:c(function(a){return a=a.replace(ra,sa),function(b){return(b.textContent||b.innerText||u(b)).indexOf(a)>-1}}),lang:c(function(b){return ja.test(b||"")||a.error("unsupported lang: "+b),b=b.replace(ra,sa).toLowerCase(),function(a){var c;do if(c=F?a.lang:a.getAttribute("xml:lang")||a.getAttribute("lang"))return c=c.toLowerCase(),c===b||0===c.indexOf(b+"-");while((a=a.parentNode)&&1===a.nodeType);return!1}}),target:function(a){var b=window.location&&window.location.hash;return b&&b.slice(1)===a.id},root:function(a){return a===E},focus:function(a){return a===D.activeElement&&(!D.hasFocus||D.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!t.pseudos.empty(a)},header:function(a){return ma.test(a.nodeName)},input:function(a){return la.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:g(function(){return[0]}),last:g(function(a,b){return[b-1]}),eq:g(function(a,b,c){return[c<0?c+b:c]}),even:g(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:g(function(a,b,c){for(var d=c<0?c+b:c;++d2&&"ID"===(g=f[0]).type&&s.getById&&9===b.nodeType&&F&&t.relative[f[1].type]){if(b=(t.find.ID(g.matches[0].replace(ra,sa),b)||[])[0],!b)return c;l&&(b=b.parentNode),a=a.slice(f.shift().value.length)}for(e=ka.needsContext.test(a)?0:f.length;e--&&(g=f[e],!t.relative[i=g.type]);)if((k=t.find[i])&&(d=k(g.matches[0].replace(ra,sa),pa.test(f[0].type)&&h(b.parentNode)||b))){if(f.splice(e,1),a=d.length&&j(f),!a)return Y.apply(c,d),c;break}}return(l||x(a,m))(d,b,!F,c,pa.test(a)&&h(b.parentNode)||b),c},s.sortStable=K.split("").sort(R).join("")===K,s.detectDuplicates=!!B,C(),s.sortDetached=!0,a}),g("1r",[],function(){var a=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},b=function(b){var c,d,e=b;if(!a(b))for(e=[],c=0,d=b.length;c)[^>]*$|#([\w\-]*)$)/,k=b.Event,l=e.makeMap("children,contents,next,prev"),m=function(a){return"undefined"!=typeof a},n=function(a){return"string"==typeof a},o=function(a){return a&&a==a.window},p=function(a,b){var c,d,e;for(b=b||g,e=b.createElement("div"),c=b.createDocumentFragment(),e.innerHTML=a;d=e.firstChild;)c.appendChild(d);return c},q=function(a,b,c,d){var e;if(n(b))b=p(b,F(a[0]));else if(b.length&&!b.nodeType){if(b=z.makeArray(b),d)for(e=b.length-1;e>=0;e--)q(a,b[e],c,d);else for(e=0;e"===b.charAt(b.length-1)&&b.length>=3?[null,b,null]:j.exec(b),!d)return z(c).find(b);if(d[1])for(e=p(b,F(c)).firstChild;e;)h.call(f,e),e=e.nextSibling;else{if(e=F(c).getElementById(d[2]),!e)return f;if(e.id!==d[2])return f.find(b);f.length=1,f[0]=e}}else this.add(b,!1);return f},toArray:function(){return e.toArray(this)},add:function(a,b){var c,d,e=this;if(n(a))return e.add(z(a));if(b!==!1)for(c=z.unique(e.toArray().concat(z.makeArray(a))),e.length=c.length,d=0;d1&&(l[a]||(e=z.unique(e)),0===a.indexOf("parents")&&(e=e.reverse())),e=z(e),c?e.filter(c):e}}),D({parentsUntil:function(a,b){return G(a,"parentNode",b)},nextUntil:function(a,b){return H(a,"nextSibling",1,b).slice(1)},prevUntil:function(a,b){return H(a,"previousSibling",1,b).slice(1)}},function(a,b){z.fn[a]=function(c,d){var e=this,f=[];return e.each(function(){var a=b.call(f,this,c,f);a&&(z.isArray(a)?f.push.apply(f,a):f.push(a))}),this.length>1&&(f=z.unique(f),0!==a.indexOf("parents")&&"prevUntil"!==a||(f=f.reverse())),f=z(f),d?f.filter(d):f}}),z.fn.is=function(a){return!!a&&this.filter(a).length>0},z.fn.init.prototype=z.fn,z.overrideDefaults=function(a){var b,c=function(d,e){return b=b||a(),0===arguments.length&&(d=b.element),e||(e=b.context),new c.fn.init(d,e)};return z.extend(c,this),c};var J=function(a,b,c){D(c,function(c,d){a[c]=a[c]||{},a[c][b]=d})};return d.ie&&d.ie<8&&(J(x,"get",{maxlength:function(a){var b=a.maxLength;return 2147483647===b?f:b},size:function(a){var b=a.size;return 20===b?f:b},"class":function(a){return a.className},style:function(a){var b=a.style.cssText;return 0===b.length?f:b}}),J(x,"set",{"class":function(a,b){a.className=b},style:function(a,b){a.style.cssText=b}})),d.ie&&d.ie<9&&(w["float"]="styleFloat",J(y,"set",{opacity:function(a,b){var c=a.style;null===b||""===b?c.removeAttribute("filter"):(c.zoom=1,c.filter="alpha(opacity="+100*b+")")}})),z.attrHooks=x,z.cssHooks=y,z}),g("4z",[],function(){var a=function(a){var b,c=!1;return function(){return c||(c=!0,b=a.apply(null,arguments)),b}};return{cached:a}}),h("74",Number),g("6q",["1i","74","3b"],function(a,b,c){var d=function(a,b){for(var c=0;c1)throw c.error("HTML does not have a single root node",a),"HTML must have a single root node";return h(f.childNodes[0])},f=function(a,b){var c=b||d,e=c.createElement(a);return h(e)},g=function(a,b){var c=b||d,e=c.createTextNode(a);return h(e)},h=function(c){if(null===c||void 0===c)throw new b("Node cannot be null or undefined");return{dom:a.constant(c)}};return{fromHtml:e,fromTag:f,fromText:g,fromDom:h}}),g("4d",[],function(){return{ATTRIBUTE:2,CDATA_SECTION:4,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,ELEMENT:1,TEXT:3,PROCESSING_INSTRUCTION:7,ENTITY_REFERENCE:5,ENTITY:6,NOTATION:12}}),g("3f",["4d"],function(a){var b=function(a){var b=a.dom().nodeName;return b.toLowerCase()},c=function(a){return a.dom().nodeType},d=function(a){return a.dom().nodeValue},e=function(a){return function(b){return c(b)===a}},f=function(d){return c(d)===a.COMMENT||"#comment"===b(d)},g=e(a.ELEMENT),h=e(a.TEXT),i=e(a.DOCUMENT);return{name:b,type:c,value:d,isElement:g,isText:h,isDocument:i,isComment:f}}),g("28",["4","3b"],function(a,b){var c=function(c){if(null===c)return"null";var d=typeof c;return"object"===d&&a.prototype.isPrototypeOf(c)?"array":"object"===d&&b.prototype.isPrototypeOf(c)?"string":d},d=function(a){return function(b){return c(b)===a}};return{isString:d("string"),isObject:d("object"),isArray:d("array"),isNull:d("null"),isBoolean:d("boolean"),isUndefined:d("undefined"),isFunction:d("function"),isNumber:d("number")}}),g("4g",["2n","3a"],function(a,b){var c=function(){var a=b.keys,c=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b};return void 0===a?c:a}(),d=function(a,b){for(var d=c(a),e=0,f=d.length;e0})},v=function(a){var b={},c=a.dom();if(i.isSupported(c))for(var d=0;d0&&e.unsuppMessage(m);var n={};return a.each(h,function(a){n[a]=b.constant(f[a])}),a.each(i,function(a){n[a]=b.constant(g.prototype.hasOwnProperty.call(f,a)?d.some(f[a]):d.none())}),n}}}),g("45",["55","56"],function(a,b){return{immutable:a,immutableBag:b}}),g("57",[],function(){var a=function(a,b){var c=[],d=function(a){return c.push(a),b(a)},e=b(a);do e=e.bind(d);while(e.isSome());return c};return{toArray:a}}),g("4c",["3c"],function(a){var b=function(){var b=a.getOrDie("Node");return b},c=function(a,b,c){return 0!==(a.compareDocumentPosition(b)&c)},d=function(a,d){return c(a,d,b().DOCUMENT_POSITION_PRECEDING)},e=function(a,d){return c(a,d,b().DOCUMENT_POSITION_CONTAINED_BY)};return{documentPositionPreceding:d,documentPositionContainedBy:e}}),g("2z",["1i","2n","1v","4d","5","1j"],function(a,b,c,d,e,f){var g=d.ELEMENT,h=d.DOCUMENT,i=function(a,b){var c=a.dom();if(c.nodeType!==g)return!1;if(void 0!==c.matches)return c.matches(b);if(void 0!==c.msMatchesSelector)return c.msMatchesSelector(b);if(void 0!==c.webkitMatchesSelector)return c.webkitMatchesSelector(b);if(void 0!==c.mozMatchesSelector)return c.mozMatchesSelector(b);throw new e("Browser lacks native selectors")},j=function(a){return a.nodeType!==g&&a.nodeType!==h||0===a.childElementCount},k=function(b,d){var e=void 0===d?f:d.dom();return j(e)?[]:a.map(e.querySelectorAll(b),c.fromDom)},l=function(a,d){var e=void 0===d?f:d.dom();return j(e)?b.none():b.from(e.querySelector(a)).map(c.fromDom)};return{all:k,is:i,one:l}}),g("31",["1i","1","4c","3d","2z"],function(a,b,c,d,e){var f=function(a,b){return a.dom()===b.dom()},g=function(a,b){return a.dom().isEqualNode(b.dom())},h=function(c,d){return a.exists(d,b.curry(f,c))},i=function(a,b){var c=a.dom(),d=b.dom();return c!==d&&c.contains(d)},j=function(a,b){return c.documentPositionContainedBy(a.dom(),b.dom())},k=d.detect().browser,l=k.isIE()?j:i;return{eq:f,isEqualNode:g,member:h,contains:l,is:e.is}}),g("3h",["28","1i","1","2n","45","57","31","1v"],function(a,b,c,d,e,f,g,h){var i=function(a){return h.fromDom(a.dom().ownerDocument)},j=function(a){var b=i(a);return h.fromDom(b.dom().documentElement)},k=function(a){var b=a.dom(),c=b.ownerDocument.defaultView;return h.fromDom(c)},l=function(a){var b=a.dom();return d.from(b.parentNode).map(h.fromDom)},m=function(a){return l(a).bind(function(c){var d=u(c);return b.findIndex(d,function(b){return g.eq(a,b)})})},n=function(b,d){for(var e=a.isFunction(d)?d:c.constant(!1),f=b.dom(),g=[];null!==f.parentNode&&void 0!==f.parentNode;){var i=f.parentNode,j=h.fromDom(i);if(g.push(j),e(j)===!0)break;f=i}return g},o=function(a){var c=function(c){return b.filter(c,function(b){return!g.eq(a,b)})};return l(a).map(u).map(c).getOr([])},p=function(a){var b=a.dom();return d.from(b.offsetParent).map(h.fromDom)},q=function(a){var b=a.dom();return d.from(b.previousSibling).map(h.fromDom)},r=function(a){var b=a.dom();return d.from(b.nextSibling).map(h.fromDom)},s=function(a){return b.reverse(f.toArray(a,q))},t=function(a){return f.toArray(a,r)},u=function(a){var c=a.dom();return b.map(c.childNodes,h.fromDom)},v=function(a,b){var c=a.dom().childNodes;return d.from(c[b]).map(h.fromDom)},w=function(a){return v(a,0)},x=function(a){return v(a,a.dom().childNodes.length-1)},y=function(a,b){return a.dom().childNodes.length},z=e.immutable("element","offset"),A=function(a,b){var c=u(a);return c.length>0&&b=b.length&&c(d)}};0===b.length?c([]):a.each(b,function(a,b){a.get(f(b))})})};return{par:b}}),g("3j",["1i","3i","5a"],function(a,b,c){var d=function(a){return c.par(a,b.nu)},e=function(b,c){var e=a.map(b,c);return d(e)},f=function(a,b){return function(c){return b(c).bind(a)}};return{par:d,mapM:e,compose:f}}),g("3k",["1","2n"],function(a,b){var c=function(d){var e=function(a){return d===a},f=function(a){return c(d)},g=function(a){return c(d)},h=function(a){return c(a(d))},i=function(a){a(d)},j=function(a){return a(d)},k=function(a,b){return b(d)},l=function(a){return a(d)},m=function(a){return a(d)},n=function(){return b.some(d)};return{is:e,isValue:a.constant(!0),isError:a.constant(!1),getOr:a.constant(d),getOrThunk:a.constant(d),getOrDie:a.constant(d),or:f,orThunk:g,fold:k,map:h,each:i,bind:j,exists:l,forall:m,toOption:n}},d=function(c){var e=function(a){return a()},f=function(){return a.die(c)()},g=function(a){return a},h=function(a){return a()},i=function(a){return d(c)},j=function(a){return d(c)},k=function(a,b){return a(c)};return{is:a.constant(!1),isValue:a.constant(!1),isError:a.constant(!0),getOr:a.identity,getOrThunk:e,getOrDie:f,or:g,orThunk:h,fold:k,map:i,each:a.noop,bind:j,exists:a.constant(!1),forall:a.constant(!0),toOption:b.none}};return{value:c,error:d}}),g("1t",["1i","1","3i","3j","3k","1m","15","1e"],function(a,b,c,d,e,f,g,h){"use strict";return function(i,j){var k,l=0,m={};j=j||{},k=j.maxLoadTime||5e3;var n=function(a){i.getElementsByTagName("head")[0].appendChild(a)},o=function(a,b,c){var d,e,j,o,p=function(){for(var a=o.passed,b=a.length;b--;)a[b]();o.status=2,o.passed=[],o.failed=[]},q=function(){for(var a=o.failed,b=a.length;b--;)a[b]();o.status=3,o.passed=[],o.failed=[]},r=function(){var a=f.userAgent.match(/WebKit\/(\d*)/);return!!(a&&a[1]<536)},s=function(a,b){a()||((new Date).getTime()-j0)return e=i.createElement("style"),e.textContent='@import "'+a+'"',u(),void n(e);t()}n(d),d.href=a}},p=function(a){return c.nu(function(c){o(a,b.compose(c,b.constant(e.value(a))),b.compose(c,b.constant(e.error(a))))})},q=function(a){return a.fold(b.identity,b.identity)},r=function(b,c,e){d.par(a.map(b,p)).get(function(b){var d=a.partition(b,function(a){return a.isValue()});d.fail.length>0?e(d.fail.map(q)):c(d.pass.map(q))})};return{load:o,loadAll:r}}}),g("s",[],function(){return function(a,b){var c=a,d=function(a,c,d,e){var f,g;if(a){if(!e&&a[c])return a[c];if(a!=b){if(f=a[d])return f;for(g=a.parentNode;g&&g!=b;g=g.parentNode)if(f=g[d])return f}}},e=function(a,c,d,e){var f,g,h;if(a){if(f=a[d],b&&f===b)return;if(f){if(!e)for(h=f[c];h;h=h[c])if(!h[c])return h;return f}if(g=a.parentNode,g&&g!==b)return g}};this.current=function(){return c},this.next=function(a){return c=d(c,"firstChild","nextSibling",a)},this.prev=function(a){return c=d(c,"lastChild","previousSibling",a)},this.prev2=function(a){return c=e(c,"lastChild","previousSibling",a)}}}),g("3l",["1i","1","3f"],function(a,b,c){var d=["article","aside","details","div","dt","figcaption","footer","form","fieldset","header","hgroup","html","main","nav","section","summary","body","p","dl","multicol","dd","figure","address","center","blockquote","h1","h2","h3","h4","h5","h6","listing","xmp","pre","plaintext","menu","dir","ul","ol","li","hr","table","tbody","thead","tfoot","th","tr","td","caption"],e=["area","base","basefont","br","col","frame","hr","img","input","isindex","link","meta","param","embed","source","wbr","track"],f=["td","th"],g=["thead","tbody","tfoot"],h=["h1","h2","h3","h4","h5","h6","p","div","address","pre","form","blockquote","center","dir","fieldset","header","footer","article","section","hgroup","aside","nav","figure"],i=["h1","h2","h3","h4","h5","h6"],j=["li","dd","dt"],k=["ul","ol","dl"],l=function(d){var e;return function(f){return e=e?e:a.mapToObject(d,b.constant(!0)),e.hasOwnProperty(c.name(f))}},m=l(i),n=l(d),o=function(a){return c.isElement(a)&&!n(a)},p=function(a){return c.isElement(a)&&"br"===c.name(a)};return{isBlock:n,isInline:o,isHeading:m,isTextBlock:l(h),isList:l(k),isListItem:l(j),isVoid:l(e),isTableSection:l(g),isTableCell:l(f),isBr:p}}),g("1y",[],function(){var a=function(a){return function(b){return!!b&&b.nodeType==a}},b=a(1),c=function(a){return a=a.toLowerCase().split(" "),function(b){var c,d;if(b&&b.nodeType)for(d=b.nodeName.toLowerCase(),c=0;c=0;j--)g(h,k[j]);if(c.isDocument(i)===!1){if(c.isText(i)&&i.nodeValue.length>0){var l=d.trim(i.nodeValue).length;if(h.isBlock(i.parentNode)||l>0)return;if(0===l&&e(i))return}else if(c.isElement(i)&&(k=i.childNodes,1===k.length&&f(k[0])&&i.parentNode.insertBefore(k[0],i),k.length||b.isVoid(a.fromDom(i))))return;h.remove(i)}return i}};return{trimNode:g}}),g("v",["1v","1e"],function(a,b){var c,d,e,f=b.makeMap,g=/[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,h=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,i=/[<>&\"\']/g,j=/&#([a-z0-9]+);?|&([a-z0-9]+);/gi,k={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};d={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},e={"<":"<",">":">","&":"&",""":'"',"'":"'"};var l=function(b){var c;return c=a.fromTag("div").dom(),c.innerHTML=b,c.textContent||c.innerText||b},m=function(a,b){var c,e,f,g={};if(a){for(a=a.split(","),b=b||10,c=0;c1?"&#"+(1024*(a.charCodeAt(0)-55296)+(a.charCodeAt(1)-56320)+65536)+";":d[a]||"&#"+a.charCodeAt(0)+";"})},encodeNamed:function(a,b,e){return e=e||c,a.replace(b?g:h,function(a){return d[a]||e[a]||a})},getEncodeFunc:function(a,b){b=m(b)||c;var e=function(a,c){return a.replace(c?g:h,function(a){return void 0!==d[a]?d[a]:void 0!==b[a]?b[a]:a.length>1?"&#"+(1024*(a.charCodeAt(0)-55296)+(a.charCodeAt(1)-56320)+65536)+";":"&#"+a.charCodeAt(0)+";"})},i=function(a,c){return n.encodeNamed(a,c,b)};return a=f(a.replace(/\+/g,",")),a.named&&a.numeric?e:a.named?b?i:n.encodeNamed:a.numeric?n.encodeNumeric:n.encodeRaw},decode:function(a){return a.replace(j,function(a,b){return b?(b="x"===b.charAt(0).toLowerCase()?parseInt(b.substr(1),16):parseInt(b,10),b>65535?(b-=65536,String.fromCharCode(55296+(b>>10),56320+(1023&b))):k[b]||String.fromCharCode(b)):e[a]||c[a]||l(a)})}};return n}),g("y",["1e"],function(a){var b={},c={},d=a.makeMap,e=a.each,f=a.extend,g=a.explode,h=a.inArray,i=function(b,c){return b=a.trim(b),b?b.split(c||" "):[]},j=function(a){var d,f,g,h,j,k,l={},m=function(a,b,e){var f,g,h,j=function(a,b){var c,d,e={};for(c=0,d=a.length;c